Expand compiler interface, add bcel-based bytecode generator.

This commit is contained in:
James Roseborough
2009-10-29 22:20:56 +00:00
parent 0b6cd02bc6
commit f729c1b626
13 changed files with 1224 additions and 41 deletions

View File

@@ -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();
}

View 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 );
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 {