fix setmetatable() to match C version
This commit is contained in:
@@ -118,7 +118,8 @@ public class BaseLib extends LFunction {
|
||||
Lua.TYPE_NAMES[type]+" expected, got no value)") );
|
||||
}
|
||||
|
||||
private void checkargtype(LuaState vm, int index, int type) {
|
||||
private void checkargtype
|
||||
(LuaState vm, int index, int type) {
|
||||
checkargexists( vm, index, type );
|
||||
int t = vm.type(index);
|
||||
if ( t != type ) {
|
||||
@@ -164,8 +165,11 @@ public class BaseLib extends LFunction {
|
||||
}
|
||||
case SETMETATABLE: {
|
||||
checkargtype(vm,2,Lua.LUA_TTABLE);
|
||||
if ( vm.gettop()<3 || ! (vm.isnil(3) || vm.istable(3)) )
|
||||
vm.error( "bad argument #2 to '?' (nil or table expected)" );
|
||||
vm.setmetatable(2);
|
||||
vm.remove(1);
|
||||
vm.settop(1);
|
||||
break;
|
||||
}
|
||||
case TYPE: {
|
||||
|
||||
@@ -43,7 +43,7 @@ public class PackageLib extends LFunction {
|
||||
|
||||
public static InputStream STDIN = null;
|
||||
public static PrintStream STDOUT = System.out;
|
||||
public static LTable LOADED = new LTable();
|
||||
public static LTable LOADED = null;
|
||||
|
||||
private static final LString _M = new LString("_M");
|
||||
private static final LString _NAME = new LString("_NAME");
|
||||
@@ -86,6 +86,7 @@ public class PackageLib extends LFunction {
|
||||
pckg = new LTable();
|
||||
for ( int i=LOADLIB; i<=SEEALL; i++ )
|
||||
pckg.put( NAMES[i], new PackageLib(i) );
|
||||
LOADED = new LTable();
|
||||
pckg.put( "loaded", LOADED );
|
||||
pckg.put( _PRELOAD, new LTable() );
|
||||
LTable loaders = new LTable(3,0);
|
||||
|
||||
@@ -85,8 +85,6 @@ public class LTable extends LValue {
|
||||
|
||||
private LTable m_metatable;
|
||||
|
||||
|
||||
|
||||
/** Construct an empty LTable with no initial capacity. */
|
||||
public LTable() {
|
||||
m_vector = EMPTY_ARRAY;
|
||||
@@ -273,8 +271,14 @@ public class LTable extends LValue {
|
||||
|
||||
/** Valid for tables */
|
||||
public void luaSetMetatable(LValue metatable) {
|
||||
this.m_metatable = ( metatable != null && metatable != LNil.NIL ) ?
|
||||
(LTable) metatable : null;
|
||||
if ( m_metatable != null && m_metatable.containsKey(TM_METATABLE) )
|
||||
throw new LuaErrorException("cannot change a protected metatable");
|
||||
if ( metatable == null || metatable == LNil.NIL )
|
||||
this.m_metatable = null;
|
||||
else if ( metatable.luaGetType() == Lua.LUA_TTABLE )
|
||||
this.m_metatable = (LTable) metatable;
|
||||
else
|
||||
throw new LuaErrorException("nil or table expected, got "+metatable.luaGetTypeName());
|
||||
}
|
||||
|
||||
public String toJavaString() {
|
||||
|
||||
@@ -31,6 +31,9 @@ public class LValue {
|
||||
/** Metatable tag for intercepting table sets */
|
||||
public static final LString TM_NEWINDEX = new LString("__newindex");
|
||||
|
||||
/** Metatable tag for intercepting table sets */
|
||||
public static final LString TM_METATABLE = new LString("__metatable");
|
||||
|
||||
protected void conversionError(String target) {
|
||||
throw new LuaErrorException( "bad conversion: "+luaGetTypeName()+" to "+target );
|
||||
}
|
||||
@@ -70,12 +73,12 @@ public class LValue {
|
||||
|
||||
// unsupported except for numbers
|
||||
public LValue luaBinOpInteger(int opcode, int m_value) {
|
||||
return arithmeticError("number");
|
||||
return arithmeticError(luaGetTypeName());
|
||||
}
|
||||
|
||||
// unsupported except for numbers
|
||||
public LValue luaBinOpDouble(int opcode, double m_value) {
|
||||
return arithmeticError("number");
|
||||
return arithmeticError(luaGetTypeName());
|
||||
}
|
||||
|
||||
// unsupported except for numbers, strings, and == with various combinations of Nil, Boolean, etc.
|
||||
|
||||
@@ -141,7 +141,7 @@ public class LuaJTest extends TestCase {
|
||||
private void runTest( String testName ) throws IOException, InterruptedException {
|
||||
|
||||
// new lua state
|
||||
LuaState state = new DebugLuaState();
|
||||
LuaState state = LuaState.newState();
|
||||
|
||||
// add standard bindings
|
||||
state.installStandardLibs();
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
-- unit tests for functions in BaseLib.java
|
||||
local ids = {}
|
||||
local function id(obj)
|
||||
local v = ids[obj]
|
||||
if v then
|
||||
return v
|
||||
end
|
||||
table.insert(ids,obj)
|
||||
ids[obj] = type(obj)..'.'..tostring(#ids)
|
||||
return ids[obj]
|
||||
end
|
||||
package.path = "?.lua;src/test/res/?.lua"
|
||||
require 'ids'
|
||||
|
||||
-- print
|
||||
print()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
-- object ids
|
||||
package.path = "?.lua;src/test/res/?.lua"
|
||||
require 'ids'
|
||||
ids = {}
|
||||
|
||||
-- test of common types of errors
|
||||
local function c(f,...) return f(...) end
|
||||
@@ -9,7 +8,6 @@ local function b(...) return c(...) end
|
||||
local function a(...) return pcall(b,...) end
|
||||
s = 'some string'
|
||||
local t = {}
|
||||
|
||||
-- error message tests
|
||||
print( 'a(error)', a(error) )
|
||||
print( 'a(error,"msg")', a(error,"msg") )
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
package.path = "?.lua;src/test/res/?.lua"
|
||||
require 'ids'
|
||||
|
||||
-- The purpose of this test case is to demonstrate that
|
||||
-- basic metatable operations on non-table types work.
|
||||
-- i.e. that s.sub(s,...) could be used in place of string.sub(s,...)
|
||||
local s = "hello"
|
||||
print(s:sub(2,4))
|
||||
|
||||
local t = {}
|
||||
function op(name,...)
|
||||
a,b,c,d = pcall( setmetatable, t, ... )
|
||||
print( name, id(t), id(getmetatable(t)), id(a), id(b), id(c), id(d) )
|
||||
end
|
||||
op('set{} ',{})
|
||||
op('set-nil',nil)
|
||||
op('set{} ',{})
|
||||
op('set')
|
||||
op('set{} ',{})
|
||||
op('set{} ',{})
|
||||
op('set{}{}',{},{})
|
||||
op('set-nil',nil)
|
||||
op('set{__}',{__metatable={}})
|
||||
op('set{} ',{})
|
||||
op('set-nil',nil)
|
||||
t = {}
|
||||
op('set{} ',{})
|
||||
op('set-nil',nil)
|
||||
op('set{__}',{__metatable='abc'})
|
||||
op('set{} ',{})
|
||||
op('set-nil',nil)
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
-- unit tests for require() function
|
||||
local ids = {}
|
||||
local ti = table.insert
|
||||
local function id(obj)
|
||||
if not obj or type(obj) == 'number' or type(obj) == 'string' or type(obj) == 'boolean' then
|
||||
return obj
|
||||
end
|
||||
local v = ids[obj]
|
||||
if v then
|
||||
return v
|
||||
end
|
||||
ti(ids,obj)
|
||||
ids[obj] = type(obj)..'.'..tostring(#ids)
|
||||
return ids[obj]
|
||||
end
|
||||
package.path = "?.lua;src/test/res/?.lua"
|
||||
require 'ids'
|
||||
|
||||
-- tests on require
|
||||
package.path='?.lua;src/test/res/?.lua'
|
||||
|
||||
Reference in New Issue
Block a user