refactor get table with metatable
This commit is contained in:
@@ -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 );
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user