v 0.44, drop debug support
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" path="src/core"/>
|
<classpathentry kind="src" path="src/core"/>
|
||||||
<classpathentry kind="src" path="src/debug"/>
|
|
||||||
<classpathentry kind="src" path="src/j2me"/>
|
<classpathentry kind="src" path="src/j2me"/>
|
||||||
<classpathentry kind="src" path="src/j2se"/>
|
<classpathentry kind="src" path="src/j2se"/>
|
||||||
<classpathentry kind="src" path="src/script"/>
|
<classpathentry kind="src" path="src/script"/>
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ target
|
|||||||
build
|
build
|
||||||
luaj*.jar
|
luaj*.jar
|
||||||
jit
|
jit
|
||||||
|
*.ser
|
||||||
|
|||||||
@@ -43,7 +43,6 @@
|
|||||||
<classpath refid="cobertura.classpath" />
|
<classpath refid="cobertura.classpath" />
|
||||||
<classpath refid="wtk-libs" />
|
<classpath refid="wtk-libs" />
|
||||||
<src path="src/core"/>
|
<src path="src/core"/>
|
||||||
<src path="src/debug"/>
|
|
||||||
<src path="src/j2me"/>
|
<src path="src/j2me"/>
|
||||||
<src path="src/j2se"/>
|
<src path="src/j2se"/>
|
||||||
<src path="src/script"/>
|
<src path="src/script"/>
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
</copy>
|
</copy>
|
||||||
<javac destdir="build/core/classes" encoding="utf-8" source="1.3" target="1.1" bootclasspathref="wtk-libs">
|
<javac destdir="build/core/classes" encoding="utf-8" source="1.3" target="1.1" bootclasspathref="wtk-libs">
|
||||||
<src path="build/core/src"/>
|
<src path="build/core/src"/>
|
||||||
<src path="src/debug"/>
|
|
||||||
</javac>
|
</javac>
|
||||||
<javac destdir="build/j2me/classes" encoding="utf-8" source="1.3" target="1.1" bootclasspathref="wtk-libs">
|
<javac destdir="build/j2me/classes" encoding="utf-8" source="1.3" target="1.1" bootclasspathref="wtk-libs">
|
||||||
<classpath path="build/core/classes"/>
|
<classpath path="build/core/classes"/>
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm;
|
package org.luaj.vm;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
|
||||||
@@ -37,14 +36,17 @@ import java.io.Reader;
|
|||||||
*/
|
*/
|
||||||
abstract public class Platform {
|
abstract public class Platform {
|
||||||
|
|
||||||
public static String DEBUG_CLASS_NAME = "org.luaj.debug.DebugLuaState";
|
/**
|
||||||
|
* When non-null, name of a Java Class that implements LuaState
|
||||||
public static final String PROPERTY_LUAJ_DEBUG = "Luaj-Debug";
|
* and has a default constructor which will be used to construct
|
||||||
public static final String PROPERTY_LUAJ_DEBUG_SUSPEND_AT_START = "Luaj-Debug-SuspendAtStart";
|
* a new lua state using Platform.newLuaState()
|
||||||
public static final String PROPERTY_LUAJ_DEBUG_HOST = "Luaj-Debug-Host";
|
* @see newLuaState
|
||||||
public static final String PROPERTY_LUAJ_DEBUG_PORT = "Luaj-Debug-Port";
|
*/
|
||||||
public static final String PROPERTY_LUAJ_DEBUG_CLASS = "Luaj-Debug-Class";
|
public static String LUA_STATE_CLASS_NAME = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The singleton Platform instance in use by this JVM
|
||||||
|
*/
|
||||||
private static Platform instance;
|
private static Platform instance;
|
||||||
|
|
||||||
|
|
||||||
@@ -73,21 +75,30 @@ abstract public class Platform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of LuaState. If debug properties are present,
|
* Creates a new instance of LuaState.
|
||||||
* DebugLuaState (a LuaState with debugging capabilities) will be created.
|
|
||||||
*
|
*
|
||||||
* @return a new instance of LuaState
|
* If Platform.LUA_STATE_CLASS_NAME is not null, this method
|
||||||
|
* will attempt to create an instance using a construction such as
|
||||||
|
* (LuaState) Class.forName(Platform.LUA_STATE_CLASS_NAME).newInstance()
|
||||||
|
*
|
||||||
|
* If Platform.LUA_STATE_CLASS_NAME is null or the specified class cannot
|
||||||
|
* be instantiated for some reason, a new instance of LuaState
|
||||||
|
* will be created and used.
|
||||||
|
*
|
||||||
|
* In either case, the method LuaState.init() will be invoked, followed by
|
||||||
|
* Platform.installOptionalProperties(LuaState) on the new instance.
|
||||||
|
*
|
||||||
|
* @return a new instance of LuaState initialized via init() and installOptionalProperties()
|
||||||
|
*
|
||||||
|
* @see LUA_STATE_CLASS_NAME
|
||||||
|
* @see LuaState
|
||||||
*/
|
*/
|
||||||
public static LuaState newLuaState() {
|
public static LuaState newLuaState() {
|
||||||
Platform p = Platform.getInstance();
|
Platform p = Platform.getInstance();
|
||||||
String isDebugStr = p.getProperty(PROPERTY_LUAJ_DEBUG);
|
|
||||||
boolean isDebug = (isDebugStr != null && "true".equalsIgnoreCase(isDebugStr));
|
|
||||||
|
|
||||||
LuaState vm = null;
|
LuaState vm = null;
|
||||||
if (isDebug) {
|
if (LUA_STATE_CLASS_NAME != null) {
|
||||||
try {
|
try {
|
||||||
String c = p.getProperty(PROPERTY_LUAJ_DEBUG_CLASS);
|
vm = (LuaState) Class.forName(LUA_STATE_CLASS_NAME).newInstance();
|
||||||
vm = (LuaState) Class.forName(c!=null? c: DEBUG_CLASS_NAME).newInstance();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Warning: no debug support, " + e);
|
System.out.println("Warning: no debug support, " + e);
|
||||||
}
|
}
|
||||||
@@ -133,44 +144,12 @@ abstract public class Platform {
|
|||||||
*/
|
*/
|
||||||
abstract public String getProperty(String propertyName);
|
abstract public String getProperty(String propertyName);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an platform dependent DebugSupport instance.
|
|
||||||
*
|
|
||||||
* @return an platform dependent DebugSupport instance.
|
|
||||||
*/
|
|
||||||
abstract public DebugNetSupport getDebugSupport() throws IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install optional libraries on the LuaState.
|
* Install optional libraries on the LuaState.
|
||||||
* @param vm LuaState instance
|
* @param vm LuaState instance
|
||||||
*/
|
*/
|
||||||
abstract protected void installOptionalLibs(LuaState vm);
|
abstract protected void installOptionalLibs(LuaState vm);
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience method for the subclasses to figure out the debug host.
|
|
||||||
* @return the debug host property. If it is not present, null is returned.
|
|
||||||
*/
|
|
||||||
protected String getDebugHost() {
|
|
||||||
String host = getProperty(PROPERTY_LUAJ_DEBUG_HOST);
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience method for the subclasses to figure out the debug port.
|
|
||||||
* @return -1 if the port is not found in the platform properties; the port
|
|
||||||
* as an integer if it is present in the platform properties and valid.
|
|
||||||
*/
|
|
||||||
protected int getDebugPort() {
|
|
||||||
String portStr = getProperty(PROPERTY_LUAJ_DEBUG_PORT);
|
|
||||||
int port = -1;
|
|
||||||
if (portStr != null) {
|
|
||||||
try {
|
|
||||||
port = Integer.parseInt(portStr);
|
|
||||||
} catch (NumberFormatException e) {}
|
|
||||||
}
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute math.pow() for two numbers using double math when available.
|
* Compute math.pow() for two numbers using double math when available.
|
||||||
* @param lhs LNumber base
|
* @param lhs LNumber base
|
||||||
|
|||||||
@@ -1,34 +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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AbortException is thrown by DebugLuaState to abort the VM execution on request
|
|
||||||
* of the debugger client.
|
|
||||||
*/
|
|
||||||
public class AbortException extends RuntimeException {
|
|
||||||
private static final long serialVersionUID = 8043724992294286647L;
|
|
||||||
|
|
||||||
public AbortException(String msg) {
|
|
||||||
super(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,810 +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 java.io.IOException;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import org.luaj.debug.event.DebugEventBreakpoint;
|
|
||||||
import org.luaj.debug.event.DebugEventError;
|
|
||||||
import org.luaj.debug.net.DebugNetSupportBase;
|
|
||||||
import org.luaj.debug.request.DebugRequestLineBreakpointToggle;
|
|
||||||
import org.luaj.debug.request.DebugRequestListener;
|
|
||||||
import org.luaj.debug.request.DebugRequestStack;
|
|
||||||
import org.luaj.debug.response.DebugResponseCallgraph;
|
|
||||||
import org.luaj.debug.response.DebugResponseStack;
|
|
||||||
import org.luaj.debug.response.DebugResponseVariables;
|
|
||||||
import org.luaj.vm.CallInfo;
|
|
||||||
import org.luaj.vm.DebugNetSupport;
|
|
||||||
import org.luaj.vm.LClosure;
|
|
||||||
import org.luaj.vm.LPrototype;
|
|
||||||
import org.luaj.vm.LString;
|
|
||||||
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;
|
|
||||||
import org.luaj.vm.Platform;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <code>DebugLuaState</code> extends <code>LuaState</code> to provide the
|
|
||||||
* debugging support for luaj-vm. It defines the debugging protocol between a
|
|
||||||
* debugger, such as LuaJEclipse in Eclipse, and the luaj-vm. The
|
|
||||||
* debugger and luaj-vm communicates via <code>DebugMessage</code>. The
|
|
||||||
* debugger sends requests to the luaj-vm and receive responses and events from
|
|
||||||
* the luaj-vm. For requests that require immediately replies, luaj-vm responds
|
|
||||||
* synchronously. For events occurs in the luaj-vm, for instance, an exception
|
|
||||||
* is raised or a breakpoint is hit, luaj-vm informs the debugger when the event
|
|
||||||
* occurs.
|
|
||||||
* <p>
|
|
||||||
* <i>Debugger Requests:</i>
|
|
||||||
* <ul>
|
|
||||||
* <li><code>DebugMessageType.start</code>: The first message for the handshake
|
|
||||||
* between the debugger and the luaj-vm. The VM responds with
|
|
||||||
* <code>DebugMessageType.started</code> immediately. If the VM is paused
|
|
||||||
* on start, it will now resume the execution.
|
|
||||||
* <li><code>DebugMessageType.resume</code>: The debugger instructs the
|
|
||||||
* luaj-vm to resume the execution when the VM is suspended. No reply is needed.
|
|
||||||
* <li><code>DebugMessageType.suspend</code>: The debugger instructs the luaj-vm
|
|
||||||
* to suspend. VM replies with <code>DebugMessageType.suspendedByClient</code>
|
|
||||||
* when it is suspended.
|
|
||||||
* <li><code>DebugMessageType.lineBreakpointSet</code>: The debugger informs the
|
|
||||||
* VM that a breakpoint at the given source and line number is set. No reply
|
|
||||||
* is needed. For future improvement, VM should check if the breakpoint is
|
|
||||||
* valid and gives the debugger feedback.
|
|
||||||
* <li><code>DebugMessageType.lineBreakpointClear</code>: The debugger informs
|
|
||||||
* the VM to clear a breakpoint at the given source and line number. No reply
|
|
||||||
* is needed. For future enhancement, VM should check if the breakpoint is
|
|
||||||
* valid and gives the debugger feedback.
|
|
||||||
* <li><code>DebugMessageType.watchpointSet</code>: The debugger sets a watchpoint
|
|
||||||
* on the given source and line number. Not implemented yet.
|
|
||||||
* <li><code>DebugMessageType.watchpointClear</code>: The debugger clears a
|
|
||||||
* watchpoint at the given source and line number. Not implemented yet.
|
|
||||||
* <li><code>DebugMessageType.callgraph</code>: The debugger requests for the
|
|
||||||
* current call graph. VM replies with the call graph immediately in a debug
|
|
||||||
* message of type <code>DebugMessageType.clientRequestCallgraphReply</code>.
|
|
||||||
* <li><code>DebugMessageType.stack</code>: The debugger request for the stack
|
|
||||||
* information for the given stack. VM replies with the variables on the stack
|
|
||||||
* immediately in a debug message of type
|
|
||||||
* <code>DebugMessageType.clientRequestStackReply</code>.
|
|
||||||
* <li><code>DebugMessageType.stepInto</code>: The debugger instructs the VM
|
|
||||||
* to begin stepping in stepInto mode. No reply is needed.
|
|
||||||
* <li><code>DebugMessageType.stepOver</code>: The debugger instructs the VM to
|
|
||||||
* begin stepping in stepOver mode. No rely is needed.
|
|
||||||
* <li><code>DebugMessageType.stepReturn</code>: The debugger instructs the VM
|
|
||||||
* to begin stepping in stepReturn mode. No reply is needed.
|
|
||||||
* <li><code>DebugMessageType.global</code>: The debug request the information
|
|
||||||
* about the globals. VM replies with global variables in a debug message of
|
|
||||||
* type <code>DebugMessageType.clientRequestGlobalReply</code>.
|
|
||||||
* <li><code>DebugMessageType.disconnect</code>: The debugger informs the VM
|
|
||||||
* that it is about to disconnect from the VM. VM resets its state and responds
|
|
||||||
* with <code>DebugMessageType.disconnected</code> immediately.
|
|
||||||
* <li><code>DebugMessageType.exit</code>: The debugger instructs the VM to
|
|
||||||
* terminate. VM prepares for termination and responds with
|
|
||||||
* <code>DebugMessageType.terminated</code>.
|
|
||||||
* <li><code>DebugMessageType.reset</code>: This is an internal debug message.
|
|
||||||
* When the communication layer detects that the debugger or the debug service
|
|
||||||
* exits abnormally, it sends the message to the VM for reset. VM acts upon the
|
|
||||||
* message and reset its internal state.
|
|
||||||
* <li><code>DebugMessageType.debugServiceDown</code>: This message is sent from
|
|
||||||
* the debug service (on-device remote debugging) when the debug service observed
|
|
||||||
* that the debugger exits abnormally. Before the debug service restarts the debug
|
|
||||||
* session, it informs the VM to reset itself.
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* <i>VM Responses and Events:</i>
|
|
||||||
* <ul>
|
|
||||||
* <li><code>DebugMessageType.clientRequestCallgraphReply</code>: VM replies to
|
|
||||||
* the <code>DebugMessageType.callgraph</code> request with the information
|
|
||||||
* about the current call graph. A call graph is made of a list of call stacks.
|
|
||||||
* Call stacks are organized chronically with the most recent call on the top
|
|
||||||
* of the stack.
|
|
||||||
* <li><code>DebugMessageType.clientRequestStackReply</code>: VM replies
|
|
||||||
* to the <code>DebugMessageType.stack</code> request with the variables visible
|
|
||||||
* on the call stack <code>i</code> where <code>i</code> the call stack index
|
|
||||||
* ranging between 0 and <code>LuaState.calls.length</code>.
|
|
||||||
* <li><code>DebugMessageType.clientRequestGlobalReply</code>: VM replies to the
|
|
||||||
* <code>DebugMessageType.global</code> request with all the globals.
|
|
||||||
* <li><code>DebugMessageType.started</code>: VM replies when a
|
|
||||||
* <code>DebugMessageType.start</code> request is received.
|
|
||||||
* <li><code>DebugMessageType.resumedOnSteppingEnd</code>: VM informs the debugger
|
|
||||||
* that VM is getting out of the stepping mode upon step return because it has
|
|
||||||
* reached the last call stack.
|
|
||||||
* <li><code>DebugMessageType.suspendedByClient</code>: VM sends the event to
|
|
||||||
* respond to a debugger pause action.
|
|
||||||
* <li><code>DebugMessageType.suspendedOnBreakpoint</code>: VM sends the event
|
|
||||||
* when a breakpoint is hit during the execution.
|
|
||||||
* <li><code>DebugMessageType.suspendedOnWatchpoint</code>: Not implemented yet.
|
|
||||||
* VM sends the event when VM is paused to evaluate a watchpoint.
|
|
||||||
* <li><code>DebugMessageType.suspendedOnStepping</code>: VM sends the event when
|
|
||||||
* VM is paused during the stepping. The debugger has instructed the VM to begin
|
|
||||||
* stepping into, over or return earlier.
|
|
||||||
* <li><code>DebugMessageType.suspendedOnError</code>: VM sends the event when
|
|
||||||
* an error is raised in VM.
|
|
||||||
* <li><code>DebugMessageType.terminated</code>: VM sends the event when it is
|
|
||||||
* ready to exit.
|
|
||||||
* <li><code>DebugMessageType.disconnected</code>: VM sends the event when it
|
|
||||||
* has de-attached the debugger from the debug session.
|
|
||||||
* <li><code>DebugMessageType.outputRedirect</code>: VM forwards the print
|
|
||||||
* output to the debugger console.
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
*/
|
|
||||||
public class DebugLuaState extends LuaState implements DebugRequestListener {
|
|
||||||
private static final boolean TRACE = (null != System.getProperty("TRACE"));
|
|
||||||
|
|
||||||
// stepping constants and stepping state
|
|
||||||
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_RETURN = 3;
|
|
||||||
protected int stepping = STEP_NONE;
|
|
||||||
protected boolean shouldPauseForStepping = false;
|
|
||||||
protected int steppingFrame = -1;
|
|
||||||
|
|
||||||
protected Hashtable breakpoints = new Hashtable();
|
|
||||||
protected boolean exiting = false;
|
|
||||||
protected boolean suspended = false;
|
|
||||||
protected boolean bSuspendOnStart = false;
|
|
||||||
protected int lastline = -1;
|
|
||||||
protected String lastSource;
|
|
||||||
protected DebugNetSupportBase debugSupport;
|
|
||||||
protected LuaErrorException lastError;
|
|
||||||
|
|
||||||
final String openUpVal = "+";
|
|
||||||
final String closedUpVal = "-";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance of DebugLuaState.
|
|
||||||
*
|
|
||||||
* @deprecated As of version 0.10, replaced by {@link #Platform.newLuaState()}
|
|
||||||
*/
|
|
||||||
public DebugLuaState() {}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see org.luaj.vm.LuaState#init()
|
|
||||||
*/
|
|
||||||
public void init() {
|
|
||||||
super.init();
|
|
||||||
|
|
||||||
Platform platform = Platform.getInstance();
|
|
||||||
|
|
||||||
// set if the vm should be suspended at start
|
|
||||||
String suspendOnStartStr = platform.getProperty(Platform.PROPERTY_LUAJ_DEBUG_SUSPEND_AT_START);
|
|
||||||
boolean bSuspendOnStart = (suspendOnStartStr != null && "true".equalsIgnoreCase(suspendOnStartStr));
|
|
||||||
setSuspendAtStart(bSuspendOnStart);
|
|
||||||
|
|
||||||
// set up the debug networking support
|
|
||||||
try {
|
|
||||||
DebugNetSupport debugSupport = platform.getDebugSupport();
|
|
||||||
if (debugSupport != null)
|
|
||||||
setDebugSupport(debugSupport);
|
|
||||||
else
|
|
||||||
System.out.println("Warning: DebugNetSupport is missing. Cannot communicate with a debugging client.");
|
|
||||||
} catch (IOException e) {
|
|
||||||
// no debug client can talk to VM, but VM can continue functioning
|
|
||||||
System.out.println("Warning: cannot communicate with a debugging client due to error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see org.luaj.vm.LuaState#shutdown()
|
|
||||||
*/
|
|
||||||
public void shutdown() {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setDebugSupport(DebugNetSupport debugSupport)
|
|
||||||
throws IOException {
|
|
||||||
if (debugSupport == null) {
|
|
||||||
throw new IllegalArgumentException("DebugNetSupportBase cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.debugSupport = (DebugNetSupportBase) debugSupport;
|
|
||||||
this.debugSupport.setDebugStackState(this);
|
|
||||||
debugSupport.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSuspendAtStart(boolean bSuspendAtStart) {
|
|
||||||
this.bSuspendOnStart = bSuspendAtStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void debugAssert(boolean b) {
|
|
||||||
if (!b)
|
|
||||||
error("assert failure");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
} 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) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// debug hooks
|
|
||||||
public void debugHooks(int pc) {
|
|
||||||
if (TRACE) {
|
|
||||||
CallInfo ci = calls[cc];
|
|
||||||
LClosure cl = ci.closure;
|
|
||||||
LPrototype p = cl.p;
|
|
||||||
Print.printState(this, base, top, base+p.maxstacksize, cl, pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exiting) {
|
|
||||||
throw new AbortException("aborted by debug client");
|
|
||||||
}
|
|
||||||
|
|
||||||
//*
|
|
||||||
if (TRACE) {
|
|
||||||
System.out.println("entered debugHook on pc=" + pc + "...Line: " + getFileLine(cc));
|
|
||||||
for (int j = 0; j <= cc; j++) {
|
|
||||||
System.out.println("calls[" + j + "]: base=" + calls[j].base + ", top=" + calls[j].top + " , pc=" + calls[j].pc);
|
|
||||||
dumpStack(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//*/
|
|
||||||
synchronized (this) {
|
|
||||||
while (bSuspendOnStart) {
|
|
||||||
try {
|
|
||||||
this.wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CallInfo currentCallInfo = calls[cc];
|
|
||||||
LPrototype 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 = getSourceFileName(currentProto.source);
|
|
||||||
if (!isStepping() && lastline == line && source.equals(lastSource)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TRACE)
|
|
||||||
System.out.println("debugHook - executing line: " + line);
|
|
||||||
|
|
||||||
int i = currentProto.code[pc];
|
|
||||||
int opCode = LuaState.GET_OPCODE(i);
|
|
||||||
if (isStepping() && opCode == LuaState.OP_RETURN && cc == 0) {
|
|
||||||
cancelStepping();
|
|
||||||
} else if (shouldPauseForStepping) {
|
|
||||||
shouldPauseForStepping = false;
|
|
||||||
suspendOnStepping();
|
|
||||||
} else if (stepping == STEP_INTO) {
|
|
||||||
if (lastline != line) {
|
|
||||||
suspendOnStepping();
|
|
||||||
} else if (opCode == LuaState.OP_CALL) {
|
|
||||||
shouldPauseForStepping = true;
|
|
||||||
}
|
|
||||||
} else if (stepping == STEP_OVER) {
|
|
||||||
if ((steppingFrame == cc && lastline != line)||
|
|
||||||
(steppingFrame > cc)) {
|
|
||||||
suspendOnStepping();
|
|
||||||
}
|
|
||||||
} else if (stepping == STEP_RETURN) {
|
|
||||||
if ((opCode == LuaState.OP_RETURN && cc == this.steppingFrame) ||
|
|
||||||
(opCode == LuaState.OP_TAILCALL && cc == this.steppingFrame)) {
|
|
||||||
shouldPauseForStepping = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for a break point if we aren't suspended already
|
|
||||||
if (!suspended && lastline != line) {
|
|
||||||
if (TRACE)
|
|
||||||
System.out.println("Source: " + currentProto.source);
|
|
||||||
String fileName = getSourceFileName(source);
|
|
||||||
String breakpointKey = constructBreakpointKey(fileName, line);
|
|
||||||
if (breakpoints.containsKey(breakpointKey)) {
|
|
||||||
if (TRACE)
|
|
||||||
System.out.println("hitting breakpoint "
|
|
||||||
+ constructBreakpointKey(fileName, line));
|
|
||||||
if (debugSupport != null) {
|
|
||||||
debugSupport.notifyDebugEvent(
|
|
||||||
new DebugEventBreakpoint(fileName, 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();
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
ie.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isStepping() {
|
|
||||||
return stepping != STEP_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelStepping() {
|
|
||||||
if (debugSupport != null) {
|
|
||||||
debugSupport.notifyDebugEvent(
|
|
||||||
new DebugMessage(DebugMessageType.resumedOnSteppingEnd));
|
|
||||||
}
|
|
||||||
stepping = STEP_NONE;
|
|
||||||
steppingFrame = -1;
|
|
||||||
shouldPauseForStepping = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void suspendOnStepping() {
|
|
||||||
if (debugSupport != null) {
|
|
||||||
debugSupport.notifyDebugEvent(
|
|
||||||
new DebugMessage(DebugMessageType.suspendedOnStepping));
|
|
||||||
}
|
|
||||||
suspended = true;
|
|
||||||
steppingFrame = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current line number
|
|
||||||
*
|
|
||||||
* @param pc program counter
|
|
||||||
* @return the line number corresponding to the pc
|
|
||||||
*/
|
|
||||||
private int getLineNumber(CallInfo ci) {
|
|
||||||
int[] lineNumbers = ci.closure.p.lineinfo;
|
|
||||||
int pc = getCurrentPc(ci);
|
|
||||||
int line = (lineNumbers != null && lineNumbers.length > pc ?
|
|
||||||
lineNumbers[pc] :
|
|
||||||
-1);
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------ commands coming from the debugger -------------------
|
|
||||||
|
|
||||||
public void handleRequest(DebugMessage request) {
|
|
||||||
if (this.debugSupport == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"DebugNetSupportBase must be defined.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TRACE)
|
|
||||||
System.out.println("DebugStackState is handling request: "
|
|
||||||
+ request.toString());
|
|
||||||
|
|
||||||
DebugMessageType requestType = request.getType();
|
|
||||||
if (DebugMessageType.start == requestType) {
|
|
||||||
DebugMessage event = new DebugMessage(DebugMessageType.started);
|
|
||||||
debugSupport.notifyDebugEvent(event);
|
|
||||||
cancelSuspendOnStart();
|
|
||||||
} else if (DebugMessageType.exit == requestType) {
|
|
||||||
stop();
|
|
||||||
} else if (DebugMessageType.disconnect == requestType) {
|
|
||||||
disconnect();
|
|
||||||
} else if (DebugMessageType.debugServiceDown == requestType) {
|
|
||||||
disconnectFromDebugService();
|
|
||||||
} else if (DebugMessageType.reset == requestType) {
|
|
||||||
reset();
|
|
||||||
} else if (DebugMessageType.suspend == requestType) {
|
|
||||||
suspend();
|
|
||||||
DebugMessage event = new DebugMessage(DebugMessageType.suspendedByClient);
|
|
||||||
debugSupport.notifyDebugEvent(event);
|
|
||||||
} else if (DebugMessageType.resume == requestType) {
|
|
||||||
resume();
|
|
||||||
} else if (DebugMessageType.lineBreakpointSet == requestType) {
|
|
||||||
DebugRequestLineBreakpointToggle setBreakpointRequest
|
|
||||||
= (DebugRequestLineBreakpointToggle) request;
|
|
||||||
setBreakpoint(setBreakpointRequest.getSource(),
|
|
||||||
setBreakpointRequest.getLineNumber());
|
|
||||||
} else if (DebugMessageType.lineBreakpointClear == requestType) {
|
|
||||||
DebugRequestLineBreakpointToggle clearBreakpointRequest
|
|
||||||
= (DebugRequestLineBreakpointToggle) request;
|
|
||||||
clearBreakpoint(clearBreakpointRequest.getSource(),
|
|
||||||
clearBreakpointRequest.getLineNumber());
|
|
||||||
} else if (DebugMessageType.callgraph == requestType) {
|
|
||||||
DebugResponseCallgraph callgraph
|
|
||||||
= new DebugResponseCallgraph(getCallgraph());
|
|
||||||
debugSupport.notifyDebugEvent(callgraph);
|
|
||||||
} else if (DebugMessageType.stack == requestType) {
|
|
||||||
DebugRequestStack stackRequest = (DebugRequestStack) request;
|
|
||||||
int index = stackRequest.getIndex();
|
|
||||||
DebugResponseStack stackState
|
|
||||||
= new DebugResponseStack(index, getStack(index));
|
|
||||||
debugSupport.notifyDebugEvent(stackState);
|
|
||||||
} else if (DebugMessageType.global == requestType) {
|
|
||||||
DebugResponseVariables globals
|
|
||||||
= new DebugResponseVariables(getGlobals(), DebugMessageType.clientRequestGlobalReply);
|
|
||||||
debugSupport.notifyDebugEvent(globals);
|
|
||||||
} else if (DebugMessageType.stepInto == requestType) {
|
|
||||||
stepInto();
|
|
||||||
} else if (DebugMessageType.stepOver == requestType) {
|
|
||||||
stepOver();
|
|
||||||
} else if (DebugMessageType.stepReturn == requestType) {
|
|
||||||
stepReturn();
|
|
||||||
} else {
|
|
||||||
throw new java.lang.IllegalArgumentException("unkown request type: "
|
|
||||||
+ request.getType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* suspend the execution
|
|
||||||
*/
|
|
||||||
public synchronized void suspend() {
|
|
||||||
suspended = true;
|
|
||||||
stepping = STEP_NONE;
|
|
||||||
lastline = -1;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the VM is suspended on start, this method resumes the execution.
|
|
||||||
*/
|
|
||||||
protected synchronized void cancelSuspendOnStart() {
|
|
||||||
if (bSuspendOnStart) {
|
|
||||||
bSuspendOnStart = false;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resume the execution
|
|
||||||
*/
|
|
||||||
public synchronized void resume() {
|
|
||||||
this.suspended = false;
|
|
||||||
this.stepping = STEP_NONE;
|
|
||||||
this.shouldPauseForStepping = false;
|
|
||||||
this.steppingFrame = -1;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops the debugging communication with the debug client and terminate the
|
|
||||||
* VM execution.
|
|
||||||
*/
|
|
||||||
public synchronized void stop() {
|
|
||||||
if (exiting) return;
|
|
||||||
|
|
||||||
if (this.debugSupport != null) {
|
|
||||||
DebugMessage event = new DebugMessage(DebugMessageType.terminated);
|
|
||||||
debugSupport.notifyDebugEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit();
|
|
||||||
|
|
||||||
if (this.debugSupport != null) {
|
|
||||||
debugSupport.stop();
|
|
||||||
debugSupport = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disconnect() {
|
|
||||||
if (this.debugSupport == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"DebugNetSupportBase must be defined.");
|
|
||||||
}
|
|
||||||
|
|
||||||
reset();
|
|
||||||
DebugMessage event = new DebugMessage(DebugMessageType.disconnected);
|
|
||||||
debugSupport.notifyDebugEvent(event);
|
|
||||||
debugSupport.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disconnectFromDebugService() {
|
|
||||||
if (this.debugSupport == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"DebugNetSupportBase must be defined.");
|
|
||||||
}
|
|
||||||
|
|
||||||
reset();
|
|
||||||
debugSupport.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void reset() {
|
|
||||||
this.breakpoints.clear();
|
|
||||||
if (this.suspended) {
|
|
||||||
resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* terminate the execution
|
|
||||||
*/
|
|
||||||
public synchronized void exit() {
|
|
||||||
exiting = true;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set breakpoint at line N
|
|
||||||
*
|
|
||||||
* @param N -- the line to set the breakpoint at
|
|
||||||
*/
|
|
||||||
public void setBreakpoint(String source, int lineNumber) {
|
|
||||||
String fileName = getSourceFileName(source);
|
|
||||||
String breakpointKey = constructBreakpointKey(fileName, lineNumber);
|
|
||||||
|
|
||||||
breakpoints.put(breakpointKey, Boolean.TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String constructBreakpointKey(String source, int lineNumber) {
|
|
||||||
return source + ":" + lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* clear breakpoint at line lineNumber of source source
|
|
||||||
*/
|
|
||||||
public void clearBreakpoint(String source, int lineNumber) {
|
|
||||||
String fileName = getSourceFileName(source);
|
|
||||||
String breakpointKey = constructBreakpointKey(fileName, lineNumber);
|
|
||||||
|
|
||||||
breakpoints.remove(breakpointKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return the current call graph (i.e. stack frames from new to old, include
|
|
||||||
* information about file, method, etc.)
|
|
||||||
*/
|
|
||||||
public StackFrame[] getCallgraph() {
|
|
||||||
int n = cc;
|
|
||||||
|
|
||||||
if (n < 0 || n >= calls.length)
|
|
||||||
return new StackFrame[0];
|
|
||||||
|
|
||||||
int length = n + 1;
|
|
||||||
StackFrame[] frames = new StackFrame[length];
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
CallInfo ci = calls[i];
|
|
||||||
String src = getSourceFileName(ci.closure.p.source);
|
|
||||||
frames[length - i - 1] = new StackFrame(src, getLineNumber(ci));
|
|
||||||
}
|
|
||||||
return frames;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the visible local variables on a stack frame.
|
|
||||||
* @param index The stack frame index
|
|
||||||
* @return the visible local variables on the given stack frame.
|
|
||||||
*/
|
|
||||||
public Variable[] getStack(int index) {
|
|
||||||
if (index < 0 || index > cc) {
|
|
||||||
throw new RuntimeException("invalid stack index");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CallInfo callInfo = calls[index];
|
|
||||||
LClosure closure = callInfo.closure;
|
|
||||||
LPrototype prototype = closure.p;
|
|
||||||
LocVars[] localVariables = prototype.locvars;
|
|
||||||
|
|
||||||
Vector variables = new Vector();
|
|
||||||
|
|
||||||
int pc = getCurrentPc(callInfo);
|
|
||||||
|
|
||||||
// add upvalues
|
|
||||||
for ( int i=0; i<prototype.nups; i++ ) {
|
|
||||||
if ( closure.upVals[i] != null ) {
|
|
||||||
LString[] ups = prototype.upvalues;
|
|
||||||
String upstate = (closure.upVals[i].isClosed()? closedUpVal: openUpVal);
|
|
||||||
String name = (ups!=null && ups.length>i? String.valueOf(ups[i]): "?");
|
|
||||||
LValue value = closure.upVals[i].getValue();
|
|
||||||
addVariable( variables, upstate+name, value );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add locals
|
|
||||||
for (int i = 0; i < localVariables.length; i++) {
|
|
||||||
if (isActiveVariable(pc, localVariables[i])) {
|
|
||||||
String name = localVariables[i].varname.toJavaString();
|
|
||||||
LValue value = stack[callInfo.base+i];
|
|
||||||
addVariable(variables, name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// convert to array
|
|
||||||
Variable[] result = new Variable[variables.size()];
|
|
||||||
variables.copyInto(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the current LPrototype is lexically defined in the caller scope.
|
|
||||||
* @param p -- current LPrototype
|
|
||||||
* @param ci -- caller info
|
|
||||||
* @return true if the current LPrototype is lexically defined in the
|
|
||||||
* caller scope; false, otherwise.
|
|
||||||
*/
|
|
||||||
protected boolean isInScope(LPrototype p, CallInfo ci) {
|
|
||||||
LPrototype[] enclosingProtos = ci.closure.p.p;
|
|
||||||
boolean bFound = false;
|
|
||||||
for (int i = 0; enclosingProtos!= null && i < enclosingProtos.length; i++) {
|
|
||||||
if (enclosingProtos[i] == p) {
|
|
||||||
bFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the visible globals to the current VM.
|
|
||||||
* @return the visible globals.
|
|
||||||
*/
|
|
||||||
public Variable[] getGlobals() {
|
|
||||||
Vector variables = new Vector();
|
|
||||||
variables.addElement(
|
|
||||||
new TableVariable(0,
|
|
||||||
"*Globals*",
|
|
||||||
Lua.LUA_TTABLE,
|
|
||||||
(LTable) _G));
|
|
||||||
|
|
||||||
Variable[] result = new Variable[variables.size()];
|
|
||||||
for (int i = 0; i < variables.size(); i++) {
|
|
||||||
result[i] = (Variable) variables.elementAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debugging Utility. Dumps the variables for a given call frame.
|
|
||||||
* @param index Index of the call frame
|
|
||||||
*/
|
|
||||||
private void dumpStack(int index) {
|
|
||||||
if (index < 0 || index > cc) return;
|
|
||||||
|
|
||||||
CallInfo callInfo = calls[index];
|
|
||||||
LPrototype prototype = callInfo.closure.p;
|
|
||||||
LocVars[] localVariables = prototype.locvars;
|
|
||||||
System.out.println("Stack Frame: " + index + " [" + base + "," + top + "]," +
|
|
||||||
" # of localvars: " + localVariables.length + ", pc=" + callInfo.pc +
|
|
||||||
" # upvals: " + prototype.nups );
|
|
||||||
|
|
||||||
int pc = getCurrentPc(callInfo);
|
|
||||||
for (int i = 0; i < localVariables.length; i++) {
|
|
||||||
if (!isActiveVariable(pc, localVariables[i])) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
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++){
|
|
||||||
System.out.println("stack[" + i + "]=" + stack[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a variable is in scope.
|
|
||||||
* @param pc -- Current program counter.
|
|
||||||
* @param localVariable -- A local variable.
|
|
||||||
* @return true if the variable is active under the given program counter;
|
|
||||||
* false, otherwise.
|
|
||||||
*/
|
|
||||||
private boolean isActiveVariable(int pc, LocVars localVariable) {
|
|
||||||
return pc >= localVariable.startpc && pc <= localVariable.endpc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an active variable for the given call frame to the list of variables.
|
|
||||||
* @param variables -- the list of active variables.
|
|
||||||
* @param varName -- the name of the variable
|
|
||||||
* @param index -- the value of the variable
|
|
||||||
*/
|
|
||||||
private void addVariable(Vector variables, String varName, LValue value) {
|
|
||||||
|
|
||||||
int selectedVariableCount = variables.size();
|
|
||||||
if (TRACE) {
|
|
||||||
System.out.print("\tVariable: " + varName);
|
|
||||||
System.out.print("\tValue: " + value);
|
|
||||||
System.out.print("\tN: "+selectedVariableCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null) {
|
|
||||||
int type = value.luaGetType();
|
|
||||||
if (TRACE)
|
|
||||||
System.out.print("\tType: " + value.luaGetTypeName());
|
|
||||||
if (type == Lua.LUA_TTABLE) {
|
|
||||||
variables.addElement(new TableVariable( selectedVariableCount, varName, type, (LTable) value));
|
|
||||||
} else if (type == LUA_TSTRING) {
|
|
||||||
variables.addElement(new Variable(selectedVariableCount, varName, type, "'"+value.toString()+"'"));
|
|
||||||
} else {
|
|
||||||
variables.addElement(new Variable(selectedVariableCount, varName, type, value.toString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TRACE)
|
|
||||||
System.out.print("");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* step over to next line
|
|
||||||
*/
|
|
||||||
public synchronized void stepOver() {
|
|
||||||
suspended = false;
|
|
||||||
stepping = STEP_OVER;
|
|
||||||
steppingFrame = cc;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* step to the next statement
|
|
||||||
*/
|
|
||||||
public synchronized void stepInto() {
|
|
||||||
suspended = false;
|
|
||||||
stepping = STEP_INTO;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return from the current method call
|
|
||||||
*/
|
|
||||||
public synchronized void stepReturn() {
|
|
||||||
suspended = false;
|
|
||||||
stepping = STEP_RETURN;
|
|
||||||
steppingFrame = cc;
|
|
||||||
this.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class DebugMessage implements Serializable {
|
|
||||||
protected DebugMessageType type;
|
|
||||||
|
|
||||||
public DebugMessage(DebugMessageType type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DebugMessageType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(DebugMessageType type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#toString()
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
return type.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, DebugMessage object)
|
|
||||||
throws IOException {
|
|
||||||
SerializationHelper.serialize(object.getType(), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in) throws IOException {
|
|
||||||
DebugMessageType type = (DebugMessageType) SerializationHelper
|
|
||||||
.deserialize(in);
|
|
||||||
return new DebugMessage(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +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 java.io.DataInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
|
|
||||||
public class DebugMessageType extends EnumType {
|
|
||||||
// requests
|
|
||||||
public static final DebugMessageType start = new DebugMessageType("start", 0);
|
|
||||||
public static final DebugMessageType resume = new DebugMessageType("resume", 1);
|
|
||||||
public static final DebugMessageType suspend = new DebugMessageType("suspend", 2);
|
|
||||||
public static final DebugMessageType exit = new DebugMessageType("exit", 3);
|
|
||||||
public static final DebugMessageType disconnect = new DebugMessageType("disconnect", 4);
|
|
||||||
public static final DebugMessageType lineBreakpointSet = new DebugMessageType("lineBreakpointSet", 5);
|
|
||||||
public static final DebugMessageType lineBreakpointClear = new DebugMessageType("lineBreakpointClear", 6);
|
|
||||||
public static final DebugMessageType watchpointSet = new DebugMessageType("watchpointSet", 7);
|
|
||||||
public static final DebugMessageType watchpointClear = new DebugMessageType("watchpointClear", 8);
|
|
||||||
public static final DebugMessageType callgraph = new DebugMessageType("callgraph", 9);
|
|
||||||
public static final DebugMessageType stack = new DebugMessageType("stack", 10);
|
|
||||||
public static final DebugMessageType stepInto = new DebugMessageType("stepInto", 11);
|
|
||||||
public static final DebugMessageType stepOver = new DebugMessageType("stepOver", 12);
|
|
||||||
public static final DebugMessageType stepReturn = new DebugMessageType("stepReturn", 13);
|
|
||||||
public static final DebugMessageType global = new DebugMessageType("global", 14);
|
|
||||||
public static final DebugMessageType reset = new DebugMessageType("reset", 15);
|
|
||||||
public static final DebugMessageType debugServiceDown = new DebugMessageType("debugServiceDown", 16);
|
|
||||||
|
|
||||||
// responses
|
|
||||||
public static final DebugMessageType clientRequestCallgraphReply = new DebugMessageType("clientRequestCallgraphReply", 17);
|
|
||||||
public static final DebugMessageType clientRequestStackReply = new DebugMessageType("clientRequestStackReply", 18);
|
|
||||||
public static final DebugMessageType clientRequestGlobalReply = new DebugMessageType("clientRequestGlobalReply", 19);
|
|
||||||
|
|
||||||
// events
|
|
||||||
public static final DebugMessageType started = new DebugMessageType("started", 20);
|
|
||||||
public static final DebugMessageType suspendedByClient = new DebugMessageType("suspendedByClient", 21);
|
|
||||||
public static final DebugMessageType suspendedOnBreakpoint = new DebugMessageType("suspendedOnBreakpoint", 22);
|
|
||||||
public static final DebugMessageType suspendedOnWatchpoint = new DebugMessageType("suspendedOnWatchpoint", 23);
|
|
||||||
public static final DebugMessageType suspendedOnStepping = new DebugMessageType("suspendedOnStepping", 24);
|
|
||||||
public static final DebugMessageType suspendedOnError = new DebugMessageType("suspendedOnError", 25);
|
|
||||||
public static final DebugMessageType resumedOnSteppingEnd = new DebugMessageType("resumedOnSteppingEnd", 26);
|
|
||||||
public static final DebugMessageType outputRedirect = new DebugMessageType("outputRedirect", 27);
|
|
||||||
public static final DebugMessageType terminated = new DebugMessageType("terminated", 28);
|
|
||||||
public static final DebugMessageType disconnected = new DebugMessageType("disconnected", 29);
|
|
||||||
|
|
||||||
protected static DebugMessageType[] ENUMS = new DebugMessageType[] {
|
|
||||||
// requests
|
|
||||||
start,
|
|
||||||
resume,
|
|
||||||
suspend,
|
|
||||||
exit,
|
|
||||||
disconnect,
|
|
||||||
lineBreakpointSet,
|
|
||||||
lineBreakpointClear,
|
|
||||||
watchpointSet,
|
|
||||||
watchpointClear,
|
|
||||||
callgraph,
|
|
||||||
stack,
|
|
||||||
stepInto,
|
|
||||||
stepOver,
|
|
||||||
stepReturn,
|
|
||||||
global,
|
|
||||||
reset,
|
|
||||||
debugServiceDown,
|
|
||||||
|
|
||||||
// responses
|
|
||||||
clientRequestCallgraphReply,
|
|
||||||
clientRequestStackReply,
|
|
||||||
clientRequestGlobalReply,
|
|
||||||
|
|
||||||
// events
|
|
||||||
started,
|
|
||||||
suspendedByClient,
|
|
||||||
suspendedOnBreakpoint,
|
|
||||||
suspendedOnWatchpoint,
|
|
||||||
suspendedOnStepping,
|
|
||||||
suspendedOnError,
|
|
||||||
resumedOnSteppingEnd,
|
|
||||||
outputRedirect,
|
|
||||||
terminated,
|
|
||||||
disconnected
|
|
||||||
};
|
|
||||||
|
|
||||||
protected DebugMessageType(String name, int ordinal) {
|
|
||||||
super(name, ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessageType deserialize(DataInputStream in)
|
|
||||||
throws IOException {
|
|
||||||
int ordinal = in.readInt();
|
|
||||||
if (ordinal < 0 || ordinal >= ENUMS.length) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"DebugMessageType: ordinal is out of the range.");
|
|
||||||
}
|
|
||||||
return ENUMS[ordinal];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class EnumType implements Serializable {
|
|
||||||
protected String name;
|
|
||||||
protected int ordinal;
|
|
||||||
|
|
||||||
public EnumType(String name, int ordinal) {
|
|
||||||
this.name = name;
|
|
||||||
this.ordinal = ordinal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean equals(Object other) {
|
|
||||||
return (this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int hashCode() {
|
|
||||||
return System.identityHashCode(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final String name() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int ordinal() {
|
|
||||||
return this.ordinal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, EnumType enumType) throws IOException {
|
|
||||||
out.writeInt(enumType.ordinal());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +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 java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class NullableString implements Serializable {
|
|
||||||
protected String string;
|
|
||||||
|
|
||||||
public NullableString(String someString) {
|
|
||||||
this.string = someString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNullableString() {
|
|
||||||
return (this.string == null) ? "[NULL]" : this.string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRawString() {
|
|
||||||
return (this.string.equals("[NULL]")) ? null : this.string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, NullableString string)
|
|
||||||
throws IOException {
|
|
||||||
out.writeUTF(string.getNullableString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NullableString deserialize(DataInputStream in)
|
|
||||||
throws IOException {
|
|
||||||
String string = in.readUTF();
|
|
||||||
return new NullableString(string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
import org.luaj.debug.event.DebugEventListener;
|
|
||||||
import org.luaj.debug.event.DebugEventOutputRedirect;
|
|
||||||
|
|
||||||
public class RedirectOutputStream extends OutputStream {
|
|
||||||
|
|
||||||
protected DebugEventListener listener;
|
|
||||||
protected int count;
|
|
||||||
protected byte[] buffer;
|
|
||||||
|
|
||||||
public RedirectOutputStream(DebugEventListener listener) {
|
|
||||||
this(listener, 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RedirectOutputStream(DebugEventListener listener, int count) {
|
|
||||||
this.listener = listener;
|
|
||||||
this.count = 0;
|
|
||||||
this.buffer = new byte[count];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws IOException {
|
|
||||||
flushBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void flush() throws IOException {
|
|
||||||
flushBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(byte[] b, int off, int len) throws IOException {
|
|
||||||
super.write(b, off, len);
|
|
||||||
flushBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(byte[] b) throws IOException {
|
|
||||||
super.write(b);
|
|
||||||
flushBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void write(int b) throws IOException {
|
|
||||||
if (count >= buffer.length) {
|
|
||||||
flushBuffer();
|
|
||||||
}
|
|
||||||
buffer[count++] = (byte)b;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized void flushBuffer(){
|
|
||||||
if (count > 0) {
|
|
||||||
String msg = new String(buffer, 0, this.count);
|
|
||||||
listener.notifyDebugEvent(new DebugEventOutputRedirect(msg));
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface Serializable { }
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.event.DebugEventBreakpoint;
|
|
||||||
import org.luaj.debug.event.DebugEventError;
|
|
||||||
import org.luaj.debug.event.DebugEventOutputRedirect;
|
|
||||||
import org.luaj.debug.request.DebugRequestLineBreakpointToggle;
|
|
||||||
import org.luaj.debug.request.DebugRequestStack;
|
|
||||||
import org.luaj.debug.response.DebugResponseCallgraph;
|
|
||||||
import org.luaj.debug.response.DebugResponseStack;
|
|
||||||
import org.luaj.debug.response.DebugResponseVariables;
|
|
||||||
|
|
||||||
public class SerializationHelper {
|
|
||||||
|
|
||||||
public static byte[] serialize(Serializable object) throws IOException {
|
|
||||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
|
||||||
DataOutputStream dout = new DataOutputStream(bout);
|
|
||||||
|
|
||||||
serialize(object, dout);
|
|
||||||
|
|
||||||
byte[] data = bout.toByteArray();
|
|
||||||
|
|
||||||
bout.close();
|
|
||||||
dout.close();
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Serializable deserialize(byte[] data) throws IOException {
|
|
||||||
ByteArrayInputStream bin = new ByteArrayInputStream(data);
|
|
||||||
DataInputStream din = new DataInputStream(bin);
|
|
||||||
|
|
||||||
Serializable object = deserialize(din);
|
|
||||||
|
|
||||||
bin.close();
|
|
||||||
din.close();
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final int SERIAL_TYPE_NullableString = 0;
|
|
||||||
static final int SERIAL_TYPE_TableVariable = 1;
|
|
||||||
static final int SERIAL_TYPE_Variable = 2;
|
|
||||||
static final int SERIAL_TYPE_StackFrame = 3;
|
|
||||||
static final int SERIAL_TYPE_DebugMessageType = 4;
|
|
||||||
static final int SERIAL_TYPE_DebugMessage = 5;
|
|
||||||
static final int SERIAL_TYPE_DebugRequestStack = 6;
|
|
||||||
static final int SERIAL_TYPE_DebugRequestLineBreakpointToggle = 7;
|
|
||||||
static final int SERIAL_TYPE_DebugEventBreakpoint = 8;
|
|
||||||
static final int SERIAL_TYPE_DebugEventError = 9;
|
|
||||||
static final int SERIAL_TYPE_DebugResponseCallgraph = 10;
|
|
||||||
static final int SERIAL_TYPE_DebugResponseVariables = 11;
|
|
||||||
static final int SERIAL_TYPE_DebugResponseStack = 12;
|
|
||||||
static final int SERIAL_TYPE_DebugEventOutputRedirect = 13;
|
|
||||||
|
|
||||||
public static void serialize(Serializable object, DataOutputStream dout)
|
|
||||||
throws IOException {
|
|
||||||
if (object instanceof NullableString) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_NullableString);
|
|
||||||
NullableString.serialize(dout, (NullableString) object);
|
|
||||||
} else if (object instanceof TableVariable) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_TableVariable);
|
|
||||||
TableVariable.serialize(dout, (TableVariable) object);
|
|
||||||
} else if (object instanceof Variable) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_Variable);
|
|
||||||
Variable.serialize(dout, (Variable) object);
|
|
||||||
} else if (object instanceof StackFrame) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_StackFrame);
|
|
||||||
StackFrame.serialize(dout, (StackFrame) object);
|
|
||||||
} else if (object instanceof DebugMessageType) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_DebugMessageType);
|
|
||||||
DebugMessageType.serialize(dout, (DebugMessageType) object);
|
|
||||||
} else if (object instanceof DebugRequestStack) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_DebugRequestStack);
|
|
||||||
DebugRequestStack.serialize(dout, (DebugRequestStack) object);
|
|
||||||
} else if (object instanceof DebugRequestLineBreakpointToggle) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_DebugRequestLineBreakpointToggle);
|
|
||||||
DebugRequestLineBreakpointToggle.serialize(dout,
|
|
||||||
(DebugRequestLineBreakpointToggle) object);
|
|
||||||
} else if (object instanceof DebugEventBreakpoint) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_DebugEventBreakpoint);
|
|
||||||
DebugEventBreakpoint.serialize(dout, (DebugEventBreakpoint) object);
|
|
||||||
} else if (object instanceof DebugEventError) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_DebugEventError);
|
|
||||||
DebugEventError.serialize(dout, (DebugEventError) object);
|
|
||||||
} else if (object instanceof DebugEventOutputRedirect) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_DebugEventOutputRedirect);
|
|
||||||
DebugEventOutputRedirect.serialize(dout, (DebugEventOutputRedirect) 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 DebugMessage) {
|
|
||||||
dout.writeInt(SERIAL_TYPE_DebugMessage);
|
|
||||||
DebugMessage.serialize(dout, (DebugMessage) object);
|
|
||||||
} else {
|
|
||||||
// catch the errors: forgot to implement
|
|
||||||
// serialization/deserialization
|
|
||||||
throw new RuntimeException(
|
|
||||||
"serialization operation is not supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Serializable deserialize(DataInputStream din)
|
|
||||||
throws IOException {
|
|
||||||
Serializable object = null;
|
|
||||||
int type = din.readInt();
|
|
||||||
switch (type) {
|
|
||||||
case SERIAL_TYPE_NullableString:
|
|
||||||
object = NullableString.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_TableVariable:
|
|
||||||
object = TableVariable.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_Variable:
|
|
||||||
object = Variable.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_StackFrame:
|
|
||||||
object = StackFrame.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_DebugMessageType:
|
|
||||||
object = DebugMessageType.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_DebugRequestStack:
|
|
||||||
object = DebugRequestStack.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_DebugRequestLineBreakpointToggle:
|
|
||||||
object = DebugRequestLineBreakpointToggle.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_DebugEventBreakpoint:
|
|
||||||
object = DebugEventBreakpoint.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_DebugEventError:
|
|
||||||
object = DebugEventError.deserialize(din);
|
|
||||||
break;
|
|
||||||
case SERIAL_TYPE_DebugEventOutputRedirect:
|
|
||||||
object = DebugEventOutputRedirect.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_DebugMessage:
|
|
||||||
object = DebugMessage.deserialize(din);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new RuntimeException(
|
|
||||||
"deserialization operation is not supported: " + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,113 +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.
|
|
||||||
******************************************************************************/
|
|
||||||
/*******************************************************************************
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
public class StackFrame implements Serializable {
|
|
||||||
protected int lineNumber;
|
|
||||||
|
|
||||||
protected String source;
|
|
||||||
|
|
||||||
public StackFrame(String source, int lineNumber) {
|
|
||||||
this.lineNumber = lineNumber;
|
|
||||||
this.source = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLineNumber() {
|
|
||||||
return this.lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSource() {
|
|
||||||
return this.source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (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());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StackFrame deserialize(DataInputStream in) throws IOException {
|
|
||||||
int lineNumber = in.readInt();
|
|
||||||
String source = in.readUTF();
|
|
||||||
return new StackFrame(source, lineNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +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 java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import org.luaj.vm.LTable;
|
|
||||||
import org.luaj.vm.LValue;
|
|
||||||
import org.luaj.vm.Lua;
|
|
||||||
|
|
||||||
|
|
||||||
public class TableVariable extends Variable {
|
|
||||||
protected String[] keys;
|
|
||||||
protected Object[] values;
|
|
||||||
|
|
||||||
public TableVariable(int index, String name, int type, LTable table) {
|
|
||||||
super(index, name, type, null);
|
|
||||||
|
|
||||||
int size = table.size();
|
|
||||||
Vector keyList = new Vector();
|
|
||||||
Vector valueList = new Vector();
|
|
||||||
LValue[] keyValues = table.getKeys();
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
|
|
||||||
LValue value = table.get(keyValues[i]);
|
|
||||||
if (value == table) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
keyList.addElement(keyValues[i].toString());
|
|
||||||
if (value instanceof LTable) {
|
|
||||||
valueList.addElement(new TableVariable(i, "[" + keyValues[i].toString() + "]", Lua.LUA_TTABLE, (LTable)value));
|
|
||||||
} else {
|
|
||||||
valueList.addElement(value.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.keys = new String[keyList.size()];
|
|
||||||
for (int i = 0; i < keyList.size(); i++) {
|
|
||||||
this.keys[i] = (String)keyList.elementAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.values = new Object[valueList.size()];
|
|
||||||
for (int i = 0; i < valueList.size(); i++) {
|
|
||||||
this.values[i] = valueList.elementAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.keys.length != this.values.length) {
|
|
||||||
throw new RuntimeException("Internal Error: key.length must equal to values.length");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TableVariable(int index, String name, int type, String[] keys, Object[] values) {
|
|
||||||
super(index, name, type, null);
|
|
||||||
this.keys = keys;
|
|
||||||
this.values = values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getKeys() {
|
|
||||||
return this.keys == null ? new String[0] : this.keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object[] getValues() {
|
|
||||||
return this.values == null ? new Object[0] : this.values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, TableVariable variable) throws IOException {
|
|
||||||
out.writeInt(variable.getIndex());
|
|
||||||
out.writeUTF(variable.getName());
|
|
||||||
out.writeInt(variable.getType());
|
|
||||||
|
|
||||||
String[] keys = variable.getKeys();
|
|
||||||
out.writeInt(keys.length);
|
|
||||||
for (int i = 0; keys != null && i < keys.length; i++) {
|
|
||||||
SerializationHelper.serialize(new NullableString(keys[i]), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object[] values = variable.getValues();
|
|
||||||
for (int i = 0; values != null && i < values.length; i++) {
|
|
||||||
if (values[i] instanceof String) {
|
|
||||||
SerializationHelper.serialize(new NullableString((String)values[i]), out);
|
|
||||||
} else if (values[i] instanceof TableVariable) {
|
|
||||||
SerializationHelper.serialize((TableVariable)values[i], out);
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Internal Error: values array should only contain String and TableVariable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variable deserialize(DataInputStream in) throws IOException {
|
|
||||||
int index = in.readInt();
|
|
||||||
String name = in.readUTF();
|
|
||||||
int type = in.readInt();
|
|
||||||
|
|
||||||
String[] keys = null;
|
|
||||||
Object[] values = null;
|
|
||||||
int count = in.readInt();
|
|
||||||
keys = new String[count];
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
keys[i] = ((NullableString) SerializationHelper.deserialize(in)).getRawString();
|
|
||||||
}
|
|
||||||
|
|
||||||
values = new Object[count];
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
int serialType = in.readInt();
|
|
||||||
if (serialType == SerializationHelper.SERIAL_TYPE_NullableString) {
|
|
||||||
values[i] = NullableString.deserialize(in).getRawString();
|
|
||||||
} else if (serialType == SerializationHelper.SERIAL_TYPE_TableVariable) {
|
|
||||||
values[i] = TableVariable.deserialize(in);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TableVariable variable = new TableVariable(index, name, type, keys, values);
|
|
||||||
return variable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,124 +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 java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.vm.Lua;
|
|
||||||
|
|
||||||
|
|
||||||
public class Variable implements Serializable {
|
|
||||||
protected int index;
|
|
||||||
protected String name;
|
|
||||||
protected String value;
|
|
||||||
protected int type;
|
|
||||||
|
|
||||||
public Variable(int index, String name, int type, String value) {
|
|
||||||
if (name == null) {
|
|
||||||
throw new IllegalArgumentException("argument name is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type < Lua.LUA_TNIL || type > Lua.LUA_TTHREAD) {
|
|
||||||
throw new IllegalArgumentException("invalid LValue type: " + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.index = index;
|
|
||||||
this.name = name;
|
|
||||||
this.type = type;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getType() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndex() {
|
|
||||||
return this.index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "index: " + getIndex() + " name:" + getName() + " type: " + Lua.TYPE_NAMES[getType()] + " value:" + getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + index;
|
|
||||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
|
||||||
result = prime * result + type;
|
|
||||||
result = prime * result + ((value == null) ? 0 : value.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 Variable other = (Variable) obj;
|
|
||||||
if (index != other.index)
|
|
||||||
return false;
|
|
||||||
if (name == null) {
|
|
||||||
if (other.name != null)
|
|
||||||
return false;
|
|
||||||
} else if (!name.equals(other.name))
|
|
||||||
return false;
|
|
||||||
if (type != other.type)
|
|
||||||
return false;
|
|
||||||
if (value == null) {
|
|
||||||
if (other.value != null)
|
|
||||||
return false;
|
|
||||||
} else if (!value.equals(other.value))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, Variable variable)
|
|
||||||
throws IOException {
|
|
||||||
out.writeInt(variable.getIndex());
|
|
||||||
out.writeUTF(variable.getName());
|
|
||||||
out.writeInt(variable.getType());
|
|
||||||
SerializationHelper.serialize(new NullableString(variable.getValue()), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Variable deserialize(DataInputStream in) throws IOException {
|
|
||||||
int index = in.readInt();
|
|
||||||
String name = in.readUTF();
|
|
||||||
int type = in.readInt();
|
|
||||||
NullableString value = (NullableString)SerializationHelper.deserialize(in);
|
|
||||||
|
|
||||||
Variable variable = new Variable(index, name, type, value.getRawString());
|
|
||||||
return variable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +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.event;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
|
|
||||||
public class DebugEventBreakpoint extends DebugMessage {
|
|
||||||
protected String source;
|
|
||||||
|
|
||||||
protected int lineNumber;
|
|
||||||
|
|
||||||
public DebugEventBreakpoint(String source, int lineNumber) {
|
|
||||||
super(DebugMessageType.suspendedOnBreakpoint);
|
|
||||||
if (source == null) {
|
|
||||||
throw new IllegalArgumentException("argument source cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lineNumber <= 0) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"argument lineNumber must be positive integer");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.source = source;
|
|
||||||
this.lineNumber = lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSource() {
|
|
||||||
return this.source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLineNumber() {
|
|
||||||
return this.lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see lua.debug.DebugEvent#toString()
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + " source:" + getSource() + " line:"
|
|
||||||
+ getLineNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out,
|
|
||||||
DebugEventBreakpoint object) throws IOException {
|
|
||||||
out.writeUTF(object.getSource());
|
|
||||||
out.writeInt(object.getLineNumber());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in) throws IOException {
|
|
||||||
String source = in.readUTF();
|
|
||||||
int lineNo = in.readInt();
|
|
||||||
|
|
||||||
return new DebugEventBreakpoint(source, lineNo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +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.event;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
|
|
||||||
public class DebugEventError extends DebugMessage {
|
|
||||||
protected String cause;
|
|
||||||
protected String trace;
|
|
||||||
|
|
||||||
public DebugEventError(String cause, String trace) {
|
|
||||||
super(DebugMessageType.suspendedOnError);
|
|
||||||
this.cause = cause;
|
|
||||||
this.trace = trace;
|
|
||||||
}
|
|
||||||
|
|
||||||
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() + "[cause: " + getCause() + ", trace: " + trace + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, DebugEventError object)
|
|
||||||
throws IOException {
|
|
||||||
out.writeUTF(object.getCause());
|
|
||||||
out.writeUTF(object.getTrace());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in) throws IOException {
|
|
||||||
String detail = in.readUTF();
|
|
||||||
String trace = in.readUTF();
|
|
||||||
return new DebugEventError(detail, trace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +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.event;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
|
|
||||||
public interface DebugEventListener {
|
|
||||||
public void notifyDebugEvent(DebugMessage event);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package org.luaj.debug.event;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
|
|
||||||
public class DebugEventOutputRedirect extends DebugMessage {
|
|
||||||
protected String data;
|
|
||||||
|
|
||||||
public DebugEventOutputRedirect(String data) {
|
|
||||||
super(DebugMessageType.outputRedirect);
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOutput() {
|
|
||||||
return this.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#toString()
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
return type.toString() + ": " + this.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, DebugEventOutputRedirect event)
|
|
||||||
throws IOException {
|
|
||||||
out.writeUTF(event.getOutput());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in) throws IOException {
|
|
||||||
String data = in.readUTF();
|
|
||||||
return new DebugEventOutputRedirect(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package org.luaj.debug.net;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugLuaState;
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.event.DebugEventListener;
|
|
||||||
import org.luaj.debug.request.DebugRequestListener;
|
|
||||||
import org.luaj.vm.DebugNetSupport;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DebugNetSupportBase provides the network communication support between the luaj-vm
|
|
||||||
* and debug clients.
|
|
||||||
*/
|
|
||||||
public abstract class DebugNetSupportBase implements DebugRequestListener, DebugEventListener, DebugNetSupport {
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.luaj.debug.net.DebugNetSupport#start()
|
|
||||||
*/
|
|
||||||
public abstract void start() throws IOException;
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.luaj.debug.net.DebugNetSupport#stop()
|
|
||||||
*/
|
|
||||||
public abstract void stop();
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.luaj.debug.net.DebugNetSupport#disconnect()
|
|
||||||
*/
|
|
||||||
public abstract void disconnect();
|
|
||||||
|
|
||||||
protected DebugLuaState vm;
|
|
||||||
public void setDebugStackState(DebugLuaState vm) {
|
|
||||||
this.vm = vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.luaj.debug.request.DebugRequestListener#handleRequest(org.luaj.debug.request.DebugRequest)
|
|
||||||
*/
|
|
||||||
public void handleRequest(DebugMessage request) {
|
|
||||||
vm.handleRequest(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static final int UNKNOWN = 0;
|
|
||||||
protected static final int RUNNING = 1;
|
|
||||||
protected static final int STOPPED = 2;
|
|
||||||
|
|
||||||
protected int state = UNKNOWN;
|
|
||||||
protected synchronized void setState(int state) {
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized boolean isRunning() {
|
|
||||||
return this.state == RUNNING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,75 +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.request;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
import org.luaj.debug.SerializationHelper;
|
|
||||||
|
|
||||||
|
|
||||||
public class DebugRequestLineBreakpointToggle extends DebugMessage {
|
|
||||||
protected String source;
|
|
||||||
protected int lineNumber;
|
|
||||||
|
|
||||||
public DebugRequestLineBreakpointToggle(DebugMessageType type, String source, int lineNumber) {
|
|
||||||
super(type);
|
|
||||||
if (lineNumber < 0) {
|
|
||||||
throw new IllegalArgumentException("lineNumber must be equal to greater than zero");
|
|
||||||
}
|
|
||||||
this.source = source;
|
|
||||||
this.lineNumber = lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLineNumber() {
|
|
||||||
return this.lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSource() {
|
|
||||||
return this.source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see lua.debug.DebugRequest#toString()
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + " Source:" + getSource() + " lineNumber:" + getLineNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, DebugRequestLineBreakpointToggle request)
|
|
||||||
throws IOException {
|
|
||||||
SerializationHelper.serialize(request.getType(), out);
|
|
||||||
out.writeUTF(request.getSource());
|
|
||||||
out.writeInt(request.getLineNumber());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in) throws IOException {
|
|
||||||
DebugMessageType type = (DebugMessageType)SerializationHelper.deserialize(in);
|
|
||||||
String source = in.readUTF();
|
|
||||||
int lineNo = in.readInt();
|
|
||||||
|
|
||||||
return new DebugRequestLineBreakpointToggle(type, source, lineNo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +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.request;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
|
|
||||||
|
|
||||||
public interface DebugRequestListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debugging client can send the following requests to the server:
|
|
||||||
* suspend -- suspend the execution and listen for debug requests
|
|
||||||
* resume -- resume the execution
|
|
||||||
* exit -- terminate the execution
|
|
||||||
* set N -- set breakpoint at line N
|
|
||||||
* clear N -- clear breakpoint at line N
|
|
||||||
* callgraph -- return the current call graph (i.e. stack frames from
|
|
||||||
* old to new, include information about file, method, etc.)
|
|
||||||
* stack -- return the content of the current stack frame,
|
|
||||||
* listing the (variable, value) pairs
|
|
||||||
* step -- single step forward (go to next statement)
|
|
||||||
*/
|
|
||||||
public void handleRequest(DebugMessage request);
|
|
||||||
}
|
|
||||||
@@ -1,63 +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.request;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
|
|
||||||
public class DebugRequestStack extends DebugMessage {
|
|
||||||
protected int index;
|
|
||||||
|
|
||||||
public DebugRequestStack(int index) {
|
|
||||||
super(DebugMessageType.stack);
|
|
||||||
this.index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndex() {
|
|
||||||
return this.index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see lua.debug.DebugRequest#toString()
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + " stack frame:" + getIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out, DebugRequestStack request)
|
|
||||||
throws IOException {
|
|
||||||
out.writeInt(request.getIndex());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in)
|
|
||||||
throws IOException {
|
|
||||||
int index = in.readInt();
|
|
||||||
|
|
||||||
return new DebugRequestStack(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +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.request;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
import org.luaj.debug.EnumType;
|
|
||||||
|
|
||||||
public class DebugRequestWatchpointToggle extends DebugMessage {
|
|
||||||
public static class AccessType extends EnumType {
|
|
||||||
private static final long serialVersionUID = 3523086189648091587L;
|
|
||||||
|
|
||||||
public static final AccessType Ignore = new AccessType("Ignore", 0);
|
|
||||||
public static final AccessType Read = new AccessType("Read", 1);
|
|
||||||
public static final AccessType Modify = new AccessType("Modify", 2);
|
|
||||||
public static final AccessType ReadAndModify = new AccessType("ReadAndModify", 3);
|
|
||||||
|
|
||||||
protected AccessType(String name, int ordinal) {
|
|
||||||
super(name, ordinal);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
protected String functionName;
|
|
||||||
protected String variableName;
|
|
||||||
|
|
||||||
public DebugRequestWatchpointToggle(String functionName,
|
|
||||||
String variableName,
|
|
||||||
AccessType accessType) {
|
|
||||||
super(accessType == AccessType.Ignore ?
|
|
||||||
DebugMessageType.watchpointClear :
|
|
||||||
DebugMessageType.watchpointSet);
|
|
||||||
this.functionName = functionName;
|
|
||||||
this.variableName = variableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFunctionName() {
|
|
||||||
return this.functionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVariableName() {
|
|
||||||
return this.variableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see lua.debug.DebugRequest#toString()
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + " functionName:" + getFunctionName() + " variableName:" + getVariableName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: add the serialization stuff
|
|
||||||
}
|
|
||||||
@@ -1,76 +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.response;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
import org.luaj.debug.StackFrame;
|
|
||||||
|
|
||||||
public class DebugResponseCallgraph extends DebugMessage {
|
|
||||||
protected StackFrame[] stackFrames;
|
|
||||||
|
|
||||||
public DebugResponseCallgraph(StackFrame[] callgraph) {
|
|
||||||
super(DebugMessageType.clientRequestCallgraphReply);
|
|
||||||
if (callgraph == null) {
|
|
||||||
this.stackFrames = new StackFrame[0];
|
|
||||||
} else {
|
|
||||||
this.stackFrames = callgraph;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public StackFrame[] getCallgraph() {
|
|
||||||
return this.stackFrames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
StringBuffer buffer = new StringBuffer("callgraph: ");
|
|
||||||
for (int i = 0; i < stackFrames.length; i++) {
|
|
||||||
StackFrame frame = stackFrames[i];
|
|
||||||
buffer.append(frame.toString());
|
|
||||||
buffer.append("\n");
|
|
||||||
}
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out,
|
|
||||||
DebugResponseCallgraph response) throws IOException {
|
|
||||||
StackFrame[] stackFrames = response.getCallgraph();
|
|
||||||
out.writeInt(stackFrames == null ? 0 : stackFrames.length);
|
|
||||||
for (int i = 0; stackFrames != null && i < stackFrames.length; i++) {
|
|
||||||
StackFrame.serialize(out, stackFrames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in) throws IOException {
|
|
||||||
int count = in.readInt();
|
|
||||||
StackFrame[] stackFrames = new StackFrame[count];
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
stackFrames[i] = StackFrame.deserialize(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DebugResponseCallgraph(stackFrames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package org.luaj.debug.response;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
import org.luaj.debug.SerializationHelper;
|
|
||||||
import org.luaj.debug.Variable;
|
|
||||||
|
|
||||||
public class DebugResponseStack extends DebugResponseVariables {
|
|
||||||
protected int stackFrameIndex;
|
|
||||||
|
|
||||||
public DebugResponseStack(int index, Variable[] variables) {
|
|
||||||
super(variables, DebugMessageType.clientRequestStackReply);
|
|
||||||
this.stackFrameIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndex() {
|
|
||||||
return this.stackFrameIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out,
|
|
||||||
DebugResponseStack response)
|
|
||||||
throws IOException {
|
|
||||||
out.writeInt(response.getIndex());
|
|
||||||
|
|
||||||
Variable[] variables = response.getVariables();
|
|
||||||
out.writeInt(variables == null ? 0 : variables.length);
|
|
||||||
for (int i = 0; i < variables.length; i++) {
|
|
||||||
SerializationHelper.serialize(variables[i], out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in) throws IOException {
|
|
||||||
int index = in.readInt();
|
|
||||||
|
|
||||||
int count = in.readInt();
|
|
||||||
Variable[] variables = new Variable[count];
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
variables[i] = (Variable) SerializationHelper.deserialize(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DebugResponseStack(index, variables);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +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.response;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
import org.luaj.debug.SerializationHelper;
|
|
||||||
import org.luaj.debug.Variable;
|
|
||||||
|
|
||||||
public class DebugResponseVariables extends DebugMessage {
|
|
||||||
protected Variable[] variables;
|
|
||||||
|
|
||||||
public DebugResponseVariables(Variable[] variables, DebugMessageType type) {
|
|
||||||
super(type);
|
|
||||||
if (variables == null) {
|
|
||||||
this.variables = new Variable[0];
|
|
||||||
} else {
|
|
||||||
this.variables = variables;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variable[] getVariables() {
|
|
||||||
return this.variables;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see java.lang.Object#toString()
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
StringBuffer buffer = new StringBuffer(getType().toString() + ":");
|
|
||||||
for (int i = 0; variables != null && i < variables.length; i++) {
|
|
||||||
buffer.append("\t" + variables[i].getName() + ":" + variables[i].getIndex() + "\n");
|
|
||||||
}
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serialize(DataOutputStream out,
|
|
||||||
DebugResponseVariables response)
|
|
||||||
throws IOException {
|
|
||||||
DebugMessageType.serialize(out, response.getType());
|
|
||||||
Variable[] variables = response.getVariables();
|
|
||||||
out.writeInt(variables == null ? 0 : variables.length);
|
|
||||||
for (int i = 0; i < variables.length; i++) {
|
|
||||||
SerializationHelper.serialize(variables[i], out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DebugMessage deserialize(DataInputStream in)
|
|
||||||
throws IOException {
|
|
||||||
DebugMessageType type = DebugMessageType.deserialize(in);
|
|
||||||
int count = in.readInt();
|
|
||||||
Variable[] variables = new Variable[count];
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
variables[i] = (Variable) SerializationHelper.deserialize(in);
|
|
||||||
}
|
|
||||||
return new DebugResponseVariables(variables, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
package org.luaj.debug.net.j2me;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.microedition.io.Connector;
|
|
||||||
import javax.microedition.io.SocketConnection;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
import org.luaj.debug.RedirectOutputStream;
|
|
||||||
import org.luaj.debug.SerializationHelper;
|
|
||||||
import org.luaj.debug.event.DebugEventListener;
|
|
||||||
import org.luaj.lib.BaseLib;
|
|
||||||
|
|
||||||
public class ClientConnectionTask implements Runnable, DebugEventListener {
|
|
||||||
private static final boolean TRACE = true; //(null != System.getProperty("TRACE"));
|
|
||||||
|
|
||||||
protected String host;
|
|
||||||
protected int port;
|
|
||||||
protected DebugSupportImpl debugSupport;
|
|
||||||
protected boolean bDisconnected = false;
|
|
||||||
|
|
||||||
protected SocketConnection connection;
|
|
||||||
protected DataInputStream inStream;
|
|
||||||
protected DataOutputStream outStream;
|
|
||||||
|
|
||||||
protected RedirectOutputStream redirectOutputStream;
|
|
||||||
|
|
||||||
public ClientConnectionTask(String host, int port, DebugSupportImpl debugSupport) {
|
|
||||||
this.host = host;
|
|
||||||
this.port = port;
|
|
||||||
this.debugSupport = debugSupport;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void disconnect () {
|
|
||||||
this.bDisconnected = true;
|
|
||||||
if (this.inStream != null) {
|
|
||||||
try {
|
|
||||||
inStream.close();
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDisconnected() {
|
|
||||||
return this.bDisconnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
if ( TRACE )
|
|
||||||
System.out.println("LuaJ debug server connecting to " + host + ":" + port);
|
|
||||||
|
|
||||||
// create connection
|
|
||||||
this.connection = (SocketConnection)
|
|
||||||
Connector.open("socket://" + host + ":" + port);
|
|
||||||
this.inStream = connection.openDataInputStream();
|
|
||||||
this.outStream = connection.openDataOutputStream();
|
|
||||||
|
|
||||||
if ( TRACE )
|
|
||||||
System.out.println("LuaJ debug server connected to " + host + ":" + port);
|
|
||||||
|
|
||||||
// to redirect the print to the debug client console
|
|
||||||
this.redirectOutputStream = new RedirectOutputStream(this);
|
|
||||||
BaseLib.redirectOutput( redirectOutputStream );
|
|
||||||
|
|
||||||
// loop for incoming requests
|
|
||||||
while ( !isDisconnected() ) {
|
|
||||||
byte[] data = null;
|
|
||||||
int size = inStream.readInt();
|
|
||||||
data = new byte[size];
|
|
||||||
inStream.readFully(data);
|
|
||||||
|
|
||||||
DebugMessage request = (DebugMessage) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
if ( TRACE )
|
|
||||||
System.out.println("SERVER receives request: " + request.toString());
|
|
||||||
|
|
||||||
handleRequest(request);
|
|
||||||
}
|
|
||||||
} catch (EOFException e) {
|
|
||||||
// client has terminated the connection
|
|
||||||
// it may be time to exit.
|
|
||||||
handleRequest(new DebugMessage(DebugMessageType.reset));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
// if the connected debugging client aborted abnormally,
|
|
||||||
// discard the current connection.
|
|
||||||
handleRequest(new DebugMessage(DebugMessageType.reset));
|
|
||||||
|
|
||||||
debugSupport.disconnect();
|
|
||||||
} finally {
|
|
||||||
if (redirectOutputStream != null) {
|
|
||||||
try {
|
|
||||||
redirectOutputStream.close();
|
|
||||||
} catch (IOException ignore) {}
|
|
||||||
|
|
||||||
// restore the print output
|
|
||||||
BaseLib.restoreStandardOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void dispose() {
|
|
||||||
if (this.inStream != null) {
|
|
||||||
try {
|
|
||||||
inStream.close();
|
|
||||||
inStream = null;
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.outStream != null) {
|
|
||||||
try {
|
|
||||||
outStream.close();
|
|
||||||
outStream = null;
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.connection != null) {
|
|
||||||
try {
|
|
||||||
connection.close();
|
|
||||||
connection = null;
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleRequest(DebugMessage request) {
|
|
||||||
if ( TRACE )
|
|
||||||
System.out.println("SERVER handling request: " + request.toString());
|
|
||||||
|
|
||||||
debugSupport.handleRequest(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notifyDebugEvent(DebugMessage event) {
|
|
||||||
if (outStream == null) return;
|
|
||||||
|
|
||||||
if ( TRACE )
|
|
||||||
System.out.println("SERVER sending event: " + event.toString());
|
|
||||||
|
|
||||||
try {
|
|
||||||
byte[] data = SerializationHelper.serialize(event);
|
|
||||||
outStream.writeInt(data.length);
|
|
||||||
outStream.write(data);
|
|
||||||
outStream.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
package org.luaj.debug.net.j2me;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.net.DebugNetSupportBase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* J2ME version of DebugNetSupportBase implementation. The vm will connect to a debug
|
|
||||||
* service hosted on a remote machine and have the debug service relay the
|
|
||||||
* debugging messages between the vm and the debug client.
|
|
||||||
*/
|
|
||||||
public class DebugSupportImpl extends DebugNetSupportBase {
|
|
||||||
protected String host;
|
|
||||||
protected int port;
|
|
||||||
ClientConnectionTask clientTask;
|
|
||||||
Thread main;
|
|
||||||
|
|
||||||
public DebugSupportImpl(String host, int port) throws IOException {
|
|
||||||
this.host = host;
|
|
||||||
this.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() throws IOException {
|
|
||||||
setState(RUNNING);
|
|
||||||
main = new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
while ( isRunning() ) {
|
|
||||||
synchronized (DebugSupportImpl.this) {
|
|
||||||
if ( clientTask == null ) {
|
|
||||||
clientTask = new ClientConnectionTask(host, port, DebugSupportImpl.this);
|
|
||||||
new Thread(clientTask).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized(main) {
|
|
||||||
try {
|
|
||||||
main.wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
main.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
setState(STOPPED);
|
|
||||||
disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disconnect() {
|
|
||||||
clientTask.disconnect();
|
|
||||||
clientTask = null;
|
|
||||||
synchronized(main) {
|
|
||||||
main.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void notifyDebugEvent(DebugMessage event) {
|
|
||||||
if (clientTask != null) {
|
|
||||||
clientTask.notifyDebugEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,12 @@
|
|||||||
package org.luaj.platform;
|
package org.luaj.platform;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
|
||||||
import javax.microedition.midlet.MIDlet;
|
import javax.microedition.midlet.MIDlet;
|
||||||
|
|
||||||
import org.luaj.debug.net.j2me.DebugSupportImpl;
|
|
||||||
import org.luaj.lib.MathLib;
|
|
||||||
import org.luaj.vm.DebugNetSupport;
|
|
||||||
import org.luaj.vm.LDouble;
|
|
||||||
import org.luaj.vm.LNumber;
|
import org.luaj.vm.LNumber;
|
||||||
import org.luaj.vm.LuaErrorException;
|
|
||||||
import org.luaj.vm.LuaState;
|
import org.luaj.vm.LuaState;
|
||||||
import org.luaj.vm.Platform;
|
import org.luaj.vm.Platform;
|
||||||
|
|
||||||
@@ -37,13 +31,6 @@ public class J2meMidp10Cldc10Platform extends Platform {
|
|||||||
InputStream is = this.getClass().getResourceAsStream(fileName);
|
InputStream is = this.getClass().getResourceAsStream(fileName);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DebugNetSupport getDebugSupport() throws IOException {
|
|
||||||
String host = getDebugHost();
|
|
||||||
int port = getDebugPort();
|
|
||||||
return new DebugSupportImpl(host, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProperty(String key) {
|
public String getProperty(String key) {
|
||||||
return midlet.getAppProperty(key);
|
return midlet.getAppProperty(key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,247 +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.j2se;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.luaj.compiler.LuaC;
|
|
||||||
import org.luaj.debug.DebugLuaState;
|
|
||||||
import org.luaj.lib.PackageLib;
|
|
||||||
import org.luaj.platform.J2sePlatform;
|
|
||||||
import org.luaj.vm.LClosure;
|
|
||||||
import org.luaj.vm.LPrototype;
|
|
||||||
import org.luaj.vm.LString;
|
|
||||||
import org.luaj.vm.LValue;
|
|
||||||
import org.luaj.vm.LoadState;
|
|
||||||
import org.luaj.vm.LuaErrorException;
|
|
||||||
import org.luaj.vm.LuaState;
|
|
||||||
import org.luaj.vm.Platform;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* StandardLuaJVM executes a lua program in normal run mode or debug mode.
|
|
||||||
*
|
|
||||||
* @author: Shu Lei
|
|
||||||
* @version: 1.0
|
|
||||||
*/
|
|
||||||
public class StandardLuaJVM {
|
|
||||||
private static final String CMD_LINE_DEBUG_OPTION_SUSPEND_ON_START = "suspendOnStart=";
|
|
||||||
private static final String CMD_LINE_DEBUG_OPTION_PORT = "port=";
|
|
||||||
protected boolean isDebugMode = false;
|
|
||||||
protected int debugPort = -1;;
|
|
||||||
protected boolean bSuspendOnStart = false;
|
|
||||||
protected String script;
|
|
||||||
protected String[] scriptArgs;
|
|
||||||
protected LuaState state;
|
|
||||||
protected boolean isReady = false;
|
|
||||||
protected boolean isTerminated = false;
|
|
||||||
|
|
||||||
// command line parsing utilities
|
|
||||||
class ParseException extends Exception {
|
|
||||||
private static final long serialVersionUID = -3134938136698856577L;
|
|
||||||
|
|
||||||
public ParseException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void printUsage() {
|
|
||||||
System.out.println("Usage:");
|
|
||||||
System.out.println("\t java StandardLuaJVM [-Dport=<port>[,suspendedOnStart=<true|false>]] [-L<lua path>] <script> [<script arguments>]");
|
|
||||||
System.out.println("where [] denotes an optional argument and <> denotes a placeholder.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse(String[] args) throws ParseException {
|
|
||||||
if (args == null || args.length < 1) {
|
|
||||||
throw new ParseException("Invalid command line arguments.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
if (args[index] != null && args[index].startsWith("-D")) {
|
|
||||||
if (args.length < 2) {
|
|
||||||
throw new ParseException("Invalid command line arguments.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isDebugMode = true;
|
|
||||||
System.setProperty(Platform.PROPERTY_LUAJ_DEBUG, "true");
|
|
||||||
|
|
||||||
String debugOptions = args[index];
|
|
||||||
debugOptions = debugOptions.substring(2); // remove '-D'
|
|
||||||
String[] options = debugOptions.split(",");
|
|
||||||
for (int i = 0; options != null && i < options.length; i++) {
|
|
||||||
if (options[i].startsWith(CMD_LINE_DEBUG_OPTION_PORT)) {
|
|
||||||
String portString = options[i].substring(CMD_LINE_DEBUG_OPTION_PORT.length());
|
|
||||||
try {
|
|
||||||
this.debugPort = Integer.parseInt(portString);
|
|
||||||
System.setProperty(Platform.PROPERTY_LUAJ_DEBUG_PORT, String.valueOf(debugPort));
|
|
||||||
if (this.debugPort <= 0) {
|
|
||||||
throw new ParseException(
|
|
||||||
"Invalid debug port: it must be greater than zero.");
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new ParseException("Invalid debug port: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} else if (options[i].startsWith(CMD_LINE_DEBUG_OPTION_SUSPEND_ON_START)) {
|
|
||||||
String suspendOnStartStr
|
|
||||||
= options[i].substring(CMD_LINE_DEBUG_OPTION_SUSPEND_ON_START.length());
|
|
||||||
if (!suspendOnStartStr.equalsIgnoreCase("true") &&
|
|
||||||
!suspendOnStartStr.equalsIgnoreCase("false")) {
|
|
||||||
throw new ParseException("invalid debug flag: suspendOnStart");
|
|
||||||
}
|
|
||||||
this.bSuspendOnStart = "true".equalsIgnoreCase(suspendOnStartStr);
|
|
||||||
System.setProperty(Platform.PROPERTY_LUAJ_DEBUG_SUSPEND_AT_START, suspendOnStartStr);
|
|
||||||
} else {
|
|
||||||
throw new ParseException("Invalid command line argument: " + debugOptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.debugPort == -1) {
|
|
||||||
throw new ParseException("Invalid command line: debug port is missing");
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] scriptArgStrs;
|
|
||||||
if (index != 0) {
|
|
||||||
int scriptArgsCount = args.length - index;
|
|
||||||
scriptArgStrs = new String[scriptArgsCount];
|
|
||||||
System.arraycopy(args, index, scriptArgStrs, 0, scriptArgsCount);
|
|
||||||
} else {
|
|
||||||
scriptArgStrs = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
parseScriptArgs(scriptArgStrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parseScriptArgs(String[] args)
|
|
||||||
throws org.luaj.debug.j2se.StandardLuaJVM.ParseException {
|
|
||||||
if (args == null || args.length < 1) {
|
|
||||||
throw new ParseException("script is missing.");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.script = args[0];
|
|
||||||
int scriptArgsLength = args.length - 1;
|
|
||||||
if (scriptArgsLength > 0) {
|
|
||||||
this.scriptArgs = new String[scriptArgsLength];
|
|
||||||
for (int i = 1; i < args.length; i++) {
|
|
||||||
this.scriptArgs[i - 1] = args[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// end of command line parsing utilities
|
|
||||||
|
|
||||||
boolean isDebug() {
|
|
||||||
return this.isDebugMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getDebugPort() {
|
|
||||||
return this.debugPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean getSuspendOnStart() {
|
|
||||||
return this.bSuspendOnStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getScript() {
|
|
||||||
return this.script;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasScriptArgs() {
|
|
||||||
return (this.scriptArgs != null && this.scriptArgs.length > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] getScriptArgs() {
|
|
||||||
return this.scriptArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getLuaPath() {
|
|
||||||
return System.getProperty("LUA_PATH");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
// new lua debug state
|
|
||||||
Platform.setInstance(new J2sePlatform());
|
|
||||||
state = Platform.newLuaState();
|
|
||||||
init(state);
|
|
||||||
|
|
||||||
// load the Lua file
|
|
||||||
InputStream is = new FileInputStream(new File(getScript()));
|
|
||||||
LPrototype p = LoadState.undump(state, is, getScript());
|
|
||||||
|
|
||||||
// create closure and execute
|
|
||||||
final LClosure c = p.newClosure(state._G);
|
|
||||||
String[] args = getScriptArgs();
|
|
||||||
int numOfScriptArgs = (args != null ? args.length : 0);
|
|
||||||
LValue[] vargs = new LValue[numOfScriptArgs];
|
|
||||||
for (int i = 0; i < numOfScriptArgs; i++) {
|
|
||||||
vargs[i] = new LString(args[i]);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
state.doCall(c, vargs);
|
|
||||||
} finally {
|
|
||||||
if (state instanceof DebugLuaState) {
|
|
||||||
((DebugLuaState)state).stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (LuaErrorException e) {
|
|
||||||
System.err.println("Error: " + e.getMessage());
|
|
||||||
System.err.print(state.getStackTrace());
|
|
||||||
System.err.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void init(LuaState state) {
|
|
||||||
// add the compiler
|
|
||||||
LuaC.install();
|
|
||||||
|
|
||||||
// set the lua path if present
|
|
||||||
String luaPath = getLuaPath();
|
|
||||||
if (luaPath != null && luaPath.trim().length() > 0) {
|
|
||||||
PackageLib.setLuaPath(luaPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the command line arguments and executes/debugs the lua program.
|
|
||||||
* @param args -- command line arguments:
|
|
||||||
* [-debug <requestPort> <eventPort>] <script> <script arguments separated by a whitespace>
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
StandardLuaJVM vm = new StandardLuaJVM();
|
|
||||||
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
vm.run();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
System.out.println("Error: " + e.getMessage());
|
|
||||||
vm.printUsage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
package org.luaj.debug.net.j2se;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.Socket;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.DebugMessageType;
|
|
||||||
import org.luaj.debug.RedirectOutputStream;
|
|
||||||
import org.luaj.debug.SerializationHelper;
|
|
||||||
import org.luaj.debug.event.DebugEventListener;
|
|
||||||
import org.luaj.lib.BaseLib;
|
|
||||||
|
|
||||||
public class ClientConnectionTask implements Runnable, DebugEventListener {
|
|
||||||
private static final boolean TRACE = (null != System.getProperty("TRACE"));
|
|
||||||
protected static int counter = 1;
|
|
||||||
|
|
||||||
protected int sessionId;
|
|
||||||
protected Socket clientSocket;
|
|
||||||
protected boolean bDisconnected = false;
|
|
||||||
protected DataInputStream requestReader;
|
|
||||||
protected DataOutputStream eventWriter;
|
|
||||||
protected DebugSupportImpl debugSupport;
|
|
||||||
protected boolean isDisposed = false;
|
|
||||||
protected RedirectOutputStream redirectOutputStream;
|
|
||||||
|
|
||||||
public ClientConnectionTask(DebugSupportImpl debugSupport, Socket socket)
|
|
||||||
throws IOException {
|
|
||||||
this.debugSupport = debugSupport;
|
|
||||||
this.sessionId = getNextId();
|
|
||||||
this.clientSocket = socket;
|
|
||||||
this.requestReader
|
|
||||||
= new DataInputStream(clientSocket.getInputStream());
|
|
||||||
this.eventWriter
|
|
||||||
= new DataOutputStream(clientSocket.getOutputStream());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized int getNextId() {
|
|
||||||
// when the number of ClientConnectionTask created approaches
|
|
||||||
// Integer.MAX_VALUE, reset to 1. We don't expect we have
|
|
||||||
// Integer.MAX_VALUE concurrent debug clients ever.
|
|
||||||
if (counter == Integer.MAX_VALUE) {
|
|
||||||
counter = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disconnect () {
|
|
||||||
this.bDisconnected = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDisconnected() {
|
|
||||||
return this.bDisconnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSessionId() {
|
|
||||||
return this.sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
// to redirect the print to the debug client console
|
|
||||||
this.redirectOutputStream = new RedirectOutputStream(this);
|
|
||||||
BaseLib.redirectOutput( redirectOutputStream );
|
|
||||||
|
|
||||||
// loop for incoming requests
|
|
||||||
while (!isDisconnected()) {
|
|
||||||
byte[] data = null;
|
|
||||||
int size = requestReader.readInt();
|
|
||||||
data = new byte[size];
|
|
||||||
requestReader.readFully(data);
|
|
||||||
|
|
||||||
DebugMessage request = (DebugMessage) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
if (TRACE) {
|
|
||||||
System.out.println("SERVER receives request: " + request.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
handleRequest(request);
|
|
||||||
}
|
|
||||||
} catch (EOFException e) {
|
|
||||||
// client has terminated the connection
|
|
||||||
// it's time to exit.
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
// if the connected debugging client aborted abnormally,
|
|
||||||
// discard the current connection.
|
|
||||||
handleRequest(new DebugMessage(DebugMessageType.reset));
|
|
||||||
|
|
||||||
debugSupport.disconnect();
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
redirectOutputStream.close();
|
|
||||||
} catch (IOException ignore) {}
|
|
||||||
|
|
||||||
// restore the print output
|
|
||||||
BaseLib.restoreStandardOutput();
|
|
||||||
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleRequest(DebugMessage request) {
|
|
||||||
if (TRACE) {
|
|
||||||
System.out.println("SERVER handling request: " + request.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
debugSupport.handleRequest(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notifyDebugEvent(DebugMessage event) {
|
|
||||||
if (TRACE)
|
|
||||||
System.out.println("SERVER sending event: " + event.toString());
|
|
||||||
|
|
||||||
try {
|
|
||||||
byte[] data = SerializationHelper.serialize(event);
|
|
||||||
eventWriter.writeInt(data.length);
|
|
||||||
eventWriter.write(data);
|
|
||||||
eventWriter.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dispose() {
|
|
||||||
if ( this.isDisposed ) return;
|
|
||||||
|
|
||||||
this.isDisposed = true;
|
|
||||||
debugSupport.decrementClientCount();
|
|
||||||
|
|
||||||
if (this.requestReader != null) {
|
|
||||||
try {
|
|
||||||
requestReader.close();
|
|
||||||
requestReader = null;
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.eventWriter != null) {
|
|
||||||
try {
|
|
||||||
eventWriter.close();
|
|
||||||
eventWriter = null;
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.clientSocket != null) {
|
|
||||||
try {
|
|
||||||
clientSocket.close();
|
|
||||||
clientSocket = null;
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,161 +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.net.j2se;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.Socket;
|
|
||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
|
||||||
import org.luaj.debug.net.DebugNetSupportBase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* J2SE version of DebugNetSupportBase. The luaj-vm opens a port accepting the debug
|
|
||||||
* client connections. The current implementation allows the vm to accept one
|
|
||||||
* and only one debug client connection at any time.
|
|
||||||
*/
|
|
||||||
public class DebugSupportImpl extends DebugNetSupportBase {
|
|
||||||
|
|
||||||
protected int numClientConnectionsAllowed;
|
|
||||||
protected int numClientConnections = 0;
|
|
||||||
protected ServerSocket serverSocket;
|
|
||||||
protected int debugPort;
|
|
||||||
protected ClientConnectionTask clientConnectionTask;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance of DebugNetSupportBase at the given port
|
|
||||||
* @param debugPort
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public DebugSupportImpl(int debugPort) throws IOException {
|
|
||||||
this(debugPort, 1);
|
|
||||||
this.serverSocket
|
|
||||||
= new ServerSocket(debugPort, this.numClientConnectionsAllowed);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a debugging service on the given port. The service will support
|
|
||||||
* <code>numClientConnections</code> debug client connections.
|
|
||||||
* @param port Debug port
|
|
||||||
* @param connections
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
protected DebugSupportImpl(int port, int connections) throws IOException {
|
|
||||||
if (port < 0 || port > 0xFFFF) {
|
|
||||||
throw new IllegalArgumentException("port value out of range: " + port);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connections <= 0) {
|
|
||||||
throw new IllegalArgumentException("numClientConnections value must be greater than zero");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.debugPort = port;
|
|
||||||
this.numClientConnectionsAllowed = connections;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() throws IOException {
|
|
||||||
if (this.vm == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"DebugLuaState is not set. Please call setDebugStackState first.");
|
|
||||||
}
|
|
||||||
|
|
||||||
setState(RUNNING);
|
|
||||||
System.out.println("LuaJ debug server is listening on port: " + debugPort);
|
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
while (isRunning()) {
|
|
||||||
try {
|
|
||||||
acceptClientConnection();
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void incrementClientCount() {
|
|
||||||
this.numClientConnections++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void decrementClientCount() {
|
|
||||||
this.numClientConnections--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized int getClientCount() {
|
|
||||||
return this.numClientConnections;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void stop() {
|
|
||||||
setState(STOPPED);
|
|
||||||
if (clientConnectionTask != null) {
|
|
||||||
disconnect();
|
|
||||||
}
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see org.luaj.debug.event.DebugEventListener#notifyDebugEvent(org.luaj.debug.DebugMessage)
|
|
||||||
*/
|
|
||||||
public void notifyDebugEvent(DebugMessage event) {
|
|
||||||
if (clientConnectionTask != null) {
|
|
||||||
clientConnectionTask.notifyDebugEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void disconnect() {
|
|
||||||
clientConnectionTask.disconnect();
|
|
||||||
clientConnectionTask = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void acceptClientConnection() throws IOException {
|
|
||||||
try {
|
|
||||||
Socket clientSocket = serverSocket.accept();
|
|
||||||
int count = getClientCount();
|
|
||||||
if (count == numClientConnectionsAllowed) {
|
|
||||||
clientSocket.close();
|
|
||||||
} else {
|
|
||||||
synchronized(this) {
|
|
||||||
incrementClientCount();
|
|
||||||
this.clientConnectionTask = new ClientConnectionTask(this, clientSocket);
|
|
||||||
new Thread(clientConnectionTask).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected synchronized void dispose() {
|
|
||||||
if (this.clientConnectionTask != null) {
|
|
||||||
clientConnectionTask.dispose();
|
|
||||||
clientConnectionTask = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.serverSocket != null) {
|
|
||||||
try {
|
|
||||||
serverSocket.close();
|
|
||||||
serverSocket = null;
|
|
||||||
} catch (IOException e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,19 +3,14 @@ package org.luaj.platform;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
|
||||||
import org.luaj.debug.net.j2se.DebugSupportImpl;
|
|
||||||
import org.luaj.lib.MathLib;
|
import org.luaj.lib.MathLib;
|
||||||
import org.luaj.lib.j2se.LuajavaLib;
|
import org.luaj.lib.j2se.LuajavaLib;
|
||||||
import org.luaj.vm.DebugNetSupport;
|
|
||||||
import org.luaj.vm.LDouble;
|
import org.luaj.vm.LDouble;
|
||||||
import org.luaj.vm.LNumber;
|
import org.luaj.vm.LNumber;
|
||||||
import org.luaj.vm.LValue;
|
|
||||||
import org.luaj.vm.LuaErrorException;
|
|
||||||
import org.luaj.vm.LuaState;
|
import org.luaj.vm.LuaState;
|
||||||
import org.luaj.vm.Platform;
|
import org.luaj.vm.Platform;
|
||||||
|
|
||||||
@@ -29,11 +24,6 @@ public class J2sePlatform extends Platform {
|
|||||||
return new InputStreamReader(inputStream);
|
return new InputStreamReader(inputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DebugNetSupport getDebugSupport() throws IOException {
|
|
||||||
DebugNetSupport debugNetSupport = new DebugSupportImpl(getDebugPort());
|
|
||||||
return debugNetSupport;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProperty(String propertyName) {
|
public String getProperty(String propertyName) {
|
||||||
return System.getProperty(propertyName);
|
return System.getProperty(propertyName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import javax.tools.ToolProvider;
|
|||||||
import javax.tools.JavaCompiler.CompilationTask;
|
import javax.tools.JavaCompiler.CompilationTask;
|
||||||
|
|
||||||
import org.luaj.compiler.LuaC;
|
import org.luaj.compiler.LuaC;
|
||||||
import org.luaj.debug.Print;
|
|
||||||
import org.luaj.vm.LPrototype;
|
import org.luaj.vm.LPrototype;
|
||||||
import org.luaj.vm.LValue;
|
import org.luaj.vm.LValue;
|
||||||
import org.luaj.vm.LoadState;
|
import org.luaj.vm.LoadState;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.luaj.debug;
|
package org.luaj.jit;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
@@ -27,19 +27,6 @@ public class AllTests {
|
|||||||
compiler.addTestSuite(org.luaj.compiler.CompilerUnitTests.class);
|
compiler.addTestSuite(org.luaj.compiler.CompilerUnitTests.class);
|
||||||
suite.addTest(compiler);
|
suite.addTest(compiler);
|
||||||
|
|
||||||
// debug tests
|
|
||||||
TestSuite debug = new TestSuite("Debug");
|
|
||||||
debug.addTestSuite(org.luaj.debug.DebugEventTest.class);
|
|
||||||
debug.addTestSuite(org.luaj.debug.DebugRequestTest.class);
|
|
||||||
debug.addTestSuite(org.luaj.debug.DebugResponseTest.class);
|
|
||||||
debug.addTestSuite(org.luaj.debug.DebugStackStateTest.class);
|
|
||||||
debug.addTestSuite(org.luaj.debug.EnumTypeTest.class);
|
|
||||||
debug.addTestSuite(org.luaj.debug.StackFrameTest.class);
|
|
||||||
debug.addTestSuite(org.luaj.debug.TableVariableTest.class);
|
|
||||||
debug.addTestSuite(org.luaj.debug.VariableTest.class);
|
|
||||||
debug.addTestSuite(org.luaj.debug.j2se.LuaJVMTest.class);
|
|
||||||
suite.addTest(debug);
|
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.net.URL;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.luaj.TestPlatform;
|
import org.luaj.TestPlatform;
|
||||||
import org.luaj.debug.Print;
|
import org.luaj.jit.Print;
|
||||||
import org.luaj.vm.LPrototype;
|
import org.luaj.vm.LPrototype;
|
||||||
import org.luaj.vm.LoadState;
|
import org.luaj.vm.LoadState;
|
||||||
import org.luaj.vm.LuaState;
|
import org.luaj.vm.LuaState;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import java.io.InputStream;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.luaj.TestPlatform;
|
import org.luaj.TestPlatform;
|
||||||
import org.luaj.debug.Print;
|
import org.luaj.jit.Print;
|
||||||
import org.luaj.lib.BaseLib;
|
import org.luaj.lib.BaseLib;
|
||||||
import org.luaj.vm.LClosure;
|
import org.luaj.vm.LClosure;
|
||||||
import org.luaj.vm.LPrototype;
|
import org.luaj.vm.LPrototype;
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.luaj.debug.event.DebugEventBreakpoint;
|
|
||||||
import org.luaj.debug.event.DebugEventOutputRedirect;
|
|
||||||
|
|
||||||
public class DebugEventTest extends TestCase {
|
|
||||||
public void testDebugEventSerialization() {
|
|
||||||
try {
|
|
||||||
DebugMessage event = new DebugMessage(DebugMessageType.started);
|
|
||||||
byte[] data = SerializationHelper.serialize(event);
|
|
||||||
DebugMessage eventOut = (DebugMessage) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
assertNotNull(eventOut);
|
|
||||||
assertEquals(event.getType(), eventOut.getType());
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDebugEventBreakpointSerialization() {
|
|
||||||
try {
|
|
||||||
DebugEventBreakpoint event = new DebugEventBreakpoint("test.lua",
|
|
||||||
100);
|
|
||||||
byte[] data = SerializationHelper.serialize(event);
|
|
||||||
DebugEventBreakpoint eventOut = (DebugEventBreakpoint) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
assertNotNull(eventOut);
|
|
||||||
assertEquals(event.getSource(), eventOut.getSource());
|
|
||||||
assertEquals(event.getLineNumber(), eventOut.getLineNumber());
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDebugEventOutputRedirectSerialization() {
|
|
||||||
try {
|
|
||||||
String msg = "This is a testing message";
|
|
||||||
DebugEventOutputRedirect redirectEvent = new DebugEventOutputRedirect(msg);
|
|
||||||
byte[] data = SerializationHelper.serialize(redirectEvent);
|
|
||||||
DebugEventOutputRedirect redirectEventOut = (DebugEventOutputRedirect)
|
|
||||||
SerializationHelper.deserialize(data);
|
|
||||||
assertEquals(msg, redirectEventOut.getOutput());
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.luaj.debug.request.DebugRequestLineBreakpointToggle;
|
|
||||||
import org.luaj.debug.request.DebugRequestStack;
|
|
||||||
|
|
||||||
public class DebugRequestTest extends TestCase {
|
|
||||||
public void testDebugRequestSerialization() {
|
|
||||||
try {
|
|
||||||
DebugMessage request = new DebugMessage(DebugMessageType.resume);
|
|
||||||
byte[] data = SerializationHelper.serialize(request);
|
|
||||||
DebugMessage requestOut = (DebugMessage) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
assertNotNull(requestOut);
|
|
||||||
assertEquals(request.getType(), requestOut.getType());
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDebugRequestStackSerialization() {
|
|
||||||
try {
|
|
||||||
DebugRequestStack request = new DebugRequestStack(1);
|
|
||||||
byte[] data = SerializationHelper.serialize(request);
|
|
||||||
DebugRequestStack requestOut = (DebugRequestStack) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
assertNotNull(requestOut);
|
|
||||||
assertEquals(requestOut.getIndex(), 1);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDebugRequestLineBreakpointToggleSerialization() {
|
|
||||||
try {
|
|
||||||
doTestDebugRequestLineBreakpointToggleSerialization(
|
|
||||||
DebugMessageType.lineBreakpointSet, "test.lua", 100);
|
|
||||||
doTestDebugRequestLineBreakpointToggleSerialization(
|
|
||||||
DebugMessageType.lineBreakpointClear, "test.lua", 50);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTestDebugRequestLineBreakpointToggleSerialization(
|
|
||||||
DebugMessageType type, String source, int lineNo)
|
|
||||||
throws IOException {
|
|
||||||
DebugRequestLineBreakpointToggle request = new DebugRequestLineBreakpointToggle(
|
|
||||||
DebugMessageType.lineBreakpointSet, "test.lua", 100);
|
|
||||||
byte[] data = SerializationHelper.serialize(request);
|
|
||||||
DebugRequestLineBreakpointToggle requestOut = (DebugRequestLineBreakpointToggle) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
assertNotNull(requestOut);
|
|
||||||
assertEquals(request.getType(), requestOut.getType());
|
|
||||||
assertEquals(request.getSource(), requestOut.getSource());
|
|
||||||
assertEquals(request.getLineNumber(), requestOut.getLineNumber());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.luaj.debug.response.DebugResponseCallgraph;
|
|
||||||
import org.luaj.debug.response.DebugResponseStack;
|
|
||||||
import org.luaj.vm.Lua;
|
|
||||||
|
|
||||||
public class DebugResponseTest extends TestCase {
|
|
||||||
|
|
||||||
public void testDebugResponseStackSerialization() {
|
|
||||||
try {
|
|
||||||
doTestDebugResponseStackSerialization(0, null);
|
|
||||||
|
|
||||||
doTestDebugResponseStackSerialization(1, new Variable[0]);
|
|
||||||
|
|
||||||
Variable[] variables = new Variable[5];
|
|
||||||
variables[0] = new Variable(0, "variable1", Lua.LUA_TSTRING,
|
|
||||||
"value1");
|
|
||||||
variables[1] = new Variable(1, "variable2", Lua.LUA_TNIL, "nil");
|
|
||||||
variables[2] = new Variable(2, "variable3", Lua.LUA_TBOOLEAN,
|
|
||||||
"false");
|
|
||||||
|
|
||||||
TableVariable childTable = new TableVariable(0, "child",
|
|
||||||
Lua.LUA_TTABLE, new String[0], new Object[0]);
|
|
||||||
String[] keys = new String[] { "key1", "key2" };
|
|
||||||
Object[] values = new Object[] { "value1", childTable };
|
|
||||||
variables[3] = new TableVariable(2, "variable4", Lua.LUA_TTABLE,
|
|
||||||
keys, values);
|
|
||||||
|
|
||||||
variables[4] = new Variable(2, "variable3", Lua.LUA_TNUMBER, "10");
|
|
||||||
doTestDebugResponseStackSerialization(2, variables);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTestDebugResponseStackSerialization(int index, Variable[] variables)
|
|
||||||
throws IOException {
|
|
||||||
DebugResponseStack stackIn = new DebugResponseStack(index, variables);
|
|
||||||
byte[] data = SerializationHelper.serialize(stackIn);
|
|
||||||
DebugResponseStack stackOut = (DebugResponseStack) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
Variable[] variablesIn = stackIn.getVariables();
|
|
||||||
Variable[] variablesOut = stackOut.getVariables();
|
|
||||||
assertNotNull(variablesIn);
|
|
||||||
assertNotNull(variablesOut);
|
|
||||||
assertEquals(stackIn.getIndex(), stackOut.getIndex());
|
|
||||||
assertEquals(variablesIn.length, variablesOut.length);
|
|
||||||
for (int i = 0; i < variablesIn.length; i++) {
|
|
||||||
assertEquals(variablesIn[i], variablesOut[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDebugResponseCallgraphSerialization() {
|
|
||||||
try {
|
|
||||||
doTestDebugResponseCallgraphSerialization(null);
|
|
||||||
doTestDebugResponseCallgraphSerialization(new StackFrame[0]);
|
|
||||||
|
|
||||||
StackFrame[] frames = new StackFrame[1];
|
|
||||||
frames[0] = new StackFrame("test.lua", 100);
|
|
||||||
doTestDebugResponseCallgraphSerialization(frames);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTestDebugResponseCallgraphSerialization(StackFrame[] frames)
|
|
||||||
throws IOException {
|
|
||||||
DebugResponseCallgraph responseIn = new DebugResponseCallgraph(frames);
|
|
||||||
byte[] data = SerializationHelper.serialize(responseIn);
|
|
||||||
DebugResponseCallgraph responseOut = (DebugResponseCallgraph) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
assertNotNull(responseOut);
|
|
||||||
StackFrame[] inFrames = responseIn.getCallgraph();
|
|
||||||
StackFrame[] outFrames = responseOut.getCallgraph();
|
|
||||||
assertNotNull(outFrames);
|
|
||||||
assertEquals(inFrames.length, outFrames.length);
|
|
||||||
for (int i = 0; i < inFrames.length; i++) {
|
|
||||||
assertEquals(inFrames[i], outFrames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,171 +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 java.io.ByteArrayInputStream;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.luaj.TestPlatform;
|
|
||||||
import org.luaj.compiler.LuaC;
|
|
||||||
import org.luaj.vm.DebugNetSupport;
|
|
||||||
import org.luaj.vm.LClosure;
|
|
||||||
import org.luaj.vm.LPrototype;
|
|
||||||
import org.luaj.vm.LValue;
|
|
||||||
import org.luaj.vm.LoadState;
|
|
||||||
import org.luaj.vm.Platform;
|
|
||||||
|
|
||||||
public class DebugStackStateTest extends TestCase {
|
|
||||||
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
System.setProperty(Platform.PROPERTY_LUAJ_DEBUG, "true");
|
|
||||||
Platform.setInstance(new TestPlatform() {
|
|
||||||
public DebugNetSupport getDebugSupport() throws IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
LuaC.install();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void testStackStateUpvalues() throws Exception {
|
|
||||||
tryScript(
|
|
||||||
"print( 'aaa' ); local a = 3;\n"+
|
|
||||||
"print( 'bbb' ); local f = function()\n"+
|
|
||||||
" print('in f'); local b = 4; a=33\n"+
|
|
||||||
" print( 'bbb' ); local g = function()\n"+
|
|
||||||
" print('in g'); local c = 6; b=444; a=333\n" +
|
|
||||||
" return c, b, a\n"+
|
|
||||||
" end; print( 'calling g' ); g(); return b, a\n"+
|
|
||||||
"end\n"+
|
|
||||||
"print('calling f'); f()\n"+
|
|
||||||
"print( 'returned from f' ); local d = 6\n"+
|
|
||||||
"return 123, a, b, c, d\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testStackStateLocals() throws Exception {
|
|
||||||
tryScript(
|
|
||||||
"print('hello, world')\n"+
|
|
||||||
"print('aaa'); local a = 3; print('aaa')\n"+
|
|
||||||
"print('bbb'); local b = 4; print('bbb')\n"+
|
|
||||||
"print('ccc'); local c = 5; print('ccc')\n"+
|
|
||||||
"print('ddd'); local d = 6; print('ddd')\n"+
|
|
||||||
"print( a,b,c,d )\n"+
|
|
||||||
"return 123\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryScript(String script) throws Exception {
|
|
||||||
|
|
||||||
// set up closure
|
|
||||||
final DebugLuaState vm = (DebugLuaState) Platform.newLuaState();
|
|
||||||
final InputStream is = new ByteArrayInputStream(script.getBytes());
|
|
||||||
final LPrototype p = LoadState.undump(vm, is, "script");
|
|
||||||
final LClosure c = p.newClosure( vm._G );
|
|
||||||
|
|
||||||
// suspend the vm right away
|
|
||||||
vm.suspend();
|
|
||||||
|
|
||||||
// start the call processing in its own thread
|
|
||||||
Thread t = new Thread() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
vm.doCall( c, new LValue[0] );
|
|
||||||
} catch ( Throwable e ) {
|
|
||||||
System.out.println(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
t.start();
|
|
||||||
|
|
||||||
for ( int i=0; i<20; i++ ) {
|
|
||||||
vm.stepInto();
|
|
||||||
printStackState(vm);
|
|
||||||
Thread.sleep(100);
|
|
||||||
}
|
|
||||||
vm.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void testDebugStackState() throws InterruptedException, IOException {
|
|
||||||
String script = "src/test/res/test6.lua";
|
|
||||||
|
|
||||||
final DebugLuaState state = (DebugLuaState) Platform.newLuaState();
|
|
||||||
InputStream is = new FileInputStream( script );
|
|
||||||
LPrototype p = LoadState.undump(state, is, script);
|
|
||||||
|
|
||||||
// create closure and execute
|
|
||||||
final LClosure c = p.newClosure( state._G );
|
|
||||||
|
|
||||||
// suspend the vm right away
|
|
||||||
state.suspend();
|
|
||||||
state.setBreakpoint(script, 14);
|
|
||||||
|
|
||||||
// start the call processing in its own thread
|
|
||||||
new Thread() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
state.doCall( c, new LValue[0] );
|
|
||||||
} catch ( Exception e ) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
|
|
||||||
// step for 5 steps
|
|
||||||
for ( int i=0; i<5; i++ ) {
|
|
||||||
state.stepOver();
|
|
||||||
Thread.sleep(500);
|
|
||||||
System.out.println("--- callgraph="+state.getCallgraph() );
|
|
||||||
System.out.println("--- stack="+state.getStack(0) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// resume the vm
|
|
||||||
state.resume();
|
|
||||||
Thread.sleep(500);
|
|
||||||
System.out.println("--- callgraph="+state.getCallgraph() );
|
|
||||||
state.resume();
|
|
||||||
Thread.sleep(500);
|
|
||||||
System.out.println("--- callgraph="+state.getCallgraph() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void printStackState(DebugLuaState vm) {
|
|
||||||
int n = vm.getCallgraph().length;
|
|
||||||
System.out.println("stacks: "+n);
|
|
||||||
for ( int j=0; j<n; j++ ) {
|
|
||||||
try {
|
|
||||||
Variable[] v = vm.getStack(j);
|
|
||||||
for ( int i=0; i<v.length; i++ )
|
|
||||||
System.out.println("v["+j+","+i+"]= index="+v[i].index+" "+v[i].name+"="+v[i].value+" type="+v[i].type);
|
|
||||||
} catch ( Throwable t ) {
|
|
||||||
System.out.println(t.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
public class EnumTypeTest extends TestCase {
|
|
||||||
public void testDebugRequestTypeSerialization() {
|
|
||||||
try {
|
|
||||||
DebugMessageType type = DebugMessageType.lineBreakpointClear;
|
|
||||||
byte[] data = SerializationHelper.serialize(type);
|
|
||||||
DebugMessageType typeOut = (DebugMessageType) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
assertEquals(type, typeOut);
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDebugEventTypeSerialization() {
|
|
||||||
try {
|
|
||||||
DebugMessageType type = DebugMessageType.suspendedOnError;
|
|
||||||
byte[] data = SerializationHelper.serialize(type);
|
|
||||||
DebugMessageType typeOut = (DebugMessageType) SerializationHelper
|
|
||||||
.deserialize(data);
|
|
||||||
assertNotNull(typeOut);
|
|
||||||
assertEquals(type, typeOut);
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.luaj.debug.event.DebugEventListener;
|
|
||||||
|
|
||||||
public class RedirectOutputStreamTest extends TestCase {
|
|
||||||
public void testRedirectOutputStream() {
|
|
||||||
RedirectOutputStream redirectOut = new RedirectOutputStream(
|
|
||||||
new DebugEventListener(){
|
|
||||||
public void notifyDebugEvent(DebugMessage event) {
|
|
||||||
assertEquals(event.toString(), "outputRedirect: true\r\na");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
PrintWriter writer = new PrintWriter(redirectOut);
|
|
||||||
writer.print(true);
|
|
||||||
writer.println();
|
|
||||||
writer.print('a');
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.SerializationHelper;
|
|
||||||
import org.luaj.debug.StackFrame;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
public class StackFrameTest extends TestCase {
|
|
||||||
public void testSerialization() {
|
|
||||||
try {
|
|
||||||
StackFrame stackIn = new StackFrame("test.lua", 10);
|
|
||||||
byte[] data = SerializationHelper.serialize(stackIn);
|
|
||||||
StackFrame stackOut = (StackFrame) SerializationHelper.deserialize(data);
|
|
||||||
assertNotNull(stackOut);
|
|
||||||
assertEquals(stackIn, stackOut);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.SerializationHelper;
|
|
||||||
import org.luaj.debug.TableVariable;
|
|
||||||
import org.luaj.vm.LBoolean;
|
|
||||||
import org.luaj.vm.LDouble;
|
|
||||||
import org.luaj.vm.LInteger;
|
|
||||||
import org.luaj.vm.LNil;
|
|
||||||
import org.luaj.vm.LString;
|
|
||||||
import org.luaj.vm.LTable;
|
|
||||||
import org.luaj.vm.Lua;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
public class TableVariableTest extends TestCase {
|
|
||||||
public void testCreate() {
|
|
||||||
LTable table = new LTable();
|
|
||||||
table.put("key1", new LString("value1"));
|
|
||||||
table.put("key2", new LNil());
|
|
||||||
table.put("key3", LBoolean.TRUE);
|
|
||||||
table.put("key4", LInteger.valueOf(10));
|
|
||||||
table.put("key5", new LDouble(0.5));
|
|
||||||
LTable childTable = new LTable();
|
|
||||||
childTable.put("childKey1", new LString("childValue1"));
|
|
||||||
table.put("key6", childTable);
|
|
||||||
|
|
||||||
TableVariable tableVariable = new TableVariable(0, "tableVar", Lua.LUA_TTABLE, table);
|
|
||||||
String[] keys = tableVariable.getKeys();
|
|
||||||
assertNotNull(keys);
|
|
||||||
assertEquals(keys.length, 6);
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
assertTrue(keys[i].startsWith("key"));
|
|
||||||
}
|
|
||||||
Object[] values = tableVariable.getValues();
|
|
||||||
assertNotNull(values);
|
|
||||||
assertEquals(values.length, 6);
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
if (values[i] instanceof String) {
|
|
||||||
assertTrue(values[i].equals("value1") ||
|
|
||||||
values[i].equals("nil") ||
|
|
||||||
values[i].equals("true") ||
|
|
||||||
values[i].equals("10") ||
|
|
||||||
values[i].equals("0.5"));
|
|
||||||
} else if (values[i] instanceof TableVariable) {
|
|
||||||
TableVariable child = (TableVariable) values[i];
|
|
||||||
|
|
||||||
String[] childKeys = child.getKeys();
|
|
||||||
assertNotNull(childKeys);
|
|
||||||
assertEquals(childKeys.length, 1);
|
|
||||||
assertEquals(childKeys[0], "childKey1");
|
|
||||||
|
|
||||||
Object[] childValues = child.getValues();
|
|
||||||
assertNotNull(childValues);
|
|
||||||
assertEquals(childValues.length, 1);
|
|
||||||
assertEquals(childValues[0], "childValue1");
|
|
||||||
} else {
|
|
||||||
fail("bad value type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSerialization() {
|
|
||||||
String[] keys = null;
|
|
||||||
Object[] values = null;
|
|
||||||
try {
|
|
||||||
doTestSerialization(0, "name", Lua.LUA_TTABLE, keys, values);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
keys = new String[0];
|
|
||||||
values = new String[0];
|
|
||||||
try {
|
|
||||||
doTestSerialization(0, "name", Lua.LUA_TTABLE, keys, values);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
keys = new String[] {"key1", "key2"};
|
|
||||||
values = new String[] {"value1", "value2"};
|
|
||||||
try {
|
|
||||||
doTestSerialization(0, "name", Lua.LUA_TTABLE, keys, values);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
TableVariable grandchild = new TableVariable(1, "child", Lua.LUA_TTABLE, keys, values);
|
|
||||||
keys = new String[] {"grandchild1", "grandchild2", "grandchild3"};
|
|
||||||
values = new Object[] {"value1", "value2", grandchild};
|
|
||||||
TableVariable child = new TableVariable(1, "child", Lua.LUA_TTABLE, keys, values);
|
|
||||||
keys = new String[] {"child1", "child2"};
|
|
||||||
values = new Object[] {"value1", child};
|
|
||||||
try {
|
|
||||||
doTestSerialization(0, "name", Lua.LUA_TTABLE, keys, values);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doTestSerialization(int index, String name, int type,
|
|
||||||
String[] keys, Object[] values)
|
|
||||||
throws IOException {
|
|
||||||
TableVariable in = new TableVariable(index, name, type, keys, values);
|
|
||||||
byte[] data = SerializationHelper.serialize(in);
|
|
||||||
TableVariable out = (TableVariable) SerializationHelper.deserialize(data);
|
|
||||||
|
|
||||||
assertTableVariable(in, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTableVariable(TableVariable in, TableVariable out) {
|
|
||||||
assertEquals(in.getIndex(), out.getIndex());
|
|
||||||
assertEquals(in.getType(), out.getType());
|
|
||||||
assertEquals(in.getName(), out.getName());
|
|
||||||
|
|
||||||
String[] inKeys = in.getKeys();
|
|
||||||
String[] outKeys = out.getKeys();
|
|
||||||
assertEquals(inKeys == null ? 0 : inKeys.length, outKeys == null ? 0 : outKeys.length);
|
|
||||||
for (int i = 0; inKeys != null && i < inKeys.length; i++) {
|
|
||||||
assertEquals(inKeys[i], outKeys[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object[] inValues = in.getValues();
|
|
||||||
Object[] outValues = out.getValues();
|
|
||||||
assertEquals(inValues == null ? 0 : inValues.length, outValues == null ? 0 : outValues.length);
|
|
||||||
for (int i = 0; inValues != null && i < inValues.length; i++) {
|
|
||||||
if (inValues[i] instanceof String && outValues[i] instanceof String) {
|
|
||||||
assertEquals(inValues[i], outValues[i]);
|
|
||||||
} else if (inValues[i] instanceof TableVariable && outValues[i] instanceof TableVariable) {
|
|
||||||
assertTableVariable((TableVariable)inValues[i], (TableVariable)outValues[i]);
|
|
||||||
} else {
|
|
||||||
fail("bad serialization");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package org.luaj.debug;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.debug.SerializationHelper;
|
|
||||||
import org.luaj.debug.Variable;
|
|
||||||
import org.luaj.vm.Lua;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
public class VariableTest extends TestCase {
|
|
||||||
public void testSerialization() {
|
|
||||||
doTestSerialization(0, "varName", Lua.LUA_TSTRING, null);
|
|
||||||
doTestSerialization(0, "varName", Lua.LUA_TSTRING, "varValue");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doTestSerialization(int index, String varName, int type, String varValue) {
|
|
||||||
Variable varIn = new Variable(index, varName, type, varValue);
|
|
||||||
Variable varOut = null;
|
|
||||||
try {
|
|
||||||
byte[] data = SerializationHelper.serialize(varIn);
|
|
||||||
varOut = (Variable) SerializationHelper.deserialize(data);
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
}
|
|
||||||
assertNotNull(varOut);
|
|
||||||
assertEquals(varIn, varOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,268 +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.j2se;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.luaj.TestPlatform;
|
|
||||||
import org.luaj.debug.j2se.StandardLuaJVM.ParseException;
|
|
||||||
import org.luaj.vm.Platform;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sanity test for StandardLuaJVM.
|
|
||||||
*/
|
|
||||||
public class LuaJVMTest extends TestCase {
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
|
|
||||||
System.setProperty(Platform.PROPERTY_LUAJ_DEBUG_PORT, "1999");
|
|
||||||
Platform.setInstance(new TestPlatform());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCommandLineParse() {
|
|
||||||
// null arguments
|
|
||||||
String[] args = null;
|
|
||||||
StandardLuaJVM vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
fail("Bad parsing program. Should never reach this line.");
|
|
||||||
} catch (ParseException e) {}
|
|
||||||
|
|
||||||
// empty arguments
|
|
||||||
args = new String[] {};
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
fail("Bad parsing program. Should never reach this line.");
|
|
||||||
} catch (ParseException e) {}
|
|
||||||
|
|
||||||
// incomplete arguments
|
|
||||||
args = new String[] { "-D" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
fail("Bad parsing program. Should never reach this line.");
|
|
||||||
} catch (ParseException e) {}
|
|
||||||
|
|
||||||
args = new String[] { "-D1046" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
fail("Bad parsing program. Should never reach this line.");
|
|
||||||
} catch (ParseException e) {}
|
|
||||||
|
|
||||||
args = new String[] { "-DsuspendOnStart=true" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
fail("Bad parsing program. Should never reach this line.");
|
|
||||||
} catch (ParseException e) {}
|
|
||||||
|
|
||||||
// invalid debug option format
|
|
||||||
args = new String[] { "-Dport=1044:suspendOnStart=true", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertFalse(1044 == vm.getDebugPort());
|
|
||||||
assertFalse(true == vm.getSuspendOnStart());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
//expected
|
|
||||||
}
|
|
||||||
|
|
||||||
args = new String[] { "-Dport=1044,suspendOnStart=xyz", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertTrue(1044 == vm.getDebugPort());
|
|
||||||
assertFalse(true == vm.getSuspendOnStart());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
//expected
|
|
||||||
}
|
|
||||||
|
|
||||||
// missing script name
|
|
||||||
args = new String[] { "-Dport=1047,suspendOnStart=true"};
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
fail("Bad parsing program. Should never reach this line.");
|
|
||||||
} catch (ParseException e) {}
|
|
||||||
|
|
||||||
// lua script cannot be found
|
|
||||||
args = new String[] { "-Dport=1046,suspendOnStart", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
vm.run();
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
} catch (ParseException e) {}
|
|
||||||
|
|
||||||
// lua script cannot be found
|
|
||||||
args = new String[] { "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
vm.run();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// valid command line
|
|
||||||
args = new String[] { "-Dport=1044,suspendOnStart=true", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertEquals(1044, vm.getDebugPort());
|
|
||||||
assertEquals(true, vm.getSuspendOnStart());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
args = new String[] { "-Dport=1044,suspendOnStart=True", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertEquals(1044, vm.getDebugPort());
|
|
||||||
assertEquals(true, vm.getSuspendOnStart());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
args = new String[] { "-DsuspendOnStart=true,port=1044", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertEquals(1044, vm.getDebugPort());
|
|
||||||
assertEquals(true, vm.getSuspendOnStart());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
args = new String[] { "-DsuspendOnStart=TRUE,port=1044", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertEquals(1044, vm.getDebugPort());
|
|
||||||
assertEquals(true, vm.getSuspendOnStart());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
args = new String[] { "-Dport=1044", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertEquals(1044, vm.getDebugPort());
|
|
||||||
assertEquals(false, vm.getSuspendOnStart());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.setProperty("LUA_PATH", "c:/work/CSI/prototypes/uidemo/?.lua");
|
|
||||||
args = new String[] {"dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertEquals("c:/work/CSI/prototypes/uidemo/?.lua", vm.getLuaPath());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.setProperty("LUA_PATH", "c:/work/CSI/prototypes/uidemo/?.lua");
|
|
||||||
args = new String[] { "-Dport=1044", "dummy.lua" };
|
|
||||||
vm = new StandardLuaJVM();
|
|
||||||
try {
|
|
||||||
vm.parse(args);
|
|
||||||
assertEquals(1044, vm.getDebugPort());
|
|
||||||
assertEquals("c:/work/CSI/prototypes/uidemo/?.lua", vm.getLuaPath());
|
|
||||||
assertEquals("dummy.lua", vm.getScript());
|
|
||||||
} catch (ParseException e) {
|
|
||||||
fail("Should never reach this line.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRun() {
|
|
||||||
Properties props = System.getProperties();
|
|
||||||
props.remove(Platform.PROPERTY_LUAJ_DEBUG);
|
|
||||||
props.remove(Platform.PROPERTY_LUAJ_DEBUG_HOST);
|
|
||||||
props.remove(Platform.PROPERTY_LUAJ_DEBUG_PORT);
|
|
||||||
props.remove(Platform.PROPERTY_LUAJ_DEBUG_SUSPEND_AT_START);
|
|
||||||
System.setProperties(props);
|
|
||||||
|
|
||||||
String[] tests = new String[] { "autoload", "boolean", "calls",
|
|
||||||
"coercions", "compare", "math", "mathlib", "metatables",
|
|
||||||
"select", "setlist", "swingapp", "test1", "test2", "test3",
|
|
||||||
"test4", "test5", "test6", "test7", "type", "upvalues",
|
|
||||||
"strlib"
|
|
||||||
};
|
|
||||||
doRun(tests);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDebugRun() {
|
|
||||||
Properties props = System.getProperties();
|
|
||||||
props.setProperty(Platform.PROPERTY_LUAJ_DEBUG, "true");
|
|
||||||
props.setProperty(Platform.PROPERTY_LUAJ_DEBUG_PORT, "1999");
|
|
||||||
System.setProperties(props);
|
|
||||||
|
|
||||||
String[] tests = new String[] { "boolean", "calls",
|
|
||||||
"coercions", "compare", "math", "mathlib", "metatables",
|
|
||||||
"select", "setlist", "swingapp", "test1", "test2", "test3",
|
|
||||||
"test4", "test5", "test6", "test7", "type", "upvalues"
|
|
||||||
};
|
|
||||||
doRun(tests);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doRun(String[] tests) {
|
|
||||||
for (int i = 0; i < tests.length; i++) {
|
|
||||||
String test = tests[i];
|
|
||||||
System.out.println("==> running test: " + test + ".lua");
|
|
||||||
doTestRun(test + ".lua");
|
|
||||||
System.out.println("==> running test: " + test + ".luac");
|
|
||||||
doTestRun(test + ".luac");
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doTestRun(String testName) {
|
|
||||||
String[] args = new String[1];
|
|
||||||
URL filePath = getClass().getResource("/" + testName);
|
|
||||||
if (filePath != null) {
|
|
||||||
args[0] = filePath.getPath();
|
|
||||||
try {
|
|
||||||
StandardLuaJVM.main(args);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
fail("Test " + testName + " failed due to " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +1 @@
|
|||||||
version: 0.43
|
version: 0.44
|
||||||
|
|||||||
Reference in New Issue
Block a user