diff --git a/src/core/org/luaj/vm2/LuaTable.java b/src/core/org/luaj/vm2/LuaTable.java index b73de9fe..31282bfc 100644 --- a/src/core/org/luaj/vm2/LuaTable.java +++ b/src/core/org/luaj/vm2/LuaTable.java @@ -200,7 +200,7 @@ public class LuaTable extends LuaValue { } } - public Varargs remove(int pos) { + public LuaValue remove(int pos) { if ( pos == 0 ) pos = length(); if ( pos < 1 || pos > array.length ) diff --git a/src/core/org/luaj/vm2/lib/BaseLib.java b/src/core/org/luaj/vm2/lib/BaseLib.java index 56b389e3..225df4a3 100644 --- a/src/core/org/luaj/vm2/lib/BaseLib.java +++ b/src/core/org/luaj/vm2/lib/BaseLib.java @@ -25,13 +25,11 @@ import java.io.InputStream; import java.io.PrintStream; import org.luaj.vm2.LoadState; -import org.luaj.vm2.LuaClosure; import org.luaj.vm2.LuaError; import org.luaj.vm2.LuaString; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaThread; import org.luaj.vm2.LuaValue; -import org.luaj.vm2.Prototype; import org.luaj.vm2.Varargs; /** diff --git a/src/core/org/luaj/vm2/lib/CoroutineLib.java b/src/core/org/luaj/vm2/lib/CoroutineLib.java index a4ed5adb..51571dbc 100644 --- a/src/core/org/luaj/vm2/lib/CoroutineLib.java +++ b/src/core/org/luaj/vm2/lib/CoroutineLib.java @@ -27,9 +27,8 @@ import org.luaj.vm2.LuaValue; import org.luaj.vm2.Varargs; public class CoroutineLib extends VarArgFunction { - + private static final String[] NAMES = { - "", "create", "resume", "running", @@ -39,36 +38,31 @@ public class CoroutineLib extends VarArgFunction { "wrapped" }; - private static final int INSTALL = 0; - private static final int CREATE = 1; - private static final int RESUME = 2; - private static final int RUNNING = 3; - private static final int STATUS = 4; - private static final int YIELD = 5; - private static final int WRAP = 6; - private static final int WRAPPED = 7; - - public static void install(LuaValue globals) { - globals.set("coroutine", createInstance()); - } + private static final int INIT = -1; + private static final int CREATE = 0; + private static final int RESUME = 1; + private static final int RUNNING = 2; + private static final int STATUS = 3; + private static final int YIELD = 4; + private static final int WRAP = 5; + private static final int WRAPPED = 6; - public static final LuaValue createInstance() { - LuaTable t = new LuaTable(); - CoroutineLib f = new CoroutineLib(); - LibFunction.bind(t, f.getClass(), NAMES); - return t; + public CoroutineLib() { + name = "coroutine";; + opcode = INIT; } - public CoroutineLib() {} - private CoroutineLib(String name, int opcode, LuaThread thread) { super(name, opcode, thread); } public Varargs invoke(Varargs args) { switch ( opcode ) { - case INSTALL: - return createInstance(); + case INIT: { + LuaTable t = new LuaTable(); + LibFunction.bind(t, this.getClass(), NAMES); + return t; + } case CREATE: { final LuaValue func = args.checkfunction(1); return new LuaThread(func, func.getfenv() ); diff --git a/src/core/org/luaj/vm2/lib/DebugLib.java b/src/core/org/luaj/vm2/lib/DebugLib.java index 1cb07397..00044663 100644 --- a/src/core/org/luaj/vm2/lib/DebugLib.java +++ b/src/core/org/luaj/vm2/lib/DebugLib.java @@ -37,12 +37,12 @@ import org.luaj.vm2.Varargs; public class DebugLib extends VarArgFunction { public static final boolean CALLS = (null != System.getProperty("CALLS")); public static final boolean TRACE = (null != System.getProperty("TRACE")); - - // leave this unset to allow obfuscators to remove it in production builds + + // leave this unset to allow obfuscators to + // remove it in production builds public static boolean DEBUG_ENABLED; private static final String[] NAMES = { - "", "debug", "getfenv", "gethook", @@ -59,71 +59,65 @@ public class DebugLib extends VarArgFunction { "traceback", }; - private static final int INSTALL = 0; - private static final int DEBUG = 1; - private static final int GETFENV = 2; - private static final int GETHOOK = 3; - private static final int GETINFO = 4; - private static final int GETLOCAL = 5; - private static final int GETMETATABLE = 6; - private static final int GETREGISTRY = 7; - private static final int GETUPVALUE = 8; - private static final int SETFENV = 9; - private static final int SETHOOK = 10; - private static final int SETLOCAL = 11; - private static final int SETMETATABLE = 12; - private static final int SETUPVALUE = 13; - private static final int TRACEBACK = 14; + private static final int INIT = -1; + private static final int DEBUG = 0; + private static final int GETFENV = 1; + private static final int GETHOOK = 2; + private static final int GETINFO = 3; + private static final int GETLOCAL = 4; + private static final int GETMETATABLE = 5; + private static final int GETREGISTRY = 6; + private static final int GETUPVALUE = 7; + private static final int SETFENV = 8; + private static final int SETHOOK = 9; + private static final int SETLOCAL = 10; + private static final int SETMETATABLE = 11; + private static final int SETUPVALUE = 12; + private static final int TRACEBACK = 13; /* maximum stack for a Lua function */ private static final int MAXSTACK = 250; - private static final LuaString LUA = LuaString.valueOf("Lua"); - private static final LuaString JAVA = LuaString.valueOf("Java"); - private static final LuaString QMARK = LuaString.valueOf("?"); - private static final LuaString GLOBAL = LuaString.valueOf("global"); - private static final LuaString LOCAL = LuaString.valueOf("local"); - private static final LuaString METHOD = LuaString.valueOf("method"); - private static final LuaString UPVALUE = LuaString.valueOf("upvalue"); - private static final LuaString FIELD = LuaString.valueOf("field"); - private static final LuaString CALL = LuaString.valueOf("call"); - private static final LuaString LINE = LuaString.valueOf("line"); - private static final LuaString COUNT = LuaString.valueOf("count"); - private static final LuaString RETURN = LuaString.valueOf("return"); - private static final LuaString TAILRETURN = LuaString.valueOf("tail return"); + private static final LuaString LUA = valueOf("Lua"); + private static final LuaString JAVA = valueOf("Java"); + private static final LuaString QMARK = valueOf("?"); + private static final LuaString GLOBAL = valueOf("global"); + private static final LuaString LOCAL = valueOf("local"); + private static final LuaString METHOD = valueOf("method"); + private static final LuaString UPVALUE = valueOf("upvalue"); + private static final LuaString FIELD = valueOf("field"); + private static final LuaString CALL = valueOf("call"); + private static final LuaString LINE = valueOf("line"); + private static final LuaString COUNT = valueOf("count"); + private static final LuaString RETURN = valueOf("return"); + private static final LuaString TAILRETURN = valueOf("tail return"); - private static final LuaString FUNC = LuaString.valueOf("func"); - private static final LuaString NUPS = LuaString.valueOf("nups"); - private static final LuaString NAME = LuaString.valueOf("name"); - private static final LuaString NAMEWHAT = LuaString.valueOf("namewhat"); - private static final LuaString WHAT = LuaString.valueOf("what"); - private static final LuaString SOURCE = LuaString.valueOf("source"); - private static final LuaString SHORT_SRC = LuaString.valueOf("short_src"); - private static final LuaString LINEDEFINED = LuaString.valueOf("linedefined"); - private static final LuaString LASTLINEDEFINED = LuaString.valueOf("lastlinedefined"); - private static final LuaString CURRENTLINE = LuaString.valueOf("currentline"); - private static final LuaString ACTIVELINES = LuaString.valueOf("activelines"); + private static final LuaString FUNC = valueOf("func"); + private static final LuaString NUPS = valueOf("nups"); + private static final LuaString NAME = valueOf("name"); + private static final LuaString NAMEWHAT = valueOf("namewhat"); + private static final LuaString WHAT = valueOf("what"); + private static final LuaString SOURCE = valueOf("source"); + private static final LuaString SHORT_SRC = valueOf("short_src"); + private static final LuaString LINEDEFINED = valueOf("linedefined"); + private static final LuaString LASTLINEDEFINED = valueOf("lastlinedefined"); + private static final LuaString CURRENTLINE = valueOf("currentline"); + private static final LuaString ACTIVELINES = valueOf("activelines"); - public static void install(LuaValue globals) { - globals.set("debug", DebugLib.createInstance() ); + public DebugLib() { + name = "debug"; + opcode = INIT; } - public static final LuaValue createInstance() { - LuaTable t = new LuaTable(); - DebugLib f = new DebugLib(); - LibFunction.bind(t, f.getClass(), NAMES); - if ( ! DEBUG_ENABLED ) { - DEBUG_ENABLED = true; - } - return t; - } - - public DebugLib() {} - public Varargs invoke(Varargs args) { switch ( opcode ) { - case INSTALL: - return createInstance(); + case INIT: { + LuaTable t = new LuaTable(0,20); + LibFunction.bind(t, this.getClass(), NAMES); + if ( ! DEBUG_ENABLED ) + DEBUG_ENABLED = true; + return t; + } case DEBUG: return _debug(args); case GETFENV: diff --git a/src/core/org/luaj/vm2/lib/IoLib.java b/src/core/org/luaj/vm2/lib/IoLib.java index fbac3e3c..336a445f 100644 --- a/src/core/org/luaj/vm2/lib/IoLib.java +++ b/src/core/org/luaj/vm2/lib/IoLib.java @@ -33,7 +33,7 @@ import org.luaj.vm2.Varargs; abstract -public class IoLib extends LuaTable { +public class IoLib extends VarArgFunction { abstract protected class File extends LuaValue{ @@ -56,7 +56,7 @@ public class IoLib extends LuaTable { // delegate method access to file methods table public LuaValue get( LuaValue key ) { - return filemethods.get(key); + return env.get(FILEMETHODS).get(key); } // essentially a userdata instance @@ -113,11 +113,6 @@ public class IoLib extends LuaTable { */ abstract protected File openProgram(String prog, String mode) throws IOException; - - //protected final Table filemt; - protected final LuaTable filemethods; - private final LuaValue linesiter; - private File infile = null; private File outfile = null; private File errfile = null; @@ -127,128 +122,123 @@ public class IoLib extends LuaTable { private static final LuaValue STDERR = valueOf("stderr"); private static final LuaValue FILE = valueOf("file"); private static final LuaValue CLOSED_FILE = valueOf("closed file"); + private static final LuaValue FILEMETHODS = valueOf("__filemethods"); + private static final LuaValue LINESITER = valueOf("__linesiter"); - public IoLib() { + public IoLib() {} + + protected LuaTable init() { // io lib functions - set("flush", new IoFuncV("flush",0)); - set("tmpfile", new IoFuncV("tmpfile",1)); - set("close", new IoFuncV("close",2)); - set("input", new IoFuncV("input",3)); - set("output", new IoFuncV("output",4)); - set("type", new IoFuncV("type",5)); - set("popen", new IoFuncV("popen",6)); - set("open", new IoFuncV("open",7)); - set("lines", new IoFuncV("lines",8)); - set("read", new IoFuncV("read",9)); - set("write", new IoFuncV("write",10)); - setmetatable( tableOf(new LuaValue[] { - valueOf("__index"),new IoFuncV("__index",11), - }) ); + LuaTable t = new LuaTable(); + LibFunction.bind(t, this.getClass(), new String[] { + "flush", "tmpfile", "close", "input", "output", + "type", "popen", "open", "lines", "read", + "write", "__linesiter" }, 1 ); - // create file metatable - filemethods = tableOf(new LuaValue[] { - valueOf("close"), new IoFuncV("close",12), - valueOf("flush"), new IoFuncV("flush",13), - valueOf("setvbuf"), new IoFuncV("setvbuf",14), - valueOf("lines"), new IoFuncV("lines",15), - valueOf("read"), new IoFuncV("read",16), - valueOf("seek"), new IoFuncV("seek",17), - valueOf("write"), new IoFuncV("write",18), - }); - //filemt = tableOf(new Value[]{valueOf("__index"),filemethods}); + // create metatable + LuaTable idx = new LuaTable(); + LibFunction.bind(idx, this.getClass(), new String[] { + "__index", }, 13 ); + t.setmetatable( idx ); - // lines iterator - linesiter = new IoFuncV("linesiter",19); + // create file methods table + LuaTable filemethods = new LuaTable(); + LibFunction.bind(filemethods, this.getClass(), new String[] { + "close", "flush", "setvbuf", "lines", "read", + "seek", "write", }, 14 ); + t.set(FILEMETHODS, filemethods); + + // return the table + return t; } - public class IoFuncV extends VarArgFunction { - public IoFuncV(String name, int opcode) { - super(name,opcode,IoLib.this); - } - public Varargs invoke(Varargs args) { - File f; - int n; - LuaValue v; - try { - switch ( opcode ) { - case 0: // io.flush() -> bool - checkopen(output()); - outfile.flush(); - return LuaValue.TRUE; - case 1: // io.tmpfile() -> file - return tmpFile(); - case 2: // io.close([file]) -> void - f = args.arg1().isnil()? output(): checkfile(args.arg1()); - checkopen(f); - return ioclose(f); - case 3: // io.input([file]) -> file - infile = args.arg1().isnil()? input(): args.arg1().isstring()? - ioopenfile(args.checkString(1),"r"): - checkfile(args.arg1()); - return infile; - - case 4: // io.output(filename) -> file - outfile = args.arg1().isnil()? output(): args.arg1().isstring()? - ioopenfile(args.checkString(1),"w"): - checkfile(args.arg1()); - return outfile; - case 5: // io.type(obj) -> "file" | "closed file" | nil - if ( (f=optfile(args.arg1())) != null ) - return f.isclosed()? CLOSED_FILE: FILE; - return NIL; - case 6: // io.popen(prog, [mode]) -> file - return openProgram(args.checkString(1),args.optString(2,"r")); - case 7: // io.open(filename, [mode]) -> file | nil,err - return rawopenfile(args.checkString(1), args.optString(2,"r")); - case 8: // io.lines(filename) -> iterator - infile = args.arg1().isnil()? input(): ioopenfile(args.checkString(1),"r"); - checkopen(infile); - return lines(infile); - case 9: // io.read(...) -> (...) - checkopen(infile); - return ioread(infile,args); - case 10: // io.write(...) -> void - checkopen(output()); - return iowrite(outfile,args); - case 11: // __index, returns a field - v = args.arg(2); - return v.equals(STDOUT)?output(): - v.equals(STDIN)? input(): - v.equals(STDERR)? errput(): NIL; - - // ------------ file metatable operations + public Varargs invoke(Varargs args) { + File f; + int n; + LuaValue v; + try { + switch ( opcode ) { + case 0: // init + return init(); + case 1: // io.flush() -> bool + checkopen(output()); + outfile.flush(); + return LuaValue.TRUE; + case 2: // io.tmpfile() -> file + return tmpFile(); + case 3: // io.close([file]) -> void + f = args.arg1().isnil()? output(): checkfile(args.arg1()); + checkopen(f); + return ioclose(f); + case 4: // io.input([file]) -> file + infile = args.arg1().isnil()? input(): args.arg1().isstring()? + ioopenfile(args.checkString(1),"r"): + checkfile(args.arg1()); + return infile; - case 12: // file:close() -> void - return ioclose(checkfile(args.arg1())); - case 13: // file:flush() -> void - checkfile(args.arg1()).flush(); - return LuaValue.TRUE; - case 14: // file:setvbuf(mode,[size]) -> void - f = checkfile(args.arg1()); - f.setvbuf(args.checkString(2),args.optint(3, 1024)); - return LuaValue.TRUE; - case 15: // file:lines() -> iterator - return lines(checkfile(args.arg1())); - case 16: // file:read(...) -> (...) - f = checkfile(args.arg1()); - return ioread(f,args.subargs(2)); - case 17: // file:seek([whence][,offset]) -> pos | nil,error - f = checkfile(args.arg1()); - n = f.seek(args.optString(2,"cur"),args.optint(3,0)); - return valueOf(n); - case 18: // file:write(...) -> void - f = checkfile(args.arg1()); - return iowrite(f,args.subargs(2)); - case 19: // lines iterator(s,var) -> var' - f = checkfile(args.arg1()); - return freadline(f); - } - } catch ( IOException ioe ) { - return errorresult(ioe); + case 5: // io.output(filename) -> file + outfile = args.arg1().isnil()? output(): args.arg1().isstring()? + ioopenfile(args.checkString(1),"w"): + checkfile(args.arg1()); + return outfile; + case 6: // io.type(obj) -> "file" | "closed file" | nil + if ( (f=optfile(args.arg1())) != null ) + return f.isclosed()? CLOSED_FILE: FILE; + return NIL; + case 7: // io.popen(prog, [mode]) -> file + return openProgram(args.checkString(1),args.optString(2,"r")); + case 8: // io.open(filename, [mode]) -> file | nil,err + return rawopenfile(args.checkString(1), args.optString(2,"r")); + case 9: // io.lines(filename) -> iterator + infile = args.arg1().isnil()? input(): ioopenfile(args.checkString(1),"r"); + checkopen(infile); + return lines(infile); + case 10: // io.read(...) -> (...) + checkopen(infile); + return ioread(infile,args); + case 11: // io.write(...) -> void + checkopen(output()); + return iowrite(outfile,args); + case 12: // lines iterator(s,var) -> var' + f = checkfile(args.arg1()); + return freadline(f); + + // ------------ __index metatable operation + case 13: // __index, returns a field + v = args.arg(2); + return v.equals(STDOUT)?output(): + v.equals(STDIN)? input(): + v.equals(STDERR)? errput(): NIL; + + // ------------ file metatable operations + + case 14: // file:close() -> void + return ioclose(checkfile(args.arg1())); + case 15: // file:flush() -> void + checkfile(args.arg1()).flush(); + return LuaValue.TRUE; + case 16: // file:setvbuf(mode,[size]) -> void + f = checkfile(args.arg1()); + f.setvbuf(args.checkString(2),args.optint(3, 1024)); + return LuaValue.TRUE; + case 17: // file:lines() -> iterator + return lines(checkfile(args.arg1())); + case 18: // file:read(...) -> (...) + f = checkfile(args.arg1()); + return ioread(f,args.subargs(2)); + case 19: // file:seek([whence][,offset]) -> pos | nil,error + f = checkfile(args.arg1()); + n = f.seek(args.optString(2,"cur"),args.optint(3,0)); + return valueOf(n); + case 20: // file:write(...) -> void + f = checkfile(args.arg1()); + return iowrite(f,args.subargs(2)); } - return NONE; + } catch ( IOException ioe ) { + return errorresult(ioe); } + return NONE; } private File input() { @@ -296,6 +286,7 @@ public class IoLib extends LuaTable { // TODO: how to close on finalization private Varargs lines(final File f) throws IOException { + LuaValue linesiter = env.get(LINESITER); return varargsOf( linesiter, f ); } diff --git a/src/core/org/luaj/vm2/lib/LibFunction.java b/src/core/org/luaj/vm2/lib/LibFunction.java index b6b42b78..66ef56e9 100644 --- a/src/core/org/luaj/vm2/lib/LibFunction.java +++ b/src/core/org/luaj/vm2/lib/LibFunction.java @@ -45,12 +45,16 @@ abstract public class LibFunction extends LuaFunction { return name!=null? name: super.toString(); } - /** Bind a set of names to class instances, put values into the table. */ public static LuaTable bind( LuaTable table, Class libFuncClass, String[] names ) { + return bind( table, libFuncClass, names, 0 ); + } + + /** Bind a set of names to class instances, put values into the table. */ + public static LuaTable bind( LuaTable table, Class libFuncClass, String[] names, int firstOpcode ) { try { for ( int i=0, n=names.length; i=0; ) - set(NAMES[i], new OsFuncV(NAMES[i], i, this)); + name = "os"; + opcode = INIT; } - public String toString() { - return "os"; - } - - private class OsFuncV extends VarArgFunction { - public OsFuncV(String name, int opcode, OsLib lib) { - super(name, opcode, lib); - } - public Varargs invoke(Varargs args) { - try { - switch ( opcode ) { - case CLOCK: - return valueOf(clock()); - case DATE: { - String s = args.optString(1, null); - long t = args.optlong(2,-1); - return valueOf( date(s, t==-1? System.currentTimeMillis(): t) ); - } - case DIFFTIME: - return valueOf(difftime(args.checklong(1),args.checklong(2))); - case EXECUTE: - return valueOf(execute(args.optString(1, null))); - case EXIT: - exit(args.optint(1, 0)); - return NONE; - case GETENV: { - final String val = getenv(args.checkString(1)); - return val!=null? valueOf(val): NIL; - } - case REMOVE: - remove(args.checkString(1)); - return LuaValue.TRUE; - case RENAME: - rename(args.checkString(1), args.checkString(2)); - return LuaValue.TRUE; - case SETLOCALE: { - String s = setlocale(args.optString(1,null), args.optString(2, "all")); - return s!=null? valueOf(s): NIL; - } - case TIME: - return valueOf(time(args.arg1().isnil()? null: args.checktable(1))); - case TMPNAME: - return valueOf(tmpname()); - } - return NONE; - } catch ( IOException e ) { - return varargsOf(NIL, valueOf(e.getMessage())); + public Varargs invoke(Varargs args) { + try { + switch ( opcode ) { + case INIT: { + LuaTable t = new LuaTable(); + LibFunction.bind(t, getClass(), NAMES); + return t; } + case CLOCK: + return valueOf(clock()); + case DATE: { + String s = args.optString(1, null); + long t = args.optlong(2,-1); + return valueOf( date(s, t==-1? System.currentTimeMillis(): t) ); + } + case DIFFTIME: + return valueOf(difftime(args.checklong(1),args.checklong(2))); + case EXECUTE: + return valueOf(execute(args.optString(1, null))); + case EXIT: + exit(args.optint(1, 0)); + return NONE; + case GETENV: { + final String val = getenv(args.checkString(1)); + return val!=null? valueOf(val): NIL; + } + case REMOVE: + remove(args.checkString(1)); + return LuaValue.TRUE; + case RENAME: + rename(args.checkString(1), args.checkString(2)); + return LuaValue.TRUE; + case SETLOCALE: { + String s = setlocale(args.optString(1,null), args.optString(2, "all")); + return s!=null? valueOf(s): NIL; + } + case TIME: + return valueOf(time(args.arg1().isnil()? null: args.checktable(1))); + case TMPNAME: + return valueOf(tmpname()); + } + return NONE; + } catch ( IOException e ) { + return varargsOf(NIL, valueOf(e.getMessage())); } } diff --git a/src/core/org/luaj/vm2/lib/StringLib.java b/src/core/org/luaj/vm2/lib/StringLib.java index f1c41657..83377a59 100644 --- a/src/core/org/luaj/vm2/lib/StringLib.java +++ b/src/core/org/luaj/vm2/lib/StringLib.java @@ -32,33 +32,36 @@ import org.luaj.vm2.LuaValue; import org.luaj.vm2.Varargs; import org.luaj.vm2.compiler.DumpState; -public class StringLib extends LuaTable { +public class StringLib extends OneArgFunction { - public static StringLib instance; + public static LuaTable instance; public StringLib() { - LibFunction.bind( this, new StringFunc1().getClass(), new String[] { - "dump", "len", "lower", "reverse", - "upper", } ); - LibFunction.bind( this, new StringFuncV().getClass(), new String[] { - "byte", "char", "find", "format", - "gmatch", "gsub", "match", "rep", - "sub"} ); - instance = this; + name = "string"; + opcode = -1; } - public static class StringFunc1 extends OneArgFunction { - public LuaValue call(LuaValue arg) { - switch ( opcode ) { - case 0: return StringLib.dump(arg); // dump (function) - case 1: return StringLib.len(arg); // len (function) - case 2: return StringLib.lower(arg); // lower (function) - case 3: return StringLib.reverse(arg); // reverse (function) - case 4: return StringLib.upper(arg); // upper (function) - } - return NIL; + public LuaValue call(LuaValue arg) { + switch ( opcode ) { + case -1: { + LuaTable t = new LuaTable(); + LibFunction.bind( t, getClass(), new String[] { + "dump", "len", "lower", "reverse", "upper", } ); + LibFunction.bind( t, new StringFuncV().getClass(), new String[] { + "byte", "char", "find", "format", + "gmatch", "gsub", "match", "rep", + "sub"} ); + instance = t; + return t; + } + case 0: return dump(arg); // dump (function) + case 1: return len(arg); // len (function) + case 2: return lower(arg); // lower (function) + case 3: return reverse(arg); // reverse (function) + case 4: return upper(arg); // upper (function) + } + return NIL; } - } public static class StringFuncV extends VarArgFunction { public Varargs invoke(Varargs args) { diff --git a/src/core/org/luaj/vm2/lib/TableLib.java b/src/core/org/luaj/vm2/lib/TableLib.java index 78d15935..728223e9 100644 --- a/src/core/org/luaj/vm2/lib/TableLib.java +++ b/src/core/org/luaj/vm2/lib/TableLib.java @@ -25,34 +25,36 @@ import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Varargs; -public class TableLib extends LuaTable { +public class TableLib extends OneArgFunction { public TableLib() { - LibFunction.bind( this, new TableFunc1().getClass(), new String[] { - "getn", // (table) -> number - "maxn", // (table) -> number - } ); - LibFunction.bind( this, new TableFuncV().getClass(), new String[] { - "remove", // (table [, pos]) -> removed-ele - "concat", // (table [, sep [, i [, j]]]) -> string - "insert", // (table, [pos,] value) -> prev-ele - "sort", // (table [, comp]) -> void - "foreach", // (table, func) -> void - "foreachi", // (table, func) -> void - } ); + name = "table"; + opcode = -1; } - - public static class TableFunc1 extends OneArgFunction { - public LuaValue call(LuaValue arg) { - switch ( opcode ) { - case 0: return arg.checktable().getn(); - case 1: return valueOf( arg.checktable().maxn()); - } - return NIL; + + public LuaValue call(LuaValue arg) { + switch ( opcode ) { + case -1: { + LuaTable t = new LuaTable(); + LibFunction.bind( t, this.getClass(), new String[] { + "getn", // (table) -> number + "maxn", // (table) -> number + } ); + LibFunction.bind( t, new TableFuncV().getClass(), new String[] { + "remove", // (table [, pos]) -> removed-ele + "concat", // (table [, sep [, i [, j]]]) -> string + "insert", // (table, [pos,] value) -> prev-ele + "sort", // (table [, comp]) -> void + "foreach", // (table, func) -> void + "foreachi", // (table, func) -> void + } ); + return t; } - + case 0: return arg.checktable().getn(); + case 1: return valueOf( arg.checktable().maxn()); + } + return NIL; } - public static class TableFuncV extends VarArgFunction { public Varargs invoke(Varargs args) { diff --git a/src/jme/org/luaj/vm2/lib/JmePlatform.java b/src/jme/org/luaj/vm2/lib/JmePlatform.java index 35209ad3..5b5988b8 100644 --- a/src/jme/org/luaj/vm2/lib/JmePlatform.java +++ b/src/jme/org/luaj/vm2/lib/JmePlatform.java @@ -22,6 +22,7 @@ package org.luaj.vm2.lib; import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; public class JmePlatform { @@ -33,13 +34,25 @@ public class JmePlatform { public static LuaTable standardGlobals() { LuaTable _G = new BaseLib(); new org.luaj.vm2.lib.PackageLib(_G); - _G.set( "io", new org.luaj.vm2.lib.jme.JseIoLib() ); - _G.set( "math", new org.luaj.vm2.lib.MathLib() ); - _G.set( "os", new org.luaj.vm2.lib.OsLib() ); - _G.set( "table", new org.luaj.vm2.lib.TableLib() ); - _G.set( "string", new org.luaj.vm2.lib.StringLib() ); - CoroutineLib.install( _G ); + set(_G, "coroutine", new org.luaj.vm2.lib.CoroutineLib() ); + set(_G, "io", new org.luaj.vm2.lib.jme.JseIoLib() ); + set(_G, "math", new org.luaj.vm2.lib.MathLib() ); + set(_G, "os", new org.luaj.vm2.lib.OsLib() ); + set(_G, "table", new org.luaj.vm2.lib.TableLib() ); + set(_G, "string", new org.luaj.vm2.lib.StringLib() ); return _G; } + + public static LuaTable debugGlobals() { + LuaTable _G = standardGlobals(); + set(_G, "string", new org.luaj.vm2.lib.DebugLib() ); + return _G; + } + + private static void set( LuaTable _G, String name, LuaValue chunk ) { + chunk.setfenv(_G); + LuaValue pkg = chunk.call(LuaValue.valueOf(name)); + _G.set( name, pkg ); + } } diff --git a/src/jse/org/luaj/vm2/lib/JsePlatform.java b/src/jse/org/luaj/vm2/lib/JsePlatform.java index 31ae4566..d764a868 100644 --- a/src/jse/org/luaj/vm2/lib/JsePlatform.java +++ b/src/jse/org/luaj/vm2/lib/JsePlatform.java @@ -22,6 +22,7 @@ package org.luaj.vm2.lib; import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.CoroutineLib; import org.luaj.vm2.lib.jse.JseBaseLib; import org.luaj.vm2.lib.jse.JseIoLib; @@ -39,15 +40,20 @@ public class JsePlatform { public static LuaTable standardGlobals() { LuaTable _G = new JseBaseLib(); new org.luaj.vm2.lib.PackageLib(_G); - _G.set( "io", new org.luaj.vm2.lib.jse.JseIoLib() ); - _G.set( "math", new org.luaj.vm2.lib.jse.JseMathLib() ); - _G.set( "os", new org.luaj.vm2.lib.jse.JseOsLib() ); - _G.set( "table", new org.luaj.vm2.lib.TableLib() ); - _G.set( "string", new org.luaj.vm2.lib.StringLib() ); - _G.set( "luajava", new org.luaj.vm2.lib.jse.LuajavaLib() ); - CoroutineLib.install(_G); - DebugLib.install(_G); + set(_G, "table", new org.luaj.vm2.lib.TableLib() ); + set(_G, "string", new org.luaj.vm2.lib.StringLib() ); + set(_G, "coroutine", new org.luaj.vm2.lib.CoroutineLib() ); + set(_G, "debug", new org.luaj.vm2.lib.DebugLib() ); + set(_G, "math", new org.luaj.vm2.lib.jse.JseMathLib() ); + set(_G, "io", new org.luaj.vm2.lib.jse.JseIoLib() ); + set(_G, "os", new org.luaj.vm2.lib.jse.JseOsLib() ); + set(_G, "luajava", new org.luaj.vm2.lib.jse.LuajavaLib() ); return _G; } - + + private static void set( LuaTable _G, String name, LuaValue chunk ) { + chunk.setfenv(_G); + LuaValue pkg = chunk.call(LuaValue.valueOf(name)); + _G.set( name, pkg ); + } } diff --git a/src/jse/org/luaj/vm2/lib/jse/JseMathLib.java b/src/jse/org/luaj/vm2/lib/jse/JseMathLib.java index fd2fa173..e0226693 100644 --- a/src/jse/org/luaj/vm2/lib/jse/JseMathLib.java +++ b/src/jse/org/luaj/vm2/lib/jse/JseMathLib.java @@ -21,9 +21,9 @@ ******************************************************************************/ package org.luaj.vm2.lib.jse; +import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.LibFunction; -import org.luaj.vm2.lib.OneArgFunction; import org.luaj.vm2.lib.TwoArgFunction; /** @@ -34,31 +34,33 @@ import org.luaj.vm2.lib.TwoArgFunction; */ public class JseMathLib extends org.luaj.vm2.lib.MathLib { - public JseMathLib() { - LibFunction.bind( this, new J2seMathFunc1().getClass(), new String[] { + public JseMathLib() {} + + protected LuaTable init() { + LuaTable t = super.init(); + LibFunction.bind( t, this.getClass(), new String[] { "acos", "asin", "atan", "cosh", "exp", "log", "log10", "sinh", "tanh" } ); - LibFunction.bind( this, new J2seMathFunc2().getClass(), new String[] { + LibFunction.bind( t, new J2seMathFunc2().getClass(), new String[] { "atan2", "pow", } ); - + return t; } - - public static class J2seMathFunc1 extends OneArgFunction { - public LuaValue call(LuaValue arg) { - switch ( opcode ) { - case 0: return valueOf(Math.acos(arg.todouble())); - case 1: return valueOf(Math.asin(arg.todouble())); - case 2: return valueOf(Math.atan(arg.todouble())); - case 3: return valueOf(Math.cosh(arg.todouble())); - case 4: return valueOf(Math.exp(arg.todouble())); - case 5: return valueOf(Math.log(arg.todouble())); - case 6: return valueOf(Math.log10(arg.todouble())); - case 7: return valueOf(Math.sinh(arg.todouble())); - case 8: return valueOf(Math.tanh(arg.todouble())); - } - return NIL; + + public LuaValue call(LuaValue arg) { + switch ( opcode ) { + case -1: return init(); + case 0: return valueOf(Math.acos(arg.todouble())); + case 1: return valueOf(Math.asin(arg.todouble())); + case 2: return valueOf(Math.atan(arg.todouble())); + case 3: return valueOf(Math.cosh(arg.todouble())); + case 4: return valueOf(Math.exp(arg.todouble())); + case 5: return valueOf(Math.log(arg.todouble())); + case 6: return valueOf(Math.log10(arg.todouble())); + case 7: return valueOf(Math.sinh(arg.todouble())); + case 8: return valueOf(Math.tanh(arg.todouble())); } + return NIL; } public static class J2seMathFunc2 extends TwoArgFunction { diff --git a/src/jse/org/luaj/vm2/lib/jse/LuajavaLib.java b/src/jse/org/luaj/vm2/lib/jse/LuajavaLib.java index 9ed34bcd..3c848a72 100644 --- a/src/jse/org/luaj/vm2/lib/jse/LuajavaLib.java +++ b/src/jse/org/luaj/vm2/lib/jse/LuajavaLib.java @@ -47,15 +47,19 @@ import org.luaj.vm2.lib.ThreeArgFunction; import org.luaj.vm2.lib.TwoArgFunction; import org.luaj.vm2.lib.VarArgFunction; -public class LuajavaLib extends LuaTable { +public class LuajavaLib extends VarArgFunction { - private static final int BINDCLASS = 0; - private static final int NEWINSTANCE = 1; - private static final int NEW = 2; - private static final int CREATEPROXY = 3; - private static final int LOADLIB = 4; + private static final String LIBNAME = "luajava"; + private static final int INIT = 0; + private static final int BINDCLASS = 1; + private static final int NEWINSTANCE = 2; + private static final int NEW = 3; + private static final int CREATEPROXY = 4; + private static final int LOADLIB = 5; + private static final String[] NAMES = { + LIBNAME, "bindClass", "newInstance", "new", @@ -69,89 +73,91 @@ public class LuajavaLib extends LuaTable { } public LuajavaLib() { - LibFunction.bind( this, LuajavaFuncV.class, NAMES ); + name = LIBNAME; + opcode = INIT; } - // perform a lua call - public static class LuajavaFuncV extends VarArgFunction { - - public Varargs invoke(final Varargs args) { - try { - switch ( opcode ) { - case BINDCLASS: { - final Class clazz = Class.forName(args.checkString(1)); - return toUserdata( clazz, clazz ); - } - case NEWINSTANCE: - case NEW: { - // get constructor - final LuaValue c = args.checkvalue(1); - final Class clazz = (opcode==NEWINSTANCE? Class.forName(c.toString()): (Class) c.checkuserdata(Class.class)); - final ParamsList params = new ParamsList( args ); - final Constructor con = resolveConstructor( clazz, params ); - - // coerce args, construct instance - Object[] cargs = CoerceLuaToJava.coerceArgs( params.values, con.getParameterTypes() ); - Object o = con.newInstance( cargs ); - - // return result - return toUserdata( o, clazz ); - } - - case CREATEPROXY: { - final int niface = args.narg()-1; - if ( niface <= 0 ) - throw new LuaError("no interfaces"); - final LuaValue lobj = args.checktable(niface+1); - - // get the interfaces - final Class[] ifaces = new Class[niface]; - for ( int i=0; i