Improve documentation and samples.
This commit is contained in:
@@ -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) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
54
examples/jse/SampleMultiThreaded.java
Normal file
54
examples/jse/SampleMultiThreaded.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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++ )
|
||||
|
||||
Reference in New Issue
Block a user