Tests and fixes for debug.setupvalue, getupvalue, setmetatable, and getmetatable
This commit is contained in:
@@ -31,7 +31,7 @@ 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.LuaErrorException;
|
||||
import org.luaj.vm.LuaState;
|
||||
|
||||
public class DebugLib extends LFunction {
|
||||
@@ -348,15 +348,27 @@ public class DebugLib extends LFunction {
|
||||
private void getmetatable(LuaState vm) {
|
||||
LValue object = vm.topointer(2);
|
||||
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) {
|
||||
LValue object = vm.topointer(2);
|
||||
LValue table = vm.totable(3);
|
||||
object.luaSetMetatable(table);
|
||||
vm.resettop();
|
||||
vm.pushlvalue( object );
|
||||
try {
|
||||
if ( ! vm.isnoneornil(3) )
|
||||
object.luaSetMetatable(vm.checktable(3));
|
||||
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) {
|
||||
@@ -364,14 +376,26 @@ public class DebugLib extends LFunction {
|
||||
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) {
|
||||
LFunction func = vm.checkfunction(2);
|
||||
int up = vm.checkint(3);
|
||||
vm.resettop();
|
||||
if ( func instanceof LClosure ) {
|
||||
LClosure c = (LClosure) func;
|
||||
if ( c.upVals != null && up > 0 && up < c.upVals.length ) {
|
||||
vm.pushlvalue(c.upVals[up].getValue());
|
||||
LString name = findupvalue(c, up);
|
||||
if ( name != null ) {
|
||||
vm.pushlstring(name);
|
||||
vm.pushlvalue(c.upVals[up-1].getValue());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -385,12 +409,10 @@ public class DebugLib extends LFunction {
|
||||
vm.resettop();
|
||||
if ( func instanceof LClosure ) {
|
||||
LClosure c = (LClosure) func;
|
||||
if ( c.upVals != null && up > 0 && up < c.upVals.length ) {
|
||||
c.upVals[up].setValue(value);
|
||||
if ( c.p.upvalues != null && up < c.p.upvalues.length )
|
||||
vm.pushlvalue( c.p.upvalues[up] );
|
||||
else
|
||||
vm.pushstring( "."+up+"" );
|
||||
LString name = findupvalue(c, up);
|
||||
if ( name != null ) {
|
||||
c.upVals[up-1].setValue(value);
|
||||
vm.pushlstring(name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ public class LValue {
|
||||
* @return this if unchanged, or new LTable if copied using weak table
|
||||
*/
|
||||
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 */
|
||||
|
||||
@@ -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
|
||||
print( 'has debug', debug~=nil )
|
||||
if not debug then error( 'no debug' ) end
|
||||
@@ -49,6 +49,75 @@ do lvl=2,3
|
||||
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)
|
||||
return 'f:'..tostring(a)..'|'..tostring(b)
|
||||
|
||||
Reference in New Issue
Block a user