diff --git a/README.html b/README.html index 6c7f0fe2..a80cc443 100644 --- a/README.html +++ b/README.html @@ -241,15 +241,22 @@ Lua scripts can also be run directly in this mode without precompiling using the

Run a script in a Java Application

-The following pattern is used within Java SE +A simple hello, world example in luaj is:

 	import org.luaj.vm2.*;
 	import org.luaj.vm2.lib.jse.*;
 
-	String script = "examples/lua/hello.lua";
-	LuaValue _G = JsePlatform.standardGlobals();
-	_G.get("dofile").call( LuaValue.valueOf(script) );
+	Globals globals = JsePlatform.standardGlobals();
+	LuaValue chunk = globals.load("print 'hello, world'");
+	chunk.call();
+	
+
+ +Loading from a file is done via Globals.loadFile(): + +
+	LuaValue chunk = globals.loadfile("examples/lua/hello.lua");
 

@@ -270,13 +277,13 @@ The for MIDlets the JmePlatform is used instead: import org.luaj.vm2.*; import org.luaj.vm2.lib.jme.*; - String script = "examples/lua/hello.lua"; - LuaValue _G = JmePlatform.standardGlobals(); - _G.get("dofile").call( LuaValue.valueOf(script) ); + Globals globals = JmePlatform.standardGlobals(); + LuaValue chunk = globals.loadfile("examples/lua/hello.lua"); + chunk.call();

-The file must be a resource within within the midlet jar for dofile() to find it. +The file must be a resource within within the midlet jar for the loader to find it. Any files included via require() must also be part of the midlet resources.

@@ -310,6 +317,8 @@ The standard use of JSR-223 scripting engines may be used: System.out.println( "y="+e.get("y") ); +You can also look up the engine by language "lua" or mimetypes "text/lua" or "application/lua". +

All standard aspects of script engines including compiled statements should be supported. @@ -341,7 +350,7 @@ To exclude the lua-to-lua-bytecode compiler, do not call but instead initialize globals with including only those libraries that are needed and omitting the line:

-	org.luaj.vm2.compiler.LuaC.install();
+	org.luaj.vm2.compiler.LuaC.install(globals);
 
@@ -349,10 +358,10 @@ that are needed and omitting the line:

To compile from lua to Java bytecode for all lua loaded at runtime, -install the LuaJC compiler after globals have been created using: +install the LuaJC compiler into a globals object use:

-	org.luaj.vm2.jse.luajc.LuaJC.install();
+	org.luaj.vm2.jse.luajc.LuaJC.install(globals);
 

@@ -389,8 +398,8 @@ Luaj 3.0 can be run in multiple threads, with the following restrictions:

For an example of loading allocating per-thread Globals and invoking scripts in @@ -886,12 +895,14 @@ Files are no longer hosted at LuaForge.   3.0-beta2

Known Issues

+

Limitations

+

File Character Encoding

+Source files can be considered encoded in UTF-8 or ISO-8859-1 and results should be as expected, +with literal string contianing quoted characters compiling to the same byte sequences as the input. +For a non ASCII-compatible encoding such as EBSDIC, however, there are restrictions: + +These restrictions are mainly a side effect of how the language is defined as allowing byte literals +within literal strings in source files. + +Code that is generated on the fly within lua and compiled with lua's load() function +should work as expected, however, since these strings will never be represented with the +host's native character encoding. diff --git a/examples/jme/SampleMIDlet.java b/examples/jme/SampleMIDlet.java index 19fd4734..f4287a4a 100644 --- a/examples/jme/SampleMIDlet.java +++ b/examples/jme/SampleMIDlet.java @@ -4,9 +4,7 @@ import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; import org.luaj.vm2.*; -import org.luaj.vm2.lib.*; import org.luaj.vm2.lib.jme.JmePlatform; -import org.luaj.vm2.compiler.LuaC; public class SampleMIDlet extends MIDlet { @@ -21,8 +19,8 @@ public class SampleMIDlet extends MIDlet { script = DEFAULT_SCRIPT; // create an environment to run in - LuaValue _G = JmePlatform.standardGlobals(); - _G.get("require").call( LuaValue.valueOf(script) ); + Globals globals = JmePlatform.standardGlobals(); + globals.get("require").call( LuaValue.valueOf(script) ); } protected void destroyApp(boolean arg0) throws MIDletStateChangeException { diff --git a/examples/jse/SampleJseMain.java b/examples/jse/SampleJseMain.java index b6ac1c1b..ffe7f582 100644 --- a/examples/jse/SampleJseMain.java +++ b/examples/jse/SampleJseMain.java @@ -13,7 +13,7 @@ public class SampleJseMain { Globals globals = JsePlatform.standardGlobals(); // Use the convenience function on the globals to load a chunk. - LuaValue chunk = globals.loadFile(script); + LuaValue chunk = globals.loadfile(script); // Use any of the "call()" or "invoke()" functions directly on the chunk. chunk.call( LuaValue.valueOf(script) ); diff --git a/examples/jse/SampleMultiThreaded.java b/examples/jse/SampleMultiThreaded.java index 486fa806..51fa6c9e 100644 --- a/examples/jse/SampleMultiThreaded.java +++ b/examples/jse/SampleMultiThreaded.java @@ -26,8 +26,8 @@ public class SampleMultiThreaded { // Once a Globals is created, it can and should be reused // within the same thread. - g.loadFile(script1).call(); - g.loadFile(script2).call(); + g.loadfile(script1).call(); + g.loadfile(script2).call(); } catch ( Exception e ) { e.printStackTrace(); diff --git a/src/core/org/luaj/vm2/Buffer.java b/src/core/org/luaj/vm2/Buffer.java index 7083ca8b..0a1117c4 100644 --- a/src/core/org/luaj/vm2/Buffer.java +++ b/src/core/org/luaj/vm2/Buffer.java @@ -163,13 +163,13 @@ public final class Buffer { * Append a Java String to the buffer. * The Java string will be converted to bytes using the UTF8 encoding. * @return {@code this} to allow call chaining - * @see LuaString#encodeToUtf8(char[], byte[], int) + * @see LuaString#encodeToUtf8(char[], int, byte[], int) */ public final Buffer append( String str ) { - char[] chars = str.toCharArray(); - final int n = LuaString.lengthAsUtf8( chars ); + char[] c = str.toCharArray(); + final int n = LuaString.lengthAsUtf8( c ); makeroom( 0, n ); - LuaString.encodeToUtf8( chars, bytes, offset + length ); + LuaString.encodeToUtf8( c, c.length, bytes, offset + length ); length += n; return this; } diff --git a/src/core/org/luaj/vm2/Globals.java b/src/core/org/luaj/vm2/Globals.java index 66b35aa2..a5578d4c 100644 --- a/src/core/org/luaj/vm2/Globals.java +++ b/src/core/org/luaj/vm2/Globals.java @@ -21,10 +21,11 @@ ******************************************************************************/ package org.luaj.vm2; +import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; +import java.io.Reader; -import org.luaj.vm2.LoadState.LuaCompiler; import org.luaj.vm2.lib.BaseLib; import org.luaj.vm2.lib.DebugLib; import org.luaj.vm2.lib.PackageLib; @@ -68,9 +69,6 @@ public class Globals extends LuaTable { /** The installed ResourceFinder for looking files by name. */ public ResourceFinder FINDER; - /** The installed compiler. */ - public LuaCompiler compiler = null; - /** The currently running thread. Should not be changed by non-library code. */ public LuaThread running = new LuaThread(this); @@ -86,30 +84,119 @@ public class Globals extends LuaTable { /** The current error handler for this Globals */ public LuaValue errorfunc; + /** Interface for module that converts a Prototype into a LuaFunction with an environment. */ + public interface Loader { + /** Convert the prototype into a LuaFunction with the supplied environment. */ + LuaFunction load(Prototype prototype, String chunkname, LuaValue env) throws IOException; + } + + /** Interface for module that converts lua source text into a prototype. */ + public interface Compiler { + /** Compile lua source into a Prototype. The InputStream is assumed to be in UTF-8. */ + Prototype compile(InputStream stream, String chunkname) throws IOException; + } + + /** Interface for module that loads lua binary chunk into a prototype. */ + public interface Undumper { + /** Load the supplied input stream into a prototype. */ + Prototype undump(InputStream stream, String chunkname) throws IOException; + } + /** Check that this object is a Globals object, and return it, otherwise throw an error. */ public Globals checkglobals() { return this; } + + /** The installed loader. */ + public Loader loader; - /** Convenience function for loading a file. + /** The installed compiler. */ + public Compiler compiler; + + /** The installed undumper. */ + public Undumper undumper; + + /** Convenience function for loading a file that is either binary lua or lua source. * @param filename Name of the file to load. * @return LuaValue that can be call()'ed or invoke()'ed. * @throws LuaError if the file could not be loaded. */ - public LuaValue loadFile(String filename) { - Varargs v = baselib.loadFile(filename, "bt", this); - return !v.isnil(1)? v.arg1(): error(v.arg(2).tojstring()); + public LuaValue loadfile(String filename) { + try { + return load(FINDER.findResource(filename), "@"+filename, "bt", this); + } catch (Exception e) { + return error("load "+filename+": "+e); + } } - /** Convenience function to load a string value as a script. + /** Convenience function to load a string value as a script. Must be lua source. * @param script Contents of a lua script, such as "print 'hello, world.'" * @param chunkname Name that will be used within the chunk as the source. * @return LuaValue that may be executed via .call(), .invoke(), or .method() calls. * @throws LuaError if the script could not be compiled. */ - public LuaValue loadString(String script, String chunkname) { - Varargs v = baselib.loadStream(valueOf(script).toInputStream(), chunkname, "bt", this); - return !v.isnil(1)? v.arg1(): error(v.arg(2).tojstring()); + public LuaValue load(String script, String chunkname) { + return load(new StrReader(script), chunkname); + } + + /** Load the content form a reader as a text file. Must be lua source. + * The source is converted to UTF-8, so any characters appearing in quoted literals + * above the range 128 will be converted into multiple bytes. */ + public LuaValue load(Reader reader, String chunkname) { + return load(new UTF8Stream(reader), chunkname, "t", this); + } + + /** Load the content form an input stream as a binary chunk or text file. */ + public LuaValue load(InputStream is, String chunkname, String mode, LuaValue env) { + try { + Prototype p = loadPrototype(is, chunkname, mode); + return loader.load(p, chunkname, env); + } catch (LuaError l) { + throw l; + } catch (Exception e) { + return error("load "+chunkname+": "+e); + } + } + + /** Load lua source or lua binary from an input stream into a Prototype. + * The InputStream is either a binary lua chunk starting with the lua binary chunk signature, + * or a text input file. If it is a text input file, it is interpreted as a UTF-8 byte sequence. + */ + public Prototype loadPrototype(InputStream is, String chunkname, String mode) throws IOException { + if (mode.indexOf('b') >= 0) { + if (undumper == null) + error("No undumper."); + if (!is.markSupported()) + is = new MarkStream(is); + is.mark(4); + final Prototype p = undumper.undump(is, chunkname); + if (p != null) + return p; + is.reset(); + } + if (mode.indexOf('t') >= 0) { + return compilePrototype(is, chunkname); + } + error("Failed to load prototype "+chunkname+" using mode '"+mode+"'"); + return null; + } + + /** Compile lua source from a Reader into a Prototype. The characters in the reader + * are converted to bytes using the UTF-8 encoding, so a string literal containing + * characters with codepoints 128 or above will be converted into multiple bytes. + */ + public Prototype compilePrototype(Reader reader, String chunkname) throws IOException { + return compilePrototype(new UTF8Stream(reader), chunkname); + } + + /** Compile lua source from an InputStream into a Prototype. + * The input is assumed to be UTf-8, but since bytes in the range 128-255 are passed along as + * literal bytes, any ASCII-compatible encoding such as ISO 8859-1 may also be used. + */ + public Prototype compilePrototype(InputStream stream, String chunkname) throws IOException { + if (compiler == null) + error("No compiler."); + return compiler.compile(stream, chunkname); } /** Function which yields the current thread. @@ -123,4 +210,80 @@ public class Globals extends LuaTable { return s.lua_yield(args); } + /** Reader implementation to read chars from a String in JME or JSE. */ + static class StrReader extends Reader { + final String s; + int i = 0, n; + StrReader(String s) { + this.s = s; + n = s.length(); + } + public void close() throws IOException { + i = n; + } + public int read(char[] cbuf, int off, int len) throws IOException { + int j = 0; + for (; j < len && i < n; ++j, ++i) + cbuf[off+j] = s.charAt(i); + return j > 0 || len == 0 ? j : -1; + } + } + + /** Simple converter from Reader to InputStream using UTF8 encoding that will work + * on both JME and JSE. + */ + static class UTF8Stream extends InputStream { + final char[] c = new char[32]; + final byte[] b = new byte[96]; + int i = 0, j = 0; + final Reader r; + UTF8Stream(Reader r) { + this.r = r; + } + public int read() throws IOException { + if (i < j) + return c[i++]; + int n = r.read(c); + if (n < 0) + return -1; + j = LuaString.encodeToUtf8(c, n, b, i = 0); + return b[i++]; + } + } + + /** Simple InputStream that supports mark. + * Used to examine an InputStream for a 4-byte binary lua signature, + * and fall back to text input when the signature is not found. + */ + static class MarkStream extends InputStream { + private int[] b; + private int i = 0, j = 0; + private final InputStream s; + MarkStream(InputStream s) { + this.s = s; + } + public int read() throws IOException { + if (i < j) + return b[i++]; + final int c = s.read(); + if (c < 0) + return -1; + if (j < b.length) { + b[j++] = c; + i = j; + } + return c; + } + public synchronized void mark(int n) { + b = new int[n]; + i = j = 0; + } + public boolean markSupported() { + return true; + } + public synchronized void reset() throws IOException { + i = 0; + } + } + } diff --git a/src/core/org/luaj/vm2/LoadState.java b/src/core/org/luaj/vm2/LoadState.java index 46c27287..f32cb392 100644 --- a/src/core/org/luaj/vm2/LoadState.java +++ b/src/core/org/luaj/vm2/LoadState.java @@ -35,10 +35,10 @@ import java.io.InputStream; *

* A simple pattern for loading and executing code is *

 {@code
-* LuaValue _G = JsePlatform.standardGlobals();
-* LoadState.load( new FileInputStream("main.lua"), "main.lua", _G ).call();
+* Globals _G = JsePlatform.standardGlobals();
+* _G.load(new FileReader("main.lua"), "main.lua", _G ).call();
 * } 
-* This should work regardless of which {@link LuaCompiler} +* This should work regardless of which {@link Globals.Compiler} * has been installed. *

* @@ -52,7 +52,7 @@ import java.io.InputStream; * for example: *

 {@code
 * LuaValue _G = JsePlatform.standardGlobals();
-* LuaJC.install();
+* LuaJC.install(_G);
 * LoadState.load( new FileInputStream("main.lua"), "main.lua", _G ).call();
 * } 
* @@ -64,7 +64,10 @@ import java.io.InputStream; * @see LuaC * @see LuaJC */ -public class LoadState { +public class LoadState implements Globals.Undumper { + + /** Shared instance of Globals.Undumper to use loading prototypes from binary lua files */ + public static final Globals.Undumper instance = new LoadState(); /** format corresponding to non-number-patched lua, all numbers are floats or doubles */ public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES = 0; @@ -89,22 +92,9 @@ public class LoadState { public static final int LUA_TTHREAD = 8; public static final int LUA_TVALUE = 9; - /** Interface for the compiler, if it is installed. - *

- * See the {@link LuaClosure} documentation for examples of how to use the compiler. - * @see LuaClosure - * @see #load(InputStream, String, LuaValue) - * */ - public interface LuaCompiler { - - /** 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 */ - public static LuaCompiler compiler = null; - + /** The character encoding to use for file encoding. Null means the default encoding */ + public static String encoding = null; + /** Signature byte indicating the file is a compiled binary chunk */ public static final byte[] LUA_SIGNATURE = { '\033', 'L', 'u', 'a' }; @@ -150,7 +140,11 @@ public class LoadState { /** Read buffer */ private byte[] buf = new byte[512]; - + + /** Install this class as the standard Globals.Undumper for the supplied Globals */ + public static void install(Globals globals) { + globals.undumper = instance; + } /** Load a 4-byte int value from the input stream * @return the int value laoded. @@ -369,60 +363,22 @@ public class LoadState { } /** - * Load lua in either binary or text from an input stream. - * @param firstByte the first byte of the input stream + * Load input stream as a lua binary chunk if the first 4 bytes are the lua binary signature. * @param stream InputStream to read, after having read the first byte already * @param name Name to apply to the loaded chunk - * @param mode "b" for binary only, "t" for text only, "bt" for binary or text. - * @return {@link Prototype} that was loaded - * @throws IllegalArgumentException if the signature is bac + * @return {@link Prototype} that was loaded, or null if the first 4 bytes were not the lua signature. * @throws IOException if an IOException occurs */ - public static LuaFunction load( InputStream stream, String name, String mode, LuaValue env ) throws IOException { - if ( compiler != null ) - 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 ); - } - } - - /** - * Load lua in the default mode "bt" from an input stream. - * @param firstByte the first byte of the input stream - * @param stream InputStream to read, after having read the first byte already - * @param name Name to apply to the loaded chunk - * @return {@link Prototype} that was loaded - * @throws IllegalArgumentException if the signature is bac - * @throws IOException if an IOException occurs - */ - public static LuaFunction load( InputStream stream, String name, LuaValue env ) throws IOException { - return load(stream, name, "bt", env); - } - - /** - * Load lua thought to be a binary chunk from its first byte from an input stream. - * @param firstByte the first byte of the input stream - * @param stream InputStream to read, after having read the first byte already - * @param name Name to apply to the loaded chunk - * @return {@link Prototype} that was loaded - * @throws IllegalArgumentException if the signature is bac - * @throws IOException if an IOException occurs - */ - public static Prototype loadBinaryChunk( int firstByte, InputStream stream, String name ) throws IOException { - + public Prototype undump(InputStream stream, String chunkname) throws IOException { // check rest of signature - if ( firstByte != LUA_SIGNATURE[0] + if ( stream.read() != LUA_SIGNATURE[0] || stream.read() != LUA_SIGNATURE[1] || stream.read() != LUA_SIGNATURE[2] || stream.read() != LUA_SIGNATURE[3] ) - throw new IllegalArgumentException("bad signature"); + return null; // load file as a compiled chunk - String sname = getSourceName(name); + String sname = getSourceName(chunkname); LoadState s = new LoadState( stream, sname ); s.loadHeader(); @@ -457,4 +413,9 @@ public class LoadState { this.name = name; this.is = new DataInputStream( stream ); } + + private LoadState() { + this.name = ""; + this.is = null; + } } diff --git a/src/core/org/luaj/vm2/LuaString.java b/src/core/org/luaj/vm2/LuaString.java index 1557e3a2..6bac4180 100644 --- a/src/core/org/luaj/vm2/LuaString.java +++ b/src/core/org/luaj/vm2/LuaString.java @@ -26,6 +26,7 @@ import java.io.ByteArrayInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.PrintStream; import org.luaj.vm2.lib.MathLib; import org.luaj.vm2.lib.StringLib; @@ -48,7 +49,7 @@ import org.luaj.vm2.lib.StringLib; * When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed. * The functions * {@link LuaString#lengthAsUtf8(char[]), - * {@link LuaString#encodeToUtf8(char[], byte[], int)}, and + * {@link LuaString#encodeToUtf8(char[], int, byte[], int)}, and * {@link LuaString#decodeAsUtf8(byte[], int, int) * are used to convert back and forth between UTF8 byte arrays and character arrays. * @@ -108,7 +109,7 @@ public class LuaString extends LuaValue { public static LuaString valueOf(String string) { char[] c = string.toCharArray(); byte[] b = new byte[lengthAsUtf8(c)]; - encodeToUtf8(c, b, 0); + encodeToUtf8(c, c.length, b, 0); return valueOf(b, 0, b.length); } @@ -143,20 +144,31 @@ public class LuaString extends LuaValue { /** Construct a {@link LuaString} using the supplied characters as byte values. *

- * Only th elow-order 8-bits of each character are used, the remainder is ignored. + * Only the low-order 8-bits of each character are used, the remainder is ignored. *

* This is most useful for constructing byte sequences that do not conform to UTF8. * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. * @return {@link LuaString} wrapping a copy of the byte buffer */ public static LuaString valueOf(char[] bytes) { - int n = bytes.length; - byte[] b = new byte[n]; - for ( int i=0; i + * Only the low-order 8-bits of each character are used, the remainder is ignored. + *

+ * This is most useful for constructing byte sequences that do not conform to UTF8. + * @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array. + * @return {@link LuaString} wrapping a copy of the byte buffer + */ + public static LuaString valueOf(char[] bytes, int off, int len) { + byte[] b = new byte[len]; + for ( int i=0; i @@ -556,7 +568,7 @@ public class LuaString extends LuaValue { * @param length number of bytes to convert * @return Java String corresponding to the value of bytes interpreted using UTF8 * @see #lengthAsUtf8(char[]) - * @see #encodeToUtf8(char[], byte[], int) + * @see #encodeToUtf8(char[], int, byte[], int) * @see #isValidUtf8() */ public static String decodeAsUtf8(byte[] bytes, int offset, int length) { @@ -581,7 +593,7 @@ public class LuaString extends LuaValue { * Count the number of bytes required to encode the string as UTF-8. * @param chars Array of unicode characters to be encoded as UTF-8 * @return count of bytes needed to encode using UTF-8 - * @see #encodeToUtf8(char[], byte[], int) + * @see #encodeToUtf8(char[], int, byte[], int) * @see #decodeAsUtf8(byte[], int, int) * @see #isValidUtf8() */ @@ -601,16 +613,18 @@ public class LuaString extends LuaValue { * The string should be measured first with lengthAsUtf8 * to make sure the given byte array is large enough. * @param chars Array of unicode characters to be encoded as UTF-8 + * @param nchars Number of characters in the array to convert. * @param bytes byte array to hold the result * @param off offset into the byte array to start writing + * @return number of bytes converted. * @see #lengthAsUtf8(char[]) * @see #decodeAsUtf8(byte[], int, int) * @see #isValidUtf8() */ - public static void encodeToUtf8(char[] chars, byte[] bytes, int off) { - final int n = chars.length; + public static int encodeToUtf8(char[] chars, int nchars, byte[] bytes, int off) { char c; - for ( int i=0, j=off; i buff.length ) buff = LuaC.realloc( buff, nbuff*2+1 ); - buff[nbuff++] = (byte) c; + buff[nbuff++] = (char) c; } @@ -272,12 +273,11 @@ public class LexState { // only called by new_localvarliteral() for var names. LuaString newstring( String s ) { - byte[] b = s.getBytes(); - return L.newTString(b, 0, b.length); + return L.newTString(s); } - LuaString newstring( byte[] bytes, int offset, int len ) { - return L.newTString( bytes, offset, len ); + LuaString newstring( char[] chars, int offset, int len ) { + return L.newTString(new String(chars, offset, len)); } void inclinenumber() { @@ -327,9 +327,9 @@ public class LexState { return true; } - void buffreplace(byte from, byte to) { + void buffreplace(char from, char to) { int n = nbuff; - byte[] p = buff; + char[] p = buff; while ((--n) >= 0) if (p[n] == from) p[n] = to; @@ -477,7 +477,7 @@ public class LexState { } } if (seminfo != null) - seminfo.ts = newstring(buff, 2 + sep, nbuff - 2 * (2 + sep)); + seminfo.ts = L.newTString(LuaString.valueOf(buff, 2 + sep, nbuff - 2 * (2 + sep))); } int hexvalue(int c) { @@ -574,7 +574,7 @@ public class LexState { } } save_and_next(); /* skip delimiter */ - seminfo.ts = newstring(buff, 1, nbuff - 2); + seminfo.ts = L.newTString(LuaString.valueOf(buff, 1, nbuff-2)); } int llex(SemInfo seminfo) { @@ -845,7 +845,7 @@ public class LexState { if (t.token == TK_NAME || t.token == TK_STRING) { LuaString ts = t.seminfo.ts; // TODO: is this necessary? - newstring(ts.m_bytes, 0, ts.m_length); + L.cachedLuaString(t.seminfo.ts); } } diff --git a/src/core/org/luaj/vm2/compiler/LuaC.java b/src/core/org/luaj/vm2/compiler/LuaC.java index 349620cd..87cea448 100644 --- a/src/core/org/luaj/vm2/compiler/LuaC.java +++ b/src/core/org/luaj/vm2/compiler/LuaC.java @@ -25,7 +25,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.Hashtable; -import org.luaj.vm2.LoadState; +import org.luaj.vm2.Globals; import org.luaj.vm2.LocVars; import org.luaj.vm2.Lua; import org.luaj.vm2.LuaClosure; @@ -35,7 +35,7 @@ import org.luaj.vm2.LuaString; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Prototype; import org.luaj.vm2.Upvaldesc; -import org.luaj.vm2.LoadState.LuaCompiler; +import org.luaj.vm2.lib.BaseLib; /** * Compiler for Lua. @@ -45,7 +45,7 @@ import org.luaj.vm2.LoadState.LuaCompiler; * and optionaly instantiates a {@link LuaClosure} around the result * using a user-supplied environment. *

- * Implements the {@link LuaCompiler} interface for loading + * Implements the {@link Globals.Compiler} interface for loading * initialized chunks, which is an interface common to * lua bytecode compiling and java bytecode compiling. *

@@ -66,7 +66,7 @@ import org.luaj.vm2.LoadState.LuaCompiler; * @see LuaCompiler * @see Prototype */ -public class LuaC extends Lua implements LuaCompiler { +public class LuaC extends Lua implements Globals.Compiler, Globals.Loader { public static final LuaC instance = new LuaC(); @@ -74,8 +74,9 @@ public class LuaC extends Lua implements LuaCompiler { * try to use it when handed bytes that are * not already a compiled lua chunk. */ - public static void install() { - org.luaj.vm2.LoadState.compiler = instance; + public static void install(Globals g) { + g.compiler = instance; + g.loader = instance; } protected static void _assert(boolean b) { @@ -213,6 +214,13 @@ public class LuaC extends Lua implements LuaCompiler { return a; } + static char[] realloc(char[] v, int n) { + char[] a = new char[n]; + if ( v != null ) + System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); + return a; + } + public int nCcalls; Hashtable strings; @@ -221,29 +229,25 @@ public class LuaC extends Lua implements LuaCompiler { private LuaC(Hashtable strings) { this.strings = strings; } - - /** Load into a Closure or LuaFunction, with the supplied initial environment */ - public LuaFunction load(InputStream stream, String name, LuaValue env) throws IOException { - Prototype p = compile( stream, name ); - return new LuaClosure( p, env ); - } - /** 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); + /** Compile lua source into a Prototype. + * @param stream InputStream representing the text source conforming to lua source syntax. + * @param chunkname String name of the chunk to use. + * @return Prototype representing the lua chunk for this source. + * @throws IOException + */ + public Prototype compile(InputStream stream, String chunkname) throws IOException { + return (new LuaC(new Hashtable())).luaY_parser(stream, chunkname); } /** Parse the input */ - private Prototype luaY_parser(int firstByte, InputStream z, String name) { + private Prototype luaY_parser(InputStream z, String name) throws IOException{ LexState lexstate = new LexState(this, z); FuncState funcstate = new FuncState(); // lexstate.buff = buff; lexstate.fs = funcstate; - lexstate.setinput( this, firstByte, z, (LuaString) LuaValue.valueOf(name) ); + lexstate.setinput( this, z.read(), z, (LuaString) LuaValue.valueOf(name) ); /* main func. is always vararg */ funcstate.f = new Prototype(); funcstate.f.source = (LuaString) LuaValue.valueOf(name); @@ -256,25 +260,28 @@ public class LuaC extends Lua implements LuaCompiler { } // look up and keep at most one copy of each string - public LuaString newTString(byte[] bytes, int offset, int len) { - LuaString tmp = LuaString.valueOf(bytes, offset, len); - LuaString v = (LuaString) strings.get(tmp); - if ( v == null ) { - // must copy bytes, since bytes could be from reusable buffer - byte[] copy = new byte[len]; - System.arraycopy(bytes, offset, copy, 0, len); - v = LuaString.valueOf(copy); - strings.put(v, v); - } - return v; + public LuaString newTString(String s) { + return cachedLuaString(LuaString.valueOf(s)); + } + + // look up and keep at most one copy of each string + public LuaString newTString(LuaString s) { + return cachedLuaString(s); + } + + public LuaString cachedLuaString(LuaString s) { + LuaString c = (LuaString) strings.get(s); + if (c != null) + return c; + strings.put(s, s); + return s; } public String pushfstring(String string) { return string; } - public LuaFunction load(Prototype p, String filename, LuaValue env) { - return new LuaClosure( p, env ); + public LuaFunction load(Prototype prototype, String chunkname, LuaValue env) throws IOException { + return new LuaClosure(prototype, env); } - } diff --git a/src/core/org/luaj/vm2/lib/BaseLib.java b/src/core/org/luaj/vm2/lib/BaseLib.java index 7be31f69..c246def7 100644 --- a/src/core/org/luaj/vm2/lib/BaseLib.java +++ b/src/core/org/luaj/vm2/lib/BaseLib.java @@ -228,9 +228,9 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder { public Varargs invoke(Varargs args) { LuaValue tostring = globals.get("tostring"); for ( int i=1, n=args.narg(); i<=n; i++ ) { - if ( i>1 ) globals.STDOUT.write( '\t' ); + if ( i>1 ) globals.STDOUT.print( '\t' ); LuaString s = tostring.call( args.arg(i) ).strvalue(); - globals.STDOUT.write( s.m_bytes, s.m_offset, s.m_length ); + globals.STDOUT.print(s.tojstring()); } globals.STDOUT.println(); return NONE; @@ -438,7 +438,7 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder { try { if ( is == null ) return varargsOf(NIL, valueOf("not found: "+chunkname)); - return LoadState.load(is, chunkname, mode, env); + return globals.load(is, chunkname, mode, env); } catch (Exception e) { return varargsOf(NIL, valueOf(e.getMessage())); } diff --git a/src/core/org/luaj/vm2/lib/DebugLib.java b/src/core/org/luaj/vm2/lib/DebugLib.java index 83a5048e..82fa0857 100644 --- a/src/core/org/luaj/vm2/lib/DebugLib.java +++ b/src/core/org/luaj/vm2/lib/DebugLib.java @@ -22,7 +22,6 @@ package org.luaj.vm2.lib; import org.luaj.vm2.Globals; -import org.luaj.vm2.LoadState.LuaCompiler; import org.luaj.vm2.Lua; import org.luaj.vm2.LuaBoolean; import org.luaj.vm2.LuaClosure; diff --git a/src/core/org/luaj/vm2/lib/OsLib.java b/src/core/org/luaj/vm2/lib/OsLib.java index 632eff4c..1e23e112 100644 --- a/src/core/org/luaj/vm2/lib/OsLib.java +++ b/src/core/org/luaj/vm2/lib/OsLib.java @@ -151,7 +151,7 @@ public class OsLib extends TwoArgFunction { tbl.set("min", LuaValue.valueOf(d.get(Calendar.MINUTE))); tbl.set("sec", LuaValue.valueOf(d.get(Calendar.SECOND))); tbl.set("wday", LuaValue.valueOf(d.get(Calendar.DAY_OF_WEEK))); - tbl.set("yday", LuaValue.valueOf(d.get(Calendar.DAY_OF_YEAR))); + tbl.set("yday", LuaValue.valueOf(d.get(0x6))); // Day of year tbl.set("isdst", LuaValue.valueOf(isDaylightSavingsTime(d))); return tbl; } diff --git a/src/core/org/luaj/vm2/lib/PackageLib.java b/src/core/org/luaj/vm2/lib/PackageLib.java index 65960eb2..bfdae8a3 100644 --- a/src/core/org/luaj/vm2/lib/PackageLib.java +++ b/src/core/org/luaj/vm2/lib/PackageLib.java @@ -240,7 +240,7 @@ public class PackageLib extends TwoArgFunction { LuaString filename = v.arg1().strvalue(); // Try to load the file. - v = globals.loadFile(filename.tojstring()); + v = globals.loadfile(filename.tojstring()); if ( v.arg1().isfunction() ) return LuaValue.varargsOf(v.arg1(), filename); diff --git a/src/jme/org/luaj/vm2/lib/jme/JmePlatform.java b/src/jme/org/luaj/vm2/lib/jme/JmePlatform.java index ff9c793f..fedc6b09 100644 --- a/src/jme/org/luaj/vm2/lib/jme/JmePlatform.java +++ b/src/jme/org/luaj/vm2/lib/jme/JmePlatform.java @@ -24,7 +24,6 @@ package org.luaj.vm2.lib.jme; import org.luaj.vm2.compiler.LuaC; import org.luaj.vm2.Globals; import org.luaj.vm2.LoadState; -import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaThread; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.BaseLib; @@ -114,8 +113,8 @@ public class JmePlatform { _G.load(new StringLib()); _G.load(new CoroutineLib()); _G.load(new JmeIoLib()); - LuaC.install(); - _G.compiler = LuaC.instance; + LoadState.install(_G); + LuaC.install(_G); return _G; } diff --git a/src/jse/lua.java b/src/jse/lua.java index eb4896e2..aa161799 100644 --- a/src/jse/lua.java +++ b/src/jse/lua.java @@ -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 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 ) + 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 {@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(); * } * @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 ) { diff --git a/src/jse/org/luaj/vm2/script/LuaScriptEngine.java b/src/jse/org/luaj/vm2/script/LuaScriptEngine.java index ee44ff6b..e84d7793 100644 --- a/src/jse/org/luaj/vm2/script/LuaScriptEngine.java +++ b/src/jse/org/luaj/vm2/script/LuaScriptEngine.java @@ -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() ); diff --git a/src/jse/org/luaj/vm2/script/LuaScriptEngineFactory.java b/src/jse/org/luaj/vm2/script/LuaScriptEngineFactory.java index ac5b0a8b..83df7486 100644 --- a/src/jse/org/luaj/vm2/script/LuaScriptEngineFactory.java +++ b/src/jse/org/luaj/vm2/script/LuaScriptEngineFactory.java @@ -38,7 +38,6 @@ public class LuaScriptEngineFactory implements ScriptEngineFactory { }; private static final String [] MIMETYPES = { - "text/plain", "text/lua", "application/lua" }; diff --git a/src/jse/org/luaj/vm2/script/LuajContext.java b/src/jse/org/luaj/vm2/script/LuajContext.java index 1b940987..7d9393d5 100644 --- a/src/jse/org/luaj/vm2/script/LuajContext.java +++ b/src/jse/org/luaj/vm2/script/LuajContext.java @@ -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. *

* 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; diff --git a/test/java/org/luaj/luajc/TestLuaJ.java b/test/java/org/luaj/luajc/TestLuaJ.java index c72a7c71..2c670577 100644 --- a/test/java/org/luaj/luajc/TestLuaJ.java +++ b/test/java/org/luaj/luajc/TestLuaJ.java @@ -21,14 +21,10 @@ ******************************************************************************/ package org.luaj.luajc; -import java.io.ByteArrayInputStream; -import java.io.InputStream; - -import org.luaj.vm2.LuaTable; +import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Print; import org.luaj.vm2.Prototype; -import org.luaj.vm2.compiler.LuaC; import org.luaj.vm2.lib.jse.JsePlatform; /** Test the plain old bytecode interpreter */ @@ -51,11 +47,10 @@ public class TestLuaJ { System.out.println(script); // create an environment to run in - LuaTable _G = JsePlatform.standardGlobals(); + Globals _G = JsePlatform.standardGlobals(); // compile into a chunk, or load as a class - InputStream is = new ByteArrayInputStream( script.getBytes() ); - LuaValue chunk = LuaC.instance.load(is, "script", _G); + LuaValue chunk = _G.load(script, "script"); // The loaded chunk should be a closure, which contains the prototype. print( chunk.checkclosure().p ); diff --git a/test/java/org/luaj/luajc/TestLuaJC.java b/test/java/org/luaj/luajc/TestLuaJC.java index fd62b085..b7650244 100644 --- a/test/java/org/luaj/luajc/TestLuaJC.java +++ b/test/java/org/luaj/luajc/TestLuaJC.java @@ -51,14 +51,14 @@ public class TestLuaJC { _G = JsePlatform.standardGlobals(); // print the chunk as a closure, and pretty-print the closure. - LuaValue f = _G.loadFile(filename).arg1(); + LuaValue f = _G.loadfile(filename).arg1(); Prototype p = f.checkclosure().p; Print.print(p); // load into a luajc java-bytecode based chunk by installing the LuaJC compiler first if ( ! (args.length>0 && args[0].equals("nocompile")) ) { - LuaJC.install(); - f = _G.loadFile(filename).arg1(); + LuaJC.install(_G); + f = _G.loadfile(filename).arg1(); } // call with arguments @@ -80,7 +80,7 @@ public class TestLuaJC { String destdir = "."; InputStream is = _G.FINDER.findResource(filename); - Hashtable t = LuaJC.getInstance().compileAll(is, filename, filename, true); + Hashtable t = LuaJC.instance.compileAll(is, filename, filename, _G, true); // write out the chunk for ( Enumeration e = t.keys(); e.hasMoreElements(); ) { diff --git a/test/junit/org/luaj/vm2/CompatibiltyTest.java b/test/junit/org/luaj/vm2/CompatibiltyTest.java index 2f0eadf5..36ae746b 100644 --- a/test/junit/org/luaj/vm2/CompatibiltyTest.java +++ b/test/junit/org/luaj/vm2/CompatibiltyTest.java @@ -107,7 +107,7 @@ public class CompatibiltyTest extends TestSuite { protected void setUp() throws Exception { super.setUp(); System.setProperty("JME", "false"); - LuaJC.install(); + LuaJC.install(globals); } // not supported on this platform - don't test public void testDebugLib() {} diff --git a/test/junit/org/luaj/vm2/FragmentsTest.java b/test/junit/org/luaj/vm2/FragmentsTest.java index 3972fc9e..ab33ba29 100644 --- a/test/junit/org/luaj/vm2/FragmentsTest.java +++ b/test/junit/org/luaj/vm2/FragmentsTest.java @@ -21,13 +21,13 @@ ******************************************************************************/ package org.luaj.vm2; -import java.io.ByteArrayInputStream; -import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.luaj.vm2.compiler.LuaC; +import org.luaj.vm2.lib.jse.JsePlatform; import org.luaj.vm2.luajc.LuaJC; /** @@ -64,16 +64,18 @@ public class FragmentsTest extends TestSuite { public void runFragment( Varargs expected, String script ) { try { String name = getName(); - Globals _G = org.luaj.vm2.lib.jse.JsePlatform.debugGlobals(); - InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8")); + Globals _G = JsePlatform.debugGlobals(); + Reader reader = new StringReader(script); LuaValue chunk ; switch ( TEST_TYPE ) { case TEST_TYPE_LUAJC: - chunk = LuaJC.getInstance().load(is,name,_G); + LuaJC.install(_G); + chunk = _G.load(reader, name); break; default: - chunk = LuaC.instance.load( is, name, _G ); - Print.print(((LuaClosure)chunk).p); + Prototype p = _G.compilePrototype(reader, name); + chunk = new LuaClosure(p, _G); + Print.print(p); break; } Varargs actual = chunk.invoke(); diff --git a/test/junit/org/luaj/vm2/LuaOperationsTest.java b/test/junit/org/luaj/vm2/LuaOperationsTest.java index 8adc4574..03d0144c 100644 --- a/test/junit/org/luaj/vm2/LuaOperationsTest.java +++ b/test/junit/org/luaj/vm2/LuaOperationsTest.java @@ -21,8 +21,8 @@ ******************************************************************************/ package org.luaj.vm2; -import java.io.ByteArrayInputStream; -import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; import java.lang.reflect.InvocationTargetException; import junit.framework.TestCase; @@ -130,9 +130,9 @@ public class LuaOperationsTest extends TestCase { public Prototype createPrototype( String script, String name ) { try { - LuaTable _G = org.luaj.vm2.lib.jse.JsePlatform.standardGlobals(); - InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8")); - return LuaC.instance.compile(is, name); + Globals _G = org.luaj.vm2.lib.jse.JsePlatform.standardGlobals(); + Reader reader = new StringReader(script); + return _G.compilePrototype(reader, name); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/test/junit/org/luaj/vm2/OrphanedThreadTest.java b/test/junit/org/luaj/vm2/OrphanedThreadTest.java index 81c96a1b..14cecb4c 100644 --- a/test/junit/org/luaj/vm2/OrphanedThreadTest.java +++ b/test/junit/org/luaj/vm2/OrphanedThreadTest.java @@ -21,15 +21,10 @@ ******************************************************************************/ package org.luaj.vm2; -import java.io.ByteArrayInputStream; import java.lang.ref.WeakReference; import junit.framework.TestCase; -import org.luaj.vm2.LoadState; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Varargs; -import org.luaj.vm2.compiler.LuaC; import org.luaj.vm2.lib.OneArgFunction; import org.luaj.vm2.lib.jse.JsePlatform; @@ -74,8 +69,7 @@ public class OrphanedThreadTest extends TestCase { "arg = coroutine.yield(0)\n" + "print('leakage in closure.3, arg is '..arg)\n" + "return 'done'\n"; - LuaC.install(); - function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", "bt", globals); + function = globals.load(script, "script"); doTest(LuaValue.TRUE, LuaValue.ZERO); } @@ -90,8 +84,7 @@ public class OrphanedThreadTest extends TestCase { " return 'done'\n" + "end\n" + "print( 'pcall-closre.result:', pcall( f, ... ) )\n"; - LuaC.install(); - function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", "bt", globals); + function = globals.load(script, "script"); doTest(LuaValue.TRUE, LuaValue.ZERO); } @@ -107,8 +100,7 @@ public class OrphanedThreadTest extends TestCase { " return t[i]\n" + "end\n" + "load(f)()\n"; - LuaC.install(); - function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", "bt", globals); + function = globals.load(script, "script"); doTest(LuaValue.TRUE, LuaValue.ONE); } diff --git a/test/junit/org/luaj/vm2/ScriptDrivenTest.java b/test/junit/org/luaj/vm2/ScriptDrivenTest.java index 2ae2a476..3e0860a4 100644 --- a/test/junit/org/luaj/vm2/ScriptDrivenTest.java +++ b/test/junit/org/luaj/vm2/ScriptDrivenTest.java @@ -177,7 +177,7 @@ public class ScriptDrivenTest extends TestCase implements ResourceFinder { } } - protected LuaValue loadScript(String name, LuaTable _G) throws IOException { + protected LuaValue loadScript(String name, Globals _G) throws IOException { InputStream script = this.findResource(name+".lua"); if ( script == null ) fail("Could not load script for test case: " + name); @@ -188,10 +188,11 @@ public class ScriptDrivenTest extends TestCase implements ResourceFinder { LuaValue c = (LuaValue) Class.forName(name).newInstance(); return c; } else { - return LuaJC.getInstance().load( script, name, _G); + LuaJC.install(_G); + return _G.load(script, name, "bt", _G); } default: - return LoadState.load(script, "@"+name+".lua", "bt", _G); + return _G.load(script, "@"+name+".lua", "bt", _G); } } catch ( Exception e ) { e.printStackTrace(); diff --git a/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java b/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java index 9695506a..8f8de5e3 100644 --- a/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java +++ b/test/junit/org/luaj/vm2/compiler/AbstractUnitTests.java @@ -11,8 +11,8 @@ import java.net.URL; import junit.framework.TestCase; +import org.luaj.vm2.Globals; import org.luaj.vm2.LoadState; -import org.luaj.vm2.LuaTable; import org.luaj.vm2.Print; import org.luaj.vm2.Prototype; import org.luaj.vm2.lib.jse.JsePlatform; @@ -21,7 +21,7 @@ abstract public class AbstractUnitTests extends TestCase { private final String dir; private final String jar; - private LuaTable _G; + private Globals _G; public AbstractUnitTests(String zipdir, String zipfile, String dir) { URL zip = null; @@ -67,7 +67,7 @@ abstract public class AbstractUnitTests extends TestCase { // compile in memory InputStream is = new ByteArrayInputStream(lua); - Prototype p = LuaC.instance.compile(is, "@" + file); + Prototype p = _G.loadPrototype(is, "@" + file, "bt"); String actual = protoToString(p); // load expected value from jar @@ -109,7 +109,7 @@ abstract public class AbstractUnitTests extends TestCase { protected Prototype loadFromBytes(byte[] bytes, String script) throws IOException { InputStream is = new ByteArrayInputStream(bytes); - return LoadState.loadBinaryChunk(is.read(), is, script); + return _G.loadPrototype(is, script, "b"); } 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 7b5d9e0a..00c6d776 100644 --- a/test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java +++ b/test/junit/org/luaj/vm2/compiler/DumpLoadEndianIntTest.java @@ -6,13 +6,15 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; import junit.framework.TestCase; +import org.luaj.vm2.Globals; 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; import org.luaj.vm2.lib.jse.JsePlatform; @@ -28,7 +30,7 @@ public class DumpLoadEndianIntTest extends TestCase { private static final String withdoubles = "1234-#!-23.75"; private static final String withints = "1234-#!-23"; - private LuaTable _G; + private Globals _G; protected void setUp() throws Exception { super.setUp(); @@ -83,8 +85,8 @@ public class DumpLoadEndianIntTest extends TestCase { try { // compile into prototype - InputStream is = new ByteArrayInputStream(script.getBytes()); - Prototype p = LuaC.instance.compile(is, "script"); + Reader reader = new StringReader(script); + Prototype p = _G.compilePrototype(reader, "script"); // double check script result before dumping LuaFunction f = new LuaClosure(p, _G); @@ -107,8 +109,8 @@ public class DumpLoadEndianIntTest extends TestCase { byte[] dumped = baos.toByteArray(); // load again using compiler - is = new ByteArrayInputStream(dumped); - f = LoadState.load(is, "dumped", "bt", _G); + InputStream is = new ByteArrayInputStream(dumped); + f = _G.load(is, "dumped", "b", _G).checkfunction(); 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 e8b2ae1f..638f4c34 100644 --- a/test/junit/org/luaj/vm2/compiler/SimpleTests.java +++ b/test/junit/org/luaj/vm2/compiler/SimpleTests.java @@ -1,20 +1,16 @@ package org.luaj.vm2.compiler; -import java.io.ByteArrayInputStream; -import java.io.InputStream; - import junit.framework.TestCase; +import org.luaj.vm2.Globals; 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.lib.jse.JsePlatform; public class SimpleTests extends TestCase { - private LuaTable _G; + private Globals _G; protected void setUp() throws Exception { super.setUp(); @@ -23,8 +19,7 @@ public class SimpleTests extends TestCase { private void doTest( String script ) { try { - InputStream is = new ByteArrayInputStream( script.getBytes("UTF8") ); - LuaFunction c = LuaC.instance.load( is, "script", _G ); + LuaValue c = _G.load(script, "script"); c.call(); } catch ( Exception e ) { fail("i/o exception: "+e ); diff --git a/test/junit/org/luaj/vm2/lib/jse/LuajavaAccessibleMembersTest.java b/test/junit/org/luaj/vm2/lib/jse/LuajavaAccessibleMembersTest.java index 1bb2d99c..c0dccfe4 100644 --- a/test/junit/org/luaj/vm2/lib/jse/LuajavaAccessibleMembersTest.java +++ b/test/junit/org/luaj/vm2/lib/jse/LuajavaAccessibleMembersTest.java @@ -1,20 +1,13 @@ package org.luaj.vm2.lib.jse; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.security.Permission; - import junit.framework.TestCase; -import org.luaj.vm2.LuaFunction; -import org.luaj.vm2.LuaTable; +import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; -import org.luaj.vm2.compiler.LuaC; -import org.luaj.vm2.lib.jse.JsePlatform; public class LuajavaAccessibleMembersTest extends TestCase { - private LuaTable _G; + private Globals _G; protected void setUp() throws Exception { super.setUp(); @@ -23,8 +16,7 @@ public class LuajavaAccessibleMembersTest extends TestCase { private String invokeScript(String script) { try { - InputStream is = new ByteArrayInputStream( script.getBytes("UTF8") ); - LuaFunction c = LuaC.instance.load( is, "script", _G ); + LuaValue c = _G.load(script, "script"); return c.call().tojstring(); } catch ( Exception e ) { fail("exception: "+e ); diff --git a/test/junit/org/luaj/vm2/script/ScriptEngineTests.java b/test/junit/org/luaj/vm2/script/ScriptEngineTests.java index 4d2f3842..031896c0 100644 --- a/test/junit/org/luaj/vm2/script/ScriptEngineTests.java +++ b/test/junit/org/luaj/vm2/script/ScriptEngineTests.java @@ -21,7 +21,6 @@ ******************************************************************************/ package org.luaj.vm2.script; -import java.io.ByteArrayInputStream; import java.io.CharArrayReader; import java.io.CharArrayWriter; import java.io.Reader; @@ -100,8 +99,8 @@ public class ScriptEngineTests extends TestSuite { return new SimpleBindings(); } public void setUp() { + System.setProperty("org.luaj.luajc", "true"); super.setUp(); - org.luaj.vm2.luajc.LuaJC.install(); } public void testCompiledFunctionIsNotClosure() throws ScriptException { CompiledScript cs = ((Compilable)e).compile("return 'foo'");