Simplified, extended jit implementation

This commit is contained in:
James Roseborough
2008-05-18 15:12:03 +00:00
parent c5c322fee1
commit 039d79fe5f
13 changed files with 314 additions and 174 deletions

View File

@@ -29,23 +29,12 @@ public class LClosure extends LFunction {
public LTable env; public LTable env;
/**
* @deprecated construct with environment instead
* @param state
* @param p
*/
public LClosure(LuaState state, LPrototype p) {
this.env = state._G;
this.p = p;
upVals = new UpVal[p.nups];
}
/** /**
* Construct using a prototype and initial environment. * Construct using a prototype and initial environment.
* @param p * @param p
* @param env * @param env
*/ */
public LClosure(LPrototype p, LTable env) { protected LClosure(LPrototype p, LTable env) {
this.p = p; this.p = p;
this.env = env; this.env = env;
upVals = new UpVal[p.nups]; upVals = new UpVal[p.nups];

View File

@@ -450,7 +450,7 @@ public class LuaState extends Lua {
public int load( InputStream is, String chunkname ) { public int load( InputStream is, String chunkname ) {
try { try {
LPrototype p = LoadState.undump(this, is, chunkname ); LPrototype p = LoadState.undump(this, is, chunkname );
pushlvalue( new LClosure( p, _G ) ); pushlvalue( p.newClosure( _G ) );
return 0; return 0;
} catch ( Throwable t ) { } catch ( Throwable t ) {
pushstring( t.getMessage() ); pushstring( t.getMessage() );
@@ -840,7 +840,7 @@ public class LuaState extends Lua {
case LuaState.OP_CLOSURE: { case LuaState.OP_CLOSURE: {
b = LuaState.GETARG_Bx(i); b = LuaState.GETARG_Bx(i);
proto = cl.p.p[b]; proto = cl.p.p[b];
newClosure = new LClosure(proto, cl.env); newClosure = proto.newClosure(cl.env);
for (int j = 0; j < newClosure.upVals.length; j++, ci.pc++) { for (int j = 0; j < newClosure.upVals.length; j++, ci.pc++) {
i = code[ci.pc]; i = code[ci.pc];
o = LuaState.GET_OPCODE(i); o = LuaState.GET_OPCODE(i);

View File

@@ -193,7 +193,7 @@ public class StandardLuaJVM {
LPrototype p = LoadState.undump(state, is, getScript()); LPrototype p = LoadState.undump(state, is, getScript());
// create closure and execute // create closure and execute
final LClosure c = new LClosure(p, state._G); final LClosure c = p.newClosure(state._G);
String[] args = getScriptArgs(); String[] args = getScriptArgs();
int numOfScriptArgs = (args != null ? args.length : 0); int numOfScriptArgs = (args != null ? args.length : 0);
LValue[] vargs = new LValue[numOfScriptArgs]; LValue[] vargs = new LValue[numOfScriptArgs];

View File

@@ -69,7 +69,7 @@ public class LuaRunner {
LPrototype p = LoadState.undump(state, is, script); LPrototype p = LoadState.undump(state, is, script);
// create closure and execute // create closure and execute
LClosure c = new LClosure( p, state._G ); LClosure c = p.newClosure( state._G );
// do the call // do the call
state.doCall( c, new LValue[0] ); state.doCall( c, new LValue[0] );

View File

@@ -58,7 +58,7 @@ public class LuajavaRunner {
LPrototype p = LoadState.undump(state, is, script); LPrototype p = LoadState.undump(state, is, script);
// create closure and execute // create closure and execute
LClosure c = new LClosure( p, state._G ); LClosure c = p.newClosure( state._G );
state.doCall(c, new LValue[0]); state.doCall(c, new LValue[0]);
} }

View File

@@ -14,6 +14,10 @@ public class JitPrototype extends LPrototype {
super(); super();
} }
protected void unimplemented() {
throw new RuntimeException("unimplemented");
}
protected void setLuaPrototype(LPrototype lp) { protected void setLuaPrototype(LPrototype lp) {
this.p = lp; this.p = lp;
} }
@@ -22,17 +26,17 @@ public class JitPrototype extends LPrototype {
return new JitClosure(this, env); return new JitClosure(this, env);
} }
private static final class JitClosure extends LClosure { protected static final class JitClosure extends LClosure {
private final JitPrototype jp; private final JitPrototype jp;
public JitClosure(JitPrototype jitPrototype, LTable env) { public JitClosure(JitPrototype jitPrototype, LTable env) {
super( jitPrototype.p, env ); super( jitPrototype.p, env );
this.jp = jitPrototype; this.jp = jitPrototype;
} }
public boolean luaStackCall(LuaState vm) { public boolean luaStackCall(LuaState vm) {
jp.jitCall(vm,env); jp.jitCall(vm,env,this);
return false; return false;
} }
} }
public abstract void jitCall( LuaState vm, LTable env ); public abstract void jitCall( LuaState vm, LTable env, JitClosure jcl );
} }

View File

@@ -19,6 +19,7 @@ import javax.tools.JavaCompiler.CompilationTask;
import org.luaj.compiler.LuaC; import org.luaj.compiler.LuaC;
import org.luaj.debug.Print; import org.luaj.debug.Print;
import org.luaj.jit.JitPrototype.JitClosure;
import org.luaj.platform.J2sePlatform; import org.luaj.platform.J2sePlatform;
import org.luaj.vm.LClosure; import org.luaj.vm.LClosure;
import org.luaj.vm.LPrototype; import org.luaj.vm.LPrototype;
@@ -99,26 +100,89 @@ public class LuaJit extends Lua {
return p; return p;
} }
private static String RKBC_jit(int bc) {
return LuaState.ISK(bc) ?
"k"+LuaState.INDEXK(bc):
"s"+bc;
}
private static String GETARG_RKB_jit(int i) {
return RKBC_jit(GETARG_B(i));
}
private static String GETARG_RKC_jit(int i) {
return RKBC_jit(GETARG_C(i));
}
private static void writeSource( PrintStream ps, String name, LPrototype p ) { private static void writeSource( PrintStream ps, String name, LPrototype p ) {
int i, a, b, c, o, n, cb; int i, a, b, c, o, n, cb;
LValue rkb, rkc, nvarargs, key, val; LValue rkb, rkc, nvarargs, key, val;
LValue i0, step, idx, limit, init, table; LValue i0, table;
boolean back, body; boolean body;
String bs, cs;
int[] code = p.code;
LValue[] k = p.k;
// class header
ps.print( ps.print(
"import org.luaj.vm.*;\n"+ "import org.luaj.vm.*;\n"+
"import org.luaj.jit.*;\n"+ "import org.luaj.jit.*;\n"+
"\n"+ "\n"+
"public class "+name+" extends JitPrototype {\n"+ "public class "+name+" extends JitPrototype {\n" );
" public void jitCall(LuaState vm, LTable env) {\n"+
" int base = vm.base;\n"+
"" );
int[] code = p.code; // static constants
LValue[] k = p.k; int nk = k.length;
if ( nk > 0 ) {
ps.print( "\tprivate LValue k0" ) ;
for (int ik=1; ik<nk; ik++ )
ps.print( ",k"+ik ) ;
ps.println( ";" ) ;
ps.println(" protected void setLuaPrototype(LPrototype lp) {\n" );
ps.println(" super.setLuaPrototype(lp);\n" );
ps.println( " final LValue[] k = p.k;" ) ;
for (int ik=0; ik<nk; ik++ )
ps.println( " k"+ik+" = k["+ik+"];" ) ;
ps.println(" }" ) ;
}
// jit call
ps.println( "\tpublic void jitCall(LuaState vm, LTable env, JitClosure jcl) {" );
ps.println( "\t\tint base = vm.base;" );
// parameters
int ns = p.maxstacksize;
int is = 0;
if ( ! p.is_vararg ) {
ps.println( "\t\tvm.settop("+p.numparams+");");
for (; is<p.numparams; is++ )
ps.println( "\t\tLValue s"+is+" = vm.stack[base+"+is+"];" );
}
for (; is<ns; is++ )
ps.println( "\t\tLValue s"+is+" = LNil.NIL;" );
ps.println();
// find local variables, jump points
int forlevel=0,maxforlevels=0;
int[] jumpdeltas = new int[code.length];
for ( int pc=0; pc<code.length; pc++ ) {
i = code[pc];
o = (i >> POS_OP) & MAX_OP;
switch (o) {
case OP_FORPREP:
maxforlevels = Math.max(maxforlevels, ++forlevel);
break;
case OP_FORLOOP:
forlevel--;
break;
}
}
for ( int j=0; j<maxforlevels; j++ )
ps.println("\t\tboolean back"+j+";");
// loop until a return instruction is processed, // loop until a return instruction is processed,
// or the vm yields // or the vm yields
for ( int pc=0; pc<code.length; pc++ ) { for ( int pc=0; pc<code.length; pc++ ) {
@@ -136,16 +200,19 @@ public class LuaJit extends Lua {
a = (i >> POS_A) & MAXARG_A; a = (i >> POS_A) & MAXARG_A;
switch (o) { switch (o) {
default:
ps.println( "\t\tunimplemented();");
break;
case LuaState.OP_MOVE: { case LuaState.OP_MOVE: {
b = LuaState.GETARG_B(i); b = LuaState.GETARG_B(i);
// this.stack[base + a] = this.stack[base + b]; // this.stack[base + a] = this.stack[base + b];
ps.println( "\t\tvm.stack[base+"+a+"] = vm.stack[base+"+b+"];" ); ps.println( "\t\ts"+a+" = s"+b+";" );
continue; continue;
} }
case LuaState.OP_LOADK: { case LuaState.OP_LOADK: {
b = LuaState.GETARG_Bx(i); b = LuaState.GETARG_Bx(i);
// this.stack[base + a] = k[b]; // this.stack[base + a] = k[b];
ps.println( "\t\tvm.stack[base+"+a+"] = p.k["+b+"];" ); ps.println( "\t\ts"+a+" = k"+b+";" );
continue; continue;
} }
/* /*
@@ -157,75 +224,104 @@ public class LuaJit extends Lua {
ci.pc++; // skip next instruction (if C) ci.pc++; // skip next instruction (if C)
continue; continue;
} }
*/
case LuaState.OP_LOADNIL: { case LuaState.OP_LOADNIL: {
b = LuaState.GETARG_B(i); b = LuaState.GETARG_B(i);
do { ps.print("\t\t");
this.stack[base + b] = LNil.NIL; for ( int j=a; j<=b; j++ )
} while ((--b) >= a); ps.print("s"+j+"=");
continue; ps.println("LNil.NIL;");
break;
} }
case LuaState.OP_GETUPVAL: { case LuaState.OP_GETUPVAL: {
b = LuaState.GETARG_B(i); //b = LuaState.GETARG_B(i);
this.stack[base + a] = cl.upVals[b].getValue(); //this.stack[base + a] = cl.upVals[b].getValue();
continue; //continue;
b = LuaState.GETARG_B(i);
ps.println("\t\t\ts"+a+" = jcl.upVals["+b+"].getValue();");
break;
} }
*/
case LuaState.OP_GETGLOBAL: { case LuaState.OP_GETGLOBAL: {
b = LuaState.GETARG_Bx(i); // b = LuaState.GETARG_Bx(i);
// key = k[b]; // key = k[b];
// table = cl.env; // table = cl.env;
// top = base + a; // top = base + a;
// table.luaGetTable(this, table, key); // table.luaGetTable(this, table, key);
// pw.println("\t\tvm.top = base+"+a+";"); // pw.println("\t\tvm.top = base+"+a+";");
ps.println("\t\tvm.top = "+a+";"); // continue
ps.println("\t\tenv.luaGetTable(vm, env, p.k["+b+"]);"); b = LuaState.GETARG_Bx(i);
continue; ps.println("\t\tenv.luaGetTable(vm, env, k"+b+");");
ps.println("\t\ts"+a+" = vm.stack[--vm.top];");
break;
} }
/*
case LuaState.OP_GETTABLE: { case LuaState.OP_GETTABLE: {
b = LuaState.GETARG_B(i); //b = GETARG_B(i);
key = GETARG_RKC(k, i); //key = GETARG_RKC(k, i);
table = this.stack[base + b]; //table = this.stack[base + b];
top = base + a; //top = base + a;
table.luaGetTable(this, table, key); //table.luaGetTable(this, table, key);
continue; //continue;
b = GETARG_B(i);
cs = GETARG_RKC_jit(i);
ps.println("\t\ts"+b+".luaGetTable(vm, s"+b+", "+cs+");");
ps.println("\t\ts"+a+" = vm.stack[--vm.top];");
break;
} }
case LuaState.OP_SETGLOBAL: { case LuaState.OP_SETGLOBAL: {
//b = LuaState.GETARG_Bx(i);
//key = k[b];
//val = this.stack[base + a];
//table = cl.env;
//table.luaSetTable(this, table, key, val);
//continue;
b = LuaState.GETARG_Bx(i); b = LuaState.GETARG_Bx(i);
key = k[b]; ps.println("\t\tenv.luaSetTable(vm, env, k"+b+", s"+a+");");
val = this.stack[base + a]; break;
table = cl.env;
table.luaSetTable(this, table, key, val);
continue;
} }
case LuaState.OP_SETUPVAL: { case LuaState.OP_SETUPVAL: {
b = LuaState.GETARG_B(i); //b = LuaState.GETARG_B(i);
cl.upVals[b].setValue( this.stack[base + a] ); //cl.upVals[b].setValue( this.stack[base + a] );
continue; //continue;
b = LuaState.GETARG_B(i);
ps.println("\t\t\tjcl.upVals["+b+"].setValue(s"+a+");");
break;
} }
case LuaState.OP_SETTABLE: { case LuaState.OP_SETTABLE: {
key = GETARG_RKB(k, i); //key = GETARG_RKB(k, i);
val = GETARG_RKC(k, i); //val = GETARG_RKC(k, i);
table = this.stack[base + a]; //table = this.stack[base + a];
table.luaSetTable(this, table, key, val); //table.luaSetTable(this, table, key, val);
continue; //continue;
bs = GETARG_RKB_jit(i);
cs = GETARG_RKC_jit(i);
ps.println("\t\ts"+a+".luaSetTable(vm, s"+a+", "+bs+", "+cs+");");
break;
} }
case LuaState.OP_NEWTABLE: { case LuaState.OP_NEWTABLE: {
b = LuaState.GETARG_B(i); //b = LuaState.GETARG_B(i);
c = LuaState.GETARG_C(i); //c = LuaState.GETARG_C(i);
this.stack[base + a] = new LTable(b, c); //this.stack[base + a] = new LTable(b, c);
continue; //continue;
b = GETARG_B(i);
c = GETARG_C(i);
ps.println("\t\ts"+a+" = new LTable("+b+","+c+");");
break;
} }
case LuaState.OP_SELF: { case LuaState.OP_SELF: {
rkb = GETARG_RKB(k, i); //rkb = GETARG_RKB(k, i);
rkc = GETARG_RKC(k, i); //rkc = GETARG_RKC(k, i);
top = base + a; //top = base + a;
rkb.luaGetTable(this, rkb, rkc); //rkb.luaGetTable(this, rkb, rkc);
this.stack[base + a + 1] = rkb; //this.stack[base + a + 1] = rkb;
// StkId rb = RB(i); //// StkId rb = RB(i);
// setobjs2s(L, ra+1, rb); //// setobjs2s(L, ra+1, rb);
// Protect(luaV_gettable(L, rb, RKC(i), ra)); //// Protect(luaV_gettable(L, rb, RKC(i), ra));
continue; //continue;
bs = GETARG_RKB_jit(i);
cs = GETARG_RKC_jit(i);
ps.println("\t\t"+bs+".luaGetTable(vm, "+bs+", "+cs+");");
ps.println("\t\ts"+(a+1)+" = "+bs+";");
break;
} }
case LuaState.OP_ADD: case LuaState.OP_ADD:
case LuaState.OP_SUB: case LuaState.OP_SUB:
@@ -233,27 +329,39 @@ public class LuaJit extends Lua {
case LuaState.OP_DIV: case LuaState.OP_DIV:
case LuaState.OP_MOD: case LuaState.OP_MOD:
case LuaState.OP_POW: { case LuaState.OP_POW: {
rkb = GETARG_RKB(k, i); //rkb = GETARG_RKB(k, i);
rkc = GETARG_RKC(k, i); //rkc = GETARG_RKC(k, i);
this.stack[base + a] = rkc.luaBinOpUnknown(o, rkb); //this.stack[base + a] = rkc.luaBinOpUnknown(o, rkb);
continue; //continue;
bs = GETARG_RKB_jit(i);
cs = GETARG_RKC_jit(i);
ps.println("\t\ts"+a+" = "+cs+".luaBinOpUnknown("+o+","+bs+");");
break;
} }
case LuaState.OP_UNM: { case LuaState.OP_UNM: {
rkb = GETARG_RKB(k, i); //rkb = GETARG_RKB(k, i);
this.stack[base + a] = rkb.luaUnaryMinus(); //this.stack[base + a] = rkb.luaUnaryMinus();
continue; //continue;
bs = GETARG_RKB_jit(i);
ps.println("\t\ts"+a+" = "+bs+".luaUnaryMinus();");
} }
case LuaState.OP_NOT: { case LuaState.OP_NOT: {
rkb = GETARG_RKB(k, i); //rkb = GETARG_RKB(k, i);
this.stack[base + a] = (!rkb.toJavaBoolean() ? LBoolean.TRUE //this.stack[base + a] = (!rkb.toJavaBoolean() ? LBoolean.TRUE
: LBoolean.FALSE); // : LBoolean.FALSE);
continue; //continue;
bs = GETARG_RKB_jit(i);
ps.println("\t\ts"+a+" = ("+bs+".toJavaBoolean()? LBoolean.TRUE: LBoolean.FALSE);");
break;
} }
case LuaState.OP_LEN: { case LuaState.OP_LEN: {
rkb = GETARG_RKB(k, i); //rkb = GETARG_RKB(k, i);
this.stack[base + a] = LInteger.valueOf( rkb.luaLength() ); //this.stack[base + a] = LInteger.valueOf( rkb.luaLength() );
continue; //continue;
bs = GETARG_RKB_jit(i);
ps.println("\t\ts"+a+" = LInteger.valueOf("+bs+".luaLength());");
} }
/*
case LuaState.OP_CONCAT: { case LuaState.OP_CONCAT: {
b = LuaState.GETARG_B(i); b = LuaState.GETARG_B(i);
c = LuaState.GETARG_C(i); c = LuaState.GETARG_C(i);
@@ -296,50 +404,57 @@ public class LuaJit extends Lua {
} }
*/ */
case LuaState.OP_CALL: { case LuaState.OP_CALL: {
//
// ra is base of new call frame //// ra is base of new call frame
// this.base += a; //this.base += a;
// ps.println("\t\tvm.base = base+"+a+";"); //
//// number of args
// number of args //b = LuaState.GETARG_B(i);
b = LuaState.GETARG_B(i); //if (b != 0) // else use previous instruction set top
// top = base + b;
//
//// number of return values we need
//c = LuaState.GETARG_C(i);
//
//// make or set up the call
//this.nresults = c - 1;
//if (this.stack[base].luaStackCall(this))
// return;
//
//// adjustTop only for case when call was completed
//// and number of args > 0. If call completed but
//// c == 0, leave top to point to end of results
//if (c > 0)
// adjustTop(base + c - 1);
//
//// restore base
//base = ci.base;
//
//continue;
// adjust top before the call // copy call to vm stack
if (b != 0) { // else use previous instruction set top ps.println( "\t\tvm.stack[base+"+a+"] = s"+a+";" );
// top = base + b;
ps.println("\t\tvm.top = "+(a+b)+";"); // number of args
} b = LuaState.GETARG_B(i);
if (b > 0) { // else use previous instruction set top
// number of return values we need for ( int j=1; j<b; j++ )
c = LuaState.GETARG_C(i); ps.println( "\t\tvm.stack[base+"+(a+j)+"] = s"+(a+j)+";" );
ps.println( "\t\tvm.top = base+"+(a+b)+";" );
}
// number of return values we need
c = LuaState.GETARG_C(i);
// make the call // make the call
ps.println("\t\tvm.call("+(b-1)+","+(c-1)+");"); ps.println("\t\tvm.call("+(b-1)+","+(c-1)+");");
//
// // copy results to local vars
// // make or set up the call if ( c > 0 )
// // this.nresults = c - 1; for ( int j=0; j<c-1; j++ )
// int nresults = c - 1; ps.println( "\t\ts"+(a+j)+" = vm.stack[base+"+(a+j)+"];" );
// ps.println("\t\tvm.nresults = "+nresults+";");
// // if (this.stack[base].luaStackCall(this)) break;
// // return;
// ps.println("\t\tif ( vm.stack[base].luaStackCall(vm) ) {");
// ps.println("\t\t\tvm.execute();");
// ps.println("\t\t}");
//
// // adjustTop only for case when call was completed
// // and number of args > 0. If call completed but
// // c == 0, leave top to point to end of results
// if (c > 0) {
// // adjustTop(base + c - 1);
// ps.println( "\t\tvm.settop("+nresults+");");
// }
//
// // restore base
// // base = ci.base;
//
// // continue;
break;
} }
/* /*
case LuaState.OP_TAILCALL: { case LuaState.OP_TAILCALL: {
@@ -381,31 +496,40 @@ public class LuaJit extends Lua {
// force restore of base, etc. // force restore of base, etc.
return; return;
} }
case LuaState.OP_RETURN: {
// number of return vals to return
b = LuaState.GETARG_B(i) - 1;
if (b == -1)
b = top - (base + a);
// close open upvals
closeUpVals( base );
// number to copy down
System.arraycopy(stack, base + a, stack, ci.resultbase, b);
top = ci.resultbase + b;
// adjust results to what caller expected
if (ci.nresults >= 0)
adjustTop(ci.resultbase + ci.nresults);
// pop the call stack
--cc;
// force a reload of the calling context
return;
}
*/ */
case LuaState.OP_RETURN: {
//// number of return vals to return
//b = LuaState.GETARG_B(i) - 1;
//if (b == -1)
// b = top - (base + a);
//
//// close open upvals
//closeUpVals( base );
//
//// number to copy down
//System.arraycopy(stack, base + a, stack, ci.resultbase, b);
//top = ci.resultbase + b;
//
//// adjust results to what caller expected
//if (ci.nresults >= 0)
// adjustTop(ci.resultbase + ci.nresults);
//
//// pop the call stack
//--cc;
//
//// force a reload of the calling context
//return;
// number of return vals to return
b = LuaState.GETARG_B(i);
if (b > 0) {
for ( int j=1; j<b; j++ )
ps.println( "\t\tvm.stack[base+"+(a+j-1)+"] = s"+(a+j-1)+";" );
ps.println( "\t\tvm.top = base+"+(a+b)+";" );
}
ps.println( "\t\treturn;" );
break;
}
case LuaState.OP_FORPREP: { case LuaState.OP_FORPREP: {
//init = this.stack[base + a]; //init = this.stack[base + a];
//step = this.stack[base + a + 2]; //step = this.stack[base + a + 2];
@@ -418,16 +542,21 @@ public class LuaJit extends Lua {
b = LuaState.GETARG_sBx(i); b = LuaState.GETARG_sBx(i);
// set up the loop variables // set up the loop variables
ps.println( "\t\tdouble index = vm.stack[base+"+a+"].toJavaDouble();"); String init = "s"+(a);
ps.println( "\t\tdouble limit = vm.stack[base+"+(a+1)+"].toJavaDouble();"); String limit = "s"+(a+1);
ps.println( "\t\tdouble step = vm.stack[base+"+(a+2)+"].toJavaDouble();"); String step = "s"+(a+2);
ps.println( "\t\tboolean back = step < 0;"); String idx = "s"+(a+3);
ps.println( "\t\tfor ( ; back? (index>=limit): (index<=limit); index+=step ) {"); String back = "back"+(forlevel++);
ps.println( "\t\tvm.stack[base+"+(a+3)+"] = LDouble.valueOf(index);"); ps.println( "\t\t"+back+"="+step+".luaBinCmpInteger(Lua.OP_LT,0);");
ps.println( "\t\tfor ( "+idx+"="+init+";\n" +
"\t\t\t"+back+"? "+idx+".luaBinCmpUnknown(Lua.OP_LE, "+limit+"): "+limit+".luaBinCmpUnknown(Lua.OP_LE, "+idx+");\n" +
"\t\t\t"+idx+"="+idx+".luaBinOpUnknown(Lua.OP_ADD,"+step+") ) {");
forlevel++;
break; break;
} }
case LuaState.OP_FORLOOP: { case LuaState.OP_FORLOOP: {
ps.println( "\t\t}"); forlevel--;
ps.println( "\t\t}");
//i0 = this.stack[base + a]; //i0 = this.stack[base + a];
//step = this.stack[base + a + 2]; //step = this.stack[base + a + 2];
//idx = step.luaBinOpUnknown(Lua.OP_ADD, i0); //idx = step.luaBinOpUnknown(Lua.OP_ADD, i0);
@@ -444,8 +573,8 @@ public class LuaJit extends Lua {
//continue; //continue;
break; break;
} }
/*
case LuaState.OP_TFORLOOP: { case LuaState.OP_TFORLOOP: {
ps.println( "\t\t}");
//cb = base + a + 3; // call base //cb = base + a + 3; // call base
//base = cb; //base = cb;
//adjustTop( cb + 3 ); //adjustTop( cb + 3 );
@@ -467,7 +596,6 @@ public class LuaJit extends Lua {
//} //}
//continue; //continue;
} }
/*
case LuaState.OP_SETLIST: { case LuaState.OP_SETLIST: {
b = LuaState.GETARG_B(i); b = LuaState.GETARG_B(i);
c = LuaState.GETARG_C(i); c = LuaState.GETARG_C(i);
@@ -493,7 +621,7 @@ public class LuaJit extends Lua {
case LuaState.OP_CLOSURE: { case LuaState.OP_CLOSURE: {
b = LuaState.GETARG_Bx(i); b = LuaState.GETARG_Bx(i);
proto = cl.p.p[b]; proto = cl.p.p[b];
newClosure = new LClosure(proto, cl.env); newClosure = proto.newClosure(cl.env);
for (int j = 0; j < newClosure.upVals.length; j++, ci.pc++) { for (int j = 0; j < newClosure.upVals.length; j++, ci.pc++) {
i = code[ci.pc]; i = code[ci.pc];
o = LuaState.GET_OPCODE(i); o = LuaState.GET_OPCODE(i);

View File

@@ -0,0 +1,19 @@
package org.luaj.jit;
import java.io.IOException;
import org.luaj.vm.LPrototype;
import org.luaj.vm.LuaJTest;
import org.luaj.vm.LuaState;
/**
* Suite of standard tests, but using the LuaJit compiler
* for all loaded prototypes.
*/
public class LuaJitTest extends LuaJTest {
protected LPrototype loadScriptResource( LuaState state, String name ) throws IOException {
LPrototype p = super.loadScriptResource(state, name);
return LuaJit.jitCompile(p);
}
}

View File

@@ -111,7 +111,7 @@ public class LuaScriptEngine extends LFunction implements ScriptEngine {
LineNumberInputStream is = new LineNumberInputStream( bais ); LineNumberInputStream is = new LineNumberInputStream( bais );
try { try {
LPrototype p = LoadState.undump(luaState, is, "script"); LPrototype p = LoadState.undump(luaState, is, "script");
LClosure c = new LClosure( p, luaState._G ); LClosure c = p.newClosure( luaState._G );
luaState.doCall( c, new LValue[0] ); luaState.doCall( c, new LValue[0] );
return luaState.topointer(1); return luaState.topointer(1);
} catch ( LuaErrorException lee ) { } catch ( LuaErrorException lee ) {

View File

@@ -31,7 +31,7 @@ public class SimpleTests extends TestCase {
// try running the code! // try running the code!
LuaState state = Platform.newLuaState(); LuaState state = Platform.newLuaState();
BaseLib.install( state._G ); BaseLib.install( state._G );
LClosure c = new LClosure( state, p ); LClosure c = p.newClosure( state._G );
state.doCall( c, new LValue[0] ); state.doCall( c, new LValue[0] );
} catch ( Exception e ) { } catch ( Exception e ) {
fail("i/o exception: "+e ); fail("i/o exception: "+e );

View File

@@ -55,7 +55,7 @@ public class DebugStackStateTest extends TestCase {
LPrototype p = LoadState.undump(state, is, script); LPrototype p = LoadState.undump(state, is, script);
// create closure and execute // create closure and execute
final LClosure c = new LClosure( state, p ); final LClosure c = p.newClosure( state._G );
// suspend the vm right away // suspend the vm right away
state.suspend(); state.suspend();

View File

@@ -194,7 +194,7 @@ public class LuaJTest extends TestCase {
BaseLib.redirectOutput( outputStream ); BaseLib.redirectOutput( outputStream );
try { try {
// create closure and execute // create closure and execute
LClosure c = new LClosure( p, state._G ); LClosure c = p.newClosure( state._G );
state.doCall(c, new LValue[0]); state.doCall(c, new LValue[0]);
final String actualOutput = new String( outputStream.toByteArray() ); final String actualOutput = new String( outputStream.toByteArray() );
@@ -207,7 +207,7 @@ public class LuaJTest extends TestCase {
} }
} }
private LPrototype loadScriptResource( LuaState state, String name ) throws IOException { protected LPrototype loadScriptResource( LuaState state, String name ) throws IOException {
InputStream script = getClass().getResourceAsStream( "/"+name+".luac" ); InputStream script = getClass().getResourceAsStream( "/"+name+".luac" );
if ( script == null ) { if ( script == null ) {
script = getClass().getResourceAsStream( "/"+name+".lua" ); script = getClass().getResourceAsStream( "/"+name+".lua" );

View File

@@ -74,7 +74,7 @@ public class StandardTest extends TestCase {
// the garbage collector. Until we implement that, remove the // the garbage collector. Until we implement that, remove the
// built-in collectgarbage function. // built-in collectgarbage function.
state._G.put( "collectgarbage", LNil.NIL ); state._G.put( "collectgarbage", LNil.NIL );
LClosure c = new LClosure( code, state._G ); LClosure c = code.newClosure( state._G );
ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream();
BaseLib.redirectOutput( output ); BaseLib.redirectOutput( output );