expose public getlocal and getupvalue functions.

This commit is contained in:
James Roseborough
2009-04-09 20:20:14 +00:00
parent f66c456934
commit 67c66c684c
2 changed files with 58 additions and 14 deletions

View File

@@ -23,6 +23,7 @@ package org.luaj.lib;
import org.luaj.vm.CallInfo; import org.luaj.vm.CallInfo;
import org.luaj.vm.LBoolean;
import org.luaj.vm.LClosure; import org.luaj.vm.LClosure;
import org.luaj.vm.LFunction; import org.luaj.vm.LFunction;
import org.luaj.vm.LInteger; import org.luaj.vm.LInteger;
@@ -31,10 +32,10 @@ import org.luaj.vm.LPrototype;
import org.luaj.vm.LString; import org.luaj.vm.LString;
import org.luaj.vm.LTable; import org.luaj.vm.LTable;
import org.luaj.vm.LValue; import org.luaj.vm.LValue;
import org.luaj.vm.LoadState;
import org.luaj.vm.Lua; import org.luaj.vm.Lua;
import org.luaj.vm.LuaErrorException; import org.luaj.vm.LuaErrorException;
import org.luaj.vm.LuaState; import org.luaj.vm.LuaState;
import org.luaj.vm.UpVal;
public class DebugLib extends LFunction { public class DebugLib extends LFunction {
@@ -286,7 +287,7 @@ public class DebugLib extends LFunction {
StackInfo si = getstackinfo(threadVm, level, 1)[0]; StackInfo si = getstackinfo(threadVm, level, 1)[0];
CallInfo ci = (si!=null? si.luainfo: null); CallInfo ci = (si!=null? si.luainfo: null);
LPrototype p = (ci!=null? ci.closure.p: null); LPrototype p = (ci!=null? ci.closure.p: null);
LString name = (p!=null? p.getlocalname(local, ci.pc>0? ci.pc-1: 0): null); LString name = (p!=null? p.getlocalname(local, ci.currentpc()): null);
if ( name != null ) { if ( name != null ) {
LValue value = threadVm.stack[ci.base+(local-1)]; LValue value = threadVm.stack[ci.base+(local-1)];
vm.pushlvalue( name ); vm.pushlvalue( name );
@@ -306,7 +307,7 @@ public class DebugLib extends LFunction {
StackInfo si = getstackinfo(threadVm, level, 1)[0]; StackInfo si = getstackinfo(threadVm, level, 1)[0];
CallInfo ci = (si!=null? si.luainfo: null); CallInfo ci = (si!=null? si.luainfo: null);
LPrototype p = (ci!=null? ci.closure.p: null); LPrototype p = (ci!=null? ci.closure.p: null);
LString name = (p!=null? p.getlocalname(local, ci.pc>0? ci.pc-1: 0): null); LString name = (p!=null? p.getlocalname(local, ci.currentpc()): null);
if ( name != null ) { if ( name != null ) {
threadVm.stack[ci.base+(local-1)] = value; threadVm.stack[ci.base+(local-1)] = value;
vm.pushlvalue(name); vm.pushlvalue(name);
@@ -347,7 +348,7 @@ public class DebugLib extends LFunction {
return 1; return 1;
} }
private LString findupvalue(LClosure c, int up) { private static LString findupvalue(LClosure c, int up) {
if ( c.upVals != null && up > 0 && up <= c.upVals.length ) { if ( c.upVals != null && up > 0 && up <= c.upVals.length ) {
if ( c.p.upvalues != null && up <= c.p.upvalues.length ) if ( c.p.upvalues != null && up <= c.p.upvalues.length )
return c.p.upvalues[up-1]; return c.p.upvalues[up-1];
@@ -361,7 +362,7 @@ public class DebugLib extends LFunction {
LFunction func = vm.checkfunction(1); LFunction func = vm.checkfunction(1);
int up = vm.checkint(2); int up = vm.checkint(2);
vm.resettop(); vm.resettop();
if ( func instanceof LClosure ) { if ( func.isClosure() ) {
LClosure c = (LClosure) func; LClosure c = (LClosure) func;
LString name = findupvalue(c, up); LString name = findupvalue(c, up);
if ( name != null ) { if ( name != null ) {
@@ -394,18 +395,54 @@ public class DebugLib extends LFunction {
protected int traceback(LuaState vm) { protected int traceback(LuaState vm) {
LuaState threadVm = optthreadvm(vm, 1); LuaState threadVm = optthreadvm(vm, 1);
String message = ""; String message = "stack traceback:\n";
int level = vm.optint(2,1); int level = vm.optint(2,1);
if ( ! vm.isnoneornil(1) ) if ( ! vm.isnoneornil(1) )
message = vm.checkstring(1)+"\n"; message = vm.checkstring(1)+"\n";
String tb = DebugLib.traceback(threadVm, level, message); String tb = DebugLib.traceback(threadVm, level);
vm.pushstring(tb); vm.pushstring(message+tb);
return 1; return 1;
} }
public static String traceback(LuaState vm, int level, String message) { // =================== public utilities ====================
/**
* @param callinfo the CallInfo to inspect
* @param up the 1-based index of the local
* @return { name, value } or null if not found.
*/
public static LValue[] getlocal(LuaState vm, CallInfo ci, int local) {
LPrototype p = ci.closure.p;
LString name = p.getlocalname(local, ci.currentpc());
if ( name != null ) {
LValue value = vm.stack[ci.base+(local-1)];
return new LValue[] { name, value };
}
return null;
}
/**
* @param c the LClosure to inspect
* @param up the 1-based index of the upvalue
* @return { name, value, isclosed } or null if not found.
*/
public static LValue[] getupvalue(LClosure c, int up) {
LString name = findupvalue(c, up);
if ( name != null ) {
UpVal u = c.upVals[up-1];
LValue value = u.getValue();
boolean isclosed = u.isClosed();
return new LValue[] { name, value, LBoolean.valueOf(isclosed) };
}
return null;
}
/**
* Get a traceback as a string for an arbitrary LuaState
*/
public static String traceback(LuaState vm, int level) {
StackInfo[] s = getstackinfo(vm, level, 10); StackInfo[] s = getstackinfo(vm, level, 10);
StringBuffer sb = new StringBuffer(message!=null? "stack traceback:": message); StringBuffer sb = new StringBuffer();
for ( int i=0; i<s.length; i++ ) { for ( int i=0; i<s.length; i++ ) {
StackInfo si = s[i]; StackInfo si = s[i];
if ( si != null ) { if ( si != null ) {
@@ -415,7 +452,7 @@ public class DebugLib extends LFunction {
sb.append( si.tracename() ); sb.append( si.tracename() );
} }
} }
return message+sb; return sb.toString();
} }
// ======================================================= // =======================================================
@@ -515,7 +552,7 @@ public class DebugLib extends LFunction {
private static StackInfo findstackinfo(LuaState vm, LFunction func) { private static StackInfo findstackinfo(LuaState vm, LFunction func) {
for (int j=vm.cc; j>=0; --j) { for (int j=vm.cc; j>=0; --j) {
CallInfo ci = vm.calls[j]; CallInfo ci = vm.calls[j];
int instr = ci.closure.p.code[ci.pc>0? ci.pc-1: 0]; int instr = ci.closure.p.code[ci.currentpc()];
if ( Lua.GET_OPCODE(instr) == Lua.OP_CALL ) { if ( Lua.GET_OPCODE(instr) == Lua.OP_CALL ) {
int a = Lua.GETARG_A(instr); int a = Lua.GETARG_A(instr);
if ( func == vm.stack[ci.base + a] ) if ( func == vm.stack[ci.base + a] )

View File

@@ -50,7 +50,7 @@ public class CallInfo {
public int currentline() { public int currentline() {
int[] li = closure.p.lineinfo; int[] li = closure.p.lineinfo;
if ( li != null && pc <= li.length ) if ( li != null && pc <= li.length )
return li[pc>0? pc-1: pc]; return li[currentpc()];
return -1; return -1;
} }
@@ -73,11 +73,18 @@ public class CallInfo {
* @return register of the current function executing, or null * @return register of the current function executing, or null
*/ */
public int currentfunca(LuaState vm) { public int currentfunca(LuaState vm) {
int i = closure.p.code[pc>0? pc-1: 0]; int i = closure.p.code[currentpc()];
int op = Lua.GET_OPCODE(i); int op = Lua.GET_OPCODE(i);
if ( op == Lua.OP_CALL || op == Lua.OP_TAILCALL ) if ( op == Lua.OP_CALL || op == Lua.OP_TAILCALL )
return Lua.GETARG_A(i); return Lua.GETARG_A(i);
return -1; return -1;
} }
/**
* Get current program counter or instruction being executed now.
*/
public int currentpc() {
return pc>0? pc-1: 0;
}
} }