Improve compatibility with lua 5.2.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import org.luaj.vm2.Globals;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||||
|
|
||||||
@@ -10,8 +11,8 @@ public class SampleJseMain {
|
|||||||
String script = "examples/lua/hello.lua";
|
String script = "examples/lua/hello.lua";
|
||||||
|
|
||||||
// create an environment to run in
|
// create an environment to run in
|
||||||
LuaValue _G = JsePlatform.standardGlobals();
|
Globals _G = JsePlatform.standardGlobals();
|
||||||
_G.get("dofile").call( LuaValue.valueOf(script) );
|
_G.loadFile(script).arg1().call( LuaValue.valueOf(script) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,16 +10,22 @@ import javax.script.ScriptException;
|
|||||||
import javax.script.SimpleBindings;
|
import javax.script.SimpleBindings;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
|
import org.luaj.vm2.lib.OneArgFunction;
|
||||||
|
|
||||||
public class ScriptEngineSample {
|
public class ScriptEngineSample {
|
||||||
|
|
||||||
public static void main(String [] args) {
|
public static void main(String [] args) {
|
||||||
|
// Set the property 'luaj.debug' before getting the engine to get
|
||||||
|
// the debug libraries, which will be slower, but may provide stack traces
|
||||||
|
// when luaJC is not used.
|
||||||
|
// System.setProperty("luaj.debug", "true");
|
||||||
|
|
||||||
ScriptEngineManager sem = new ScriptEngineManager();
|
ScriptEngineManager sem = new ScriptEngineManager();
|
||||||
ScriptEngine e = sem.getEngineByExtension(".lua");
|
ScriptEngine e = sem.getEngineByExtension(".lua");
|
||||||
ScriptEngineFactory f = e.getFactory();
|
ScriptEngineFactory f = e.getFactory();
|
||||||
|
|
||||||
// uncomment to enable the lua-to-java bytecode compiler
|
// uncomment to enable the lua-to-java bytecode compiler
|
||||||
// (require bcel library in class path)
|
// (requires bcel library in class path)
|
||||||
// org.luaj.vm2.luajc.LuaJC.install();
|
// org.luaj.vm2.luajc.LuaJC.install();
|
||||||
|
|
||||||
System.out.println( "Engine name: " +f.getEngineName() );
|
System.out.println( "Engine name: " +f.getEngineName() );
|
||||||
@@ -29,6 +35,7 @@ public class ScriptEngineSample {
|
|||||||
String statement = f.getOutputStatement("\"hello, world\"");
|
String statement = f.getOutputStatement("\"hello, world\"");
|
||||||
System.out.println(statement);
|
System.out.println(statement);
|
||||||
try {
|
try {
|
||||||
|
// Simple evaluations. Each tiny script is compiled then evaluated.
|
||||||
e.eval(statement);
|
e.eval(statement);
|
||||||
|
|
||||||
e.put("x", 25);
|
e.put("x", 25);
|
||||||
@@ -39,21 +46,36 @@ public class ScriptEngineSample {
|
|||||||
e.eval("y = math.sqrt(x)");
|
e.eval("y = math.sqrt(x)");
|
||||||
System.out.println( "y="+e.get("y") );
|
System.out.println( "y="+e.get("y") );
|
||||||
|
|
||||||
|
e.put("f", new OneArgFunction() {
|
||||||
|
public LuaValue call(LuaValue arg) {
|
||||||
|
System.out.println("arg "+arg.tojstring());
|
||||||
|
return LuaValue.valueOf(123);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
System.out.println("eval: "+e.eval("return f('abc')"));
|
||||||
|
|
||||||
|
// Example of compiled script tha can be reused once compiled.
|
||||||
CompiledScript cs = ((Compilable)e).compile("y = math.sqrt(x); return y");
|
CompiledScript cs = ((Compilable)e).compile("y = math.sqrt(x); return y");
|
||||||
Bindings b = e.createBindings();
|
|
||||||
b.put("x", 3);
|
|
||||||
System.out.println( "eval: "+cs.eval(b) );
|
|
||||||
System.out.println( "y="+b.get("y") );
|
|
||||||
|
|
||||||
SimpleBindings sb = new SimpleBindings();
|
Bindings b1 = e.createBindings();
|
||||||
sb.put("x", 144);
|
Bindings b2 = e.createBindings();
|
||||||
|
b1.put("x", 3);
|
||||||
|
b2.put("x", 144);
|
||||||
|
System.out.println( "eval: "+cs.eval(b1) );
|
||||||
|
System.out.println( "eval: "+cs.eval(b2) );
|
||||||
|
System.out.println( "y="+b1.get("y") );
|
||||||
|
System.out.println( "y="+b2.get("y") );
|
||||||
|
|
||||||
|
// Bindings that use a client-specified Bindings type.
|
||||||
|
Bindings sb = new SimpleBindings();
|
||||||
|
sb.put("x", 2);
|
||||||
System.out.println( "eval: "+cs.eval(sb) );
|
System.out.println( "eval: "+cs.eval(sb) );
|
||||||
System.out.println( "y="+sb.get("y") );
|
|
||||||
|
|
||||||
|
// Example of how exceptions are generated.
|
||||||
try {
|
try {
|
||||||
e.eval("\n\nbogus example\n\n");
|
e.eval("\n\nbuggy lua code\n\n");
|
||||||
} catch ( ScriptException se ) {
|
} catch ( ScriptException se ) {
|
||||||
System.out.println("script threw ScriptException as expected, message is '"+se.getMessage()+"'");
|
System.out.println("script exception thrown for buggy script, message: '"+se.getMessage()+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
testEngineBindings(e);
|
testEngineBindings(e);
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ import org.apache.bcel.generic.Type;
|
|||||||
import org.luaj.vm2.Buffer;
|
import org.luaj.vm2.Buffer;
|
||||||
import org.luaj.vm2.Lua;
|
import org.luaj.vm2.Lua;
|
||||||
import org.luaj.vm2.LuaBoolean;
|
import org.luaj.vm2.LuaBoolean;
|
||||||
import org.luaj.vm2.LuaDouble;
|
|
||||||
import org.luaj.vm2.LuaInteger;
|
import org.luaj.vm2.LuaInteger;
|
||||||
import org.luaj.vm2.LuaNumber;
|
import org.luaj.vm2.LuaNumber;
|
||||||
import org.luaj.vm2.LuaString;
|
import org.luaj.vm2.LuaString;
|
||||||
@@ -73,7 +72,6 @@ public class JavaBuilder {
|
|||||||
private static final String STR_LUAVALUE = LuaValue.class.getName();
|
private static final String STR_LUAVALUE = LuaValue.class.getName();
|
||||||
private static final String STR_LUASTRING = LuaString.class.getName();
|
private static final String STR_LUASTRING = LuaString.class.getName();
|
||||||
private static final String STR_LUAINTEGER = LuaInteger.class.getName();
|
private static final String STR_LUAINTEGER = LuaInteger.class.getName();
|
||||||
private static final String STR_LUADOUBLE = LuaDouble.class.getName();
|
|
||||||
private static final String STR_LUANUMBER = LuaNumber.class.getName();
|
private static final String STR_LUANUMBER = LuaNumber.class.getName();
|
||||||
private static final String STR_LUABOOLEAN = LuaBoolean.class.getName();
|
private static final String STR_LUABOOLEAN = LuaBoolean.class.getName();
|
||||||
private static final String STR_LUATABLE = LuaTable.class.getName();
|
private static final String STR_LUATABLE = LuaTable.class.getName();
|
||||||
@@ -84,7 +82,6 @@ public class JavaBuilder {
|
|||||||
private static final ObjectType TYPE_LUAVALUE = new ObjectType(STR_LUAVALUE);
|
private static final ObjectType TYPE_LUAVALUE = new ObjectType(STR_LUAVALUE);
|
||||||
private static final ObjectType TYPE_LUASTRING = new ObjectType(STR_LUASTRING);
|
private static final ObjectType TYPE_LUASTRING = new ObjectType(STR_LUASTRING);
|
||||||
private static final ObjectType TYPE_LUAINTEGER = new ObjectType(STR_LUAINTEGER);
|
private static final ObjectType TYPE_LUAINTEGER = new ObjectType(STR_LUAINTEGER);
|
||||||
private static final ObjectType TYPE_LUADOUBLE = new ObjectType(STR_LUADOUBLE);
|
|
||||||
private static final ObjectType TYPE_LUANUMBER = new ObjectType(STR_LUANUMBER);
|
private static final ObjectType TYPE_LUANUMBER = new ObjectType(STR_LUANUMBER);
|
||||||
private static final ObjectType TYPE_LUABOOLEAN = new ObjectType(STR_LUABOOLEAN);
|
private static final ObjectType TYPE_LUABOOLEAN = new ObjectType(STR_LUABOOLEAN);
|
||||||
private static final ObjectType TYPE_LUATABLE = new ObjectType(STR_LUATABLE);
|
private static final ObjectType TYPE_LUATABLE = new ObjectType(STR_LUATABLE);
|
||||||
@@ -92,10 +89,9 @@ public class JavaBuilder {
|
|||||||
|
|
||||||
private static final ArrayType TYPE_LOCALUPVALUE = new ArrayType( TYPE_LUAVALUE, 1 );
|
private static final ArrayType TYPE_LOCALUPVALUE = new ArrayType( TYPE_LUAVALUE, 1 );
|
||||||
private static final ArrayType TYPE_CHARARRAY = new ArrayType( Type.CHAR, 1 );
|
private static final ArrayType TYPE_CHARARRAY = new ArrayType( Type.CHAR, 1 );
|
||||||
|
private static final ArrayType TYPE_LUAVALUEARRAY = new ArrayType( TYPE_LUAVALUE, 1 );
|
||||||
|
|
||||||
|
|
||||||
private static final Class[] NO_INNER_CLASSES = {};
|
|
||||||
|
|
||||||
private static final String STR_FUNCV = VarArgFunction.class.getName();
|
private static final String STR_FUNCV = VarArgFunction.class.getName();
|
||||||
private static final String STR_FUNC0 = ZeroArgFunction.class.getName();
|
private static final String STR_FUNC0 = ZeroArgFunction.class.getName();
|
||||||
private static final String STR_FUNC1 = OneArgFunction.class.getName();
|
private static final String STR_FUNC1 = OneArgFunction.class.getName();
|
||||||
@@ -108,7 +104,6 @@ public class JavaBuilder {
|
|||||||
private static final Type[] ARG_TYPES_DOUBLE = { Type.DOUBLE };
|
private static final Type[] ARG_TYPES_DOUBLE = { Type.DOUBLE };
|
||||||
private static final Type[] ARG_TYPES_STRING = { Type.STRING };
|
private static final Type[] ARG_TYPES_STRING = { Type.STRING };
|
||||||
private static final Type[] ARG_TYPES_CHARARRAY = { TYPE_CHARARRAY };
|
private static final Type[] ARG_TYPES_CHARARRAY = { TYPE_CHARARRAY };
|
||||||
private static final Type[] ARG_TYPES_VARARGS_INT = { TYPE_VARARGS, Type.INT };
|
|
||||||
private static final Type[] ARG_TYPES_INT_LUAVALUE = { Type.INT, TYPE_LUAVALUE };
|
private static final Type[] ARG_TYPES_INT_LUAVALUE = { Type.INT, TYPE_LUAVALUE };
|
||||||
private static final Type[] ARG_TYPES_INT_VARARGS = { Type.INT, TYPE_VARARGS };
|
private static final Type[] ARG_TYPES_INT_VARARGS = { Type.INT, TYPE_VARARGS };
|
||||||
private static final Type[] ARG_TYPES_LUAVALUE_VARARGS = { TYPE_LUAVALUE, TYPE_VARARGS };
|
private static final Type[] ARG_TYPES_LUAVALUE_VARARGS = { TYPE_LUAVALUE, TYPE_VARARGS };
|
||||||
@@ -161,10 +156,12 @@ public class JavaBuilder {
|
|||||||
private final int[] targets;
|
private final int[] targets;
|
||||||
private final BranchInstruction[] branches;
|
private final BranchInstruction[] branches;
|
||||||
private final InstructionHandle[] branchDestHandles;
|
private final InstructionHandle[] branchDestHandles;
|
||||||
|
private final InstructionHandle[] lastInstrHandles;
|
||||||
private InstructionHandle beginningOfLuaInstruction;
|
private InstructionHandle beginningOfLuaInstruction;
|
||||||
|
|
||||||
// hold vararg result
|
// hold vararg result
|
||||||
private LocalVariableGen varresult = null;
|
private LocalVariableGen varresult = null;
|
||||||
|
private int prev_line = -1;
|
||||||
|
|
||||||
public JavaBuilder(ProtoInfo pi, String classname, String filename) {
|
public JavaBuilder(ProtoInfo pi, String classname, String filename) {
|
||||||
this.pi = pi;
|
this.pi = pi;
|
||||||
@@ -220,6 +217,7 @@ public class JavaBuilder {
|
|||||||
targets = new int[nc];
|
targets = new int[nc];
|
||||||
branches = new BranchInstruction[nc];
|
branches = new BranchInstruction[nc];
|
||||||
branchDestHandles = new InstructionHandle[nc];
|
branchDestHandles = new InstructionHandle[nc];
|
||||||
|
lastInstrHandles = new InstructionHandle[nc];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initializeSlots() {
|
public void initializeSlots() {
|
||||||
@@ -339,6 +337,7 @@ public class JavaBuilder {
|
|||||||
|
|
||||||
private Map<Integer,Integer> plainSlotVars = new HashMap<Integer,Integer>();
|
private Map<Integer,Integer> plainSlotVars = new HashMap<Integer,Integer>();
|
||||||
private Map<Integer,Integer> upvalueSlotVars = new HashMap<Integer,Integer>();
|
private Map<Integer,Integer> upvalueSlotVars = new HashMap<Integer,Integer>();
|
||||||
|
private Map<Integer,LocalVariableGen> localVarGenBySlot = new HashMap<Integer,LocalVariableGen>();
|
||||||
private int findSlot( int slot, Map<Integer,Integer> map, String prefix, Type type ) {
|
private int findSlot( int slot, Map<Integer,Integer> map, String prefix, Type type ) {
|
||||||
Integer islot = Integer.valueOf(slot);
|
Integer islot = Integer.valueOf(slot);
|
||||||
if ( map.containsKey(islot) )
|
if ( map.containsKey(islot) )
|
||||||
@@ -347,6 +346,7 @@ public class JavaBuilder {
|
|||||||
LocalVariableGen local = mg.addLocalVariable(name, type, null, null);
|
LocalVariableGen local = mg.addLocalVariable(name, type, null, null);
|
||||||
int index = local.getIndex();
|
int index = local.getIndex();
|
||||||
map.put(islot, Integer.valueOf(index));
|
map.put(islot, Integer.valueOf(index));
|
||||||
|
localVarGenBySlot.put(slot, local);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
private int findSlotIndex( int slot, boolean isupvalue ) {
|
private int findSlotIndex( int slot, boolean isupvalue ) {
|
||||||
@@ -748,11 +748,25 @@ public class JavaBuilder {
|
|||||||
beginningOfLuaInstruction = ih;
|
beginningOfLuaInstruction = ih;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEndOfLuaInstruction(int pc) {
|
public void onEndOfLuaInstruction(int pc, int line) {
|
||||||
branchDestHandles[pc] = beginningOfLuaInstruction;
|
branchDestHandles[pc] = beginningOfLuaInstruction;
|
||||||
|
lastInstrHandles[pc] = main.getEnd();
|
||||||
|
if (line != prev_line)
|
||||||
|
mg.addLineNumber(beginningOfLuaInstruction, prev_line = line);
|
||||||
beginningOfLuaInstruction = null;
|
beginningOfLuaInstruction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVarStartEnd(int slot, int start_pc, int end_pc, String name) {
|
||||||
|
if (localVarGenBySlot.containsKey(slot)) {
|
||||||
|
name = name.replaceAll("[^a-zA-Z0-9]", "_");
|
||||||
|
LocalVariableGen l = localVarGenBySlot.get(slot);
|
||||||
|
l.setEnd(lastInstrHandles[end_pc-1]);
|
||||||
|
if (start_pc > 1)
|
||||||
|
l.setStart(lastInstrHandles[start_pc-2]);
|
||||||
|
l.setName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void resolveBranches() {
|
private void resolveBranches() {
|
||||||
int nc = p.code.length;
|
int nc = p.code.length;
|
||||||
for (int pc = 0; pc < nc; pc++) {
|
for (int pc = 0; pc < nc; pc++) {
|
||||||
@@ -798,7 +812,17 @@ public class JavaBuilder {
|
|||||||
append(factory.createInvoke(STR_BUFFER, "value", TYPE_LUAVALUE, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
|
append(factory.createInvoke(STR_BUFFER, "value", TYPE_LUAVALUE, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeUpvalue(int pc, int i) {
|
public void closeUpvalue(int pc, int upindex) {
|
||||||
// TODO: assign the upvalue location the value null;
|
// TODO: assign the upvalue location the value null;
|
||||||
|
/*
|
||||||
|
boolean isrw = pi.isReadWriteUpvalue( pi.upvals[upindex] );
|
||||||
|
append(InstructionConstants.THIS);
|
||||||
|
append(InstructionConstants.ACONST_NULL);
|
||||||
|
if ( isrw ) {
|
||||||
|
append(factory.createFieldAccess(classname, upvalueName(upindex), TYPE_LUAVALUEARRAY, Constants.PUTFIELD));
|
||||||
|
} else {
|
||||||
|
append(factory.createFieldAccess(classname, upvalueName(upindex), TYPE_LUAVALUE, Constants.PUTFIELD));
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2.luajc;
|
package org.luaj.vm2.luajc;
|
||||||
|
|
||||||
|
import org.luaj.vm2.LocVars;
|
||||||
import org.luaj.vm2.Lua;
|
import org.luaj.vm2.Lua;
|
||||||
import org.luaj.vm2.Prototype;
|
import org.luaj.vm2.Prototype;
|
||||||
import org.luaj.vm2.Upvaldesc;
|
import org.luaj.vm2.Upvaldesc;
|
||||||
@@ -46,6 +47,10 @@ public class JavaGen {
|
|||||||
// build this class
|
// build this class
|
||||||
JavaBuilder builder = new JavaBuilder(pi, classname, filename);
|
JavaBuilder builder = new JavaBuilder(pi, classname, filename);
|
||||||
scanInstructions(pi, classname, builder);
|
scanInstructions(pi, classname, builder);
|
||||||
|
for (int i = 0; i < pi.prototype.locvars.length; ++i) {
|
||||||
|
LocVars l = pi.prototype.locvars[i];
|
||||||
|
builder.setVarStartEnd(i, l.startpc, l.endpc, l.varname.tojstring());
|
||||||
|
}
|
||||||
this.bytecode = builder.completeClass();
|
this.bytecode = builder.completeClass();
|
||||||
|
|
||||||
// build sub-prototypes
|
// build sub-prototypes
|
||||||
@@ -80,8 +85,9 @@ public class JavaGen {
|
|||||||
|
|
||||||
for ( int pc=b0.pc0; pc<=b0.pc1; pc++ ) {
|
for ( int pc=b0.pc0; pc<=b0.pc1; pc++ ) {
|
||||||
|
|
||||||
int pc0 = pc; // closure changes pc
|
final int pc0 = pc; // closure changes pc
|
||||||
int ins = p.code[pc];
|
final int ins = p.code[pc];
|
||||||
|
final int line = pc < p.lineinfo.length? p.lineinfo[pc]: -1;
|
||||||
final int o = Lua.GET_OPCODE(ins);
|
final int o = Lua.GET_OPCODE(ins);
|
||||||
int a = Lua.GETARG_A(ins);
|
int a = Lua.GETARG_A(ins);
|
||||||
int b = Lua.GETARG_B(ins);
|
int b = Lua.GETARG_B(ins);
|
||||||
@@ -420,7 +426,7 @@ public class JavaGen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// let builder process branch instructions
|
// let builder process branch instructions
|
||||||
builder.onEndOfLuaInstruction( pc0 );
|
builder.onEndOfLuaInstruction( pc0, line );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ public class LuaJC implements LuaCompiler {
|
|||||||
|
|
||||||
public LuaFunction load(InputStream stream, String name, LuaValue env) throws IOException {
|
public LuaFunction load(InputStream stream, String name, LuaValue env) throws IOException {
|
||||||
Prototype p = LuaC.instance.compile(stream, name);
|
Prototype p = LuaC.instance.compile(stream, name);
|
||||||
String classname = toStandardJavaClassName( name );
|
|
||||||
String luaname = toStandardLuaFileName( name );
|
String luaname = toStandardLuaFileName( name );
|
||||||
|
String classname = toStandardJavaClassName( luaname );
|
||||||
JavaLoader loader = new JavaLoader();
|
JavaLoader loader = new JavaLoader();
|
||||||
return loader.load(p, classname, luaname, env);
|
return loader.load(p, classname, luaname, env);
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ public class LuaJC implements LuaCompiler {
|
|||||||
private static String toStandardLuaFileName( String luachunkname ) {
|
private static String toStandardLuaFileName( String luachunkname ) {
|
||||||
String stub = toStub( luachunkname );
|
String stub = toStub( luachunkname );
|
||||||
String filename = stub.replace('.','/')+".lua";
|
String filename = stub.replace('.','/')+".lua";
|
||||||
return filename;
|
return filename.startsWith("@")? filename.substring(1): filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String toStub( String s ) {
|
private static String toStub( String s ) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.Iterator;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.script.Bindings;
|
import javax.script.Bindings;
|
||||||
import javax.script.Compilable;
|
import javax.script.Compilable;
|
||||||
@@ -37,6 +37,7 @@ import javax.script.ScriptException;
|
|||||||
import javax.script.SimpleBindings;
|
import javax.script.SimpleBindings;
|
||||||
import javax.script.SimpleScriptContext;
|
import javax.script.SimpleScriptContext;
|
||||||
|
|
||||||
|
import org.luaj.vm2.Globals;
|
||||||
import org.luaj.vm2.LoadState;
|
import org.luaj.vm2.LoadState;
|
||||||
import org.luaj.vm2.Lua;
|
import org.luaj.vm2.Lua;
|
||||||
import org.luaj.vm2.LuaClosure;
|
import org.luaj.vm2.LuaClosure;
|
||||||
@@ -59,7 +60,7 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
|||||||
private static final String __NAME__ = "Luaj";
|
private static final String __NAME__ = "Luaj";
|
||||||
private static final String __SHORT_NAME__ = "Luaj";
|
private static final String __SHORT_NAME__ = "Luaj";
|
||||||
private static final String __LANGUAGE__ = "lua";
|
private static final String __LANGUAGE__ = "lua";
|
||||||
private static final String __LANGUAGE_VERSION__ = "5.1";
|
private static final String __LANGUAGE_VERSION__ = "5.2";
|
||||||
private static final String __ARGV__ = "arg";
|
private static final String __ARGV__ = "arg";
|
||||||
private static final String __FILENAME__ = "?";
|
private static final String __FILENAME__ = "?";
|
||||||
|
|
||||||
@@ -67,12 +68,14 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
|||||||
|
|
||||||
private ScriptContext defaultContext;
|
private ScriptContext defaultContext;
|
||||||
|
|
||||||
private final LuaValue _G;
|
private final Globals _G;
|
||||||
|
|
||||||
public LuaScriptEngine() {
|
public LuaScriptEngine() {
|
||||||
|
|
||||||
// create globals
|
// create globals
|
||||||
_G = JsePlatform.standardGlobals();
|
_G = "true".equals(System.getProperty("luaj.debug"))?
|
||||||
|
JsePlatform.debugGlobals():
|
||||||
|
JsePlatform.standardGlobals();
|
||||||
|
|
||||||
// set up context
|
// set up context
|
||||||
ScriptContext ctx = new SimpleScriptContext();
|
ScriptContext ctx = new SimpleScriptContext();
|
||||||
@@ -88,8 +91,10 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
|||||||
put(FILENAME, __FILENAME__);
|
put(FILENAME, __FILENAME__);
|
||||||
put(NAME, __SHORT_NAME__);
|
put(NAME, __SHORT_NAME__);
|
||||||
put("THREADING", null);
|
put("THREADING", null);
|
||||||
}
|
|
||||||
|
|
||||||
|
// Let globals act as an index metatable
|
||||||
|
_G.set(LuaValue.INDEX, _G);
|
||||||
|
}
|
||||||
|
|
||||||
public Object eval(String script) throws ScriptException {
|
public Object eval(String script) throws ScriptException {
|
||||||
return eval(new StringReader(script));
|
return eval(new StringReader(script));
|
||||||
@@ -162,22 +167,24 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
|||||||
try {
|
try {
|
||||||
InputStream ris = new Utf8Encoder(reader);
|
InputStream ris = new Utf8Encoder(reader);
|
||||||
try {
|
try {
|
||||||
final LuaFunction f = LoadState.load(ris, "script", "bt", null);
|
final LuaFunction f = LoadState.load(ris, "script", "bt", _G);
|
||||||
if ( f.isclosure() ) {
|
if ( f.isclosure() ) {
|
||||||
// most compiled functions are closures with prototypes
|
// most compiled functions are closures with prototypes
|
||||||
final Prototype p = f.checkclosure().p;
|
final Prototype p = f.checkclosure().p;
|
||||||
return new CompiledScriptImpl() {
|
return new CompiledScriptImpl() {
|
||||||
protected LuaFunction newFunctionInstance() {
|
protected LuaFunction newFunctionInstance(LuaTable env) {
|
||||||
return new LuaClosure( p, null );
|
return new LuaClosure( p, env );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// when luajc is used, functions are java class instances
|
// when luajc is used, functions are java class instances
|
||||||
final Class c = f.getClass();
|
final Class c = f.getClass();
|
||||||
return new CompiledScriptImpl() {
|
return new CompiledScriptImpl() {
|
||||||
protected LuaFunction newFunctionInstance() throws ScriptException {
|
protected LuaFunction newFunctionInstance(LuaTable env) throws ScriptException {
|
||||||
try {
|
try {
|
||||||
return (LuaFunction) c.newInstance();
|
LuaFunction f = (LuaFunction) c.newInstance();
|
||||||
|
f.initupvalue1( env );
|
||||||
|
return f;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ScriptException("instantiation failed: "+e.toString());
|
throw new ScriptException("instantiation failed: "+e.toString());
|
||||||
}
|
}
|
||||||
@@ -195,56 +202,45 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract protected class CompiledScriptImpl extends CompiledScript {
|
abstract protected class CompiledScriptImpl extends CompiledScript {
|
||||||
abstract protected LuaFunction newFunctionInstance() throws ScriptException;
|
abstract protected LuaFunction newFunctionInstance(LuaTable env) throws ScriptException;
|
||||||
public ScriptEngine getEngine() {
|
public ScriptEngine getEngine() {
|
||||||
return LuaScriptEngine.this;
|
return LuaScriptEngine.this;
|
||||||
}
|
}
|
||||||
public Object eval(ScriptContext context) throws ScriptException {
|
public Object eval(ScriptContext context) throws ScriptException {
|
||||||
Bindings b = context.getBindings(ScriptContext.ENGINE_SCOPE);
|
Bindings b = context.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||||
LuaFunction f = newFunctionInstance();
|
BindingsGlobals env = new BindingsGlobals(b);
|
||||||
ClientBindings cb = new ClientBindings(b);
|
LuaFunction f = newFunctionInstance(env);
|
||||||
f.initupvalue1(cb.env);
|
try {
|
||||||
Varargs result = f.invoke(LuaValue.NONE);
|
return f.invoke(LuaValue.NONE);
|
||||||
cb.copyGlobalsToBindings();
|
} finally {
|
||||||
return result;
|
env.copyout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ClientBindings {
|
class BindingsGlobals extends Globals {
|
||||||
public final Bindings b;
|
final Bindings b;
|
||||||
public final LuaTable env;
|
BindingsGlobals(Bindings b) {
|
||||||
public ClientBindings( Bindings b ) {
|
|
||||||
this.b = b;
|
this.b = b;
|
||||||
this.env = new LuaTable();
|
this.setmetatable(_G);
|
||||||
env.setmetatable(LuaTable.tableOf(new LuaValue[] { LuaValue.INDEX, _G }));
|
this.debuglib = _G.debuglib;
|
||||||
this.copyBindingsToGlobals();
|
for (Entry<String,Object> e : b.entrySet())
|
||||||
|
rawset(toLua(e.getKey()), toLua(e.getValue()));
|
||||||
}
|
}
|
||||||
public void copyBindingsToGlobals() {
|
void copyout() {
|
||||||
for ( Iterator i = b.keySet().iterator(); i.hasNext(); ) {
|
b.clear();
|
||||||
String key = (String) i.next();
|
for (Varargs v = next(LuaValue.NIL); !v.arg1().isnil(); v = next(v.arg1()))
|
||||||
Object val = b.get(key);
|
b.put(toJava(v.arg1()).toString(), toJava(v.arg(2)));
|
||||||
LuaValue luakey = toLua(key);
|
|
||||||
LuaValue luaval = toLua(val);
|
|
||||||
env.set(luakey, luaval);
|
|
||||||
i.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private LuaValue toLua(Object javaValue) {
|
|
||||||
|
LuaValue toLua(Object javaValue) {
|
||||||
return javaValue == null? LuaValue.NIL:
|
return javaValue == null? LuaValue.NIL:
|
||||||
javaValue instanceof LuaValue? (LuaValue) javaValue:
|
javaValue instanceof LuaValue? (LuaValue) javaValue:
|
||||||
CoerceJavaToLua.coerce(javaValue);
|
CoerceJavaToLua.coerce(javaValue);
|
||||||
}
|
}
|
||||||
public void copyGlobalsToBindings() {
|
|
||||||
LuaValue[] keys = env.keys();
|
Object toJava(LuaValue v) {
|
||||||
for ( int i=0; i<keys.length; i++ ) {
|
|
||||||
LuaValue luakey = keys[i];
|
|
||||||
LuaValue luaval = env.get(luakey);
|
|
||||||
String key = luakey.tojstring();
|
|
||||||
Object val = toJava( luaval );
|
|
||||||
b.put(key,val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private Object toJava(LuaValue v) {
|
|
||||||
switch ( v.type() ) {
|
switch ( v.type() ) {
|
||||||
case LuaValue.TNIL: return null;
|
case LuaValue.TNIL: return null;
|
||||||
case LuaValue.TSTRING: return v.tojstring();
|
case LuaValue.TSTRING: return v.tojstring();
|
||||||
@@ -253,7 +249,6 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
|||||||
default: return v;
|
default: return v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ------ convert char stream to byte stream for lua compiler -----
|
// ------ convert char stream to byte stream for lua compiler -----
|
||||||
|
|
||||||
|
|||||||
@@ -21,75 +21,64 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.luajc;
|
package org.luaj.luajc;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.Globals;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.Print;
|
import org.luaj.vm2.Print;
|
||||||
import org.luaj.vm2.Prototype;
|
import org.luaj.vm2.Prototype;
|
||||||
import org.luaj.vm2.Varargs;
|
import org.luaj.vm2.Varargs;
|
||||||
import org.luaj.vm2.compiler.LuaC;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||||
import org.luaj.vm2.luajc.LuaJC;
|
import org.luaj.vm2.luajc.LuaJC;
|
||||||
|
|
||||||
public class TestLuaJC {
|
public class TestLuaJC {
|
||||||
// create the script
|
// This file will be loaded using the FINDER as a resource, provided it is in the
|
||||||
public static String name = "script";
|
// build path. This allows the debugger to find the file when stepping into the function.
|
||||||
public static String script =
|
public static String filename = "perf/nsieve.lua";
|
||||||
"function f1(a) print( 'f1:', a ) return a end\n" +
|
|
||||||
"b = f1()\n" +
|
static Globals _G;
|
||||||
"return b";
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
System.out.println(script);
|
System.out.println("filename: "+filename);
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// create an environment to run in
|
// create an environment to run in
|
||||||
LuaTable _G = JsePlatform.standardGlobals();
|
_G = JsePlatform.standardGlobals();
|
||||||
System.out.println("_G: "+_G);
|
|
||||||
System.out.println("_G.print: "+_G.get("print"));
|
|
||||||
|
|
||||||
// print the chunk as a closure
|
// print the chunk as a closure, and pretty-print the closure.
|
||||||
byte[] bytes = script.getBytes();
|
LuaValue f = _G.loadFile(filename).arg1();
|
||||||
LuaValue chunk = LuaC.instance.load(new ByteArrayInputStream(bytes), "script", _G);
|
Prototype p = f.checkclosure().p;
|
||||||
Prototype p = chunk.checkclosure().p;
|
|
||||||
Print.print(p);
|
Print.print(p);
|
||||||
|
|
||||||
// compile into a luajc chunk, or load as a class
|
// load into a luajc java-bytecode based chunk by installing the LuaJC compiler first
|
||||||
if ( ! (args.length>0 && args[0].equals("nocompile")) ) {
|
if ( ! (args.length>0 && args[0].equals("nocompile")) ) {
|
||||||
chunk = LuaJC.getInstance().load(new ByteArrayInputStream(bytes), "script", _G);
|
LuaJC.install();
|
||||||
} else {
|
f = _G.loadFile(filename).arg1();
|
||||||
chunk = (LuaValue) Class.forName("script").newInstance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// call with arguments
|
// call with arguments
|
||||||
LuaValue[] vargs = new LuaValue[args.length];
|
Varargs v = f.invoke(LuaValue.NONE);
|
||||||
for ( int i=0; i<args.length; i++ )
|
|
||||||
vargs[i] = LuaValue.valueOf(args[i]);
|
|
||||||
Varargs cargs = LuaValue.varargsOf(vargs);
|
|
||||||
Varargs v = chunk.invoke(cargs);
|
|
||||||
|
|
||||||
// print the result
|
// print the result
|
||||||
for ( int i=1; i<=v.narg(); i++ )
|
System.out.println("result: "+v);
|
||||||
System.out.println("result["+i+"]: "+v.arg(i));
|
|
||||||
|
// Write out the files.
|
||||||
|
// saveClasses();
|
||||||
|
|
||||||
} catch ( Throwable e ) {
|
} catch ( Throwable e ) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
saveClasses();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void saveClasses() throws Exception {
|
private static void saveClasses() throws Exception {
|
||||||
// create the chunk
|
// create the chunk
|
||||||
String chunkname = "script";
|
|
||||||
String filename = "script";
|
|
||||||
String destdir = ".";
|
String destdir = ".";
|
||||||
|
|
||||||
InputStream is = new ByteArrayInputStream( script.getBytes() );
|
InputStream is = _G.FINDER.findResource(filename);
|
||||||
Hashtable t = LuaJC.getInstance().compileAll(is, chunkname, filename);
|
Hashtable t = LuaJC.getInstance().compileAll(is, filename, filename);
|
||||||
|
|
||||||
// write out the chunk
|
// write out the chunk
|
||||||
for ( Enumeration e = t.keys(); e.hasMoreElements(); ) {
|
for ( Enumeration e = t.keys(); e.hasMoreElements(); ) {
|
||||||
@@ -97,7 +86,7 @@ public class TestLuaJC {
|
|||||||
byte[] bytes = (byte[]) t.get(key);
|
byte[] bytes = (byte[]) t.get(key);
|
||||||
String destpath = (destdir!=null? destdir+"/": "") + key + ".class";
|
String destpath = (destdir!=null? destdir+"/": "") + key + ".class";
|
||||||
System.out.println(
|
System.out.println(
|
||||||
"chunk "+chunkname+
|
"chunk "+filename+
|
||||||
" from "+filename+
|
" from "+filename+
|
||||||
" written to "+destpath
|
" written to "+destpath
|
||||||
+" length="+bytes.length+" bytes");
|
+" length="+bytes.length+" bytes");
|
||||||
|
|||||||
Reference in New Issue
Block a user