Use JavaCompiler class to compile generated files.

This commit is contained in:
James Roseborough
2008-05-17 21:53:56 +00:00
parent 2f7f25e996
commit ebdbe60849
2 changed files with 92 additions and 41 deletions

View File

@@ -65,7 +65,7 @@ public class Print extends Lua {
}; };
static void printString(final LString s) { static void printString(PrintStream ps, final LString s) {
final byte[] bytes = s.m_bytes; final byte[] bytes = s.m_bytes;
final int off = s.m_offset; final int off = s.m_offset;
@@ -110,9 +110,9 @@ public class Print extends Lua {
ps.print('"'); ps.print('"');
} }
static void printValue( LValue v ) { static void printValue( PrintStream ps, LValue v ) {
if ( v instanceof LString ) if ( v instanceof LString )
printString( v.luaAsString() ); printString( ps, v.luaAsString() );
else if ( v instanceof LInteger ) { else if ( v instanceof LInteger ) {
ps.print( v.toJavaInt() ); ps.print( v.toJavaInt() );
} else if ( v instanceof LDouble ) { } else if ( v instanceof LDouble ) {
@@ -128,8 +128,8 @@ public class Print extends Lua {
} }
} }
static void printConstant(LPrototype f, int i) { static void printConstant(PrintStream ps, LPrototype f, int i) {
printValue( f.k[i] ); printValue( ps, f.k[i] );
} }
public static void printCode(LPrototype f) { public static void printCode(LPrototype f) {
@@ -142,6 +142,10 @@ public class Print extends Lua {
} }
public static void printOpCode(LPrototype f, int pc) { public static void printOpCode(LPrototype f, int pc) {
printOpCode(ps,f,pc);
}
public static void printOpCode(PrintStream ps, LPrototype f, int pc) {
int[] code = f.code; int[] code = f.code;
int i = code[pc]; int i = code[pc];
int o = GET_OPCODE(i); int o = GET_OPCODE(i);
@@ -182,26 +186,26 @@ public class Print extends Lua {
switch (o) { switch (o) {
case OP_LOADK: case OP_LOADK:
ps.print(" ; "); ps.print(" ; ");
printConstant(f, bx); printConstant(ps, f, bx);
break; break;
case OP_GETUPVAL: case OP_GETUPVAL:
case OP_SETUPVAL: case OP_SETUPVAL:
ps.print(" ; "); ps.print(" ; ");
if ( f.upvalues.length > b ) if ( f.upvalues.length > b )
printValue(f.upvalues[b]); printValue(ps, f.upvalues[b]);
else else
ps.print( "-" ); ps.print( "-" );
break; break;
case OP_GETGLOBAL: case OP_GETGLOBAL:
case OP_SETGLOBAL: case OP_SETGLOBAL:
ps.print(" ; "); ps.print(" ; ");
printConstant( f, bx ); printConstant( ps, f, bx );
break; break;
case OP_GETTABLE: case OP_GETTABLE:
case OP_SELF: case OP_SELF:
if (ISK(c)) { if (ISK(c)) {
ps.print(" ; "); ps.print(" ; ");
printConstant(f, INDEXK(c)); printConstant(ps, f, INDEXK(c));
} }
break; break;
case OP_SETTABLE: case OP_SETTABLE:
@@ -216,12 +220,12 @@ public class Print extends Lua {
if (ISK(b) || ISK(c)) { if (ISK(b) || ISK(c)) {
ps.print(" ; "); ps.print(" ; ");
if (ISK(b)) if (ISK(b))
printConstant(f, INDEXK(b)); printConstant(ps, f, INDEXK(b));
else else
ps.print("-"); ps.print("-");
ps.print(" "); ps.print(" ");
if (ISK(c)) if (ISK(c))
printConstant(f, INDEXK(c)); printConstant(ps, f, INDEXK(c));
else else
ps.print("-"); ps.print("-");
} }
@@ -272,7 +276,7 @@ public class Print extends Lua {
ps.print("constants (" + n + ") for " + id(f) + ":\n"); ps.print("constants (" + n + ") for " + id(f) + ":\n");
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
ps.print(" " + (i + 1) + " "); ps.print(" " + (i + 1) + " ");
printValue( f.k[i] ); printValue( ps, f.k[i] );
ps.print( "\n"); ps.print( "\n");
} }
} }
@@ -355,4 +359,5 @@ public class Print extends Lua {
return "Proto"; return "Proto";
} }
} }

View File

@@ -1,19 +1,27 @@
package org.luaj.jit; package org.luaj.jit;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintWriter; import java.io.PrintStream;
import java.util.Arrays;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler; import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
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.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;
import org.luaj.vm.LTable;
import org.luaj.vm.LValue; import org.luaj.vm.LValue;
import org.luaj.vm.Lua; import org.luaj.vm.Lua;
import org.luaj.vm.LuaState; import org.luaj.vm.LuaState;
@@ -30,11 +38,8 @@ public class LuaJit extends Lua {
InputStream is = new ByteArrayInputStream(program.getBytes()); InputStream is = new ByteArrayInputStream(program.getBytes());
LPrototype p = LuaC.compile(is, "program"); LPrototype p = LuaC.compile(is, "program");
test( p ); test( p );
LPrototype q = LuaJit.compile( p ); LPrototype q = LuaJit.jitCompile( p );
test( q ); test( q );
// JitPrototype jp = new JitPrototypeOne();
// jp.setLuaPrototype(p);
// test( jp );
} }
private static void test(LPrototype p) { private static void test(LPrototype p) {
@@ -48,20 +53,67 @@ public class LuaJit extends Lua {
} }
} }
public static LPrototype compile( LPrototype p ) { private static int counter = 0;
private static synchronized String filename() {
return "LuaJit"+(counter++);
}
public static LPrototype jitCompile( LPrototype p ) {
try {
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
System.err.println("no java compiler");
return p;
}
// write the file
String name = filename();
File source = new File(name+JavaFileObject.Kind.SOURCE.extension);
PrintStream ps = new PrintStream(new FileOutputStream(source));
writeSource(ps, name, p);
ps.close();
// set up output location
Iterable<? extends File> dest = Arrays.asList(new File[] { new File("bin") });
StandardJavaFileManager fm = compiler.getStandardFileManager( null, null, null);
fm.setLocation(StandardLocation.CLASS_OUTPUT, dest);
// compile the file
Iterable<? extends JavaFileObject> compilationUnits = fm.getJavaFileObjects(source);
CompilationTask task = compiler.getTask(null, fm, null, null, null, compilationUnits);
boolean success = task.call();
System.out.println("Success: " + success);
// instantiate, config and return
if (success) {
Class clazz = Class.forName(name);
Object instance = clazz.newInstance();
JitPrototype jp = (JitPrototype) instance;
jp.setLuaPrototype(p);
return jp;
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
return 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, step, idx, limit, init, table;
boolean back, body; boolean back, body;
PrintWriter pw = new PrintWriter( System.out ); ps.print(
String name = "JitPrototypeOne"; "import org.luaj.vm.*;\n"+
pw.print( "import org.luaj.jit.*;\n"+
"package org.luaj.jit;\n"+ "\n"+
"import org.luaj.vm.LTable;\n"+
"import org.luaj.vm.LuaState;\n"+
"public class "+name+" extends JitPrototype {\n"+ "public class "+name+" extends JitPrototype {\n"+
" public void jitCall(LuaState vm, LTable env) {\n"+ " public void jitCall(LuaState vm, LTable env) {\n"+
" int base = vm.base;\n"+
"" ); "" );
int[] code = p.code; int[] code = p.code;
@@ -72,10 +124,9 @@ public class LuaJit extends Lua {
for ( int pc=0; pc<code.length; pc++ ) { for ( int pc=0; pc<code.length; pc++ ) {
// print the instruction // print the instruction
pw.print( "\n\t\t// "); ps.print( "\n\t\t// ");
pw.flush(); Print.printOpCode(ps, p, pc);
Print.printOpCode(p, pc); ps.println();
pw.println();
// get instruction // get instruction
i = code[pc]; i = code[pc];
@@ -88,13 +139,13 @@ public class LuaJit extends Lua {
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];
pw.println( "\t\tvm.stack[base+"+a+"] = vm.stack[base+"+b+"];" ); ps.println( "\t\tvm.stack[base+"+a+"] = vm.stack[base+"+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];
pw.println( "\t\tvm.stack[base+"+a+"] = p.k["+b+"];" ); ps.println( "\t\tvm.stack[base+"+a+"] = p.k["+b+"];" );
continue; continue;
} }
/* /*
@@ -126,8 +177,8 @@ public class LuaJit extends Lua {
// 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+";");
pw.println("\t\tvm.settop("+a+");"); ps.println("\t\tvm.settop("+a+");");
pw.println("\t\tenv.luaGetTable(vm, env, p.k["+b+"]);"); ps.println("\t\tenv.luaGetTable(vm, env, p.k["+b+"]);");
continue; continue;
} }
/* /*
@@ -445,13 +496,8 @@ public class LuaJit extends Lua {
*/ */
} }
} }
pw.print( "\n"+ ps.print(
" return false;\n"+
" }\n"+ " }\n"+
"}\n" ); "}\n" );
pw.flush();
return p;
} }
} }