1. changed to use LuaErrorException and removed VMException

2. refactored the debug network communication layer
This commit is contained in:
Shu Lei
2007-11-20 23:25:50 +00:00
parent 62a3510272
commit 6c9d02b3a3
12 changed files with 383 additions and 528 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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()];

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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) {

View 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
}
}