Improve upvalue processing in for loops for luajc compiler

This commit is contained in:
James Roseborough
2010-04-21 06:07:32 +00:00
parent 68b260efdd
commit 9b6c9e1326
4 changed files with 32 additions and 24 deletions

View File

@@ -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) };
}
}

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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;
}