diff --git a/src/core/org/luaj/vm2/LoadState.java b/src/core/org/luaj/vm2/LoadState.java index 42aa41cc..6dc072db 100644 --- a/src/core/org/luaj/vm2/LoadState.java +++ b/src/core/org/luaj/vm2/LoadState.java @@ -325,10 +325,10 @@ public class LoadState { */ public Prototype loadFunction(LuaString p) throws IOException { Prototype f = new Prototype(); -// this.L.push(f); - f.source = loadString(); - if ( f.source == null ) - f.source = p; +//// this.L.push(f); +// f.source = loadString(); +// if ( f.source == null ) +// f.source = p; f.linedefined = loadInt(); f.lastlinedefined = loadInt(); f.numparams = is.readUnsignedByte(); @@ -347,6 +347,15 @@ public class LoadState { return f; } + static final byte[] LUAC_TAIL = { + (byte) 0x19, + (byte) 0x93, + (byte) '\r', + (byte) '\n', + (byte) 0x1a, + (byte) '\n', + }; + /** * Load the lua chunk header values. * @throws IOException if an i/o exception occurs. @@ -360,6 +369,9 @@ public class LoadState { luacSizeofInstruction = is.readByte(); luacSizeofLuaNumber = is.readByte(); luacNumberFormat = is.readByte(); + for (int i=0; i < LUAC_TAIL.length; ++i) + if (is.readByte() != LUAC_TAIL[i]) + throw new LuaError("Unexpeted byte in luac tail of header, index="+i); } /** diff --git a/src/core/org/luaj/vm2/LuaClosure.java b/src/core/org/luaj/vm2/LuaClosure.java index 3701be87..546ece89 100644 --- a/src/core/org/luaj/vm2/LuaClosure.java +++ b/src/core/org/luaj/vm2/LuaClosure.java @@ -314,6 +314,12 @@ public class LuaClosure extends LuaFunction { case Lua.OP_JMP: /* sBx pc+=sBx */ pc += (i>>>14)-0x1ffff; + if (a > 0) + for (int j = 0; j < openups.length; ++j) + if (openups[j] != null && openups[j].index == a) { + openups[j].close(); + openups[j] = null; + } continue; case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ @@ -465,18 +471,18 @@ public class LuaClosure extends LuaFunction { } continue; - case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ + case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */ { Prototype newp = p.p[i>>>14]; - LuaClosure newcl = new LuaClosure(newp, env); - for ( int j=0, nup=newp.upvalues.length; j>>23; - newcl.upValues[j] = (i&4) != 0? - upValues[b]: - openups[b]!=null? openups[b]: (openups[b]=new UpValue(stack,b)); + LuaClosure ncl = new LuaClosure(newp, env); + Upvaldesc[] uv = newp.upvalues; + for ( int j=0, nup=uv.length; j 0"); + final int n = openups.length; + for (int i = 0; i < n; ++i) + if (openups[i] != null && openups[i].index == idx) + return openups[i]; + for (int i = 0; i < n; ++i) + if (openups[i] == null) + return openups[idx] = new UpValue(stack, idx); + this.error("No space for upvalue"); + return null; + } + protected LuaValue getUpvalue(int i) { return upValues[i].getValue(); } diff --git a/src/core/org/luaj/vm2/Print.java b/src/core/org/luaj/vm2/Print.java index d13a9b68..38d074e9 100644 --- a/src/core/org/luaj/vm2/Print.java +++ b/src/core/org/luaj/vm2/Print.java @@ -38,12 +38,13 @@ public class Print extends Lua { public static final String[] OPNAMES = { "MOVE", "LOADK", + "LOADKX", "LOADBOOL", "LOADNIL", "GETUPVAL", - "GETGLOBAL", + "GETTABUP", "GETTABLE", - "SETGLOBAL", + "SETTABUP", "SETUPVAL", "SETTABLE", "NEWTABLE", @@ -69,11 +70,12 @@ public class Print extends Lua { "RETURN", "FORLOOP", "FORPREP", + "TFORCALL", "TFORLOOP", "SETLIST", - "CLOSE", "CLOSURE", "VARARG", + "EXTRAARG", null, }; @@ -215,15 +217,30 @@ public class Print extends Lua { case OP_GETUPVAL: case OP_SETUPVAL: ps.print(" ; "); - if ( f.upvalues.length > b ) - printUpvalue(ps, f.upvalues[b]); - else - ps.print( "-" ); + printUpvalue(ps, f.upvalues[b]); break; case OP_GETTABUP: + ps.print(" ; "); + printUpvalue(ps, f.upvalues[b]); + ps.print(" "); + if (ISK(c)) + printConstant(ps, f, INDEXK(c)); + else + ps.print("-"); + break; case OP_SETTABUP: ps.print(" ; "); - printConstant( ps, f, b ); + printUpvalue(ps, f.upvalues[a]); + ps.print(" "); + if (ISK(b)) + printConstant(ps, f, INDEXK(b)); + else + ps.print("-"); + ps.print(" "); + if (ISK(c)) + printConstant(ps, f, INDEXK(c)); + else + ps.print("-"); break; case OP_GETTABLE: case OP_SELF: diff --git a/src/core/org/luaj/vm2/Upvaldesc.java b/src/core/org/luaj/vm2/Upvaldesc.java index 839ac4c6..28326c6c 100644 --- a/src/core/org/luaj/vm2/Upvaldesc.java +++ b/src/core/org/luaj/vm2/Upvaldesc.java @@ -37,4 +37,8 @@ public class Upvaldesc { this.instack = instack; this.idx = (short) idx; } + + public String toString() { + return idx + (instack? " instack ": " closed ") + String.valueOf(name); + } } diff --git a/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java b/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java index 0d82a5b9..141562ea 100644 --- a/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java +++ b/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java @@ -67,7 +67,7 @@ abstract public class AbstractUnitTests extends TestCase { // compile in memory InputStream is = new ByteArrayInputStream(lua); - Prototype p = LuaC.instance.compile(is, "@" + dir + "/" + file); + Prototype p = LuaC.instance.compile(is, "@" + file); String actual = protoToString(p); // load expected value from jar