Improve upvalue processing in for loops for luajc compiler
This commit is contained in:
@@ -282,4 +282,16 @@ abstract public class LibFunction extends LuaFunction {
|
||||
return delegate.oncallv(opcode,varargs);
|
||||
}
|
||||
}
|
||||
|
||||
// -------- code generation helper functions --------
|
||||
|
||||
// allocate storage for upvalue, leave it empty
|
||||
protected static LuaValue[] newupe() {
|
||||
return new LuaValue[1];
|
||||
}
|
||||
|
||||
// allocate storage for upvalue, initialize with nil
|
||||
protected static LuaValue[] newupn() {
|
||||
return new LuaValue[] { valueOf(777) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,8 @@ public class JavaBuilder {
|
||||
|
||||
private static final ArrayType TYPE_LOCALUPVALUE = new ArrayType( TYPE_LUAVALUE, 1 );
|
||||
private static final ArrayType TYPE_CHARARRAY = new ArrayType( Type.CHAR, 1 );
|
||||
|
||||
private static final Type[] ARGS_NONE = new Type[0];
|
||||
|
||||
private static final Class[] NO_INNER_CLASSES = {};
|
||||
|
||||
@@ -242,7 +244,7 @@ public class JavaBuilder {
|
||||
// add class initializer
|
||||
if ( ! init.isEmpty() ) {
|
||||
MethodGen mg = new MethodGen(Constants.ACC_STATIC, Type.VOID,
|
||||
new Type[] {}, new String[] {}, "<clinit>", cg
|
||||
ARGS_NONE, new String[] {}, "<clinit>", cg
|
||||
.getClassName(), init, cg.getConstantPool());
|
||||
init.append(InstructionConstants.RETURN);
|
||||
mg.setMaxStack();
|
||||
@@ -318,13 +320,12 @@ public class JavaBuilder {
|
||||
}
|
||||
|
||||
public void storeLocal(int pc, int slot) {
|
||||
boolean isupval = slots.isUpvalueAssign(pc, slot);
|
||||
boolean isupval = slots.isUpvalue(pc, slot);
|
||||
int index = findSlotIndex( slot, isupval );
|
||||
if (isupval) {
|
||||
boolean isupcreate = slots.isUpvalueCreate(pc, slot);
|
||||
if ( isupcreate ) {
|
||||
append(new PUSH(cp, 1));
|
||||
append(new ANEWARRAY(cp.addClass(STR_LUAVALUE)));
|
||||
append(factory.createInvoke(classname, "newupe", TYPE_LOCALUPVALUE, ARGS_NONE, Constants.INVOKESTATIC));
|
||||
append(InstructionConstants.DUP);
|
||||
append(new ASTORE(index));
|
||||
} else {
|
||||
@@ -345,12 +346,7 @@ public class JavaBuilder {
|
||||
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(factory.createInvoke(classname, "newupn", TYPE_LOCALUPVALUE, ARGS_NONE, Constants.INVOKESTATIC));
|
||||
append(new ASTORE(index));
|
||||
}
|
||||
}
|
||||
@@ -397,7 +393,7 @@ public class JavaBuilder {
|
||||
|
||||
public void arg(int argindex) {
|
||||
if ( argindex == 1 ) {
|
||||
append(factory.createInvoke(STR_VARARGS, "arg1", TYPE_LUAVALUE, new Type[] {}, Constants.INVOKEVIRTUAL));
|
||||
append(factory.createInvoke(STR_VARARGS, "arg1", TYPE_LUAVALUE, ARGS_NONE, Constants.INVOKEVIRTUAL));
|
||||
} else {
|
||||
append(new PUSH(cp, argindex));
|
||||
append(factory.createInvoke(STR_VARARGS, "arg", TYPE_LUAVALUE, new Type[] { Type.INT }, Constants.INVOKEVIRTUAL));
|
||||
@@ -525,7 +521,7 @@ public class JavaBuilder {
|
||||
|
||||
public void call(int nargs) {
|
||||
switch ( nargs ) {
|
||||
case 0: append(factory.createInvoke(STR_LUAVALUE, "call", TYPE_LUAVALUE, new Type[] {}, Constants.INVOKEVIRTUAL)); break;
|
||||
case 0: append(factory.createInvoke(STR_LUAVALUE, "call", TYPE_LUAVALUE, ARGS_NONE, Constants.INVOKEVIRTUAL)); break;
|
||||
case 1: append(factory.createInvoke(STR_LUAVALUE, "call", TYPE_LUAVALUE, new Type[] { TYPE_LUAVALUE }, Constants.INVOKEVIRTUAL)); break;
|
||||
case 2: append(factory.createInvoke(STR_LUAVALUE, "call", TYPE_LUAVALUE, new Type[] { TYPE_LUAVALUE, TYPE_LUAVALUE }, Constants.INVOKEVIRTUAL)); break;
|
||||
case 3: append(factory.createInvoke(STR_LUAVALUE, "call", TYPE_LUAVALUE, new Type[] { TYPE_LUAVALUE, TYPE_LUAVALUE, TYPE_LUAVALUE }, Constants.INVOKEVIRTUAL)); break;
|
||||
@@ -540,7 +536,7 @@ public class JavaBuilder {
|
||||
public void invoke(int nargs) {
|
||||
switch ( nargs ) {
|
||||
case -1: append(factory.createInvoke(STR_LUAVALUE, "invoke", TYPE_VARARGS, new Type[] { TYPE_VARARGS }, Constants.INVOKEVIRTUAL)); break;
|
||||
case 0: append(factory.createInvoke(STR_LUAVALUE, "invoke", TYPE_VARARGS, new Type[] {}, Constants.INVOKEVIRTUAL)); break;
|
||||
case 0: append(factory.createInvoke(STR_LUAVALUE, "invoke", TYPE_VARARGS, ARGS_NONE, Constants.INVOKEVIRTUAL)); break;
|
||||
case 1: append(factory.createInvoke(STR_LUAVALUE, "invoke", TYPE_VARARGS, new Type[] { TYPE_VARARGS }, Constants.INVOKEVIRTUAL)); break;
|
||||
case 2: append(factory.createInvoke(STR_LUAVALUE, "invoke", TYPE_VARARGS, new Type[] { TYPE_LUAVALUE, TYPE_VARARGS }, Constants.INVOKEVIRTUAL)); break;
|
||||
case 3: append(factory.createInvoke(STR_LUAVALUE, "invoke", TYPE_VARARGS, new Type[] { TYPE_LUAVALUE, TYPE_LUAVALUE, TYPE_VARARGS }, Constants.INVOKEVIRTUAL)); break;
|
||||
|
||||
@@ -180,7 +180,7 @@ public class JavaGen {
|
||||
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, pc1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -329,14 +329,13 @@ public class JavaGen {
|
||||
builder.loadLocal(pc, a);
|
||||
builder.loadLocal(pc, a+1);
|
||||
builder.loadLocal(pc, a+2);
|
||||
builder.invoke(2);
|
||||
builder.invoke(2); // varresult on stack
|
||||
for ( int i=0; i<c; i++ ) {
|
||||
if ( i+1 < c )
|
||||
builder.dup();
|
||||
builder.arg( i+1 );
|
||||
builder.storeLocal(pc, a+3+i);
|
||||
}
|
||||
|
||||
builder.loadLocal(pc, a+3);
|
||||
builder.isNil();
|
||||
builder.addBranch(pc, JavaBuilder.BRANCH_IFNE, pc+2);
|
||||
@@ -376,7 +375,7 @@ public class JavaGen {
|
||||
for ( int up=0; up<nup; ++up ) {
|
||||
if ( up+1 < nup )
|
||||
builder.dup();
|
||||
ins = p.code[++pc];
|
||||
ins = p.code[pc+up+1];
|
||||
b = Lua.GETARG_B(ins);
|
||||
if ( (ins&4) != 0 ) {
|
||||
builder.closureInitUpvalueFromUpvalue( protoname, up, b );
|
||||
|
||||
@@ -59,8 +59,9 @@ public class Slots {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUpvalueAssign(int pc, int slot) {
|
||||
public boolean isUpvalue(int pc, int slot) {
|
||||
switch (slots[pc+1][slot]) {
|
||||
case UPVAL_USE:
|
||||
case UPVAL_CREATE:
|
||||
case UPVAL_USE_CREATE:
|
||||
case UPVAL_USE_ASSIGN:
|
||||
@@ -342,7 +343,7 @@ public class Slots {
|
||||
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 );
|
||||
checkPromoteLoopUpvalue( pc0+1, pc1+1, a+3+j );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,16 +352,16 @@ public class Slots {
|
||||
|
||||
}
|
||||
|
||||
private void checkPromoteLoopUpvalue(int pc0, int pc1, int slot) {
|
||||
for ( int index=pc0+1; index<=pc1; ++index ) {
|
||||
private void checkPromoteLoopUpvalue(int index0, int index1, int slot) {
|
||||
for ( int index=index0; index<=index1; ++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 )
|
||||
int i = index0;
|
||||
slots[i][slot] = UPVAL_CREATE;
|
||||
while ( ++i<=index1 )
|
||||
slots[i][slot] = UPVAL_USE;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user