Expand compiler interface, add bcel-based bytecode generator.
This commit is contained in:
@@ -15,5 +15,6 @@
|
||||
<classpathentry kind="var" path="ANTLR_HOME"/>
|
||||
<classpathentry kind="var" path="WTK_HOME/lib/cldcapi11.jar"/>
|
||||
<classpathentry kind="var" path="WTK_HOME/lib/midpapi20.jar"/>
|
||||
<classpathentry kind="var" path="BCEL_LIB"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
@@ -39,8 +39,7 @@ public class LoadState {
|
||||
/** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */
|
||||
public static final int NUMBER_FORMAT_NUM_PATCH_INT32 = 4;
|
||||
|
||||
// type constants
|
||||
|
||||
// type constants
|
||||
public static final int LUA_TINT = (-2);
|
||||
public static final int LUA_TNONE = (-1);
|
||||
public static final int LUA_TNIL = 0;
|
||||
@@ -56,7 +55,10 @@ public class LoadState {
|
||||
|
||||
/** Interface for the compiler, if it is installed. */
|
||||
public interface LuaCompiler {
|
||||
/** Compile into a prototype, without taking the additional step of create a LuaFunction or LuaClosure */
|
||||
public Prototype compile(int firstByte, InputStream stream, String name) throws IOException;
|
||||
/** Load into a Closure or LuaFunction, with the supplied initial environment */
|
||||
public LuaFunction load(int firstByte, InputStream stream, String name, LuaValue env) throws IOException;
|
||||
}
|
||||
|
||||
/** Compiler instance, if installed */
|
||||
@@ -266,12 +268,11 @@ public class LoadState {
|
||||
luacNumberFormat = is.readByte();
|
||||
}
|
||||
|
||||
public static Prototype undump( InputStream stream, String name ) throws IOException {
|
||||
// check first byte to see if its a precompiled chunk
|
||||
public static LuaFunction load( InputStream stream, String name, LuaValue env ) throws IOException {
|
||||
int c = stream.read();
|
||||
if ( c != LUA_SIGNATURE[0] ) {
|
||||
if ( compiler != null )
|
||||
return compiler.compile(c, stream, name);
|
||||
return compiler.load(c, stream, name, env);
|
||||
throw new LuaError("no compiler");
|
||||
}
|
||||
|
||||
@@ -296,7 +297,8 @@ public class LoadState {
|
||||
throw new LuaError("unsupported int size");
|
||||
}
|
||||
|
||||
return s.loadFunction( LuaString.valueOf(sname) );
|
||||
Prototype p = s.loadFunction( LuaString.valueOf(sname) );
|
||||
return new LuaClosure( p, env );
|
||||
}
|
||||
|
||||
public static String getSourceName(String name) {
|
||||
|
||||
@@ -310,6 +310,7 @@ public class LuaValue extends Varargs {
|
||||
|
||||
// table initializers
|
||||
public static LuaTable tableOf() { return new LuaTable(); }
|
||||
public static LuaTable tableOf(int narray, int nhash) { return new LuaTable(narray, nhash); }
|
||||
public static LuaTable listOf(LuaValue[] unnamedValues) { return new LuaTable(null,unnamedValues,null); }
|
||||
public static LuaTable listOf(LuaValue[] unnamedValues,Varargs lastarg) { return new LuaTable(null,unnamedValues,lastarg); }
|
||||
public static LuaTable tableOf(LuaValue[] namedValues) { return new LuaTable(namedValues,null,null); }
|
||||
|
||||
@@ -299,7 +299,11 @@ public class Print extends Lua {
|
||||
}
|
||||
}
|
||||
|
||||
public void printFunction(Prototype f, boolean full) {
|
||||
public static void print(Prototype p) {
|
||||
printFunction(p, true);
|
||||
}
|
||||
|
||||
public static void printFunction(Prototype f, boolean full) {
|
||||
int i, n = f.p.length;
|
||||
printHeader(f);
|
||||
printCode(f);
|
||||
|
||||
@@ -27,10 +27,12 @@ import java.util.Hashtable;
|
||||
|
||||
import org.luaj.vm2.LocVars;
|
||||
import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.LuaClosure;
|
||||
import org.luaj.vm2.LuaError;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.LuaString;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.LoadState.LuaCompiler;
|
||||
|
||||
|
||||
@@ -158,8 +160,19 @@ public class LuaC extends Lua implements LuaCompiler {
|
||||
|
||||
/** Utility method to invoke the compiler for an input stream
|
||||
*/
|
||||
public static Prototype compile(InputStream is, String string) throws IOException {
|
||||
return new LuaC().compile(is.read(), is, string);
|
||||
public static Prototype compile(InputStream is, String name) throws IOException {
|
||||
return new LuaC().compile(is.read(), is, name);
|
||||
}
|
||||
|
||||
/** Load into a Closure or LuaFunction, with the supplied initial environment */
|
||||
public static LuaFunction load(InputStream is, String name, LuaValue env) throws IOException {
|
||||
return new LuaC().load(is.read(), is, name, env);
|
||||
}
|
||||
|
||||
/** Load into a Closure or LuaFunction, with the supplied initial environment */
|
||||
public LuaFunction load(int firstByte, InputStream stream, String name, LuaValue env) throws IOException {
|
||||
Prototype p = compile(firstByte, stream, name);
|
||||
return new LuaClosure( p, env );
|
||||
}
|
||||
|
||||
/** Compile source bytes into a LPrototype.
|
||||
|
||||
@@ -222,8 +222,7 @@ public class BaseLib extends LuaTable implements ResourceFinder {
|
||||
try {
|
||||
LuaValue func = args.checkfunction(1);
|
||||
String chunkname = args.optString(2, "function");
|
||||
Prototype p = LoadState.undump(new StringInputStream(func), chunkname);
|
||||
return new LuaClosure(p,LuaThread.getRunningEnv(env));
|
||||
return LoadState.load(new StringInputStream(func), chunkname, LuaThread.getRunningEnv(env));
|
||||
} catch ( Exception e ) {
|
||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||
}
|
||||
@@ -240,8 +239,7 @@ public class BaseLib extends LuaTable implements ResourceFinder {
|
||||
try {
|
||||
LuaString script = args.checkstring(1);
|
||||
LuaString chunkname = args.optstring(2, script);
|
||||
Prototype p = LoadState.undump(script.toInputStream(), chunkname.toString());
|
||||
return new LuaClosure(p,LuaThread.getRunningEnv(env));
|
||||
return LoadState.load(script.toInputStream(), chunkname.toString(),LuaThread.getRunningEnv(env));
|
||||
} catch ( Exception e ) {
|
||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||
}
|
||||
@@ -344,8 +342,7 @@ public class BaseLib extends LuaTable implements ResourceFinder {
|
||||
if ( is == null )
|
||||
return varargsOf(NIL, valueOf("not found: "+filename));
|
||||
try {
|
||||
Prototype p = LoadState.undump(is, filename);
|
||||
return new LuaClosure(p,LuaThread.getRunningEnv(env));
|
||||
return LoadState.load(is, filename, LuaThread.getRunningEnv(env));
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
|
||||
@@ -29,9 +29,8 @@ import java.io.InputStreamReader;
|
||||
|
||||
import org.luaj.vm2.LoadState;
|
||||
import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.LuaClosure;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
import org.luaj.vm2.lib.DebugLib;
|
||||
import org.luaj.vm2.lib.JsePlatform;
|
||||
@@ -167,10 +166,9 @@ public class lua {
|
||||
|
||||
private static void processScript( InputStream script, String chunkname, String[] args, int offset ) throws IOException {
|
||||
try {
|
||||
LuaClosure c;
|
||||
LuaFunction c;
|
||||
try {
|
||||
Prototype p = LoadState.undump(script, chunkname );
|
||||
c = new LuaClosure(p,_G);
|
||||
c = LoadState.load(script, chunkname, _G);
|
||||
} finally {
|
||||
script.close();
|
||||
}
|
||||
|
||||
83
src/jse/org/luaj/vm2/luajc/JavaBytecodeCompiler.java
Normal file
83
src/jse/org/luaj/vm2/luajc/JavaBytecodeCompiler.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2.luajc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.luaj.vm2.LoadState;
|
||||
import org.luaj.vm2.LuaClosure;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.LoadState.LuaCompiler;
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
|
||||
public class JavaBytecodeCompiler implements LuaCompiler {
|
||||
|
||||
private static JavaBytecodeCompiler instance;
|
||||
private JavaBytecodeGenerator gen;
|
||||
private LuaC luac;
|
||||
|
||||
public static JavaBytecodeCompiler getInstance() {
|
||||
if ( instance == null )
|
||||
instance = new JavaBytecodeCompiler();
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the compiler as the main compiler to use.
|
||||
* Will fall back to the LuaC prototype compiler.
|
||||
*/
|
||||
public static final void install() {
|
||||
LoadState.compiler = getInstance();
|
||||
}
|
||||
|
||||
private JavaBytecodeCompiler() {
|
||||
luac = new LuaC();
|
||||
gen = new JavaBytecodeGenerator();
|
||||
}
|
||||
|
||||
/** Compile into protoype form. */
|
||||
public Prototype compile(int firstByte, InputStream stream, String name) throws IOException {
|
||||
return luac.compile(firstByte, stream, name);
|
||||
}
|
||||
|
||||
/** Compile into class form. */
|
||||
public LuaFunction load(int firstByte, InputStream stream, String name, LuaValue env) throws IOException {
|
||||
Prototype p = compile( firstByte, stream, name);
|
||||
try {
|
||||
System.out.println("compiling "+name);
|
||||
Class c = gen.toJavaBytecode(p, name);
|
||||
Object o = c.newInstance();
|
||||
System.out.println("instance is: "+o);
|
||||
LuaFunction f = (LuaFunction) o;
|
||||
f.setfenv(env);
|
||||
return f;
|
||||
} catch ( Throwable t ) {
|
||||
t.printStackTrace();
|
||||
return new LuaClosure( p, env );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
1051
src/jse/org/luaj/vm2/luajc/JavaBytecodeGenerator.java
Normal file
1051
src/jse/org/luaj/vm2/luajc/JavaBytecodeGenerator.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@ import org.luaj.vm2.LoadState;
|
||||
import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.LuaClosure;
|
||||
import org.luaj.vm2.LuaError;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
@@ -165,18 +166,41 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
||||
try {
|
||||
InputStream ris = new Utf8Encoder(reader);
|
||||
try {
|
||||
final Prototype p = LoadState.undump(ris, "script");
|
||||
return new CompiledScript() {
|
||||
public Object eval(ScriptContext context) throws ScriptException {
|
||||
Bindings b = context.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
LuaBindings lb = (LuaBindings) b;
|
||||
LuaClosure c = new LuaClosure( p, lb.env );
|
||||
return c.call();
|
||||
}
|
||||
public ScriptEngine getEngine() {
|
||||
return LuaScriptEngine.this;
|
||||
}
|
||||
};
|
||||
final LuaFunction f = LoadState.load(ris, "script", null);
|
||||
if ( f.isclosure() ) {
|
||||
LuaClosure c = f.checkclosure();
|
||||
final Prototype p = c.p;
|
||||
return new CompiledScript() {
|
||||
public Object eval(ScriptContext context) throws ScriptException {
|
||||
Bindings b = context.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
LuaBindings lb = (LuaBindings) b;
|
||||
LuaClosure c = new LuaClosure( p, lb.env );
|
||||
return c.invoke(LuaValue.NONE);
|
||||
}
|
||||
public ScriptEngine getEngine() {
|
||||
return LuaScriptEngine.this;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
final Class c = f.getClass();
|
||||
return new CompiledScript() {
|
||||
public Object eval(ScriptContext context) throws ScriptException {
|
||||
Bindings b = context.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
LuaBindings lb = (LuaBindings) b;
|
||||
LuaFunction lf;
|
||||
try {
|
||||
lf = (LuaFunction) c.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new ScriptException("instantiation failed: "+e.toString());
|
||||
}
|
||||
lf.setfenv(lb.env);
|
||||
return lf.invoke(LuaValue.NONE);
|
||||
}
|
||||
public ScriptEngine getEngine() {
|
||||
return LuaScriptEngine.this;
|
||||
}
|
||||
};
|
||||
}
|
||||
} catch ( LuaError lee ) {
|
||||
throw new ScriptException(lee.getMessage() );
|
||||
} finally {
|
||||
|
||||
@@ -57,7 +57,6 @@ public class AllTests {
|
||||
// luajc regression tests
|
||||
TestSuite luajc = new TestSuite("Luajc Tests");
|
||||
luajc.addTestSuite(FragmentsTest.class);
|
||||
luajc.addTest( new TestSuite( LuaJCCompatibilityTest.class, "LuaJC Compatiblity Tests" ) );
|
||||
suite.addTest(luajc);
|
||||
|
||||
return suite;
|
||||
|
||||
@@ -24,6 +24,8 @@ package org.luaj.vm2;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.luaj.vm2.luajc.JavaBytecodeCompiler;
|
||||
|
||||
/**
|
||||
* Compatibility tests for the Luaj VM
|
||||
*
|
||||
@@ -59,6 +61,8 @@ public class CompatibiltyTest {
|
||||
TestSuite suite = new TestSuite("Compatibility Tests");
|
||||
suite.addTest( new TestSuite( JseCompatibilityTest.class, "JSE Tests" ) );
|
||||
suite.addTest( new TestSuite( JmeCompatibilityTest.class, "JME Tests" ) );
|
||||
suite.addTest( new TestSuite( JseBytecodeTest.class, "JSE Bytecode Tests" ) );
|
||||
suite.addTest( new TestSuite( LuaJCCompatibilityTest.class, "LuaJC Gen Tests" ) );
|
||||
return suite;
|
||||
}
|
||||
|
||||
@@ -76,8 +80,18 @@ public class CompatibiltyTest {
|
||||
super(ScriptDrivenTest.PlatformType.JSE);
|
||||
}
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("JME", "false");
|
||||
super.setUp();
|
||||
System.setProperty("JME", "false");
|
||||
}
|
||||
}
|
||||
public static class JseBytecodeTest extends CompatibiltyTestSuite {
|
||||
public JseBytecodeTest() {
|
||||
super(ScriptDrivenTest.PlatformType.JSE);
|
||||
}
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
System.setProperty("JME", "false");
|
||||
JavaBytecodeCompiler.install();
|
||||
}
|
||||
}
|
||||
public static class LuaJCCompatibilityTest extends CompatibiltyTestSuite {
|
||||
@@ -85,8 +99,8 @@ public class CompatibiltyTest {
|
||||
super(ScriptDrivenTest.PlatformType.LUAJIT);
|
||||
}
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("JME", "false");
|
||||
super.setUp();
|
||||
System.setProperty("JME", "false");
|
||||
}
|
||||
// skipping - not supported yet
|
||||
public void testDebugLib() {}
|
||||
|
||||
@@ -31,9 +31,7 @@ import java.io.PrintStream;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
import org.luaj.vm2.lib.BaseLib;
|
||||
import org.luaj.vm2.lib.CoroutineLib;
|
||||
import org.luaj.vm2.lib.DebugLib;
|
||||
import org.luaj.vm2.luajc.LuaJCompiler;
|
||||
|
||||
@@ -58,7 +56,6 @@ public class ScriptDrivenTest extends TestCase {
|
||||
try {
|
||||
|
||||
// create globals
|
||||
LuaC.install();
|
||||
LuaTable _G = null;
|
||||
switch ( platform ) {
|
||||
default:
|
||||
@@ -120,8 +117,7 @@ public class ScriptDrivenTest extends TestCase {
|
||||
}
|
||||
default:
|
||||
script = new FileInputStream(file);
|
||||
Prototype p = LoadState.undump(script, "stdin");
|
||||
return new LuaClosure(p,_G);
|
||||
return LoadState.load(script, "stdin", _G);
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
|
||||
Reference in New Issue
Block a user