Fix setfenv(), getfenv(), let threads inherit environment.
This commit is contained in:
@@ -115,10 +115,16 @@ public class LuaThread extends LuaValue implements Runnable {
|
|||||||
public static boolean isMainThread(LuaThread r) {
|
public static boolean isMainThread(LuaThread r) {
|
||||||
return r == mainthread;
|
return r == mainthread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get environment of the running thread, or defval if not defined */
|
/** Set the globals of the current thread */
|
||||||
public static LuaValue getRunningEnv(LuaValue defval) {
|
public static void setGlobals(LuaValue globals) {
|
||||||
return running_thread.env!=null? running_thread.env: defval;
|
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) {
|
public static final void onCall(LuaFunction function) {
|
||||||
@@ -137,9 +143,14 @@ public class LuaThread extends LuaValue implements Runnable {
|
|||||||
return running_thread.calls;
|
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) {
|
public static final LuaFunction getCallstackFunction(int level) {
|
||||||
return level>=0 && level<running_thread.calls?
|
return level>0 && level<=running_thread.calls?
|
||||||
running_thread.callstack[running_thread.calls-level-1]:
|
running_thread.callstack[running_thread.calls-level]:
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,4 +233,5 @@ public class LuaThread extends LuaValue implements Runnable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import java.io.PrintStream;
|
|||||||
|
|
||||||
import org.luaj.vm2.LoadState;
|
import org.luaj.vm2.LoadState;
|
||||||
import org.luaj.vm2.LuaError;
|
import org.luaj.vm2.LuaError;
|
||||||
|
import org.luaj.vm2.LuaFunction;
|
||||||
import org.luaj.vm2.LuaString;
|
import org.luaj.vm2.LuaString;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
import org.luaj.vm2.LuaThread;
|
import org.luaj.vm2.LuaThread;
|
||||||
@@ -131,13 +132,8 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
protected LuaValue oncall1(int opcode, LuaValue arg) {
|
protected LuaValue oncall1(int opcode, LuaValue arg) {
|
||||||
switch ( opcode ) {
|
switch ( opcode ) {
|
||||||
case 0: { // "getfenv", // ( [f] ) -> env
|
case 0: { // "getfenv", // ( [f] ) -> env
|
||||||
if ( ! arg.isfunction() ) {
|
LuaValue f = getfenvobj(arg);
|
||||||
int i = arg.optint(0);
|
LuaValue e = f.getfenv();
|
||||||
arg = (i==0)? (LuaValue) LuaThread.getRunning(): (LuaValue) LuaThread.getCallstackFunction(i-1);
|
|
||||||
if ( arg == null )
|
|
||||||
LuaValue.argerror(1, "invalid level");
|
|
||||||
}
|
|
||||||
LuaValue e = arg.getfenv();
|
|
||||||
return e!=null? e: NIL;
|
return e!=null? e: NIL;
|
||||||
}
|
}
|
||||||
case 1: // "getmetatable", // ( object ) -> table
|
case 1: // "getmetatable", // ( object ) -> table
|
||||||
@@ -148,7 +144,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
}
|
}
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LuaValue oncall2(int opcode, LuaValue arg1, LuaValue arg2) {
|
protected LuaValue oncall2(int opcode, LuaValue arg1, LuaValue arg2) {
|
||||||
switch ( opcode ) {
|
switch ( opcode ) {
|
||||||
case 0: // "collectgarbage", // ( opt [,arg] ) -> value
|
case 0: // "collectgarbage", // ( opt [,arg] ) -> value
|
||||||
@@ -172,15 +168,10 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
case 2: // "rawequal", // (v1, v2) -> boolean
|
case 2: // "rawequal", // (v1, v2) -> boolean
|
||||||
return valueOf(arg1 == arg2);
|
return valueOf(arg1 == arg2);
|
||||||
case 3: { // "setfenv", // (f, table) -> void
|
case 3: { // "setfenv", // (f, table) -> void
|
||||||
LuaValue f = arg1;
|
LuaTable t = arg2.checktable();
|
||||||
if ( ! f.isfunction() ) {
|
LuaValue f = getfenvobj(arg1);
|
||||||
int i = arg1.checkint(0);
|
f.setfenv(t);
|
||||||
f = (i==0)? (LuaValue) LuaThread.getRunning(): (LuaValue) LuaThread.getCallstackFunction(i-1);
|
return f.isthread()? NONE: f;
|
||||||
if ( f == null )
|
|
||||||
LuaValue.argerror(1, "invalid level");
|
|
||||||
}
|
|
||||||
f.setfenv(arg2);
|
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
case 4: // "tonumber", // (e [,base]) -> value
|
case 4: // "tonumber", // (e [,base]) -> value
|
||||||
final int base = arg2.optint(10);
|
final int base = arg2.optint(10);
|
||||||
@@ -195,6 +186,17 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
}
|
}
|
||||||
return NIL;
|
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) {
|
protected Varargs oncallv(int opcode, Varargs args) {
|
||||||
switch ( opcode ) {
|
switch ( opcode ) {
|
||||||
@@ -216,7 +218,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
try {
|
try {
|
||||||
LuaValue func = args.checkfunction(1);
|
LuaValue func = args.checkfunction(1);
|
||||||
String chunkname = args.optString(2, "function");
|
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 ) {
|
} catch ( Exception e ) {
|
||||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -233,7 +235,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
try {
|
try {
|
||||||
LuaString script = args.checkstring(1);
|
LuaString script = args.checkstring(1);
|
||||||
String chunkname = args.optString(2, "string");
|
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 ) {
|
} catch ( Exception e ) {
|
||||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -279,7 +281,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
}
|
}
|
||||||
case 7: // "print", // (...) -> void
|
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++ ) {
|
for ( int i=1, n=args.narg(); i<=n; i++ ) {
|
||||||
if ( i>1 ) STDOUT.write( '\t' );
|
if ( i>1 ) STDOUT.write( '\t' );
|
||||||
LuaString s = tostring.call( args.arg(i) ).strvalue();
|
LuaString s = tostring.call( args.arg(i) ).strvalue();
|
||||||
@@ -347,7 +349,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
if ( is == null )
|
if ( is == null )
|
||||||
return varargsOf(NIL, valueOf("not found: "+filename));
|
return varargsOf(NIL, valueOf("not found: "+filename));
|
||||||
try {
|
try {
|
||||||
return LoadState.load(is, filename, LuaThread.getRunningEnv(env));
|
return LoadState.load(is, filename, LuaThread.getGlobals());
|
||||||
} finally {
|
} finally {
|
||||||
is.close();
|
is.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class CoroutineLib extends ZeroArgFunction {
|
|||||||
switch ( opcode ) {
|
switch ( opcode ) {
|
||||||
case CREATE: {
|
case CREATE: {
|
||||||
final LuaValue func = args.checkfunction(1);
|
final LuaValue func = args.checkfunction(1);
|
||||||
return new LuaThread(func, func.getfenv() );
|
return new LuaThread(func, LuaThread.getGlobals() );
|
||||||
}
|
}
|
||||||
case RESUME: {
|
case RESUME: {
|
||||||
final LuaThread t = args.checkthread(1);
|
final LuaThread t = args.checkthread(1);
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ import java.io.InputStream;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaFunction;
|
import org.luaj.vm2.LuaFunction;
|
||||||
import org.luaj.vm2.LuaThread;
|
|
||||||
import org.luaj.vm2.LuaString;
|
import org.luaj.vm2.LuaString;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
|
import org.luaj.vm2.LuaThread;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.Varargs;
|
import org.luaj.vm2.Varargs;
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ public class PackageLib extends OneArgFunction {
|
|||||||
LuaValue m = t.getmetatable();
|
LuaValue m = t.getmetatable();
|
||||||
if ( m == null )
|
if ( m == null )
|
||||||
t.setmetatable(m=tableOf());
|
t.setmetatable(m=tableOf());
|
||||||
m.set( INDEX, env );
|
m.set( INDEX, LuaThread.getGlobals() );
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
package org.luaj.vm2.lib;
|
package org.luaj.vm2.lib;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
|
import org.luaj.vm2.LuaThread;
|
||||||
import org.luaj.vm2.lib.jme.JmeIoLib;
|
import org.luaj.vm2.lib.jme.JmeIoLib;
|
||||||
|
|
||||||
public class JmePlatform {
|
public class JmePlatform {
|
||||||
@@ -41,6 +42,7 @@ public class JmePlatform {
|
|||||||
_G.load(new StringLib());
|
_G.load(new StringLib());
|
||||||
_G.load(new CoroutineLib());
|
_G.load(new CoroutineLib());
|
||||||
_G.load(new JmeIoLib());
|
_G.load(new JmeIoLib());
|
||||||
|
LuaThread.setGlobals(_G);
|
||||||
return _G;
|
return _G;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
package org.luaj.vm2.lib;
|
package org.luaj.vm2.lib;
|
||||||
|
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
|
import org.luaj.vm2.LuaThread;
|
||||||
import org.luaj.vm2.lib.jse.JseBaseLib;
|
import org.luaj.vm2.lib.jse.JseBaseLib;
|
||||||
import org.luaj.vm2.lib.jse.JseIoLib;
|
import org.luaj.vm2.lib.jse.JseIoLib;
|
||||||
import org.luaj.vm2.lib.jse.JseMathLib;
|
import org.luaj.vm2.lib.jse.JseMathLib;
|
||||||
@@ -47,6 +48,7 @@ public class JsePlatform {
|
|||||||
_G.load(new JseIoLib());
|
_G.load(new JseIoLib());
|
||||||
_G.load(new JseOsLib());
|
_G.load(new JseOsLib());
|
||||||
_G.load(new LuajavaLib());
|
_G.load(new LuajavaLib());
|
||||||
|
LuaThread.setGlobals(_G);
|
||||||
return _G;
|
return _G;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user