diff --git a/src/core/org/luaj/vm2/Lua.java b/src/core/org/luaj/vm2/Lua.java index 57f3b40c..0666c332 100644 --- a/src/core/org/luaj/vm2/Lua.java +++ b/src/core/org/luaj/vm2/Lua.java @@ -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)) */ diff --git a/src/core/org/luaj/vm2/LuaClosure.java b/src/core/org/luaj/vm2/LuaClosure.java index 24f9879b..1b059150 100644 --- a/src/core/org/luaj/vm2/LuaClosure.java +++ b/src/core/org/luaj/vm2/LuaClosure.java @@ -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; diff --git a/src/core/org/luaj/vm2/lib/DebugLib.java b/src/core/org/luaj/vm2/lib/DebugLib.java index 80508d74..96f33055 100644 --- a/src/core/org/luaj/vm2/lib/DebugLib.java +++ b/src/core/org/luaj/vm2/lib/DebugLib.java @@ -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; } } diff --git a/src/jse/org/luaj/vm2/luajc/BasicBlock.java b/src/jse/org/luaj/vm2/luajc/BasicBlock.java index 130f7947..dea9f933 100644 --- a/src/jse/org/luaj/vm2/luajc/BasicBlock.java +++ b/src/jse/org/luaj/vm2/luajc/BasicBlock.java @@ -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; diff --git a/src/jse/org/luaj/vm2/luajc/JavaGen.java b/src/jse/org/luaj/vm2/luajc/JavaGen.java index b9c757a9..27ca98e8 100644 --- a/src/jse/org/luaj/vm2/luajc/JavaGen.java +++ b/src/jse/org/luaj/vm2/luajc/JavaGen.java @@ -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 */ diff --git a/src/jse/org/luaj/vm2/luajc/ProtoInfo.java b/src/jse/org/luaj/vm2/luajc/ProtoInfo.java index b09fb281..5bfa9dad 100644 --- a/src/jse/org/luaj/vm2/luajc/ProtoInfo.java +++ b/src/jse/org/luaj/vm2/luajc/ProtoInfo.java @@ -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; j0 && 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(); } diff --git a/test/junit/org/luaj/vm2/FragmentsTest.java b/test/junit/org/luaj/vm2/FragmentsTest.java index be949653..73881928 100644 --- a/test/junit/org/luaj/vm2/FragmentsTest.java +++ b/test/junit/org/luaj/vm2/FragmentsTest.java @@ -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), diff --git a/test/lua/debuglib.lua b/test/lua/debuglib.lua index 57ac8cda..c8463245 100644 --- a/test/lua/debuglib.lua +++ b/test/lua/debuglib.lua @@ -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