1. changed to use LuaErrorException and removed VMException
2. refactored the debug network communication layer
This commit is contained in:
@@ -56,6 +56,8 @@
|
||||
<src path="src/debug" />
|
||||
<exclude name="org/luaj/debug/j2se/**"/>
|
||||
<exclude name="org/luaj/debug/j2me/**"/>
|
||||
<exclude name="org/luaj/debug/net/j2se/**"/>
|
||||
<exclude name="org/luaj/debug/net/j2me/**"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
@@ -66,6 +68,7 @@
|
||||
<src path="src/debug" />
|
||||
<src path="src/j2se" />
|
||||
<include name="org/luaj/debug/j2se/**"/>
|
||||
<include name="org/luaj/debug/net/j2se/**"/>
|
||||
<include name="org/luaj/lib/j2se/**"/>
|
||||
</javac>
|
||||
</target>
|
||||
@@ -76,6 +79,7 @@
|
||||
bootclasspathref="wtk-libs" classpath="build/core/classes">
|
||||
<src path="src/debug" />
|
||||
<exclude name="org/luaj/debug/j2se/**"/>
|
||||
<exclude name="org/luaj/debug/net/j2se/**"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
|
||||
@@ -937,6 +937,24 @@ public class LuaState extends Lua {
|
||||
return pc;
|
||||
}
|
||||
|
||||
protected String getSourceFileName(LString source) {
|
||||
String sourceStr = LoadState.getSourceName(source.toJavaString());
|
||||
return getSourceFileName(sourceStr);
|
||||
}
|
||||
|
||||
protected String getSourceFileName(String sourceStr) {
|
||||
if (!LoadState.SOURCE_BINARY_STRING.equals(sourceStr)) {
|
||||
sourceStr = sourceStr.replace('\\', '/');
|
||||
}
|
||||
|
||||
int index = sourceStr.lastIndexOf('/');
|
||||
if (index != -1) {
|
||||
sourceStr = sourceStr.substring(index + 1);
|
||||
}
|
||||
|
||||
return sourceStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file line number info for a particular call frame.
|
||||
* @param cindex
|
||||
@@ -949,7 +967,7 @@ public class LuaState extends Lua {
|
||||
CallInfo call = this.calls[cindex];
|
||||
LPrototype p = call.closure.p;
|
||||
if (p != null && p.source != null)
|
||||
source = p.source.toJavaString();
|
||||
source = getSourceFileName(p.source);
|
||||
int pc = getCurrentPc(call);
|
||||
if (p.lineinfo != null && p.lineinfo.length > pc)
|
||||
line = ":" + String.valueOf(p.lineinfo[pc]);
|
||||
@@ -957,6 +975,16 @@ public class LuaState extends Lua {
|
||||
return source + line;
|
||||
}
|
||||
|
||||
public String getStackTrace() {
|
||||
StringBuffer buffer = new StringBuffer("Stack Trace:\n");
|
||||
for (int i = cc; i >= 0; i--) {
|
||||
buffer.append(" ");
|
||||
buffer.append(getFileLine(i));
|
||||
buffer.append("\n");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Raises an error. The message is pushed onto the stack and used as the error message.
|
||||
* It also adds at the beginning of the message the file name and the line number where
|
||||
|
||||
@@ -23,8 +23,6 @@ package org.luaj.debug;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.luaj.compiler.LexState;
|
||||
@@ -32,7 +30,9 @@ import org.luaj.debug.event.DebugEvent;
|
||||
import org.luaj.debug.event.DebugEventBreakpoint;
|
||||
import org.luaj.debug.event.DebugEventError;
|
||||
import org.luaj.debug.event.DebugEventType;
|
||||
import org.luaj.debug.net.DebugSupport;
|
||||
import org.luaj.debug.request.DebugRequest;
|
||||
import org.luaj.debug.request.DebugRequestDisconnect;
|
||||
import org.luaj.debug.request.DebugRequestLineBreakpointToggle;
|
||||
import org.luaj.debug.request.DebugRequestListener;
|
||||
import org.luaj.debug.request.DebugRequestStack;
|
||||
@@ -47,6 +47,7 @@ import org.luaj.vm.LTable;
|
||||
import org.luaj.vm.LValue;
|
||||
import org.luaj.vm.LocVars;
|
||||
import org.luaj.vm.Lua;
|
||||
import org.luaj.vm.LuaErrorException;
|
||||
import org.luaj.vm.LuaState;
|
||||
|
||||
|
||||
@@ -69,6 +70,7 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
protected int lastline = -1;
|
||||
protected String lastSource;
|
||||
protected DebugSupport debugSupport;
|
||||
protected LuaErrorException lastError;
|
||||
|
||||
public DebugLuaState() {}
|
||||
|
||||
@@ -103,23 +105,29 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
super.exec();
|
||||
} catch (AbortException e) {
|
||||
// ignored. Client aborts the debugging session.
|
||||
} catch (Exception e) {
|
||||
// let VM exceptions be processed if the debugger is not attached
|
||||
// the same as the base class to minimize differences
|
||||
// between the debug and non-debug behavior
|
||||
VMException lastException = new VMException(e);
|
||||
if (debugSupport != null) {
|
||||
debugSupport.notifyDebugEvent(new DebugEventError(e.getMessage()));
|
||||
suspend();
|
||||
synchronized (this) {
|
||||
while (suspended) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e1) {}
|
||||
}
|
||||
}
|
||||
} catch (LuaErrorException e) {
|
||||
// give debug client a chance to see the error
|
||||
if (e != lastError) {
|
||||
lastError = e;
|
||||
debugErrorHook(e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void debugErrorHook(Exception e) {
|
||||
if (debugSupport != null) {
|
||||
String msg = getFileLine(cc) + ": " + e.getMessage();
|
||||
String trace = getStackTrace();
|
||||
debugSupport.notifyDebugEvent(new DebugEventError(msg, trace));
|
||||
synchronized (this) {
|
||||
suspend();
|
||||
while (suspended) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException ex) {}
|
||||
}
|
||||
}
|
||||
throw lastException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,16 +143,16 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
if (exiting) {
|
||||
throw new AbortException("aborted by debug client");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if (DebugUtils.IS_DEBUG) {
|
||||
DebugUtils.println("entered debugHook on pc=" + pc + "...Line: " + getFileLine(cc));
|
||||
if (TRACE) {
|
||||
System.out.println("entered debugHook on pc=" + pc + "...Line: " + getFileLine(cc));
|
||||
for (int j = 0; j <= cc; j++) {
|
||||
DebugUtils.println("calls[" + j + "]: base=" + calls[j].base + ", top=" + calls[j].top + " ,pc=" + calls[j].pc);
|
||||
System.out.println("calls[" + j + "]: base=" + calls[j].base + ", top=" + calls[j].top + " , pc=" + calls[j].pc);
|
||||
dumpStack(j);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
*/
|
||||
synchronized (this) {
|
||||
while (bSuspendOnStart) {
|
||||
try {
|
||||
@@ -160,13 +168,13 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
// if we are not stepping, we would keep going if the line doesn't
|
||||
// change
|
||||
int line = getLineNumber(currentCallInfo);
|
||||
String source = DebugUtils.getSourceFileName(currentProto.source);
|
||||
String source = getSourceFileName(currentProto.source);
|
||||
if (!isStepping() && lastline == line && source.equals(lastSource)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("debugHook - executing line: " + line);
|
||||
if (TRACE)
|
||||
System.out.println("debugHook - executing line: " + line);
|
||||
|
||||
int i = currentProto.code[pc];
|
||||
int opCode = LuaState.GET_OPCODE(i);
|
||||
@@ -195,17 +203,18 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
|
||||
// check for a break point if we aren't suspended already
|
||||
if (!suspended && lastline != line) {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("Source: " + currentProto.source);
|
||||
String fileName = DebugUtils.getSourceFileName(source);
|
||||
if (TRACE)
|
||||
System.out.println("Source: " + currentProto.source);
|
||||
String fileName = getSourceFileName(source);
|
||||
String breakpointKey = constructBreakpointKey(fileName, line);
|
||||
if (breakpoints.containsKey(breakpointKey)) {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("hitting breakpoint "
|
||||
if (TRACE)
|
||||
System.out.println("hitting breakpoint "
|
||||
+ constructBreakpointKey(fileName, line));
|
||||
|
||||
debugSupport.notifyDebugEvent(new DebugEventBreakpoint(
|
||||
fileName, line));
|
||||
if (debugSupport != null) {
|
||||
debugSupport.notifyDebugEvent(
|
||||
new DebugEventBreakpoint(fileName, line));
|
||||
}
|
||||
suspended = true;
|
||||
}
|
||||
}
|
||||
@@ -218,8 +227,6 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
while (suspended && !exiting) {
|
||||
try {
|
||||
this.wait();
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("resuming execution...");
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
@@ -232,16 +239,20 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
}
|
||||
|
||||
private void cancelStepping() {
|
||||
debugSupport.notifyDebugEvent(new DebugEvent(
|
||||
DebugEventType.resumedOnSteppingEnd));
|
||||
if (debugSupport != null) {
|
||||
debugSupport.notifyDebugEvent(
|
||||
new DebugEvent(DebugEventType.resumedOnSteppingEnd));
|
||||
}
|
||||
stepping = STEP_NONE;
|
||||
steppingFrame = -1;
|
||||
shouldPauseForStepping = false;
|
||||
}
|
||||
|
||||
private void suspendOnStepping() {
|
||||
debugSupport.notifyDebugEvent(new DebugEvent(
|
||||
DebugEventType.suspendedOnStepping));
|
||||
if (debugSupport != null) {
|
||||
debugSupport.notifyDebugEvent(new DebugEvent(
|
||||
DebugEventType.suspendedOnStepping));
|
||||
}
|
||||
suspended = true;
|
||||
steppingFrame = -1;
|
||||
}
|
||||
@@ -266,11 +277,11 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
public void handleRequest(DebugRequest request) {
|
||||
if (this.debugSupport == null) {
|
||||
throw new IllegalStateException(
|
||||
"DebugStackState is not equiped with DebugSupport.");
|
||||
"DebugSupport must be defined.");
|
||||
}
|
||||
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("DebugStackState is handling request: "
|
||||
if (TRACE)
|
||||
System.out.println("DebugStackState is handling request: "
|
||||
+ request.toString());
|
||||
|
||||
DebugRequestType requestType = request.getType();
|
||||
@@ -281,7 +292,12 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
} else if (DebugRequestType.exit == requestType) {
|
||||
stop();
|
||||
} else if (DebugRequestType.disconnect == requestType) {
|
||||
disconnect();
|
||||
DebugRequestDisconnect disconnectRequest
|
||||
= (DebugRequestDisconnect) request;
|
||||
int connectionId = disconnectRequest.getSessionId();
|
||||
disconnect(connectionId);
|
||||
} else if (DebugRequestType.reset == requestType) {
|
||||
reset();
|
||||
} else if (DebugRequestType.suspend == requestType) {
|
||||
suspend();
|
||||
DebugEvent event = new DebugEvent(DebugEventType.suspendedByClient);
|
||||
@@ -379,35 +395,29 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
public void stop() {
|
||||
if (this.debugSupport == null) {
|
||||
throw new IllegalStateException(
|
||||
"DebugStackState is not equiped with DebugSupport.");
|
||||
"DebugSupport must be defined.");
|
||||
}
|
||||
|
||||
DebugEvent event = new DebugEvent(DebugEventType.terminated);
|
||||
debugSupport.notifyDebugEvent(event);
|
||||
|
||||
new Timer().schedule(new TimerTask() {
|
||||
public void run() {
|
||||
debugSupport.stop();
|
||||
debugSupport = null;
|
||||
}
|
||||
}, 500);
|
||||
|
||||
exit();
|
||||
debugSupport.stop();
|
||||
debugSupport = null;
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
public void disconnect(int connectionId) {
|
||||
if (this.debugSupport == null) {
|
||||
throw new IllegalStateException(
|
||||
"DebugStackState is not equiped with DebugSupport.");
|
||||
"DebugSupport must be defined.");
|
||||
}
|
||||
|
||||
reset();
|
||||
debugSupport.disconnect();
|
||||
DebugEvent event = new DebugEvent(DebugEventType.disconnected);
|
||||
debugSupport.notifyDebugEvent(event);
|
||||
debugSupport.notifyDebugEvent(event);
|
||||
debugSupport.disconnect(connectionId);
|
||||
}
|
||||
|
||||
protected void reset() {
|
||||
public void reset() {
|
||||
synchronized (this) {
|
||||
this.breakpoints.clear();
|
||||
if (this.suspended) {
|
||||
@@ -432,12 +442,9 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
* @param N -- the line to set the breakpoint at
|
||||
*/
|
||||
public void setBreakpoint(String source, int lineNumber) {
|
||||
String fileName = DebugUtils.getSourceFileName(source);
|
||||
String fileName = getSourceFileName(source);
|
||||
String breakpointKey = constructBreakpointKey(fileName, lineNumber);
|
||||
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("adding breakpoint " + breakpointKey);
|
||||
|
||||
breakpoints.put(breakpointKey, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@@ -449,12 +456,9 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
* clear breakpoint at line lineNumber of source source
|
||||
*/
|
||||
public void clearBreakpoint(String source, int lineNumber) {
|
||||
String fileName = DebugUtils.getSourceFileName(source);
|
||||
String fileName = getSourceFileName(source);
|
||||
String breakpointKey = constructBreakpointKey(fileName, lineNumber);
|
||||
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("removing breakpoint " + breakpointKey);
|
||||
|
||||
breakpoints.remove(breakpointKey);
|
||||
}
|
||||
|
||||
@@ -471,7 +475,8 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
StackFrame[] frames = new StackFrame[n + 1];
|
||||
for (int i = 0; i <= n; i++) {
|
||||
CallInfo ci = calls[i];
|
||||
frames[i] = new StackFrame(ci, getLineNumber(ci));
|
||||
String src = getSourceFileName(ci.closure.p.source);
|
||||
frames[i] = new StackFrame(src, getLineNumber(ci));
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
@@ -552,21 +557,21 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
CallInfo callInfo = calls[index];
|
||||
LPrototype prototype = callInfo.closure.p;
|
||||
LocVars[] localVariables = prototype.locvars;
|
||||
DebugUtils.println("Stack Frame: " + index + " [" + base + "," + top + "], # of localvars: " + localVariables.length + ", pc=" + callInfo.pc);
|
||||
System.out.println("Stack Frame: " + index + " [" + base + "," + top + "], # of localvars: " + localVariables.length + ", pc=" + callInfo.pc);
|
||||
|
||||
int pc = getCurrentPc(callInfo);
|
||||
for (int i = 0; i < localVariables.length; i++) {
|
||||
if (!isActiveVariable(pc, localVariables[i])) {
|
||||
continue;
|
||||
} else {
|
||||
DebugUtils.println("localvars["+i+"]=" + localVariables[i].varname.toJavaString());
|
||||
System.out.println("localvars["+i+"]=" + localVariables[i].varname.toJavaString());
|
||||
}
|
||||
}
|
||||
|
||||
int base = callInfo.base;
|
||||
int top = callInfo.top < callInfo.base ? callInfo.base+1 : callInfo.top;
|
||||
for (int i = base; i < top; i++){
|
||||
DebugUtils.println("stack[" + i + "]=" + stack[i]);
|
||||
System.out.println("stack[" + i + "]=" + stack[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,7 +622,7 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
int base = callInfo.base;
|
||||
int top = callInfo.top < callInfo.base ? callInfo.base+1 : callInfo.top;
|
||||
|
||||
if (DebugUtils.IS_DEBUG) {
|
||||
if (TRACE) {
|
||||
dumpStack(index);
|
||||
}
|
||||
|
||||
@@ -630,9 +635,9 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(DebugUtils.IS_DEBUG) {
|
||||
DebugUtils.print("\tVariable: " + varName);
|
||||
DebugUtils.print("\tValue: " + stack[i]);
|
||||
if(TRACE) {
|
||||
System.out.print("\tVariable: " + varName);
|
||||
System.out.print("\tValue: " + stack[i]);
|
||||
}
|
||||
if (!variablesSeen.contains(varName) &&
|
||||
!LexState.isReservedKeyword(varName)) {
|
||||
@@ -640,11 +645,11 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
LValue value = stack[i];
|
||||
if (value != null) {
|
||||
int type = value.luaGetType();
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.print("\tType: " + Lua.TYPE_NAMES[type]);
|
||||
if (TRACE)
|
||||
System.out.print("\tType: " + Lua.TYPE_NAMES[type]);
|
||||
if (type == Lua.LUA_TTABLE) {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.print(" (selected)");
|
||||
if (TRACE)
|
||||
System.out.print(" (selected)");
|
||||
variables.addElement(
|
||||
new TableVariable(selectedVariableCount++,
|
||||
varName,
|
||||
@@ -653,8 +658,8 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
} else if (type == LUA_TTHREAD) {
|
||||
// coroutines
|
||||
} else if (type != LUA_TFUNCTION) {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.print(" (selected)");
|
||||
if (TRACE)
|
||||
System.out.print(" (selected)");
|
||||
variables.addElement(
|
||||
new Variable(selectedVariableCount++,
|
||||
varName,
|
||||
@@ -664,8 +669,8 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
}
|
||||
}
|
||||
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("");
|
||||
if (TRACE)
|
||||
System.out.print("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,9 +679,6 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
*/
|
||||
public void stepOver() {
|
||||
synchronized (this) {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("stepOver on cc=" + cc + "...");
|
||||
|
||||
suspended = false;
|
||||
stepping = STEP_OVER;
|
||||
steppingFrame = cc;
|
||||
@@ -700,9 +702,6 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
||||
*/
|
||||
public void stepReturn() {
|
||||
synchronized (this) {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("stepReturn on cc=" + cc + "...");
|
||||
|
||||
suspended = false;
|
||||
stepping = STEP_RETURN;
|
||||
steppingFrame = cc;
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
package org.luaj.debug;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.luaj.debug.event.DebugEvent;
|
||||
import org.luaj.debug.event.DebugEventListener;
|
||||
import org.luaj.debug.request.DebugRequest;
|
||||
import org.luaj.debug.request.DebugRequestListener;
|
||||
|
||||
/**
|
||||
* DebugSupport provides the network communication support for the debugger and
|
||||
* debugee.
|
||||
*/
|
||||
public abstract class DebugSupport implements DebugRequestListener, DebugEventListener {
|
||||
protected static final int UNKNOWN = 0;
|
||||
protected static final int RUNNING = 1;
|
||||
protected static final int STOPPED = 2;
|
||||
|
||||
protected DebugLuaState vm;
|
||||
protected int debugPort;
|
||||
protected ClientConnectionTask clientConnectionTask;
|
||||
protected int state = UNKNOWN;
|
||||
protected DataInputStream requestReader;
|
||||
protected DataOutputStream eventWriter;
|
||||
|
||||
class ClientConnectionTask implements Runnable {
|
||||
protected boolean bDisconnected = false;
|
||||
|
||||
public synchronized void disconnect () {
|
||||
this.bDisconnected = true;
|
||||
}
|
||||
|
||||
public synchronized boolean isDisconnected() {
|
||||
return this.bDisconnected;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
acceptClientConnection();
|
||||
|
||||
while (getState() != STOPPED && !isDisconnected()) {
|
||||
loopForRequest();
|
||||
}
|
||||
|
||||
if (isDisconnected()) {
|
||||
releaseClientConnection();
|
||||
} else {
|
||||
dispose();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
// the connected debugging client aborted abnormally
|
||||
// discard the current connection and start new
|
||||
vm.reset();
|
||||
releaseClientConnection();
|
||||
newClientConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DebugSupport(int debugPort) throws IOException {
|
||||
if (debugPort == -1) {
|
||||
throw new IllegalArgumentException("requestPort is invalid");
|
||||
}
|
||||
this.debugPort = debugPort;
|
||||
}
|
||||
|
||||
public void setDebugStackState(DebugLuaState vm) {
|
||||
this.vm = vm;
|
||||
}
|
||||
|
||||
protected abstract void releaseClientConnection();
|
||||
|
||||
protected void dispose() {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("releasing the networkig resources...");
|
||||
|
||||
if (requestReader != null) {
|
||||
try {
|
||||
requestReader.close();
|
||||
requestReader = null;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (eventWriter != null) {
|
||||
try {
|
||||
eventWriter.close();
|
||||
eventWriter = null;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean isStarted() {
|
||||
return (state == RUNNING || state == STOPPED);
|
||||
}
|
||||
|
||||
public synchronized void start() throws IOException {
|
||||
if (this.vm == null) {
|
||||
throw new IllegalStateException(
|
||||
"DebugLuaState is not set. Please call setDebugStackState first.");
|
||||
}
|
||||
|
||||
newClientConnection();
|
||||
this.state = RUNNING;
|
||||
|
||||
System.out.println("LuaJ debug server is listening on port: " + debugPort);
|
||||
}
|
||||
|
||||
private void newClientConnection() {
|
||||
this.clientConnectionTask = new ClientConnectionTask();
|
||||
new Thread(clientConnectionTask).start();
|
||||
}
|
||||
|
||||
protected synchronized int getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public synchronized void stop() {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("stopping the debug support...");
|
||||
this.state = STOPPED;
|
||||
}
|
||||
|
||||
public abstract void acceptClientConnection() throws IOException;
|
||||
|
||||
protected void loopForRequest() throws IOException {
|
||||
byte[] data = null;
|
||||
int size = requestReader.readInt();
|
||||
data = new byte[size];
|
||||
requestReader.readFully(data);
|
||||
|
||||
DebugRequest request = (DebugRequest) SerializationHelper
|
||||
.deserialize(data);
|
||||
if (DebugUtils.IS_DEBUG) {
|
||||
DebugUtils.println("SERVER receives request: " + request.toString());
|
||||
}
|
||||
|
||||
handleRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method provides the second communication channel with the debugging
|
||||
* client. The server can send events via this channel to notify the client
|
||||
* about debug events (see below) asynchronously.
|
||||
*
|
||||
* The following events can be fired: 1. started -- the vm is started and
|
||||
* ready to receive debugging requests (guaranteed to be the first event
|
||||
* sent) 2. terminated -- the vm is terminated (guaranteed to be the last
|
||||
* event sent) 3. suspended client|step|breakpoint N -- the vm is suspended
|
||||
* by client, due to a stepping request or the breakpoint at line N is hit
|
||||
* 4. resumed client|step -- the vm resumes execution by client or step
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
protected synchronized void sendEvent(DebugEvent event) {
|
||||
if (DebugUtils.IS_DEBUG)
|
||||
DebugUtils.println("SERVER sending event: " + event.toString());
|
||||
|
||||
if (eventWriter == null) return;
|
||||
|
||||
try {
|
||||
byte[] data = SerializationHelper.serialize(event);
|
||||
eventWriter.writeInt(data.length);
|
||||
eventWriter.write(data);
|
||||
eventWriter.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.luaj.debug.event.DebugEventListener#notifyDebugEvent(org.luaj.debug.event.DebugEvent)
|
||||
*/
|
||||
public void notifyDebugEvent(DebugEvent event) {
|
||||
sendEvent(event);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.luaj.debug.request.DebugRequestListener#handleRequest(org.luaj.debug.request.DebugRequest)
|
||||
*/
|
||||
public void handleRequest(DebugRequest request) {
|
||||
if (DebugUtils.IS_DEBUG) {
|
||||
DebugUtils.println("SERVER handling request: " + request.toString());
|
||||
}
|
||||
|
||||
vm.handleRequest(request);
|
||||
}
|
||||
|
||||
public synchronized void disconnect() {
|
||||
clientConnectionTask.disconnect();
|
||||
clientConnectionTask = null;
|
||||
|
||||
newClientConnection();
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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 org.luaj.debug;
|
||||
|
||||
import org.luaj.vm.LString;
|
||||
import org.luaj.vm.LoadState;
|
||||
|
||||
|
||||
public class DebugUtils {
|
||||
public static final boolean IS_DEBUG = (null != System.getProperty("TRACE"));
|
||||
|
||||
public static void println(String message) {
|
||||
if (IS_DEBUG) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void print(String message) {
|
||||
if (IS_DEBUG) {
|
||||
System.out.print(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getSourceFileName(LString source) {
|
||||
String sourceStr = LoadState.getSourceName(source.toJavaString());
|
||||
return getSourceFileName(sourceStr);
|
||||
}
|
||||
|
||||
public static String getSourceFileName(String sourceStr) {
|
||||
if (!LoadState.SOURCE_BINARY_STRING.equals(sourceStr)) {
|
||||
sourceStr = sourceStr.replace('\\', '/');
|
||||
}
|
||||
|
||||
int index = sourceStr.lastIndexOf('/');
|
||||
if (index != -1) {
|
||||
sourceStr = sourceStr.substring(index + 1);
|
||||
}
|
||||
|
||||
return sourceStr;
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,12 @@ import org.luaj.debug.event.DebugEventBreakpoint;
|
||||
import org.luaj.debug.event.DebugEventError;
|
||||
import org.luaj.debug.event.DebugEventType;
|
||||
import org.luaj.debug.request.DebugRequest;
|
||||
import org.luaj.debug.request.DebugRequestDisconnect;
|
||||
import org.luaj.debug.request.DebugRequestLineBreakpointToggle;
|
||||
import org.luaj.debug.request.DebugRequestStack;
|
||||
import org.luaj.debug.request.DebugRequestType;
|
||||
import org.luaj.debug.response.DebugResponseCallgraph;
|
||||
import org.luaj.debug.response.DebugResponseSession;
|
||||
import org.luaj.debug.response.DebugResponseStack;
|
||||
import org.luaj.debug.response.DebugResponseVariables;
|
||||
|
||||
@@ -49,18 +51,20 @@ public class SerializationHelper {
|
||||
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_DebugResponseVariables = 4;
|
||||
static final int SERIAL_TYPE_DebugResponseStack = 5;
|
||||
static final int SERIAL_TYPE_StackFrame = 6;
|
||||
static final int SERIAL_TYPE_DebugRequestType = 7;
|
||||
static final int SERIAL_TYPE_DebugRequest = 8;
|
||||
static final int SERIAL_TYPE_DebugRequestStack = 9;
|
||||
static final int SERIAL_TYPE_DebugRequestLineBreakpointToggle = 10;
|
||||
static final int SERIAL_TYPE_DebugEventType = 11;
|
||||
static final int SERIAL_TYPE_DebugEvent = 12;
|
||||
static final int SERIAL_TYPE_DebugEventBreakpoint = 13;
|
||||
static final int SERIAL_TYPE_DebugEventError = 14;
|
||||
static final int SERIAL_TYPE_StackFrame = 3;
|
||||
static final int SERIAL_TYPE_DebugRequestType = 4;
|
||||
static final int SERIAL_TYPE_DebugRequest = 5;
|
||||
static final int SERIAL_TYPE_DebugRequestStack = 6;
|
||||
static final int SERIAL_TYPE_DebugRequestLineBreakpointToggle = 7;
|
||||
static final int SERIAL_TYPE_DebugRequestDisconnect = 8;
|
||||
static final int SERIAL_TYPE_DebugEventType = 9;
|
||||
static final int SERIAL_TYPE_DebugEvent = 10;
|
||||
static final int SERIAL_TYPE_DebugEventBreakpoint = 11;
|
||||
static final int SERIAL_TYPE_DebugEventError = 12;
|
||||
static final int SERIAL_TYPE_DebugResponseCallgraph = 13;
|
||||
static final int SERIAL_TYPE_DebugResponseVariables = 14;
|
||||
static final int SERIAL_TYPE_DebugResponseStack = 15;
|
||||
static final int SERIAL_TYPE_DebugResponseSession = 16;
|
||||
|
||||
public static void serialize(Serializable object, DataOutputStream dout)
|
||||
throws IOException {
|
||||
@@ -76,16 +80,6 @@ public class SerializationHelper {
|
||||
} else if (object instanceof StackFrame) {
|
||||
dout.writeInt(SERIAL_TYPE_StackFrame);
|
||||
StackFrame.serialize(dout, (StackFrame) object);
|
||||
} else if (object instanceof DebugResponseStack) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugResponseStack);
|
||||
DebugResponseStack.serialize(dout, (DebugResponseStack) object);
|
||||
} else if (object instanceof DebugResponseVariables) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugResponseVariables);
|
||||
DebugResponseVariables.serialize(dout, (DebugResponseVariables) object);
|
||||
} else if (object instanceof DebugResponseCallgraph) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugResponseCallgraph);
|
||||
DebugResponseCallgraph.serialize(dout,
|
||||
(DebugResponseCallgraph) object);
|
||||
} else if (object instanceof DebugRequestType) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugRequestType);
|
||||
DebugRequestType.serialize(dout, (DebugRequestType) object);
|
||||
@@ -96,6 +90,9 @@ public class SerializationHelper {
|
||||
dout.writeInt(SERIAL_TYPE_DebugRequestLineBreakpointToggle);
|
||||
DebugRequestLineBreakpointToggle.serialize(dout,
|
||||
(DebugRequestLineBreakpointToggle) object);
|
||||
} else if (object instanceof DebugRequestDisconnect) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugRequestDisconnect);
|
||||
DebugRequestDisconnect.serialize(dout, (DebugRequestDisconnect) object);
|
||||
} else if (object instanceof DebugRequest) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugRequest);
|
||||
DebugRequest.serialize(dout, (DebugRequest) object);
|
||||
@@ -108,6 +105,19 @@ public class SerializationHelper {
|
||||
} else if (object instanceof DebugEventError) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugEventError);
|
||||
DebugEventError.serialize(dout, (DebugEventError) object);
|
||||
} else if (object instanceof DebugResponseStack) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugResponseStack);
|
||||
DebugResponseStack.serialize(dout, (DebugResponseStack) object);
|
||||
} else if (object instanceof DebugResponseVariables) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugResponseVariables);
|
||||
DebugResponseVariables.serialize(dout, (DebugResponseVariables) object);
|
||||
} else if (object instanceof DebugResponseCallgraph) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugResponseCallgraph);
|
||||
DebugResponseCallgraph.serialize(dout,
|
||||
(DebugResponseCallgraph) object);
|
||||
} else if (object instanceof DebugResponseSession) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugResponseSession);
|
||||
DebugResponseSession.serialize(dout, (DebugResponseSession) object);
|
||||
} else if (object instanceof DebugEvent) {
|
||||
dout.writeInt(SERIAL_TYPE_DebugEvent);
|
||||
DebugEvent.serialize(dout, (DebugEvent) object);
|
||||
@@ -136,15 +146,6 @@ public class SerializationHelper {
|
||||
case SERIAL_TYPE_StackFrame:
|
||||
object = StackFrame.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugResponseCallgraph:
|
||||
object = DebugResponseCallgraph.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugResponseStack:
|
||||
object = DebugResponseStack.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugResponseVariables:
|
||||
object = DebugResponseVariables.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugRequestType:
|
||||
object = DebugRequestType.deserialize(din);
|
||||
break;
|
||||
@@ -154,6 +155,9 @@ public class SerializationHelper {
|
||||
case SERIAL_TYPE_DebugRequestLineBreakpointToggle:
|
||||
object = DebugRequestLineBreakpointToggle.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugRequestDisconnect:
|
||||
object = DebugRequestDisconnect.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugRequest:
|
||||
object = DebugRequest.deserialize(din);
|
||||
break;
|
||||
@@ -166,12 +170,24 @@ public class SerializationHelper {
|
||||
case SERIAL_TYPE_DebugEventError:
|
||||
object = DebugEventError.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugResponseCallgraph:
|
||||
object = DebugResponseCallgraph.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugResponseStack:
|
||||
object = DebugResponseStack.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugResponseVariables:
|
||||
object = DebugResponseVariables.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugResponseSession:
|
||||
object = DebugResponseSession.deserialize(din);
|
||||
break;
|
||||
case SERIAL_TYPE_DebugEvent:
|
||||
object = DebugEvent.deserialize(din);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"deserialization operation is not supported");
|
||||
"deserialization operation is not supported: " + type);
|
||||
}
|
||||
|
||||
return object;
|
||||
|
||||
@@ -1,116 +1,113 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
* 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 org.luaj.debug;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.luaj.vm.CallInfo;
|
||||
|
||||
|
||||
public class StackFrame implements Serializable {
|
||||
protected int lineNumber;
|
||||
|
||||
protected String source;
|
||||
|
||||
public StackFrame(CallInfo callInfo, int lineNumber) {
|
||||
this(lineNumber, DebugUtils.getSourceFileName(callInfo.closure.p.source));
|
||||
|
||||
public StackFrame(String source, int lineNumber) {
|
||||
this.lineNumber = lineNumber;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
StackFrame(int lineNumber, String source) {
|
||||
this.lineNumber = lineNumber;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return this.lineNumber;
|
||||
}
|
||||
|
||||
|
||||
public String getSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
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());
|
||||
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);
|
||||
int lineNumber = in.readInt();
|
||||
String source = in.readUTF();
|
||||
return new StackFrame(source, lineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ public class TableVariable extends Variable {
|
||||
super(index, name, type, null);
|
||||
|
||||
int size = table.size();
|
||||
DebugUtils.println("table size:" + size);
|
||||
Vector keyList = new Vector();
|
||||
Vector valueList = new Vector();
|
||||
LValue[] keyValues = table.getKeys();
|
||||
@@ -52,12 +51,10 @@ public class TableVariable extends Variable {
|
||||
|
||||
keyList.addElement(keyValues[i].toString());
|
||||
if (value instanceof LTable) {
|
||||
DebugUtils.println("table: value[" + i + "]=" + value.toString());
|
||||
valueList.addElement(new TableVariable(i, "element[" + keyValues[i].toString() + "]", Lua.LUA_TTABLE, (LTable)value));
|
||||
} else {
|
||||
valueList.addElement(value.toString());
|
||||
}
|
||||
DebugUtils.println("["+ keyValues[i].toString() + "," + value.toString() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
this.keys = new String[keyList.size()];
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.luaj.debug;
|
||||
|
||||
public class VMException extends RuntimeException {
|
||||
private static final long serialVersionUID = 7876955153693775429L;
|
||||
|
||||
public VMException(Exception e) {
|
||||
super(e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,24 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
* 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 org.luaj.debug.event;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
@@ -26,31 +26,41 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DebugEventError extends DebugEvent {
|
||||
protected String detail;
|
||||
|
||||
public DebugEventError(String detail) {
|
||||
protected String cause;
|
||||
protected String trace;
|
||||
|
||||
public DebugEventError(String cause, String trace) {
|
||||
super(DebugEventType.error);
|
||||
this.detail = detail;
|
||||
}
|
||||
|
||||
public String getDetail() {
|
||||
return this.detail;
|
||||
this.cause = cause;
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
public String getCause() {
|
||||
return this.cause;
|
||||
}
|
||||
|
||||
public String getTrace() {
|
||||
return this.trace;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see lua.debug.DebugEvent#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString() + " detail: " + getDetail();
|
||||
return super.toString() + "[cause: " + getCause() + ", trace: " + trace + "]";
|
||||
}
|
||||
|
||||
public static void serialize(DataOutputStream out, DebugEventError object)
|
||||
throws IOException {
|
||||
out.writeUTF(object.getDetail());
|
||||
}
|
||||
|
||||
public static DebugEvent deserialize(DataInputStream in) throws IOException {
|
||||
String detail = in.readUTF();
|
||||
return new DebugEventError(detail);
|
||||
}
|
||||
public static void serialize(DataOutputStream out, DebugEventError object)
|
||||
throws IOException {
|
||||
out.writeUTF(object.getCause());
|
||||
out.writeUTF(object.getTrace());
|
||||
}
|
||||
|
||||
public static DebugEvent deserialize(DataInputStream in) throws IOException {
|
||||
String detail = in.readUTF();
|
||||
String trace = in.readUTF();
|
||||
return new DebugEventError(detail, trace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@ public class DebugEventType extends EnumType {
|
||||
public static DebugEventType clientRequestGlobalReply
|
||||
= new DebugEventType("clientRequestGlobalReply", 16);
|
||||
public static DebugEventType disconnected
|
||||
= new DebugEventType("disconnected", 17);
|
||||
= new DebugEventType("disconnected", 17);
|
||||
public static DebugEventType session
|
||||
= new DebugEventType("session", 17);
|
||||
|
||||
protected static DebugEventType[] ENUMS = new DebugEventType[] {
|
||||
started,
|
||||
@@ -70,7 +72,8 @@ public class DebugEventType extends EnumType {
|
||||
clientRequestCallgraphReply,
|
||||
clientRequestStackReply,
|
||||
clientRequestGlobalReply,
|
||||
disconnected
|
||||
disconnected,
|
||||
session
|
||||
};
|
||||
|
||||
protected DebugEventType(String name, int ordinal) {
|
||||
|
||||
75
src/debug/org/luaj/debug/net/j2me/DebugSupportImpl.java
Normal file
75
src/debug/org/luaj/debug/net/j2me/DebugSupportImpl.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package org.luaj.debug.net.j2me;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.microedition.io.Connector;
|
||||
import javax.microedition.io.ServerSocketConnection;
|
||||
import javax.microedition.io.SocketConnection;
|
||||
|
||||
import org.luaj.debug.DebugLuaState;
|
||||
import org.luaj.debug.event.DebugEvent;
|
||||
import org.luaj.debug.net.DebugSupport;
|
||||
import org.luaj.debug.request.DebugRequest;
|
||||
|
||||
public class DebugSupportImpl implements DebugSupport {
|
||||
protected ServerSocketConnection serverConnection;
|
||||
|
||||
public DebugSupportImpl(int port) throws IOException {
|
||||
this.serverConnection
|
||||
= (ServerSocketConnection) Connector.open(
|
||||
"socket://:" + port);
|
||||
}
|
||||
|
||||
public synchronized void acceptClientConnection()
|
||||
throws IOException {
|
||||
// Set up the request socket and request input + event output streams
|
||||
SocketConnection clientDebugConnection
|
||||
= (SocketConnection) serverConnection.acceptAndOpen();
|
||||
clientDebugConnection.setSocketOption(SocketConnection.DELAY, 0);
|
||||
clientDebugConnection.setSocketOption(SocketConnection.LINGER, 0);
|
||||
clientDebugConnection.setSocketOption(SocketConnection.KEEPALIVE, 1);
|
||||
clientDebugConnection.setSocketOption(SocketConnection.RCVBUF, 1024);
|
||||
clientDebugConnection.setSocketOption(SocketConnection.SNDBUF, 1024);
|
||||
//TODO....
|
||||
}
|
||||
|
||||
protected void dispose() {
|
||||
if (this.serverConnection != null) {
|
||||
try {
|
||||
serverConnection.close();
|
||||
serverConnection = null;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect(int id) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void setDebugStackState(DebugLuaState vm) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void handleRequest(DebugRequest request) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void notifyDebugEvent(DebugEvent event) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user