make the debugging support code compile under JDK 1.3
This commit is contained in:
@@ -29,7 +29,7 @@ public class GlobalState {
|
|||||||
resetGlobals();
|
resetGlobals();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resetGlobals() {
|
static public void resetGlobals() {
|
||||||
_G = new LTable();
|
_G = new LTable();
|
||||||
_G .put( "_G", _G );
|
_G .put( "_G", _G );
|
||||||
Builtin.addBuiltins( _G );
|
Builtin.addBuiltins( _G );
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ public class DebugEvent implements Serializable {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return type.toString();
|
return type.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ public class DebugEventBreakpoint extends DebugEvent {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see lua.debug.DebugEvent#toString()
|
* @see lua.debug.DebugEvent#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " source:" + getSource() + " line:" + getLineNumber();
|
return super.toString() + " source:" + getSource() + " line:" + getLineNumber();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public class DebugEventError extends DebugEvent {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see lua.debug.DebugEvent#toString()
|
* @see lua.debug.DebugEvent#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " detail: " + getDetail();
|
return super.toString() + " detail: " + getDetail();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,16 +21,20 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package lua.debug;
|
package lua.debug;
|
||||||
|
|
||||||
public enum DebugEventType {
|
public class DebugEventType extends EnumType {
|
||||||
started,
|
public static DebugEventType started = new DebugEventType("started", 0);
|
||||||
suspendedByClient,
|
public static DebugEventType suspendedByClient = new DebugEventType("suspendedByClient", 1);
|
||||||
suspendedOnBreakpoint,
|
public static DebugEventType suspendedOnBreakpoint = new DebugEventType("suspendedOnBreakpoint", 2);
|
||||||
suspendedOnWatchpoint,
|
public static DebugEventType suspendedOnWatchpoint = new DebugEventType("suspendedOnWatchpoint", 3);
|
||||||
suspendedOnStepping,
|
public static DebugEventType suspendedOnStepping = new DebugEventType("suspendedOnStepping", 4);
|
||||||
suspendedOnError,
|
public static DebugEventType suspendedOnError = new DebugEventType("suspendedOnError", 5);
|
||||||
resumedByClient,
|
public static DebugEventType resumedByClient = new DebugEventType("resumedByClient", 6);
|
||||||
resumedOnStepping,
|
public static DebugEventType resumedOnStepping = new DebugEventType("resumedOnStepping", 7);
|
||||||
resumedOnError,
|
public static DebugEventType resumedOnError = new DebugEventType("resumedOnError", 8);
|
||||||
error,
|
public static DebugEventType error = new DebugEventType("error", 9);
|
||||||
terminated
|
public static DebugEventType terminated = new DebugEventType("terminated", 10);
|
||||||
|
|
||||||
|
protected DebugEventType(String name, int ordinal) {
|
||||||
|
super(name, ordinal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ public class DebugRequest implements Serializable {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return type.toString();
|
return type.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ public class DebugRequestLineBreakpointToggle extends DebugRequest {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see lua.debug.DebugRequest#toString()
|
* @see lua.debug.DebugRequest#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " Source:" + getSource() + " lineNumber:" + getLineNumber();
|
return super.toString() + " Source:" + getSource() + " lineNumber:" + getLineNumber();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public class DebugRequestStack extends DebugRequest {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see lua.debug.DebugRequest#toString()
|
* @see lua.debug.DebugRequest#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " stack frame:" + getIndex();
|
return super.toString() + " stack frame:" + getIndex();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,15 +21,21 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package lua.debug;
|
package lua.debug;
|
||||||
|
|
||||||
public enum DebugRequestType {
|
public class DebugRequestType extends EnumType {
|
||||||
suspend,
|
private static final long serialVersionUID = 2829883820534540402L;
|
||||||
resume,
|
|
||||||
exit,
|
public static final DebugRequestType suspend = new DebugRequestType("suspend", 0);
|
||||||
lineBreakpointSet,
|
public static final DebugRequestType resume = new DebugRequestType("resume", 1);
|
||||||
lineBreakpointClear,
|
public static final DebugRequestType exit = new DebugRequestType("exit", 2);
|
||||||
watchpointSet,
|
public static final DebugRequestType lineBreakpointSet = new DebugRequestType("lineBreakpointSet", 3);
|
||||||
watchpointClear,
|
public static final DebugRequestType lineBreakpointClear = new DebugRequestType("lineBreakpointClear", 4);
|
||||||
callgraph,
|
public static final DebugRequestType watchpointSet = new DebugRequestType("watchpointSet", 5);
|
||||||
stack,
|
public static final DebugRequestType watchpointClear = new DebugRequestType("watchpointClear", 6);
|
||||||
step
|
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);
|
||||||
|
|
||||||
|
public DebugRequestType(String name, int ordinal) {
|
||||||
|
super(name, ordinal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,17 @@ package lua.debug;
|
|||||||
public class DebugRequestWatchpointToggle extends DebugRequest {
|
public class DebugRequestWatchpointToggle extends DebugRequest {
|
||||||
private static final long serialVersionUID = -2978341358052851046L;
|
private static final long serialVersionUID = -2978341358052851046L;
|
||||||
|
|
||||||
public enum AccessType {
|
public static class AccessType extends EnumType {
|
||||||
Ignore,
|
private static final long serialVersionUID = 3523086189648091587L;
|
||||||
Read,
|
|
||||||
Modify,
|
public static final AccessType Ignore = new AccessType("Ignore", 0);
|
||||||
ReadAndModify
|
public static final AccessType Read = new AccessType("Read", 1);
|
||||||
|
public static final AccessType Modify = new AccessType("Modify", 2);
|
||||||
|
public static final AccessType ReadAndModify = new AccessType("ReadAndModify", 3);
|
||||||
|
|
||||||
|
protected AccessType(String name, int ordinal) {
|
||||||
|
super(name, ordinal);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected String functionName;
|
protected String functionName;
|
||||||
@@ -37,7 +43,9 @@ public class DebugRequestWatchpointToggle extends DebugRequest {
|
|||||||
public DebugRequestWatchpointToggle(String functionName,
|
public DebugRequestWatchpointToggle(String functionName,
|
||||||
String variableName,
|
String variableName,
|
||||||
AccessType accessType) {
|
AccessType accessType) {
|
||||||
super(accessType == AccessType.Ignore ? DebugRequestType.watchpointClear : DebugRequestType.watchpointSet);
|
super(accessType == AccessType.Ignore ?
|
||||||
|
DebugRequestType.watchpointClear :
|
||||||
|
DebugRequestType.watchpointSet);
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
this.variableName = variableName;
|
this.variableName = variableName;
|
||||||
}
|
}
|
||||||
@@ -53,7 +61,6 @@ public class DebugRequestWatchpointToggle extends DebugRequest {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see lua.debug.DebugRequest#toString()
|
* @see lua.debug.DebugRequest#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " functionName:" + getFunctionName() + " variableName:" + getVariableName();
|
return super.toString() + " functionName:" + getFunctionName() + " variableName:" + getVariableName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,17 +34,12 @@ public class DebugResponseCallgraph extends DebugResponseSimple {
|
|||||||
return this.stackFrames;
|
return this.stackFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see java.lang.Object#toString()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder buffer = new StringBuilder();
|
StringBuilder buffer = new StringBuilder();
|
||||||
if (this.stackFrames != null) {
|
for (int i = 0; stackFrames != null && i < stackFrames.length; i++) {
|
||||||
for (StackFrame frame : stackFrames) {
|
StackFrame frame = stackFrames[i];
|
||||||
buffer.append(frame.toString());
|
buffer.append(frame.toString());
|
||||||
buffer.append("\n");
|
buffer.append("\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ public class DebugResponseSimple implements DebugResponse, Serializable {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.valueOf(isSuccessful);
|
return String.valueOf(isSuccessful);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public class DebugResponseStack extends DebugResponseSimple {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder buffer = new StringBuilder();
|
StringBuilder buffer = new StringBuilder();
|
||||||
for (int i = 0; variables != null && i < variables.length; i++) {
|
for (int i = 0; variables != null && i < variables.length; i++) {
|
||||||
|
|||||||
@@ -41,13 +41,12 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
protected Map<String,Boolean> breakpoints = new HashMap<String,Boolean>();
|
protected Map breakpoints = new HashMap();
|
||||||
protected boolean exiting = false;
|
protected boolean exiting = false;
|
||||||
protected boolean suspended = false;
|
protected boolean suspended = false;
|
||||||
protected boolean stepping = false;
|
protected boolean stepping = false;
|
||||||
protected int lastline = -1;
|
protected int lastline = -1;
|
||||||
protected List<DebugEventListener> debugEventListeners
|
protected List debugEventListeners = new ArrayList();
|
||||||
= new ArrayList<DebugEventListener>();
|
|
||||||
|
|
||||||
public DebugStackState() {
|
public DebugStackState() {
|
||||||
}
|
}
|
||||||
@@ -70,9 +69,10 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyDebugEventListeners(DebugEvent event) {
|
protected void notifyDebugEventListeners(DebugEvent event) {
|
||||||
for (DebugEventListener listener : debugEventListeners) {
|
for (int i = 0; debugEventListeners != null && i < debugEventListeners.size(); i++) {
|
||||||
|
DebugEventListener listener = (DebugEventListener)debugEventListeners.get(i);
|
||||||
listener.notifyDebugEvent(event);
|
listener.notifyDebugEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFileLine(int cindex) {
|
private String getFileLine(int cindex) {
|
||||||
@@ -183,37 +183,38 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
|
|
||||||
public DebugResponse handleRequest(DebugRequest request) {
|
public DebugResponse handleRequest(DebugRequest request) {
|
||||||
DebugUtils.println("DebugStackState is handling request: " + request.toString());
|
DebugUtils.println("DebugStackState is handling request: " + request.toString());
|
||||||
switch (request.getType()) {
|
DebugRequestType requestType = request.getType();
|
||||||
case suspend:
|
if (DebugRequestType.suspend == requestType) {
|
||||||
suspend();
|
suspend();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
case resume:
|
} else if (DebugRequestType.resume == requestType) {
|
||||||
resume();
|
resume();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
case exit:
|
} else if (DebugRequestType.exit == requestType) {
|
||||||
exit();
|
exit();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
case lineBreakpointSet:
|
} else if (DebugRequestType.lineBreakpointSet == requestType) {
|
||||||
DebugRequestLineBreakpointToggle setBreakpointRequest
|
DebugRequestLineBreakpointToggle setBreakpointRequest
|
||||||
= (DebugRequestLineBreakpointToggle)request;
|
= (DebugRequestLineBreakpointToggle)request;
|
||||||
setBreakpoint(setBreakpointRequest.getSource(), setBreakpointRequest.getLineNumber());
|
setBreakpoint(setBreakpointRequest.getSource(), setBreakpointRequest.getLineNumber());
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
case lineBreakpointClear:
|
} else if (DebugRequestType.lineBreakpointClear == requestType) {
|
||||||
DebugRequestLineBreakpointToggle clearBreakpointRequest
|
DebugRequestLineBreakpointToggle clearBreakpointRequest
|
||||||
= (DebugRequestLineBreakpointToggle)request;
|
= (DebugRequestLineBreakpointToggle)request;
|
||||||
clearBreakpoint(clearBreakpointRequest.getSource(), clearBreakpointRequest.getLineNumber());
|
clearBreakpoint(clearBreakpointRequest.getSource(), clearBreakpointRequest.getLineNumber());
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
case callgraph:
|
} else if (DebugRequestType.callgraph == requestType) {
|
||||||
return new DebugResponseCallgraph(getCallgraph());
|
return new DebugResponseCallgraph(getCallgraph());
|
||||||
case stack:
|
} else if (DebugRequestType.stack == requestType) {
|
||||||
DebugRequestStack stackRequest = (DebugRequestStack) request;
|
DebugRequestStack stackRequest = (DebugRequestStack) request;
|
||||||
int index = stackRequest.getIndex();
|
int index = stackRequest.getIndex();
|
||||||
return new DebugResponseStack(getStack(index));
|
return new DebugResponseStack(getStack(index));
|
||||||
case step:
|
} else if (DebugRequestType.step == requestType) {
|
||||||
step();
|
step();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
}
|
}
|
||||||
throw new java.lang.IllegalArgumentException( "unkown request type: "+request.getType() );
|
|
||||||
|
throw new java.lang.IllegalArgumentException( "unkown request type: "+ request.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,9 +304,9 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
int top = callInfo.top < callInfo.base ? callInfo.base : callInfo.top;
|
int top = callInfo.top < callInfo.base ? callInfo.base : callInfo.top;
|
||||||
Proto prototype = callInfo.closure.p;
|
Proto prototype = callInfo.closure.p;
|
||||||
LocVars[] localVariables = prototype.locvars;
|
LocVars[] localVariables = prototype.locvars;
|
||||||
List<Variable> variables = new ArrayList<Variable>();
|
List variables = new ArrayList();
|
||||||
int localVariableCount = 0;
|
int localVariableCount = 0;
|
||||||
Set<String> variablesSeen = new HashSet<String>();
|
Set variablesSeen = new HashSet();
|
||||||
for (int i = 0; localVariables != null && i < localVariables.length && i <= top; i++) {
|
for (int i = 0; localVariables != null && i < localVariables.length && i <= top; i++) {
|
||||||
String varName = localVariables[i].varname.toString();
|
String varName = localVariables[i].varname.toString();
|
||||||
DebugUtils.print("\tVariable: " + varName);
|
DebugUtils.print("\tVariable: " + varName);
|
||||||
|
|||||||
@@ -29,10 +29,16 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
public class DebugSupport implements DebugEventListener {
|
public class DebugSupport implements DebugEventListener {
|
||||||
public enum State {
|
public static class State extends EnumType {
|
||||||
UNKNOWN,
|
private static final long serialVersionUID = 3657364516937093612L;
|
||||||
RUNNING,
|
|
||||||
STOPPED
|
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);
|
||||||
|
|
||||||
|
public State(String name, int ordinal) {
|
||||||
|
super(name, ordinal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DebugRequestListener listener;
|
protected DebugRequestListener listener;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import lua.io.LoadState;
|
|||||||
import lua.value.LString;
|
import lua.value.LString;
|
||||||
|
|
||||||
public class DebugUtils {
|
public class DebugUtils {
|
||||||
public static final boolean IS_DEBUG = false;
|
public static final boolean IS_DEBUG = true;
|
||||||
|
|
||||||
public static void println(String message) {
|
public static void println(String message) {
|
||||||
if (IS_DEBUG) {
|
if (IS_DEBUG) {
|
||||||
|
|||||||
63
src/main/java/lua/debug/EnumType.java
Normal file
63
src/main/java/lua/debug/EnumType.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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.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;
|
||||||
|
|
||||||
|
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() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean equals(Object other) {
|
||||||
|
return (this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int hashCode() {
|
||||||
|
return System.identityHashCode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String name() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int ordinal() {
|
||||||
|
return this.ordinal;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -70,7 +70,6 @@ public class StackFrame implements Serializable {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getSource() + ":" + getLineNumber();
|
return getSource() + ":" + getLineNumber();
|
||||||
}
|
}
|
||||||
|
|||||||
305
src/main/java/lua/debug/StandardLuaJVM.java
Normal file
305
src/main/java/lua/debug/StandardLuaJVM.java
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import lua.GlobalState;
|
||||||
|
import lua.StackState;
|
||||||
|
import lua.addon.luacompat.LuaCompat;
|
||||||
|
import lua.addon.luajava.LuaJava;
|
||||||
|
import lua.io.Closure;
|
||||||
|
import lua.io.LoadState;
|
||||||
|
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();
|
||||||
|
protected boolean isDebugMode = false;
|
||||||
|
protected DebugSupport debugSupport;
|
||||||
|
protected int requestPort;
|
||||||
|
protected int eventPort;
|
||||||
|
protected String script;
|
||||||
|
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 void printUsage() {
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
formatter.printHelp("java StandardLuaJVM", options);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void parse(String[] args) throws ParseException {
|
||||||
|
CommandLineParser parser = new GnuParser();
|
||||||
|
try {
|
||||||
|
CommandLine line = parser.parse(options, args);
|
||||||
|
if (line.hasOption("debug")) {
|
||||||
|
this.isDebugMode = true;
|
||||||
|
String[] ports = line.getOptionValues("debug");
|
||||||
|
|
||||||
|
this.requestPort = Integer.parseInt(ports[0]);
|
||||||
|
if (this.requestPort <= 0) {
|
||||||
|
throw new ParseException("Invalid request port: it must be greater than zero.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventPort = Integer.parseInt(ports[1]);
|
||||||
|
if (this.eventPort <= 0) {
|
||||||
|
throw new ParseException("Invalid event port: it must be greater than zero.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.requestPort == this.eventPort) {
|
||||||
|
throw new ParseException("Invalid ports: request port and event port must be different");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.hasOption("file")) {
|
||||||
|
String[] fileArgs = line.getOptionValues("file");
|
||||||
|
this.script = URLDecoder.decode(fileArgs[0], "UTF-8");
|
||||||
|
DebugUtils.println("Lua script to run: " + this.script);
|
||||||
|
this.scriptArgs = new String[fileArgs.length - 1];
|
||||||
|
for (int i = 1; i < fileArgs.length; i++) {
|
||||||
|
this.scriptArgs[i-1] = URLDecoder.decode(fileArgs[i], "UTF-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(NumberFormatException e) {
|
||||||
|
throw new ParseException("Invalid port number: " + e.getMessage());
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new ParseException("Malformed program argument strings: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isDebug() {
|
||||||
|
return this.isDebugMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getRequestPort() {
|
||||||
|
return this.requestPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getEventPort() {
|
||||||
|
return this.eventPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getScript() {
|
||||||
|
return this.script;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean hasScriptArgs() {
|
||||||
|
return (this.scriptArgs != null && this.scriptArgs.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String[] getScriptArgs() {
|
||||||
|
return this.scriptArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() throws IOException {
|
||||||
|
if (isDebug()) {
|
||||||
|
doDebug();
|
||||||
|
} else {
|
||||||
|
doRun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init() {
|
||||||
|
//Reset the _G table
|
||||||
|
GlobalState.resetGlobals();
|
||||||
|
|
||||||
|
// add LuaJava bindings
|
||||||
|
LuaJava.install();
|
||||||
|
|
||||||
|
// add LuaCompat bindings
|
||||||
|
LuaCompat.install();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doRun() throws IOException {
|
||||||
|
init();
|
||||||
|
|
||||||
|
// new lua state
|
||||||
|
state = new StackState();
|
||||||
|
|
||||||
|
// convert args to lua
|
||||||
|
int numOfScriptArgs = getScriptArgs().length;
|
||||||
|
LValue[] vargs = new LValue[numOfScriptArgs];
|
||||||
|
for (int i = 0; i < numOfScriptArgs; i++) {
|
||||||
|
vargs[i] = new LString(getScriptArgs()[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the Lua file
|
||||||
|
DebugUtils.println("loading Lua script '" + getScript() + "'");
|
||||||
|
InputStream is = new FileInputStream(new File(getScript()));
|
||||||
|
Proto p = LoadState.undump(state, is, getScript());
|
||||||
|
|
||||||
|
// create closure and execute
|
||||||
|
Closure c = new Closure(state, p);
|
||||||
|
state.doCall(c, vargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doDebug() throws IOException {
|
||||||
|
DebugUtils.println("start debugging...");
|
||||||
|
this.debugSupport = new DebugSupport(this, getRequestPort(), getEventPort());
|
||||||
|
DebugUtils.println("created client request socket connection...");
|
||||||
|
debugSupport.start();
|
||||||
|
|
||||||
|
DebugUtils.println("setting up LuaJava and debug stack state...");
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
// new lua state
|
||||||
|
state = new DebugStackState();
|
||||||
|
getDebugState().addDebugEventListener(debugSupport);
|
||||||
|
|
||||||
|
// load the Lua file
|
||||||
|
DebugUtils.println("loading Lua script '" + getScript() + "'");
|
||||||
|
InputStream is = new FileInputStream(new File(getScript()));
|
||||||
|
Proto p = LoadState.undump(state, is, getScript());
|
||||||
|
|
||||||
|
// create closure and execute
|
||||||
|
final Closure c = new Closure(state, p);
|
||||||
|
getDebugState().suspend();
|
||||||
|
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
int numOfScriptArgs = getScriptArgs().length;
|
||||||
|
LValue[] vargs = new LValue[numOfScriptArgs];
|
||||||
|
for (int i = 0; i < numOfScriptArgs; i++) {
|
||||||
|
vargs[i] = new LString(getScriptArgs()[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDebugState().doCall(c, vargs);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
debugSupport.fireEvent(new DebugEvent(DebugEventType.started));
|
||||||
|
}
|
||||||
|
|
||||||
|
private DebugStackState getDebugState() {
|
||||||
|
return (DebugStackState)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see lua.debug.DebugRequestListener#handleRequest(java.lang.String)
|
||||||
|
*/
|
||||||
|
public DebugResponse handleRequest(DebugRequest request) {
|
||||||
|
if (!isDebug()) {
|
||||||
|
throw new UnsupportedOperationException("Must be in debug mode to handle the debug requests");
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugUtils.println("handling request: " + request.toString());
|
||||||
|
DebugRequestType requestType = request.getType();
|
||||||
|
if (DebugRequestType.suspend == requestType) {
|
||||||
|
DebugResponse status = getDebugState().handleRequest(request);
|
||||||
|
DebugEvent event = new DebugEvent(DebugEventType.suspendedByClient);
|
||||||
|
debugSupport.fireEvent(event);
|
||||||
|
return status;
|
||||||
|
} else if (DebugRequestType.resume == requestType) {
|
||||||
|
DebugResponse status = getDebugState().handleRequest(request);
|
||||||
|
DebugEvent event = new DebugEvent(DebugEventType.resumedByClient);
|
||||||
|
debugSupport.fireEvent(event);
|
||||||
|
return status;
|
||||||
|
} else if (DebugRequestType.exit == requestType) {
|
||||||
|
stop();
|
||||||
|
return DebugResponseSimple.SUCCESS;
|
||||||
|
} else {
|
||||||
|
return getDebugState().handleRequest(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void stop() {
|
||||||
|
DebugUtils.println("exit LuaJ VM...");
|
||||||
|
if (this.debugSupport != null) {
|
||||||
|
DebugEvent event = new DebugEvent(DebugEventType.terminated);
|
||||||
|
debugSupport.fireEvent(event);
|
||||||
|
Timer timer = new Timer("DebugServerDeathThread");
|
||||||
|
timer.schedule(new TimerTask() {
|
||||||
|
public void run() {
|
||||||
|
debugSupport.stop();
|
||||||
|
debugSupport = null;
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
getDebugState().exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the command line arguments and executes/debugs the lua program.
|
||||||
|
* @param args -- command line arguments:
|
||||||
|
* [-debug requestPort eventPort] -file luaProgram args
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
StandardLuaJVM vm = new StandardLuaJVM();
|
||||||
|
|
||||||
|
try {
|
||||||
|
vm.parse(args);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
DebugUtils.println(e.getMessage());
|
||||||
|
vm.printUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
vm.run();
|
||||||
|
} catch (IOException e) {
|
||||||
|
//TODO: handle the error
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,10 +56,6 @@ public class Variable implements Serializable {
|
|||||||
return this.index;
|
return this.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see java.lang.Object#toString()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "index: " + getIndex() + " name:" + getName() + " type: " + Lua.TYPE_NAMES[getType()] + " value:" + getValue();
|
return "index: " + getIndex() + " name:" + getName() + " type: " + Lua.TYPE_NAMES[getType()] + " value:" + getValue();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,10 +24,9 @@ package lua.debug;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import lua.LuaJVM;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanity test for LuaJVM.
|
* Sanity test for StandardLuaJVM.
|
||||||
*/
|
*/
|
||||||
public class LuaJVMTest extends TestCase {
|
public class LuaJVMTest extends TestCase {
|
||||||
protected void doTestRun(String testName) {
|
protected void doTestRun(String testName) {
|
||||||
@@ -37,7 +36,7 @@ public class LuaJVMTest extends TestCase {
|
|||||||
if (filePath != null) {
|
if (filePath != null) {
|
||||||
args[1] = filePath.getPath();
|
args[1] = filePath.getPath();
|
||||||
try {
|
try {
|
||||||
LuaJVM.main(args);
|
StandardLuaJVM.main(args);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("Test " + testName + " failed due to " + e.getMessage());
|
fail("Test " + testName + " failed due to " + e.getMessage());
|
||||||
@@ -70,7 +69,8 @@ public class LuaJVMTest extends TestCase {
|
|||||||
//"strlib"
|
//"strlib"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (String test : tests) {
|
for (int i = 0; i < tests.length; i++) {
|
||||||
|
String test = tests[i];
|
||||||
System.out.println("==> running test: " + test + ".lua");
|
System.out.println("==> running test: " + test + ".lua");
|
||||||
doTestRun(test + ".lua");
|
doTestRun(test + ".lua");
|
||||||
System.out.println("==> running test: " + test + ".luac");
|
System.out.println("==> running test: " + test + ".luac");
|
||||||
|
|||||||
Reference in New Issue
Block a user