refactor get table with metatable

This commit is contained in:
James Roseborough
2008-05-23 07:39:57 +00:00
parent c2c573744b
commit 8c074d6ac6
3 changed files with 58 additions and 11 deletions

View File

@@ -29,6 +29,10 @@ public class LFunction extends LValue {
return "function: "+hashCode(); return "function: "+hashCode();
} }
public boolean isFunction() {
return true;
}
public void luaSetTable(LuaState vm, LValue table, LValue key, LValue val) { public void luaSetTable(LuaState vm, LValue table, LValue key, LValue val) {
vm.pushlvalue( this ); vm.pushlvalue( this );
vm.pushlvalue( table ); vm.pushlvalue( table );

View File

@@ -340,4 +340,9 @@ public class LValue {
public boolean isTable() { public boolean isTable() {
return false; return false;
} }
/** Return true if this is a LFunction */
public boolean isFunction() {
return false;
}
} }

View File

@@ -77,7 +77,8 @@ public class LuaState extends Lua {
private static final int LUA_ERRERR = 5; private static final int LUA_ERRERR = 5;
private static final int LUA_MINSTACK = 20; private static final int LUA_MINSTACK = 20;
private static final int LUA_MINCALLS = 10; private static final int LUA_MINCALLS = 10;
private static final int MAXTAGLOOP = 100;
public int base = 0; public int base = 0;
public int top = 0; public int top = 0;
@@ -560,7 +561,7 @@ public class LuaState extends Lua {
key = k[b]; key = k[b];
table = cl.env; table = cl.env;
this.top = base + a; this.top = base + a;
this.stack[base+a] = table.luaGetTable(this, table, key); luaV_gettable(table, key);
continue; continue;
} }
case LuaState.OP_GETTABLE: { case LuaState.OP_GETTABLE: {
@@ -568,7 +569,7 @@ public class LuaState extends Lua {
key = GETARG_RKC(k, i); key = GETARG_RKC(k, i);
table = this.stack[base + b]; table = this.stack[base + b];
this.top = base + a; this.top = base + a;
this.stack[base+a] = table.luaGetTable(this, table, key); luaV_gettable(table, key);
continue; continue;
} }
case LuaState.OP_SETGLOBAL: { case LuaState.OP_SETGLOBAL: {
@@ -603,7 +604,7 @@ public class LuaState extends Lua {
rkb = GETARG_RKB(k, i); rkb = GETARG_RKB(k, i);
rkc = GETARG_RKC(k, i); rkc = GETARG_RKC(k, i);
this.top = base + a; this.top = base + a;
this.stack[base + a] = rkb.luaGetTable(this, rkb, rkc); luaV_gettable(rkb, rkc);
this.stack[base + a + 1] = rkb; this.stack[base + a + 1] = rkb;
// StkId rb = RB(i); // StkId rb = RB(i);
// setobjs2s(L, ra+1, rb); // setobjs2s(L, ra+1, rb);
@@ -797,8 +798,8 @@ public class LuaState extends Lua {
case LuaState.OP_TFORLOOP: { case LuaState.OP_TFORLOOP: {
cb = base + a + 3; /* call base */ cb = base + a + 3; /* call base */
base = cb; base = cb;
adjustTop( cb + 3 );
System.arraycopy(this.stack, cb-3, this.stack, cb, 3); System.arraycopy(this.stack, cb-3, this.stack, cb, 3);
top = cb + 3;
// call the iterator // call the iterator
c = LuaState.GETARG_C(i); c = LuaState.GETARG_C(i);
@@ -907,6 +908,46 @@ public class LuaState extends Lua {
return calls[cc-callStackDepth]; return calls[cc-callStackDepth];
} }
private LValue mtget(LValue t, LString tag) {
LTable mt = t.luaGetMetatable();
if ( mt == null )
return null;
LValue h = mt.get(tag);
return h.isNil()? null: h;
}
private void luaV_gettable(LValue table, LValue key) {
LTable m;
LValue v,h=LNil.NIL,t=table;
for ( int loop=0; loop<MAXTAGLOOP; loop++ ) {
if ( t.isTable() ) {
v = ((LTable) t).get(key);
if ( !v.isNil() ) {
pushlvalue( v );
return;
}
h = mtget(t, LTable.TM_INDEX);
if ( h == null ) {
pushnil();
return;
}
} else {
h = mtget(t, LTable.TM_INDEX);
if ( h == null ) {
error("type error: "+t.luaGetTypeName()+" (index)");
}
}
if (h.isFunction()) {
pushlvalue(h);
pushlvalue(table);
pushlvalue(key);
call(2,1);
return;
}
t = h;
}
error("loop in gettable");
}
//=============================================================== //===============================================================
// Lua Java API // Lua Java API
@@ -1329,7 +1370,7 @@ public class LuaState extends Lua {
*/ */
public void getfield(int index, LString k) { public void getfield(int index, LString k) {
LTable t = totable(index); LTable t = totable(index);
pushlvalue( t.luaGetTable(this, t, k) ); luaV_gettable(t, k);
} }
/** /**
@@ -1345,8 +1386,7 @@ public class LuaState extends Lua {
* </pre> * </pre>
*/ */
public void getglobal(String s) { public void getglobal(String s) {
LTable t = this._G; luaV_gettable(_G, new LString(s));
pushlvalue( t.luaGetTable(this, t, new LString(s)) );
} }
/** /**
@@ -1385,9 +1425,7 @@ public class LuaState extends Lua {
public void gettable(int index) { public void gettable(int index) {
LValue t = totable(index); LValue t = totable(index);
LValue k = poplvalue(); LValue k = poplvalue();
// todo: what if this triggers metatable ops luaV_gettable(t, k);
// pushlvalue( t.luaGetTable(this, t, k) );
pushlvalue( t.luaGetTable(this, t, k) );
} }
/** /**