From 69bbae70a1d70693051be267ee033ddd2eb69f3c Mon Sep 17 00:00:00 2001 From: James Roseborough Date: Sun, 25 Jul 2010 22:31:43 +0000 Subject: [PATCH] simplify LuaCompiler interface and add Lua2Java utility class. --- src/core/org/luaj/vm2/LoadState.java | 39 ++-- src/core/org/luaj/vm2/compiler/LuaC.java | 48 ++--- src/jse/luac.java | 2 +- src/jse/org/luaj/vm2/lua2java/Lua2Java.java | 168 ++++++++++++++++++ src/jse/org/luaj/vm2/luajc/JavaLoader.java | 17 +- src/jse/org/luaj/vm2/luajc/LuaJC.java | 26 +-- test/java/org/luaj/luajc/TestLuaJ.java | 4 +- test/junit/org/luaj/vm2/CompatibiltyTest.java | 13 ++ test/junit/org/luaj/vm2/FragmentsTest.java | 2 +- .../junit/org/luaj/vm2/LuaOperationsTest.java | 2 +- test/junit/org/luaj/vm2/ScriptDrivenTest.java | 3 +- .../luaj/vm2/compiler/AbstractUnitTests.java | 4 +- .../vm2/compiler/DumpLoadEndianIntTest.java | 8 +- .../org/luaj/vm2/compiler/SimpleTests.java | 12 +- 14 files changed, 238 insertions(+), 110 deletions(-) create mode 100644 src/jse/org/luaj/vm2/lua2java/Lua2Java.java diff --git a/src/core/org/luaj/vm2/LoadState.java b/src/core/org/luaj/vm2/LoadState.java index feadce69..c74ac435 100644 --- a/src/core/org/luaj/vm2/LoadState.java +++ b/src/core/org/luaj/vm2/LoadState.java @@ -56,15 +56,9 @@ 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; - - /** Load into a LuaFunction given a prototype. May compile into a class, or return a LuaClosure - * @param filename TODO*/ - public LuaFunction load(Prototype p, String filename, LuaValue env); + /** Load into a Closure or LuaFunction from a Stream and initializes the environment + * @throws IOException */ + public LuaFunction load(InputStream stream, String filename, LuaValue env) throws IOException; } /** Compiler instance, if installed */ @@ -275,26 +269,25 @@ public class LoadState { } public static LuaFunction load( InputStream stream, String name, LuaValue env ) throws IOException { - Prototype p = compile( stream, name ); if ( compiler != null ) - return compiler.load(p, name, env); - else + return compiler.load(stream, name, env); + else { + int firstByte = stream.read(); + if ( firstByte != LUA_SIGNATURE[0] ) + throw new LuaError("no compiler"); + Prototype p = loadBinaryChunk( firstByte, stream, name ); return new LuaClosure( p, env ); + } } - public static Prototype compile( InputStream stream, String name ) throws IOException { - int c = stream.read(); - if ( c != LUA_SIGNATURE[0] ) { - if ( compiler != null ) - return compiler.compile(c, stream, name); - throw new LuaError("no compiler"); - } + public static Prototype loadBinaryChunk( int firstByte, InputStream stream, String name ) throws IOException { // check rest of signature - for ( int i=1; i<4; i++ ) { - if ( stream.read() != LUA_SIGNATURE[i] ) - throw new IllegalArgumentException("bad signature"); - } + if ( firstByte != LUA_SIGNATURE[0] + || stream.read() != LUA_SIGNATURE[1] + || stream.read() != LUA_SIGNATURE[2] + || stream.read() != LUA_SIGNATURE[3] ) + throw new IllegalArgumentException("bad signature"); // load file as a compiled chunk String sname = getSourceName(name); diff --git a/src/core/org/luaj/vm2/compiler/LuaC.java b/src/core/org/luaj/vm2/compiler/LuaC.java index 4ff6a52f..f3345bb6 100644 --- a/src/core/org/luaj/vm2/compiler/LuaC.java +++ b/src/core/org/luaj/vm2/compiler/LuaC.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.Hashtable; +import org.luaj.vm2.LoadState; import org.luaj.vm2.LocVars; import org.luaj.vm2.Lua; import org.luaj.vm2.LuaClosure; @@ -41,12 +42,14 @@ import org.luaj.vm2.LoadState.LuaCompiler; */ public class LuaC extends Lua implements LuaCompiler { + public static final LuaC instance = new LuaC(); + /** Install the compiler so that LoadState will first * try to use it when handed bytes that are * not already a compiled lua chunk. */ public static void install() { - org.luaj.vm2.LoadState.compiler = new LuaC(); + org.luaj.vm2.LoadState.compiler = instance; } protected static void _assert(boolean b) { @@ -156,43 +159,26 @@ public class LuaC extends Lua implements LuaCompiler { } public int nCcalls; - Hashtable strings = new Hashtable(); + Hashtable strings; - /** Utility method to invoke the compiler for an input stream - */ - public static Prototype compile(InputStream is, String name) throws IOException { - return new LuaC().compile(is.read(), is, name); + protected LuaC() {} + + private LuaC(Hashtable strings) { + this.strings = strings; } /** 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); + public LuaFunction load(InputStream stream, String name, LuaValue env) throws IOException { + Prototype p = compile( stream, name ); return new LuaClosure( p, env ); } - /** Compile source bytes into a LPrototype. - * - * Try to compile the file, and return the Prototype on success, - * or throw LuaErrorException on syntax error or I/O Exception - * - * @param firstByte the first byte from the InputStream. - * This can be read by the client and tested to see if it is already a binary chunk. - * @param stream InputStream to read from. - * @param name Name of the chunk - * @return null if the first byte indicates it is a binary chunk, - * a LPrototype instance if it can be compiled, - * or an exception is thrown if there is an error. - * @throws IOException if an I/O exception occurs - * @throws LuaError if there is a syntax error. - */ - public Prototype compile(int firstByte, InputStream stream, String name) throws IOException { - LuaC compiler = new LuaC(); - return compiler.luaY_parser(firstByte, stream, name); + /** Compile a prototype or load as a binary chunk */ + public static Prototype compile(InputStream stream, String name) throws IOException { + int firstByte = stream.read(); + return ( firstByte == '\033' )? + LoadState.loadBinaryChunk(firstByte, stream, name): + (new LuaC(new Hashtable())).luaY_parser(firstByte, stream, name); } /** Parse the input */ diff --git a/src/jse/luac.java b/src/jse/luac.java index b6098efd..6ad8a1e1 100644 --- a/src/jse/luac.java +++ b/src/jse/luac.java @@ -159,7 +159,7 @@ public class luac { private void processScript( InputStream script, String chunkname, OutputStream out ) throws IOException { try { // create the chunk - Prototype chunk = LuaC.compile(script, chunkname); + Prototype chunk = LuaC.instance.compile(script, chunkname); // list the chunk if (list) diff --git a/src/jse/org/luaj/vm2/lua2java/Lua2Java.java b/src/jse/org/luaj/vm2/lua2java/Lua2Java.java new file mode 100644 index 00000000..a1e67588 --- /dev/null +++ b/src/jse/org/luaj/vm2/lua2java/Lua2Java.java @@ -0,0 +1,168 @@ +package org.luaj.vm2.lua2java; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Arrays; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; +import javax.tools.JavaCompiler.CompilationTask; + +import org.luaj.vm2.LoadState; +import org.luaj.vm2.LuaFunction; +import org.luaj.vm2.LuaValue; +import org.luaj.vm2.LoadState.LuaCompiler; +import org.luaj.vm2.ast.Chunk; +import org.luaj.vm2.compiler.LuaC; +import org.luaj.vm2.parser.LuaParser; + +public class Lua2Java implements LuaCompiler { + + public static final Lua2Java instance = new Lua2Java(); + + public static final void install() { + LoadState.compiler = instance; + } + + private Lua2Java() { + } + + public LuaFunction load(InputStream stream, String filename, LuaValue env) throws IOException { + + // get first byte + if ( ! stream.markSupported() ) + stream = new BufferedInputStream( stream ); + stream.mark( 1 ); + int firstByte = stream.read(); + stream.reset(); + + // we can only sompile sources + if ( firstByte != '\033' ) { + final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + if (compiler == null) + LuaValue.error("no java compiler"); + + // break into package and class + if ( filename.endsWith( ".lua") ) + filename = filename.substring(0, filename.length()-4); + String s = filename.replace('\\', '/').replace('/','.').replaceAll("[^\\w]", "_"); + int p = s.lastIndexOf('.'); + final String packageName = p>=0? s.substring(0,p): null; + final String className = toClassname( s.substring(p+1) ); + + // open output file + final String pkgSubdir = (packageName!=null? packageName.replace('.','/'): ""); + final String srcDirRoot = "lua2java/src"; + final String binDirRoot = "lua2java/classes"; + final String srcDirname = srcDirRoot+"/"+pkgSubdir; + final String binDirname = binDirRoot+"/"+pkgSubdir; + final String srcFilename = srcDirname + "/" + className + ".java"; + + // make directories + new File(srcDirname).mkdirs(); + new File(binDirname).mkdirs(); + + // generate java source + try { + LuaParser parser = new LuaParser(stream,"ISO8859-1"); + Chunk chunk = parser.Chunk(); + File source = new File(srcFilename); + Writer writer = new OutputStreamWriter( new FileOutputStream(source) ); + new JavaCodeGen(chunk,writer,packageName,className); + writer.close(); + + // set up output location + Iterable dest = Arrays.asList(new File[] { new File(binDirRoot) }); + StandardJavaFileManager fm = compiler.getStandardFileManager( null, null, null); + fm.setLocation(StandardLocation.CLASS_OUTPUT, dest); + + // compile the file + Iterable compilationUnits = fm.getJavaFileObjects(source); + CompilationTask task = compiler.getTask(null, fm, null, null, null, compilationUnits); + boolean success = task.call(); + + // instantiate, config and return + if (success) { + // create instance + ClassLoader cl = new ClassLoader() { + public Class findClass(String classname) throws ClassNotFoundException { + if ( classname.startsWith(className) ) { + File f = new File( binDirname+"/"+classname+".class"); + long n = f.length(); + byte[] b = new byte[(int) n]; + try { + DataInputStream dis = new DataInputStream( new FileInputStream(f) ); + dis.readFully(b); + } catch ( Exception e ) { + throw new RuntimeException("failed to read class bytes: "+e ); + } + return defineClass(classname, b, 0, b.length); + } + return super.findClass(classname); + } + }; + Class clazz = cl.loadClass(className); + Object instance = clazz.newInstance(); + LuaFunction value = (LuaFunction) instance; + value.setfenv( env ); + return value; + } else { + } + } catch ( Exception e ) { + LuaValue.error("compile task failed: "+e); + } + + // report compilation error + LuaValue.error("compile task failed:"); + return null; + } + + // fall back to plain compiler + return LuaC.instance.load( stream, filename, env); + } + + /** Convert lua filename to valid class name */ + public static final String toClassname( String filename ) { + int n=filename.length(); + int j=n; + if ( filename.endsWith(".lua") ) + j -= 4; + for ( int k=0; k='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9') ) + return true; + switch ( c ) { + case '.': + case '$': + case '_': + return true; + default: + return false; + } + } +} diff --git a/src/jse/org/luaj/vm2/luajc/JavaLoader.java b/src/jse/org/luaj/vm2/luajc/JavaLoader.java index 31f5dbb5..29edbdd5 100644 --- a/src/jse/org/luaj/vm2/luajc/JavaLoader.java +++ b/src/jse/org/luaj/vm2/luajc/JavaLoader.java @@ -1,13 +1,11 @@ package org.luaj.vm2.luajc; -import java.io.IOException; -import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import org.luaj.vm2.LuaFunction; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Prototype; -import org.luaj.vm2.compiler.LuaC; /******************************************************************************* * Copyright (c) 2010 Luaj.org. All rights reserved. @@ -40,25 +38,20 @@ public class JavaLoader extends ClassLoader { this.env = env; } - public LuaValue load( InputStream is, String classname, String filename ) throws IOException { - Prototype p = LuaC.compile(is, classname); - return load( p, classname, filename ); - } - - public LuaValue load( Prototype p, String classname, String filename ) { + public LuaFunction load( Prototype p, String classname, String filename ) { JavaGen jg = new JavaGen( p, classname, filename ); return load( jg ); } - public LuaValue load( JavaGen jg ) { + public LuaFunction load( JavaGen jg ) { include( jg ); return load( jg.classname ); } - public LuaValue load(String classname) { + public LuaFunction load(String classname) { try { Class c = loadClass( classname ); - LuaValue v = (LuaValue) c.newInstance(); + LuaFunction v = (LuaFunction) c.newInstance(); v.setfenv(env); return v; } catch ( Exception e ) { diff --git a/src/jse/org/luaj/vm2/luajc/LuaJC.java b/src/jse/org/luaj/vm2/luajc/LuaJC.java index 1826169a..205ae5dd 100644 --- a/src/jse/org/luaj/vm2/luajc/LuaJC.java +++ b/src/jse/org/luaj/vm2/luajc/LuaJC.java @@ -37,7 +37,6 @@ public class LuaJC implements LuaCompiler { private static final String NON_IDENTIFIER = "[^a-zA-Z0-9_$]"; private static LuaJC instance; - private LuaC luac; public static LuaJC getInstance() { if ( instance == null ) @@ -54,12 +53,11 @@ public class LuaJC implements LuaCompiler { } public LuaJC() { - luac = new LuaC(); } public Hashtable compileAll(InputStream script, String classname, String filename) throws IOException { Hashtable h = new Hashtable(); - Prototype p = luac.compile(script.read(), script, classname); + Prototype p = LuaC.instance.compile(script, classname); JavaGen gen = new JavaGen(p, classname, filename); insert( h, gen ); return h; @@ -71,25 +69,11 @@ public class LuaJC implements LuaCompiler { insert(h, gen.inners[i]); } - public Prototype compile(int firstByte, InputStream stream, String name) throws IOException { - return luac.compile(firstByte, stream, name); - } - - public LuaFunction load(int firstByte, InputStream stream, String name, LuaValue env) throws IOException { - return load( compile(firstByte, stream, name), name, env ); - } - - public LuaFunction load(Prototype p, String filename, LuaValue env) { - String classname = filename.endsWith(".lua")? filename.substring(0,filename.length()-4): filename; + public LuaFunction load(InputStream stream, String name, LuaValue env) throws IOException { + Prototype p = LuaC.instance.compile(stream, name); + String classname = name.endsWith(".lua")? name.substring(0,name.length()-4): name; classname = classname.replaceAll(NON_IDENTIFIER, "_"); - JavaGen gen = new JavaGen(p, classname, filename); JavaLoader loader = new JavaLoader(env); - loader.include(gen); - return (LuaFunction) loader.load(p, classname, filename); + return loader.load(p, classname, name); } - - public LuaValue load(InputStream stream, String name, LuaValue env) throws IOException { - return load(stream.read(), stream, name, env); - } - } diff --git a/test/java/org/luaj/luajc/TestLuaJ.java b/test/java/org/luaj/luajc/TestLuaJ.java index 20ab2482..4d9b9ab3 100644 --- a/test/java/org/luaj/luajc/TestLuaJ.java +++ b/test/java/org/luaj/luajc/TestLuaJ.java @@ -56,9 +56,7 @@ public class TestLuaJ { // compile into a chunk, or load as a class InputStream is = new ByteArrayInputStream( script.getBytes() ); - Prototype p = LuaC.compile(is, "script"); - print( p ); - LuaValue chunk = new LuaClosure(p,_G); + LuaValue chunk = LuaC.instance.load(is, "script",_G); chunk.call(); } diff --git a/test/junit/org/luaj/vm2/CompatibiltyTest.java b/test/junit/org/luaj/vm2/CompatibiltyTest.java index ec0652d9..46949145 100644 --- a/test/junit/org/luaj/vm2/CompatibiltyTest.java +++ b/test/junit/org/luaj/vm2/CompatibiltyTest.java @@ -24,6 +24,7 @@ package org.luaj.vm2; import junit.framework.Test; import junit.framework.TestSuite; +import org.luaj.vm2.lua2java.Lua2Java; import org.luaj.vm2.luajc.LuaJC; /** @@ -62,9 +63,21 @@ 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( Lua2JavaTest.class, "Lua2Java Tests" ) ); suite.addTest( new TestSuite( JseBytecodeTest.class, "JSE Bytecode Tests" ) ); return suite; } + + public static class Lua2JavaTest extends CompatibiltyTestSuite { + public Lua2JavaTest() { + super(ScriptDrivenTest.PlatformType.LUA2JAVA); + } + protected void setUp() throws Exception { + super.setUp(); + System.setProperty("Lua2Java", "false"); + Lua2Java.install(); + } + } public static class JmeCompatibilityTest extends CompatibiltyTestSuite { public JmeCompatibilityTest() { diff --git a/test/junit/org/luaj/vm2/FragmentsTest.java b/test/junit/org/luaj/vm2/FragmentsTest.java index 26a8eda2..8cd2c758 100644 --- a/test/junit/org/luaj/vm2/FragmentsTest.java +++ b/test/junit/org/luaj/vm2/FragmentsTest.java @@ -45,7 +45,7 @@ public class FragmentsTest extends TestCase { if ( true ) { chunk = LuaJC.getInstance().load(is,name,_G); } else { - chunk = (new LuaC()).load( is, name, _G ); + chunk = LuaC.instance.load( is, name, _G ); } Varargs actual = chunk.invoke(); assertEquals( expected.narg(), actual.narg() ); diff --git a/test/junit/org/luaj/vm2/LuaOperationsTest.java b/test/junit/org/luaj/vm2/LuaOperationsTest.java index 9ab8e09e..29b465bc 100644 --- a/test/junit/org/luaj/vm2/LuaOperationsTest.java +++ b/test/junit/org/luaj/vm2/LuaOperationsTest.java @@ -181,7 +181,7 @@ public class LuaOperationsTest extends TestCase { try { LuaTable _G = org.luaj.vm2.lib.JsePlatform.standardGlobals(); InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8")); - return LuaC.compile(is, name); + return LuaC.instance.compile(is, name); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/test/junit/org/luaj/vm2/ScriptDrivenTest.java b/test/junit/org/luaj/vm2/ScriptDrivenTest.java index b10bfcc3..ca0f4cfa 100644 --- a/test/junit/org/luaj/vm2/ScriptDrivenTest.java +++ b/test/junit/org/luaj/vm2/ScriptDrivenTest.java @@ -39,7 +39,7 @@ public class ScriptDrivenTest extends TestCase { public static final boolean nocompile = "true".equals(System.getProperty("nocompile")); public enum PlatformType { - JME, JSE, LUAJIT, + JME, JSE, LUAJIT, LUA2JAVA, } private final PlatformType platform; @@ -57,6 +57,7 @@ public class ScriptDrivenTest extends TestCase { default: case JSE: case LUAJIT: + case LUA2JAVA: _G = org.luaj.vm2.lib.JsePlatform.debugGlobals(); break; case JME: diff --git a/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java b/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java index 3219dcb4..5c6e430f 100644 --- a/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java +++ b/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java @@ -54,7 +54,7 @@ abstract public class AbstractUnitTests extends TestCase { // compile in memory InputStream is = new ByteArrayInputStream(lua); - Prototype p = LuaC.compile(is, "@" + dir + "/" + file); + Prototype p = LuaC.instance.compile(is, "@" + dir + "/" + file); String actual = protoToString(p); // load expected value from jar @@ -97,7 +97,7 @@ abstract public class AbstractUnitTests extends TestCase { protected Prototype loadFromBytes(byte[] bytes, String script) throws IOException { InputStream is = new ByteArrayInputStream(bytes); - return LoadState.compile(is, script); + return LoadState.loadBinaryChunk(is.read(), is, script); } protected String protoToString(Prototype p) { diff --git a/test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java b/test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java index ff22caf0..e9781c66 100644 --- a/test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java +++ b/test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java @@ -11,6 +11,7 @@ import junit.framework.TestCase; import org.luaj.vm2.LoadState; import org.luaj.vm2.LuaClosure; +import org.luaj.vm2.LuaFunction; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Prototype; @@ -83,10 +84,10 @@ public class DumpLoadEndianIntTest extends TestCase { // compile into prototype InputStream is = new ByteArrayInputStream(script.getBytes()); - Prototype p = LuaC.compile(is, "script"); + Prototype p = LuaC.instance.compile(is, "script"); // double check script result before dumping - LuaClosure f = new LuaClosure(p, _G); + LuaFunction f = new LuaClosure(p, _G); LuaValue r = f.call(); String actual = r.tojstring(); assertEquals( expectedPriorDump, actual ); @@ -107,8 +108,7 @@ public class DumpLoadEndianIntTest extends TestCase { // load again using compiler is = new ByteArrayInputStream(dumped); - p = LoadState.compile(is, "dumped"); - f = new LuaClosure(p, _G); + f = LoadState.load(is, "dumped", _G); r = f.call(); actual = r.tojstring(); assertEquals( expectedPostDump, actual ); diff --git a/test/junit/org/luaj/vm2/compiler/SimpleTests.java b/test/junit/org/luaj/vm2/compiler/SimpleTests.java index 0c632ee1..f4182066 100644 --- a/test/junit/org/luaj/vm2/compiler/SimpleTests.java +++ b/test/junit/org/luaj/vm2/compiler/SimpleTests.java @@ -5,14 +5,11 @@ import java.io.InputStream; import junit.framework.TestCase; -import org.luaj.vm2.LuaClosure; import org.luaj.vm2.LuaDouble; +import org.luaj.vm2.LuaFunction; import org.luaj.vm2.LuaInteger; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Print; -import org.luaj.vm2.Prototype; -import org.luaj.vm2.lib.BaseLib; import org.luaj.vm2.lib.JsePlatform; public class SimpleTests extends TestCase { @@ -27,12 +24,7 @@ public class SimpleTests extends TestCase { private void doTest( String script ) { try { InputStream is = new ByteArrayInputStream( script.getBytes("UTF8") ); - Prototype p = LuaC.compile( is, "script" ); - assertNotNull( p ); - Print.printCode( p ); - - // try running the code! - LuaClosure c = new LuaClosure( p, _G ); + LuaFunction c = LuaC.instance.load( is, "script", _G ); c.call(); } catch ( Exception e ) { fail("i/o exception: "+e );