/*******************************************************************************
 * Copyright (c) 2005, 2009 Wind River Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Bjorn Freeman-Benson - initial API and implementation
 *     Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
 *******************************************************************************/
package org.eclipse.debug.examples.pdavm;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Push Down Automata interpreter.
 * 
 * @since 3.5
 */
public class PDAVirtualMachine {

    static class Stack extends LinkedList {
        private static final long serialVersionUID = 1L;

        public Object pop() {
            return isEmpty() ? new Integer(0) : remove(size() - 1);
        }

        public void push(Object value) {
            add(value);
        }
    }
    
    static class Register {
        Register(String name) { 
            fName = name; 
        }
        String fName;
        String fGroup = "<no_group>";
        boolean fIsWriteable = true;
        Map fBitFields = new LinkedHashMap(0);
        int fValue;
    }

    static class BitField {
        BitField(String name) { 
            fName = name; 
        }
        String fName;
        int fBitOffset;
        int fBitCount;
        Map fMnemonics = new LinkedHashMap(0);
    }

    Map fRegisters = new LinkedHashMap(0);
    
    class Args {
        final String[] fArgs;

        int next = 0;

        Args(String[] args) {
            fArgs = args;
        }

        boolean hasNextArg() {
            return fArgs.length > next;
        }
        
        String getNextStringArg() {
            if (fArgs.length > next) {
                return fArgs[next++];
            }
            return "";
        }

        int getNextIntArg() {
            String arg = getNextStringArg();
            try {
                return Integer.parseInt(arg);
            } catch (NumberFormatException e) {
            }
            return 0;
        }

        boolean getNextBooleanArg() {
            String arg = getNextStringArg();
            try {
                return Boolean.getBoolean(arg);
            } catch (NumberFormatException e) {
            }
            return false;
        }

        Object getNextIntOrStringArg() {
            String arg = getNextStringArg();
            try {
                return new Integer(arg);
            } catch (NumberFormatException e) {
            }
            return arg;
        }

        PDAThread getThreadArg() {
            int id = getNextIntArg();
            return (PDAThread)fThreads.get( new Integer(id) );
        }
    }

    class PDAThread {
        final int fID;

        /** The push down automata data stack (the data stack). */
        final Stack fStack = new Stack();

        /**
         * PDAThread copy of the code. It can differ from the program if
         * performing an evaluation.
         */
        String[] fThreadCode;

        /** PDAThread copy of the labels. */
        Map fThreadLabels;

        /** The stack of stack frames (the control stack) */
        final List fFrames = new LinkedList();

        /** Current stack frame (not includced in fFrames) */
        Frame fCurrentFrame;

        /**
         * The run flag is true if the thread is running. If the run flag is
         * false, the thread exits the next time the main instruction loop runs.
         */
        boolean fRun = true;

        String fSuspend = null;

        boolean fStep = false;

        boolean fStepReturn = false;
        
        int fSavedPC;

        boolean fPerformingEval = false;
        
        PDAThread(int id, String function, int pc) {
            fID = id;
            fCurrentFrame = new Frame(function, pc);
            fThreadCode = fCode;
            fThreadLabels = fLabels;
        }
    }

    final Map fThreads = new LinkedHashMap();

    int fNextThreadId = 1;

    boolean fStarted = true;
    /**
     * The code is stored as an array of strings, each line of the source file
     * being one entry in the array.
     */
    final String[] fCode;

    /** A mapping of labels to indicies in the code array */
    final Map fLabels;

    /** Each stack frame is a mapping of variable names to values. */
    class Frame {
        final Map fLocalVariables = new LinkedHashMap();
        
        /**
         * The name of the function in this frame
         */
        final String fFunction;

        /**
         * The current program counter in the frame the pc points to the next
         * instruction to be executed
         */
        int fPC;

        Frame(String function, int pc) {
            fFunction = function;
            fPC = pc;
        }
        
        void set(String name, Object value) {
            if (name.startsWith("$")) {
                setRegisterValue(name, value);
            } else {
                fLocalVariables.put(name, value);
            }
        }
        
        Object get(String name) {
            if (name.startsWith("$")) {
                return getRegisterValue(name);
            } else { 
                return fLocalVariables.get(name);
            }
        }
    }

    void setRegisterValue(String name, Object value) {
        Register reg = (Register)fRegisters.get(getRegisterPartOfName(name));
        if (reg == null) return;
        String bitFieldName = getBitFieldPartOfName(name);
        if (bitFieldName != null) {
            BitField bitField = (BitField)reg.fBitFields.get(bitFieldName);
            if (bitField == null) return;
            Integer intValue = null;
            if (value instanceof Integer) {
                intValue = (Integer)value;
            } else if (value instanceof String) {
                intValue = (Integer)bitField.fMnemonics.get(value);
            }
            if (intValue != null) {
                int bitFieldMask = 2^(bitField.fBitCount - 1);           
                int registerMask = ~(bitFieldMask << bitField.fBitOffset);
                int bitFieldValue = intValue.intValue() & bitFieldMask;
                reg.fValue = (reg.fValue & registerMask) | (bitFieldValue << bitField.fBitOffset);
            }
        } else if (value instanceof Integer) {
            reg.fValue = ((Integer)value).intValue();
        }
    }

    Object getRegisterValue(String name) {
        Register reg = (Register)fRegisters.get(getRegisterPartOfName(name));
        if (reg == null) return null;
        String bitFieldName = getBitFieldPartOfName(name);
        if (bitFieldName != null) {
            BitField bitField = (BitField)reg.fBitFields.get(bitFieldName);
            if (bitField == null) return null;
            int bitFieldMask = 2^(bitField.fBitCount - 1);           
            int registerMask = bitFieldMask << bitField.fBitOffset;
            return new Integer( (reg.fValue & registerMask) >> bitField.fBitOffset );
        } else {
            return new Integer(reg.fValue);
        }
    }
    
    /**
     * Breakpoints are stored per each each line of code.  The boolean indicates
     * whether the whole VM should suspend or just the triggering thread.
     */
    final Map fBreakpoints = new HashMap();

    /**
     * The suspend flag is true if the VM should suspend running the program and
     * just listen for debug commands.
     */
    String fSuspendVM;

    /** Flag indicating whether the debugger is performing a step. */
    boolean fStepVM = false;

    /** Flag indicating whether the debugger is performing a step return */
    boolean fStepReturnVM = false;
    
    int fSteppingThread = 0;

    /** Name of the pda program being debugged */
    final String fFilename;

    /** The command line argument to start a debug session. */
    final boolean fDebug;

    /** The port to listen for debug commands on */
    final int fCommandPort;

    /**
     * Command socket for receiving debug commands and sending command responses
     */
    Socket fCommandSocket;

    /** Command socket reader */
    BufferedReader fCommandReceiveStream;

    /** Command socket write stream. */
    OutputStream fCommandResponseStream;

    /** The port to send debug events to */
    final int fEventPort;

    /** Event socket */
    Socket fEventSocket;

    /** Event socket and write stream. */
    OutputStream fEventStream;

    /** The eventstops table holds which events cause suspends and which do not. */
    final Map fEventStops = new HashMap();
    {
        fEventStops.put("unimpinstr", Boolean.FALSE);
        fEventStops.put("nosuchlabel", Boolean.FALSE);
    }

    /**
     * The watchpoints table holds watchpoint information.
     * <p/>
     * variablename_stackframedepth => N
     * <ul> 
     * <li>N = 0 is no watch</li> 
     * <li>N = 1 is read watch</li>
     * <li>N = 2 is write watch</li>
     * <li>N = 3 is both, etc.</li>
     */
    final Map fWatchpoints = new HashMap();

    public static void main(String[] args) {
        String programFile = args.length >= 1 ? args[0] : null;
        if (programFile == null) {
            System.err.println("Error: No program specified");
            return;
        }

        String debugFlag = args.length >= 2 ? args[1] : "";
        boolean debug = "-debug".equals(debugFlag);
        int commandPort = 0;
        int eventPort = 0;

        if (debug) {
            String commandPortStr = args.length >= 3 ? args[2] : "";
            try {
                commandPort = Integer.parseInt(commandPortStr);
            } catch (NumberFormatException e) {
                System.err.println("Error: Invalid command port");
                return;
            }

            String eventPortStr = args.length >= 4 ? args[3] : "";
            try {
                eventPort = Integer.parseInt(eventPortStr);
            } catch (NumberFormatException e) {
                System.err.println("Error: Invalid event port");
                return;
            }
        }

        PDAVirtualMachine pdaVM = null;
        try {
            pdaVM = new PDAVirtualMachine(programFile, debug, commandPort, eventPort);
            pdaVM.startDebugger();
        } catch (IOException e) {
            System.err.println("Error: " + e.toString());
            return;
        }
        pdaVM.run();
    }

    PDAVirtualMachine(String inputFile, boolean debug, int commandPort, int eventPort) throws IOException {
        fFilename = inputFile;

        // Load all the code into memory
        FileReader fileReader = new FileReader(inputFile);
        StringWriter stringWriter = new StringWriter();
        List code = new LinkedList();
        int c = fileReader.read();
        while (c != -1) {
            if (c == '\n') {
                code.add(stringWriter.toString().trim());
                stringWriter = new StringWriter();
            } else {
                stringWriter.write(c);
            }
            c = fileReader.read();
        }
        code.add(stringWriter.toString().trim());
        fCode = (String[])code.toArray(new String[code.size()]);

        fLabels = mapLabels(fCode);

        fDebug = debug;
        fCommandPort = commandPort;
        fEventPort = eventPort;
    }

    /**
     * Initializes the labels map
     */
    Map mapLabels(String[] code) {
        Map labels = new HashMap();
        for (int i = 0; i < code.length; i++) {
            if (code[i].length() != 0 && code[i].charAt(0) == ':') {
                labels.put(code[i].substring(1), new Integer(i));
            }
        }
        return labels;
    }

    void sendCommandResponse(String response) {
        try {
            fCommandResponseStream.write(response.getBytes());
            fCommandResponseStream.flush();
        } catch (IOException e) {
        }
    }

    void sendDebugEvent(String event, boolean error) {
        if (fDebug) {
            try {
                fEventStream.write(event.getBytes());
                fEventStream.write('\n');
                fEventStream.flush();
            } catch (IOException e) {
                System.err.println("Error: " + e);
                System.exit(1);
            }
        } else if (error) {
            System.err.println("Error: " + event);
        }
    }

    void startDebugger() throws IOException {
        if (fDebug) {
            System.out.println("-debug " + fCommandPort + " " + fEventPort);
        }

        ServerSocket commandServerSocket = new ServerSocket(fCommandPort);
        fCommandSocket = commandServerSocket.accept();
        fCommandReceiveStream = new BufferedReader(new InputStreamReader(fCommandSocket.getInputStream()));
        fCommandResponseStream = new PrintStream(fCommandSocket.getOutputStream());
        commandServerSocket.close();

        ServerSocket eventServerSocket = new ServerSocket(fEventPort);
        fEventSocket = eventServerSocket.accept();
        fEventStream = new PrintStream(fEventSocket.getOutputStream());
        eventServerSocket.close();

        System.out.println("debug connection accepted");

        fSuspendVM = "client";
    }
    
    void run() {
        int id = fNextThreadId++;
        sendDebugEvent("vmstarted", false);
        fThreads.put(new Integer(id), new PDAThread(id, "main", 0));
        if (fDebug) {
            sendDebugEvent("started " + id, false);
        }

        boolean allThreadsSuspended = false;
        while (!fThreads.isEmpty()) {
            checkForBreakpoint();
            
            if (fSuspendVM != null) {
                debugUI();
            } else {
                yieldToDebug(allThreadsSuspended);
                if (fSuspendVM != null) {
                    // Received a command to suspend VM, skip executing threads.
                    continue;
                }
            }

            PDAThread[] threadsCopy = (PDAThread[])fThreads.values().toArray(new PDAThread[fThreads.size()]);
            allThreadsSuspended = true;
            for (int i = 0; i < threadsCopy.length; i++) {
                PDAThread thread = threadsCopy[i];
                if (thread.fSuspend == null) {
                    allThreadsSuspended = false;
                    
                    String instruction = thread.fThreadCode[thread.fCurrentFrame.fPC];
                    thread.fCurrentFrame.fPC++;
                    doOneInstruction(thread, instruction);
                    if (thread.fCurrentFrame.fPC >= thread.fThreadCode.length) {
                        // Thread reached end of code, exit from the thread.
                        thread.fRun = false;
                    } else if (thread.fStepReturn) {
                        // If this thread is in a step-return operation, check
                        // if we've returned from a call.  
                        instruction = thread.fThreadCode[thread.fCurrentFrame.fPC];
                        if ("return".equals(instruction)) {
                            // Note: this will only be triggered if the current 
                            // thread also has the fStepReturn flag set.
                            if (fStepReturnVM) {
                                fSuspendVM = thread.fID + " step";
                            } else {
                                thread.fSuspend = "step";
                            }
                        }
                    }
                    if (!thread.fRun) {
                        sendDebugEvent("exited " + thread.fID, false);
                        fThreads.remove(new Integer(thread.fID));
                    } else if (thread.fSuspend != null) {
                        sendDebugEvent("suspended " + thread.fID + " " + thread.fSuspend, false);
                        thread.fStep = thread.fStepReturn = thread.fPerformingEval = false;
                    }
                } 
            }
            
            // Force thread context switch to avoid starving out other
            // processes in the system.
            Thread.yield();
        }
        
        sendDebugEvent("vmterminated", false);
        if (fDebug) {
            try {
                fCommandReceiveStream.close();
                fCommandResponseStream.close();
                fCommandSocket.close();
                fEventStream.close();
                fEventSocket.close();
            } catch (IOException e) {
                System.out.println("Error: " + e);
            }
        }

    }

    void doOneInstruction(PDAThread thread, String instr) {
        StringTokenizer tokenizer = new StringTokenizer(instr);
        String op = tokenizer.nextToken();
        List tokens = new LinkedList();
        while (tokenizer.hasMoreTokens()) {
            tokens.add(tokenizer.nextToken());
        }
        Args args = new Args( (String[])tokens.toArray(new String[tokens.size()]) );

        boolean opValid = true;
        if (op.equals("add")) iAdd(thread, args);
        else if (op.equals("branch_not_zero")) iBranchNotZero(thread, args);
        else if (op.equals("call")) iCall(thread, args);
        else if (op.equals("dec")) iDec(thread, args);
        else if (op.equals("def")) iDef(thread, args);
        else if (op.equals("dup")) iDup(thread, args);
        else if (op.equals("exec")) iExec(thread, args);            
        else if (op.equals("halt")) iHalt(thread, args);
        else if (op.equals("output")) iOutput(thread, args);
        else if (op.equals("pop")) iPop(thread, args);
        else if (op.equals("push")) iPush(thread, args);
        else if (op.equals("return")) iReturn(thread, args);
        else if (op.equals("var")) iVar(thread, args);
        else if (op.equals("xyzzy")) iInternalEndEval(thread, args);
        else if (op.startsWith(":")) {} // label
        else if (op.startsWith("#")) {} // comment
        else {
            opValid = false;
        }

        if (!opValid) {
            sendDebugEvent("unimplemented instruction " + op, true);
            if ( ((Boolean)fEventStops.get("unimpinstr")).booleanValue() ) {
                fSuspendVM = thread.fID + " event unimpinstr";
                thread.fCurrentFrame.fPC--;
            }
        } else if (thread.fStep) {
            if (fStepVM) {
                fSuspendVM = thread.fID + " step";
                fStepVM = false;
            } else {
                thread.fSuspend = "step";
            }
            thread.fStep = false;
        }
    }

    void checkForBreakpoint() {
        if (fDebug) {
            for (Iterator itr = fThreads.values().iterator(); itr.hasNext();) {
                PDAThread thread = (PDAThread)itr.next();
                Integer pc = new Integer(thread.fCurrentFrame.fPC);
                // Suspend for breakpoint if:
                // - the VM is not yet set to suspend, for e.g. as a result of step end,
                // - the thread is not yet suspended and is not performing an evaluation
                // - the breakpoints table contains a breakpoint for the given line.
                if (fSuspendVM == null && 
                    thread.fSuspend == null && !thread.fPerformingEval && 
                    fBreakpoints.containsKey(pc)) 
                {
                    if ( ((Boolean)fBreakpoints.get(pc)).booleanValue() ) {
                        fSuspendVM = thread.fID + " breakpoint " + pc;
                    } else {
                        thread.fSuspend = "breakpoint " + pc;
                        thread.fStep = thread.fStepReturn = false;
                        sendDebugEvent("suspended " + thread.fID + " " + thread.fSuspend, false);
                    }
                }
            }
        }
    }

    /**
     * After each instruction, we check the debug command channel for control input. If
     * there are commands, process them.
     */
    void yieldToDebug(boolean allThreadsSuspended) {
        if (fDebug) {
            String line = "";
            try {
                if (allThreadsSuspended || fCommandReceiveStream.ready()) {
                    line = fCommandReceiveStream.readLine();
                    processDebugCommand(line);
                }
            } catch (IOException e) {
                System.err.println("Error: " + e);
                System.exit(1);
            }
        }
    }

    /**
     *  Service the debugger commands while the VM is suspended
     */
    void debugUI() {
        if (!fStarted) {
            sendDebugEvent("vmsuspended " + fSuspendVM, false);
        } else {
            fStarted = false;
        }

        // Clear all stepping flags.  In case the VM suspended while
        // a step operation was being performed for the VM or some thread.
        fStepVM = fStepReturnVM = false;
        for (Iterator itr = fThreads.values().iterator(); itr.hasNext();) {
            PDAThread thread = (PDAThread)itr.next();
            thread.fSuspend = null;
            thread.fStep = thread.fStepReturn = thread.fPerformingEval = false;
        }
        
        while (fSuspendVM != null) {
            String line = "";
            try {
                line = fCommandReceiveStream.readLine();
            } catch (IOException e) {
                System.err.println("Error: " + e);
                System.exit(1);
                return;
            }
            processDebugCommand(line);
        }

        if (fStepVM || fStepReturnVM) {
            sendDebugEvent("vmresumed step", false);
        } else {
            sendDebugEvent("vmresumed client", false);
        }
    }

    void processDebugCommand(String line) {
        StringTokenizer tokenizer = new StringTokenizer(line.trim());
        if (line.length() == 0) {
            return;
        }

        String command = tokenizer.nextToken();
        List tokens = new LinkedList();
        while (tokenizer.hasMoreTokens()) {
            tokens.add(tokenizer.nextToken());
        }
        Args args = new Args( (String[])tokens.toArray(new String[tokens.size()]));

        if ("children".equals(command)) debugChildren(args);
        else if ("clear".equals(command)) debugClearBreakpoint(args);
        else if ("data".equals(command)) debugData(args);
        else if ("drop".equals(command)) debugDropFrame(args);
        else if ("eval".equals(command)) debugEval(args);
        else if ("eventstop".equals(command)) debugEventStop(args);
        else if ("frame".equals(command)) debugFrame(args);
        else if ("groups".equals(command)) debugGroups(args);
        else if ("popdata".equals(command)) debugPopData(args);
        else if ("pushdata".equals(command)) debugPushData(args);
        else if ("registers".equals(command)) debugRegisters(args);
        else if ("restart".equals(command)) debugRestart(args);
        else if ("resume".equals(command)) debugResume(args);
        else if ("set".equals(command)) debugSetBreakpoint(args);
        else if ("setdata".equals(command)) debugSetData(args);
        else if ("setvar".equals(command)) debugSetVariable(args);
        else if ("stack".equals(command)) debugStack(args);
        else if ("stackdepth".equals(command)) debugStackDepth(args);
        else if ("state".equals(command)) debugState(args);
        else if ("step".equals(command)) debugStep(args);
        else if ("stepreturn".equals(command)) debugStepReturn(args);
        else if ("suspend".equals(command)) debugSuspend(args);
        else if ("terminate".equals(command)) debugTerminate();
        else if ("threads".equals(command)) debugThreads();
        else if ("var".equals(command)) debugVar(args);
        else if ("vmresume".equals(command)) debugVMResume();
        else if ("vmsuspend".equals(command)) debugVMSuspend();
        else if ("watch".equals(command)) debugWatch(args);
        else {
            sendCommandResponse("error: invalid command\n");
        }
    }

    void debugChildren(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }

        int sfnumber = args.getNextIntArg();
        String var = args.getNextStringArg();
        
        Frame frame = sfnumber >= thread.fFrames.size()    
            ? thread.fCurrentFrame : (Frame)thread.fFrames.get(sfnumber);

        String varDot = var + ".";
        List children = new ArrayList();
        for (Iterator itr = frame.fLocalVariables.keySet().iterator(); itr.hasNext();) {
            String localVar = (String)itr.next();
            if (localVar.startsWith(varDot) && localVar.indexOf('.', varDot.length() + 1) == -1) {
                children.add(localVar);
            }
        }

        StringBuffer result = new StringBuffer();
        for (Iterator itr = children.iterator(); itr.hasNext();) {
            result.append(itr.next());
            result.append('|');
        }
        result.append('\n');

        sendCommandResponse(result.toString());
    }
    
    void debugClearBreakpoint(Args args) {
        int line = args.getNextIntArg();

        fBreakpoints.remove( new Integer(line) );
        sendCommandResponse("ok\n");
    }

    private static Pattern fPackPattern = Pattern.compile("%([a-fA-F0-9][a-fA-F0-9])");

    void debugData(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }

        StringBuffer result = new StringBuffer();
        for (Iterator itr = thread.fStack.iterator(); itr.hasNext();) {
            result.append(itr.next());
            result.append('|');
        }
        result.append('\n');
        sendCommandResponse(result.toString());
    }

    void debugDropFrame(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }

        if (!thread.fFrames.isEmpty()) {
            thread.fCurrentFrame = (Frame)thread.fFrames.remove(thread.fFrames.size() - 1);
        }
        thread.fCurrentFrame.fPC--;
        sendCommandResponse("ok\n");
        if (fSuspendVM != null) {
            sendDebugEvent("vmresumed drop", false);
            sendDebugEvent("vmsuspended " + thread.fID + " drop", false);
        } else {
            sendDebugEvent("resumed " + thread.fID + " drop", false);
            sendDebugEvent("suspended " + thread.fID + " drop", false);
        }
    }

    void debugEval(Args args) {
        if (fSuspendVM != null) {
            sendCommandResponse("error: cannot evaluate while vm is suspended\n");        
            return;
        }
        
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }
        
        if (thread.fSuspend == null) {
            sendCommandResponse("error: thread running\n");
            return;
        }
        
        StringTokenizer tokenizer = new StringTokenizer(args.getNextStringArg(), "|");
        tokenizer.countTokens();

        int numEvalLines = tokenizer.countTokens();
        thread.fThreadCode = new String[fCode.length + numEvalLines + 1];
        System.arraycopy(fCode, 0, thread.fThreadCode, 0, fCode.length);
        for (int i = 0; i < numEvalLines; i++) {
            String line = tokenizer.nextToken();
            StringBuffer lineBuf = new StringBuffer(line.length());
            Matcher matcher = fPackPattern.matcher(line);
            int lastMatchEnd = 0;
            while (matcher.find()) {
                lineBuf.append(line.substring(lastMatchEnd, matcher.start()));
                String charCode = line.substring(matcher.start() + 1, matcher.start() + 3);
                try {
                    lineBuf.append((char) Integer.parseInt(charCode, 16));
                } catch (NumberFormatException e) {
                }
                lastMatchEnd = matcher.end();
            }
            if (lastMatchEnd < line.length()) {
                lineBuf.append(line.substring(lastMatchEnd));
            }
            thread.fThreadCode[fCode.length + i] = lineBuf.toString();
        }
        thread.fThreadCode[fCode.length + numEvalLines] = "xyzzy";
        thread.fThreadLabels = mapLabels(fCode);

        thread.fSavedPC = thread.fCurrentFrame.fPC;
        thread.fCurrentFrame.fPC = fCode.length;
        thread.fPerformingEval = true;
        
        thread.fSuspend = null;
        
        sendCommandResponse("ok\n");

        sendDebugEvent("resumed " + thread.fID + " eval", false);
    }

    void debugEventStop(Args args) {
        String event = args.getNextStringArg();
        int stop = args.getNextIntArg();
        fEventStops.put(event, new Boolean(stop > 0));
        sendCommandResponse("ok\n");
    }

    void debugTerminate() {
        sendCommandResponse("ok\n");
        sendDebugEvent("vmterminated", false);
        System.exit(0);
    }

    void debugFrame(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }

        int sfnumber = args.getNextIntArg();
        Frame frame = null;
        if (sfnumber >= thread.fFrames.size()) {
            frame = thread.fCurrentFrame;
        } else {
            frame = (Frame)thread.fFrames.get(sfnumber);
        }
        sendCommandResponse(printFrame(frame) + "\n");
    }

    void debugGroups(Args args) {
        TreeSet groups = new TreeSet();
        for (Iterator itr = fRegisters.values().iterator(); itr.hasNext();) {
            Register reg = (Register)itr.next();
            groups.add(reg.fGroup);
        }
        StringBuffer response = new StringBuffer();
        for (Iterator itr = groups.iterator(); itr.hasNext();) {
            response.append(itr.next());
            response.append('|');
        }
        response.append('\n');
        sendCommandResponse(response.toString());
    }

    void debugPopData(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }

        thread.fStack.pop();
        sendCommandResponse("ok\n");
    }

    void debugPushData(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }
        
        Object val = args.getNextIntOrStringArg();
        thread.fStack.push(val);
        sendCommandResponse("ok\n");
    }

    void debugRegisters(Args args) {
        String group = args.getNextStringArg();
        
        StringBuffer response = new StringBuffer();
        for (Iterator itr = fRegisters.values().iterator(); itr.hasNext();) {
            Register reg = (Register)itr.next();
            if (group.equals(reg.fGroup)) {
                response.append(reg.fName);
                response.append(' ');
                response.append(reg.fIsWriteable);
                for (Iterator itr2 = reg.fBitFields.values().iterator(); itr2.hasNext();) {
                    BitField bitField = (BitField)itr2.next();
                    response.append('|');
                    response.append(bitField.fName);
                    response.append(' ');
                    response.append(bitField.fBitOffset);
                    response.append(' ');
                    response.append(bitField.fBitCount);
                    response.append(' ');
                    for (Iterator itr3 = bitField.fMnemonics.entrySet().iterator(); itr3.hasNext();) {
                        Map.Entry mnemonicEntry = (Map.Entry)itr3.next();
                        response.append(mnemonicEntry.getKey());
                        response.append(' ');
                        response.append(mnemonicEntry.getValue());
                        response.append(' ');
                    }
                }
                
                response.append('#');
            }
        }
        response.append('\n');
        sendCommandResponse(response.toString());
    }

    void debugRestart(Args args) {
        fSuspendVM = "restart";

        for (Iterator itr = fThreads.keySet().iterator(); itr.hasNext();) {
            Integer id = (Integer)itr.next();
            sendDebugEvent("exited " + id, false);            
        }
        fThreads.clear();

        int id = fNextThreadId++;
        fThreads.put(new Integer(id), new PDAThread(id, "main", 0));
        sendDebugEvent("started " + id, false);            
        
        fRegisters.clear();
        
        sendCommandResponse("ok\n");
    }

    void debugResume(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        } 
        if (fSuspendVM != null) {
            sendCommandResponse("error: cannot resume thread when vm is suspended\n");
            return;
        } 
        if (thread.fSuspend == null) {
            sendCommandResponse("error: thread already running\n");
            return;
        } 
        
        thread.fSuspend = null;
        sendDebugEvent("resumed " + thread.fID + " client", false);
        
        sendCommandResponse("ok\n");
    }

    void debugSetBreakpoint(Args args) {
        int line = args.getNextIntArg();
        int stopVM = args.getNextIntArg();
        
        fBreakpoints.put(new Integer(line), new Boolean(stopVM != 0));
        sendCommandResponse("ok\n");
    }

    void debugSetData(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }
        
        int offset = args.getNextIntArg();
        Object val = args.getNextIntOrStringArg();

        if (offset < thread.fStack.size()) {
            thread.fStack.set(offset, val);
        } else {
            thread.fStack.add(0, val);
        }
        sendCommandResponse("ok\n");
    }

    void debugSetVariable(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }

        int sfnumber = args.getNextIntArg();
        String var = args.getNextStringArg();
        Object val = args.getNextIntOrStringArg();
        while (args.hasNextArg()) {
            val = val.toString() + " " + args.getNextStringArg();
        }
        
        if (sfnumber >= thread.fFrames.size()) {
            thread.fCurrentFrame.set(var, val);
        } else {
            ((Frame)thread.fFrames.get(sfnumber)).set(var, val);
        }
        sendCommandResponse("ok\n");
    }

    void debugStack(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }

        StringBuffer result = new StringBuffer();
        
        for (Iterator itr = thread.fFrames.iterator(); itr.hasNext();) {
            Frame frame = (Frame)itr.next();
            result.append(printFrame(frame));
            result.append('#');
        }
        result.append(printFrame(thread.fCurrentFrame));
        result.append('\n');
        sendCommandResponse(result.toString());
    }

    void debugStackDepth(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }
        sendCommandResponse( Integer.toString(thread.fFrames.size() + 1) + "\n" );
    }


    /**
     * The stack frame output is: frame # frame # frame ... where each frame is:
     * filename | line number | function name | var | var | var | var ...
     */
    private String printFrame(Frame frame) {
        StringBuffer buf = new StringBuffer();
        buf.append(fFilename);
        buf.append('|');
        buf.append(frame.fPC);
        buf.append('|');
        buf.append(frame.fFunction);
        for (Iterator itr = frame.fLocalVariables.keySet().iterator(); itr.hasNext();) {
            String var = (String)itr.next();
            if (var.indexOf('.') == -1) {
                buf.append('|');
                buf.append(var);
            }
        }
        return buf.toString();
    }

    void debugState(Args args) {
        PDAThread thread = args.getThreadArg();
        String response = null;
        if (thread == null) {
            response = fSuspendVM == null ? "running" : fSuspendVM;
        } else if (fSuspendVM != null) {
            response = "vm";
        } else {
            response = thread.fSuspend == null ? "running" : thread.fSuspend;
        }
        sendCommandResponse(response + "\n");
    }
    
    void debugStep(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        } 

        // Set suspend to null to allow the debug loop to exit back to the 
        // instruction loop and thus run an instruction. However, we want to 
        // come back to the debug loop right away, so the step flag is set to 
        // true which will cause the suspend flag to get set to true when we 
        // get to the next instruction.
        if (fSuspendVM != null) {
            // All threads are suspended, so suspend all threads again when 
            // step completes.
            fSuspendVM = null;
            fStepVM = true;
            // Also mark the thread that initiated the step to mark it as
            // the triggering thread when suspending.
            thread.fStep = true;
        } else {
            if (thread.fSuspend == null) {
                sendCommandResponse("error: thread already running\n");
                return;
            }
            thread.fSuspend = null;
            thread.fStep = true;
            sendDebugEvent("resumed " + thread.fID + " step", false);
        }
        sendCommandResponse("ok\n");
    }

    void debugStepReturn(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        } 
        
        if (fSuspendVM != null) {
            fSuspendVM = null;
            fStepReturnVM = true;
            thread.fStepReturn = true;
        } else {
            if (thread.fSuspend == null) {
                sendCommandResponse("error: thread running\n");
                return;
            }
            thread.fSuspend = null;
            thread.fStepReturn = true;
            sendDebugEvent("resumed " + thread.fID + " step", false);
        }
        sendCommandResponse("ok\n");
    }

    void debugSuspend(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        } 
        if (fSuspendVM != null) {
            sendCommandResponse("error: vm already suspended\n");
            return;
        }
        if (thread.fSuspend != null) {
            sendCommandResponse("error: thread already suspended\n");
            return;
        } 
        
        thread.fSuspend = "client";
        sendDebugEvent("suspended " + thread.fID + " client", false);
        sendCommandResponse("ok\n");
    }

    void debugThreads() {
        StringBuffer response = new StringBuffer();
        for (Iterator itr = fThreads.keySet().iterator(); itr.hasNext();) {
            response.append(itr.next());
            response.append(' ');
        }
        sendCommandResponse(response.toString().trim() + "\n");
    }

    void debugVar(Args args) {
        PDAThread thread = args.getThreadArg();
        if (thread == null) {
            sendCommandResponse("error: invalid thread\n");
            return;
        }

        int sfnumber = args.getNextIntArg();
        String var = args.getNextStringArg();

        Frame frame = sfnumber >= thread.fFrames.size()    
            ? thread.fCurrentFrame : (Frame)thread.fFrames.get(sfnumber);
        
        Object val = frame.get(var);
        if (val == null) {
            sendCommandResponse("error: variable undefined\n");
        } else {
            sendCommandResponse(val.toString() + "\n");
        }
    }

    void debugVMResume() {
        if (fSuspendVM == null) {
            sendCommandResponse("error: vm already running\n");
            return;
        } 

        fSuspendVM = null;
        sendCommandResponse("ok\n");
    }

    void debugVMSuspend() {
        if (fSuspendVM != null) {
            sendCommandResponse("error: vm already suspended\n");
            return;
        }

        fSuspendVM = "client";
        sendCommandResponse("ok\n");
    }

    void debugWatch(Args args) {
        String funcAndVar = args.getNextStringArg();
        int flags = args.getNextIntArg();
        fWatchpoints.put(funcAndVar, new Integer(flags));
        sendCommandResponse("ok\n");
    }

    void iAdd(PDAThread thread, Args args) {
        Object val1 = thread.fStack.pop();
        Object val2 = thread.fStack.pop();
        if (val1 instanceof Integer && val2 instanceof Integer) {
            int intVal1 = ((Integer) val1).intValue();
            int intVal2 = ((Integer) val2).intValue();
            thread.fStack.push( new Integer(intVal1 + intVal2) );
        } else {
            thread.fStack.push( new Integer(-1) );
        }
    }

    void iBranchNotZero(PDAThread thread, Args args) {
        Object val = thread.fStack.pop();
        if (val instanceof Integer && ((Integer) val).intValue() != 0) {
            String label = args.getNextStringArg();
            if (thread.fThreadLabels.containsKey(label)) {
                thread.fCurrentFrame.fPC = ((Integer)thread.fThreadLabels.get(label)).intValue();
            } else {
                sendDebugEvent("no such label " + label, true);
                if ( ((Boolean)fEventStops.get("nosuchlabel")).booleanValue() ) {
                    fSuspendVM = thread.fID + " event nosuchlabel";
                    thread.fStack.push(val);
                    thread.fCurrentFrame.fPC--;
                }
            }
        }
    }

    void iCall(PDAThread thread, Args args) {
        String label = args.getNextStringArg();
        if (thread.fThreadLabels.containsKey(label)) {
            thread.fFrames.add(thread.fCurrentFrame);
            thread.fCurrentFrame = new Frame(label, ((Integer)thread.fThreadLabels.get(label)).intValue());
        } else {
            sendDebugEvent("no such label " + label, true);
            if ( ((Boolean)fEventStops.get("nosuchlabel")).booleanValue() ) {
                fSuspendVM = thread.fID + " event nosuchlabel";
                thread.fCurrentFrame.fPC--;
            }
        }
    }

    void iDec(PDAThread thread, Args args) {
        Object val = thread.fStack.pop();
        if (val instanceof Integer) {
            val = new Integer(((Integer) val).intValue() - 1);
        }
        thread.fStack.push(val);
    }

    void iDef(PDAThread thread, Args args) {
        String type = args.getNextStringArg();

        String name = args.getNextStringArg();
        String regName = getRegisterPartOfName(name);
        String bitFieldName = getBitFieldPartOfName(name);

        if ("register".equals(type)) {
            Register reg = new Register(regName); 
            reg.fGroup = args.getNextStringArg();
            fRegisters.put(regName, reg);
            reg.fIsWriteable = args.getNextBooleanArg();
        } else if ("bitfield".equals(type)) {
            Register reg = (Register)fRegisters.get(regName);
            if (reg == null) return;
            BitField bitField = new BitField(bitFieldName);
            bitField.fBitOffset = args.getNextIntArg();
            bitField.fBitCount = args.getNextIntArg();
            reg.fBitFields.put(bitFieldName, bitField);
        } else if ("mnemonic".equals(type)) {
            Register reg = (Register)fRegisters.get(regName);
            if (reg == null) return;
            BitField bitField = (BitField)reg.fBitFields.get(bitFieldName);
            if (bitField == null) return;
            bitField.fMnemonics.put(args.getNextStringArg(), new Integer(args.getNextIntArg()));
        }
        sendDebugEvent("registers", false);
    }

    private String getRegisterPartOfName(String name) {
        if (name.startsWith("$")) {
            int end = name.indexOf('.');
            end = end != -1 ? end : name.length();
            return name.substring(1, end);
        }
        return null;
    }

    private String getBitFieldPartOfName(String name) {
        int start = name.indexOf('.');
        if (name.startsWith("$") && start != -1) {
            return name.substring(start + 1, name.length());
        }
        return null;        
    }

    void iDup(PDAThread thread, Args args) {
        Object val = thread.fStack.pop();
        thread.fStack.push(val);
        thread.fStack.push(val);
    }
    
    void iExec(PDAThread thread, Args args) {
        String label = args.getNextStringArg();
        if (fLabels.containsKey(label)) {
            int id = fNextThreadId++;
            fThreads.put( new Integer(id), new PDAThread(id, label, ((Integer)fLabels.get(label)).intValue()) );
            sendDebugEvent("started " + id, false);
        } else {
            sendDebugEvent("no such label " + label, true);
            if ( ((Boolean)fEventStops.get("nosuchlabel")).booleanValue() ) {
                thread.fSuspend = "event nosuchlabel";
                thread.fCurrentFrame.fPC--;
            }
        }
    }

    void iHalt(PDAThread thread, Args args) {
        thread.fRun = false;
    }

    void iOutput(PDAThread thread, Args args) {
        System.out.println(thread.fStack.pop());
    }

    void iPop(PDAThread thread, Args args) {
        String arg = args.getNextStringArg();
        if (arg.startsWith("$")) {
            String var = arg.substring(1);
            thread.fCurrentFrame.set(var, thread.fStack.pop());
            String key = thread.fCurrentFrame.fFunction + "::" + var;
            if ( fWatchpoints.containsKey(key) && (((Integer)fWatchpoints.get(key)).intValue() & 2) != 0 ) {
                fSuspendVM = thread.fID + " watch write " + key;
            }
        } else {
            thread.fStack.pop();
        }
    }

    void iPush(PDAThread thread, Args args) {
        String arg = args.getNextStringArg();
        while (arg.length() != 0) {
            if (arg.startsWith("$")) {
                String var = arg.substring(1);
                Object val = thread.fCurrentFrame.get(var);
                if (val == null) val = "<undefined>";
                thread.fStack.push(val);
                String key = thread.fCurrentFrame.fFunction + "::" + var;
                if (fWatchpoints.containsKey(key) && (((Integer)fWatchpoints.get(key)).intValue() & 1) != 0) {
                    fSuspendVM = thread.fID + " watch read " + key;
                }
            } else {
                Object val = arg;
                if (args.hasNextArg()) {
                    while (args.hasNextArg()) {
                        val = val.toString() + " " + args.getNextStringArg();
                    }
                } else {
                    try {
                        val = new Integer(arg);
                    } catch (NumberFormatException e) {
                    }
                }
                thread.fStack.push(val);
            }
            
            arg = args.getNextStringArg();
        }
    }

    void iReturn(PDAThread thread, Args args) {
        if (!thread.fFrames.isEmpty()) {
            thread.fCurrentFrame = (Frame)thread.fFrames.remove(thread.fFrames.size() - 1);
        } else {
            // Execution returned from the top frame, which means this thread
            // should exit.
            thread.fRun = false;
        }
    }

    void iVar(PDAThread thread, Args args) {
        String var = args.getNextStringArg();
        thread.fCurrentFrame.set(var, new Integer(0));
    }

    void iInternalEndEval(PDAThread thread, Args args) {
        Object result = thread.fStack.pop();
        thread.fThreadCode = fCode;
        thread.fThreadLabels = fLabels;
        thread.fCurrentFrame.fPC = thread.fSavedPC;
        sendDebugEvent("evalresult " + result, false);
        thread.fSuspend = "eval";
        thread.fPerformingEval = false;
    }

}
