1. improved stack state (correct scoping)
2. fixed the problem with debugger not pausing on first line
This commit is contained in:
@@ -6,6 +6,7 @@ import java.util.Stack;
|
|||||||
|
|
||||||
import lua.io.Closure;
|
import lua.io.Closure;
|
||||||
import lua.io.LoadState;
|
import lua.io.LoadState;
|
||||||
|
import lua.io.LocVars;
|
||||||
import lua.io.Proto;
|
import lua.io.Proto;
|
||||||
import lua.io.UpVal;
|
import lua.io.UpVal;
|
||||||
import lua.value.LBoolean;
|
import lua.value.LBoolean;
|
||||||
@@ -340,11 +341,21 @@ public class StackState extends Lua implements VM {
|
|||||||
// loop until a return instruction is processed,
|
// loop until a return instruction is processed,
|
||||||
// or the vm yields
|
// or the vm yields
|
||||||
while (true) {
|
while (true) {
|
||||||
debugAssert( ci == calls[cc] );
|
debugAssert( ci == calls[cc] );
|
||||||
|
|
||||||
if (TRACE)
|
// sync up top
|
||||||
|
ci.top = top;
|
||||||
|
|
||||||
|
if (TRACE) {
|
||||||
Print.printState(this, base, top, base+p.maxstacksize, cl, ci.pc);
|
Print.printState(this, base, top, base+p.maxstacksize, cl, ci.pc);
|
||||||
|
for (int j = 0; j <= cc; j++) {
|
||||||
|
System.out.println("calls[" + j + "]: " + calls[j].base + "," + calls[j].top);
|
||||||
|
LocVars[] localVars = calls[j].closure.p.locvars;
|
||||||
|
for (int t = 0; t < localVars.length; t++)
|
||||||
|
System.out.println("localVars[" + t + "]: " + localVars[t].varname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// allow debug hooks a chance to operate
|
// allow debug hooks a chance to operate
|
||||||
debugHooks( ci.pc );
|
debugHooks( ci.pc );
|
||||||
|
|
||||||
@@ -367,8 +378,7 @@ public class StackState extends Lua implements VM {
|
|||||||
case StackState.OP_LOADBOOL: {
|
case StackState.OP_LOADBOOL: {
|
||||||
b = StackState.GETARG_B(i);
|
b = StackState.GETARG_B(i);
|
||||||
c = StackState.GETARG_C(i);
|
c = StackState.GETARG_C(i);
|
||||||
this.stack[base + a] = (b != 0 ? LBoolean.TRUE
|
this.stack[base + a] = (b != 0 ? LBoolean.TRUE : LBoolean.FALSE);
|
||||||
: LBoolean.FALSE);
|
|
||||||
if (c != 0)
|
if (c != 0)
|
||||||
ci.pc++; /* skip next instruction (if C) */
|
ci.pc++; /* skip next instruction (if C) */
|
||||||
continue;
|
continue;
|
||||||
@@ -535,7 +545,7 @@ public class StackState extends Lua implements VM {
|
|||||||
|
|
||||||
// restore base
|
// restore base
|
||||||
base = ci.base;
|
base = ci.base;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,11 +565,20 @@ public class StackState extends Lua implements VM {
|
|||||||
this.top = base + b;
|
this.top = base + b;
|
||||||
this.nresults = ci.nresults;
|
this.nresults = ci.nresults;
|
||||||
--cc;
|
--cc;
|
||||||
|
|
||||||
// make or set up the call
|
// make or set up the call
|
||||||
if (this.stack[base].luaStackCall(this))
|
try {
|
||||||
return;
|
if (this.stack[base].luaStackCall(this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
// in case of error, we need to restore cc so that
|
||||||
|
// the debug can get the correct location where the error
|
||||||
|
// occured.
|
||||||
|
cc++;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
// adjustTop only for case when call was completed
|
// adjustTop only for case when call was completed
|
||||||
// and number of args > 0. If call completed but
|
// and number of args > 0. If call completed but
|
||||||
// c == 0, leave top to point to end of results
|
// c == 0, leave top to point to end of results
|
||||||
@@ -704,7 +723,6 @@ public class StackState extends Lua implements VM {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ci.top = top;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007 LuaJ. All rights reserved.
|
* Copyright (c) 2007 LuaJ. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* 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
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package lua.debug;
|
package lua.debug;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -51,331 +51,365 @@ import lua.value.LValue;
|
|||||||
|
|
||||||
public class DebugStackState extends StackState implements DebugRequestListener {
|
public class DebugStackState extends StackState implements DebugRequestListener {
|
||||||
|
|
||||||
// stepping constants and stepping state
|
// stepping constants and stepping state
|
||||||
protected static final int STEP_NONE = 0;
|
protected static final int STEP_NONE = 0;
|
||||||
protected static final int STEP_OVER = 1;
|
|
||||||
protected static final int STEP_INTO = 2;
|
protected static final int STEP_OVER = 1;
|
||||||
protected static final int STEP_RETURN = 3;
|
|
||||||
|
protected static final int STEP_INTO = 2;
|
||||||
|
|
||||||
|
protected static final int STEP_RETURN = 3;
|
||||||
|
|
||||||
protected int stepping = STEP_NONE;
|
protected int stepping = STEP_NONE;
|
||||||
protected boolean shouldPauseForStepping = false;
|
protected boolean shouldPauseForStepping = false;
|
||||||
protected int steppingFrame = -1;
|
protected int steppingFrame = -1;
|
||||||
|
protected Hashtable breakpoints = new Hashtable();
|
||||||
protected Hashtable breakpoints = new Hashtable();
|
|
||||||
protected boolean exiting = false;
|
protected boolean exiting = false;
|
||||||
protected boolean suspended = false;
|
protected boolean suspended = false;
|
||||||
|
protected boolean isStarted = false;
|
||||||
protected int lastline = -1;
|
protected int lastline = -1;
|
||||||
protected String lastSource;
|
protected String lastSource;
|
||||||
protected DebugSupport debugSupport;
|
protected DebugSupport debugSupport;
|
||||||
protected VMException lastException;
|
protected VMException lastException;
|
||||||
|
|
||||||
|
|
||||||
public DebugStackState() {}
|
public DebugStackState() {
|
||||||
|
|
||||||
public void setDebugSupport(DebugSupport debugSupport) throws IOException {
|
|
||||||
if (debugSupport == null) {
|
|
||||||
throw new IllegalArgumentException("DebugSupport cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.debugSupport = debugSupport;
|
|
||||||
debugSupport.setDebugStackState(this);
|
|
||||||
debugSupport.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void debugAssert(boolean b) {
|
|
||||||
if ( ! b )
|
|
||||||
error( "assert failure" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFileLine(int cindex) {
|
|
||||||
String func = "?";
|
|
||||||
String line = "?";
|
|
||||||
String source = "?";
|
|
||||||
if ( cindex >= 0 ) {
|
|
||||||
CallInfo call = this.calls[cindex];
|
|
||||||
Proto p = call.closure.p;
|
|
||||||
if ( p != null && p.source != null )
|
|
||||||
source = p.source.toJavaString();
|
|
||||||
if ( p.lineinfo != null && p.lineinfo.length > call.pc )
|
|
||||||
line = String.valueOf( p.lineinfo[call.pc] );
|
|
||||||
// TODO: reverse lookup on function name ????
|
|
||||||
func = call.closure.toJavaString();
|
|
||||||
}
|
|
||||||
return source+":"+line+"("+func+")";
|
|
||||||
}
|
|
||||||
|
|
||||||
// override and fill in line number info
|
|
||||||
public void error(String message, int level) {
|
|
||||||
super.error( level<=0? message: getFileLine(cc+1-level)+": "+message );
|
|
||||||
}
|
|
||||||
|
|
||||||
// use line numbers by default
|
public void setDebugSupport(DebugSupport debugSupport) throws IOException {
|
||||||
public void error(String message) {
|
if (debugSupport == null) {
|
||||||
error(message, 1);
|
throw new IllegalArgumentException("DebugSupport cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
// intercept exceptions and fill in line numbers
|
this.debugSupport = debugSupport;
|
||||||
public void exec() {
|
debugSupport.setDebugStackState(this);
|
||||||
try {
|
debugSupport.start();
|
||||||
super.exec();
|
}
|
||||||
} catch ( AbortException e ) {
|
|
||||||
|
protected void debugAssert(boolean b) {
|
||||||
|
if (!b)
|
||||||
|
error("assert failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFileLine(int cindex) {
|
||||||
|
String func = "?";
|
||||||
|
String line = "?";
|
||||||
|
String source = "?";
|
||||||
|
if (cindex >= 0) {
|
||||||
|
CallInfo call = this.calls[cindex];
|
||||||
|
Proto p = call.closure.p;
|
||||||
|
if (p != null && p.source != null)
|
||||||
|
source = p.source.toJavaString();
|
||||||
|
if (p.lineinfo != null && p.lineinfo.length > call.pc)
|
||||||
|
line = String.valueOf(p.lineinfo[call.pc]);
|
||||||
|
// TODO: reverse lookup on function name ????
|
||||||
|
func = call.closure.toJavaString();
|
||||||
|
}
|
||||||
|
return source + ":" + line + "(" + func + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
// override and fill in line number info
|
||||||
|
public void error(String message, int level) {
|
||||||
|
super.error(level <= 0 ? message : getFileLine(cc + 1 - level) + ": "
|
||||||
|
+ message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// use line numbers by default
|
||||||
|
public void error(String message) {
|
||||||
|
error(message, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// intercept exceptions and fill in line numbers
|
||||||
|
public void exec() {
|
||||||
|
try {
|
||||||
|
super.exec();
|
||||||
|
} catch (AbortException e) {
|
||||||
// ignored. Client aborts the debugging session.
|
// ignored. Client aborts the debugging session.
|
||||||
} catch ( VMException e ) {
|
} catch (VMException e) {
|
||||||
// let VM exceptions be processed
|
// let VM exceptions be processed
|
||||||
// the same as the base class to minimize differences
|
// the same as the base class to minimize differences
|
||||||
// between the debug and non-debug behavior
|
// between the debug and non-debug behavior
|
||||||
throw e;
|
throw e;
|
||||||
} catch ( Exception e ) {
|
} catch (Exception e) {
|
||||||
lastException = new VMException(e);
|
lastException = new VMException(e);
|
||||||
debugSupport.notifyDebugEvent(new DebugEventError(e.getMessage()));
|
debugSupport.notifyDebugEvent(new DebugEventError(e.getMessage()));
|
||||||
suspend();
|
suspend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debug hooks
|
||||||
// debug hooks
|
public void debugHooks(int pc) {
|
||||||
public void debugHooks( int pc ) {
|
if (exiting) {
|
||||||
if ( exiting ) {
|
throw new AbortException("aborted by debug client");
|
||||||
throw new AbortException("aborted by debug client");
|
}
|
||||||
}
|
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
if(DebugUtils.IS_DEBUG)
|
DebugUtils.println("entered debugHook on pc=" + pc + "...");
|
||||||
DebugUtils.println("entered debugHook on pc=" + pc + "...");
|
|
||||||
|
synchronized (this) {
|
||||||
synchronized ( this ) {
|
while (!isStarted) {
|
||||||
CallInfo currentCallInfo = calls[cc];
|
try {
|
||||||
Proto currentProto = currentCallInfo.closure.p;
|
this.wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
// if we are not stepping, we keep going if the line doesn't change
|
e.printStackTrace();
|
||||||
int line = getLineNumber(currentCallInfo);
|
}
|
||||||
String source = DebugUtils.getSourceFileName(currentProto.source);
|
|
||||||
if ( !isStepping() && lastline == line && source.equals(lastSource) ) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DebugUtils.IS_DEBUG)
|
CallInfo currentCallInfo = calls[cc];
|
||||||
DebugUtils.println("debugHook - executing line: " + line);
|
Proto currentProto = currentCallInfo.closure.p;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
if (!isStepping() && lastline == line && source.equals(lastSource)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("debugHook - executing line: " + line);
|
||||||
|
|
||||||
int i = currentProto.code[pc];
|
int i = currentProto.code[pc];
|
||||||
int opCode = StackState.GET_OPCODE(i);
|
int opCode = StackState.GET_OPCODE(i);
|
||||||
if (isStepping() &&
|
if (isStepping() && opCode == StackState.OP_RETURN && cc == 0) {
|
||||||
opCode == StackState.OP_RETURN && cc == 0) {
|
cancelStepping();
|
||||||
cancelStepping();
|
|
||||||
} else if (shouldPauseForStepping) {
|
} else if (shouldPauseForStepping) {
|
||||||
shouldPauseForStepping = false;
|
shouldPauseForStepping = false;
|
||||||
suspendOnStepping();
|
suspendOnStepping();
|
||||||
} else if ( stepping == STEP_INTO ) {
|
} else if (stepping == STEP_INTO) {
|
||||||
if (lastline != line){
|
if (lastline != line) {
|
||||||
suspendOnStepping();
|
suspendOnStepping();
|
||||||
} else if (opCode == StackState.OP_CALL) {
|
} else if (opCode == StackState.OP_CALL) {
|
||||||
shouldPauseForStepping = true;
|
shouldPauseForStepping = true;
|
||||||
}
|
}
|
||||||
} else if (stepping == STEP_OVER) {
|
} else if (stepping == STEP_OVER) {
|
||||||
if ((lastline != line && steppingFrame == cc) || (steppingFrame > cc)) {
|
if ((lastline != line && steppingFrame == cc)
|
||||||
suspendOnStepping();
|
|| (steppingFrame > cc)) {
|
||||||
}
|
suspendOnStepping();
|
||||||
|
}
|
||||||
} else if (stepping == STEP_RETURN) {
|
} else if (stepping == STEP_RETURN) {
|
||||||
if ((opCode == StackState.OP_RETURN && cc == this.steppingFrame) ||
|
if ((opCode == StackState.OP_RETURN && cc == this.steppingFrame)
|
||||||
(opCode == StackState.OP_TAILCALL && cc == this.steppingFrame)){
|
|| (opCode == StackState.OP_TAILCALL && cc == this.steppingFrame)) {
|
||||||
shouldPauseForStepping = true;
|
shouldPauseForStepping = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for a break point if we aren't suspended already
|
// check for a break point if we aren't suspended already
|
||||||
if ( !suspended && lastline != line) {
|
if (!suspended && lastline != line) {
|
||||||
if (DebugUtils.IS_DEBUG)
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("Source: " + currentProto.source);
|
DebugUtils.println("Source: " + currentProto.source);
|
||||||
|
String fileName = DebugUtils.getSourceFileName(source);
|
||||||
|
String breakpointKey = constructBreakpointKey(fileName, line);
|
||||||
|
if (breakpoints.containsKey(breakpointKey)) {
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("hitting breakpoint "
|
||||||
|
+ constructBreakpointKey(fileName, line));
|
||||||
|
|
||||||
String breakpointKey = constructBreakpointKey(source, line);
|
debugSupport.notifyDebugEvent(new DebugEventBreakpoint(
|
||||||
if (breakpoints.containsKey(breakpointKey)){
|
fileName, line));
|
||||||
if(DebugUtils.IS_DEBUG)
|
suspended = true;
|
||||||
DebugUtils.println("hitting breakpoint " + constructBreakpointKey(source, line));
|
}
|
||||||
|
}
|
||||||
debugSupport.notifyDebugEvent(new DebugEventBreakpoint(source, line));
|
|
||||||
suspended = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// save line in case next op is a step
|
|
||||||
lastline = line;
|
|
||||||
lastSource = source;
|
|
||||||
|
|
||||||
// wait for a state change
|
|
||||||
while (suspended && !exiting ) {
|
|
||||||
try {
|
|
||||||
this.wait();
|
|
||||||
if(DebugUtils.IS_DEBUG)
|
|
||||||
DebugUtils.println("resuming execution...");
|
|
||||||
|
|
||||||
if (lastException != null) {
|
|
||||||
throw lastException;
|
|
||||||
}
|
|
||||||
} catch ( InterruptedException ie ) {
|
|
||||||
ie.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isStepping() {
|
// save line in case next op is a step
|
||||||
return stepping != STEP_NONE;
|
lastline = line;
|
||||||
}
|
lastSource = source;
|
||||||
|
|
||||||
private void cancelStepping() {
|
// wait for a state change
|
||||||
debugSupport.notifyDebugEvent(new DebugEvent(DebugEventType.resumedOnSteppingEnd));
|
while (suspended && !exiting) {
|
||||||
stepping = STEP_NONE;
|
try {
|
||||||
steppingFrame = -1;
|
this.wait();
|
||||||
shouldPauseForStepping = false;
|
if (DebugUtils.IS_DEBUG)
|
||||||
}
|
DebugUtils.println("resuming execution...");
|
||||||
|
|
||||||
private void suspendOnStepping() {
|
if (lastException != null) {
|
||||||
debugSupport.notifyDebugEvent(new DebugEvent(DebugEventType.suspendedOnStepping));
|
throw lastException;
|
||||||
suspended = true;
|
}
|
||||||
steppingFrame = -1;
|
} catch (InterruptedException ie) {
|
||||||
}
|
ie.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStepping() {
|
||||||
|
return stepping != STEP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelStepping() {
|
||||||
|
debugSupport.notifyDebugEvent(new DebugEvent(
|
||||||
|
DebugEventType.resumedOnSteppingEnd));
|
||||||
|
stepping = STEP_NONE;
|
||||||
|
steppingFrame = -1;
|
||||||
|
shouldPauseForStepping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void suspendOnStepping() {
|
||||||
|
debugSupport.notifyDebugEvent(new DebugEvent(
|
||||||
|
DebugEventType.suspendedOnStepping));
|
||||||
|
suspended = true;
|
||||||
|
steppingFrame = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current line number
|
* Get the current line number
|
||||||
|
*
|
||||||
* @param pc program counter
|
* @param pc program counter
|
||||||
* @return the line number corresponding to the pc
|
* @return the line number corresponding to the pc
|
||||||
*/
|
*/
|
||||||
private int getLineNumber(CallInfo ci) {
|
private int getLineNumber(CallInfo ci) {
|
||||||
int[] lineNumbers = ci.closure.p.lineinfo;
|
int[] lineNumbers = ci.closure.p.lineinfo;
|
||||||
int pc = ci.pc;
|
int pc = ci.pc;
|
||||||
int line = (lineNumbers != null && lineNumbers.length > pc ? lineNumbers[pc] : -1);
|
int line = (lineNumbers != null && lineNumbers.length > pc ? lineNumbers[pc]
|
||||||
|
: -1);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------ commands coming from the debugger -------------------
|
// ------------------ commands coming from the debugger -------------------
|
||||||
|
|
||||||
public DebugResponse handleRequest(DebugRequest request) {
|
public DebugResponse handleRequest(DebugRequest request) {
|
||||||
if (this.debugSupport == null) {
|
if (this.debugSupport == null) {
|
||||||
throw new IllegalStateException("DebugStackState is not equiped with DebugSupport.");
|
throw new IllegalStateException(
|
||||||
}
|
"DebugStackState is not equiped with DebugSupport.");
|
||||||
|
}
|
||||||
if (DebugUtils.IS_DEBUG)
|
|
||||||
DebugUtils.println("DebugStackState is handling request: " + request.toString());
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("DebugStackState is handling request: "
|
||||||
DebugRequestType requestType = request.getType();
|
+ request.toString());
|
||||||
|
|
||||||
|
DebugRequestType requestType = request.getType();
|
||||||
if (DebugRequestType.start == requestType) {
|
if (DebugRequestType.start == requestType) {
|
||||||
DebugEvent event = new DebugEvent(DebugEventType.started);
|
DebugEvent event = new DebugEvent(DebugEventType.started);
|
||||||
debugSupport.notifyDebugEvent(event);
|
debugSupport.notifyDebugEvent(event);
|
||||||
|
setStarted();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
} else if (DebugRequestType.exit == requestType) {
|
} else if (DebugRequestType.exit == requestType) {
|
||||||
stop();
|
stop();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
} else if (DebugRequestType.suspend == requestType) {
|
} else if (DebugRequestType.suspend == requestType) {
|
||||||
suspend();
|
suspend();
|
||||||
DebugEvent event = new DebugEvent(DebugEventType.suspendedByClient);
|
DebugEvent event = new DebugEvent(DebugEventType.suspendedByClient);
|
||||||
debugSupport.notifyDebugEvent(event);
|
|
||||||
return DebugResponseSimple.SUCCESS;
|
|
||||||
} else if (DebugRequestType.resume == requestType) {
|
|
||||||
resume();
|
|
||||||
DebugEvent event = new DebugEvent(DebugEventType.resumedByClient);
|
|
||||||
debugSupport.notifyDebugEvent(event);
|
debugSupport.notifyDebugEvent(event);
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
} else if (DebugRequestType.lineBreakpointSet == requestType) {
|
} else if (DebugRequestType.resume == requestType) {
|
||||||
DebugRequestLineBreakpointToggle setBreakpointRequest
|
resume();
|
||||||
= (DebugRequestLineBreakpointToggle)request;
|
DebugEvent event = new DebugEvent(DebugEventType.resumedByClient);
|
||||||
setBreakpoint(setBreakpointRequest.getSource(), setBreakpointRequest.getLineNumber());
|
debugSupport.notifyDebugEvent(event);
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
} else if (DebugRequestType.lineBreakpointClear == requestType) {
|
} else if (DebugRequestType.lineBreakpointSet == requestType) {
|
||||||
DebugRequestLineBreakpointToggle clearBreakpointRequest
|
DebugRequestLineBreakpointToggle setBreakpointRequest = (DebugRequestLineBreakpointToggle) request;
|
||||||
= (DebugRequestLineBreakpointToggle)request;
|
setBreakpoint(setBreakpointRequest.getSource(),
|
||||||
clearBreakpoint(clearBreakpointRequest.getSource(), clearBreakpointRequest.getLineNumber());
|
setBreakpointRequest.getLineNumber());
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
} else if (DebugRequestType.callgraph == requestType) {
|
} else if (DebugRequestType.lineBreakpointClear == requestType) {
|
||||||
|
DebugRequestLineBreakpointToggle clearBreakpointRequest = (DebugRequestLineBreakpointToggle) request;
|
||||||
|
clearBreakpoint(clearBreakpointRequest.getSource(),
|
||||||
|
clearBreakpointRequest.getLineNumber());
|
||||||
|
return DebugResponseSimple.SUCCESS;
|
||||||
|
} else if (DebugRequestType.callgraph == requestType) {
|
||||||
return new DebugResponseCallgraph(getCallgraph());
|
return new DebugResponseCallgraph(getCallgraph());
|
||||||
} else if (DebugRequestType.stack == requestType) {
|
} else if (DebugRequestType.stack == requestType) {
|
||||||
DebugRequestStack stackRequest = (DebugRequestStack) request;
|
DebugRequestStack stackRequest = (DebugRequestStack) request;
|
||||||
int index = stackRequest.getIndex();
|
int index = stackRequest.getIndex();
|
||||||
return new DebugResponseStack(getStack(index));
|
return new DebugResponseStack(getStack(index));
|
||||||
} else if (DebugRequestType.stepInto == requestType) {
|
} else if (DebugRequestType.stepInto == requestType) {
|
||||||
DebugEvent event = new DebugEvent(DebugEventType.resumedOnSteppingInto);
|
DebugEvent event = new DebugEvent(
|
||||||
|
DebugEventType.resumedOnSteppingInto);
|
||||||
debugSupport.notifyDebugEvent(event);
|
debugSupport.notifyDebugEvent(event);
|
||||||
stepInto();
|
stepInto();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
} else if (DebugRequestType.stepOver == requestType) {
|
} else if (DebugRequestType.stepOver == requestType) {
|
||||||
DebugEvent event = new DebugEvent(DebugEventType.resumedOnSteppingOver);
|
DebugEvent event = new DebugEvent(
|
||||||
|
DebugEventType.resumedOnSteppingOver);
|
||||||
debugSupport.notifyDebugEvent(event);
|
debugSupport.notifyDebugEvent(event);
|
||||||
stepOver();
|
stepOver();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
} else if (DebugRequestType.stepReturn == requestType) {
|
} else if (DebugRequestType.stepReturn == requestType) {
|
||||||
DebugEvent event = new DebugEvent(DebugEventType.resumedOnSteppingReturn);
|
DebugEvent event = new DebugEvent(
|
||||||
|
DebugEventType.resumedOnSteppingReturn);
|
||||||
debugSupport.notifyDebugEvent(event);
|
debugSupport.notifyDebugEvent(event);
|
||||||
stepReturn();
|
stepReturn();
|
||||||
return DebugResponseSimple.SUCCESS;
|
return DebugResponseSimple.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new java.lang.IllegalArgumentException( "unkown request type: "+ request.getType());
|
throw new java.lang.IllegalArgumentException("unkown request type: "
|
||||||
}
|
+ request.getType());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* suspend the execution
|
* suspend the execution
|
||||||
*/
|
*/
|
||||||
public void suspend() {
|
public void suspend() {
|
||||||
synchronized ( this ) {
|
synchronized (this) {
|
||||||
suspended = true;
|
suspended = true;
|
||||||
stepping = STEP_NONE;
|
|
||||||
lastline = -1;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resume the execution
|
|
||||||
*/
|
|
||||||
public void resume() {
|
|
||||||
synchronized ( this ) {
|
|
||||||
suspended = false;
|
|
||||||
stepping = STEP_NONE;
|
stepping = STEP_NONE;
|
||||||
this.notify();
|
lastline = -1;
|
||||||
}
|
this.notify();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setStarted() {
|
||||||
|
synchronized (this) {
|
||||||
|
isStarted = true;
|
||||||
|
this.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resume the execution
|
||||||
|
*/
|
||||||
|
public void resume() {
|
||||||
|
synchronized (this) {
|
||||||
|
suspended = false;
|
||||||
|
stepping = STEP_NONE;
|
||||||
|
this.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (this.debugSupport == null) {
|
if (this.debugSupport == null) {
|
||||||
throw new IllegalStateException("DebugStackState is not equiped with DebugSupport.");
|
throw new IllegalStateException(
|
||||||
}
|
"DebugStackState is not equiped with DebugSupport.");
|
||||||
|
}
|
||||||
|
|
||||||
DebugEvent event = new DebugEvent(DebugEventType.terminated);
|
DebugEvent event = new DebugEvent(DebugEventType.terminated);
|
||||||
debugSupport.notifyDebugEvent(event);
|
debugSupport.notifyDebugEvent(event);
|
||||||
|
|
||||||
new Timer().schedule(new TimerTask() {
|
new Timer().schedule(new TimerTask() {
|
||||||
public void run () {
|
public void run() {
|
||||||
debugSupport.stop();
|
debugSupport.stop();
|
||||||
debugSupport = null;
|
debugSupport = null;
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* terminate the execution
|
* terminate the execution
|
||||||
*/
|
*/
|
||||||
public void exit() {
|
public void exit() {
|
||||||
synchronized ( this ) {
|
synchronized (this) {
|
||||||
exiting = true;
|
exiting = true;
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set breakpoint at line N
|
* set breakpoint at line N
|
||||||
* @param N the line to set the breakpoint at
|
*
|
||||||
|
* @param N
|
||||||
|
* the line to set the breakpoint at
|
||||||
*/
|
*/
|
||||||
public void setBreakpoint(String source, int lineNumber) {
|
public void setBreakpoint(String source, int lineNumber) {
|
||||||
if (DebugUtils.IS_DEBUG) {
|
String fileName = DebugUtils.getSourceFileName(source);
|
||||||
DebugUtils.print("source: " + source + " line:" + lineNumber);
|
String breakpointKey = constructBreakpointKey(fileName, lineNumber);
|
||||||
DebugUtils.println("adding breakpoint " + constructBreakpointKey(source, lineNumber));
|
|
||||||
}
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("adding breakpoint " + breakpointKey);
|
||||||
synchronized ( this ) {
|
|
||||||
String normalizedFileName = DebugUtils.getSourceFileName(source);
|
breakpoints.put(breakpointKey, Boolean.TRUE);
|
||||||
breakpoints.put(constructBreakpointKey(normalizedFileName, lineNumber), Boolean.TRUE );
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String constructBreakpointKey(String source, int lineNumber) {
|
protected String constructBreakpointKey(String source, int lineNumber) {
|
||||||
return source + ":" + lineNumber;
|
return source + ":" + lineNumber;
|
||||||
}
|
}
|
||||||
@@ -383,139 +417,172 @@ public class DebugStackState extends StackState implements DebugRequestListener
|
|||||||
/**
|
/**
|
||||||
* clear breakpoint at line lineNumber of source source
|
* clear breakpoint at line lineNumber of source source
|
||||||
*/
|
*/
|
||||||
public void clearBreakpoint(String source, int lineNumber) {
|
public void clearBreakpoint(String source, int lineNumber) {
|
||||||
if(DebugUtils.IS_DEBUG)
|
String fileName = DebugUtils.getSourceFileName(source);
|
||||||
DebugUtils.println("removing breakpoint " + constructBreakpointKey(source, lineNumber));
|
String breakpointKey = constructBreakpointKey(fileName, lineNumber);
|
||||||
synchronized ( this ) {
|
|
||||||
String normalizedFileName = DebugUtils.getSourceFileName(source);
|
|
||||||
breakpoints.remove(constructBreakpointKey(normalizedFileName, lineNumber));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return the current call graph (i.e. stack frames from
|
|
||||||
* old to new, include information about file, method, etc.)
|
|
||||||
*/
|
|
||||||
public StackFrame[] getCallgraph() {
|
|
||||||
int n = cc;
|
|
||||||
|
|
||||||
if ( n < 0 || n >= calls.length )
|
|
||||||
return new StackFrame[0];
|
|
||||||
|
|
||||||
StackFrame[] frames = new StackFrame[n+1];
|
|
||||||
for ( int i = 0; i <= n; i++ ) {
|
|
||||||
CallInfo ci = calls[i];
|
|
||||||
frames[i] = new StackFrame(ci, getLineNumber(ci));
|
|
||||||
}
|
|
||||||
return frames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variable[] getStack(int index) {
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("removing breakpoint " + breakpointKey);
|
||||||
|
|
||||||
|
breakpoints.remove(breakpointKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the current call graph (i.e. stack frames from old to new, include
|
||||||
|
* information about file, method, etc.)
|
||||||
|
*/
|
||||||
|
public StackFrame[] getCallgraph() {
|
||||||
|
int n = cc;
|
||||||
|
|
||||||
|
if (n < 0 || n >= calls.length)
|
||||||
|
return new StackFrame[0];
|
||||||
|
|
||||||
|
StackFrame[] frames = new StackFrame[n + 1];
|
||||||
|
for (int i = 0; i <= n; i++) {
|
||||||
|
CallInfo ci = calls[i];
|
||||||
|
frames[i] = new StackFrame(ci, getLineNumber(ci));
|
||||||
|
}
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variable[] getStack(int index) {
|
||||||
if (index < 0 || index >= calls.length) {
|
if (index < 0 || index >= calls.length) {
|
||||||
//TODO: this is an error, handle it differently
|
throw new RuntimeException("invalid stack index");
|
||||||
return new Variable[0];
|
}
|
||||||
|
|
||||||
|
Vector variables = new Vector();
|
||||||
|
Hashtable variablesSeen = new Hashtable();
|
||||||
|
for (int i = index; i >= 0; i--) {
|
||||||
|
addVariables(variables, variablesSeen, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable[] result = new Variable[variables.size()];
|
||||||
|
for (int i = 0; i < variables.size(); i++) {
|
||||||
|
result[i] = (Variable) variables.elementAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getVariable(CallInfo callInfo, int index) {
|
||||||
|
Proto prototype = callInfo.closure.p;
|
||||||
|
int count = -1;
|
||||||
|
LocVars[] localVariables = prototype.locvars;
|
||||||
|
for (int i = 0; i < localVariables.length; i++) {
|
||||||
|
if (callInfo.pc < localVariables[i].startpc ||
|
||||||
|
callInfo.pc > localVariables[i].endpc) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
count++;
|
||||||
|
if (count == index) {
|
||||||
|
return localVariables[i].varname.toJavaString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addVariables(Vector variables, Hashtable variablesSeen, int index) {
|
||||||
CallInfo callInfo = calls[index];
|
CallInfo callInfo = calls[index];
|
||||||
if(DebugUtils.IS_DEBUG)
|
|
||||||
DebugUtils.println("Stack Frame: " + index + "[" + callInfo.base + "," + callInfo.top + "]");
|
|
||||||
int top = callInfo.top < callInfo.base ? callInfo.base : callInfo.top;
|
|
||||||
Proto prototype = callInfo.closure.p;
|
Proto prototype = callInfo.closure.p;
|
||||||
LocVars[] localVariables = prototype.locvars;
|
int base = callInfo.base;
|
||||||
Vector variables = new Vector();
|
int top = callInfo.top < callInfo.base ? callInfo.base+1 : callInfo.top;
|
||||||
int localVariableCount = 0;
|
|
||||||
Hashtable variablesSeen = new Hashtable();
|
if (DebugUtils.IS_DEBUG) {
|
||||||
for (int i = 0; localVariables != null && i < localVariables.length && i <= top; i++) {
|
DebugUtils.println("Stack Frame: " + index + " [" + base + "," + top + "], # of localvars: " + prototype.locvars.length + ", pc=" + callInfo.pc);
|
||||||
String varName = localVariables[i].varname.toString();
|
for (int i = 0; i < prototype.locvars.length; i++) {
|
||||||
|
DebugUtils.println("localvars[" + i + "]: " + prototype.locvars[i].varname + "(" + prototype.locvars[i].startpc + "," + prototype.locvars[i].endpc + ")");
|
||||||
|
}
|
||||||
|
for (int i = base; i < top; i++){
|
||||||
|
DebugUtils.println("stack[" + i + "]=" + stack[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int selectedVariableCount = 0;
|
||||||
|
for (int i = base; i < top; i++) {
|
||||||
|
String varName = getVariable(callInfo, i-base);
|
||||||
|
if (varName == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(DebugUtils.IS_DEBUG) {
|
if(DebugUtils.IS_DEBUG) {
|
||||||
DebugUtils.print("\tVariable: " + varName);
|
DebugUtils.print("\tVariable: " + varName);
|
||||||
DebugUtils.print("\tValue: " + stack[callInfo.base + i]);
|
DebugUtils.print("\tValue: " + stack[i]);
|
||||||
}
|
}
|
||||||
if (!variablesSeen.contains(varName) &&
|
if (!variablesSeen.contains(varName) &&
|
||||||
!LexState.isReservedKeyword(varName)) {
|
!LexState.isReservedKeyword(varName)) {
|
||||||
variablesSeen.put(varName, varName);
|
variablesSeen.put(varName, varName);
|
||||||
LValue value = stack[callInfo.base + i];
|
LValue value = stack[i];
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
int type = value.luaGetType();
|
int type = value.luaGetType();
|
||||||
if (DebugUtils.IS_DEBUG)
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.print("\tType: " + Lua.TYPE_NAMES[type]);
|
DebugUtils.print("\tType: " + Lua.TYPE_NAMES[type]);
|
||||||
if (type == Lua.LUA_TTABLE) {
|
if (type == Lua.LUA_TTABLE) {
|
||||||
if (DebugUtils.IS_DEBUG)
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println(" (selected)");
|
DebugUtils.print(" (selected)");
|
||||||
variables.addElement(
|
variables.addElement(
|
||||||
new TableVariable(localVariableCount++,
|
new TableVariable(selectedVariableCount++,
|
||||||
varName,
|
varName,
|
||||||
type,
|
type,
|
||||||
(LTable) value));
|
(LTable) value));
|
||||||
} else if (type != Lua.LUA_TFUNCTION &&
|
} else if (type == LUA_TTHREAD) {
|
||||||
type != LUA_TTHREAD) {
|
// coroutines
|
||||||
if (DebugUtils.IS_DEBUG)
|
} else if (type != LUA_TFUNCTION) {
|
||||||
DebugUtils.println(" (selected)");
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.print(" (selected)");
|
||||||
variables.addElement(
|
variables.addElement(
|
||||||
new Variable(localVariableCount++,
|
new Variable(selectedVariableCount++,
|
||||||
varName,
|
varName,
|
||||||
type,
|
type,
|
||||||
value.toString()));
|
value.toString()));
|
||||||
} else {
|
|
||||||
if (DebugUtils.IS_DEBUG)
|
|
||||||
DebugUtils.println("");
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (DebugUtils.IS_DEBUG)
|
|
||||||
DebugUtils.println("");
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (DebugUtils.IS_DEBUG)
|
|
||||||
DebugUtils.println("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DebugUtils.IS_DEBUG)
|
||||||
|
DebugUtils.println("");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Variable[] result = new Variable[variables.size()];
|
|
||||||
for (int i = 0; i < variables.size(); i++) {
|
|
||||||
result[i] = (Variable) variables.elementAt(i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* step over to next line
|
* step over to next line
|
||||||
*/
|
*/
|
||||||
public void stepOver() {
|
public void stepOver() {
|
||||||
synchronized ( this ) {
|
synchronized (this) {
|
||||||
if (DebugUtils.IS_DEBUG)
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("stepOver on cc=" + cc + "...");
|
DebugUtils.println("stepOver on cc=" + cc + "...");
|
||||||
|
|
||||||
|
suspended = false;
|
||||||
|
stepping = STEP_OVER;
|
||||||
|
steppingFrame = cc;
|
||||||
|
this.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspended = false;
|
|
||||||
stepping = STEP_OVER;
|
|
||||||
steppingFrame = cc;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* step a single statement
|
* step a single statement
|
||||||
*/
|
*/
|
||||||
public void stepInto() {
|
public void stepInto() {
|
||||||
synchronized ( this ) {
|
synchronized (this) {
|
||||||
suspended = false;
|
suspended = false;
|
||||||
stepping = STEP_INTO;
|
stepping = STEP_INTO;
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return from the method call
|
* return from the method call
|
||||||
*/
|
*/
|
||||||
public void stepReturn() {
|
public void stepReturn() {
|
||||||
synchronized ( this ) {
|
synchronized (this) {
|
||||||
if (DebugUtils.IS_DEBUG)
|
if (DebugUtils.IS_DEBUG)
|
||||||
DebugUtils.println("stepReturn on cc=" + cc + "...");
|
DebugUtils.println("stepReturn on cc=" + cc + "...");
|
||||||
|
|
||||||
suspended = false;
|
suspended = false;
|
||||||
stepping = STEP_RETURN;
|
stepping = STEP_RETURN;
|
||||||
steppingFrame = cc;
|
steppingFrame = cc;
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ public class DebugUtils {
|
|||||||
if (!LoadState.SOURCE_BINARY_STRING.equals(sourceStr)) {
|
if (!LoadState.SOURCE_BINARY_STRING.equals(sourceStr)) {
|
||||||
sourceStr = sourceStr.replace('\\', '/');
|
sourceStr = sourceStr.replace('\\', '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int index = sourceStr.lastIndexOf('/');
|
||||||
|
if (index != -1) {
|
||||||
|
sourceStr = sourceStr.substring(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
return sourceStr;
|
return sourceStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,8 +210,7 @@ public class StandardLuaJVM {
|
|||||||
DebugUtils.println("start debugging...");
|
DebugUtils.println("start debugging...");
|
||||||
DebugSupport debugSupport
|
DebugSupport debugSupport
|
||||||
= new DebugSupportImpl(getRequestPort(), getEventPort());
|
= new DebugSupportImpl(getRequestPort(), getEventPort());
|
||||||
getDebugState().setDebugSupport(debugSupport);
|
getDebugState().setDebugSupport(debugSupport);
|
||||||
getDebugState().suspend();
|
|
||||||
|
|
||||||
// create closure and execute
|
// create closure and execute
|
||||||
final Closure c = new Closure(state, p);
|
final Closure c = new Closure(state, p);
|
||||||
|
|||||||
Reference in New Issue
Block a user