Move hook function state to LuaThread.State class.

This commit is contained in:
James Roseborough
2015-03-22 16:54:56 +00:00
parent 450692d130
commit 591de13a46
2 changed files with 47 additions and 51 deletions

View File

@@ -94,20 +94,8 @@ public class LuaThread extends LuaValue {
public final Globals globals; public final Globals globals;
/** Hook function control state used by debug lib. */
public LuaValue hookfunc;
/** Error message handler for this thread, if any. */ /** Error message handler for this thread, if any. */
public LuaValue errorfunc; public LuaValue errorfunc;
public boolean hookline;
public boolean hookcall;
public boolean hookrtrn;
public int hookcount;
public boolean inhook;
public int lastline;
public int bytecodes;
/** Private constructor for main thread only */ /** Private constructor for main thread only */
public LuaThread(Globals globals) { public LuaThread(Globals globals) {
@@ -173,6 +161,18 @@ public class LuaThread extends LuaValue {
Varargs args = LuaValue.NONE; Varargs args = LuaValue.NONE;
Varargs result = LuaValue.NONE; Varargs result = LuaValue.NONE;
String error = null; String error = null;
/** Hook function control state used by debug lib. */
public LuaValue hookfunc;
public boolean hookline;
public boolean hookcall;
public boolean hookrtrn;
public int hookcount;
public boolean inhook;
public int lastline;
public int bytecodes;
public int status = LuaThread.STATUS_INITIAL; public int status = LuaThread.STATUS_INITIAL;
State(Globals globals, LuaThread lua_thread, LuaValue function) { State(Globals globals, LuaThread lua_thread, LuaValue function) {
@@ -245,15 +245,6 @@ public class LuaThread extends LuaValue {
this.result = LuaValue.NONE; this.result = LuaValue.NONE;
} }
} }
public synchronized void set_inhook(boolean value) {
LuaThread t = (LuaThread) this.lua_thread.get();
if (t == null) {
this.status = STATUS_DEAD;
throw new OrphanedThread();
}
t.inhook = value;
}
} }
} }

View File

@@ -139,10 +139,11 @@ public class DebugLib extends TwoArgFunction {
final class gethook extends VarArgFunction { final class gethook extends VarArgFunction {
public Varargs invoke(Varargs args) { public Varargs invoke(Varargs args) {
LuaThread t = args.narg() > 0 ? args.checkthread(1): globals.running; LuaThread t = args.narg() > 0 ? args.checkthread(1): globals.running;
LuaThread.State s = t.state;
return varargsOf( return varargsOf(
t.hookfunc != null? t.hookfunc: NIL, s.hookfunc != null? s.hookfunc: NIL,
valueOf((t.hookcall?"c":"")+(t.hookline?"l":"")+(t.hookrtrn?"r":"")), valueOf((s.hookcall?"c":"")+(s.hookline?"l":"")+(s.hookrtrn?"r":"")),
valueOf(t.hookcount)); valueOf(s.hookcount));
} }
} }
@@ -275,11 +276,12 @@ public class DebugLib extends TwoArgFunction {
case 'l': line=true; break; case 'l': line=true; break;
case 'r': rtrn=true; break; case 'r': rtrn=true; break;
} }
t.hookfunc = func; LuaThread.State s = t.state;
t.hookcall = call; s.hookfunc = func;
t.hookline = line; s.hookcall = call;
t.hookcount = count; s.hookline = line;
t.hookrtrn = rtrn; s.hookcount = count;
s.hookrtrn = rtrn;
return NONE; return NONE;
} }
} }
@@ -337,7 +339,7 @@ public class DebugLib extends TwoArgFunction {
public Varargs invoke(Varargs args) { public Varargs invoke(Varargs args) {
Object o = args.checkuserdata(1); Object o = args.checkuserdata(1);
LuaValue v = args.checkvalue(2); LuaValue v = args.checkvalue(2);
LuaUserdata u = (LuaUserdata)args.arg1(); LuaUserdata u = (LuaUserdata) o;
u.m_instance = v.checkuserdata(); u.m_instance = v.checkuserdata();
u.m_metatable = v.getmetatable(); u.m_metatable = v.getmetatable();
return NONE; return NONE;
@@ -388,55 +390,58 @@ public class DebugLib extends TwoArgFunction {
} }
public void onCall(LuaFunction f) { public void onCall(LuaFunction f) {
if (globals.running.inhook) return; LuaThread.State s = globals.running.state;
if (s.inhook) return;
callstack().onCall(f); callstack().onCall(f);
callHook(globals.running.hookfunc, CALL, NIL); if (s.hookcall) callHook(s, CALL, NIL);
} }
public void onCall(LuaClosure c, Varargs varargs, LuaValue[] stack) { public void onCall(LuaClosure c, Varargs varargs, LuaValue[] stack) {
if (globals.running.inhook) return; LuaThread.State s = globals.running.state;
if (s.inhook) return;
callstack().onCall(c, varargs, stack); callstack().onCall(c, varargs, stack);
callHook(globals.running.hookfunc, CALL, NIL); if (s.hookcall) callHook(s, CALL, NIL);
} }
public void onInstruction(int pc, Varargs v, int top) { public void onInstruction(int pc, Varargs v, int top) {
if (globals.running.inhook) return; LuaThread.State s = globals.running.state;
if (s.inhook) return;
callstack().onInstruction(pc, v, top); callstack().onInstruction(pc, v, top);
if (globals.running.hookfunc == null) return; if (s.hookfunc == null) return;
if (globals.running.hookcount > 0) if (s.hookcount > 0)
if (++globals.running.bytecodes % globals.running.hookcount == 0) if (++s.bytecodes % s.hookcount == 0)
callHook(globals.running.hookfunc, COUNT, NIL); callHook(s, COUNT, NIL);
if (globals.running.hookline) { if (s.hookline) {
int newline = callstack().currentline(); int newline = callstack().currentline();
if ( newline != globals.running.lastline ) { if ( newline != s.lastline ) {
globals.running.lastline = newline; s.lastline = newline;
callHook(globals.running.hookfunc, LINE, LuaValue.valueOf(newline)); callHook(s, LINE, LuaValue.valueOf(newline));
} }
} }
} }
public void onReturn() { public void onReturn() {
if (globals.running.inhook) return; LuaThread.State s = globals.running.state;
if (s.inhook) return;
callstack().onReturn(); callstack().onReturn();
callHook(globals.running.hookfunc, RETURN, NIL); if (s.hookrtrn) callHook(s, RETURN, NIL);
} }
public String traceback(int level) { public String traceback(int level) {
return callstack().traceback(level); return callstack().traceback(level);
} }
void callHook(LuaValue hookfunc, LuaValue type, LuaValue arg) { void callHook(LuaThread.State s, LuaValue type, LuaValue arg) {
if (hookfunc == null) return; if (s.inhook || s.hookfunc == null) return;
LuaThread.State state = globals.running.state; s.inhook = true;
state.set_inhook(true);
try { try {
hookfunc.call(type, arg); s.hookfunc.call(type, arg);
} catch (LuaError e) { } catch (LuaError e) {
throw e; throw e;
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw new LuaError(e); throw new LuaError(e);
} finally { } finally {
state.set_inhook(false); s.inhook = false;
} }
} }