Remove env from LuaFunction, replace with upValiue array, and remove most occurances of setfenv and getfenv.

This commit is contained in:
James Roseborough
2012-09-07 04:36:50 +00:00
parent 244a964af5
commit 3bacea878e
36 changed files with 130 additions and 265 deletions

View File

@@ -34,7 +34,7 @@ public class Lua {
/** use return values from previous op */
public static final int LUA_MULTRET = -1;
// from lopcodes.h
/*===========================================================================

View File

@@ -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? */

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 ) {

View File

@@ -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 );

View File

@@ -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() {

View File

@@ -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: {

View File

@@ -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+"'" );

View File

@@ -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", } );

View File

@@ -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

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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 {
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -60,7 +60,7 @@ public class TestLuaJC {
} else {
chunk = (LuaValue) Class.forName("script").newInstance();
}
chunk.setfenv(_G);
//chunk.setfenv(_G); // TODO: convert to setupvalue()?
// call with arguments
LuaValue[] vargs = new LuaValue[args.length];

View File

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

View File

@@ -55,9 +55,9 @@ public class LuaOperationsTest extends TestCase {
private final LuaValue stringlong = LuaValue.valueOf(samplestringlong);
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(table) { public LuaValue call() { return NONE;}};
private final LuaThread thread = new LuaThread(somefunc,table);
private final Prototype proto = new Prototype();
private final LuaValue somefunc = new ZeroArgFunction() { public LuaValue call() { return NONE;}};
private final LuaThread thread = new LuaThread(somefunc);
private final Prototype proto = new Prototype(1);
private final LuaClosure someclosure = new LuaClosure(proto,table);
private final LuaUserdata userdataobj = LuaValue.userdataOf(sampleobject);
private final LuaUserdata userdatacls = LuaValue.userdataOf(sampledata);
@@ -127,55 +127,6 @@ public class LuaOperationsTest extends TestCase {
throwsLuaError( "length", userdataobj );
throwsLuaError( "length", userdatacls );
}
public void testGetfenv() {
throwsLuaError( "getfenv", somenil );
throwsLuaError( "getfenv", sometrue );
throwsLuaError( "getfenv", somefalse );
throwsLuaError( "getfenv", zero );
throwsLuaError( "getfenv", intint );
throwsLuaError( "getfenv", longdouble );
throwsLuaError( "getfenv", doubledouble );
throwsLuaError( "getfenv", stringstring );
throwsLuaError( "getfenv", stringint );
throwsLuaError( "getfenv", stringlong );
throwsLuaError( "getfenv", stringdouble );
throwsLuaError( "getfenv", table );
assertTrue( table == thread.getfenv() );
assertTrue( table == someclosure.getfenv() );
assertTrue( table == somefunc.getfenv() );
throwsLuaError( "getfenv", userdataobj );
throwsLuaError( "getfenv", userdatacls );
}
public void testSetfenv() {
LuaTable table2 = LuaValue.listOf( new LuaValue[] {
LuaValue.valueOf("ccc"),
LuaValue.valueOf("ddd") } );
throwsLuaError( "setfenv", somenil, table2 );
throwsLuaError( "setfenv", sometrue, table2 );
throwsLuaError( "setfenv", somefalse, table2 );
throwsLuaError( "setfenv", zero, table2 );
throwsLuaError( "setfenv", intint, table2 );
throwsLuaError( "setfenv", longdouble, table2 );
throwsLuaError( "setfenv", doubledouble, table2 );
throwsLuaError( "setfenv", stringstring, table2 );
throwsLuaError( "setfenv", stringint, table2 );
throwsLuaError( "setfenv", stringlong, table2 );
throwsLuaError( "setfenv", stringdouble, table2 );
throwsLuaError( "setfenv", table, table2 );
thread.setfenv(table2);
assertTrue( table2 == thread.getfenv() );
assertTrue( table == someclosure.getfenv() );
assertTrue( table == somefunc.getfenv() );
someclosure.setfenv(table2);
assertTrue( table2 == someclosure.getfenv() );
assertTrue( table == somefunc.getfenv() );
somefunc.setfenv(table2);
assertTrue( table2 == somefunc.getfenv() );
throwsLuaError( "setfenv", userdataobj, table2 );
throwsLuaError( "setfenv", userdatacls, table2 );
}
public Prototype createPrototype( String script, String name ) {
try {
@@ -206,56 +157,20 @@ public class LuaOperationsTest extends TestCase {
// function tests
{
LuaFunction f = new ZeroArgFunction(_G) { public LuaValue call() { return env.get("a");}};
LuaFunction f = new ZeroArgFunction() { public LuaValue call() { return _G.get("a");}};
assertEquals( aaa, f.call() );
f.setfenv(newenv);
assertEquals( newenv, f.getfenv() );
assertEquals( eee, f.call() );
}
// closure tests
{
Prototype p = createPrototype( "return a\n", "closuretester" );
LuaClosure c = new LuaClosure(p, _G);
// Test that a clusure with a custom enviroment uses that environment.
assertEquals( aaa, c.call() );
c.setfenv(newenv);
assertEquals( newenv, c.getfenv() );
c = new LuaClosure(p, newenv);
assertEquals( newenv, c.upValues[0].getValue() );
assertEquals( eee, c.call() );
}
// thread tests, functions created in threads inherit the thread's environment initially
// those closures created not in any other function get the thread's enviroment
Prototype p2 = createPrototype( "return loadstring('return a')", "threadtester" );
{
LuaThread t = new LuaThread(new LuaClosure(p2,_G), _G);
Varargs v = t.resume(LuaValue.NONE);
assertEquals(LuaValue.TRUE, v.arg(1) );
LuaValue f = v.arg(2);
assertEquals( LuaValue.TFUNCTION, f.type() );
assertEquals( aaa, f.call() );
assertEquals( _G, f.getfenv() );
}
{
// change the thread environment after creation!
LuaThread t = new LuaThread(new LuaClosure(p2,_G), _G);
t.setfenv(newenv);
Varargs v = t.resume(LuaValue.NONE);
assertEquals(LuaValue.TRUE, v.arg(1) );
LuaValue f = v.arg(2);
assertEquals( LuaValue.TFUNCTION, f.type() );
assertEquals( eee, f.call() );
assertEquals( newenv, f.getfenv() );
}
{
// let the closure have a different environment from the thread
Prototype p3 = createPrototype( "return function() return a end", "envtester" );
LuaThread t = new LuaThread(new LuaClosure(p3,newenv), _G);
Varargs v = t.resume(LuaValue.NONE);
assertEquals(LuaValue.TRUE, v.arg(1) );
LuaValue f = v.arg(2);
assertEquals( LuaValue.TFUNCTION, f.type() );
assertEquals( eee, f.call() );
assertEquals( newenv, f.getfenv() );
}
}
}

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,table);
private final LuaClosure closure = new LuaClosure();
private final LuaThread thread = new LuaThread(function);
private final LuaClosure closure = new LuaClosure(new Prototype());
private final LuaUserdata userdata = LuaValue.userdataOf(sampleobject);
private final LuaUserdata userdatamt = LuaValue.userdataOf(sampledata,table);

View File

@@ -113,7 +113,7 @@ public class OrphanedThreadTest extends TestCase {
}
private void doTest(LuaValue status2, LuaValue value2) throws Exception {
luathread = new LuaThread(function, env);
luathread = new LuaThread(function);
luathr_ref = new WeakReference(luathread);
func_ref = new WeakReference(function);
assertNotNull(luathr_ref.get());

View File

@@ -119,7 +119,6 @@ public class ScriptDrivenTest extends TestCase {
case LUAJIT:
if ( nocompile ) {
LuaValue c = (LuaValue) Class.forName(name).newInstance();
c.setfenv(_G);
return c;
} else {
script = new FileInputStream(file);

View File

@@ -26,8 +26,12 @@ import java.lang.reflect.InvocationTargetException;
import junit.framework.TestCase;
import org.luaj.vm2.lib.ZeroArgFunction;
import org.luaj.vm2.lib.jse.JsePlatform;
public class TypeTest extends TestCase {
static {
JsePlatform.debugGlobals();
}
private final int sampleint = 77;
private final long samplelong = 123400000000L;
@@ -52,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,table);
private final LuaClosure someclosure = new LuaClosure();
private final LuaThread thread = new LuaThread(somefunc);
private final LuaClosure someclosure = new LuaClosure(new Prototype());
private final LuaUserdata userdataobj = LuaValue.userdataOf(sampleobject);
private final LuaUserdata userdatacls = LuaValue.userdataOf(sampledata);