Move static variables used by libraries into explicit Globals object for better thread safety.

This commit is contained in:
James Roseborough
2012-09-14 04:12:50 +00:00
parent 9f3aef6403
commit f786802bf1
30 changed files with 739 additions and 1000 deletions

View File

@@ -0,0 +1,93 @@
/*******************************************************************************
* Copyright (c) 2012 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2;
import java.io.InputStream;
import java.io.PrintStream;
import org.luaj.vm2.LoadState.LuaCompiler;
import org.luaj.vm2.lib.BaseLib;
import org.luaj.vm2.lib.DebugLib;
import org.luaj.vm2.lib.ResourceFinder;
import org.luaj.vm2.lib.jme.JmePlatform;
import org.luaj.vm2.lib.jse.JsePlatform;
/**
* Global environment used by luaj.
* <p>
* Contains the global variables referenced by lua libraries such as stdin and stdout,
* the resrouce finder which is used tolook up files in a platform independent way,
* the installed lua compiler, the math library in use, debugging calls stack, and so on.
* <p>
* In a multithreded server environment, each server thread should create one Globals instance,
* which will be logically distance and not interfere with each other, but share certain
* static immutable resources such as class data and string data.
* <p>
* Typically, this is constructed indirectly by a call to
* {@link JsePlatform.standardGlobasl()} or {@link JmePlatform.standardGlobals()},
* and then used to load lua scripts for execution as in the following example.
* <pre> {@code
* Globals _G = JsePlatform.standardGlobals();
* _G.compiler.load( new ByteArrayInputStream("print 'hello'".getBytes()), "main.lua", _G ).call();
* } </pre>
* @see LuaCompiler
* @see JsePlatform
* @see JmePlatform
* @see LuaValue
*
*/
public class Globals extends LuaTable {
public InputStream STDIN = null;
public PrintStream STDOUT = System.out;
public PrintStream STDERR = System.err;
public ResourceFinder FINDER;
public LuaCompiler compiler = null;
public LuaThread.CallStack callstack = new LuaThread.CallStack();
public BaseLib baselib;
public LuaValue errorfunc;
public LuaThread running_thread = new LuaThread(this);
public DebugLib debuglib;
public Globals checkglobals() {
return this;
}
public Varargs loadFile(String filename) {
return baselib.loadFile(filename, "bt", this);
}
public Varargs yield(Varargs args) {
if (running_thread == null || running_thread.isMainThread())
throw new LuaError("cannot yield main thread");
final LuaThread.State s = running_thread.state;
return s.lua_yield(args);
}
}

View File

@@ -21,8 +21,6 @@
******************************************************************************/
package org.luaj.vm2;
import org.luaj.vm2.LoadState.LuaCompiler;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.DebugLib;
/**
@@ -92,14 +90,7 @@ public class LuaClosure extends LuaFunction {
public UpValue[] upValues;
/** Create a closure around a Prototype with the default global environment.
* If the prototype has upvalues, the environment will be written into the first upvalue.
* @param p the Prototype to construct this Closure for.
* @param env the environment to associate with the closure.
*/
public LuaClosure(Prototype p) {
this(p, LuaValue._G);
}
final Globals globals;
/** Create a closure around a Prototype with a specific environment.
* If the prototype has upvalues, the environment will be written into the first upvalue.
@@ -114,6 +105,7 @@ public class LuaClosure extends LuaFunction {
this.upValues = new UpValue[p.upvalues.length];
this.upValues[0] = new UpValue(new LuaValue[] {env}, 0);
}
globals = env instanceof Globals? (Globals) env: null;
}
public boolean isclosure() {
@@ -184,7 +176,6 @@ public class LuaClosure extends LuaFunction {
return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
}
protected Varargs execute( LuaValue[] stack, Varargs varargs ) {
// loop through instructions
int i,a,b,c,pc=0,top=0;
@@ -194,18 +185,17 @@ public class LuaClosure extends LuaFunction {
LuaValue[] k = p.k;
// upvalues are only possible when closures create closures
UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
UpValue[] openups = p.p.length>0? new UpValue[p.p.length]: null;
// debug wants args to this function
if (DebugLib.DEBUG_ENABLED)
DebugLib.debugSetupCall(varargs, stack);
if (globals != null)
globals.callstack.onCall( this, varargs, stack );
// process instructions
LuaThread.CallStack cs = LuaThread.onCall( this );
try {
while ( true ) {
if (DebugLib.DEBUG_ENABLED)
DebugLib.debugBytecode(pc, v, top);
if (DebugLib.DEBUG_ENABLED && globals != null)
globals.callstack.onInstruction( pc, v, top );
// pull out instruction
i = code[pc++];
@@ -473,7 +463,7 @@ public class LuaClosure extends LuaFunction {
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */
{
Prototype newp = p.p[i>>>14];
LuaClosure ncl = new LuaClosure(newp, null);
LuaClosure ncl = new LuaClosure(newp, globals);
Upvaldesc[] uv = newp.upvalues;
for ( int j=0, nup=uv.length; j<nup; ++j ) {
if (uv[j].instack) /* upvalue refes to local variable? */
@@ -504,11 +494,16 @@ public class LuaClosure extends LuaFunction {
}
}
} catch ( LuaError le ) {
if (le.traceback == null)
processErrorHooks(le, p, pc);
throw le;
} catch ( Exception e ) {
throw new LuaError(e);
LuaError le = new LuaError(e);
processErrorHooks(le, p, pc);
throw le;
} finally {
cs.onReturn();
if (globals != null)
globals.callstack.onReturn();
if ( openups != null )
for ( int u=openups.length; --u>=0; )
if ( openups[u] != null )
@@ -516,6 +511,32 @@ public class LuaClosure extends LuaFunction {
}
}
/**
* Run the error hook if there is one
* @param msg the message to use in error hook processing.
* */
String errorHook(String msg) {
if (globals == null || globals.errorfunc == null)
return msg;
LuaValue errfunc = globals.errorfunc;
globals.errorfunc = null;
try {
return errfunc.call( LuaValue.valueOf(msg) ).tojstring();
} catch ( Throwable t ) {
return "error in error handling";
} finally {
globals.errorfunc = errfunc;
}
}
private void processErrorHooks(LuaError le, Prototype p, int pc) {
le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?");
le.traceback = errorHook(le.getMessage());
if (DebugLib.DEBUG_ENABLED && globals != null && globals.debuglib != null)
le.traceback += globals.callstack.traceback(le.level);
}
private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) {
final int n = openups.length;
for (int i = 0; i < n; ++i)
@@ -535,4 +556,22 @@ public class LuaClosure extends LuaFunction {
protected void setUpvalue(int i, LuaValue v) {
upValues[i].setValue(v);
}
/**
* Add file and line info to a message at a particular level
* @param message the String message to use
* @param level where to supply line info from in call stack
* */
private String getFileLineMessage( Exception e, int pc ) {
String msg = e.getMessage();
if ( msg == null ) return null;
if ( globals == null ) return msg;
LuaFunction f = globals.callstack.getFunction(1);
if ( ! (f instanceof LuaClosure) ) return msg;
LuaClosure c = (LuaClosure) f;
LuaString file = c.p.source != null ? c.p.source: valueOf("?");
String line = c.p.lineinfo != null && pc < c.p.lineinfo.length? String.valueOf(c.p.lineinfo[pc]): "?";
return file.tojstring() + ": " + line;
}
}

View File

@@ -38,39 +38,28 @@ import org.luaj.vm2.lib.DebugLib;
public class LuaError extends RuntimeException {
private static final long serialVersionUID = 1L;
private String traceback;
protected int level;
protected String fileline;
protected String traceback;
protected Throwable cause;
/**
* Run the error hook if there is one
* @param msg the message to use in error hook processing.
* */
private static String errorHook(String msg) {
LuaThread thread = LuaThread.getRunning();
if ( thread.err != null ) {
LuaValue errfunc = thread.err;
thread.err = null;
try {
return errfunc.call( LuaValue.valueOf(msg) ).tojstring();
} catch ( Throwable t ) {
return "error in error handling";
} finally {
thread.err = errfunc;
}
}
return msg;
public String getMessage() {
return (fileline != null? fileline + " ": "")
+ (traceback != null? traceback: super.getMessage());
}
private Throwable cause;
/** Construct LuaError when a program exception occurs.
* <p>
* All errors generated from lua code should throw LuaError(String) instead.
* @param cause the Throwable that caused the error, if known.
*/
public LuaError(Throwable cause) {
super( errorHook( addFileLine( "vm error: "+cause ) ) );
super( "vm error: "+cause );
this.cause = cause;
this.traceback = DebugLib.traceback(1);
this.level = 1;
}
/**
@@ -79,8 +68,8 @@ public class LuaError extends RuntimeException {
* @param message message to supply
*/
public LuaError(String message) {
super( errorHook( addFileLine( message ) ) );
this.traceback = DebugLib.traceback(1);
super( message );
this.level = 1;
}
/**
@@ -89,37 +78,10 @@ public class LuaError extends RuntimeException {
* @param level where to supply line info from in call stack
*/
public LuaError(String message, int level) {
super( errorHook( addFileLine( message, level ) ) );
this.traceback = DebugLib.traceback(1);
super( message );
this.level = level;
}
/**
* Add file and line info to a message at a particular level
* @param message the String message to use
* @param level where to supply line info from in call stack
* */
private static String addFileLine( String message, int level ) {
if ( message == null ) return null;
if ( level == 0 ) return message;
String fileline = DebugLib.fileline(level-1);
return fileline!=null? fileline+": "+message: message;
}
/** Add file and line info for the nearest enclosing closure
* @param message the String message to use
* */
private static String addFileLine( String message ) {
if ( message == null ) return null;
String fileline = DebugLib.fileline();
return fileline!=null? fileline+": "+message: message;
}
/** Print the message and stack trace */
public void printStackTrace() {
System.out.println( toString() );
if ( traceback != null )
System.out.println( traceback );
}
/**
* Get the cause, if any.

View File

@@ -24,6 +24,7 @@ package org.luaj.vm2;
import java.lang.ref.WeakReference;
import org.luaj.vm2.LuaThread.CallFrame;
import org.luaj.vm2.lib.DebugLib;
/**
@@ -60,7 +61,7 @@ import org.luaj.vm2.lib.DebugLib;
* @see CoroutineLib
*/
public class LuaThread extends LuaValue {
public static LuaValue s_metatable;
public static int coroutine_count = 0;
@@ -84,37 +85,39 @@ public class LuaThread extends LuaValue {
public final State state;
/** Field to hold state of error condition during debug hook function calls. */
public LuaValue err;
final CallStack callstack = new CallStack();
public static final int MAX_CALLSTACK = 256;
private static final LuaThread main_thread = new LuaThread();
// state of running thread including call stack
private static LuaThread running_thread = main_thread;
/** Interval to check for LuaThread dereferencing. */
public static int GC_INTERVAL = 30000;
/** Thread-local used by DebugLib to store debugging state. */
public Object debugState;
public LuaValue hookfunc;
public boolean hookline;
public boolean hookcall;
public boolean hookrtrn;
public int hookcount;
public final Globals globals;
/** Private constructor for main thread only */
private LuaThread() {
state = new State(this, null);
public LuaThread(Globals globals) {
state = new State(globals, this, null);
state.status = STATUS_RUNNING;
this.globals = globals;
}
/**
* Create a LuaThread around a function and environment
* @param func The function to execute
*/
public LuaThread(LuaValue func) {
public LuaThread(Globals globals, LuaValue func) {
LuaValue.assert_(func != null, "function cannot be null");
state = new State(this, func);
state = new State(globals, this, func);
this.globals = globals;
}
public int type() {
@@ -145,71 +148,20 @@ public class LuaThread extends LuaValue {
return STATUS_NAMES[state.status];
}
/**
* Get the currently running thread.
* @return {@link LuaThread} that is currenly running
*/
public static LuaThread getRunning() {
return running_thread;
}
/**
* Callback used at the beginning of a call to prepare for possible getfenv/setfenv calls
* @param function Function being called
* @return CallStack which is used to signal the return or a tail-call recursion
* @see DebugLib
*/
public static final CallStack onCall(LuaFunction function) {
CallStack cs = running_thread.callstack;
cs.onCall(function);
return cs;
public boolean isMainThread() {
return this.state.function == null;
}
/**
* Get the function called as a specific location on the stack.
* @param level 1 for the function calling this one, 2 for the next one.
* @return LuaFunction on the call stack, or null if outside of range of active stack
*/
public static final LuaFunction getCallstackFunction(int level) {
return running_thread.callstack.getFunction(level);
}
/**
* Replace the error function of the currently running thread.
* @param errfunc the new error function to use.
* @return the previous error function.
*/
public static LuaValue setErrorFunc(LuaValue errfunc) {
LuaValue prev = running_thread.err;
running_thread.err = errfunc;
return prev;
}
/** Yield the current thread with arguments
*
* @param args The arguments to send as return values to {@link #resume(Varargs)}
* @return {@link Varargs} provided as arguments to {@link #resume(Varargs)}
*/
public static Varargs yield(Varargs args) {
State s = running_thread.state;
if (s.function == null)
throw new LuaError("cannot yield main thread");
return s.lua_yield(args);
}
/** Start or resume this thread
*
* @param args The arguments to send as return values to {@link #yield(Varargs)}
* @return {@link Varargs} provided as arguments to {@link #yield(Varargs)}
*/
public Varargs resume(Varargs args) {
if (this.state.status > STATUS_SUSPENDED)
final LuaThread.State s = this.state;
if (s.status > LuaThread.STATUS_SUSPENDED)
return LuaValue.varargsOf(LuaValue.FALSE,
LuaValue.valueOf("cannot resume "+LuaThread.STATUS_NAMES[this.state.status]+" coroutine"));
return state.lua_resume(this, args);
LuaValue.valueOf("cannot resume "+(s.status==LuaThread.STATUS_DEAD? "dead": "non-suspended")+" coroutine"));
return s.lua_resume(this, args);
}
public static class State implements Runnable {
private final Globals globals;
final WeakReference lua_thread;
public final LuaValue function;
Varargs args = LuaValue.NONE;
@@ -217,7 +169,8 @@ public class LuaThread extends LuaValue {
String error = null;
public int status = LuaThread.STATUS_INITIAL;
State(LuaThread lua_thread, LuaValue function) {
State(Globals globals, LuaThread lua_thread, LuaValue function) {
this.globals = globals;
this.lua_thread = new WeakReference(lua_thread);
this.function = function;
}
@@ -236,9 +189,9 @@ public class LuaThread extends LuaValue {
}
public synchronized Varargs lua_resume(LuaThread new_thread, Varargs args) {
LuaThread previous_thread = LuaThread.running_thread;
LuaThread previous_thread = globals.running_thread;
try {
LuaThread.running_thread = new_thread;
globals.running_thread = new_thread;
this.args = args;
if (this.status == STATUS_INITIAL) {
this.status = STATUS_RUNNING;
@@ -246,7 +199,8 @@ public class LuaThread extends LuaValue {
} else {
this.notify();
}
previous_thread.state.status = STATUS_NORMAL;
if (previous_thread != null)
previous_thread.state.status = STATUS_NORMAL;
this.status = STATUS_RUNNING;
this.wait();
return (this.error != null?
@@ -255,11 +209,12 @@ public class LuaThread extends LuaValue {
} catch (InterruptedException ie) {
throw new OrphanedThread();
} finally {
running_thread = previous_thread;
running_thread.state.status =STATUS_RUNNING;
this.args = LuaValue.NONE;
this.result = LuaValue.NONE;
this.error = null;
globals.running_thread = previous_thread;
if (previous_thread != null)
globals.running_thread.state.status =STATUS_RUNNING;
}
}
@@ -287,17 +242,30 @@ public class LuaThread extends LuaValue {
}
public static class CallStack {
final LuaFunction[] functions = new LuaFunction[MAX_CALLSTACK];
int calls = 0;
final CallFrame[] frame = new CallFrame[MAX_CALLSTACK];
int calls = 0;
CallStack() {
for (int i = 0; i < MAX_CALLSTACK; ++i)
frame[i] = new CallFrame();
}
/**
* Method to indicate the start of a call
* @param stack
* @param varargs
* @see DebugLib
*/
final void onCall(LuaFunction function) {
functions[calls++] = function;
if (DebugLib.DEBUG_ENABLED)
DebugLib.debugOnCall(running_thread, calls, function);
public final void onCall(LuaFunction function) {
frame[calls++].set(function);
// if (DebugLib.DEBUG_ENABLED)
// DebugLib.debugOnCall(globals.running_thread, calls, function);
}
public final void onCall(LuaClosure function, Varargs varargs, LuaValue[] stack) {
frame[calls++].set(function, varargs, stack);
// if (DebugLib.DEBUG_ENABLED)
// DebugLib.debugOnCall(globals.running_thread, calls, function);
}
/**
@@ -305,11 +273,15 @@ public class LuaThread extends LuaValue {
* @see DebugLib
*/
public final void onReturn() {
functions[--calls] = null;
if (DebugLib.DEBUG_ENABLED)
DebugLib.debugOnReturn(running_thread, calls);
frame[--calls].reset();
// if (DebugLib.DEBUG_ENABLED)
// DebugLib.debugOnReturn(running_thread, calls);
}
public final void onInstruction(int pc, Varargs v, int top) {
frame[calls-1].instr(pc, v, top);
}
/**
* Get number of calls in stack
* @return number of calls in current call stack
@@ -324,12 +296,103 @@ public class LuaThread extends LuaValue {
* @param level # of levels back from the top of the stack.
* @return LuaFunction, or null if beyond the stack limits.
*/
LuaFunction getFunction(int level) {
return level>0 && level<=calls? functions[calls-level]: null;
public LuaFunction getFunction(int level) {
return level>0 && level<=calls? frame[calls-level].f: null;
}
/**
* Get the traceback starting at a specific level.
* @param level
* @return String containing the traceback.
*/
public String traceback(int level) {
StringBuffer sb = new StringBuffer();
sb.append( "stack traceback:" );
for (LuaFunction f = null; (f = getFunction(level)) != null; ++level) {
sb.append( "\n\t" );
sb.append( f.tostring() );
sb.append( "main chunk" );
}
return sb.toString();
}
public CallFrame getCallFrame(int level) {
if (level < 1 || level >= calls)
return null;
return frame[calls-level];
}
public CallFrame findCallFrame(LuaValue func) {
for (int i = 1; i <= calls; ++i)
if (frame[calls-i].f == func)
return frame[i];
return null;
}
}
public boolean isMainThread() {
return this.state.function == null;
public static class CallFrame {
public LuaFunction f;
int pc, top;
Varargs v;
LuaValue[] stack;
public void set(LuaClosure function, Varargs varargs, LuaValue[] stack) {
this.f = function;
this.v = varargs;
this.stack = stack;
}
public void print() {
// TODO Auto-generated method stub
}
public void set(LuaFunction function) {
this.f = function;
}
public void reset() {
this.f = null;
this.v = null;
this.stack = null;
}
public void instr(int pc, Varargs v, int top) {
this.pc = pc;
this.v = v;
this.top = top;
if (DebugLib.DEBUG_ENABLED && DebugLib.TRACE & f.isclosure())
Print.printState(f.checkclosure(), pc, stack, top, v);
}
public int getLine() {
if (!f.isclosure())
return 0;
LuaClosure c = (LuaClosure) f;
Prototype p = c.p;
if (p.lineinfo == null || pc < 0 || pc >= p.lineinfo[pc])
return 0;
return p.lineinfo[pc];
}
public Varargs getLocal(int i) {
if (!f.isclosure())
return NONE;
LuaClosure c = (LuaClosure) f;
Prototype p = c.p;
if (i < 1 || i > stack.length)
if (p.locvars != null && p.locvars.length >= i)
return varargsOf(stack[i-1], p.locvars[i-1].varname);
else
return stack[i-1];
return NONE;
}
public Varargs setLocal(int i, LuaValue value) {
if (!f.isclosure())
return NONE;
LuaClosure c = (LuaClosure) f;
Prototype p = c.p;
if (i < 1 || i > stack.length)
return NONE;
stack[i] = value;
if (p.locvars != null && p.locvars.length >= i)
return p.locvars[i-1].varname;
return NONE;
}
}
}

View File

@@ -24,7 +24,7 @@ package org.luaj.vm2;
public class LuaUserdata extends LuaValue {
public final Object m_instance;
public Object m_instance;
public LuaValue m_metatable;
public LuaUserdata(Object obj) {

View File

@@ -109,11 +109,6 @@ package org.luaj.vm2;
*/
abstract
public class LuaValue extends Varargs {
/** The default global environment. This must be set before lua can be used.
* Typically, it is set as a side effect of calling one of
* JsePlatform.standardGlobals() or similar functions.
*/
public static LuaValue _G;
/** Type enumeration constant for lua numbers that are ints, for compatibility with lua 5.1 number patch only */
public static final int TINT = (-2);
@@ -877,7 +872,16 @@ public class LuaValue extends Varargs {
* @see #checkclosure()
*/
public LuaValue checkfunction() { argerror("function"); return null; }
/** Check that the value is a Globals instance, or throw {@link LuaError} if not
* <p>
* {@link Globals} are a special {@link LuaTable} that establish the default global environment.
* @return {@code this} if if an instance fof {@Globals}
* @throws LuaError if not a {@link Globals} instance.
*/
public Globals checkglobals() { argerror("globals"); return null; }
/** Check that the value is numeric, and convert and cast value to int, or throw {@link LuaError} if not numeric
* <p>
* Values that are {@link LuaNumber} will be cast to int and may lose precision.
@@ -1354,13 +1358,14 @@ public class LuaValue extends Varargs {
public Varargs inext(LuaValue index) { return typerror("table"); }
/**
* Load a library instance by setting its environment to the global environment {@code LuaValue._G}
* Load a library instance by setting its environment to the calling object,
* and calling it, which should iniitalize the library instance and
* install itself into this instance.
* install itself into this instance. The calling object should be the
* {@link Globals} environment to associate wtih the library.
* @param library The callable {@link LuaValue} to load into {@code this}
* @return {@link LuaValue._G} containing the result of the initialization call.
*/
public LuaValue load(LuaValue library) { return load(library, _G); }
public LuaValue load(LuaValue library) { return load(library, this); }
/**
* Load a library instance by setting its environment to {@code env}

View File

@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.Lua;
import org.luaj.vm2.LuaError;
@@ -73,36 +74,21 @@ import org.luaj.vm2.Varargs;
*/
public class BaseLib extends OneArgFunction implements ResourceFinder {
public static BaseLib instance;
public InputStream STDIN = null;
public PrintStream STDOUT = System.out;
public PrintStream STDERR = System.err;
/**
* Singleton file opener for this Java ClassLoader realm.
*
* Unless set or changed elsewhere, will be set by the BaseLib that is created.
*/
public static ResourceFinder FINDER;
/**
* Construct a base libarary instance.
*/
public BaseLib() {
instance = this;
}
Globals globals;
public LuaValue call(LuaValue env) {
globals = env.checkglobals();
globals.FINDER = this;
globals.baselib = this;
env.set( "_G", env );
env.set( "_VERSION", Lua._VERSION );
env.set("assert", new _assert());
env.set("collectgarbage", new collectgarbage());
env.set("dofile", new dofile(this));
env.set("dofile", new dofile());
env.set("error", new error());
env.set("getmetatable", new getmetatable());
env.set("load", new load());
env.set("loadfile", new loadfile(this));
env.set("loadfile", new loadfile());
env.set("pcall", new pcall());
env.set("print", new print(this));
env.set("rawequal", new rawequal());
@@ -121,9 +107,6 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
env.set("pairs", new pairs(next));
env.set("ipairs", new ipairs());
// set the default resource finder if not set already
if ( FINDER == null )
FINDER = this;
return env;
}
@@ -132,8 +115,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
* Tries to open the file as a resource, which can work for JSE and JME.
*/
public InputStream findResource(String filename) {
Class c = getClass();
return c.getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
return getClass().getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
}
@@ -168,17 +150,13 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
// "dofile", // ( filename ) -> result1, ...
static final class dofile extends VarArgFunction {
final BaseLib baselib;
dofile(BaseLib baselib) {
this.baselib = baselib;
}
final class dofile extends VarArgFunction {
public Varargs invoke(Varargs args) {
args.argcheck(args.isstring(1) || args.isnil(1), 1, "filename must be string or nil");
String filename = args.isstring(1)? args.tojstring(1): null;
Varargs v = filename == null?
BaseLib.loadStream( baselib.STDIN, "=stdin", "bt",LuaValue._G ):
BaseLib.loadFile( args.checkjstring(1), "bt",LuaValue._G );
loadStream( globals.STDIN, "=stdin", "bt", globals ):
loadFile( args.checkjstring(1), "bt", globals );
return v.isnil(1)? error(v.tojstring(2)): v.arg1().invoke();
}
}
@@ -201,63 +179,59 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
}
// "load", // ( ld [, source [, mode [, env]]] ) -> chunk | nil, msg
static final class load extends VarArgFunction {
final class load extends VarArgFunction {
public Varargs invoke(Varargs args) {
LuaValue ld = args.arg1();
args.argcheck(ld.isstring() || ld.isfunction(), 1, "ld must be string or function");
String source = args.optjstring(2, ld.isstring()? ld.tojstring(): "=(load)");
String mode = args.optjstring(3, "bt");
LuaValue env = args.optvalue(4,LuaValue._G);
return BaseLib.loadStream(ld.isstring()? ld.strvalue().toInputStream():
LuaValue env = args.optvalue(4, globals);
return loadStream(ld.isstring()? ld.strvalue().toInputStream():
new StringInputStream(ld.checkfunction()), source, mode, env);
}
}
// "loadfile", // ( [filename [, mode [, env]]] ) -> chunk | nil, msg
static final class loadfile extends VarArgFunction {
final BaseLib baselib;
loadfile(BaseLib baselib) {
this.baselib = baselib;
}
final class loadfile extends VarArgFunction {
public Varargs invoke(Varargs args) {
args.argcheck(args.isstring(1) || args.isnil(1), 1, "filename must be string or nil");
String filename = args.isstring(1)? args.tojstring(1): null;
String mode = args.optjstring(2, "bt");
LuaValue env = args.optvalue(3,LuaValue._G);
LuaValue env = args.optvalue(3, globals);
return filename == null?
BaseLib.loadStream( baselib.STDIN, "=stdin", mode, env ):
BaseLib.loadFile( filename, mode, env );
loadStream( globals.STDIN, "=stdin", mode, env ):
loadFile( filename, mode, env );
}
}
// "pcall", // (f, arg1, ...) -> status, result1, ...
static final class pcall extends VarArgFunction {
final class pcall extends VarArgFunction {
public Varargs invoke(Varargs args) {
LuaValue func = args.checkvalue(1);
LuaThread.CallStack cs = LuaThread.onCall(this);
globals.callstack.onCall(this);
try {
return pcall(func,args.subargs(2),null);
} finally {
cs.onReturn();
globals.callstack.onReturn();
}
}
}
// "print", // (...) -> void
static final class print extends VarArgFunction {
final class print extends VarArgFunction {
final BaseLib baselib;
print(BaseLib baselib) {
this.baselib = baselib;
}
public Varargs invoke(Varargs args) {
LuaValue tostring =LuaValue._G.get("tostring");
LuaValue tostring = globals.get("tostring");
for ( int i=1, n=args.narg(); i<=n; i++ ) {
if ( i>1 ) baselib.STDOUT.write( '\t' );
if ( i>1 ) globals.STDOUT.write( '\t' );
LuaString s = tostring.call( args.arg(i) ).strvalue();
int z = s.indexOf((byte)0, 0);
baselib.STDOUT.write( s.m_bytes, s.m_offset, z>=0? z: s.m_length );
globals.STDOUT.write( s.m_bytes, s.m_offset, z>=0? z: s.m_length );
}
baselib.STDOUT.println();
globals.STDOUT.println();
return NONE;
}
}
@@ -374,13 +348,13 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
// "xpcall", // (f, err) -> result1, ...
static final class xpcall extends VarArgFunction {
final class xpcall extends VarArgFunction {
public Varargs invoke(Varargs args) {
LuaThread.CallStack cs = LuaThread.onCall(this);
globals.callstack.onCall(this);
try {
return pcall(args.arg1(),NONE,args.checkvalue(2));
} finally {
cs.onReturn();
globals.callstack.onReturn();
}
}
}
@@ -418,18 +392,19 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
}
public static Varargs pcall(LuaValue func, Varargs args, LuaValue errfunc) {
LuaValue olderr = LuaThread.setErrorFunc(errfunc);
public Varargs pcall(LuaValue func, Varargs args, LuaValue errorfunc) {
try {
Varargs result = varargsOf(LuaValue.TRUE, func.invoke(args));
LuaThread.setErrorFunc(olderr);
return result;
LuaValue olderr = globals.errorfunc;
globals.errorfunc = errorfunc;
try {
return varargsOf(LuaValue.TRUE, func.invoke(args));
} finally {
globals.errorfunc = olderr;
}
} catch ( LuaError le ) {
LuaThread.setErrorFunc(olderr);
String m = le.getMessage();
return varargsOf(FALSE, m!=null? valueOf(m): NIL);
} catch ( Exception e ) {
LuaThread.setErrorFunc(olderr);
String m = e.getMessage();
return varargsOf(FALSE, valueOf(m!=null? m: e.toString()));
}
@@ -441,8 +416,8 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
* @param mode
* @return Varargs containing chunk, or NIL,error-text on error
*/
public static Varargs loadFile(String filename, String mode, LuaValue env) {
InputStream is = FINDER.findResource(filename);
public Varargs loadFile(String filename, String mode, LuaValue env) {
InputStream is = globals.FINDER.findResource(filename);
if ( is == null )
return varargsOf(NIL, valueOf("cannot open "+filename+": No such file or directory"));
try {
@@ -456,7 +431,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
}
public static Varargs loadStream(InputStream is, String chunkname, String mode, LuaValue env) {
public Varargs loadStream(InputStream is, String chunkname, String mode, LuaValue env) {
try {
if ( is == null )
return varargsOf(NIL, valueOf("not found: "+chunkname));

View File

@@ -42,7 +42,7 @@ public class Bit32Lib extends OneArgFunction {
"arshift", "lrotate", "lshift", "rrotate", "rshift"
});
env.set("bit32", t);
PackageLib.instance.LOADED.set("bit32", t);
env.get("package").get("loaded").set("bit32", t);
return t;
}

View File

@@ -21,6 +21,7 @@
******************************************************************************/
package org.luaj.vm2.lib;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
@@ -61,7 +62,10 @@ public class CoroutineLib extends OneArgFunction {
static int coroutine_count = 0;
Globals globals;
public LuaValue call(LuaValue env) {
globals = env.checkglobals();
LuaTable coroutine = new LuaTable();
coroutine.set("create", new create());
coroutine.set("resume", new resume());
@@ -70,27 +74,26 @@ public class CoroutineLib extends OneArgFunction {
coroutine.set("yield", new yield());
coroutine.set("wrap", new wrap());
env.set("coroutine", coroutine);
env.get("package").get("loaded").set("coroutine", TRUE);
env.get("package").get("loaded").set("coroutine", coroutine);
return coroutine;
}
final class create extends LibFunction {
public LuaValue call(LuaValue f) {
return new LuaThread(f.checkfunction());
return new LuaThread(globals, f.checkfunction());
}
}
final class resume extends VarArgFunction {
public Varargs invoke(Varargs args) {
if (!(args.arg1() instanceof LuaThread)) argerror(1, "thread");
final LuaThread t = (LuaThread) args.arg1();
return resume( t, args.subargs(2) );
final LuaThread t = args.checkthread(1);
return t.resume( args.subargs(2) );
}
}
final class running extends VarArgFunction {
public Varargs invoke(Varargs args) {
final LuaThread r = LuaThread.getRunning();
final LuaThread r = globals.running_thread;
return varargsOf(r, valueOf(r.isMainThread()));
}
}
@@ -104,14 +107,14 @@ public class CoroutineLib extends OneArgFunction {
final class yield extends VarArgFunction {
public Varargs invoke(Varargs args) {
return yield( args );
return globals.yield( args );
}
}
final class wrap extends LibFunction {
public LuaValue call(LuaValue f) {
final LuaValue func = f.checkfunction();
final LuaThread thread = new LuaThread(func);
final LuaThread thread = new LuaThread(globals, func);
return new wrapper(thread);
}
}
@@ -122,7 +125,7 @@ public class CoroutineLib extends OneArgFunction {
this.luathread = luathread;
}
public Varargs invoke(Varargs args) {
final Varargs result = resume(luathread, args);
final Varargs result = luathread.resume(args);
if ( result.arg1().toboolean() ) {
return result.subargs(2);
} else {
@@ -130,19 +133,4 @@ public class CoroutineLib extends OneArgFunction {
}
}
}
Varargs yield(Varargs args) {
final LuaThread.State s = LuaThread.getRunning().state;
if (s.function == null)
throw new LuaError("cannot yield main thread");
return s.lua_yield(args);
}
Varargs resume(LuaThread t, Varargs args) {
final LuaThread.State s = t.state;
if (s.status > LuaThread.STATUS_SUSPENDED)
return LuaValue.varargsOf(LuaValue.FALSE,
LuaValue.valueOf("cannot resume "+(s.status==LuaThread.STATUS_DEAD? "dead": "non-suspended")+" coroutine"));
return s.lua_resume(t, args);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,7 @@ import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
@@ -212,10 +213,10 @@ public class IoLib extends OneArgFunction {
LuaTable filemethods;
public IoLib() {
}
protected Globals globals;
public LuaValue call(LuaValue env) {
globals = env.checkglobals();
// io lib functions
LuaTable t = new LuaTable();
@@ -237,7 +238,7 @@ public class IoLib extends OneArgFunction {
// return the table
env.set("io", t);
PackageLib.instance.LOADED.set("io", t);
env.get("package").get("loaded").set("io", t);
return t;
}

View File

@@ -106,7 +106,7 @@ public class MathLib extends OneArgFunction {
math.set("sqrt", new sqrt());
math.set("tan", new tan());
env.set("math", math);
PackageLib.instance.LOADED.set("math", math);
env.get("package").get("loaded").set("math", math);
return math;
}

View File

@@ -116,7 +116,7 @@ public class OsLib extends VarArgFunction {
LuaTable t = new LuaTable();
bind(t, this.getClass(), NAMES, CLOCK);
env.set("os", t);
PackageLib.instance.LOADED.set("os", t);
env.get("package").get("loaded").set("os", t);
return t;
}

View File

@@ -22,12 +22,10 @@
package org.luaj.vm2.lib;
import java.io.InputStream;
import java.io.PrintStream;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
@@ -67,14 +65,11 @@ public class PackageLib extends OneArgFunction {
public static String DEFAULT_LUA_PATH = "?.lua";
public InputStream STDIN = null;
public PrintStream STDOUT = System.out;
Globals globals;
public LuaTable LOADED;
public LuaTable PACKAGE;
/** Most recent instance of PackageLib */
public static PackageLib instance;
/** Loader that loads from preload table if found there */
public LuaValue preload_searcher;
@@ -101,11 +96,10 @@ public class PackageLib extends OneArgFunction {
private static final String FILE_SEP = System.getProperty("file.separator");
public PackageLib() {
instance = this;
}
public PackageLib() {}
public LuaValue call(LuaValue env) {
globals = env.checkglobals();
env.set("require", new PkgLib1("require",OP_REQUIRE,this));
env.set( "package", PACKAGE=tableOf( new LuaValue[] {
_LOADED, LOADED=tableOf(),
@@ -284,7 +278,7 @@ public class PackageLib extends OneArgFunction {
LuaString filename = v.arg1().strvalue();
// Try to load the file.
v = BaseLib.loadFile(filename.tojstring(), "bt", LuaValue._G);
v = globals.loadFile(filename.tojstring());
if ( v.arg1().isfunction() )
return LuaValue.varargsOf(v.arg1(), filename);
@@ -316,7 +310,7 @@ public class PackageLib extends OneArgFunction {
}
// try opening the file
InputStream is = BaseLib.FINDER.findResource(filename);
InputStream is = globals.FINDER.findResource(filename);
if (is != null) {
try { is.close(); } catch ( java.io.IOException ioe ) {}
return valueOf(filename);

View File

@@ -78,7 +78,7 @@ public class StringLib extends OneArgFunction {
instance = t;
if ( LuaString.s_metatable == null )
LuaString.s_metatable = tableOf( new LuaValue[] { INDEX, t } );
PackageLib.instance.LOADED.set("string", t);
env.get("package").get("loaded").set("string", t);
return t;
}

View File

@@ -67,16 +67,12 @@ import org.luaj.vm2.lib.LibFunction;
*/
public class JmeIoLib extends IoLib {
public JmeIoLib() {
super();
}
protected File wrapStdin() throws IOException {
return new FileImpl(BaseLib.instance.STDIN);
return new FileImpl(globals.STDIN);
}
protected File wrapStdout() throws IOException {
return new FileImpl(BaseLib.instance.STDOUT);
return new FileImpl(globals.STDOUT);
}
protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException {

View File

@@ -22,6 +22,7 @@
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;
@@ -53,7 +54,7 @@ import org.luaj.vm2.lib.TableLib;
* <p>
* A simple example of initializing globals and using them from Java is:
* <pre> {@code
* LuaValue _G = JmePlatform.standardGlobals();
* Globals _G = JmePlatform.standardGlobals();
* _G.get("print").call(LuaValue.valueOf("hello, world"));
* } </pre>
* <p>
@@ -71,6 +72,7 @@ import org.luaj.vm2.lib.TableLib;
* <p>
* The standard globals will contain all standard libraries in their JME flavors:
* <ul>
* <li>{@link Globals}</li>
* <li>{@link BaseLib}</li>
* <li>{@link PackageLib}</li>
* <li>{@link Bit32Lib}</li>
@@ -101,9 +103,8 @@ public class JmePlatform {
* @see JsePlatform
* @see JmePlatform
*/
public static LuaTable standardGlobals() {
LuaTable _G = new LuaTable();
LuaValue._G = _G;
public static Globals standardGlobals() {
Globals _G = new Globals();
_G.load(new BaseLib());
_G.load(new PackageLib());
_G.load(new Bit32Lib());
@@ -114,6 +115,7 @@ public class JmePlatform {
_G.load(new CoroutineLib());
_G.load(new JmeIoLib());
LuaC.install();
_G.compiler = LuaC.instance;
return _G;
}
@@ -125,8 +127,8 @@ public class JmePlatform {
* @see JmePlatform
* @see DebugLib
*/
public static LuaTable debugGlobals() {
LuaTable _G = standardGlobals();
public static Globals debugGlobals() {
Globals _G = standardGlobals();
_G.load(new DebugLib());
return _G;
}

View File

@@ -67,11 +67,14 @@ import org.luaj.vm2.lib.ResourceFinder;
public class JseBaseLib extends org.luaj.vm2.lib.BaseLib {
/** Construct a JSE base library instance */
public JseBaseLib() {
STDIN = System.in;
/** Extend the library loading to set the default value for {@link Globals.STDIN} */
public LuaValue call(LuaValue env) {
super.call(env);
env.checkglobals().STDIN = System.in;
return env;
}
/**
* Try to open a file in the current working directory,
* or fall back to base opener if not found.

View File

@@ -67,16 +67,12 @@ import org.luaj.vm2.lib.LibFunction;
*/
public class JseIoLib extends IoLib {
public JseIoLib() {
super();
}
protected File wrapStdin() throws IOException {
return new FileImpl(BaseLib.instance.STDIN);
return new FileImpl(globals.STDIN);
}
protected File wrapStdout() throws IOException {
return new FileImpl(BaseLib.instance.STDOUT);
return new FileImpl(globals.STDOUT);
}
protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException {

View File

@@ -21,14 +21,16 @@
******************************************************************************/
package org.luaj.vm2.lib.jse;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.Bit32Lib;
import org.luaj.vm2.lib.CoroutineLib;
import org.luaj.vm2.lib.DebugLib;
import org.luaj.vm2.lib.PackageLib;
import org.luaj.vm2.lib.ResourceFinder;
import org.luaj.vm2.lib.StringLib;
import org.luaj.vm2.lib.TableLib;
@@ -40,13 +42,13 @@ import org.luaj.vm2.lib.TableLib;
* <p>
* A simple example of initializing globals and using them from Java is:
* <pre> {@code
* LuaValue _G = JsePlatform.standardGlobals();
* Globals _G = JsePlatform.standardGlobals();
* _G.get("print").call(LuaValue.valueOf("hello, world"));
* } </pre>
* <p>
* Once globals are created, a simple way to load and run a script is:
* <pre> {@code
* LoadState.load( new FileInputStream("main.lua"), "main.lua", _G ).call();
* _G.load( new FileInputStream("main.lua"), "main.lua" ).call();
* } </pre>
* <p>
* although {@code require} could also be used:
@@ -58,6 +60,7 @@ import org.luaj.vm2.lib.TableLib;
* <p>
* The standard globals will contain all standard libraries plus {@code luajava}:
* <ul>
* <li>{@link Globals}</li>
* <li>{@link JseBaseLib}</li>
* <li>{@link PackageLib}</li>
* <li>{@link Bit32Lib}</li>
@@ -87,9 +90,8 @@ public class JsePlatform {
* @see JsePlatform
* @see JmePlatform
*/
public static LuaTable standardGlobals() {
LuaTable _G = new LuaTable();
LuaValue._G = _G;
public static Globals standardGlobals() {
Globals _G = new Globals();
_G.load(new JseBaseLib());
_G.load(new PackageLib());
_G.load(new Bit32Lib());
@@ -101,6 +103,7 @@ public class JsePlatform {
_G.load(new JseOsLib());
_G.load(new LuajavaLib());
LuaC.install();
_G.compiler = LuaC.instance;
return _G;
}
@@ -112,8 +115,8 @@ public class JsePlatform {
* @see JmePlatform
* @see DebugLib
*/
public static LuaTable debugGlobals() {
LuaTable _G = standardGlobals();
public static Globals debugGlobals() {
Globals _G = standardGlobals();
_G.load(new DebugLib());
return _G;
}

View File

@@ -102,7 +102,7 @@ public class LuajavaLib extends VarArgFunction {
LuaTable t = new LuaTable();
bind( t, LuajavaLib.class, NAMES, BINDCLASS );
env.set("luajava", t);
PackageLib.instance.LOADED.set("luajava", t);
env.get("package").get("loaded").set("luajava", t);
return t;
}
case BINDCLASS: {

View File

@@ -35,18 +35,14 @@ public class JavaLoader extends ClassLoader {
public JavaLoader() {
}
public LuaFunction load( Prototype p, String classname, String filename ) {
public LuaFunction load( Prototype p, String classname, String filename, LuaValue env ) {
JavaGen jg = new JavaGen( p, classname, filename );
return load( jg );
return load( jg, env );
}
public LuaFunction load( JavaGen jg ) {
public LuaFunction load( JavaGen jg, LuaValue env ) {
include( jg );
return load( jg.classname );
}
public LuaFunction load(String classname) {
return load(classname, LuaValue._G);
return load( jg.classname, env );
}
public LuaFunction load(String classname, LuaValue env) {

View File

@@ -100,7 +100,7 @@ public class LuaJC implements LuaCompiler {
String classname = toStandardJavaClassName( name );
String luaname = toStandardLuaFileName( name );
JavaLoader loader = new JavaLoader();
return loader.load(p, classname, luaname);
return loader.load(p, classname, luaname, env);
}
private static String toStandardJavaClassName( String luachunkname ) {

View File

@@ -24,9 +24,6 @@ package org.luaj.vm2;
import java.io.IOException;
import java.io.InputStream;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.BaseLib;
/**
* Test argument type check errors
@@ -47,7 +44,7 @@ public class ErrorsTest extends ScriptDrivenTest {
}
public void testBaseLibArgs() {
BaseLib.instance.STDIN = new InputStream() {
globals.STDIN = new InputStream() {
public int read() throws IOException {
return -1;
}

View File

@@ -64,15 +64,15 @@ public class FragmentsTest extends TestSuite {
public void runFragment( Varargs expected, String script ) {
try {
String name = getName();
org.luaj.vm2.lib.jse.JsePlatform.debugGlobals();
Globals _G = org.luaj.vm2.lib.jse.JsePlatform.debugGlobals();
InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8"));
LuaValue chunk ;
switch ( TEST_TYPE ) {
case TEST_TYPE_LUAJC:
chunk = LuaJC.getInstance().load(is,name,LuaValue._G);
chunk = LuaJC.getInstance().load(is,name,_G);
break;
default:
chunk = LuaC.instance.load( is, name, LuaValue._G );
chunk = LuaC.instance.load( is, name, _G );
Print.print(((LuaClosure)chunk).p);
break;
}

View File

@@ -56,7 +56,7 @@ public class LuaOperationsTest extends TestCase {
private final LuaValue stringdouble = LuaValue.valueOf(samplestringdouble);
private final LuaTable table = LuaValue.listOf( new LuaValue[] { LuaValue.valueOf("aaa"), LuaValue.valueOf("bbb") } );
private final LuaValue somefunc = new ZeroArgFunction() { public LuaValue call() { return NONE;}};
private final LuaThread thread = new LuaThread(somefunc);
private final LuaThread thread = new LuaThread(new Globals(), somefunc);
private final Prototype proto = new Prototype(1);
private final LuaClosure someclosure = new LuaClosure(proto,table);
private final LuaUserdata userdataobj = LuaValue.userdataOf(sampleobject);
@@ -146,7 +146,7 @@ public class LuaOperationsTest extends TestCase {
// set up suitable environments for execution
LuaValue aaa = LuaValue.valueOf("aaa");
LuaValue eee = LuaValue.valueOf("eee");
LuaTable _G = org.luaj.vm2.lib.jse.JsePlatform.standardGlobals();
final Globals _G = org.luaj.vm2.lib.jse.JsePlatform.standardGlobals();
LuaTable newenv = LuaValue.tableOf( new LuaValue[] {
LuaValue.valueOf("a"), LuaValue.valueOf("aaa"),
LuaValue.valueOf("b"), LuaValue.valueOf("bbb"), } );

View File

@@ -38,8 +38,8 @@ public class MetatableTest extends TestCase {
private final LuaValue string = LuaValue.valueOf(samplestring);
private final LuaTable table = LuaValue.tableOf();
private final LuaFunction function = new ZeroArgFunction() { public LuaValue call() { return NONE;}};
private final LuaThread thread = new LuaThread(function);
private final LuaClosure closure = new LuaClosure(new Prototype());
private final LuaThread thread = new LuaThread(new Globals(), function);
private final LuaClosure closure = new LuaClosure(new Prototype(), new LuaTable());
private final LuaUserdata userdata = LuaValue.userdataOf(sampleobject);
private final LuaUserdata userdatamt = LuaValue.userdataOf(sampledata,table);

View File

@@ -36,6 +36,7 @@ import org.luaj.vm2.lib.jse.JsePlatform;
public class OrphanedThreadTest extends TestCase {
Globals globals;
LuaThread luathread;
WeakReference luathr_ref;
LuaValue function;
@@ -113,7 +114,8 @@ public class OrphanedThreadTest extends TestCase {
}
private void doTest(LuaValue status2, LuaValue value2) throws Exception {
luathread = new LuaThread(function);
globals = JsePlatform.standardGlobals();
luathread = new LuaThread(globals, function);
luathr_ref = new WeakReference(luathread);
func_ref = new WeakReference(function);
assertNotNull(luathr_ref.get());
@@ -142,40 +144,40 @@ public class OrphanedThreadTest extends TestCase {
}
static class NormalFunction extends OneArgFunction {
class NormalFunction extends OneArgFunction {
public LuaValue call(LuaValue arg) {
System.out.println("in normal.1, arg is "+arg);
arg = LuaThread.yield(ONE).arg1();
arg = globals.yield(ONE).arg1();
System.out.println("in normal.2, arg is "+arg);
arg = LuaThread.yield(ZERO).arg1();
arg = globals.yield(ZERO).arg1();
System.out.println("in normal.3, arg is "+arg);
return NONE;
}
}
static class EarlyCompletionFunction extends OneArgFunction {
class EarlyCompletionFunction extends OneArgFunction {
public LuaValue call(LuaValue arg) {
System.out.println("in early.1, arg is "+arg);
arg = LuaThread.yield(ONE).arg1();
arg = globals.yield(ONE).arg1();
System.out.println("in early.2, arg is "+arg);
return ZERO;
}
}
static class AbnormalFunction extends OneArgFunction {
class AbnormalFunction extends OneArgFunction {
public LuaValue call(LuaValue arg) {
System.out.println("in abnormal.1, arg is "+arg);
arg = LuaThread.yield(ONE).arg1();
arg = globals.yield(ONE).arg1();
System.out.println("in abnormal.2, arg is "+arg);
error("abnormal condition");
return ZERO;
}
}
static class ClosureFunction extends OneArgFunction {
class ClosureFunction extends OneArgFunction {
public LuaValue call(LuaValue arg) {
System.out.println("in abnormal.1, arg is "+arg);
arg = LuaThread.yield(ONE).arg1();
arg = globals.yield(ONE).arg1();
System.out.println("in abnormal.2, arg is "+arg);
error("abnormal condition");
return ZERO;

View File

@@ -47,7 +47,7 @@ public class ScriptDrivenTest extends TestCase implements ResourceFinder {
private final PlatformType platform;
private final String subdir;
private LuaTable _G;
protected Globals globals;
static final String zipdir = "test/lua/";
static final String zipfile = "luaj3.0-tests.zip";
@@ -63,10 +63,10 @@ public class ScriptDrivenTest extends TestCase implements ResourceFinder {
default:
case JSE:
case LUAJIT:
_G = org.luaj.vm2.lib.jse.JsePlatform.debugGlobals();
globals = org.luaj.vm2.lib.jse.JsePlatform.standardGlobals();
break;
case JME:
_G = org.luaj.vm2.lib.jme.JmePlatform.debugGlobals();
globals = org.luaj.vm2.lib.jme.JmePlatform.standardGlobals();
break;
}
}
@@ -75,7 +75,7 @@ public class ScriptDrivenTest extends TestCase implements ResourceFinder {
protected void setUp() throws Exception {
super.setUp();
initGlobals();
BaseLib.FINDER = this;
globals.FINDER = this;
}
// ResourceFinder implementation.
@@ -147,13 +147,13 @@ public class ScriptDrivenTest extends TestCase implements ResourceFinder {
try {
// override print()
final ByteArrayOutputStream output = new ByteArrayOutputStream();
final PrintStream oldps = BaseLib.instance.STDOUT;
final PrintStream oldps = globals.STDOUT;
final PrintStream ps = new PrintStream( output );
BaseLib.instance.STDOUT = ps;
globals.STDOUT = ps;
// run the script
try {
LuaValue chunk = loadScript(testName, _G);
LuaValue chunk = loadScript(testName, globals);
chunk.call(LuaValue.valueOf(platform.toString()));
ps.flush();
@@ -164,7 +164,7 @@ public class ScriptDrivenTest extends TestCase implements ResourceFinder {
assertEquals(expectedOutput, actualOutput);
} finally {
BaseLib.instance.STDOUT = oldps;
globals.STDOUT = oldps;
ps.close();
}
} catch ( IOException ioe ) {

View File

@@ -56,8 +56,8 @@ public class TypeTest extends TestCase {
private final LuaValue stringdouble = LuaValue.valueOf(samplestringdouble);
private final LuaTable table = LuaValue.tableOf();
private final LuaFunction somefunc = new ZeroArgFunction() { public LuaValue call() { return NONE;}};
private final LuaThread thread = new LuaThread(somefunc);
private final LuaClosure someclosure = new LuaClosure(new Prototype());
private final LuaThread thread = new LuaThread(new Globals(), somefunc);
private final LuaClosure someclosure = new LuaClosure(new Prototype(), new LuaTable());
private final LuaUserdata userdataobj = LuaValue.userdataOf(sampleobject);
private final LuaUserdata userdatacls = LuaValue.userdataOf(sampledata);