-
Notifications
You must be signed in to change notification settings - Fork 10
headius/luaj
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Getting Started with LuaJ</title> <link rel="stylesheet" type="text/css" href="http://www.lua.org/lua.css"> <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1"> </head> <body> <hr> <h1> <a href="README.html"><img src="http://sourceforge.net/dbimage.php?id=196139" alt="" border="0"></a> Getting Started with LuaJ </h1> James Roseborough, Ian Farmer, Version 2.0.2 <p> <small> Copyright © 2009-2010 Luaj.org. Freely available under the terms of the <a href="http://sourceforge.net/dbimage.php?id=196142">Luaj license</a>. </small> <hr> <p> <a href="#1">introduction</a> · <a href="#2">examples</a> · <a href="#3">concepts</a> · <a href="#4">libraries</a> · <a href="#5">luaj api</a> · <a href="#6">parser</a> · <a href="#7">building</a> · <a href="#8">downloads</a> · <a href="#9">release notes</a> <!-- ====================================================================== --> <p> <h1>1 - <a name="1">Introduction</a></h1> <h2>Goals of Luaj</h2> Luaj is a lua interpreter based on the 5.1.x version of lua with the following goals in mind: <ul> <li>Java-centric implementation of lua vm built to leverage standard Java features. <li>Lightweight, high performance execution of lua. <li>Multi-platform to be able to run on JME, JSE, or JEE environments. <li>Complete set of libraries and tools for integration into real-world projects. <li>Dependable due to sufficient unit testing of vm and library features. </ul> <h2>Differences with 1.0</h2> In addition to the basic goals of luaj, version 2.0 is aimed at improving on the 1.0 vm in the following aspects. <ul> <li>Support for compiling lua source code into Java source code. <li>Support for compiling lua bytecode directly into Java bytecode. <li>Improved performance of of lua bytecode processing. <li>Stackless vm design centered around dynamically typed objects. <li>More alignment with C API (see <a href="names.csv">names.csv</a> for details) <li>Improved class and package naming conventions. <li>Improved unit tests of core classes. <li>Improved quality due to major redesign and rewrite of core elements. <li>More complete implementation including weak keys and values, and all metatags. </ul> <h2>Performance</h2> Good performance is a major goal of luaj. The following table provides measured execution times on a subset of benchmarks from <a href="http://shootout.alioth.debian.org/">the computer language benchmarks game</a> in comparison with the standard C distribution. <table cellspacing="10"><tr><td><table> <tr valign="top"> <td><u>Project</td> <td><u>Version</td> <td><u>Mode</td> <td rowspan="9"> </td> <td colspan="4" align="center"><u>Benchmark execution time (sec)</td> <td rowspan="9"> </td> <td><u>Language</td> <td><u>Sample command</td> </tr> <tr valign="top"> <td colspan="2"></td> <td></td> <td><em>binarytrees 15</em></td> <td><em>fannkuch 10</em></td> <td><em>nbody 1e6</em></td> <td><em>nsieve 9</em></td> </tr> <tr valign="top"> <td>luaj</td> <td>2.0</td> <td>-b (luajc)</td> <td>2.980</td> <td>5.073</td> <td>16.794</td> <td>11.274</td> <td>Java</td> <td>java -cp luaj-jse-2.0.2.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr> <tr valign="top"> <td></td> <td></td> <td>-j (lua2java)</td> <td>4.463</td> <td>5.884</td> <td>16.701</td> <td>13.789</td> <td></td> <td>java -cp luaj-jse-2.0.2.jar lua <b>-j</b> fannkuch.lua 10</td></tr> <tr valign="top"> <td></td> <td></td> <td>-n (interpreted)</td> <td>12.838</td> <td>23.290</td> <td>36.894</td> <td>15.163</td> <td></td> <td>java -cp luaj-jse-2.0.2.jar lua -n fannkuch.lua 10</td></tr> <tr valign="top"> <td>lua</td> <td>5.1.4</td> <td></td> <td>17.637</td> <td>16.044</td> <td>15.201</td> <td>5.477</td> <td>C</td> <td>lua fannkuch.lua 10</td></tr> <tr valign="top"> <td>jill</td> <td>1.0.1</td> <td></td> <td>44.512</td> <td>54.630</td> <td>72.172</td> <td>20.779</td> <td>Java</td> <td></td></tr> <tr valign="top"> <td>kahlua</td> <td>1.0</td> <td>jse</td> <td>22.963</td> <td>63.277</td> <td>68.223</td> <td>21.529</td> <td>Java</td> <td></td></tr> <tr valign="top"> <td>mochalua</td> <td>1.0</td> <td></td> <td>50.457</td> <td>70.368</td> <td>82.868</td> <td>41.262</td> <td>Java</td> <td></td></tr> </table></td></tr></table> Luaj in interpreted mode performs well for the benchmarks, and even better when source-to-source (lua2java) or bytecode-to-bytecode (luajc) compilers are used, and actually executes <em>faster</em> than C-based lua in some cases. It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for all benchmarks tested. <h1>2 - <a name="2">Simple Examples</a></h1> <h2>Run a lua script in Java SE</h2> <p> From the main distribution directory line type: <pre> java -cp lib/luaj-jse-2.0.2.jar lua examples/lua/hello.lua </pre> <p> You should see the following output: <pre> hello, world </pre> <h2>Compile lua source to lua bytecode</h2> <p> From the main distribution directory line type: <pre> java -cp lib/luaj-jse-2.0.2.jar luac examples/lua/hello.lua java -cp lib/luaj-jse-2.0.2.jar lua luac.out </pre> <p> The compiled output "luac.out" is lua bytecode and should run and produce the same result. <h2>Compile lua source to java source</h2> <p> Luaj can compile to lua source code to Java source code: <pre> java -cp lib/luaj-jse-2.0.2.jar lua2java -s examples/lua -d . hello.lua javac -cp lib/luaj-jse-2.0.2.jar hello.java java -cp "lib/luaj-jse-2.0.2.jar;." lua -l hello </pre> <p> The output <em>hello.java</em> is Java source, that implements the logic in hello.lua directly. Once <em>hello.java</em> is compiled into <em>hello.class</em> it can be required and used in place of the original lua script, but with better performance. There are no additional dependencies for compiling or running source-to-source compiled lua. <p> Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-j</em></b> option when run in JDK 1.5 or higher: <pre> java -cp lib/luaj-jse-2.0.2.jar lua -j examples/lua/hello.lua </pre> <h2>Compile lua bytecode to java bytecode</h2> <p> Luaj can compile lua sources or binaries directly to java bytecode if the bcel library is on the class path. From the main distribution directory line type: <pre> ant bcel-lib java -cp "lib/luaj-jse-2.0.2.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua java -cp "lib/luaj-jse-2.0.2.jar;." lua -l hello </pre> <p> The output <em>hello.class</em> is Java bytecode, should run and produce the same result. There is no runtime dependency on the bcel library, but the compiled classes must be in the class path at runtime, unless runtime jit-compiling via luajc and bcel are desired (see later sections). <p> Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path: <pre> java -cp "lib/luaj-jse-2.0.2.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua </pre> <h2>Run a script in a Java Application</h2> <p> The following pattern is used within Java SE <pre> 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) ); </pre> <p> A simple example may be found in <pre> examples/jse/SampleJseMain.java </pre> <p> You must include the library <b>lib/luaj-jse-2.0.2.jar</b> in your class path. <h2>Run a script in a MIDlet</h2> <p> The for MIDlets the <em>JmePlatform</em> is used instead: <pre> 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) ); </pre> <p> The file must be a resource within within the midlet jar for <em>dofile()</em> to find it. Any files included via <em>require()</em> must also be part of the midlet resources. <p> A simple example may be found in <pre> examples/jme/SampleMIDlet.java </pre> <p> You must include the library <b>lib/luaj-jme-2.0.2.jar</b> in your midlet jar. <p> An ant script to build and run the midlet is in <pre> build-midlet.xml </pre> <p> You must install the wireless toolkit and define <em>WTK_HOME</em> for this script to work. <h2>Run a script using JSR-223 Dynamic Scripting</h2> <p> The standard use of JSR-223 scripting engines may be used: <pre> ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine e = mgr.getEngineByExtension(".lua"); e.put("x", 25); e.eval("y = math.sqrt(x)"); System.out.println( "y="+e.get("y") ); </pre> <p> All standard aspects of script engines including compiled statements should be supported. <p> You must include the library <b>lib/luaj-jse-2.0.2.jar</b> in your class path. <p> A working example may be found in <pre> examples/jse/ScriptEngineSample.java </pre> To compile and run it using Java 1.6 or higher: <pre> javac examples/jse/ScriptEngineSample.java java -cp "lib/luaj-jse-2.0.2.jar;examples/jse" ScriptEngineSample </pre> <h2>Excluding the lua bytecode compiler</h2> By default, the compiler is included whenever <em>standardGlobals()</em> or <em>debugGlobals()</em> are called. Without a compiler, files can still be executed, but they must be compiled elsewhere beforehand. The "luac" utility is provided in the jse jar for this purpose, or a standard lua compiler can be used. <p> To exclude the lua-to-lua-bytecode compiler, do not call <em>standardGlobals()</em> or <em>debugGlobals()</em> but instead initialize globals with including only those libraries that are needed and omitting the line: <pre> org.luaj.vm2.compiler.LuaC.install(); </pre> <h2>Including the Lua2Java lua-source-to-Java-source compiler</h2> <p> To compile from lua sources to Java sources for all lua loaded at runtime, install the Lua2Java compiler <em>after</em> globals have been created using: <pre> org.luaj.vm2.jse.lua2java.Lua2Java.install(); </pre> This uses the system Java compiler to compile from Java source to Java bytecode, and cannot compile lua binary files containing lua bytecode at runtime. <h2>Including the LuaJC lua-bytecode-to-Java-bytecode compiler</h2> <p> To compile from lua to Java bytecode for all lua loaded at runtime, install the LuaJC compiler <em>after</em> globals have been created using: <pre> org.luaj.vm2.jse.luajc.LuaJC.install(); </pre> <p> This will compile all lua bytecode into Java bytecode, regardless of if they are loaded as lua source or lua binary files. <p> The requires <em>bcel</em> to be on the class path, and the ClassLoader of JSE or CDC. <h1>3 - <a name="3">Concepts</a></h1> <h2>Globals</h2> The old notion of platform has been replaced with creation of globals. Two classes are provided to encapsulate common combinations of libraries. <h3>JsePlatform</h3> This class can be used as a factory for globals in a typical Java SE application. All standard libraries are included, as well as the luajava library. The default search path is the current directory, and the math operations include all those supported by Java SE. <h3>JmePlatform</h3> This class can be used to set up the basic environment for a Java ME application. The default search path is limited to the jar resources, and the math operations are limited to those supported by Java ME. All libraries are included except luajava, and the os, io, and math libraries are limited to those functions that can be supported on that platform. <h1>4 - <a name="4">Libraries</a></h1> <h2>Standard Libraries</h2> Libraries are coded to closely match the behavior specified in See <a href="http://www.lua.org/manual/5.1/">standard lua documentation</a> for details on the library API's <p> The following libraries are loaded by both <em>JsePlatform.standardGlobals()</em> and <em>JmePlatform.standardGlobals()</em>: <pre> base coroutine io math os package string table </pre> <p> The <em>JsePlatform.standardGlobals()</em> globals also include: <pre> luajava </pre> <p> The <em>JsePlatform.debugGlobals()</em> and <em>JsePlatform.debugGlobals()</em> functions produce globals that include: <pre> debug </pre> <h3>I/O Library</h3> The implementation of the <em>io</em> library differs by platform owing to platform limitations. <p> The <em>JmePlatform.standardGlobals()</em> instantiated the io library <em>io</em> in <pre> src/jme/org/luaj/vm2/lib/jme/JmeIoLib.java </pre> The <em>JsePlatform.standardGlobals()</em> includes support for random access and is in <pre> src/jse/org/luaj/vm2/lib/jse/JseIoLib.java </pre> <h3>OS Library</h3> The implementation of the <em>os</em> library also differs per platform. <p> The basic <em>os</em> library implementation us used by <em>JmePlatform</em> and is in: <pre> src/core/org/luaj/lib/OsLib.java </pre> A richer version for use by <em>JsePlatform</em> is : <pre> src/jse/org/luaj/vm2/lib/jse/JseOsLib.java </pre> Time is a represented as number of milliseconds since the epoch, and most time and date formatting, locales, and other features are not implemented. <h3>Debug Library</h3> The <em>debug</em> library is not included by default by <em>JmePlatform.standardGlobals()</em> or <em>JsePlatform.standardGlobsls()</em> . The functions <em>JmePlatform.debugGlobals()</em> and <em>JsePlatform.debugGlobsls()</em> create globals that contain the debug library in addition to the other standard libraries. To install dynamically from lua use java-class-based require:</em>: <pre> require 'org.luaj.vm2.lib.DebugLib' </pre> The <em>lua</em> command line utility includes the <em>debug</em> library by default. <h3>The Luajava Library</h3> The <em>JsePlatform.standardGlobals()</em> includes the <em>luajava</em> library, which simplifies binding to Java classes and methods. It is patterned after the original <a href="http://www.keplerproject.org/luajava/">luajava project</a>. <p> The following lua script will open a swiing frame on Java SE: <pre> jframe = luajava.bindClass( "javax.swing.JFrame" ) frame = luajava.newInstance( "javax.swing.JFrame", "Texts" ); frame:setDefaultCloseOperation(jframe.EXIT_ON_CLOSE) frame:setSize(300,400) frame:setVisible(true) </pre> <p> See a longer sample in <em>examples/lua/swingapp.lua</em> for details, or try running it using: <pre> java -cp lib/luaj-jse-2.0.2.jar lua examples/lua/swingapp.lua </pre> <p> The Java ME platform does not include this library, and it cannot be made to work because of the lack of a reflection API in Java SE. <p> The <em>lua</em> connand line tool includes <em>luajava</em>. <h1>5 - <a name="5">LuaJ API</a></h1> <h2>API Javadoc</h2> The javadoc for the main classes in the LuaJ API are on line at <pre> <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0</a> </pre> You can also build a local version from sources using <pre> ant doc </pre> <h2>LuaValue and Varargs</h2> All lua value manipulation is now organized around <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/LuaValue.html">LuaValue</a> which exposes the majority of interfaces used for lua computation. <pre> <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/LuaValue.html">org.luaj.vm2.LuaValue</a> </pre> <h3>Common Functions</h3> <em>LuaValue</em> exposes functions for each of the operations in LuaJ. Some commonly used functions and constants include: <pre> call(); // invoke the function with no arguments call(LuaValue arg1); // call the function with 1 argument invoke(Varargs arg); // call the function with variable arguments, variable return values get(int index); // get a table entry using an integer key get(LuaValue key); // get a table entry using an arbitrary key, may be a LuaInteger rawget(int index); // raw get without metatable calls valueOf(int i); // return LuaValue corresponding to an integer valueOf(String s); // return LuaValue corresponding to a String toint(); // return value as a Java int tojstring(); // return value as a Java String isnil(); // is the value nil NIL; // the value nil NONE; // a Varargs instance with no values </pre> <h2>Varargs</h2> The interface <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">Varargs</a> provides an abstraction for both a variable argument list and multiple return values. For convenience, <em>LuaValue</em> implements <em>Varargs</em> so a single value can be supplied anywhere variable arguments are expected. <pre> <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">org.luaj.vm2.Varargs</a> </pre> <h3>Common Functions</h3> <em>Varargs</em> exposes functions for accessing elements, and coercing them to specific types: <pre> narg(); // return number of arguments arg1(); // return the first argument arg(int n); // return the nth argument isnil(int n); // true if the nth argument is nil checktable(int n); // return table or throw error optlong(int n,long d); // return n if a long, d if no argument, or error if not a long </pre> See the <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/Varargs.html">Varargs</a> API for a complete list. <h2>LibFunction</h2> The simplest way to implement a function is to choose a base class based on the number of arguments to the function. LuaJ provides 5 base classes for this purpose, depending if the function has 0, 1, 2, 3 or variable arguments, and if it provide multiple return values. <pre> <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/ZeroArgFunction.html">org.luaj.vm2.lib.ZeroArgFunction</a> <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/OneArgFunction.html">org.luaj.vm2.lib.OneArgFunction</a> <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/TwoArgFunction.html">org.luaj.vm2.lib.TwoArgFunction</a> <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/ThreeArgFunction.html">org.luaj.vm2.lib.ThreeArgFunction</a> <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/lib/VarArgFunction.html">org.luaj.vm2.lib.VarArgFunction</a> </pre> Each of these functions has an abstract method that must be implemented, and argument fixup is done automatically by the classes as each Java function is invoked. <p> For example, to implement a "hello, world" function, we could supply: <pre> pubic class hello extends ZeroArgFunction { public LuaValue call() { env.get("print").call(valueOf("hello, world")); } } </pre> The value <em>env</em> is the environment of the function, and is normally supplied by the instantiating object whenever default loading is used. <p> Calling this function from lua could be done by: <pre> require( 'hello' )() </pre> while calling this function from Java would look like: <pre> new hello().call(); </pre> Note that in both the lua and Java case, extra arguments will be ignored, and the function will be called. Also, no virtual machine instance is necessary to call the function. To allow for arguments, or return multiple values, extend one of the other base classes. <h2>Closures</h2> Closures still exist in this framework, but are optional, and are only used to implement lua bytecode execution. <h1>6 - <a name="6">Parser</a></h1> <h2>Javacc Grammar</h2> A Javacc grammarwas developed to simplify the creation of Java-based parsers for the lua language. The grammar is specified for <a href="https://javacc.dev.java.net/">javacc version 5.0</a> because that tool generates standalone parsers that do not require a separate runtime. <p> A plain undecorated grammer that can be used for validation is available in <a href="grammar/Lua51.jj">grammar/Lua51.jj</a> while a grammar that generates a typed parse tree is in <a href="grammar/LuaParser.jj">grammar/LuaParser.jj</a> <h2>Creating a Parse Tree from Lua Source</h2> The default lu compiler does a single-pass compile of lua source to lua bytecode, so no explicit parse tree is produced. <p> To simplify the creation of abstract syntax trees from lua sources, the LuaParser class is generated as part of the JME build. To use it, provide an input stream, and invoke the root generator, which will return a Chunk if the file is valid, or throw a ParseException if there is a syntax error. <p> For example, to parse a file and print all variable names, use code like: <pre> try { String file = "main.lua"; LuaParser parser = new LuaParser(new FileInputStream(file)); Chunk chunk = parser.Chunk(); chunk.accept( new Visitor() { public void visit(Exp.NameExp exp) { System.out.println("Name in use: "+exp.name.name); } } ); } catch ( ParseException e ) { System.out.println( "parse failed: "+e ); } </pre> <p> See the <a href="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/ast/package-summary.html">org.luaj.vm2.ast package</a> javadoc for the API relating to the syntax tree that is produced. <h1>7 - <a name="7">Building and Testing</a></h1> <h2>Building the jars</h2> An ant file is included in the root directory which builds the libraries by default. <p> Other targets exist for creating distribution file an measuring code coverage of unit tests. <h2>Unit tests</h2> <p> The main luaj JUnit tests are organized into a JUnit 3 suite: <pre> test/junit/org/luaj/vm2/AllTests.lua </pre> <p> Unit test scripts can be found in these locations <pre> test/lua/*.lua test/junit/org/luaj/vm2/compiler/lua5.1-tests.zip test/junit/org/luaj/vm2/compiler/regressions.zip test/junit/org/luaj/vm2/vm1/luajvm1-tests.zip </pre> <h2>Code coverage</h2> <p> A build script for running unit tests and producing code coverage statistics is in <pre> build-coverage.xml </pre> It relies on the cobertura code coverage library. <h1>8 - <a name="8">Downloads</a></h1> <h2>Downloads and Project Pages</h2> Downloads for all version available on SourceForge or LuaForge. Sources are hosted on SourceForge and available via sourceforge.net <br/> <pre> <a href="http://luaj.sourceforge.net/">SourceForge Luaj Project Page</a> <a href="http://sourceforge.net/project/platformdownload.php?group_id=197627">SourceForge Luaj Download Area</a> </pre> <p/> and LuaForge: <pre> <a href="http://luaforge.net/projects/luaj/">LuaForge Luaj Project Page</a> <a href="http://luaforge.net/frs/?group_id=457">LuaForge Luaj Project Area</a> </pre> <h1>9 - <a name="9">Release Notes</a></h1> <h2>Main Changes by Version</h2> <table cellspacing="10"><tr><td><table cellspacing="4"> <tr valign="top"><td> <b>2.0</b></td><td><ul> <li>Initial release of 2.0 version </li> </ul></td></tr> <tr valign="top"><td> <b>2.0.1</b></td><td><ul> <li>Improve correctness of singleton construction related to static initialization </li> <li>Fix nan-related error in constant folding logic that was failing on some JVMs </li> <li>JSR-223 fixes: add META-INF/services entry in jse jar, improve bindings implementation </li> </ul></td></tr> <tr valign="top"><td> <b>2.0.2</b></td><td><ul> <li>JSR-223 bindings change: non Java-primitives will now be passed as LuaValue </li> <li>JSR-223 enhancement: allow both ".lua" and "lua" as extensions in getScriptEngine() </li> <li>Improve selection logic when binding to overloaded functions using luajava</li> <li>Enhance javadoc, put it <a href="http://luaj.sourceforge.net/api/2.0/index.html">online</a> and <a href="docs/api/index.html">in distribution</a> </li> <li>Add lib/luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li> </ul></td></tr> </table> <h2>Known Issues</h2> <ul> <li>debug code may not be completely removed by some obfuscators <li>tail calls are not tracked in debug information <li>using both version 1 and 2 libraries together in the same java vm has not been tested <li>module() and setfenv() only partially supported for lau2java or luajc compiled lua <li>values associated with weak keys may linger longer than expected </ul>
About
No description, website, or topics provided.
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published