Lua 5.2 compatibility fixes.

This commit is contained in:
James Roseborough
2012-09-03 21:59:51 +00:00
parent b90998c6d4
commit 1831fbc96f
5 changed files with 75 additions and 22 deletions

View File

@@ -325,10 +325,10 @@ public class LoadState {
*/ */
public Prototype loadFunction(LuaString p) throws IOException { public Prototype loadFunction(LuaString p) throws IOException {
Prototype f = new Prototype(); Prototype f = new Prototype();
// this.L.push(f); //// this.L.push(f);
f.source = loadString(); // f.source = loadString();
if ( f.source == null ) // if ( f.source == null )
f.source = p; // f.source = p;
f.linedefined = loadInt(); f.linedefined = loadInt();
f.lastlinedefined = loadInt(); f.lastlinedefined = loadInt();
f.numparams = is.readUnsignedByte(); f.numparams = is.readUnsignedByte();
@@ -347,6 +347,15 @@ public class LoadState {
return f; 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. * Load the lua chunk header values.
* @throws IOException if an i/o exception occurs. * @throws IOException if an i/o exception occurs.
@@ -360,6 +369,9 @@ public class LoadState {
luacSizeofInstruction = is.readByte(); luacSizeofInstruction = is.readByte();
luacSizeofLuaNumber = is.readByte(); luacSizeofLuaNumber = is.readByte();
luacNumberFormat = 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);
} }
/** /**

View File

@@ -314,6 +314,12 @@ public class LuaClosure extends LuaFunction {
case Lua.OP_JMP: /* sBx pc+=sBx */ case Lua.OP_JMP: /* sBx pc+=sBx */
pc += (i>>>14)-0x1ffff; 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; continue;
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ 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; 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]; Prototype newp = p.p[i>>>14];
LuaClosure newcl = new LuaClosure(newp, env); LuaClosure ncl = new LuaClosure(newp, env);
for ( int j=0, nup=newp.upvalues.length; j<nup; ++j ) { Upvaldesc[] uv = newp.upvalues;
i = code[pc++]; for ( int j=0, nup=uv.length; j<nup; ++j ) {
b = i>>>23; if (uv[j].instack) /* upvalue refes to local variable? */
newcl.upValues[j] = (i&4) != 0? ncl.upValues[j] = findupval(stack, uv[j].idx, openups);
upValues[b]: else /* get upvalue from enclosing function */
openups[b]!=null? openups[b]: (openups[b]=new UpValue(stack,b)); ncl.upValues[j] = upValues[uv[j].idx];
} }
stack[a] = newcl; stack[a] = ncl;
} }
continue; continue;
@@ -511,6 +517,20 @@ public class LuaClosure extends LuaFunction {
} }
} }
private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) {
if (idx <= 0)
error("Upvalue index must be > 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) { protected LuaValue getUpvalue(int i) {
return upValues[i].getValue(); return upValues[i].getValue();
} }

View File

@@ -38,12 +38,13 @@ public class Print extends Lua {
public static final String[] OPNAMES = { public static final String[] OPNAMES = {
"MOVE", "MOVE",
"LOADK", "LOADK",
"LOADKX",
"LOADBOOL", "LOADBOOL",
"LOADNIL", "LOADNIL",
"GETUPVAL", "GETUPVAL",
"GETGLOBAL", "GETTABUP",
"GETTABLE", "GETTABLE",
"SETGLOBAL", "SETTABUP",
"SETUPVAL", "SETUPVAL",
"SETTABLE", "SETTABLE",
"NEWTABLE", "NEWTABLE",
@@ -69,11 +70,12 @@ public class Print extends Lua {
"RETURN", "RETURN",
"FORLOOP", "FORLOOP",
"FORPREP", "FORPREP",
"TFORCALL",
"TFORLOOP", "TFORLOOP",
"SETLIST", "SETLIST",
"CLOSE",
"CLOSURE", "CLOSURE",
"VARARG", "VARARG",
"EXTRAARG",
null, null,
}; };
@@ -215,15 +217,30 @@ public class Print extends Lua {
case OP_GETUPVAL: case OP_GETUPVAL:
case OP_SETUPVAL: case OP_SETUPVAL:
ps.print(" ; "); ps.print(" ; ");
if ( f.upvalues.length > b ) printUpvalue(ps, f.upvalues[b]);
printUpvalue(ps, f.upvalues[b]);
else
ps.print( "-" );
break; break;
case OP_GETTABUP: 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: case OP_SETTABUP:
ps.print(" ; "); 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; break;
case OP_GETTABLE: case OP_GETTABLE:
case OP_SELF: case OP_SELF:

View File

@@ -37,4 +37,8 @@ public class Upvaldesc {
this.instack = instack; this.instack = instack;
this.idx = (short) idx; this.idx = (short) idx;
} }
public String toString() {
return idx + (instack? " instack ": " closed ") + String.valueOf(name);
}
} }

View File

@@ -67,7 +67,7 @@ abstract public class AbstractUnitTests extends TestCase {
// compile in memory // compile in memory
InputStream is = new ByteArrayInputStream(lua); InputStream is = new ByteArrayInputStream(lua);
Prototype p = LuaC.instance.compile(is, "@" + dir + "/" + file); Prototype p = LuaC.instance.compile(is, "@" + file);
String actual = protoToString(p); String actual = protoToString(p);
// load expected value from jar // load expected value from jar