Lua 5.2 compatibility fixes.

This commit is contained in:
James Roseborough
2012-09-05 04:24:44 +00:00
parent c4791e2e3e
commit ed4554fa7d
6 changed files with 27 additions and 45 deletions

View File

@@ -35,11 +35,6 @@ public class Lua {
/** use return values from previous op */ /** use return values from previous op */
public static final int LUA_MULTRET = -1; public static final int LUA_MULTRET = -1;
/** masks for new-style vararg */
public static final int VARARG_HASARG = 1;
public static final int VARARG_ISVARARG = 2;
public static final int VARARG_NEEDSARG = 4;
// from lopcodes.h // from lopcodes.h
/*=========================================================================== /*===========================================================================

View File

@@ -187,10 +187,6 @@ public class LuaClosure extends LuaFunction {
// upvalues are only possible when closures create closures // upvalues are only possible when closures create closures
UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null; UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
// create varargs "arg" table
if ( p.is_vararg >= Lua.VARARG_NEEDSARG )
stack[p.numparams] = new LuaTable(varargs);
// debug wants args to this function // debug wants args to this function
if (DebugLib.DEBUG_ENABLED) if (DebugLib.DEBUG_ENABLED)
DebugLib.debugSetupCall(varargs, stack); DebugLib.debugSetupCall(varargs, stack);

View File

@@ -881,6 +881,8 @@ public class FuncState extends LuaC {
LuaValue v1, v2, r; LuaValue v1, v2, r;
if (!e1.isnumeral() || !e2.isnumeral()) if (!e1.isnumeral() || !e2.isnumeral())
return false; return false;
if ((op == OP_DIV || op == OP_MOD) && e2.u.nval().eq_b(LuaValue.ZERO))
return false; /* do not attempt to divide by 0 */
v1 = e1.u.nval(); v1 = e1.u.nval();
v2 = e2.u.nval(); v2 = e2.u.nval();
switch (op) { switch (op) {
@@ -961,9 +963,12 @@ public class FuncState extends LuaC {
e2.init(LexState.VKNUM, 0); e2.init(LexState.VKNUM, 0);
switch (op) { switch (op) {
case LexState.OPR_MINUS: { case LexState.OPR_MINUS: {
if (e.k == LexState.VK) if (e.isnumeral()) /* minus constant? */
this.exp2anyreg(e); /* cannot operate on non-numeric constants */ e.u.setNval(e.u.nval().neg()); /* fold it */
else {
this.exp2anyreg(e);
this.codearith(OP_UNM, e, e2, line); this.codearith(OP_UNM, e, e2, line);
}
break; break;
} }
case LexState.OPR_NOT: case LexState.OPR_NOT:

View File

@@ -757,13 +757,14 @@ public class LexState {
} }
public void setvalue(expdesc other) { public void setvalue(expdesc other) {
this.f.i = other.f.i;
this.k = other.k; this.k = other.k;
this.u.info = other.u.info; this.t.i = other.t.i;
this.u._nval = other.u._nval;
this.u.ind_idx = other.u.ind_idx; this.u.ind_idx = other.u.ind_idx;
this.u.ind_t = other.u.ind_t; this.u.ind_t = other.u.ind_t;
this.u.ind_vt = other.u.ind_vt; this.u.ind_vt = other.u.ind_vt;
this.t.i = other.t.i; this.u.info = other.u.info;
this.f.i = other.f.i;
} }
} }
@@ -1253,7 +1254,7 @@ public class LexState {
} while ((f.is_vararg==0) && this.testnext(',')); } while ((f.is_vararg==0) && this.testnext(','));
} }
this.adjustlocalvars(nparams); this.adjustlocalvars(nparams);
f.numparams = (fs.nactvar - (f.is_vararg & LuaC.VARARG_HASARG)); f.numparams = fs.nactvar;
fs.reserveregs(fs.nactvar); /* reserve register for parameters */ fs.reserveregs(fs.nactvar); /* reserve register for parameters */
} }
@@ -1279,7 +1280,7 @@ public class LexState {
this.close_func(); this.close_func();
} }
int explist1(expdesc v) { int explist(expdesc v) {
/* explist1 -> expr { `,' expr } */ /* explist1 -> expr { `,' expr } */
int n = 1; /* at least one expression */ int n = 1; /* at least one expression */
this.expr(v); this.expr(v);
@@ -1292,20 +1293,17 @@ public class LexState {
} }
void funcargs(expdesc f) { void funcargs(expdesc f, int line) {
FuncState fs = this.fs; FuncState fs = this.fs;
expdesc args = new expdesc(); expdesc args = new expdesc();
int base, nparams; int base, nparams;
int line = this.linenumber;
switch (this.t.token) { switch (this.t.token) {
case '(': { /* funcargs -> `(' [ explist1 ] `)' */ case '(': { /* funcargs -> `(' [ explist1 ] `)' */
if (line != this.lastline)
this.syntaxerror("ambiguous syntax (function call x new statement)");
this.next(); this.next();
if (this.t.token == ')') /* arg list is empty? */ if (this.t.token == ')') /* arg list is empty? */
args.k = VVOID; args.k = VVOID;
else { else {
this.explist1(args); this.explist(args);
fs.setmultret(args); fs.setmultret(args);
} }
this.check_match(')', '(', line); this.check_match(')', '(', line);
@@ -1393,14 +1391,14 @@ public class LexState {
this.next(); this.next();
this.checkname(key); this.checkname(key);
fs.self(v, key); fs.self(v, key);
this.funcargs(v); this.funcargs(v, line);
break; break;
} }
case '(': case '(':
case TK_STRING: case TK_STRING:
case '{': { /* funcargs */ case '{': { /* funcargs */
fs.exp2nextreg(v); fs.exp2nextreg(v);
this.funcargs(v); this.funcargs(v, line);
break; break;
} }
default: default:
@@ -1441,7 +1439,6 @@ public class LexState {
FuncState fs = this.fs; FuncState fs = this.fs;
this.check_condition(fs.f.is_vararg!=0, "cannot use " + LUA_QL("...") this.check_condition(fs.f.is_vararg!=0, "cannot use " + LUA_QL("...")
+ " outside a vararg function"); + " outside a vararg function");
fs.f.is_vararg &= ~LuaC.VARARG_NEEDSARG; /* don't need 'arg' */
v.init(VVARARG, fs.codeABC(Lua.OP_VARARG, 0, 1, 0)); v.init(VVARARG, fs.codeABC(Lua.OP_VARARG, 0, 1, 0));
break; break;
} }
@@ -1664,7 +1661,7 @@ public class LexState {
else { /* assignment . `=' explist1 */ else { /* assignment . `=' explist1 */
int nexps; int nexps;
this.checknext('='); this.checknext('=');
nexps = this.explist1(e); nexps = this.explist(e);
if (nexps != nvars) { if (nexps != nvars) {
this.adjust_assign(nvars, nexps, e); this.adjust_assign(nvars, nexps, e);
if (nexps > nvars) if (nexps > nvars)
@@ -1848,7 +1845,7 @@ public class LexState {
} }
this.checknext(TK_IN); this.checknext(TK_IN);
line = this.linenumber; line = this.linenumber;
this.adjust_assign(3, this.explist1(e), e); this.adjust_assign(3, this.explist(e), e);
fs.checkstack(3); /* extra space to call generator */ fs.checkstack(3); /* extra space to call generator */
this.forbody(base, line, nvars - 3, false); this.forbody(base, line, nvars - 3, false);
} }
@@ -1942,7 +1939,7 @@ public class LexState {
++nvars; ++nvars;
} while (this.testnext(',')); } while (this.testnext(','));
if (this.testnext('=')) if (this.testnext('='))
nexps = this.explist1(e); nexps = this.explist(e);
else { else {
e.k = VVOID; e.k = VVOID;
nexps = 0; nexps = 0;
@@ -2002,7 +1999,7 @@ public class LexState {
if (block_follow(true) || this.t.token == ';') if (block_follow(true) || this.t.token == ';')
first = nret = 0; /* return no values */ first = nret = 0; /* return no values */
else { else {
nret = this.explist1(e); /* optional return values */ nret = this.explist(e); /* optional return values */
if (hasmultret(e.k)) { if (hasmultret(e.k)) {
fs.setmultret(e); fs.setmultret(e);
if (e.k == VCALL && nret == 1) { /* tail call? */ if (e.k == VCALL && nret == 1) { /* tail call? */

View File

@@ -793,9 +793,7 @@ public class DebugLib extends VarArgFunction {
static boolean precheck(Prototype pt) { static boolean precheck(Prototype pt) {
if (!(pt.maxstacksize <= MAXSTACK)) return false; if (!(pt.maxstacksize <= MAXSTACK)) return false;
lua_assert(pt.numparams + (pt.is_vararg & Lua.VARARG_HASARG) <= pt.maxstacksize); lua_assert(pt.numparams <= pt.maxstacksize);
lua_assert((pt.is_vararg & Lua.VARARG_NEEDSARG) == 0
|| (pt.is_vararg & Lua.VARARG_HASARG) != 0);
// if (!(pt.upvalues.length <= pt.nups)) return false; // if (!(pt.upvalues.length <= pt.nups)) return false;
if (!(pt.lineinfo.length == pt.code.length || pt.lineinfo.length == 0)) return false; if (!(pt.lineinfo.length == pt.code.length || pt.lineinfo.length == 0)) return false;
if (!(Lua.GET_OPCODE(pt.code[pt.code.length - 1]) == Lua.OP_RETURN)) return false; if (!(Lua.GET_OPCODE(pt.code[pt.code.length - 1]) == Lua.OP_RETURN)) return false;

View File

@@ -234,19 +234,10 @@ public class JavaBuilder {
storeLocal(-1, slot); storeLocal(-1, slot);
} }
} }
boolean needsarg = ((p.is_vararg & Lua.VARARG_NEEDSARG) != 0);
if ( needsarg ) {
append(new ALOAD(1));
append(new PUSH(cp, 1 + p.numparams));
append(factory.createInvoke(STR_LUAVALUE, "tableOf", TYPE_LUATABLE, ARG_TYPES_VARARGS_INT, Constants.INVOKESTATIC));
storeLocal(-1, slot++ );
}
else if ( p.numparams > 0 ) {
append(new ALOAD(1)); append(new ALOAD(1));
append(new PUSH(cp, 1 + p.numparams)); append(new PUSH(cp, 1 + p.numparams));
append(factory.createInvoke(STR_VARARGS, "subargs", TYPE_VARARGS, ARG_TYPES_INT, Constants.INVOKEVIRTUAL)); append(factory.createInvoke(STR_VARARGS, "subargs", TYPE_VARARGS, ARG_TYPES_INT, Constants.INVOKEVIRTUAL));
append(new ASTORE(1)); append(new ASTORE(1));
}
} else { } else {
// fixed arg function between 0 and 3 arguments // fixed arg function between 0 and 3 arguments
for ( slot=0; slot<p.numparams; slot++ ) { for ( slot=0; slot<p.numparams; slot++ ) {