Fix for loop processing in luajc compiler code generator for lua 5.3 bytecodes

This commit is contained in:
James Roseborough
2012-09-18 14:17:00 +00:00
parent ef94aa3abb
commit 4bf132c01e
9 changed files with 89 additions and 43 deletions

View File

@@ -225,8 +225,7 @@ public class Lua {
public static final int OP_FORPREP = 33; /* A sBx R(A)-=R(A+2); pc+=sBx */
public static final int OP_TFORCALL = 34; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
public static final int OP_TFORLOOP = 35; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
public static final int OP_TFORLOOP = 35; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
public static final int OP_SETLIST = 36; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
public static final int OP_CLOSURE = 37; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */

View File

@@ -434,9 +434,10 @@ public class LuaClosure extends LuaFunction {
c = (i>>14) & 0x1ff;
while (--c >= 0)
stack[a+3+c] = v.arg(c+1);
v = NONE;
continue;
case Lua.OP_TFORLOOP: /* A sBx if R(A) != nil then ps+= sBx */
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
if (!stack[a+1].isnil()) { /* continue loop? */
stack[a] = stack[a+1]; /* save control varible. */
pc += (i>>>14)-0x1ffff;

View File

@@ -395,11 +395,15 @@ public class DebugLib extends OneArgFunction {
// debug.upvaluejoin (f1, n1, f2, n2)
final class upvaluejoin extends VarArgFunction {
public Varargs invoke(Varargs args) {
LuaValue f1 = args.checkfunction(1);
LuaClosure f1 = args.checkclosure(1);
int n1 = args.checkint(2);
LuaValue f2 = args.checkfunction(3);
LuaClosure f2 = args.checkclosure(3);
int n2 = args.checkint(4);
f1.checkclosure().upValues[n1] = f2.checkclosure().upValues[n2];
if (n1 < 1 || n1 > f1.upValues.length)
argerror("index out of range");
if (n2 < 1 || n2 > f2.upValues.length)
argerror("index out of range");
f1.upValues[n1-1] = f2.upValues[n2-1];
return NONE;
}
}

View File

@@ -120,7 +120,6 @@ public class BasicBlock {
case Lua.OP_LE:
case Lua.OP_TEST:
case Lua.OP_TESTSET:
case Lua.OP_TFORLOOP:
if ( Lua.GET_OPCODE(code[i+1]) != Lua.OP_JMP )
throw new IllegalArgumentException("test not followed by jump at "+i);
sbx = Lua.GETARG_sBx(code[i+1]);
@@ -129,6 +128,7 @@ public class BasicBlock {
visitor.visitBranch( i, j );
visitor.visitBranch( i, i+1 );
continue;
case Lua.OP_TFORLOOP:
case Lua.OP_FORLOOP:
sbx = Lua.GETARG_sBx(ins);
j = i + sbx + 1;

View File

@@ -361,10 +361,12 @@ public class JavaGen {
}
break;
case Lua.OP_TFORLOOP:/* A sBx if R(A) != nil then ps+= sBx */
builder.loadLocal(pc, a);
case Lua.OP_TFORLOOP:/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
builder.loadLocal(pc, a+1);
builder.dup();
builder.storeLocal(pc, a);
builder.isNil();
builder.addBranch(pc, JavaBuilder.BRANCH_IFNE, pc+1+sbx);
builder.addBranch(pc, JavaBuilder.BRANCH_IFEQ, pc+1+sbx);
break;
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */

View File

@@ -264,7 +264,7 @@ public class ProtoInfo {
v[a+1][pc].isreferenced = true;
v[a+3][pc] = new VarInfo(a+3,pc);
break;
case Lua.OP_LOADNIL: /* A B R(A) := ... := R(A+B) := nil */
a = Lua.GETARG_A( ins );
b = Lua.GETARG_B( ins );
@@ -296,6 +296,24 @@ public class ProtoInfo {
v[a][pc] = VarInfo.INVALID;
break;
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
a = Lua.GETARG_A( ins );
c = Lua.GETARG_C( ins );
v[a++][pc].isreferenced = true;
v[a++][pc].isreferenced = true;
v[a++][pc].isreferenced = true;
for ( int j=0; j<c; j++, a++ )
v[a][pc] = new VarInfo(a,pc);
for ( ; a<m; a++ )
v[a][pc] = VarInfo.INVALID;
break;
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
a = Lua.GETARG_A( ins );
v[a+1][pc].isreferenced = true;
v[a][pc] = new VarInfo(a,pc);
break;
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
a = Lua.GETARG_A( ins );
b = Lua.GETARG_B( ins );
@@ -311,20 +329,6 @@ public class ProtoInfo {
v[a+i][pc].isreferenced = true;
break;
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
case Lua.OP_TFORLOOP: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
a = Lua.GETARG_A( ins );
c = Lua.GETARG_C( ins );
v[a++][pc].isreferenced = true;
v[a++][pc].isreferenced = true;
v[a++][pc].isreferenced = true;
for ( int j=0; j<c; j++, a++ )
v[a][pc] = new VarInfo(a,pc);
for ( ; a<m; a++ )
v[a][pc] = VarInfo.INVALID;
break;
case Lua.OP_CLOSURE: { /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
a = Lua.GETARG_A( ins );
b = Lua.GETARG_Bx( ins );

View File

@@ -29,7 +29,10 @@ import java.util.Hashtable;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.luajc.LuaJC;
@@ -37,8 +40,9 @@ public class TestLuaJC {
// create the script
public static String name = "script";
public static String script =
"_ENV={}; return _ENV\n"+
"";
"for n,p in ipairs({77}) do\n"+
" print('n,p',n,p)\n"+
"end\n";
public static void main(String[] args) throws Exception {
System.out.println(script);
@@ -48,12 +52,16 @@ public class TestLuaJC {
LuaTable _G = JsePlatform.standardGlobals();
System.out.println("_G: "+_G);
System.out.println("_G.print: "+_G.get("print"));
// compile into a chunk, or load as a class
LuaValue chunk;
// print the chunk as a closure
byte[] bytes = script.getBytes();
LuaValue chunk = LuaC.instance.load(new ByteArrayInputStream(bytes), "script", _G);
Prototype p = chunk.checkclosure().p;
Print.print(p);
// compile into a luajc chunk, or load as a class
if ( ! (args.length>0 && args[0].equals("nocompile")) ) {
InputStream is = new ByteArrayInputStream( script.getBytes() );
chunk = LuaJC.getInstance().load(is, "script", _G);
chunk = LuaJC.getInstance().load(new ByteArrayInputStream(bytes), "script", _G);
} else {
chunk = (LuaValue) Class.forName("script").newInstance();
}

View File

@@ -94,6 +94,15 @@ public class FragmentsTest extends TestSuite {
"return b" );
}
public void testSimpleForloop() {
runFragment( LuaValue.valueOf(77),
"for n,p in ipairs({77}) do\n"+
" print('n,p',n,p)\n"+
" return p\n"+
"end\n");
}
public void testForloopParamUpvalues() {
runFragment( LuaValue.varargsOf(new LuaValue[] {
LuaValue.valueOf(77),

View File

@@ -216,22 +216,41 @@ tryhooks("r")
tryhooks("l")
tryhooks("crl")
print( '----- debug.getupvalueid' )
local x=1, y=2
function a()
print( '----- debug.upvalueid' )
local x,y = 100,200
function a(b,c)
local z,w = b,c
return function()
return x,y
x,y,z,w = x+1,y+1,z+1,w+1
return x,y,z,w
end
end
a1 = a()
a2 = a()
a1 = a(300,400)
a2 = a(500,600)
print('debug.getupvalue(a1,1)', debug.getupvalue(a1,1))
print('debug.getupvalue(a1,2)', debug.getupvalue(a1,2))
print('debug.getupvalue(a2,1)', debug.getupvalue(a2,1))
print('debug.getupvalue(a2,2)', debug.getupvalue(a2,2))
print('debug.getupvalueid(a1,1) == debug.getupvalueid(a1,1)', debug.getupvalueid(a1,1) == debug.getupvalueid(a1,1))
print('debug.getupvalueid(a1,1) == debug.getupvalueid(a2,1)', debug.getupvalueid(a1,1) == debug.getupvalueid(a2,1))
print('debug.getupvalueid(a1,2) == debug.getupvalueid(a1,2)', debug.getupvalueid(a1,2) == debug.getupvalueid(a1,2))
print('debug.getupvalueid(a1,2) == debug.getupvalueid(a2,2)', debug.getupvalueid(a1,2) == debug.getupvalueid(a2,2))
print('debug.upvalueid(a1,1) == debug.upvalueid(a1,1)', debug.upvalueid(a1,1) == debug.upvalueid(a1,1))
print('debug.upvalueid(a1,1) == debug.upvalueid(a2,1)', debug.upvalueid(a1,1) == debug.upvalueid(a2,1))
print('debug.upvalueid(a1,1) == debug.upvalueid(a1,2)', debug.upvalueid(a1,1) == debug.upvalueid(a1,2))
v
print( '----- debug.upvaluejoin' )
print('a1',a1())
print('a2',a2())
print('debug.upvaluejoin(a1,1,a2,2)', debug.upvaluejoin(a1,1,a2,2))
print('debug.upvaluejoin(a1,3,a2,4)', debug.upvaluejoin(a1,3,a2,4))
print('a1',a1())
print('a2',a2())
print('a1',a1())
print('a2',a2())
for i = 1,4 do
print('debug.getupvalue(a1,'..i..')', debug.getupvalue(a1,i))
print('debug.getupvalue(a2,'..i..')', debug.getupvalue(a2,i))
for j = 1,4 do
print('debug.upvalueid(a1,'..i..') == debug.upvalueid(a1,'..j..')', debug.upvalueid(a1,i) == debug.upvalueid(a1,j))
print('debug.upvalueid(a1,'..i..') == debug.upvalueid(a2,'..j..')', debug.upvalueid(a1,i) == debug.upvalueid(a2,j))
print('debug.upvalueid(a2,'..i..') == debug.upvalueid(a1,'..j..')', debug.upvalueid(a2,i) == debug.upvalueid(a1,j))
print('debug.upvalueid(a2,'..i..') == debug.upvalueid(a2,'..j..')', debug.upvalueid(a2,i) == debug.upvalueid(a2,j))
end
end