Improve bytecode generation.

This commit is contained in:
James Roseborough
2010-08-10 14:55:32 +00:00
parent afa2d5fd09
commit 6b379f9fe8
4 changed files with 47 additions and 19 deletions

View File

@@ -197,7 +197,9 @@ public class JavaBuilder {
// create the fields // create the fields
for ( int i=0; i<p.nups; i++ ) { for ( int i=0; i<p.nups; i++ ) {
FieldGen fg = new FieldGen(0, TYPE_LOCALUPVALUE, upvalueName(i), cp); boolean isrw = pi.isReadWriteUpvalue( pi.upvals[i] );
Type uptype = isrw? TYPE_LOCALUPVALUE: TYPE_LUAVALUE;
FieldGen fg = new FieldGen(0, uptype, upvalueName(i), cp);
cg.addField(fg.getField()); cg.addField(fg.getField());
} }
@@ -395,18 +397,29 @@ public class JavaBuilder {
} }
public void loadUpvalue(int upindex) { public void loadUpvalue(int upindex) {
boolean isrw = pi.isReadWriteUpvalue( pi.upvals[upindex] );
append(InstructionConstants.THIS); append(InstructionConstants.THIS);
append(factory.createFieldAccess(classname, upvalueName(upindex), TYPE_LOCALUPVALUE, Constants.GETFIELD)); if ( isrw ) {
append(new PUSH(cp,0)); append(factory.createFieldAccess(classname, upvalueName(upindex), TYPE_LOCALUPVALUE, Constants.GETFIELD));
append(InstructionConstants.AALOAD); append(new PUSH(cp,0));
append(InstructionConstants.AALOAD);
} else {
append(factory.createFieldAccess(classname, upvalueName(upindex), TYPE_LUAVALUE, Constants.GETFIELD));
}
} }
public void storeUpvalue(int pc, int upindex, int slot) { public void storeUpvalue(int pc, int upindex, int slot) {
boolean isrw = pi.isReadWriteUpvalue( pi.upvals[upindex] );
append(InstructionConstants.THIS); append(InstructionConstants.THIS);
append(factory.createFieldAccess(classname, upvalueName(upindex), TYPE_LOCALUPVALUE, Constants.GETFIELD)); if ( isrw ) {
append(new PUSH(cp,0)); append(factory.createFieldAccess(classname, upvalueName(upindex), TYPE_LOCALUPVALUE, Constants.GETFIELD));
loadLocal(pc, slot); append(new PUSH(cp,0));
append(InstructionConstants.AASTORE); loadLocal(pc, slot);
append(InstructionConstants.AASTORE);
} else {
loadLocal(pc, slot);
append(factory.createFieldAccess(classname, upvalueName(upindex), TYPE_LUAVALUE, Constants.PUTFIELD));
}
} }
@@ -596,18 +609,22 @@ public class JavaBuilder {
} }
public void closureInitUpvalueFromUpvalue(String protoname, int newup, int upindex) { public void closureInitUpvalueFromUpvalue(String protoname, int newup, int upindex) {
boolean isrw = pi.isReadWriteUpvalue( pi.upvals[upindex] );
Type uptype = isrw? TYPE_LOCALUPVALUE: TYPE_LUAVALUE;
String srcname = upvalueName(upindex); String srcname = upvalueName(upindex);
String destname = upvalueName(newup); String destname = upvalueName(newup);
append(InstructionConstants.THIS); append(InstructionConstants.THIS);
append(factory.createFieldAccess(classname, srcname, TYPE_LOCALUPVALUE, Constants.GETFIELD)); append(factory.createFieldAccess(classname, srcname, uptype, Constants.GETFIELD));
append(factory.createFieldAccess(protoname, destname, TYPE_LOCALUPVALUE, Constants.PUTFIELD)); append(factory.createFieldAccess(protoname, destname, uptype, Constants.PUTFIELD));
} }
public void closureInitUpvalueFromLocal(String protoname, int newup, int pc, int srcslot) { public void closureInitUpvalueFromLocal(String protoname, int newup, int pc, int srcslot) {
boolean isrw = pi.isReadWriteUpvalue( pi.vars[srcslot][pc].upvalue );
Type uptype = isrw? TYPE_LOCALUPVALUE: TYPE_LUAVALUE;
String destname = upvalueName(newup); String destname = upvalueName(newup);
int index = findSlotIndex( srcslot, true ); int index = findSlotIndex( srcslot, isrw );
append(new ALOAD(index)); append(new ALOAD(index));
append(factory.createFieldAccess(protoname, destname, TYPE_LOCALUPVALUE, Constants.PUTFIELD)); append(factory.createFieldAccess(protoname, destname, uptype, Constants.PUTFIELD));
} }
private Map<LuaValue,String> constants = new HashMap<LuaValue,String>(); private Map<LuaValue,String> constants = new HashMap<LuaValue,String>();

View File

@@ -317,7 +317,6 @@ public class JavaGen {
builder.dup(); builder.dup();
builder.dup(); builder.dup();
builder.storeLocal(pc, a); builder.storeLocal(pc, a);
// builder.createUpvalues(pc, a+3, 1);
builder.storeLocal(pc, a+3); builder.storeLocal(pc, a+3);
builder.loadLocal(pc, a+1); // limit builder.loadLocal(pc, a+1); // limit
builder.loadLocal(pc, a+2); // step builder.loadLocal(pc, a+2); // step

View File

@@ -434,14 +434,12 @@ public class ProtoInfo {
public boolean isUpvalueAssign(int pc, int slot) { public boolean isUpvalueAssign(int pc, int slot) {
VarInfo v = pc<0? params[slot]: vars[slot][pc]; VarInfo v = pc<0? params[slot]: vars[slot][pc];
// return v.upvalue != null && v.upvalue.rw; return v != null && v.upvalue != null && v.upvalue.rw;
return v != null && v.upvalue != null;
} }
public boolean isUpvalueCreate(int pc, int slot) { public boolean isUpvalueCreate(int pc, int slot) {
VarInfo v = pc<0? params[slot]: vars[slot][pc]; VarInfo v = pc<0? params[slot]: vars[slot][pc];
// return v.upvalue != null && v.upvalue.rw && v.allocupvalue && pc == v.pc; return v != null && v.upvalue != null && v.upvalue.rw && v.allocupvalue && pc == v.pc;
return v != null && v.upvalue != null && v.allocupvalue && pc == v.pc;
} }
public boolean isUpvalueRefer(int pc, int slot) { public boolean isUpvalueRefer(int pc, int slot) {
@@ -449,12 +447,15 @@ public class ProtoInfo {
if ( pc >= 0 && vars[slot][pc] != null && vars[slot][pc].pc == pc ) if ( pc >= 0 && vars[slot][pc] != null && vars[slot][pc].pc == pc )
pc -= 1; pc -= 1;
VarInfo v = pc<0? params[slot]: vars[slot][pc]; VarInfo v = pc<0? params[slot]: vars[slot][pc];
// return v.upvalue != null && v.upvalue.rw; return v != null && v.upvalue != null && v.upvalue.rw;
return v != null && v.upvalue != null;
} }
public boolean isInitialValueUsed(int slot) { public boolean isInitialValueUsed(int slot) {
VarInfo v = params[slot]; VarInfo v = params[slot];
return v.isreferenced; return v.isreferenced;
} }
public boolean isReadWriteUpvalue(UpvalInfo u) {
return u.rw;
}
} }

View File

@@ -442,5 +442,16 @@ public class FragmentsTest extends TestSuite {
"end\n" + "end\n" +
"return bar()[1]"); "return bar()[1]");
} }
public void testReadOnlyAndReadWriteUpvalues() {
runFragment( LuaValue.varargsOf( new LuaValue[] { LuaValue.valueOf(333), LuaValue.valueOf(222) } ),
"local a = 111\n" +
"local b = 222\n" +
"local c = function()\n"+
" a = a + b\n" +
" return a,b\n"+
"end\n" +
"return c()\n" );
}
} }
} }