Fix setfenv(), getfenv(), let threads inherit environment.

This commit is contained in:
James Roseborough
2010-04-17 13:15:16 +00:00
parent c0a1d002c7
commit 00f8d291f9
6 changed files with 48 additions and 30 deletions

View File

@@ -115,10 +115,16 @@ public class LuaThread extends LuaValue implements Runnable {
public static boolean isMainThread(LuaThread r) {
return r == mainthread;
}
/** get environment of the running thread, or defval if not defined */
public static LuaValue getRunningEnv(LuaValue defval) {
return running_thread.env!=null? running_thread.env: defval;
/** Set the globals of the current thread */
public static void setGlobals(LuaValue globals) {
running_thread.env = globals;
}
/** Get the current thread's environment */
public static LuaValue getGlobals() {
LuaValue e = running_thread.env;
return e!=null? e: LuaValue.error("LuaThread.setGlobals() not initialized");
}
public static final void onCall(LuaFunction function) {
@@ -137,9 +143,14 @@ public class LuaThread extends LuaValue implements Runnable {
return running_thread.calls;
}
/**
* 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 level>=0 && level<running_thread.calls?
running_thread.callstack[running_thread.calls-level-1]:
return level>0 && level<=running_thread.calls?
running_thread.callstack[running_thread.calls-level]:
null;
}
@@ -222,4 +233,5 @@ public class LuaThread extends LuaValue implements Runnable {
}
}

View File

@@ -26,6 +26,7 @@ import java.io.PrintStream;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
@@ -131,13 +132,8 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
protected LuaValue oncall1(int opcode, LuaValue arg) {
switch ( opcode ) {
case 0: { // "getfenv", // ( [f] ) -> env
if ( ! arg.isfunction() ) {
int i = arg.optint(0);
arg = (i==0)? (LuaValue) LuaThread.getRunning(): (LuaValue) LuaThread.getCallstackFunction(i-1);
if ( arg == null )
LuaValue.argerror(1, "invalid level");
}
LuaValue e = arg.getfenv();
LuaValue f = getfenvobj(arg);
LuaValue e = f.getfenv();
return e!=null? e: NIL;
}
case 1: // "getmetatable", // ( object ) -> table
@@ -148,7 +144,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
return NIL;
}
protected LuaValue oncall2(int opcode, LuaValue arg1, LuaValue arg2) {
switch ( opcode ) {
case 0: // "collectgarbage", // ( opt [,arg] ) -> value
@@ -172,15 +168,10 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
case 2: // "rawequal", // (v1, v2) -> boolean
return valueOf(arg1 == arg2);
case 3: { // "setfenv", // (f, table) -> void
LuaValue f = arg1;
if ( ! f.isfunction() ) {
int i = arg1.checkint(0);
f = (i==0)? (LuaValue) LuaThread.getRunning(): (LuaValue) LuaThread.getCallstackFunction(i-1);
if ( f == null )
LuaValue.argerror(1, "invalid level");
}
f.setfenv(arg2);
return f;
LuaTable t = arg2.checktable();
LuaValue f = getfenvobj(arg1);
f.setfenv(t);
return f.isthread()? NONE: f;
}
case 4: // "tonumber", // (e [,base]) -> value
final int base = arg2.optint(10);
@@ -195,6 +186,17 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
return NIL;
}
private LuaValue getfenvobj(LuaValue arg) {
if ( arg.isclosure() )
return arg;
int level = arg.optint(1);
if ( level == 0 )
return LuaThread.getRunning();
LuaValue f = LuaThread.getCallstackFunction(level);
arg.argcheck(f != null, 1, "invalid level");
return f;
}
protected Varargs oncallv(int opcode, Varargs args) {
switch ( opcode ) {
@@ -216,7 +218,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
try {
LuaValue func = args.checkfunction(1);
String chunkname = args.optString(2, "function");
return LoadState.load(new StringInputStream(func), chunkname, LuaThread.getRunningEnv(env));
return LoadState.load(new StringInputStream(func), chunkname, LuaThread.getGlobals());
} catch ( Exception e ) {
return varargsOf(NIL, valueOf(e.getMessage()));
}
@@ -233,7 +235,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
try {
LuaString script = args.checkstring(1);
String chunkname = args.optString(2, "string");
return LoadState.load(script.toInputStream(),chunkname,LuaThread.getRunningEnv(env));
return LoadState.load(script.toInputStream(),chunkname,LuaThread.getGlobals());
} catch ( Exception e ) {
return varargsOf(NIL, valueOf(e.getMessage()));
}
@@ -279,7 +281,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
}
case 7: // "print", // (...) -> void
{
LuaValue tostring = env.get("tostring");
LuaValue tostring = LuaThread.getGlobals().get("tostring");
for ( int i=1, n=args.narg(); i<=n; i++ ) {
if ( i>1 ) STDOUT.write( '\t' );
LuaString s = tostring.call( args.arg(i) ).strvalue();
@@ -347,7 +349,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
if ( is == null )
return varargsOf(NIL, valueOf("not found: "+filename));
try {
return LoadState.load(is, filename, LuaThread.getRunningEnv(env));
return LoadState.load(is, filename, LuaThread.getGlobals());
} finally {
is.close();
}

View File

@@ -51,7 +51,7 @@ public class CoroutineLib extends ZeroArgFunction {
switch ( opcode ) {
case CREATE: {
final LuaValue func = args.checkfunction(1);
return new LuaThread(func, func.getfenv() );
return new LuaThread(func, LuaThread.getGlobals() );
}
case RESUME: {
final LuaThread t = args.checkthread(1);

View File

@@ -25,9 +25,9 @@ import java.io.InputStream;
import java.io.PrintStream;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaThread;
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;
@@ -91,7 +91,7 @@ public class PackageLib extends OneArgFunction {
LuaValue m = t.getmetatable();
if ( m == null )
t.setmetatable(m=tableOf());
m.set( INDEX, env );
m.set( INDEX, LuaThread.getGlobals() );
return NONE;
}
}

View File

@@ -22,6 +22,7 @@
package org.luaj.vm2.lib;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.lib.jme.JmeIoLib;
public class JmePlatform {
@@ -41,6 +42,7 @@ public class JmePlatform {
_G.load(new StringLib());
_G.load(new CoroutineLib());
_G.load(new JmeIoLib());
LuaThread.setGlobals(_G);
return _G;
}

View File

@@ -22,6 +22,7 @@
package org.luaj.vm2.lib;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.lib.jse.JseBaseLib;
import org.luaj.vm2.lib.jse.JseIoLib;
import org.luaj.vm2.lib.jse.JseMathLib;
@@ -47,6 +48,7 @@ public class JsePlatform {
_G.load(new JseIoLib());
_G.load(new JseOsLib());
_G.load(new LuajavaLib());
LuaThread.setGlobals(_G);
return _G;
}
}