Improve documentation and samples.

This commit is contained in:
James Roseborough
2012-10-03 14:21:26 +00:00
parent 1f69fa38ba
commit 1a4eb0e3c7
7 changed files with 120 additions and 35 deletions

View File

@@ -1,18 +1,22 @@
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;
/** Simple program showing the minimal Java program to launch a script. */
public class SampleJseMain {
public static void main(String[] args) throws Exception {
String script = "examples/lua/hello.lua";
// create an environment to run in
Globals _G = JsePlatform.standardGlobals();
_G.loadFile(script).arg1().call( LuaValue.valueOf(script) );
Globals globals = JsePlatform.standardGlobals();
// Use the convenience function on the globals to load a chunk.
LuaValue chunk = globals.loadFile(script);
// Use any of the "call()" or "invoke()" functions directly on the chunk.
chunk.call( LuaValue.valueOf(script) );
}

View File

@@ -0,0 +1,54 @@
import java.io.IOException;
import org.luaj.vm2.Globals;
import org.luaj.vm2.lib.jse.JsePlatform;
/** Simple toy program illustrating how to run Luaj in multiple threads.
*
* By creating separate Globals in each thread, scripts can be run in each thread.
*
* However note the following:
* - type-related metatables such as LuaNumber.s_metatable are shared by all threads, so are not thread-safe.
* - creating additional threads within a Java element called by lua could result in shared access to globals.
*/
public class SampleMultiThreaded {
static class Runner implements Runnable {
final String script1, script2;
Runner(String script1, String script2) {
this.script1 = script1;
this.script2 = script2;
}
public void run() {
try {
// Each thread must have its own Globals.
Globals g = JsePlatform.standardGlobals();
// Once a Globals is created, it can and should be reused
// within the same thread.
g.loadFile(script1).call();
g.loadFile(script2).call();
} catch ( Exception e ) {
e.printStackTrace();
}
}
}
public static void main(final String[] args) throws IOException {
final String script1 = args.length > 0? args[0]: "test/lua/perf/nsieve.lua";
final String script2 = args.length > 1? args[1]: "test/lua/perf/binarytrees.lua";
try {
Thread[] thread = new Thread[10];
for (int i = 0; i < thread.length; ++i)
thread[i] = new Thread(new Runner(script1, script2),"Runner-"+i);
for (int i = 0; i < thread.length; ++i)
thread[i].start();
for (int i = 0; i < thread.length; ++i)
thread[i].join();
System.out.println("done");
} catch ( Exception e ) {
e.printStackTrace();
}
}
}

View File

@@ -56,36 +56,59 @@ import org.luaj.vm2.lib.ResourceFinder;
*/
public class Globals extends LuaTable {
/** The current default input stream. */
public InputStream STDIN = null;
/** The current default output stream. */
public PrintStream STDOUT = System.out;
/** The current default error stream. */
public PrintStream STDERR = System.err;
/** 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);
/** The BaseLib instance loaded into this Globals */
public BaseLib baselib;
public LuaValue errorfunc;
public LuaThread running_thread = new LuaThread(this);
public DebugLib debuglib;
/** The PackageLib instance loaded into this Globals */
public PackageLib package_;
/** The DebugLib instance loaded into this Globals, or null if debugging is not enabled */
public DebugLib debuglib;
/** The current error handler for this Globals */
public LuaValue errorfunc;
/** Check that this object is a Globals object, and return it, otherwise throw an error. */
public Globals checkglobals() {
return this;
}
public Varargs loadFile(String filename) {
return baselib.loadFile(filename, "bt", this);
/** Convenience function for loading a file.
* @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());
}
/** Function which yields the current thread.
* @param args Arguments to supply as return values in the resume function of the resuming thread.
* @return Values supplied as arguments to the resume() call that reactivates this thread.
*/
public Varargs yield(Varargs args) {
if (running_thread == null || running_thread.isMainThread())
if (running == null || running.isMainThread())
throw new LuaError("cannot yield main thread");
final LuaThread.State s = running_thread.state;
final LuaThread.State s = running.state;
return s.lua_yield(args);
}

View File

@@ -192,9 +192,9 @@ public class LuaThread extends LuaValue {
}
public synchronized Varargs lua_resume(LuaThread new_thread, Varargs args) {
LuaThread previous_thread = globals.running_thread;
LuaThread previous_thread = globals.running;
try {
globals.running_thread = new_thread;
globals.running = new_thread;
this.args = args;
if (this.status == STATUS_INITIAL) {
this.status = STATUS_RUNNING;
@@ -215,9 +215,9 @@ public class LuaThread extends LuaValue {
this.args = LuaValue.NONE;
this.result = LuaValue.NONE;
this.error = null;
globals.running_thread = previous_thread;
globals.running = previous_thread;
if (previous_thread != null)
globals.running_thread.state.status =STATUS_RUNNING;
globals.running.state.status =STATUS_RUNNING;
}
}

View File

@@ -93,7 +93,7 @@ public class CoroutineLib extends OneArgFunction {
final class running extends VarArgFunction {
public Varargs invoke(Varargs args) {
final LuaThread r = globals.running_thread;
final LuaThread r = globals.running;
return varargsOf(r, valueOf(r.isMainThread()));
}
}

View File

@@ -129,7 +129,7 @@ public class DebugLib extends OneArgFunction {
// debug.gethook ([thread])
final class gethook extends VarArgFunction {
public Varargs invoke(Varargs args) {
LuaThread t = args.narg() > 0 ? args.checkthread(1): globals.running_thread;
LuaThread t = args.narg() > 0 ? args.checkthread(1): globals.running;
return varargsOf(
t.hookfunc != null? t.hookfunc: NIL,
valueOf((t.hookcall?"c":"")+(t.hookline?"l":"")+(t.hookrtrn?"r":"")),
@@ -141,7 +141,7 @@ public class DebugLib extends OneArgFunction {
final class getinfo extends VarArgFunction {
public Varargs invoke(Varargs args) {
int a=1;
LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running_thread;
LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running;
LuaValue func = args.arg(a++);
String what = args.optjstring(a++, "flnStu");
DebugLib.CallStack callstack = callstack(thread);
@@ -204,7 +204,7 @@ public class DebugLib extends OneArgFunction {
final class getlocal extends VarArgFunction {
public Varargs invoke(Varargs args) {
int a=1;
LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running_thread;
LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running;
int level = args.checkint(a++);
int local = args.checkint(a++);
CallFrame f = callstack(thread).getCallFrame(level);
@@ -255,7 +255,7 @@ public class DebugLib extends OneArgFunction {
final class sethook extends VarArgFunction {
public Varargs invoke(Varargs args) {
int a=1;
LuaThread t = args.isthread(a)? args.checkthread(a++): globals.running_thread;
LuaThread t = args.isthread(a)? args.checkthread(a++): globals.running;
LuaValue func = args.optfunction(a++, null);
String str = args.optjstring(a++,"");
int count = args.optint(a++,0);
@@ -279,7 +279,7 @@ public class DebugLib extends OneArgFunction {
final class setlocal extends VarArgFunction {
public Varargs invoke(Varargs args) {
int a=1;
LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running_thread;
LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running;
int level = args.checkint(a++);
int local = args.checkint(a++);
LuaValue value = args.arg(a++);
@@ -339,7 +339,7 @@ public class DebugLib extends OneArgFunction {
final class traceback extends VarArgFunction {
public Varargs invoke(Varargs args) {
int a=1;
LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running_thread;
LuaThread thread = args.isthread(a)? args.checkthread(a++): globals.running;
String message = args.optjstring(a++, null);
int level = args.optint(a++,1);
String tb = callstack(thread).traceback(level);
@@ -379,7 +379,7 @@ public class DebugLib extends OneArgFunction {
}
public void onCall(LuaFunction f) {
LuaThread t = globals.running_thread;
LuaThread t = globals.running;
if (t.inhook) return;
callstack().onCall(f);
if (t.hookcall && t.hookfunc != null)
@@ -387,7 +387,7 @@ public class DebugLib extends OneArgFunction {
}
public void onCall(LuaClosure c, Varargs varargs, LuaValue[] stack) {
LuaThread t = globals.running_thread;
LuaThread t = globals.running;
if (t.inhook) return;
callstack().onCall(c, varargs, stack);
if (t.hookcall && t.hookfunc != null)
@@ -395,7 +395,7 @@ public class DebugLib extends OneArgFunction {
}
public void onInstruction(int pc, Varargs v, int top) {
LuaThread t = globals.running_thread;
LuaThread t = globals.running;
if (t.inhook) return;
callstack().onInstruction(pc, v, top);
if (t.hookfunc == null) return;
@@ -412,7 +412,7 @@ public class DebugLib extends OneArgFunction {
}
public void onReturn() {
LuaThread t = globals.running_thread;
LuaThread t = globals.running;
if (t.inhook) return;
callstack().onReturn();
if (t.hookcall && t.hookfunc != null)
@@ -424,7 +424,7 @@ public class DebugLib extends OneArgFunction {
}
void callHook(LuaValue type, LuaValue arg) {
LuaThread t = globals.running_thread;
LuaThread t = globals.running;
t.inhook = true;
try {
t.hookfunc.call(type, arg);
@@ -436,7 +436,7 @@ public class DebugLib extends OneArgFunction {
}
CallStack callstack() {
return callstack(globals.running_thread);
return callstack(globals.running);
}
CallStack callstack(LuaThread t) {

View File

@@ -24,7 +24,6 @@ package org.luaj.luajc;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Print;
@@ -57,11 +56,16 @@ public class TestLuaJ {
// compile into a chunk, or load as a class
InputStream is = new ByteArrayInputStream( script.getBytes() );
LuaValue chunk = LuaC.instance.load(is, "script", _G);
chunk.call();
// The loaded chunk should be a closure, which contains the prototype.
print( chunk.checkclosure().p );
// The chunk can be called with arguments as desired.
chunk.call(LuaValue.ZERO, LuaValue.ONE);
}
private static void print(Prototype p) {
System.out.println("--- "+p.is_vararg);
System.out.println("--- "+p);
Print.printCode(p);
if (p.p!=null)
for ( int i=0,n=p.p.length; i<n; i++ )