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: case Lua.OP_LOADBOOL:
if ( Lua.GETARG_C(ins) == 0 ) if ( Lua.GETARG_C(ins) == 0 )
break; 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_EQ:
case Lua.OP_LT: case Lua.OP_LT:
case Lua.OP_LE: case Lua.OP_LE:

View File

@@ -65,7 +65,7 @@ public class LuaJC implements LuaCompiler {
private void insert(Hashtable h, JavaGen gen) { private void insert(Hashtable h, JavaGen gen) {
h.put(gen.classname, gen.bytecode); 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]); insert(h, gen.inners[i]);
} }

View File

@@ -161,19 +161,19 @@ public class ProtoInfo {
for ( ; a<=b; a++ ) for ( ; a<=b; a++ )
v[a][pc] = new VarInfo(a,pc); v[a][pc] = new VarInfo(a,pc);
break; 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 */ case Lua.OP_VARARG: /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
a = Lua.GETARG_A( ins ); a = Lua.GETARG_A( ins );
b = Lua.GETARG_B( 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); v[a][pc] = new VarInfo(a,pc);
if ( b == 0 )
for ( ; a<m; a++ ) for ( ; a<m; a++ )
v[a][pc] = VarInfo.INVALID; v[a][pc] = VarInfo.INVALID;
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)) */
a = Lua.GETARG_A( ins ); a = Lua.GETARG_A( ins );
c = Lua.GETARG_C( 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); v[a][pc] = new VarInfo(a,pc);
for ( ; a<m; a++ ) for ( ; a<m; a++ )
v[a][pc] = VarInfo.INVALID; v[a][pc] = VarInfo.INVALID;
@@ -297,18 +297,23 @@ public class ProtoInfo {
public boolean isUpvalueAssign(int pc, int slot) { public boolean isUpvalueAssign(int pc, int slot) {
if ( pc < 0 ) pc = 0; if ( pc < 0 ) pc = 0;
VarInfo v = vars[slot][pc]; 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) { public boolean isUpvalueCreate(int pc, int slot) {
if ( pc < 0 ) pc = 0;
VarInfo v = vars[slot][pc]; 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) { public boolean isUpvalueRefer(int pc, int slot) {
// TODO: when it is a CALL // TODO: when it is a CALL
if ( pc < 0 ) pc = 0;
VarInfo v = vars[slot][pc]; 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) { public boolean isInitialValueUsed(int slot) {

View File

@@ -60,6 +60,13 @@ public class UpvalInfo {
// check for previous assignment // check for previous assignment
loop: while ( true ) { 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]; BasicBlock b = pi.blocks[v.pc];
if ( v.upvalue == this ) { if ( v.upvalue == this ) {
// loop detected, include previous values // loop detected, include previous values
@@ -75,10 +82,6 @@ public class UpvalInfo {
if ( v.upvalue != null ) if ( v.upvalue != null )
throw new IllegalArgumentException("upvalue collision detected between "+v.upvalue+" and "+this); throw new IllegalArgumentException("upvalue collision detected between "+v.upvalue+" and "+this);
// invalid values terminate search
if ( v == VarInfo.INVALID )
return;
// assign the variable // assign the variable
v.upvalue = this; v.upvalue = this;
this.includeVar(v); this.includeVar(v);