Convert most libraries to use standard loading.

This commit is contained in:
James Roseborough
2010-04-01 05:35:54 +00:00
parent 68fbf6cc39
commit 64751f694e
15 changed files with 481 additions and 469 deletions

View File

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

View File

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

View File

@@ -29,7 +29,6 @@ import org.luaj.vm2.Varargs;
public class CoroutineLib extends VarArgFunction {
private static final String[] NAMES = {
"<coroutine>",
"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;
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 void install(LuaValue globals) {
globals.set("coroutine", createInstance());
public CoroutineLib() {
name = "coroutine";;
opcode = INIT;
}
public static final LuaValue createInstance() {
LuaTable t = new LuaTable();
CoroutineLib f = new CoroutineLib();
LibFunction.bind(t, f.getClass(), NAMES);
return t;
}
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() );

View File

@@ -38,11 +38,11 @@ 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>",
"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:

View File

@@ -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;
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 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;
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);
// ------------ file metatable operations
// ------------ __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;
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);
// ------------ 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 );
}

View File

@@ -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<n; i++ ) {
LibFunction f = (LibFunction) libFuncClass.newInstance();
f.opcode = i;
f.opcode = firstOpcode + i;
f.name = names[i];
f.env = table;
table.set( names[i], f );

View File

@@ -35,48 +35,50 @@ import org.luaj.vm2.Varargs;
*
* @see org.luaj.vm2.lib.jse.JseMathLib
*/
public class MathLib extends LuaTable {
public class MathLib extends OneArgFunction {
public static MathLib MATHLIB = null;
private Random random;
private static final LuaValue RANDOM = valueOf("__random");
public MathLib() {
name = "math";
opcode = -1;
MATHLIB = this;
this.set( "pi", Math.PI );
this.set( "huge", LuaDouble.POSINF );
LibFunction.bind( this, new MathFunc1().getClass(), new String[] {
}
protected LuaTable init() {
LuaTable t = new LuaTable(0,30);
t.set( "pi", Math.PI );
t.set( "huge", LuaDouble.POSINF );
LibFunction.bind( t, new MathLib().getClass(), new String[] {
"abs", "ceil", "cos", "deg",
"exp", "floor", "rad", "sin",
"sqrt", "tan" } );
LibFunction.bind( this, new MathFunc2().getClass(), new String[] {
LibFunction.bind( t, new MathFunc2().getClass(), new String[] {
"fmod", "ldexp", "pow", "random",
} );
LibFunction.bind( this, new MathFuncV().getClass(), new String[] {
LibFunction.bind( t, new MathFuncV().getClass(), new String[] {
"frexp", "max", "min", "modf",
"randomseed" } );
return t;
}
public String toString() {
return "math";
}
public static class MathFunc1 extends OneArgFunction {
public LuaValue call(LuaValue arg) {
switch ( opcode ) {
case 0: return valueOf(Math.abs(arg.todouble()));
case 1: return valueOf(Math.ceil(arg.todouble()));
case 2: return valueOf(Math.cos(arg.todouble()));
case 3: return valueOf(Math.toDegrees(arg.todouble()));
case 4: return dpow(Math.E,arg.todouble());
case 5: return valueOf(Math.floor(arg.todouble()));
case 6: return valueOf(Math.toRadians(arg.todouble()));
case 7: return valueOf(Math.sin(arg.todouble()));
case 8: return valueOf(Math.sqrt(arg.todouble()));
case 9: return valueOf(Math.tan(arg.todouble()));
}
return NIL;
public LuaValue call(LuaValue arg) {
switch ( opcode ) {
case -1: return init();
case 0: return valueOf(Math.abs(arg.todouble()));
case 1: return valueOf(Math.ceil(arg.todouble()));
case 2: return valueOf(Math.cos(arg.todouble()));
case 3: return valueOf(Math.toDegrees(arg.todouble()));
case 4: return dpow(Math.E,arg.todouble());
case 5: return valueOf(Math.floor(arg.todouble()));
case 6: return valueOf(Math.toRadians(arg.todouble()));
case 7: return valueOf(Math.sin(arg.todouble()));
case 8: return valueOf(Math.sqrt(arg.todouble()));
case 9: return valueOf(Math.tan(arg.todouble()));
}
return NIL;
}
public static class MathFunc2 extends TwoArgFunction {
@@ -99,16 +101,16 @@ public class MathLib extends LuaTable {
return dpow(arg1.todouble(), arg2.todouble());
}
case 3: { // random
MathLib lib = (MathLib) env;
if ( lib.random == null )
lib.random = new Random();
Random random = (Random) env.get(RANDOM).optuserdata(Random.class, null);
if ( random == null )
env.set(RANDOM,userdataOf(random = new Random()));
if ( arg1.isnil() )
return valueOf( lib.random.nextDouble() );
return valueOf( random.nextDouble() );
int m = arg1.toint();
if ( arg2.isnil() )
return valueOf( 1 + lib.random.nextInt(m) );
return valueOf( 1 + random.nextInt(m) );
else
return valueOf( m + lib.random.nextInt(arg2.toint()-m) );
return valueOf( m + random.nextInt(arg2.toint()-m) );
}
}
return NIL;
@@ -184,7 +186,7 @@ public class MathLib extends LuaTable {
}
case 4: { // randomseed
long seed = args.checklong(1);
((MathLib) env).random = new Random(seed);
env.set(RANDOM,userdataOf(new Random(seed)));
return NONE;
}
}

View File

@@ -46,10 +46,11 @@ import org.luaj.vm2.Varargs;
*
* @see org.luaj.vm2.lib.jse.JseOsLib
*/
public class OsLib extends LuaTable {
public class OsLib extends VarArgFunction {
public static String TMP_PREFIX = ".luaj";
public static String TMP_SUFFIX = "tmp";
private static final int INIT = -1;
private static final int CLOCK = 0;
private static final int DATE = 1;
private static final int DIFFTIME = 2;
@@ -62,6 +63,20 @@ public class OsLib extends LuaTable {
private static final int TIME = 9;
private static final int TMPNAME = 10;
private static final String[] NAMES = {
"clock",
"date",
"difftime",
"execute",
"exit",
"getenv",
"remove",
"rename",
"setlocale",
"time",
"tmpname",
};
private static final long t0 = System.currentTimeMillis();
private static long tmpnames = t0;
@@ -69,71 +84,54 @@ public class OsLib extends LuaTable {
* Create and OsLib instance.
*/
public OsLib() {
String[] NAMES = {
"clock",
"date",
"difftime",
"execute",
"exit",
"getenv",
"remove",
"rename",
"setlocale",
"time",
"tmpname",
};
for ( int i=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()));
}
}

View File

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

View File

@@ -25,35 +25,37 @@ 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) {
switch ( opcode ) {

View File

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

View File

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

View File

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

View File

@@ -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<niface; i++ )
ifaces[i] = Class.forName(args.checkString(i+1));
// create the invocation handler
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
LuaValue func = lobj.get(name);
if ( func.isnil() )
return null;
int n = args!=null? args.length: 0;
LuaValue[] v = new LuaValue[n];
for ( int i=0; i<n; i++ )
v[i] = CoerceJavaToLua.coerce(args[i]);
LuaValue result = func.invoke(v).arg1();
return CoerceLuaToJava.coerceArg(result, method.getReturnType());
}
};
// create the proxy object
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), ifaces, handler);
// return the proxy
return LuaValue.userdataOf( proxy );
}
case LOADLIB: {
// get constructor
String classname = args.checkString(1);
String methodname = args.checkString(2);
Class clazz = Class.forName(classname);
Method method = clazz.getMethod(methodname, new Class[] {});
Object result = method.invoke(clazz, new Object[] {});
if ( result instanceof LuaValue ) {
return (LuaValue) result;
} else {
return NIL;
}
}
default:
throw new LuaError("not yet supported: "+this);
}
} catch (LuaError e) {
throw e;
} catch (Exception e) {
throw new LuaError(e);
public Varargs invoke(final Varargs args) {
try {
switch ( opcode ) {
case INIT: {
LuaTable t = new LuaTable(0,8);
LibFunction.bind( t, this.getClass(), NAMES );
return t;
}
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<niface; i++ )
ifaces[i] = Class.forName(args.checkString(i+1));
// create the invocation handler
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
LuaValue func = lobj.get(name);
if ( func.isnil() )
return null;
int n = args!=null? args.length: 0;
LuaValue[] v = new LuaValue[n];
for ( int i=0; i<n; i++ )
v[i] = CoerceJavaToLua.coerce(args[i]);
LuaValue result = func.invoke(v).arg1();
return CoerceLuaToJava.coerceArg(result, method.getReturnType());
}
};
// create the proxy object
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), ifaces, handler);
// return the proxy
return LuaValue.userdataOf( proxy );
}
case LOADLIB: {
// get constructor
String classname = args.checkString(1);
String methodname = args.checkString(2);
Class clazz = Class.forName(classname);
Method method = clazz.getMethod(methodname, new Class[] {});
Object result = method.invoke(clazz, new Object[] {});
if ( result instanceof LuaValue ) {
return (LuaValue) result;
} else {
return NIL;
}
}
default:
throw new LuaError("not yet supported: "+this);
}
} catch (LuaError e) {
throw e;
} catch (Exception e) {
throw new LuaError(e);
}
}

View File

@@ -64,10 +64,9 @@ public class ScriptDrivenTest extends TestCase {
_G = org.luaj.vm2.lib.JsePlatform.standardGlobals();
break;
case JME:
_G = org.luaj.vm2.lib.JmePlatform.standardGlobals();
_G = org.luaj.vm2.lib.JmePlatform.debugGlobals();
break;
}
DebugLib.install( _G );
// override print()
final ByteArrayOutputStream output = new ByteArrayOutputStream();