Remove env from LuaFunction, replace with upValiue array, and remove most occurances of setfenv and getfenv.
This commit is contained in:
@@ -34,7 +34,7 @@ public class Lua {
|
||||
|
||||
/** use return values from previous op */
|
||||
public static final int LUA_MULTRET = -1;
|
||||
|
||||
|
||||
// from lopcodes.h
|
||||
|
||||
/*===========================================================================
|
||||
|
||||
@@ -67,7 +67,6 @@ import org.luaj.vm2.lib.DebugLib;
|
||||
* Since a {@link LuaClosure} is a {@link LuaFunction} which is a {@link LuaValue},
|
||||
* all the value operations can be used directly such as:
|
||||
* <ul>
|
||||
* <li>{@link LuaValue#setfenv(LuaValue)}</li>
|
||||
* <li>{@link LuaValue#call()}</li>
|
||||
* <li>{@link LuaValue#call(LuaValue)}</li>
|
||||
* <li>{@link LuaValue#invoke()}</li>
|
||||
@@ -90,24 +89,28 @@ public class LuaClosure extends LuaFunction {
|
||||
private static final UpValue[] NOUPVALUES = new UpValue[0];
|
||||
|
||||
public final Prototype p;
|
||||
public final UpValue[] upValues;
|
||||
|
||||
LuaClosure() {
|
||||
p = null;
|
||||
upValues = null;
|
||||
/** 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);
|
||||
}
|
||||
/** Supply the initial environment */
|
||||
|
||||
/** Create a closure around a Prototype with a specific 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, LuaValue env) {
|
||||
this(p, p.upvalues.length, env);
|
||||
}
|
||||
|
||||
protected LuaClosure(Prototype p, int nupvalues, LuaValue env) {
|
||||
super( env );
|
||||
this.p = p;
|
||||
switch (nupvalues) {
|
||||
case 0: this.upValues = NOUPVALUES; break;
|
||||
case 1: this.upValues = new UpValue[] { new UpValue(new LuaValue[1], 0) }; this.upValues[0].setValue(env); break;
|
||||
default: this.upValues = new UpValue[nupvalues]; break;
|
||||
if (p.upvalues == null || p.upvalues.length == 0)
|
||||
this.upValues = NOUPVALUES;
|
||||
else {
|
||||
this.upValues = new UpValue[p.upvalues.length];
|
||||
this.upValues[0] = new UpValue(new LuaValue[] {env}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,7 +466,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, env);
|
||||
LuaClosure ncl = new LuaClosure(newp);
|
||||
Upvaldesc[] uv = newp.upvalues;
|
||||
for ( int j=0, nup=uv.length; j<nup; ++j ) {
|
||||
if (uv[j].instack) /* upvalue refes to local variable? */
|
||||
|
||||
@@ -38,16 +38,8 @@ public class LuaFunction extends LuaValue {
|
||||
/** Shared static metatable for all functions and closures. */
|
||||
public static LuaValue s_metatable;
|
||||
|
||||
protected LuaValue env;
|
||||
public UpValue[] upValues;
|
||||
|
||||
public LuaFunction() {
|
||||
this.env = NIL;
|
||||
}
|
||||
|
||||
public LuaFunction(LuaValue env) {
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
public int type() {
|
||||
return TFUNCTION;
|
||||
}
|
||||
@@ -71,12 +63,9 @@ public class LuaFunction extends LuaValue {
|
||||
public LuaValue getmetatable() {
|
||||
return s_metatable;
|
||||
}
|
||||
|
||||
public LuaValue getfenv() {
|
||||
return env;
|
||||
}
|
||||
|
||||
public void setfenv(LuaValue env) {
|
||||
this.env = env!=null? env: NIL;
|
||||
public void initupvalue1(LuaValue env) {
|
||||
if (upValues != null && upValues.length > 0)
|
||||
upValues[0] = new UpValue(new LuaValue[] {env}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ public class LuaThread extends LuaValue {
|
||||
"normal",
|
||||
"dead",};
|
||||
|
||||
private LuaValue env;
|
||||
private final State state;
|
||||
|
||||
/** Field to hold state of error condition during debug hook function calls. */
|
||||
@@ -112,11 +111,9 @@ public class LuaThread extends LuaValue {
|
||||
/**
|
||||
* Create a LuaThread around a function and environment
|
||||
* @param func The function to execute
|
||||
* @param env The environment to apply to the thread
|
||||
*/
|
||||
public LuaThread(LuaValue func, LuaValue env) {
|
||||
public LuaThread(LuaValue func) {
|
||||
LuaValue.assert_(func != null, "function cannot be null");
|
||||
this.env = env;
|
||||
state = new State(this, func);
|
||||
}
|
||||
|
||||
@@ -144,14 +141,6 @@ public class LuaThread extends LuaValue {
|
||||
return s_metatable;
|
||||
}
|
||||
|
||||
public LuaValue getfenv() {
|
||||
return env;
|
||||
}
|
||||
|
||||
public void setfenv(LuaValue env) {
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return STATUS_NAMES[state.status];
|
||||
}
|
||||
@@ -171,24 +160,6 @@ public class LuaThread extends LuaValue {
|
||||
public static boolean isMainThread(LuaThread r) {
|
||||
return r == main_thread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the globals of the current thread.
|
||||
* <p>
|
||||
* This must be done once before any other code executes.
|
||||
* @param globals The global variables for the main ghread.
|
||||
*/
|
||||
public static void setGlobals(LuaValue globals) {
|
||||
running_thread.env = globals;
|
||||
}
|
||||
|
||||
/** Get the current thread's environment
|
||||
* @return {@link LuaValue} containing the global variables of the current thread.
|
||||
*/
|
||||
public static LuaValue getGlobals() {
|
||||
LuaValue e = running_thread.env;
|
||||
return e!=null? e: LuaValue.error("LuaThread.setGlobals() not initialized");
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used at the beginning of a call to prepare for possible getfenv/setfenv calls
|
||||
|
||||
@@ -109,7 +109,11 @@ 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);
|
||||
@@ -1351,13 +1355,23 @@ public class LuaValue extends Varargs {
|
||||
public Varargs inext(LuaValue index) { return typerror("table"); }
|
||||
|
||||
/**
|
||||
* Load a library instance by setting its environment to {@code this}
|
||||
* Load a library instance by setting its environment to the global environment {@code LuaValue._G}
|
||||
* and calling it, which should iniitalize the library instance and
|
||||
* install itself into this instance.
|
||||
* @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); }
|
||||
|
||||
/**
|
||||
* Load a library instance by setting its environment to {@code env}
|
||||
* and calling it, which should iniitalize the library instance and
|
||||
* install itself into this instance.
|
||||
* @param library The callable {@link LuaValue} to load into {@code this}
|
||||
* @param env The {@link LuaValue} to use as the environment for the library.
|
||||
* @return {@link LuaValue} containing the result of the initialization call.
|
||||
*/
|
||||
public LuaValue load(LuaValue library) { library.setfenv(this); return library.call(); }
|
||||
public LuaValue load(LuaValue library, LuaValue env) { return library.call(env); }
|
||||
|
||||
// varargs references
|
||||
public LuaValue arg(int index) { return index==1? this: NIL; }
|
||||
@@ -1393,26 +1407,7 @@ public class LuaValue extends Varargs {
|
||||
* @see LuaThread#s_metatable
|
||||
*/
|
||||
public LuaValue setmetatable(LuaValue metatable) { return argerror("table"); }
|
||||
|
||||
/**
|
||||
* Get the environemnt for an instance.
|
||||
* @return {@link LuaValue} currently set as the instances environent.
|
||||
*/
|
||||
public LuaValue getfenv() { typerror("function or thread"); return null; }
|
||||
|
||||
/**
|
||||
* Set the environment on an object.
|
||||
* <p>
|
||||
* Typically the environment is created once per application via a platform
|
||||
* helper method such as {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()}
|
||||
* However, any object can serve as an environment if it contains suitable metatag
|
||||
* values to implement {@link #get(LuaValue)} to provide the environment values.
|
||||
* @param env {@link LuaValue} (typically a {@link LuaTable}) containing the environment.
|
||||
* @see org.luaj.vm2.lib.jme.JmePlatform
|
||||
* @see org.luaj.vm2.lib.jse.JsePlatform
|
||||
*/
|
||||
public void setfenv(LuaValue env) { typerror("function or thread"); }
|
||||
|
||||
|
||||
/** Call {@link this} with 0 arguments, including metatag processing,
|
||||
* and return only the first return value.
|
||||
* <p>
|
||||
|
||||
@@ -51,6 +51,12 @@ public class Prototype {
|
||||
public int is_vararg;
|
||||
public int maxstacksize;
|
||||
|
||||
|
||||
public Prototype() {}
|
||||
|
||||
public Prototype(int n_upvalues) {
|
||||
upvalues = new Upvaldesc[n_upvalues];
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return source + ":" + linedefined+"-"+lastlinedefined;
|
||||
|
||||
@@ -126,7 +126,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
public LuaValue call(LuaValue env) {
|
||||
env.set( "_G", env );
|
||||
env.set( "_VERSION", Lua._VERSION );
|
||||
bind( env, BaseLib1.class, LIB1_KEYS );
|
||||
@@ -230,8 +230,8 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
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", LuaThread.getGlobals() ):
|
||||
BaseLib.loadFile( args.checkjstring(1), "bt", LuaThread.getGlobals() );
|
||||
BaseLib.loadStream( baselib.STDIN, "=stdin", "bt",LuaValue._G ):
|
||||
BaseLib.loadFile( args.checkjstring(1), "bt",LuaValue._G );
|
||||
return v.isnil(1)? error(v.tojstring(2)): v.arg1().invoke();
|
||||
}
|
||||
case 2: // "load", // ( ld [, source [, mode [, env]]] ) -> chunk | nil, msg
|
||||
@@ -240,7 +240,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
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, LuaThread.getGlobals());
|
||||
LuaValue env = args.optvalue(4,LuaValue._G);
|
||||
return BaseLib.loadStream(ld.isstring()? ld.strvalue().toInputStream():
|
||||
new StringInputStream(ld.checkfunction()), source, mode, env);
|
||||
}
|
||||
@@ -249,7 +249,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
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, LuaThread.getGlobals());
|
||||
LuaValue env = args.optvalue(3,LuaValue._G);
|
||||
return filename == null?
|
||||
BaseLib.loadStream( baselib.STDIN, "=stdin", mode, env ):
|
||||
BaseLib.loadFile( filename, mode, env );
|
||||
@@ -275,7 +275,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
}
|
||||
case 6: // "print", // (...) -> void
|
||||
{
|
||||
LuaValue tostring = LuaThread.getGlobals().get("tostring");
|
||||
LuaValue tostring =LuaValue._G.get("tostring");
|
||||
for ( int i=1, n=args.narg(); i<=n; i++ ) {
|
||||
if ( i>1 ) baselib.STDOUT.write( '\t' );
|
||||
LuaString s = tostring.call( args.arg(i) ).strvalue();
|
||||
|
||||
@@ -65,10 +65,16 @@ public class CoroutineLib extends VarArgFunction {
|
||||
private static final int WRAP = 6;
|
||||
private static final int WRAPPED = 7;
|
||||
|
||||
private LuaThread t;
|
||||
|
||||
public CoroutineLib() {
|
||||
}
|
||||
|
||||
private LuaTable init() {
|
||||
private CoroutineLib(LuaThread t) {
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
private LuaTable init(LuaValue env) {
|
||||
LuaTable t = new LuaTable();
|
||||
bind(t, CoroutineLib.class, new String[] {
|
||||
"create", "resume", "running", "status", "yield", "wrap" },
|
||||
@@ -81,11 +87,11 @@ public class CoroutineLib extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
switch ( opcode ) {
|
||||
case INIT: {
|
||||
return init();
|
||||
return init(args.arg1());
|
||||
}
|
||||
case CREATE: {
|
||||
final LuaValue func = args.checkfunction(1);
|
||||
return new LuaThread(func, LuaThread.getGlobals() );
|
||||
return new LuaThread(func);
|
||||
}
|
||||
case RESUME: {
|
||||
final LuaThread t = args.checkthread(1);
|
||||
@@ -103,15 +109,13 @@ public class CoroutineLib extends VarArgFunction {
|
||||
}
|
||||
case WRAP: {
|
||||
final LuaValue func = args.checkfunction(1);
|
||||
final LuaThread thread = new LuaThread(func, func.getfenv());
|
||||
CoroutineLib cl = new CoroutineLib();
|
||||
cl.setfenv(thread);
|
||||
final LuaThread thread = new LuaThread(func);
|
||||
CoroutineLib cl = new CoroutineLib(thread);
|
||||
cl.name = "wrapped";
|
||||
cl.opcode = WRAPPED;
|
||||
return cl;
|
||||
}
|
||||
case WRAPPED: {
|
||||
final LuaThread t = (LuaThread) env;
|
||||
final Varargs result = t.resume( args );
|
||||
if ( result.arg1().toboolean() ) {
|
||||
return result.subargs(2);
|
||||
|
||||
@@ -136,7 +136,7 @@ public class DebugLib extends VarArgFunction {
|
||||
public DebugLib() {
|
||||
}
|
||||
|
||||
private LuaTable init() {
|
||||
private LuaTable init(LuaValue env) {
|
||||
DEBUG_ENABLED = true;
|
||||
LuaTable t = new LuaTable();
|
||||
bind(t, DebugLib.class, NAMES, DEBUG);
|
||||
@@ -147,7 +147,7 @@ public class DebugLib extends VarArgFunction {
|
||||
|
||||
public Varargs invoke(Varargs args) {
|
||||
switch ( opcode ) {
|
||||
case INIT: return init();
|
||||
case INIT: return init(args.arg1());
|
||||
case DEBUG: return _debug(args);
|
||||
case GETHOOK: return _gethook(args);
|
||||
case GETINFO: return _getinfo(args,this);
|
||||
|
||||
@@ -215,7 +215,7 @@ public class IoLib extends OneArgFunction {
|
||||
public IoLib() {
|
||||
}
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
public LuaValue call(LuaValue env) {
|
||||
|
||||
// io lib functions
|
||||
LuaTable t = new LuaTable();
|
||||
@@ -248,12 +248,13 @@ public class IoLib extends OneArgFunction {
|
||||
}
|
||||
|
||||
static final class IoLibV extends VarArgFunction {
|
||||
private File f;
|
||||
public IoLib iolib;
|
||||
public IoLibV() {
|
||||
}
|
||||
public IoLibV(LuaValue env, String name, int opcode, IoLib iolib) {
|
||||
public IoLibV(File f, String name, int opcode, IoLib iolib) {
|
||||
super();
|
||||
this.env = env;
|
||||
this.f = f;
|
||||
this.name = name;
|
||||
this.opcode = opcode;
|
||||
this.iolib = iolib;
|
||||
@@ -283,7 +284,7 @@ public class IoLib extends OneArgFunction {
|
||||
case FILE_WRITE: return iolib._file_write(args.arg1(),args.subargs(2));
|
||||
|
||||
case IO_INDEX: return iolib._io_index(args.arg(2));
|
||||
case LINES_ITER: return iolib._lines_iter(env);
|
||||
case LINES_ITER: return iolib._lines_iter(f);
|
||||
}
|
||||
} catch ( IOException ioe ) {
|
||||
return errorresult(ioe);
|
||||
|
||||
@@ -169,7 +169,6 @@ abstract public class LibFunction extends LuaFunction {
|
||||
LibFunction f = (LibFunction) factory.newInstance();
|
||||
f.opcode = firstopcode + i;
|
||||
f.name = names[i];
|
||||
f.env = env;
|
||||
env.set(f.name, f);
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
|
||||
@@ -83,7 +83,7 @@ public class MathLib extends OneArgFunction {
|
||||
MATHLIB = this;
|
||||
}
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
public LuaValue call(LuaValue env) {
|
||||
LuaTable t = new LuaTable(0,30);
|
||||
t.set( "pi", Math.PI );
|
||||
t.set( "huge", LuaDouble.POSINF );
|
||||
|
||||
@@ -58,7 +58,7 @@ abstract public class OneArgFunction extends LibFunction {
|
||||
* @param env The environment to apply during constructon.
|
||||
*/
|
||||
public OneArgFunction( LuaValue env ) {
|
||||
this.env = env;
|
||||
throw new UnsupportedOperationException("Cannot supply env to constructor");
|
||||
}
|
||||
|
||||
public final LuaValue call() {
|
||||
|
||||
@@ -112,7 +112,7 @@ public class OsLib extends VarArgFunction {
|
||||
public OsLib() {
|
||||
}
|
||||
|
||||
public LuaValue init() {
|
||||
public LuaValue init(LuaValue env) {
|
||||
LuaTable t = new LuaTable();
|
||||
bind(t, this.getClass(), NAMES, CLOCK);
|
||||
env.set("os", t);
|
||||
@@ -124,7 +124,7 @@ public class OsLib extends VarArgFunction {
|
||||
try {
|
||||
switch ( opcode ) {
|
||||
case INIT:
|
||||
return init();
|
||||
return init(args.arg1());
|
||||
case CLOCK:
|
||||
return valueOf(clock());
|
||||
case DATE: {
|
||||
|
||||
@@ -105,18 +105,18 @@ public class PackageLib extends OneArgFunction {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
env.set("require", new PkgLib1(env,"require",OP_REQUIRE,this));
|
||||
public LuaValue call(LuaValue env) {
|
||||
env.set("require", new PkgLib1("require",OP_REQUIRE,this));
|
||||
env.set( "package", PACKAGE=tableOf( new LuaValue[] {
|
||||
_LOADED, LOADED=tableOf(),
|
||||
_PRELOAD, tableOf(),
|
||||
_PATH, valueOf(DEFAULT_LUA_PATH),
|
||||
_LOADLIB, new PkgLibV(env,"loadlib",OP_LOADLIB,this),
|
||||
_SEARCHPATH, new PkgLibV(env,"searchpath",OP_SEARCHPATH,this),
|
||||
_LOADLIB, new PkgLibV("loadlib",OP_LOADLIB,this),
|
||||
_SEARCHPATH, new PkgLibV("searchpath",OP_SEARCHPATH,this),
|
||||
_SEARCHERS, listOf(new LuaValue[] {
|
||||
preload_searcher = new PkgLibV(env,"preload_searcher", OP_PRELOAD_SEARCHER,this),
|
||||
lua_searcher = new PkgLibV(env,"lua_searcher", OP_LUA_SEARCHER,this),
|
||||
java_searcher = new PkgLibV(env,"java_searcher", OP_JAVA_SEARCHER,this),
|
||||
preload_searcher = new PkgLibV("preload_searcher",OP_PRELOAD_SEARCHER, this),
|
||||
lua_searcher = new PkgLibV("lua_searcher",OP_LUA_SEARCHER, this),
|
||||
java_searcher = new PkgLibV("java_searcher",OP_JAVA_SEARCHER, this),
|
||||
}) }) );
|
||||
LOADED.set("package", PACKAGE);
|
||||
return env;
|
||||
@@ -124,8 +124,7 @@ public class PackageLib extends OneArgFunction {
|
||||
|
||||
static final class PkgLib1 extends OneArgFunction {
|
||||
PackageLib lib;
|
||||
public PkgLib1(LuaValue env,String name, int opcode, PackageLib lib) {
|
||||
this.env = env;
|
||||
public PkgLib1(String name, int opcode, PackageLib lib) {
|
||||
this.name = name;
|
||||
this.opcode = opcode;
|
||||
this.lib = lib;
|
||||
@@ -141,8 +140,7 @@ public class PackageLib extends OneArgFunction {
|
||||
|
||||
static final class PkgLibV extends VarArgFunction {
|
||||
PackageLib lib;
|
||||
public PkgLibV(LuaValue env,String name, int opcode, PackageLib lib) {
|
||||
this.env = env;
|
||||
public PkgLibV(String name,int opcode, PackageLib lib) {
|
||||
this.name = name;
|
||||
this.opcode = opcode;
|
||||
this.lib = lib;
|
||||
@@ -286,7 +284,7 @@ public class PackageLib extends OneArgFunction {
|
||||
LuaString filename = v.arg1().strvalue();
|
||||
|
||||
// Try to load the file.
|
||||
v = BaseLib.loadFile(filename.tojstring(), "bt", LuaThread.getGlobals());
|
||||
v = BaseLib.loadFile(filename.tojstring(), "bt", LuaValue._G);
|
||||
if ( v.arg1().isfunction() )
|
||||
return LuaValue.varargsOf(v.arg1(), filename);
|
||||
|
||||
@@ -340,7 +338,6 @@ public class PackageLib extends OneArgFunction {
|
||||
try {
|
||||
c = Class.forName(classname);
|
||||
v = (LuaValue) c.newInstance();
|
||||
v.setfenv(env);
|
||||
return v;
|
||||
} catch ( ClassNotFoundException cnfe ) {
|
||||
return valueOf("\n\tno class '"+classname+"'" );
|
||||
|
||||
@@ -66,7 +66,7 @@ public class StringLib extends OneArgFunction {
|
||||
public StringLib() {
|
||||
}
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
public LuaValue call(LuaValue env) {
|
||||
LuaTable t = new LuaTable();
|
||||
bind(t, StringLib1.class, new String[] {
|
||||
"dump", "len", "lower", "reverse", "upper", } );
|
||||
|
||||
@@ -61,7 +61,7 @@ public class TableLib extends OneArgFunction {
|
||||
public TableLib() {
|
||||
}
|
||||
|
||||
private LuaTable init() {
|
||||
private LuaTable init(LuaValue env) {
|
||||
LuaTable t = new LuaTable();
|
||||
bind(t, TableLib.class, new String[] { "getn", "maxn", }, 1 );
|
||||
bind(t, TableLibV.class, new String[] {
|
||||
@@ -74,7 +74,7 @@ public class TableLib extends OneArgFunction {
|
||||
public LuaValue call(LuaValue arg) {
|
||||
switch ( opcode ) {
|
||||
case 0: // init library
|
||||
return init();
|
||||
return init(arg);
|
||||
case 1: // "getn" (table) -> number
|
||||
return arg.checktable().getn();
|
||||
case 2: // "maxn" (table) -> number
|
||||
|
||||
@@ -58,7 +58,7 @@ abstract public class ThreeArgFunction extends LibFunction {
|
||||
* @param env The environment to apply during constructon.
|
||||
*/
|
||||
public ThreeArgFunction( LuaValue env ) {
|
||||
this.env = env;
|
||||
throw new UnsupportedOperationException("Cannot supply env to constructor");
|
||||
}
|
||||
|
||||
public final LuaValue call() {
|
||||
|
||||
@@ -58,7 +58,7 @@ abstract public class TwoArgFunction extends LibFunction {
|
||||
* @param env The environment to apply during constructon.
|
||||
*/
|
||||
public TwoArgFunction( LuaValue env ) {
|
||||
this.env = env;
|
||||
throw new UnsupportedOperationException("Cannot supply env to constructor");
|
||||
}
|
||||
|
||||
public final LuaValue call() {
|
||||
|
||||
@@ -51,7 +51,7 @@ abstract public class VarArgFunction extends LibFunction {
|
||||
}
|
||||
|
||||
public VarArgFunction( LuaValue env ) {
|
||||
this.env = env;
|
||||
throw new UnsupportedOperationException("Cannot supply env to constructor");
|
||||
}
|
||||
|
||||
public LuaValue call() {
|
||||
@@ -71,30 +71,12 @@ abstract public class VarArgFunction extends LibFunction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override and implement for the best performance.
|
||||
* Subclass responsibility.
|
||||
* May not have expected behavior for tail calls.
|
||||
* Should not be used if either:
|
||||
* - function needs to be used as a module
|
||||
* Should not be used if:
|
||||
* - function has a possibility of returning a TailcallVarargs
|
||||
* @param args the arguments to the function call.
|
||||
*/
|
||||
public Varargs invoke(Varargs args) {
|
||||
LuaThread.CallStack cs = LuaThread.onCall(this);
|
||||
try {
|
||||
return this.onInvoke(args).eval();
|
||||
} finally {
|
||||
cs.onReturn();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to provide a call implementation that runs in an environment
|
||||
* that can participate in setfenv, and behaves as expected
|
||||
* when returning TailcallVarargs.
|
||||
* @param args the arguments to the function call.
|
||||
*/
|
||||
public Varargs onInvoke(Varargs args) {
|
||||
return invoke(args);
|
||||
}
|
||||
abstract public Varargs invoke(Varargs args);
|
||||
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ abstract public class ZeroArgFunction extends LibFunction {
|
||||
* @param env The environment to apply during constructon.
|
||||
*/
|
||||
public ZeroArgFunction( LuaValue env ) {
|
||||
this.env = env;
|
||||
throw new UnsupportedOperationException("Cannot supply env to constructor");
|
||||
}
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
|
||||
@@ -101,6 +101,7 @@ public class JmePlatform {
|
||||
*/
|
||||
public static LuaTable standardGlobals() {
|
||||
LuaTable _G = new LuaTable();
|
||||
LuaValue._G = _G;
|
||||
_G.load(new BaseLib());
|
||||
_G.load(new PackageLib());
|
||||
_G.load(new OsLib());
|
||||
@@ -109,7 +110,6 @@ public class JmePlatform {
|
||||
_G.load(new StringLib());
|
||||
_G.load(new CoroutineLib());
|
||||
_G.load(new JmeIoLib());
|
||||
LuaThread.setGlobals(_G);
|
||||
LuaC.install();
|
||||
return _G;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,6 @@ public class lua {
|
||||
try {
|
||||
// load as java class
|
||||
LuaValue v = (LuaValue) Class.forName(libname).newInstance();
|
||||
v.setfenv(_G);
|
||||
v.call(slibname, _G);
|
||||
} catch ( Exception f ) {
|
||||
throw new IOException("loadLibrary("+libname+") failed: "+e+","+f );
|
||||
|
||||
@@ -87,6 +87,7 @@ public class JsePlatform {
|
||||
*/
|
||||
public static LuaTable standardGlobals() {
|
||||
LuaTable _G = new LuaTable();
|
||||
LuaValue._G = _G;
|
||||
_G.load(new JseBaseLib());
|
||||
_G.load(new PackageLib());
|
||||
_G.load(new TableLib());
|
||||
@@ -96,7 +97,6 @@ public class JsePlatform {
|
||||
_G.load(new JseIoLib());
|
||||
_G.load(new JseOsLib());
|
||||
_G.load(new LuajavaLib());
|
||||
LuaThread.setGlobals(_G);
|
||||
LuaC.install();
|
||||
return _G;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ public class LuajavaLib extends VarArgFunction {
|
||||
try {
|
||||
switch ( opcode ) {
|
||||
case INIT: {
|
||||
LuaValue env = args.arg1();
|
||||
LuaTable t = new LuaTable();
|
||||
bind( t, LuajavaLib.class, NAMES, BINDCLASS );
|
||||
env.set("luajava", t);
|
||||
|
||||
@@ -112,7 +112,6 @@ public class Lua2Java implements LuaCompiler {
|
||||
Class clazz = cl.loadClass(className);
|
||||
Object instance = clazz.newInstance();
|
||||
LuaFunction value = (LuaFunction) instance;
|
||||
value.setfenv( env );
|
||||
return value;
|
||||
} else {
|
||||
}
|
||||
|
||||
@@ -30,12 +30,9 @@ import org.luaj.vm2.Prototype;
|
||||
******************************************************************************/
|
||||
public class JavaLoader extends ClassLoader {
|
||||
|
||||
private final LuaValue env;
|
||||
|
||||
private Map<String,byte[]> unloaded = new HashMap<String,byte[]>();
|
||||
|
||||
public JavaLoader( LuaValue env ) {
|
||||
this.env = env;
|
||||
public JavaLoader() {
|
||||
}
|
||||
|
||||
public LuaFunction load( Prototype p, String classname, String filename ) {
|
||||
@@ -49,10 +46,14 @@ public class JavaLoader extends ClassLoader {
|
||||
}
|
||||
|
||||
public LuaFunction load(String classname) {
|
||||
return load(classname, LuaValue._G);
|
||||
}
|
||||
|
||||
public LuaFunction load(String classname, LuaValue env) {
|
||||
try {
|
||||
Class c = loadClass( classname );
|
||||
LuaFunction v = (LuaFunction) c.newInstance();
|
||||
v.setfenv(env);
|
||||
v.initupvalue1(env);
|
||||
return v;
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -99,7 +99,7 @@ public class LuaJC implements LuaCompiler {
|
||||
Prototype p = LuaC.instance.compile(stream, name);
|
||||
String classname = toStandardJavaClassName( name );
|
||||
String luaname = toStandardLuaFileName( name );
|
||||
JavaLoader loader = new JavaLoader(env);
|
||||
JavaLoader loader = new JavaLoader();
|
||||
return loader.load(p, classname, luaname);
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
||||
Bindings b = context.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
LuaFunction f = newFunctionInstance();
|
||||
ClientBindings cb = new ClientBindings(b);
|
||||
f.setfenv(cb.env);
|
||||
f.initupvalue1(cb.env);
|
||||
Varargs result = f.invoke(LuaValue.NONE);
|
||||
cb.copyGlobalsToBindings();
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user