Improve luajc bytecode generation.
This commit is contained in:
@@ -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:
|
||||||
|
|||||||
@@ -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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user