Fix for loop processing in luajc compiler code generator for lua 5.3 bytecodes
This commit is contained in:
@@ -225,8 +225,7 @@ public class Lua {
|
||||
public static final int OP_FORPREP = 33; /* A sBx R(A)-=R(A+2); pc+=sBx */
|
||||
|
||||
public static final int OP_TFORCALL = 34; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||
public static final int OP_TFORLOOP = 35; /* 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++ */
|
||||
public static final int OP_TFORLOOP = 35; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
|
||||
public static final int OP_SETLIST = 36; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
||||
|
||||
public static final int OP_CLOSURE = 37; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
||||
|
||||
@@ -434,9 +434,10 @@ public class LuaClosure extends LuaFunction {
|
||||
c = (i>>14) & 0x1ff;
|
||||
while (--c >= 0)
|
||||
stack[a+3+c] = v.arg(c+1);
|
||||
v = NONE;
|
||||
continue;
|
||||
|
||||
case Lua.OP_TFORLOOP: /* A sBx if R(A) != nil then ps+= sBx */
|
||||
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
|
||||
if (!stack[a+1].isnil()) { /* continue loop? */
|
||||
stack[a] = stack[a+1]; /* save control varible. */
|
||||
pc += (i>>>14)-0x1ffff;
|
||||
|
||||
@@ -395,11 +395,15 @@ public class DebugLib extends OneArgFunction {
|
||||
// debug.upvaluejoin (f1, n1, f2, n2)
|
||||
final class upvaluejoin extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
LuaValue f1 = args.checkfunction(1);
|
||||
LuaClosure f1 = args.checkclosure(1);
|
||||
int n1 = args.checkint(2);
|
||||
LuaValue f2 = args.checkfunction(3);
|
||||
LuaClosure f2 = args.checkclosure(3);
|
||||
int n2 = args.checkint(4);
|
||||
f1.checkclosure().upValues[n1] = f2.checkclosure().upValues[n2];
|
||||
if (n1 < 1 || n1 > f1.upValues.length)
|
||||
argerror("index out of range");
|
||||
if (n2 < 1 || n2 > f2.upValues.length)
|
||||
argerror("index out of range");
|
||||
f1.upValues[n1-1] = f2.upValues[n2-1];
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,6 @@ public class BasicBlock {
|
||||
case Lua.OP_LE:
|
||||
case Lua.OP_TEST:
|
||||
case Lua.OP_TESTSET:
|
||||
case Lua.OP_TFORLOOP:
|
||||
if ( Lua.GET_OPCODE(code[i+1]) != Lua.OP_JMP )
|
||||
throw new IllegalArgumentException("test not followed by jump at "+i);
|
||||
sbx = Lua.GETARG_sBx(code[i+1]);
|
||||
@@ -129,6 +128,7 @@ public class BasicBlock {
|
||||
visitor.visitBranch( i, j );
|
||||
visitor.visitBranch( i, i+1 );
|
||||
continue;
|
||||
case Lua.OP_TFORLOOP:
|
||||
case Lua.OP_FORLOOP:
|
||||
sbx = Lua.GETARG_sBx(ins);
|
||||
j = i + sbx + 1;
|
||||
|
||||
@@ -361,10 +361,12 @@ public class JavaGen {
|
||||
}
|
||||
break;
|
||||
|
||||
case Lua.OP_TFORLOOP:/* A sBx if R(A) != nil then ps+= sBx */
|
||||
builder.loadLocal(pc, a);
|
||||
case Lua.OP_TFORLOOP:/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
|
||||
builder.loadLocal(pc, a+1);
|
||||
builder.dup();
|
||||
builder.storeLocal(pc, a);
|
||||
builder.isNil();
|
||||
builder.addBranch(pc, JavaBuilder.BRANCH_IFNE, pc+1+sbx);
|
||||
builder.addBranch(pc, JavaBuilder.BRANCH_IFEQ, pc+1+sbx);
|
||||
break;
|
||||
|
||||
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
||||
|
||||
@@ -264,7 +264,7 @@ public class ProtoInfo {
|
||||
v[a+1][pc].isreferenced = true;
|
||||
v[a+3][pc] = new VarInfo(a+3,pc);
|
||||
break;
|
||||
|
||||
|
||||
case Lua.OP_LOADNIL: /* A B R(A) := ... := R(A+B) := nil */
|
||||
a = Lua.GETARG_A( ins );
|
||||
b = Lua.GETARG_B( ins );
|
||||
@@ -296,6 +296,24 @@ public class ProtoInfo {
|
||||
v[a][pc] = VarInfo.INVALID;
|
||||
break;
|
||||
|
||||
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
||||
a = Lua.GETARG_A( ins );
|
||||
c = Lua.GETARG_C( ins );
|
||||
v[a++][pc].isreferenced = true;
|
||||
v[a++][pc].isreferenced = true;
|
||||
v[a++][pc].isreferenced = true;
|
||||
for ( int j=0; j<c; j++, a++ )
|
||||
v[a][pc] = new VarInfo(a,pc);
|
||||
for ( ; a<m; a++ )
|
||||
v[a][pc] = VarInfo.INVALID;
|
||||
break;
|
||||
|
||||
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
|
||||
a = Lua.GETARG_A( ins );
|
||||
v[a+1][pc].isreferenced = true;
|
||||
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)) */
|
||||
a = Lua.GETARG_A( ins );
|
||||
b = Lua.GETARG_B( ins );
|
||||
@@ -311,20 +329,6 @@ public class ProtoInfo {
|
||||
v[a+i][pc].isreferenced = true;
|
||||
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_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++ */
|
||||
a = Lua.GETARG_A( ins );
|
||||
c = Lua.GETARG_C( ins );
|
||||
v[a++][pc].isreferenced = true;
|
||||
v[a++][pc].isreferenced = true;
|
||||
v[a++][pc].isreferenced = true;
|
||||
for ( int j=0; j<c; j++, a++ )
|
||||
v[a][pc] = new VarInfo(a,pc);
|
||||
for ( ; a<m; a++ )
|
||||
v[a][pc] = VarInfo.INVALID;
|
||||
break;
|
||||
|
||||
case Lua.OP_CLOSURE: { /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
||||
a = Lua.GETARG_A( ins );
|
||||
b = Lua.GETARG_Bx( ins );
|
||||
|
||||
Reference in New Issue
Block a user