Refactor API's related to compiling and loading scripts and character encoding handling.

This commit is contained in:
James Roseborough
2013-09-18 05:32:30 +00:00
parent a552494b72
commit 2123d3f924
35 changed files with 489 additions and 293 deletions

View File

@@ -56,6 +56,7 @@ public class lua {
" -b use luajc bytecode-to-bytecode compiler (requires bcel on class path)\n" +
" -n nodebug - do not load debug library by default\n" +
" -p print the prototype\n" +
" -c enc use the supplied encoding 'enc' for input files\n" +
" -- stop handling options\n" +
" - execute stdin and stop handling options";
@@ -66,6 +67,7 @@ public class lua {
private static Globals _G;
private static boolean print = false;
private static String encoding = null;
public static void main( String[] args ) throws IOException {
@@ -113,6 +115,11 @@ public class lua {
case 'p':
print = true;
break;
case 'c':
if ( ++i >= args.length )
usageExit();
encoding = args[i];
break;
case '-':
if ( args[i].length() > 2 )
usageExit();
@@ -131,7 +138,7 @@ public class lua {
// new lua state
_G = nodebug? JsePlatform.standardGlobals(): JsePlatform.debugGlobals();
if ( luajc ) LuaJC.install();
if ( luajc ) LuaJC.install(_G);
for ( int i=0, n=libs!=null? libs.size(): 0; i<n; i++ )
loadLibrary( (String) libs.elementAt(i) );
@@ -147,6 +154,7 @@ public class lua {
} else {
switch ( args[i].charAt(1) ) {
case 'l':
case 'c':
++i;
break;
case 'e':
@@ -187,9 +195,11 @@ public class lua {
private static void processScript( InputStream script, String chunkname, String[] args, int firstarg ) throws IOException {
try {
LuaFunction c;
LuaValue c;
try {
c = LoadState.load(script, chunkname, "bt", _G);
c = encoding != null?
_G.load(new InputStreamReader(script, encoding), chunkname):
_G.load(script, chunkname, "bt", _G);
} finally {
script.close();
}

View File

@@ -24,13 +24,14 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import org.luaj.vm2.Globals;
import org.luaj.vm2.Lua;
import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.compiler.DumpState;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.jse.JsePlatform;
@@ -51,6 +52,7 @@ public class luac {
" -e little endian format for numbers\n" +
" -i<n> number format 'n', (n=0,1 or 4, default="+DumpState.NUMBER_FORMAT_DEFAULT+")\n" +
" -v show version information\n" +
" -c enc use the supplied encoding 'enc' for input files\n" +
" -- stop handling options\n";
private static void usageExit() {
@@ -66,6 +68,7 @@ public class luac {
private int numberformat = DumpState.NUMBER_FORMAT_DEFAULT;
private boolean versioninfo = false;
private boolean processing = true;
private String encoding = null;
public static void main( String[] args ) throws IOException {
new luac( args );
@@ -108,6 +111,11 @@ public class luac {
case 'v':
versioninfo = true;
break;
case 'c':
if ( ++i >= args.length )
usageExit();
encoding = args[i];
break;
case '-':
if ( args[i].length() > 2 )
usageExit();
@@ -129,17 +137,18 @@ public class luac {
// process input files
try {
JsePlatform.standardGlobals();
Globals globals = JsePlatform.standardGlobals();
processing = true;
for ( int i=0; i<args.length; i++ ) {
if ( ! processing || ! args[i].startsWith("-") ) {
String chunkname = args[i].substring(0,args[i].length()-4);
processScript( new FileInputStream(args[i]), chunkname, fos );
processScript( globals, new FileInputStream(args[i]), chunkname, fos );
} else if ( args[i].length() <= 1 ) {
processScript( System.in, "=stdin", fos );
processScript( globals, System.in, "=stdin", fos );
} else {
switch ( args[i].charAt(1) ) {
case 'o':
case 'c':
++i;
break;
case '-':
@@ -158,10 +167,12 @@ public class luac {
}
}
private void processScript( InputStream script, String chunkname, OutputStream out ) throws IOException {
private void processScript( Globals globals, InputStream script, String chunkname, OutputStream out ) throws IOException {
try {
// create the chunk
Prototype chunk = LuaC.instance.compile(script, chunkname);
Prototype chunk = encoding != null?
globals.compilePrototype(new InputStreamReader(script, encoding), chunkname):
globals.compilePrototype(script, chunkname);
// list the chunk
if (list)

View File

@@ -24,11 +24,13 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import org.luaj.vm2.Globals;
import org.luaj.vm2.Lua;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.luajc.LuaJC;
@@ -49,6 +51,7 @@ public class luajc {
" -m generate main(String[]) function for JSE\n" +
" -r recursively compile all\n" +
" -l load classes to verify generated bytecode\n" +
" -c enc use the supplied encoding 'enc' for input files\n" +
" -v verbose\n";
private static void usageExit() {
@@ -62,8 +65,10 @@ public class luajc {
private boolean recurse = false;
private boolean verbose = false;
private boolean loadclasses = false;
private String encoding = null;
private String pkgprefix = null;
private List files = new ArrayList();
private Globals globals;
public static void main( String[] args ) throws IOException {
new luajc( args );
@@ -104,6 +109,11 @@ public class luajc {
case 'r':
recurse = true;
break;
case 'c':
if ( ++i >= args.length )
usageExit();
encoding = args[i];
break;
case 'v':
verbose = true;
break;
@@ -140,7 +150,7 @@ public class luajc {
}
// process input files
JsePlatform.standardGlobals();
globals = JsePlatform.standardGlobals();
for ( int i=0,n=files.size(); i<n; i++ )
processFile( (InputFile) files.get(i) );
}
@@ -197,7 +207,9 @@ public class luajc {
// create the chunk
FileInputStream fis = new FileInputStream( inf.infile );
final Hashtable t = LuaJC.getInstance().compileAll(fis, inf.luachunkname, inf.srcfilename, genmain);
final Hashtable t = encoding != null?
LuaJC.instance.compileAll( new InputStreamReader(fis, encoding), inf.luachunkname, inf.srcfilename, globals, genmain):
LuaJC.instance.compileAll( fis, inf.luachunkname, inf.srcfilename, globals, genmain);
fis.close();
// write out the chunk

View File

@@ -22,6 +22,7 @@
package org.luaj.vm2.lib.jse;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.compiler.LuaC;
@@ -101,8 +102,8 @@ public class JsePlatform {
_G.load(new JseIoLib());
_G.load(new JseOsLib());
_G.load(new LuajavaLib());
LuaC.install();
_G.compiler = LuaC.instance;
LoadState.install(_G);
LuaC.install(_G);
return _G;
}

View File

@@ -23,14 +23,15 @@ package org.luaj.vm2.luajc;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Hashtable;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.Globals;
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;
import org.luaj.vm2.lib.BaseLib;
/**
* Implementation of {@link LuaCompiler} which does direct
@@ -46,45 +47,44 @@ import org.luaj.vm2.compiler.LuaC;
* as in the following:
* <pre> {@code
* LuaValue _G = JsePlatform.standardGlobals();
* LuaJC.install();
* LoadState.load( new ByteArrayInputStream("print 'hello'".getBytes()), "main.lua", _G ).call();
* LuaJC.install(_G);
* _G.loadString("print 'hello'").call();
* } </pre>
* @see LuaCompiler
* @see LuaC
* @see JsePlatform
* @see JmePlatform
* @see BaseLib
* @see LuaValue
*/
public class LuaJC implements LuaCompiler {
private static final String NON_IDENTIFIER = "[^a-zA-Z0-9_$/.\\-]";
public class LuaJC implements Globals.Loader {
private static LuaJC instance;
public static LuaJC getInstance() {
if ( instance == null )
instance = new LuaJC();
return instance;
}
public static final LuaJC instance = new LuaJC();
/**
* Install the compiler as the main compiler to use.
* Install the compiler as the main Globals.Loader to use in a set of globals.
* Will fall back to the LuaC prototype compiler.
*/
public static final void install() {
LoadState.compiler = getInstance();
public static final void install(Globals G) {
G.loader = instance;
}
public LuaJC() {
}
protected LuaJC() {}
public Hashtable compileAll(InputStream script, String chunkname, String filename, boolean genmain) throws IOException {
String classname = toStandardJavaClassName( chunkname );
String luaname = toStandardLuaFileName( filename );
Hashtable h = new Hashtable();
Prototype p = LuaC.instance.compile(script, classname);
JavaGen gen = new JavaGen(p, classname, luaname, genmain);
public Hashtable compileAll(InputStream script, String chunkname, String filename, Globals globals, boolean genmain) throws IOException {
final String classname = toStandardJavaClassName( chunkname );
final Prototype p = globals.loadPrototype(script, classname, "bt");
return compileProtoAndSubProtos(p, classname, filename, genmain);
}
public Hashtable compileAll(Reader script, String chunkname, String filename, Globals globals, boolean genmain) throws IOException {
final String classname = toStandardJavaClassName( chunkname );
final Prototype p = globals.compilePrototype(script, classname);
return compileProtoAndSubProtos(p, classname, filename, genmain);
}
private Hashtable compileProtoAndSubProtos(Prototype p, String classname, String filename, boolean genmain) throws IOException {
final String luaname = toStandardLuaFileName( filename );
final Hashtable h = new Hashtable();
final JavaGen gen = new JavaGen(p, classname, luaname, genmain);
insert( h, gen );
return h;
}
@@ -95,12 +95,11 @@ public class LuaJC implements LuaCompiler {
insert(h, gen.inners[i]);
}
public LuaFunction load(InputStream stream, String name, LuaValue env) throws IOException {
Prototype p = LuaC.instance.compile(stream, name);
public LuaFunction load(Prototype p, String name, LuaValue globals) throws IOException {
String luaname = toStandardLuaFileName( name );
String classname = toStandardJavaClassName( luaname );
JavaLoader loader = new JavaLoader();
return loader.load(p, classname, luaname, env);
return loader.load(p, classname, luaname, globals);
}
private static String toStandardJavaClassName( String luachunkname ) {

View File

@@ -83,7 +83,7 @@ public class LuaScriptEngine extends AbstractScriptEngine implements ScriptEngin
InputStream is = new Utf8Encoder(script);
try {
final Globals g = context.globals;
final LuaFunction f = LoadState.load(is, "script", "bt", g);
final LuaFunction f = g.load(script, "script").checkfunction();
return new LuajCompiledScript(f, g);
} catch ( LuaError lee ) {
throw new ScriptException(lee.getMessage() );

View File

@@ -38,7 +38,6 @@ public class LuaScriptEngineFactory implements ScriptEngineFactory {
};
private static final String [] MIMETYPES = {
"text/plain",
"text/lua",
"application/lua"
};

View File

@@ -28,12 +28,12 @@ import java.io.PrintStream;
import java.io.Reader;
import java.io.Writer;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.SimpleScriptContext;
import org.luaj.vm2.Globals;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.luajc.LuaJC;
/**
* Context for LuaScriptEngine execution which maintains its own Globals,
@@ -61,11 +61,13 @@ public class LuajContext extends SimpleScriptContext implements ScriptContext {
* have negative impact on performance.
*/
public LuajContext() {
this("true".equals(System.getProperty("org.luaj.debug")));
this("true".equals(System.getProperty("org.luaj.debug")),
"true".equals(System.getProperty("org.luaj.luajc")));
}
/** Construct a LuajContext with its own globals, which
* which optionally are debug globals.
* which optionally are debug globals, and optionally use the
* luajc direct lua to java bytecode compiler.
* <p>
* If createDebugGlobals is set, the globals
* created will be a debug globals that includes the debug
@@ -73,11 +75,15 @@ public class LuajContext extends SimpleScriptContext implements ScriptContext {
* have negative impact on performance.
* @param createDebugGlobals true to create debug globals,
* false for standard globals.
* @param useLuaJCCompiler true to use the luajc compiler,
* reqwuires bcel to be on the class path.
*/
public LuajContext(boolean createDebugGlobals) {
public LuajContext(boolean createDebugGlobals, boolean useLuaJCCompiler) {
globals = createDebugGlobals?
JsePlatform.debugGlobals():
JsePlatform.standardGlobals();
if (useLuaJCCompiler)
LuaJC.install(globals);
stdin = globals.STDIN;
stdout = globals.STDOUT;
stderr = globals.STDERR;