Enhance debug tests, fix debug lib off-by-one erros.
This commit is contained in:
@@ -36,6 +36,7 @@ import org.luaj.vm.LuaState;
|
|||||||
public class DebugLib extends LFunction {
|
public class DebugLib extends LFunction {
|
||||||
|
|
||||||
private static final String[] NAMES = {
|
private static final String[] NAMES = {
|
||||||
|
"debuglib",
|
||||||
"debug",
|
"debug",
|
||||||
"getfenv",
|
"getfenv",
|
||||||
"gethook",
|
"gethook",
|
||||||
@@ -70,14 +71,18 @@ public class DebugLib extends LFunction {
|
|||||||
|
|
||||||
public static void install( LuaState vm ) {
|
public static void install( LuaState vm ) {
|
||||||
LTable debug = new LTable();
|
LTable debug = new LTable();
|
||||||
for (int i = 0; i < NAMES.length; i++)
|
for (int i = 1; i < NAMES.length; i++)
|
||||||
debug.put(NAMES[i], new DebugLib(i + 1));
|
debug.put(NAMES[i], new DebugLib(i));
|
||||||
vm._G.put("debug", debug);
|
vm._G.put("debug", debug);
|
||||||
PackageLib.setIsLoaded("debug", debug);
|
PackageLib.setIsLoaded("debug", debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
|
public DebugLib() {
|
||||||
|
this.id = INSTALL;
|
||||||
|
}
|
||||||
|
|
||||||
private DebugLib( int id ) {
|
private DebugLib( int id ) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
@@ -177,6 +182,7 @@ public class DebugLib extends LFunction {
|
|||||||
private void getfenv(LuaState vm) {
|
private void getfenv(LuaState vm) {
|
||||||
LValue object = vm.topointer(2);
|
LValue object = vm.topointer(2);
|
||||||
LValue env = object.luaGetEnv(null);
|
LValue env = object.luaGetEnv(null);
|
||||||
|
vm.resettop();
|
||||||
vm.pushlvalue(env!=null? env: LNil.NIL);
|
vm.pushlvalue(env!=null? env: LNil.NIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +190,7 @@ public class DebugLib extends LFunction {
|
|||||||
LValue object = vm.topointer(2);
|
LValue object = vm.topointer(2);
|
||||||
LTable table = vm.checktable(3);
|
LTable table = vm.checktable(3);
|
||||||
object.luaSetEnv(table);
|
object.luaSetEnv(table);
|
||||||
|
vm.settop(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getinfo(LuaState vm) {
|
private void getinfo(LuaState vm) {
|
||||||
@@ -263,11 +270,11 @@ public class DebugLib extends LFunction {
|
|||||||
CallInfo ci = getcallinfo(vm, threadVm, level);
|
CallInfo ci = getcallinfo(vm, threadVm, level);
|
||||||
LValue value = LNil.NIL;
|
LValue value = LNil.NIL;
|
||||||
LValue name = LNil.NIL;
|
LValue name = LNil.NIL;
|
||||||
if ( local >= 0 && local < ci.top-ci.base ) {
|
LocVars[] vars = ci.closure.p.locvars;
|
||||||
value = threadVm.stack[ ci.base + local ];
|
if ( local > 0 && local <= ci.top-ci.base ) {
|
||||||
LocVars[] vars = ci.closure.p.locvars;
|
value = threadVm.stack[ ci.base + local - 1 ];
|
||||||
if ( vars != null && local >= 0 && local < vars.length )
|
if ( vars != null && local > 0 && local <= vars.length )
|
||||||
name = vars[local].varname;
|
name = vars[local-1].varname;
|
||||||
}
|
}
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushlvalue( name );
|
vm.pushlvalue( name );
|
||||||
@@ -276,7 +283,7 @@ public class DebugLib extends LFunction {
|
|||||||
|
|
||||||
private void setlocal(LuaState vm) {
|
private void setlocal(LuaState vm) {
|
||||||
LuaState threadVm = vm;
|
LuaState threadVm = vm;
|
||||||
if ( vm.gettop() >= 4 ) {
|
if ( vm.gettop() >= 5 ) {
|
||||||
threadVm = vm.checkthread(2).vm;
|
threadVm = vm.checkthread(2).vm;
|
||||||
vm.remove(2);
|
vm.remove(2);
|
||||||
}
|
}
|
||||||
@@ -285,20 +292,21 @@ public class DebugLib extends LFunction {
|
|||||||
LValue value = vm.topointer(4);
|
LValue value = vm.topointer(4);
|
||||||
CallInfo ci = getcallinfo(vm, threadVm, level);
|
CallInfo ci = getcallinfo(vm, threadVm, level);
|
||||||
LValue name = LNil.NIL;
|
LValue name = LNil.NIL;
|
||||||
if ( local >= 0 && local < ci.top-ci.base ) {
|
LocVars[] vars = ci.closure.p.locvars;
|
||||||
threadVm.stack[ ci.base + local ] = value;
|
if ( local > 0 && local <= ci.top-ci.base ) {
|
||||||
LocVars[] vars = ci.closure.p.locvars;
|
threadVm.stack[ ci.base + local - 1 ] = value;
|
||||||
if ( vars != null && local >= 0 && local < vars.length )
|
if ( vars != null && local > 0 && local <= vars.length )
|
||||||
name = vars[local].varname;
|
name = vars[local-1].varname;
|
||||||
}
|
}
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushlvalue( name );
|
vm.pushlvalue( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
private CallInfo getcallinfo(LuaState vm, LuaState threadVm, int level) {
|
private CallInfo getcallinfo(LuaState vm, LuaState threadVm, int level) {
|
||||||
if ( level <= 0 || level > threadVm.cc )
|
--level ; // level 0 is the debug function itself
|
||||||
|
if ( level < 0 || level > threadVm.cc )
|
||||||
vm.error("level out of range");
|
vm.error("level out of range");
|
||||||
int cc = threadVm.cc-(level-1);
|
int cc = threadVm.cc-level;
|
||||||
return threadVm.calls[cc];
|
return threadVm.calls[cc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ public class lua {
|
|||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
switch ( args[i].charAt(1) ) {
|
switch ( args[i].charAt(1) ) {
|
||||||
|
case 'l':
|
||||||
|
++i;
|
||||||
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
++i;
|
++i;
|
||||||
processScript( vm, new ByteArrayInputStream(args[i].getBytes()), args[i], null, 0 );
|
processScript( vm, new ByteArrayInputStream(args[i].getBytes()), args[i], null, 0 );
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ public class CompatibiltyTest extends ScriptDrivenTest {
|
|||||||
runTest("compare");
|
runTest("compare");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDebugLib() throws IOException, InterruptedException {
|
||||||
|
runTest("debuglib");
|
||||||
|
}
|
||||||
|
|
||||||
public void testErrors() throws IOException, InterruptedException {
|
public void testErrors() throws IOException, InterruptedException {
|
||||||
runTest("errors");
|
runTest("errors");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import junit.framework.TestCase;
|
|||||||
|
|
||||||
import org.luaj.compiler.LuaC;
|
import org.luaj.compiler.LuaC;
|
||||||
import org.luaj.lib.BaseLib;
|
import org.luaj.lib.BaseLib;
|
||||||
|
import org.luaj.lib.DebugLib;
|
||||||
import org.luaj.platform.J2sePlatform;
|
import org.luaj.platform.J2sePlatform;
|
||||||
|
|
||||||
abstract
|
abstract
|
||||||
@@ -35,6 +36,9 @@ public class ScriptDrivenTest extends TestCase {
|
|||||||
// install the compiler
|
// install the compiler
|
||||||
LuaC.install();
|
LuaC.install();
|
||||||
|
|
||||||
|
// install debug lib
|
||||||
|
DebugLib.install( state );
|
||||||
|
|
||||||
// load the file
|
// load the file
|
||||||
LPrototype p = loadScript(state, testName);
|
LPrototype p = loadScript(state, testName);
|
||||||
p.source = LString.valueOf("stdin");
|
p.source = LString.valueOf("stdin");
|
||||||
|
|||||||
@@ -1,7 +1,54 @@
|
|||||||
|
|
||||||
local print = print
|
local print,tostring,_G = print,tostring,_G
|
||||||
|
local e,f,g,h,s
|
||||||
print( 'has debug', debug~=nil )
|
print( 'has debug', debug~=nil )
|
||||||
|
|
||||||
|
-- debug.getfenv, debug.setfenv
|
||||||
|
print( '----- debug.getfenv, debug.setfenv' )
|
||||||
|
f = function(a)
|
||||||
|
return 'f:'..tostring(a)..'|'..tostring(b)
|
||||||
|
end
|
||||||
|
s,e,g = pcall( debug.getfenv, f )
|
||||||
|
print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) )
|
||||||
|
s,e,g = pcall( debug.setfenv, f, {b='def'} )
|
||||||
|
print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) )
|
||||||
|
s,e,g = pcall( debug.getfenv, f )
|
||||||
|
print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) )
|
||||||
|
|
||||||
|
|
||||||
|
print( '----- debug.getlocal, debug.setlocal' )
|
||||||
|
h = function(v,i,n)
|
||||||
|
s = 'h-'..v..'-'..i
|
||||||
|
local x = debug.getlocal(v,i)
|
||||||
|
local y = debug.setlocal(v,i,n)
|
||||||
|
return s..' -> '..v..'-'..i..' '..
|
||||||
|
'old='..tostring(x)..'('..tostring(y)..')'..' '..
|
||||||
|
'new='..tostring(n)
|
||||||
|
end
|
||||||
|
g = function(...)
|
||||||
|
local p,q,r=7,8,9
|
||||||
|
local t = h(...)
|
||||||
|
local b = table.concat({...},',')
|
||||||
|
return t..'\tg locals='..p..','..q..','..r..' tbl={'..b..'}'
|
||||||
|
end
|
||||||
|
f = function(a,b,c)
|
||||||
|
local d,e,f = 4,5,6
|
||||||
|
local t = g(a,b,c)
|
||||||
|
return t..'\tf locals='..','..a..','..b..','..c..','..d..','..e..','..f
|
||||||
|
end
|
||||||
|
for lvl=1,3 do
|
||||||
|
for lcl=0,7 do
|
||||||
|
print( pcall( f, lvl, lcl, '#' ) )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
local f = function(a)
|
||||||
|
return 'f:'..tostring(a)..'|'..tostring(b)
|
||||||
|
end
|
||||||
|
local s,e
|
||||||
|
|
||||||
|
|
||||||
local printinfo = function(...)
|
local printinfo = function(...)
|
||||||
for i,a in ipairs(arg) do
|
for i,a in ipairs(arg) do
|
||||||
if type(a) == 'table' then
|
if type(a) == 'table' then
|
||||||
@@ -38,3 +85,4 @@ print( 'e,f,g', e, type(f), type(g) )
|
|||||||
printinfo( 'debug.getinfo(f,"Sl")', pcall(debug.getinfo, f, "Sl") )
|
printinfo( 'debug.getinfo(f,"Sl")', pcall(debug.getinfo, f, "Sl") )
|
||||||
printinfo( 'debug.getinfo(g,"Sl")', pcall(debug.getinfo, g, "Sl") )
|
printinfo( 'debug.getinfo(g,"Sl")', pcall(debug.getinfo, g, "Sl") )
|
||||||
printinfo( 'debug.getinfo(test,"Sl")', pcall(debug.getinfo, test, "Sl") )
|
printinfo( 'debug.getinfo(test,"Sl")', pcall(debug.getinfo, test, "Sl") )
|
||||||
|
--]]
|
||||||
Reference in New Issue
Block a user