diff --git a/.classpath b/.classpath index 009529c2..fc39bf58 100644 --- a/.classpath +++ b/.classpath @@ -6,7 +6,5 @@ - - diff --git a/build.xml b/build.xml index 43fd45aa..e75a13ac 100644 --- a/build.xml +++ b/build.xml @@ -7,8 +7,7 @@ - + @@ -46,7 +45,7 @@ - + diff --git a/lib/commons-cli-1.1.jar b/lib/commons-cli-1.1.jar deleted file mode 100644 index e633afbe..00000000 Binary files a/lib/commons-cli-1.1.jar and /dev/null differ diff --git a/src/main/java/lua/debug/DebugEvent.java b/src/main/java/lua/debug/DebugEvent.java index 963de75a..f22b2af3 100644 --- a/src/main/java/lua/debug/DebugEvent.java +++ b/src/main/java/lua/debug/DebugEvent.java @@ -21,11 +21,12 @@ ******************************************************************************/ package lua.debug; -import java.io.Serializable; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; public class DebugEvent implements Serializable { - private static final long serialVersionUID = -6167781055176807311L; protected DebugEventType type; public DebugEvent(DebugEventType type) { @@ -45,5 +46,15 @@ public class DebugEvent implements Serializable { */ public String toString() { return type.toString(); - } + } + + public static void serialize(DataOutputStream out, DebugEvent object) + throws IOException { + SerializationHelper.serialize(object.getType(), out); + } + + public static DebugEvent deserialize(DataInputStream in) throws IOException { + DebugEventType type = (DebugEventType) SerializationHelper.deserialize(in); + return new DebugEvent(type); + } } diff --git a/src/main/java/lua/debug/DebugEventBreakpoint.java b/src/main/java/lua/debug/DebugEventBreakpoint.java index 2da5921c..93d96fa5 100644 --- a/src/main/java/lua/debug/DebugEventBreakpoint.java +++ b/src/main/java/lua/debug/DebugEventBreakpoint.java @@ -21,13 +21,24 @@ ******************************************************************************/ package lua.debug; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + public class DebugEventBreakpoint extends DebugEvent { - private static final long serialVersionUID = -7573362646669094458L; protected String source; protected int lineNumber; public DebugEventBreakpoint(String source, int lineNumber) { super(DebugEventType.suspendedOnBreakpoint); + if (source == null) { + throw new IllegalArgumentException("argument source cannot be null"); + } + + if (lineNumber <= 0) { + throw new IllegalArgumentException("argument lineNumber must be positive integer"); + } + this.source = source; this.lineNumber = lineNumber; } @@ -46,4 +57,17 @@ public class DebugEventBreakpoint extends DebugEvent { public String toString() { return super.toString() + " source:" + getSource() + " line:" + getLineNumber(); } + + public static void serialize(DataOutputStream out, DebugEventBreakpoint object) + throws IOException { + out.writeUTF(object.getSource()); + out.writeInt(object.getLineNumber()); + } + + public static DebugEvent deserialize(DataInputStream in) throws IOException { + String source = in.readUTF(); + int lineNo = in.readInt(); + + return new DebugEventBreakpoint(source, lineNo); + } } diff --git a/src/main/java/lua/debug/DebugEventError.java b/src/main/java/lua/debug/DebugEventError.java index 2119ee02..b8fc6668 100644 --- a/src/main/java/lua/debug/DebugEventError.java +++ b/src/main/java/lua/debug/DebugEventError.java @@ -21,8 +21,11 @@ ******************************************************************************/ package lua.debug; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + public class DebugEventError extends DebugEvent { - private static final long serialVersionUID = -7911842790951966147L; protected String detail; public DebugEventError(String detail) { @@ -40,4 +43,15 @@ public class DebugEventError extends DebugEvent { public String toString() { return super.toString() + " detail: " + getDetail(); } + + public static void serialize(DataOutputStream out, DebugEventError object) + throws IOException { + //TODO implement + } + + public static DebugEvent deserialize(DataInputStream in) + throws IOException { + //TODO implement + return null; + } } diff --git a/src/main/java/lua/debug/DebugEventType.java b/src/main/java/lua/debug/DebugEventType.java index 5f94e5a3..828612ac 100644 --- a/src/main/java/lua/debug/DebugEventType.java +++ b/src/main/java/lua/debug/DebugEventType.java @@ -21,8 +21,12 @@ ******************************************************************************/ package lua.debug; +import java.io.DataInputStream; +import java.io.IOException; + + public class DebugEventType extends EnumType { - public static DebugEventType started = new DebugEventType("started", 0); + public static DebugEventType started = new DebugEventType("started", 0); public static DebugEventType suspendedByClient = new DebugEventType("suspendedByClient", 1); public static DebugEventType suspendedOnBreakpoint = new DebugEventType("suspendedOnBreakpoint", 2); public static DebugEventType suspendedOnWatchpoint = new DebugEventType("suspendedOnWatchpoint", 3); @@ -34,7 +38,30 @@ public class DebugEventType extends EnumType { public static DebugEventType error = new DebugEventType("error", 9); public static DebugEventType terminated = new DebugEventType("terminated", 10); + protected static DebugEventType[] ENUMS = new DebugEventType[] { + started, + suspendedByClient, + suspendedOnBreakpoint, + suspendedOnWatchpoint, + suspendedOnStepping, + suspendedOnError, + resumedByClient, + resumedOnStepping, + resumedOnError, + error, + terminated + }; + protected DebugEventType(String name, int ordinal) { super(name, ordinal); } + + public static DebugEventType deserialize(DataInputStream in) + throws IOException { + int ordinal = in.readInt(); + if (ordinal < 0 || ordinal >= ENUMS.length) { + throw new RuntimeException("ordinal is out of the range."); + } + return ENUMS[ordinal]; + } } diff --git a/src/main/java/lua/debug/DebugRequest.java b/src/main/java/lua/debug/DebugRequest.java index a3490bcc..1e273ea8 100644 --- a/src/main/java/lua/debug/DebugRequest.java +++ b/src/main/java/lua/debug/DebugRequest.java @@ -21,10 +21,11 @@ ******************************************************************************/ package lua.debug; -import java.io.Serializable; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; public class DebugRequest implements Serializable { - private static final long serialVersionUID = 2741129244733000595L; protected DebugRequestType type; public DebugRequest(DebugRequestType type) { @@ -41,4 +42,15 @@ public class DebugRequest implements Serializable { public String toString() { return type.toString(); } + + public static void serialize(DataOutputStream out, DebugRequest request) + throws IOException { + DebugRequestType type = request.getType(); + SerializationHelper.serialize(type, out); + } + + public static DebugRequest deserialize(DataInputStream in) throws IOException { + DebugRequestType type = (DebugRequestType) SerializationHelper.deserialize(in); + return new DebugRequest(type); + } } diff --git a/src/main/java/lua/debug/DebugRequestLineBreakpointToggle.java b/src/main/java/lua/debug/DebugRequestLineBreakpointToggle.java index 4b2a9279..1fc6b689 100644 --- a/src/main/java/lua/debug/DebugRequestLineBreakpointToggle.java +++ b/src/main/java/lua/debug/DebugRequestLineBreakpointToggle.java @@ -21,8 +21,11 @@ ******************************************************************************/ package lua.debug; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + public class DebugRequestLineBreakpointToggle extends DebugRequest { - private static final long serialVersionUID = -3954500569399285372L; protected String source; protected int lineNumber; @@ -49,4 +52,19 @@ public class DebugRequestLineBreakpointToggle extends DebugRequest { public String toString() { return super.toString() + " Source:" + getSource() + " lineNumber:" + getLineNumber(); } + + public static void serialize(DataOutputStream out, DebugRequestLineBreakpointToggle request) + throws IOException { + SerializationHelper.serialize(request.getType(), out); + out.writeUTF(request.getSource()); + out.writeInt(request.getLineNumber()); + } + + public static DebugRequest deserialize(DataInputStream in) throws IOException { + DebugRequestType type = (DebugRequestType)SerializationHelper.deserialize(in); + String source = in.readUTF(); + int lineNo = in.readInt(); + + return new DebugRequestLineBreakpointToggle(type, source, lineNo); + } } diff --git a/src/main/java/lua/debug/DebugRequestStack.java b/src/main/java/lua/debug/DebugRequestStack.java index 95eabd90..4d43944b 100644 --- a/src/main/java/lua/debug/DebugRequestStack.java +++ b/src/main/java/lua/debug/DebugRequestStack.java @@ -21,8 +21,11 @@ ******************************************************************************/ package lua.debug; -public class DebugRequestStack extends DebugRequest { - private static final long serialVersionUID = 6270383432060791307L; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class DebugRequestStack extends DebugRequest implements Serializable { protected int index; public DebugRequestStack(int index) { @@ -40,4 +43,15 @@ public class DebugRequestStack extends DebugRequest { public String toString() { return super.toString() + " stack frame:" + getIndex(); } + + public static void serialize(DataOutputStream out, DebugRequestStack request) + throws IOException { + out.writeInt(request.getIndex()); + } + + public static DebugRequest deserialize(DataInputStream in) throws IOException { + int index = in.readInt(); + + return new DebugRequestStack(index); + } } diff --git a/src/main/java/lua/debug/DebugRequestType.java b/src/main/java/lua/debug/DebugRequestType.java index 9c0d4f38..88db55e7 100644 --- a/src/main/java/lua/debug/DebugRequestType.java +++ b/src/main/java/lua/debug/DebugRequestType.java @@ -21,9 +21,11 @@ ******************************************************************************/ package lua.debug; +import java.io.DataInputStream; +import java.io.IOException; + + public class DebugRequestType extends EnumType { - private static final long serialVersionUID = 2829883820534540402L; - public static final DebugRequestType suspend = new DebugRequestType("suspend", 0); public static final DebugRequestType resume = new DebugRequestType("resume", 1); public static final DebugRequestType exit = new DebugRequestType("exit", 2); @@ -34,8 +36,29 @@ public class DebugRequestType extends EnumType { public static final DebugRequestType callgraph = new DebugRequestType("callgraph", 7); public static final DebugRequestType stack = new DebugRequestType("stack", 8); public static final DebugRequestType step = new DebugRequestType("step", 9); + + protected static final DebugRequestType[] ENUMS = new DebugRequestType[] { + suspend, + resume, + exit, + lineBreakpointSet, + lineBreakpointClear, + watchpointSet, + watchpointClear, + callgraph, + stack, + step + }; public DebugRequestType(String name, int ordinal) { super(name, ordinal); } + + public static DebugRequestType deserialize(DataInputStream in) throws IOException { + int ordinal = in.readInt(); + if (ordinal < 0 || ordinal >= ENUMS.length) { + throw new RuntimeException("ordinal is out of the range."); + } + return ENUMS[ordinal]; + } } diff --git a/src/main/java/lua/debug/DebugRequestWatchpointToggle.java b/src/main/java/lua/debug/DebugRequestWatchpointToggle.java index 589ce77b..e9554f4c 100644 --- a/src/main/java/lua/debug/DebugRequestWatchpointToggle.java +++ b/src/main/java/lua/debug/DebugRequestWatchpointToggle.java @@ -22,8 +22,6 @@ package lua.debug; public class DebugRequestWatchpointToggle extends DebugRequest { - private static final long serialVersionUID = -2978341358052851046L; - public static class AccessType extends EnumType { private static final long serialVersionUID = 3523086189648091587L; @@ -64,4 +62,6 @@ public class DebugRequestWatchpointToggle extends DebugRequest { public String toString() { return super.toString() + " functionName:" + getFunctionName() + " variableName:" + getVariableName(); } + + // TODO: add the serialization stuff } diff --git a/src/main/java/lua/debug/DebugResponse.java b/src/main/java/lua/debug/DebugResponse.java index 753d490e..cca17934 100644 --- a/src/main/java/lua/debug/DebugResponse.java +++ b/src/main/java/lua/debug/DebugResponse.java @@ -21,4 +21,4 @@ ******************************************************************************/ package lua.debug; -public interface DebugResponse {} +public interface DebugResponse extends Serializable {} diff --git a/src/main/java/lua/debug/DebugResponseCallgraph.java b/src/main/java/lua/debug/DebugResponseCallgraph.java index a08d2f19..03ff8b82 100644 --- a/src/main/java/lua/debug/DebugResponseCallgraph.java +++ b/src/main/java/lua/debug/DebugResponseCallgraph.java @@ -21,13 +21,19 @@ ******************************************************************************/ package lua.debug; -public class DebugResponseCallgraph extends DebugResponseSimple { - private static final long serialVersionUID = -7761865402188853413L; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class DebugResponseCallgraph implements DebugResponse { protected StackFrame[] stackFrames; public DebugResponseCallgraph(StackFrame[] callgraph) { - super(true); - this.stackFrames = callgraph; + if (callgraph == null) { + this.stackFrames = new StackFrame[0]; + } else { + this.stackFrames = callgraph; + } } public StackFrame[] getCallgraph() { @@ -36,11 +42,30 @@ public class DebugResponseCallgraph extends DebugResponseSimple { public String toString() { StringBuilder buffer = new StringBuilder(); - for (int i = 0; stackFrames != null && i < stackFrames.length; i++) { + for (int i = 0; i < stackFrames.length; i++) { StackFrame frame = stackFrames[i]; buffer.append(frame.toString()); buffer.append("\n"); } return buffer.toString(); } + + public static void serialize(DataOutputStream out, DebugResponseCallgraph response) + throws IOException { + StackFrame[] stackFrames = response.getCallgraph(); + out.writeInt(stackFrames == null ? 0 : stackFrames.length); + for (int i = 0; stackFrames != null && i < stackFrames.length; i++) { + StackFrame.serialize(out, stackFrames[i]); + } + } + + public static DebugResponseCallgraph deserialize(DataInputStream in) throws IOException { + int count = in.readInt(); + StackFrame[] stackFrames = new StackFrame[count]; + for (int i = 0; i < count; i++) { + stackFrames[i] = StackFrame.deserialize(in); + } + + return new DebugResponseCallgraph(stackFrames); + } } diff --git a/src/main/java/lua/debug/DebugResponseSimple.java b/src/main/java/lua/debug/DebugResponseSimple.java index 1d52380d..9ff63575 100644 --- a/src/main/java/lua/debug/DebugResponseSimple.java +++ b/src/main/java/lua/debug/DebugResponseSimple.java @@ -21,11 +21,11 @@ ******************************************************************************/ package lua.debug; -import java.io.Serializable; - -public class DebugResponseSimple implements DebugResponse, Serializable { - private static final long serialVersionUID = 7042417813840650230L; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +public class DebugResponseSimple implements DebugResponse { protected boolean isSuccessful; public static final DebugResponseSimple SUCCESS = new DebugResponseSimple(true); @@ -45,4 +45,15 @@ public class DebugResponseSimple implements DebugResponse, Serializable { public String toString() { return String.valueOf(isSuccessful); } + + public static void serialize(DataOutputStream out, DebugResponseSimple response) + throws IOException { + out.writeBoolean(response.isSuccessful()); + } + + public static DebugResponseSimple deserialize(DataInputStream in) + throws IOException { + boolean value = in.readBoolean(); + return value ? SUCCESS : FAILURE; + } } diff --git a/src/main/java/lua/debug/DebugResponseStack.java b/src/main/java/lua/debug/DebugResponseStack.java index a95c9fc9..babf17b8 100644 --- a/src/main/java/lua/debug/DebugResponseStack.java +++ b/src/main/java/lua/debug/DebugResponseStack.java @@ -21,13 +21,19 @@ ******************************************************************************/ package lua.debug; -public class DebugResponseStack extends DebugResponseSimple { - private static final long serialVersionUID = -2108425321162834731L; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class DebugResponseStack implements DebugResponse { protected Variable[] variables; public DebugResponseStack(Variable[] variables) { - super(true); - this.variables = variables; + if (variables == null) { + this.variables = new Variable[0]; + } else { + this.variables = variables; + } } public Variable[] getVariables() { @@ -44,4 +50,22 @@ public class DebugResponseStack extends DebugResponseSimple { } return buffer.toString(); } + + public static void serialize(DataOutputStream out, DebugResponseStack response) + throws IOException { + Variable[] variables = response.getVariables(); + out.writeInt(variables == null ? 0 : variables.length); + for (int i = 0; i < variables.length; i++) { + SerializationHelper.serialize(variables[i], out); + } + } + + public static DebugResponseStack deserialize(DataInputStream in) throws IOException { + int count = in.readInt(); + Variable[] variables = new Variable[count]; + for (int i = 0; i < count; i++) { + variables[i] = (Variable) SerializationHelper.deserialize(in); + } + return new DebugResponseStack(variables); + } } diff --git a/src/main/java/lua/debug/DebugStackState.java b/src/main/java/lua/debug/DebugStackState.java index 295f040d..4deae1e9 100644 --- a/src/main/java/lua/debug/DebugStackState.java +++ b/src/main/java/lua/debug/DebugStackState.java @@ -21,12 +21,8 @@ ******************************************************************************/ package lua.debug; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.Hashtable; +import java.util.Vector; import lua.CallInfo; import lua.Lua; @@ -41,12 +37,12 @@ public class DebugStackState extends StackState implements DebugRequestListener private static final boolean DEBUG = false; - protected Map breakpoints = new HashMap(); + protected Hashtable breakpoints = new Hashtable(); protected boolean exiting = false; protected boolean suspended = false; protected boolean stepping = false; protected int lastline = -1; - protected List debugEventListeners = new ArrayList(); + protected Vector debugEventListeners = new Vector(); public DebugStackState() { } @@ -130,25 +126,26 @@ public class DebugStackState extends StackState implements DebugRequestListener // anytime the line doesn't change we keep going int line = getLineNumber(calls[cc]); - if(DebugUtils.IS_DEBUG) - DebugUtils.println("debugHook - executing line: " + line); if ( !stepping && lastline == line ) { return; } + if(DebugUtils.IS_DEBUG) + DebugUtils.println("debugHook - executing line: " + line); // save line in case next op is a step lastline = line; if ( stepping ) { DebugUtils.println("suspended by stepping at pc=" + pc); - notifyDebugEventListeners(new DebugEventStepping()); + //TODO: notifyDebugEventListeners(new DebugEventStepping()); suspended = true; } else if ( !suspended ) { // check for a break point if we aren't suspended already Proto p = calls[cc].closure.p; String source = DebugUtils.getSourceFileName(p.source); if ( breakpoints.containsKey(constructBreakpointKey(source, line))){ - DebugUtils.println("hitting breakpoint " + constructBreakpointKey(source, line)); + if(DebugUtils.IS_DEBUG) + DebugUtils.println("hitting breakpoint " + constructBreakpointKey(source, line)); notifyDebugEventListeners( new DebugEventBreakpoint(source, line)); suspended = true; @@ -161,7 +158,8 @@ public class DebugStackState extends StackState implements DebugRequestListener while (suspended && !exiting ) { try { this.wait(); - DebugUtils.println("resuming execution..."); + if(DebugUtils.IS_DEBUG) + DebugUtils.println("resuming execution..."); } catch ( InterruptedException ie ) { ie.printStackTrace(); } @@ -271,7 +269,8 @@ public class DebugStackState extends StackState implements DebugRequestListener * clear breakpoint at line lineNumber of source source */ public void clearBreakpoint(String source, int lineNumber) { - DebugUtils.println("removing breakpoint " + constructBreakpointKey(source, lineNumber)); + if(DebugUtils.IS_DEBUG) + DebugUtils.println("removing breakpoint " + constructBreakpointKey(source, lineNumber)); synchronized ( this ) { breakpoints.remove(constructBreakpointKey(source, lineNumber)); } @@ -302,24 +301,27 @@ public class DebugStackState extends StackState implements DebugRequestListener } CallInfo callInfo = calls[index]; - DebugUtils.println("Stack Frame: " + index + "[" + callInfo.base + "," + callInfo.top + "]"); + if(DebugUtils.IS_DEBUG) + DebugUtils.println("Stack Frame: " + index + "[" + callInfo.base + "," + callInfo.top + "]"); int top = callInfo.top < callInfo.base ? callInfo.base : callInfo.top; Proto prototype = callInfo.closure.p; LocVars[] localVariables = prototype.locvars; - List variables = new ArrayList(); + Vector variables = new Vector(); int localVariableCount = 0; - Set variablesSeen = new HashSet(); + Hashtable variablesSeen = new Hashtable(); for (int i = 0; localVariables != null && i < localVariables.length && i <= top; i++) { String varName = localVariables[i].varname.toString(); - DebugUtils.print("\tVariable: " + varName); - DebugUtils.print("\tValue: " + stack[callInfo.base + i]); + if(DebugUtils.IS_DEBUG) { + DebugUtils.print("\tVariable: " + varName); + DebugUtils.print("\tValue: " + stack[callInfo.base + i]); + } if (!variablesSeen.contains(varName) && !LexState.isReservedKeyword(varName)) { - variablesSeen.add(varName); + variablesSeen.put(varName, varName); LValue value = stack[callInfo.base + i]; if (value != null) { int type = value.luaGetType(); - DebugUtils.print("\tType: " + type); + DebugUtils.print("\tType: " + Lua.TYPE_NAMES[type]); if (type == Lua.LUA_TTABLE) { DebugUtils.println(" (selected)"); variables.add( diff --git a/src/main/java/lua/debug/DebugSupport.java b/src/main/java/lua/debug/DebugSupport.java index 816e63ad..47485544 100644 --- a/src/main/java/lua/debug/DebugSupport.java +++ b/src/main/java/lua/debug/DebugSupport.java @@ -21,24 +21,36 @@ ******************************************************************************/ package lua.debug; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; public class DebugSupport implements DebugEventListener { public static class State extends EnumType { - private static final long serialVersionUID = 3657364516937093612L; - public static final State UNKNOWN = new State("UNKNOWN", 0); public static final State RUNNING = new State("RUNNING", 1); public static final State STOPPED = new State("STOPPED", 2); + protected static final State[] ENUMS = new State[] { + UNKNOWN, + RUNNING, + STOPPED + }; + public State(String name, int ordinal) { super(name, ordinal); } + + public static State deserialize(DataInputStream in) throws IOException { + int ordinal = in.readInt(); + if (ordinal < 0 || ordinal >= ENUMS.length) { + throw new RuntimeException("ordinal is out of the range."); + } + return ENUMS[ordinal]; + } } protected DebugRequestListener listener; @@ -49,12 +61,12 @@ public class DebugSupport implements DebugEventListener { protected ServerSocket requestSocket; protected Socket clientRequestSocket; - protected ObjectInputStream requestReader; - protected ObjectOutputStream requestWriter; + protected DataInputStream requestReader; + protected DataOutputStream requestWriter; protected ServerSocket eventSocket; protected Socket clientEventSocket; - protected ObjectOutputStream eventWriter; + protected DataOutputStream eventWriter; public DebugSupport(DebugRequestListener listener, int requestPort, @@ -117,14 +129,14 @@ public class DebugSupport implements DebugEventListener { this.requestSocket = new ServerSocket(requestPort); this.clientRequestSocket = requestSocket.accept(); this.requestReader - = new ObjectInputStream(clientRequestSocket.getInputStream()); + = new DataInputStream(clientRequestSocket.getInputStream()); this.requestWriter - = new ObjectOutputStream(clientRequestSocket.getOutputStream()); + = new DataOutputStream(clientRequestSocket.getOutputStream()); this.eventSocket = new ServerSocket(eventPort); this.clientEventSocket = eventSocket.accept(); this.eventWriter - = new ObjectOutputStream(clientEventSocket.getOutputStream()); + = new DataOutputStream(clientEventSocket.getOutputStream()); this.requestWatcherThread = new Thread(new Runnable() { public void run() { @@ -151,11 +163,17 @@ public class DebugSupport implements DebugEventListener { synchronized (clientRequestSocket) { try { while (getState() != State.STOPPED) { + int size = requestReader.readInt(); + byte[] data = new byte[size]; + requestReader.readFully(data); DebugRequest request - = (DebugRequest) requestReader.readObject(); + = (DebugRequest) SerializationHelper.deserialize(data); DebugUtils.println("SERVER receives request: " + request.toString()); + DebugResponse response = listener.handleRequest(request); - requestWriter.writeObject(response); + data = SerializationHelper.serialize(response); + requestWriter.writeInt(data.length); + requestWriter.write(data); requestWriter.flush(); DebugUtils.println("SERVER sends response: " + response); } @@ -167,8 +185,6 @@ public class DebugSupport implements DebugEventListener { cleanup(); } catch (IOException e) { e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } } } @@ -203,7 +219,9 @@ public class DebugSupport implements DebugEventListener { DebugUtils.println("SERVER sending event: " + event.toString()); synchronized (eventSocket) { try { - eventWriter.writeObject(event); + byte[] data = SerializationHelper.serialize(event); + eventWriter.writeInt(data.length); + eventWriter.write(data); eventWriter.flush(); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/lua/debug/DebugUtils.java b/src/main/java/lua/debug/DebugUtils.java index 61d45219..898211c7 100644 --- a/src/main/java/lua/debug/DebugUtils.java +++ b/src/main/java/lua/debug/DebugUtils.java @@ -27,7 +27,7 @@ import lua.io.LoadState; import lua.value.LString; public class DebugUtils { - public static final boolean IS_DEBUG = false; + public static final boolean IS_DEBUG = true; public static void println(String message) { if (IS_DEBUG) { diff --git a/src/main/java/lua/debug/EnumType.java b/src/main/java/lua/debug/EnumType.java index 6a4343c5..08a50afe 100644 --- a/src/main/java/lua/debug/EnumType.java +++ b/src/main/java/lua/debug/EnumType.java @@ -21,24 +21,17 @@ ******************************************************************************/ package lua.debug; +import java.io.DataOutputStream; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; -public class EnumType implements Serializable { - private static final long serialVersionUID = -496099911938395074L; - + +public abstract class EnumType implements Serializable { protected String name; protected int ordinal; - protected static Map lookup = new HashMap(); public EnumType(String name, int ordinal) { this.name = name; this.ordinal = ordinal; - lookup.put(name, this); } public String toString() { @@ -60,4 +53,8 @@ public class EnumType implements Serializable { public final int ordinal() { return this.ordinal; } + + public static void serialize(DataOutputStream out, EnumType enumType) throws IOException { + out.writeInt(enumType.ordinal()); + } } diff --git a/src/main/java/lua/debug/NullableString.java b/src/main/java/lua/debug/NullableString.java new file mode 100644 index 00000000..ca3e274b --- /dev/null +++ b/src/main/java/lua/debug/NullableString.java @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (c) 2007 LuaJ. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +******************************************************************************/ +package lua.debug; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class NullableString implements Serializable { + protected String string; + + public NullableString(String someString) { + this.string = someString; + } + + public String getNullableString() { + return (this.string == null) ? "[NULL]" : this.string; + } + + public String getRawString() { + return (this.string.equals("[NULL]")) ? null : this.string; + } + + public static void serialize(DataOutputStream out, NullableString string) + throws IOException { + out.writeUTF(string.getNullableString()); + } + + public static NullableString deserialize(DataInputStream in) + throws IOException { + String string = in.readUTF(); + return new NullableString(string); + } +} diff --git a/src/main/java/lua/debug/DebugEventStepping.java b/src/main/java/lua/debug/Serializable.java similarity index 85% rename from src/main/java/lua/debug/DebugEventStepping.java rename to src/main/java/lua/debug/Serializable.java index b8a1e9ec..400a796c 100644 --- a/src/main/java/lua/debug/DebugEventStepping.java +++ b/src/main/java/lua/debug/Serializable.java @@ -21,10 +21,6 @@ ******************************************************************************/ package lua.debug; -public class DebugEventStepping extends DebugEvent { - private static final long serialVersionUID = 3902898567880012107L; - public DebugEventStepping() { - super(DebugEventType.suspendedOnStepping); - } -} + +public interface Serializable { } diff --git a/src/main/java/lua/debug/SerializationHelper.java b/src/main/java/lua/debug/SerializationHelper.java new file mode 100644 index 00000000..d687fffa --- /dev/null +++ b/src/main/java/lua/debug/SerializationHelper.java @@ -0,0 +1,163 @@ +package lua.debug; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class SerializationHelper { + + public static byte[] serialize(Serializable object) throws IOException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + DataOutputStream dout = new DataOutputStream(bout); + + serialize(object, dout); + + byte[] data = bout.toByteArray(); + + bout.close(); + dout.close(); + + return data; + } + + public static Serializable deserialize(byte[] data) throws IOException { + ByteArrayInputStream bin = new ByteArrayInputStream(data); + DataInputStream din = new DataInputStream(bin); + + Serializable object = deserialize(din); + + bin.close(); + din.close(); + + return object; + } + + + static final int SERIAL_TYPE_NullableString = 0; + static final int SERIAL_TYPE_TableVariable = 1; + static final int SERIAL_TYPE_Variable = 2; + static final int SERIAL_TYPE_DebugResponseCallgraph = 3; + static final int SERIAL_TYPE_DebugResponseStack = 4; + static final int SERIAL_TYPE_DebugResponseSimple = 5; + static final int SERIAL_TYPE_DebugSupportState = 6; + static final int SERIAL_TYPE_StackFrame = 7; + static final int SERIAL_TYPE_DebugRequestType = 8; + static final int SERIAL_TYPE_DebugRequest = 9; + static final int SERIAL_TYPE_DebugRequestStack = 10; + static final int SERIAL_TYPE_DebugRequestLineBreakpointToggle = 11; + static final int SERIAL_TYPE_DebugEventType = 12; + static final int SERIAL_TYPE_DebugEvent = 13; + static final int SERIAL_TYPE_DebugEventBreakpoint = 14; + + public static void serialize(Serializable object, DataOutputStream dout) + throws IOException { + if (object instanceof NullableString) { + dout.writeInt(SERIAL_TYPE_NullableString); + NullableString.serialize(dout, (NullableString)object); + } else if (object instanceof TableVariable) { + dout.writeInt(SERIAL_TYPE_TableVariable); + TableVariable.serialize(dout, (TableVariable)object); + } else if (object instanceof Variable) { + dout.writeInt(SERIAL_TYPE_Variable); + Variable.serialize(dout, (Variable)object); + } else if (object instanceof StackFrame) { + dout.writeInt(SERIAL_TYPE_StackFrame); + StackFrame.serialize(dout, (StackFrame)object); + } else if (object instanceof DebugResponseSimple) { + dout.writeInt(SERIAL_TYPE_DebugResponseSimple); + DebugResponseSimple.serialize(dout, (DebugResponseSimple)object); + } else if (object instanceof DebugResponseStack) { + dout.writeInt(SERIAL_TYPE_DebugResponseStack); + DebugResponseStack.serialize(dout, (DebugResponseStack)object); + } else if (object instanceof DebugResponseCallgraph) { + dout.writeInt(SERIAL_TYPE_DebugResponseCallgraph); + DebugResponseCallgraph.serialize(dout, (DebugResponseCallgraph)object); + } else if (object instanceof DebugSupport.State) { + dout.writeInt(SERIAL_TYPE_DebugSupportState); + DebugSupport.State.serialize(dout, (DebugSupport.State)object); + } else if (object instanceof DebugRequestType) { + dout.writeInt(SERIAL_TYPE_DebugRequestType); + DebugRequestType.serialize(dout, (DebugRequestType)object); + } else if (object instanceof DebugRequestStack) { + dout.writeInt(SERIAL_TYPE_DebugRequestStack); + DebugRequestStack.serialize(dout, (DebugRequestStack)object); + } else if (object instanceof DebugRequestLineBreakpointToggle) { + dout.writeInt(SERIAL_TYPE_DebugRequestLineBreakpointToggle); + DebugRequestLineBreakpointToggle.serialize(dout, (DebugRequestLineBreakpointToggle)object); + } else if (object instanceof DebugRequest) { + dout.writeInt(SERIAL_TYPE_DebugRequest); + DebugRequest.serialize(dout, (DebugRequest)object); + } else if (object instanceof DebugEventType) { + dout.writeInt(SERIAL_TYPE_DebugEventType); + DebugEventType.serialize(dout, (DebugEventType)object); + } else if (object instanceof DebugEventBreakpoint) { + dout.writeInt(SERIAL_TYPE_DebugEventBreakpoint); + DebugEventBreakpoint.serialize(dout, (DebugEventBreakpoint)object); + } else if (object instanceof DebugEvent) { + dout.writeInt(SERIAL_TYPE_DebugEvent); + DebugEvent.serialize(dout, (DebugEvent)object); + } else { + // catch the errors: forgot to implement serialization/deserialization + throw new RuntimeException("serialization operation is not supported"); + } + } + + public static Serializable deserialize(DataInputStream din) + throws IOException { + Serializable object = null; + int type = din.readInt(); + switch (type) { + case SERIAL_TYPE_NullableString: + object = NullableString.deserialize(din); + break; + case SERIAL_TYPE_TableVariable: + object = TableVariable.deserialize(din); + break; + case SERIAL_TYPE_Variable: + object = Variable.deserialize(din); + break; + case SERIAL_TYPE_StackFrame: + object = StackFrame.deserialize(din); + break; + case SERIAL_TYPE_DebugResponseSimple: + object = DebugResponseSimple.deserialize(din); + break; + case SERIAL_TYPE_DebugResponseCallgraph: + object = DebugResponseCallgraph.deserialize(din); + break; + case SERIAL_TYPE_DebugResponseStack: + object = DebugResponseStack.deserialize(din); + break; + case SERIAL_TYPE_DebugSupportState: + object = DebugSupport.State.deserialize(din); + break; + case SERIAL_TYPE_DebugRequestType: + object = DebugRequestType.deserialize(din); + break; + case SERIAL_TYPE_DebugRequestStack: + object = DebugRequestStack.deserialize(din); + break; + case SERIAL_TYPE_DebugRequestLineBreakpointToggle: + object = DebugRequestLineBreakpointToggle.deserialize(din); + break; + case SERIAL_TYPE_DebugRequest: + object = DebugRequest.deserialize(din); + break; + case SERIAL_TYPE_DebugEventType: + object = DebugEventType.deserialize(din); + break; + case SERIAL_TYPE_DebugEventBreakpoint: + object = DebugEventBreakpoint.deserialize(din); + break; + case SERIAL_TYPE_DebugEvent: + object = DebugEvent.deserialize(din); + break; + default: + throw new RuntimeException("deserialization operation is not supported"); + } + + return object; + } +} diff --git a/src/main/java/lua/debug/StackFrame.java b/src/main/java/lua/debug/StackFrame.java index 56470fe9..02b52c73 100644 --- a/src/main/java/lua/debug/StackFrame.java +++ b/src/main/java/lua/debug/StackFrame.java @@ -42,23 +42,25 @@ ******************************************************************************/ package lua.debug; -import java.io.Serializable; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import lua.CallInfo; -import lua.io.Proto; public class StackFrame implements Serializable { - private static final long serialVersionUID = 2102834561519501432L; protected int lineNumber; protected String source; public StackFrame(CallInfo callInfo, int lineNumber) { - Proto prototype = callInfo.closure.p; - - this.lineNumber = lineNumber; - this.source = DebugUtils.getSourceFileName(prototype.source); + this(lineNumber, DebugUtils.getSourceFileName(callInfo.closure.p.source)); } + StackFrame(int lineNumber, String source) { + this.lineNumber = lineNumber; + this.source = source; + } + public int getLineNumber() { return this.lineNumber; } @@ -73,4 +75,41 @@ public class StackFrame implements Serializable { public String toString() { return getSource() + ":" + getLineNumber(); } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + lineNumber; + result = prime * result + ((source == null) ? 0 : source.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final StackFrame other = (StackFrame) obj; + if (lineNumber != other.lineNumber) + return false; + if (source == null) { + if (other.source != null) + return false; + } else if (!source.equals(other.source)) + return false; + return true; + } + + public static void serialize(DataOutputStream out, StackFrame stackFrame) throws IOException { + out.writeInt(stackFrame.getLineNumber()); + out.writeUTF(stackFrame.getSource()); + } + + public static StackFrame deserialize(DataInputStream in) throws IOException { + int lineNumber = in.readInt(); + String source = in.readUTF(); + return new StackFrame(lineNumber, source); + } } diff --git a/src/main/java/lua/debug/StandardLuaJVM.java b/src/main/java/lua/debug/StandardLuaJVM.java index 01a8a5e9..81a0758c 100644 --- a/src/main/java/lua/debug/StandardLuaJVM.java +++ b/src/main/java/lua/debug/StandardLuaJVM.java @@ -40,22 +40,13 @@ import lua.io.Proto; import lua.value.LString; import lua.value.LValue; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.GnuParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.OptionBuilder; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; - /** * StandardLuaJVM executes a lua program in normal run mode or debug mode. * * @author: Shu Lei * @version: 1.0 */ -public class StandardLuaJVM implements DebugRequestListener { - protected Options options = new Options(); +public class StandardLuaJVM implements DebugRequestListener { protected boolean isDebugMode = false; protected DebugSupport debugSupport; protected int requestPort; @@ -64,88 +55,104 @@ public class StandardLuaJVM implements DebugRequestListener { protected String[] scriptArgs; protected StackState state; protected boolean isReady = false; - protected boolean isTerminated = false; - - public StandardLuaJVM() { - options.addOption(OptionBuilder.withArgName("requestPort eventPort"). - hasArgs(2). - isRequired(false). - withValueSeparator(' '). - withDescription("run LuaJ VM in debug mode"). - create("debug")); - options.addOption(OptionBuilder.withArgName("LuaJProgram"). - withDescription("lua program to be executed"). - isRequired(). - hasArgs(). - withValueSeparator(' '). - create("file")); + protected boolean isTerminated = false; + + // command line parsing utilities + class ParseException extends Exception { + private static final long serialVersionUID = -3134938136698856577L; + + public ParseException(String message) { + super(message); + } } protected void printUsage() { - HelpFormatter formatter = new HelpFormatter(); - formatter.printHelp("java StandardLuaJVM", options); + System.out.println("Usage:"); + System.out.println("\t java StandardLuaJVM [-debug ]