Improve luajc bytecode generation.
This commit is contained in:
@@ -128,6 +128,9 @@ public class BasicBlock {
|
||||
case Lua.OP_LOADBOOL:
|
||||
if ( Lua.GETARG_C(ins) == 0 )
|
||||
break;
|
||||
if ( Lua.GET_OPCODE(code[i+1]) == Lua.OP_JMP )
|
||||
throw new IllegalArgumentException("OP_LOADBOOL followed by jump at "+i);
|
||||
break;
|
||||
case Lua.OP_EQ:
|
||||
case Lua.OP_LT:
|
||||
case Lua.OP_LE:
|
||||
|
||||
@@ -65,7 +65,7 @@ public class LuaJC implements LuaCompiler {
|
||||
|
||||
private void insert(Hashtable h, JavaGen gen) {
|
||||
h.put(gen.classname, gen.bytecode);
|
||||
for ( int i=0; i<gen.inners.length; i++ )
|
||||
for ( int i=0, n=gen.inners!=null? gen.inners.length: 0; i<n; i++ )
|
||||
insert(h, gen.inners[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,19 +161,19 @@ public class ProtoInfo {
|
||||
for ( ; a<=b; a++ )
|
||||
v[a][pc] = new VarInfo(a,pc);
|
||||
break;
|
||||
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
case Lua.OP_VARARG: /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
|
||||
a = Lua.GETARG_A( ins );
|
||||
b = Lua.GETARG_B( ins );
|
||||
for ( int j=0; j<b; j++, a++ )
|
||||
for ( int j=1; j<b; j++, a++ )
|
||||
v[a][pc] = new VarInfo(a,pc);
|
||||
if ( b == 0 )
|
||||
for ( ; a<m; a++ )
|
||||
v[a][pc] = VarInfo.INVALID;
|
||||
break;
|
||||
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
||||
a = Lua.GETARG_A( ins );
|
||||
c = Lua.GETARG_C( ins );
|
||||
for ( int j=0; j<c; j++, a++ )
|
||||
for ( int j=0; j<=c-2; j++, a++ )
|
||||
v[a][pc] = new VarInfo(a,pc);
|
||||
for ( ; a<m; a++ )
|
||||
v[a][pc] = VarInfo.INVALID;
|
||||
@@ -297,18 +297,23 @@ public class ProtoInfo {
|
||||
public boolean isUpvalueAssign(int pc, int slot) {
|
||||
if ( pc < 0 ) pc = 0;
|
||||
VarInfo v = vars[slot][pc];
|
||||
return v.upvalue != null && v.upvalue.rw;
|
||||
// return v.upvalue != null && v.upvalue.rw;
|
||||
return v != null && v.upvalue != null;
|
||||
}
|
||||
|
||||
public boolean isUpvalueCreate(int pc, int slot) {
|
||||
if ( pc < 0 ) pc = 0;
|
||||
VarInfo v = vars[slot][pc];
|
||||
return v.upvalue != null && v.upvalue.rw && v.allocupvalue && pc == v.pc;
|
||||
// return v.upvalue != null && v.upvalue.rw && v.allocupvalue && pc == v.pc;
|
||||
return v != null && v.upvalue != null && v.allocupvalue && pc == v.pc;
|
||||
}
|
||||
|
||||
public boolean isUpvalueRefer(int pc, int slot) {
|
||||
// TODO: when it is a CALL
|
||||
if ( pc < 0 ) pc = 0;
|
||||
VarInfo v = vars[slot][pc];
|
||||
return v.upvalue != null && v.upvalue.rw;
|
||||
// return v.upvalue != null && v.upvalue.rw;
|
||||
return v != null && v.upvalue != null;
|
||||
}
|
||||
|
||||
public boolean isInitialValueUsed(int slot) {
|
||||
|
||||
@@ -60,6 +60,13 @@ public class UpvalInfo {
|
||||
|
||||
// check for previous assignment
|
||||
loop: while ( true ) {
|
||||
// invalid values terminate search
|
||||
if ( v == VarInfo.INVALID )
|
||||
return;
|
||||
// nil values also terminate (TODO: mark as unintialized upvalue)
|
||||
if ( v.pc == -1 )
|
||||
return;
|
||||
|
||||
BasicBlock b = pi.blocks[v.pc];
|
||||
if ( v.upvalue == this ) {
|
||||
// loop detected, include previous values
|
||||
@@ -75,10 +82,6 @@ public class UpvalInfo {
|
||||
if ( v.upvalue != null )
|
||||
throw new IllegalArgumentException("upvalue collision detected between "+v.upvalue+" and "+this);
|
||||
|
||||
// invalid values terminate search
|
||||
if ( v == VarInfo.INVALID )
|
||||
return;
|
||||
|
||||
// assign the variable
|
||||
v.upvalue = this;
|
||||
this.includeVar(v);
|
||||
|
||||
Reference in New Issue
Block a user