Tests and fixes for debug.setupvalue, getupvalue, setmetatable, and getmetatable

This commit is contained in:
James Roseborough
2009-03-25 21:35:20 +00:00
parent 1aa3a7561f
commit 512304475e
3 changed files with 107 additions and 16 deletions

View File

@@ -31,7 +31,7 @@ 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.LocVars; import org.luaj.vm.LuaErrorException;
import org.luaj.vm.LuaState; import org.luaj.vm.LuaState;
public class DebugLib extends LFunction { public class DebugLib extends LFunction {
@@ -348,15 +348,27 @@ public class DebugLib extends LFunction {
private void getmetatable(LuaState vm) { private void getmetatable(LuaState vm) {
LValue object = vm.topointer(2); LValue object = vm.topointer(2);
vm.resettop(); vm.resettop();
vm.pushlvalue( object.luaGetMetatable() ); LValue mt = object.luaGetMetatable();
if ( mt != null )
vm.pushlvalue( object.luaGetMetatable() );
else
vm.pushnil();
} }
private void setmetatable(LuaState vm) { private void setmetatable(LuaState vm) {
LValue object = vm.topointer(2); LValue object = vm.topointer(2);
LValue table = vm.totable(3); try {
object.luaSetMetatable(table); if ( ! vm.isnoneornil(3) )
vm.resettop(); object.luaSetMetatable(vm.checktable(3));
vm.pushlvalue( object ); else
object.luaSetMetatable(null);
vm.resettop();
vm.pushboolean(true);
} catch ( LuaErrorException e ) {
vm.resettop();
vm.pushboolean(false);
vm.pushstring(e.toString());
}
} }
private void getregistry(LuaState vm) { private void getregistry(LuaState vm) {
@@ -364,14 +376,26 @@ public class DebugLib extends LFunction {
vm.pushlvalue( new LTable() ); vm.pushlvalue( new LTable() );
} }
private LString findupvalue(LClosure c, int up) {
if ( c.upVals != null && up > 0 && up <= c.upVals.length ) {
if ( c.p.upvalues != null && up <= c.p.upvalues.length )
return c.p.upvalues[up-1];
else
return new LString( "."+up+"" );
}
return null;
}
private void getupvalue(LuaState vm) { private void getupvalue(LuaState vm) {
LFunction func = vm.checkfunction(2); LFunction func = vm.checkfunction(2);
int up = vm.checkint(3); int up = vm.checkint(3);
vm.resettop(); vm.resettop();
if ( func instanceof LClosure ) { if ( func instanceof LClosure ) {
LClosure c = (LClosure) func; LClosure c = (LClosure) func;
if ( c.upVals != null && up > 0 && up < c.upVals.length ) { LString name = findupvalue(c, up);
vm.pushlvalue(c.upVals[up].getValue()); if ( name != null ) {
vm.pushlstring(name);
vm.pushlvalue(c.upVals[up-1].getValue());
return; return;
} }
} }
@@ -385,12 +409,10 @@ public class DebugLib extends LFunction {
vm.resettop(); vm.resettop();
if ( func instanceof LClosure ) { if ( func instanceof LClosure ) {
LClosure c = (LClosure) func; LClosure c = (LClosure) func;
if ( c.upVals != null && up > 0 && up < c.upVals.length ) { LString name = findupvalue(c, up);
c.upVals[up].setValue(value); if ( name != null ) {
if ( c.p.upvalues != null && up < c.p.upvalues.length ) c.upVals[up-1].setValue(value);
vm.pushlvalue( c.p.upvalues[up] ); vm.pushlstring(name);
else
vm.pushstring( "."+up+"" );
return; return;
} }
} }

View File

@@ -181,7 +181,7 @@ public class LValue {
* @return this if unchanged, or new LTable if copied using weak table * @return this if unchanged, or new LTable if copied using weak table
*/ */
public LTable luaSetMetatable(LValue metatable) { public LTable luaSetMetatable(LValue metatable) {
throw new LuaErrorException( "cannot set metatable for "+metatable.luaGetTypeName()); throw new LuaErrorException( "cannot set metatable for "+this.luaGetTypeName());
} }
/** Valid for all types: return the int value identifying the type of this value */ /** Valid for all types: return the int value identifying the type of this value */

View File

@@ -1,5 +1,5 @@
local print,tostring,_G = print,tostring,_G local print,tostring,_G,pcall,ipairs,isnumber = print,tostring,_G,pcall,ipairs,isnumber
local e,f,g,h,s local e,f,g,h,s
print( 'has debug', debug~=nil ) print( 'has debug', debug~=nil )
if not debug then error( 'no debug' ) end if not debug then error( 'no debug' ) end
@@ -49,6 +49,75 @@ do lvl=2,3
end end
end end
print( '----- debug.getupvalue, debug.setupvalue' )
local m,n,o = 101,102,103
f = function(p,q,r)
local p,q,r = 104,105,106
local g = function(s,t,u)
local v,w,x = 107,108,109
return function()
return m,n,o,p,q,r,v,w,x
end
end
return g
end
g = f()
h = g()
local callh = function()
local t = {}
for i,v in ipairs( { pcall(h) } ) do
t[i] = tostring(v)
end
return table.concat(t,',')
end
print( 'h', h() )
local funs = { f, g, h }
local names = { 'f', 'g', 'h' }
for i=1,3 do
local fun,name = funs[i],names[i]
for index=0,10 do
local s1,x1,y1 = pcall( debug.getupvalue, fun, index )
local s2,x2,y2 = pcall( debug.setupvalue, fun, index, 666000+i*111000+index )
local s3,x3,y3 = pcall( debug.getupvalue, fun, index )
print( name..' -> '..i..'-'..index..' '..
'get='..tostring(s1)..','..tostring(x1)..','..tostring(y1)..' '..
'set='..tostring(s2)..','..tostring(x2)..','..tostring(y2)..' '..
'get='..tostring(s3)..','..tostring(x3)..','..tostring(y3)..' '..
'tbl='..callh() )
end
end
print( '----- debug.setmetatable, debug.getmetatable' )
local a = {a='bbb'}
local b = {}
local mt = {__index={b='ccc'}}
print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b))
local s1,x1,y1 = pcall( debug.getmetatable, a )
local s2,x2,y2 = pcall( debug.setmetatable, a, mt )
print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b))
local s3,x3,y3 = pcall( debug.getmetatable, a )
local s4,x4,y4 = pcall( debug.getmetatable, b )
local s5,x5,y5 = pcall( debug.setmetatable, a, nil )
print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b))
local s6,x6,y6 = pcall( debug.getmetatable, a )
if not s1 then print( 's1 error', x1 ) end
if not s2 then print( 's2 error', x2 ) end
if not s3 then print( 's3 error', x3 ) end
if not s4 then print( 's4 error', x4 ) end
if not s5 then print( 's5 error', x5 ) end
if not s6 then print( 's6 error', x6 ) end
print( 'get='..tostring(s1)..','..tostring(x1==nil)..','..tostring(y1) )
print( 'set='..tostring(s2)..','..tostring(x2==a)..','..tostring(y2) )
print( 'get='..tostring(s3)..','..tostring(x3==mt)..','..tostring(y3) )
print( 'get='..tostring(s4)..','..tostring(x4==nil)..','..tostring(y4) )
print( 'set='..tostring(s5)..','..tostring(x5==a)..','..tostring(y5) )
print( 'get='..tostring(s6)..','..tostring(x6==nil)..','..tostring(y6) )
print( pcall( debug.getmetatable, 1 ) )
-- print( pcall( debug.setmetatable, 1, {} ) )
-- print( pcall( debug.setmetatable, 1, nil ) )
--[[ --[[
local f = function(a) local f = function(a)
return 'f:'..tostring(a)..'|'..tostring(b) return 'f:'..tostring(a)..'|'..tostring(b)