Special processing on for loop upvalues.
This commit is contained in:
@@ -338,6 +338,23 @@ public class JavaBuilder {
|
|||||||
append(new ASTORE(index));
|
append(new ASTORE(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void createUpvalues(int pc, int firstslot, int numslots) {
|
||||||
|
for ( int i=0; i<numslots; i++ ) {
|
||||||
|
int slot = firstslot + i;
|
||||||
|
boolean isupcreate = slots.isUpvalueCreate(pc, slot);
|
||||||
|
if ( isupcreate ) {
|
||||||
|
int index = findSlotIndex( slot, true );
|
||||||
|
append(new PUSH(cp, 1));
|
||||||
|
append(new ANEWARRAY(cp.addClass(STR_LUAVALUE)));
|
||||||
|
dup();
|
||||||
|
append(new PUSH(cp, 0));
|
||||||
|
loadNil();
|
||||||
|
append(InstructionConstants.AASTORE);
|
||||||
|
append(new ASTORE(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String upvalueName(int upindex) {
|
private static String upvalueName(int upindex) {
|
||||||
return PREFIX_UPVALUE+upindex;
|
return PREFIX_UPVALUE+upindex;
|
||||||
|
|||||||
@@ -175,8 +175,14 @@ public class JavaGen {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_JMP: /* sBx pc+=sBx */
|
case Lua.OP_JMP: /* sBx pc+=sBx */
|
||||||
|
{
|
||||||
|
int pc1 = pc+1+sbx;
|
||||||
|
ins = p.code[pc1];
|
||||||
|
if ( Lua.GET_OPCODE(ins) == Lua.OP_TFORLOOP )
|
||||||
|
builder.createUpvalues(pc, Lua.GETARG_A(ins)+3, Lua.GETARG_C(ins));
|
||||||
builder.addBranch(pc, JavaBuilder.BRANCH_GOTO, pc+1+sbx);
|
builder.addBranch(pc, JavaBuilder.BRANCH_GOTO, pc+1+sbx);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||||
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||||
@@ -280,13 +286,15 @@ public class JavaGen {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||||
if ( c == 1 )
|
if ( c == 1 ) {
|
||||||
break;
|
builder.loadNone();
|
||||||
switch ( b ) {
|
} else {
|
||||||
case 0: loadVarargResults( builder, pc, a, vresultbase ); break;
|
switch ( b ) {
|
||||||
case 1: builder.loadNone(); break;
|
case 0: loadVarargResults( builder, pc, a, vresultbase ); break;
|
||||||
case 2: builder.loadLocal(pc, a); break;
|
case 1: builder.loadNone(); break;
|
||||||
default: builder.newVarargs(pc, a, b-1); break;
|
case 2: builder.loadLocal(pc, a); break;
|
||||||
|
default: builder.newVarargs(pc, a, b-1); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
builder.areturn();
|
builder.areturn();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ public class Slots {
|
|||||||
markassignments( p );
|
markassignments( p );
|
||||||
markuninitialized( p );
|
markuninitialized( p );
|
||||||
markupvalues( p );
|
markupvalues( p );
|
||||||
|
markforloopupvalues( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@@ -329,6 +330,43 @@ public class Slots {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void markforloopupvalues( Prototype p ) {
|
||||||
|
for ( int pc1=n; --pc1>=0; ) {
|
||||||
|
int i = p.code[pc1];
|
||||||
|
if ( Lua.GET_OPCODE(i) == Lua.OP_TFORLOOP ) {
|
||||||
|
int a = Lua.GETARG_A(i);
|
||||||
|
int c = Lua.GETARG_C(i);
|
||||||
|
for ( int pc0=pc1; --pc0>=0; ) {
|
||||||
|
i = p.code[pc0];
|
||||||
|
int o = Lua.GET_OPCODE(i);
|
||||||
|
int sbx = Lua.GETARG_sBx(i);
|
||||||
|
if ( o == Lua.OP_JMP && (pc0 + 1 + sbx == pc1) ) {
|
||||||
|
for ( int j=0; j<c; j++ ) {
|
||||||
|
checkPromoteLoopUpvalue( pc0, pc1, a+3+j );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPromoteLoopUpvalue(int pc0, int pc1, int slot) {
|
||||||
|
for ( int index=pc0+1; index<=pc1; ++index ) {
|
||||||
|
switch (slots[index][slot]) {
|
||||||
|
case UPVAL_CREATE:
|
||||||
|
case UPVAL_USE_CREATE:
|
||||||
|
case UPVAL_USE_ASSIGN:
|
||||||
|
case UPVAL_USE:
|
||||||
|
int i = pc0;
|
||||||
|
slots[++i][slot] = UPVAL_CREATE;
|
||||||
|
while ( ++i<=pc1 )
|
||||||
|
slots[i][slot] = UPVAL_USE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void promoteUpvalueBefore(byte[] s, int index, int j) {
|
private void promoteUpvalueBefore(byte[] s, int index, int j) {
|
||||||
int begin = prevUndefined(index,j);
|
int begin = prevUndefined(index,j);
|
||||||
int assign = firstAssignAfter(begin,index,j);
|
int assign = firstAssignAfter(begin,index,j);
|
||||||
|
|||||||
Reference in New Issue
Block a user