Update LuaJC to work with lua 5.2 model of environments.
This commit is contained in:
@@ -90,6 +90,8 @@ public class LuaClosure extends LuaFunction {
|
|||||||
|
|
||||||
public final Prototype p;
|
public final Prototype p;
|
||||||
|
|
||||||
|
public UpValue[] upValues;
|
||||||
|
|
||||||
/** Create a closure around a Prototype with the default global environment.
|
/** Create a closure around a Prototype with the default global environment.
|
||||||
* If the prototype has upvalues, the environment will be written into the first upvalue.
|
* If the prototype has upvalues, the environment will be written into the first upvalue.
|
||||||
* @param p the Prototype to construct this Closure for.
|
* @param p the Prototype to construct this Closure for.
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ public class LuaFunction extends LuaValue {
|
|||||||
/** Shared static metatable for all functions and closures. */
|
/** Shared static metatable for all functions and closures. */
|
||||||
public static LuaValue s_metatable;
|
public static LuaValue s_metatable;
|
||||||
|
|
||||||
public UpValue[] upValues;
|
|
||||||
|
|
||||||
public int type() {
|
public int type() {
|
||||||
return TFUNCTION;
|
return TFUNCTION;
|
||||||
}
|
}
|
||||||
@@ -64,8 +62,11 @@ public class LuaFunction extends LuaValue {
|
|||||||
return s_metatable;
|
return s_metatable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Hook for implementations such as LuaJC to load the environment of the main chunk
|
||||||
|
* into the first upvalue location. If the function has no upvalues or is not a main chunk,
|
||||||
|
* calling this will be no effect.
|
||||||
|
* @param env The environment to load into the first upvalue, if there is one.
|
||||||
|
*/
|
||||||
public void initupvalue1(LuaValue env) {
|
public void initupvalue1(LuaValue env) {
|
||||||
if (upValues != null && upValues.length > 0)
|
|
||||||
upValues[0] = new UpValue(new LuaValue[] {env}, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -474,20 +474,23 @@ public class FuncState extends LuaC {
|
|||||||
this.freereg(e.u.info);
|
this.freereg(e.u.info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final LuaUserdata NIL_PROXY = new LuaUserdata(LuaValue.NIL);
|
||||||
|
|
||||||
int addk(LuaValue v) {
|
int addk(LuaValue v) {
|
||||||
|
LuaValue key = v.isnil()? NIL_PROXY: v;
|
||||||
if (this.h == null) {
|
if (this.h == null) {
|
||||||
this.h = new LuaTable();
|
this.h = new LuaTable();
|
||||||
} else {
|
} else {
|
||||||
LuaValue idx = this.h.get(v);
|
LuaValue idx = this.h.get(key);
|
||||||
if (idx.isnumber())
|
if (idx.isnumber())
|
||||||
return idx.toint();
|
return idx.toint();
|
||||||
}
|
}
|
||||||
int idx = this.nk;
|
int idx = this.nk;
|
||||||
this.h.set(v, LuaValue.valueOf(idx));
|
this.h.set(key, LuaValue.valueOf(idx));
|
||||||
final Prototype f = this.f;
|
final Prototype f = this.f;
|
||||||
if (f.k == null || nk + 1 >= f.k.length)
|
if (f.k == null || nk + 1 >= f.k.length)
|
||||||
f.k = realloc( f.k, nk*2 + 1 );
|
f.k = realloc( f.k, nk*2 + 1 );
|
||||||
f.k[this.nk++] = v.isuserdata()? LuaValue.NIL: v;
|
f.k[this.nk++] = v;
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,11 +512,8 @@ public class FuncState extends LuaC {
|
|||||||
return this.addk((b ? LuaValue.TRUE : LuaValue.FALSE));
|
return this.addk((b ? LuaValue.TRUE : LuaValue.FALSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static final LuaUserdata NIL_PROXY = new LuaUserdata(LuaValue.NIL);
|
|
||||||
|
|
||||||
int nilK() {
|
int nilK() {
|
||||||
/* cannot use nil as key; instead use table itself to represent nil */
|
return this.addk(LuaValue.NIL);
|
||||||
return this.addk(NIL_PROXY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setreturns(expdesc e, int nresults) {
|
void setreturns(expdesc e, int nresults) {
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2.lib;
|
package org.luaj.vm2.lib;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaThread;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.Varargs;
|
import org.luaj.vm2.Varargs;
|
||||||
|
|
||||||
@@ -77,6 +76,11 @@ abstract public class VarArgFunction extends LibFunction {
|
|||||||
* - function has a possibility of returning a TailcallVarargs
|
* - function has a possibility of returning a TailcallVarargs
|
||||||
* @param args the arguments to the function call.
|
* @param args the arguments to the function call.
|
||||||
*/
|
*/
|
||||||
abstract public Varargs invoke(Varargs args);
|
public Varargs invoke(Varargs args) {
|
||||||
|
return onInvoke(args).eval();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Varargs onInvoke(Varargs args) {
|
||||||
|
return invoke(args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ public class JavaBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nil parameters
|
// nil parameters
|
||||||
|
// TODO: remove this for lua 5.2, not needed
|
||||||
for ( ; slot<p.maxstacksize; slot++ ) {
|
for ( ; slot<p.maxstacksize; slot++ ) {
|
||||||
if ( pi.isInitialValueUsed(slot) ) {
|
if ( pi.isInitialValueUsed(slot) ) {
|
||||||
loadNil();
|
loadNil();
|
||||||
@@ -280,6 +281,31 @@ public class JavaBuilder {
|
|||||||
cg.addMethod(mg.getMethod());
|
cg.addMethod(mg.getMethod());
|
||||||
main.dispose();
|
main.dispose();
|
||||||
|
|
||||||
|
// add initupvalue1(LuaValue env) to initialize environment for main chunk
|
||||||
|
if (p.upvalues.length == 1 && superclassType == SUPERTYPE_VARARGS) {
|
||||||
|
MethodGen mg = new MethodGen( Constants.ACC_PUBLIC | Constants.ACC_FINAL, // access flags
|
||||||
|
Type.VOID, // return type
|
||||||
|
ARG_TYPES_LUAVALUE, // argument types
|
||||||
|
new String[] { "env" }, // arg names
|
||||||
|
"initupvalue1",
|
||||||
|
STR_LUAVALUE, // method, defining class
|
||||||
|
main, cp);
|
||||||
|
boolean isrw = pi.isReadWriteUpvalue( pi.upvals[0] );
|
||||||
|
append(InstructionConstants.THIS);
|
||||||
|
append(new ALOAD(1));
|
||||||
|
if ( isrw ) {
|
||||||
|
append(factory.createInvoke(classname, "newupl", TYPE_LOCALUPVALUE, ARG_TYPES_LUAVALUE, Constants.INVOKESTATIC));
|
||||||
|
append(factory.createFieldAccess(classname, upvalueName(0), TYPE_LOCALUPVALUE, Constants.PUTFIELD));
|
||||||
|
} else {
|
||||||
|
append(factory.createFieldAccess(classname, upvalueName(0), TYPE_LUAVALUE, Constants.PUTFIELD));
|
||||||
|
}
|
||||||
|
append(InstructionConstants.RETURN);
|
||||||
|
mg.setMaxStack();
|
||||||
|
cg.addMethod(mg.getMethod());
|
||||||
|
main.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// convert to class bytes
|
// convert to class bytes
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
@@ -420,11 +446,6 @@ public class JavaBuilder {
|
|||||||
append(factory.createInvoke(STR_LUAVALUE, "tableOf", TYPE_LUATABLE, ARG_TYPES_INT_INT, Constants.INVOKESTATIC));
|
append(factory.createInvoke(STR_LUAVALUE, "tableOf", TYPE_LUATABLE, ARG_TYPES_INT_INT, Constants.INVOKESTATIC));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadEnv() {
|
|
||||||
append(InstructionConstants.THIS);
|
|
||||||
append(factory.createFieldAccess(classname, "env", TYPE_LUAVALUE, Constants.GETFIELD));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadVarargs() {
|
public void loadVarargs() {
|
||||||
append(new ALOAD(1));
|
append(new ALOAD(1));
|
||||||
}
|
}
|
||||||
@@ -594,9 +615,6 @@ public class JavaBuilder {
|
|||||||
append(factory.createNew(new ObjectType(protoname)));
|
append(factory.createNew(new ObjectType(protoname)));
|
||||||
append(InstructionConstants.DUP);
|
append(InstructionConstants.DUP);
|
||||||
append(factory.createInvoke(protoname, "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
|
append(factory.createInvoke(protoname, "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
|
||||||
append(InstructionConstants.DUP);
|
|
||||||
loadEnv();
|
|
||||||
append(factory.createInvoke(STR_LUAVALUE, "setfenv", Type.VOID, ARG_TYPES_LUAVALUE, Constants.INVOKEVIRTUAL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closureInitUpvalueFromUpvalue(String protoname, int newup, int upindex) {
|
public void closureInitUpvalueFromUpvalue(String protoname, int newup, int upindex) {
|
||||||
@@ -779,4 +797,8 @@ public class JavaBuilder {
|
|||||||
public void tovalue() {
|
public void tovalue() {
|
||||||
append(factory.createInvoke(STR_BUFFER, "value", TYPE_LUAVALUE, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
|
append(factory.createInvoke(STR_BUFFER, "value", TYPE_LUAVALUE, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void closeUpvalue(int pc, int i) {
|
||||||
|
// TODO: assign the upvalue location the value null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2.luajc;
|
package org.luaj.vm2.luajc;
|
||||||
|
|
||||||
import org.luaj.vm2.Buffer;
|
|
||||||
import org.luaj.vm2.Lua;
|
import org.luaj.vm2.Lua;
|
||||||
import org.luaj.vm2.Prototype;
|
import org.luaj.vm2.Prototype;
|
||||||
|
import org.luaj.vm2.Upvaldesc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO:
|
* TODO:
|
||||||
@@ -202,6 +202,11 @@ public class JavaGen {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_JMP: /* sBx pc+=sBx */
|
case Lua.OP_JMP: /* sBx pc+=sBx */
|
||||||
|
if (a > 0) {
|
||||||
|
for (int i = a-1; i < pi.openups.length; ++i) {
|
||||||
|
builder.closeUpvalue(pc, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
builder.addBranch(pc, JavaBuilder.BRANCH_GOTO, pc+1+sbx);
|
builder.addBranch(pc, JavaBuilder.BRANCH_GOTO, pc+1+sbx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -228,7 +233,7 @@ public class JavaGen {
|
|||||||
builder.storeLocal( pc, a );
|
builder.storeLocal( pc, a );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
|
case Lua.OP_CALL: { /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||||
|
|
||||||
// load function
|
// load function
|
||||||
builder.loadLocal(pc, a);
|
builder.loadLocal(pc, a);
|
||||||
@@ -280,6 +285,7 @@ public class JavaGen {
|
|||||||
builder.storeVarresult();
|
builder.storeVarresult();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||||
@@ -343,45 +349,24 @@ public class JavaGen {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||||
throw new RuntimeException("Unimplemented OP_TFORCALL");
|
|
||||||
|
|
||||||
case Lua.OP_TFORLOOP: /*
|
|
||||||
* A C R(A+3), ... ,R(A+2+C):= R(A)(R(A+1),
|
|
||||||
* R(A+2)): if R(A+3) ~= nil then R(A+2)=R(A+3)
|
|
||||||
* else pc++
|
|
||||||
*/
|
|
||||||
// v = stack[a].invoke(varargsOf(stack[a+1],stack[a+2]));
|
|
||||||
// if ( (o=v.arg1()).isnil() )
|
|
||||||
// ++pc;
|
|
||||||
builder.loadLocal(pc, a);
|
builder.loadLocal(pc, a);
|
||||||
builder.loadLocal(pc, a+1);
|
builder.loadLocal(pc, a+1);
|
||||||
builder.loadLocal(pc, a+2);
|
builder.loadLocal(pc, a+2);
|
||||||
builder.invoke(2); // varresult on stack
|
builder.invoke(2);
|
||||||
builder.dup();
|
for ( int i=1; i<=c; i++ ) {
|
||||||
builder.storeVarresult();
|
if ( i < c )
|
||||||
builder.arg( 1 );
|
|
||||||
builder.isNil();
|
|
||||||
builder.addBranch(pc, JavaBuilder.BRANCH_IFNE, pc+2);
|
|
||||||
|
|
||||||
// a[2] = a[3] = v[1], leave varargs on stack
|
|
||||||
builder.createUpvalues(pc, a+3, c);
|
|
||||||
builder.loadVarresult();
|
|
||||||
if (c>=2)
|
|
||||||
builder.dup();
|
|
||||||
builder.arg( 1 );
|
|
||||||
builder.dup();
|
|
||||||
builder.storeLocal(pc, a+2);
|
|
||||||
builder.storeLocal(pc, a+3);
|
|
||||||
|
|
||||||
// v[2]..v[c], use varargs from stack
|
|
||||||
for ( int j=2; j<=c; j++ ) {
|
|
||||||
if ( j<c )
|
|
||||||
builder.dup();
|
builder.dup();
|
||||||
builder.arg( j );
|
builder.arg( i );
|
||||||
builder.storeLocal(pc, a+2+j);
|
builder.storeLocal(pc, a+2+i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Lua.OP_TFORLOOP:/* A sBx if R(A) != nil then ps+= sBx */
|
||||||
|
builder.loadLocal(pc, a);
|
||||||
|
builder.isNil();
|
||||||
|
builder.addBranch(pc, JavaBuilder.BRANCH_IFNE, pc+1+sbx);
|
||||||
|
break;
|
||||||
|
|
||||||
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
||||||
int index0 = (c-1)*Lua.LFIELDS_PER_FLUSH + 1;
|
int index0 = (c-1)*Lua.LFIELDS_PER_FLUSH + 1;
|
||||||
builder.loadLocal( pc, a );
|
builder.loadLocal( pc, a );
|
||||||
@@ -401,25 +386,20 @@ public class JavaGen {
|
|||||||
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
||||||
{
|
{
|
||||||
Prototype newp = p.p[bx];
|
Prototype newp = p.p[bx];
|
||||||
String protoname = closureName(classname, bx);
|
|
||||||
int nup = newp.upvalues.length;
|
int nup = newp.upvalues.length;
|
||||||
|
String protoname = closureName(classname, bx);
|
||||||
builder.closureCreate( protoname );
|
builder.closureCreate( protoname );
|
||||||
if ( nup > 0 )
|
if ( nup > 0 )
|
||||||
builder.dup();
|
builder.dup();
|
||||||
builder.storeLocal( pc, a );
|
builder.storeLocal( pc, a );
|
||||||
if ( nup > 0 ) {
|
for ( int up=0; up<nup; ++up ) {
|
||||||
for ( int up=0; up<nup; ++up ) {
|
if ( up+1 < nup )
|
||||||
if ( up+1 < nup )
|
builder.dup();
|
||||||
builder.dup();
|
Upvaldesc u = newp.upvalues[up];
|
||||||
ins = p.code[pc+up+1];
|
if (u.instack)
|
||||||
b = Lua.GETARG_B(ins);
|
builder.closureInitUpvalueFromLocal( protoname, up, pc, u.idx );
|
||||||
if ( (ins&4) != 0 ) {
|
else
|
||||||
builder.closureInitUpvalueFromUpvalue( protoname, up, b );
|
builder.closureInitUpvalueFromUpvalue( protoname, up, u.idx );
|
||||||
} else {
|
|
||||||
builder.closureInitUpvalueFromLocal( protoname, up, pc, b );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pc += nup;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.io.PrintStream;
|
|||||||
import org.luaj.vm2.Lua;
|
import org.luaj.vm2.Lua;
|
||||||
import org.luaj.vm2.Print;
|
import org.luaj.vm2.Print;
|
||||||
import org.luaj.vm2.Prototype;
|
import org.luaj.vm2.Prototype;
|
||||||
|
import org.luaj.vm2.Upvaldesc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prototype information for static single-assignment analysis
|
* Prototype information for static single-assignment analysis
|
||||||
@@ -22,8 +23,10 @@ public class ProtoInfo {
|
|||||||
public final UpvalInfo[] upvals; // from outer scope
|
public final UpvalInfo[] upvals; // from outer scope
|
||||||
public final UpvalInfo[][] openups; // per slot, upvalues allocated by this prototype
|
public final UpvalInfo[][] openups; // per slot, upvalues allocated by this prototype
|
||||||
|
|
||||||
|
// A main chunk proto info.
|
||||||
public ProtoInfo(Prototype p, String name) {
|
public ProtoInfo(Prototype p, String name) {
|
||||||
this(p,name,null);
|
// For the outer chunk, we have one upvalue which is the environment.
|
||||||
|
this(p,name,new UpvalInfo[] { new UpvalInfo() });
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProtoInfo(Prototype p, String name, UpvalInfo[] u) {
|
private ProtoInfo(Prototype p, String name, UpvalInfo[] u) {
|
||||||
@@ -155,7 +158,7 @@ public class ProtoInfo {
|
|||||||
if ( pc > b0.pc0 )
|
if ( pc > b0.pc0 )
|
||||||
propogateVars( v, pc-1, pc );
|
propogateVars( v, pc-1, pc );
|
||||||
|
|
||||||
int a,b,c,nups;
|
int a,b,c;
|
||||||
int ins = prototype.code[pc];
|
int ins = prototype.code[pc];
|
||||||
int op = Lua.GET_OPCODE(ins);
|
int op = Lua.GET_OPCODE(ins);
|
||||||
|
|
||||||
@@ -164,7 +167,6 @@ public class ProtoInfo {
|
|||||||
case Lua.OP_LOADK:/* A Bx R(A) := Kst(Bx) */
|
case Lua.OP_LOADK:/* A Bx R(A) := Kst(Bx) */
|
||||||
case Lua.OP_LOADBOOL:/* A B C R(A) := (Bool)B; if (C) pc++ */
|
case Lua.OP_LOADBOOL:/* A B C R(A) := (Bool)B; if (C) pc++ */
|
||||||
case Lua.OP_GETUPVAL: /* A B R(A) := UpValue[B] */
|
case Lua.OP_GETUPVAL: /* A B R(A) := UpValue[B] */
|
||||||
case Lua.OP_GETTABUP: /* A B C R(A) := UpValue[B][RK(C)] */
|
|
||||||
case Lua.OP_NEWTABLE: /* A B C R(A) := {} (size = B,C) */
|
case Lua.OP_NEWTABLE: /* A B C R(A) := {} (size = B,C) */
|
||||||
a = Lua.GETARG_A( ins );
|
a = Lua.GETARG_A( ins );
|
||||||
v[a][pc] = new VarInfo(a,pc);
|
v[a][pc] = new VarInfo(a,pc);
|
||||||
@@ -235,6 +237,13 @@ public class ProtoInfo {
|
|||||||
v[a][pc] = new VarInfo(a,pc);
|
v[a][pc] = new VarInfo(a,pc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Lua.OP_GETTABUP: /* A B C R(A) := UpValue[B][RK(C)] */
|
||||||
|
a = Lua.GETARG_A( ins );
|
||||||
|
c = Lua.GETARG_C( ins );
|
||||||
|
if (!Lua.ISK(c)) v[c][pc].isreferenced = true;
|
||||||
|
v[a][pc] = new VarInfo(a,pc);
|
||||||
|
break;
|
||||||
|
|
||||||
case Lua.OP_SELF: /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
|
case Lua.OP_SELF: /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
|
||||||
a = Lua.GETARG_A( ins );
|
a = Lua.GETARG_A( ins );
|
||||||
b = Lua.GETARG_B( ins );
|
b = Lua.GETARG_B( ins );
|
||||||
@@ -316,22 +325,16 @@ public class ProtoInfo {
|
|||||||
v[a][pc] = VarInfo.INVALID;
|
v[a][pc] = VarInfo.INVALID;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_CLOSURE: /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
case Lua.OP_CLOSURE: { /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
||||||
a = Lua.GETARG_A( ins );
|
a = Lua.GETARG_A( ins );
|
||||||
b = Lua.GETARG_Bx( ins );
|
b = Lua.GETARG_Bx( ins );
|
||||||
nups = prototype.p[b].upvalues.length;
|
Upvaldesc[] upvalues = prototype.p[b].upvalues;
|
||||||
for ( int k=1; k<=nups; ++k ) {
|
for (int k = 0, nups = upvalues.length; k < nups; ++k)
|
||||||
int i = prototype.code[pc+k];
|
if (upvalues[k].instack)
|
||||||
if ( (i&4) == 0 ) {
|
v[upvalues[k].idx][pc].isreferenced = true;
|
||||||
b = Lua.GETARG_B(i);
|
|
||||||
v[b][pc].isreferenced = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v[a][pc] = new VarInfo(a,pc);
|
v[a][pc] = new VarInfo(a,pc);
|
||||||
for ( int k=1; k<=nups; k++ )
|
|
||||||
propogateVars( v, pc, pc+k );
|
|
||||||
pc += nups;
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
||||||
a = Lua.GETARG_A( ins );
|
a = Lua.GETARG_A( ins );
|
||||||
@@ -407,9 +410,8 @@ public class ProtoInfo {
|
|||||||
UpvalInfo[] newu = new UpvalInfo[newp.upvalues.length];
|
UpvalInfo[] newu = new UpvalInfo[newp.upvalues.length];
|
||||||
String newname = name + "$" + bx;
|
String newname = name + "$" + bx;
|
||||||
for ( int j=0; j<newp.upvalues.length; ++j ) {
|
for ( int j=0; j<newp.upvalues.length; ++j ) {
|
||||||
int i = code[++pc];
|
Upvaldesc u = newp.upvalues[j];
|
||||||
int b = Lua.GETARG_B(i);
|
newu[j] = u.instack? findOpenUp(pc,u.idx) : upvals[u.idx];
|
||||||
newu[j] = (i&4) != 0? upvals[b]: findOpenUp(pc,b);
|
|
||||||
}
|
}
|
||||||
subprotos[bx] = new ProtoInfo(newp, newname, newu);
|
subprotos[bx] = new ProtoInfo(newp, newname, newu);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ public class UpvalInfo {
|
|||||||
VarInfo var[]; // list of vars
|
VarInfo var[]; // list of vars
|
||||||
boolean rw; // read-write
|
boolean rw; // read-write
|
||||||
|
|
||||||
|
// Upval info representing the implied context containing only the environment.
|
||||||
|
public UpvalInfo() {
|
||||||
|
nvars = 1;
|
||||||
|
var = new VarInfo[] { VarInfo.PARAM(0) };
|
||||||
|
}
|
||||||
|
|
||||||
public UpvalInfo(ProtoInfo pi, int pc, int slot) {
|
public UpvalInfo(ProtoInfo pi, int pc, int slot) {
|
||||||
this.pi = pi;
|
this.pi = pi;
|
||||||
this.slot = slot;
|
this.slot = slot;
|
||||||
|
|||||||
Reference in New Issue
Block a user