Special processing on for loop upvalues.
This commit is contained in:
@@ -339,6 +339,23 @@ public class JavaBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return PREFIX_UPVALUE+upindex;
|
||||
}
|
||||
|
||||
@@ -175,8 +175,14 @@ public class JavaGen {
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
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++ */
|
||||
@@ -280,13 +286,15 @@ public class JavaGen {
|
||||
break;
|
||||
|
||||
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
||||
if ( c == 1 )
|
||||
break;
|
||||
switch ( b ) {
|
||||
case 0: loadVarargResults( builder, pc, a, vresultbase ); break;
|
||||
case 1: builder.loadNone(); break;
|
||||
case 2: builder.loadLocal(pc, a); break;
|
||||
default: builder.newVarargs(pc, a, b-1); break;
|
||||
if ( c == 1 ) {
|
||||
builder.loadNone();
|
||||
} else {
|
||||
switch ( b ) {
|
||||
case 0: loadVarargResults( builder, pc, a, vresultbase ); break;
|
||||
case 1: builder.loadNone(); break;
|
||||
case 2: builder.loadLocal(pc, a); break;
|
||||
default: builder.newVarargs(pc, a, b-1); break;
|
||||
}
|
||||
}
|
||||
builder.areturn();
|
||||
break;
|
||||
|
||||
@@ -90,6 +90,7 @@ public class Slots {
|
||||
markassignments( p );
|
||||
markuninitialized( p );
|
||||
markupvalues( p );
|
||||
markforloopupvalues( p );
|
||||
}
|
||||
|
||||
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) {
|
||||
int begin = prevUndefined(index,j);
|
||||
int assign = firstAssignAfter(begin,index,j);
|
||||
|
||||
Reference in New Issue
Block a user