Improve luajc bytecode generation.

This commit is contained in:
James Roseborough
2010-08-06 14:47:00 +00:00
parent 0348ac9f90
commit df86eca3c3
4 changed files with 24 additions and 13 deletions

View File

@@ -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:

View File

@@ -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]);
}

View File

@@ -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) {

View File

@@ -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);