Add Compilable interface to LuaScriptEngine and implement it
This commit is contained in:
@@ -21,13 +21,19 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.script;
|
package org.luaj.script;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.LineNumberInputStream;
|
import java.io.LineNumberInputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringReader;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.script.Bindings;
|
import javax.script.Bindings;
|
||||||
|
import javax.script.Compilable;
|
||||||
|
import javax.script.CompiledScript;
|
||||||
import javax.script.ScriptContext;
|
import javax.script.ScriptContext;
|
||||||
import javax.script.ScriptEngine;
|
import javax.script.ScriptEngine;
|
||||||
import javax.script.ScriptEngineFactory;
|
import javax.script.ScriptEngineFactory;
|
||||||
@@ -41,6 +47,7 @@ import org.luaj.vm.LClosure;
|
|||||||
import org.luaj.vm.LDouble;
|
import org.luaj.vm.LDouble;
|
||||||
import org.luaj.vm.LFunction;
|
import org.luaj.vm.LFunction;
|
||||||
import org.luaj.vm.LInteger;
|
import org.luaj.vm.LInteger;
|
||||||
|
import org.luaj.vm.LNil;
|
||||||
import org.luaj.vm.LPrototype;
|
import org.luaj.vm.LPrototype;
|
||||||
import org.luaj.vm.LString;
|
import org.luaj.vm.LString;
|
||||||
import org.luaj.vm.LTable;
|
import org.luaj.vm.LTable;
|
||||||
@@ -56,9 +63,9 @@ import org.luaj.vm.Platform;
|
|||||||
*
|
*
|
||||||
* @author jim_roseborough
|
* @author jim_roseborough
|
||||||
*/
|
*/
|
||||||
public class LuaScriptEngine extends LFunction implements ScriptEngine {
|
public class LuaScriptEngine extends LFunction implements ScriptEngine, Compilable {
|
||||||
|
|
||||||
private static final String __ENGINE_VERSION__ = "V0.28";
|
private static final String __ENGINE_VERSION__ = "V0.39";
|
||||||
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";
|
||||||
@@ -78,7 +85,10 @@ public class LuaScriptEngine extends LFunction implements ScriptEngine {
|
|||||||
private final LuaState luaState;
|
private final LuaState luaState;
|
||||||
|
|
||||||
public LuaScriptEngine() {
|
public LuaScriptEngine() {
|
||||||
|
|
||||||
|
// set up context
|
||||||
setContext(new SimpleScriptContext());
|
setContext(new SimpleScriptContext());
|
||||||
|
|
||||||
// set special values
|
// set special values
|
||||||
put(LANGUAGE_VERSION, __LANGUAGE_VERSION__);
|
put(LANGUAGE_VERSION, __LANGUAGE_VERSION__);
|
||||||
put(LANGUAGE, __LANGUAGE__);
|
put(LANGUAGE, __LANGUAGE__);
|
||||||
@@ -89,7 +99,7 @@ public class LuaScriptEngine extends LFunction implements ScriptEngine {
|
|||||||
put(NAME, __SHORT_NAME__);
|
put(NAME, __SHORT_NAME__);
|
||||||
put("THREADING", null);
|
put("THREADING", null);
|
||||||
|
|
||||||
// set lua state
|
// create lua state
|
||||||
luaState = Platform.getInstance().newLuaState();
|
luaState = Platform.getInstance().newLuaState();
|
||||||
|
|
||||||
// connect up to bindings
|
// connect up to bindings
|
||||||
@@ -101,47 +111,32 @@ public class LuaScriptEngine extends LFunction implements ScriptEngine {
|
|||||||
|
|
||||||
|
|
||||||
public Object eval(String script) throws ScriptException {
|
public Object eval(String script) throws ScriptException {
|
||||||
return eval(script, getContext());
|
return eval(new StringReader(script));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object eval(String script, ScriptContext context) throws ScriptException {
|
public Object eval(String script, ScriptContext context) throws ScriptException {
|
||||||
try {
|
return eval(new StringReader(script), context);
|
||||||
byte[] bytes = script.getBytes("UTF-8");
|
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
|
|
||||||
LineNumberInputStream is = new LineNumberInputStream( bais );
|
|
||||||
try {
|
|
||||||
LPrototype p = LoadState.undump(luaState, is, "script");
|
|
||||||
LClosure c = p.newClosure( luaState._G );
|
|
||||||
luaState.doCall( c, new LValue[0] );
|
|
||||||
return luaState.topointer(1);
|
|
||||||
} catch ( LuaErrorException lee ) {
|
|
||||||
throw new ScriptException(lee.getMessage(), "script", is.getLineNumber() );
|
|
||||||
} finally {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
} catch ( Throwable t ) {
|
|
||||||
throw new ScriptException("eval threw "+t.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object eval(String script, Bindings bindings) throws ScriptException {
|
public Object eval(String script, Bindings bindings) throws ScriptException {
|
||||||
Bindings current = getContext().getBindings(ScriptContext.ENGINE_SCOPE);
|
return eval(new StringReader(script), bindings);
|
||||||
getContext().setBindings(bindings, ScriptContext.ENGINE_SCOPE);
|
|
||||||
Object result = eval(script);
|
|
||||||
getContext().setBindings(current, ScriptContext.ENGINE_SCOPE);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object eval(Reader reader) throws ScriptException {
|
public Object eval(Reader reader) throws ScriptException {
|
||||||
return eval(getScriptFromReader(reader));
|
return eval(reader, getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object eval(Reader reader, ScriptContext scriptContext) throws ScriptException {
|
public Object eval(Reader reader, ScriptContext scriptContext) throws ScriptException {
|
||||||
return eval(getScriptFromReader(reader), scriptContext);
|
return compile(reader).eval(scriptContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object eval(Reader reader, Bindings bindings) throws ScriptException {
|
public Object eval(Reader reader, Bindings bindings) throws ScriptException {
|
||||||
return eval(getScriptFromReader(reader), bindings);
|
ScriptContext c = getContext();
|
||||||
|
Bindings current = c.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||||
|
c.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
|
||||||
|
Object result = eval(reader);
|
||||||
|
c.setBindings(current, ScriptContext.ENGINE_SCOPE);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(String key, Object value) {
|
public void put(String key, Object value) {
|
||||||
@@ -176,20 +171,20 @@ public class LuaScriptEngine extends LFunction implements ScriptEngine {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void luaSetTable(LuaState vm, LValue table, LValue key, LValue val) {
|
public LValue __index(LuaState vm, LValue table, LValue key) {
|
||||||
Bindings b = getBindings(ScriptContext.ENGINE_SCOPE);
|
|
||||||
String k = key.toJavaString();
|
|
||||||
Object v = (val.isNil()? null: val);
|
|
||||||
b.put(k,v);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LValue luaGetTable(LuaState vm, LValue table, LValue key) {
|
|
||||||
Bindings b = getBindings(ScriptContext.ENGINE_SCOPE);
|
Bindings b = getBindings(ScriptContext.ENGINE_SCOPE);
|
||||||
String k = key.toJavaString();
|
String k = key.toJavaString();
|
||||||
Object v = b.get(k);
|
Object v = b.get(k);
|
||||||
return (LValue) v;
|
return (LValue) v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void __newindex(LuaState vm, LValue table, LValue key, LValue val) {
|
||||||
|
Bindings b = getBindings(ScriptContext.ENGINE_SCOPE);
|
||||||
|
String k = key.toJavaString();
|
||||||
|
Object v = (val.isNil()? null: val);
|
||||||
|
b.put(k,v);
|
||||||
|
}
|
||||||
|
|
||||||
public Bindings getBindings(int scope) {
|
public Bindings getBindings(int scope) {
|
||||||
return getContext().getBindings(scope);
|
return getContext().getBindings(scope);
|
||||||
}
|
}
|
||||||
@@ -214,21 +209,60 @@ public class LuaScriptEngine extends LFunction implements ScriptEngine {
|
|||||||
return myFactory;
|
return myFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public CompiledScript compile(String script) throws ScriptException {
|
||||||
* private methods
|
return compile(new StringReader(script));
|
||||||
*/
|
}
|
||||||
|
|
||||||
private static String getScriptFromReader(Reader reader) {
|
public CompiledScript compile(Reader reader) throws ScriptException {
|
||||||
try {
|
try {
|
||||||
StringWriter script = new StringWriter();
|
InputStream ris = new Utf8Encoder(reader);
|
||||||
int data;
|
LineNumberInputStream is = new LineNumberInputStream( ris);
|
||||||
while ((data = reader.read()) != -1) {
|
try {
|
||||||
script.write(data);
|
final LPrototype p = LoadState.undump(luaState, is, "script");
|
||||||
|
return new CompiledScript() {
|
||||||
|
public Object eval(ScriptContext context) throws ScriptException {
|
||||||
|
LClosure c = p.newClosure( luaState._G );
|
||||||
|
luaState.doCall( c, new LValue[0] );
|
||||||
|
return luaState.topointer(1);
|
||||||
|
}
|
||||||
|
public ScriptEngine getEngine() {
|
||||||
|
return LuaScriptEngine.this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch ( LuaErrorException lee ) {
|
||||||
|
throw new ScriptException(lee.getMessage(), "script", is.getLineNumber() );
|
||||||
|
} finally {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
} catch ( Throwable t ) {
|
||||||
|
throw new ScriptException("eval threw "+t.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class Utf8Encoder extends InputStream {
|
||||||
|
private final Reader r;
|
||||||
|
private final int[] buf = new int[2];
|
||||||
|
private int n;
|
||||||
|
|
||||||
|
private Utf8Encoder(Reader r) {
|
||||||
|
this.r = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
if ( n > 0 )
|
||||||
|
return buf[--n];
|
||||||
|
int c = r.read();
|
||||||
|
if ( c < 0x80 )
|
||||||
|
return c;
|
||||||
|
n = 0;
|
||||||
|
if ( c < 0x800 ) {
|
||||||
|
buf[n++] = (0x80 | ( c & 0x3f));
|
||||||
|
return (0xC0 | ((c>>6) & 0x1f));
|
||||||
|
} else {
|
||||||
|
buf[n++] = (0x80 | ( c & 0x3f));
|
||||||
|
buf[n++] = (0x80 | ((c>>6) & 0x3f));
|
||||||
|
return (0xE0 | ((c>>12) & 0x0f));
|
||||||
}
|
}
|
||||||
script.flush();
|
|
||||||
return script.toString();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user