Refactor lib bindings.

This commit is contained in:
James Roseborough
2010-04-27 05:05:08 +00:00
parent 3f727fbe17
commit be5252148a
10 changed files with 351 additions and 486 deletions

View File

@@ -215,7 +215,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
case 2: // "load", // ( func [,chunkname] ) -> chunk | nil, msg
try {
LuaValue func = args.checkfunction(1);
String chunkname = args.optString(2, "function");
String chunkname = args.optjstring(2, "function");
return LoadState.load(new StringInputStream(func), chunkname, LuaThread.getGlobals());
} catch ( Exception e ) {
return varargsOf(NIL, valueOf(e.getMessage()));
@@ -232,7 +232,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
case 4: // "loadstring", // ( string [,chunkname] ) -> chunk | nil, msg
try {
LuaString script = args.checkstring(1);
String chunkname = args.optString(2, "string");
String chunkname = args.optjstring(2, "string");
return LoadState.load(script.toInputStream(),chunkname,LuaThread.getGlobals());
} catch ( Exception e ) {
return varargsOf(NIL, valueOf(e.getMessage()));

View File

@@ -40,16 +40,19 @@ public class CoroutineLib extends VarArgFunction {
public CoroutineLib() {
}
private LuaTable init() {
LuaTable t = new LuaTable();
bind(t, CoroutineLib.class, new String[] {
"create", "resume", "running", "status", "yield", "wrap" },
CREATE);
env.set("coroutine", t);
return t;
}
public Varargs invoke(Varargs args) {
switch ( opcode ) {
case INIT: {
LuaTable t = new LuaTable();
bind(t, CoroutineLib.class, new String[] {
"create", "resume", "running", "status", "yield", "wrap" },
CREATE);
env.set("coroutine", t);
return t;
return init();
}
case CREATE: {
final LuaValue func = args.checkfunction(1);

View File

@@ -36,7 +36,7 @@ import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.Varargs;
public class DebugLib extends OneArgFunction {
public class DebugLib extends VarArgFunction {
public static final boolean CALLS = (null != System.getProperty("CALLS"));
public static final boolean TRACE = (null != System.getProperty("TRACE"));
@@ -61,20 +61,21 @@ public class DebugLib extends OneArgFunction {
"traceback",
};
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;
private static final int INIT = 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;
/* maximum stack for a Lua function */
private static final int MAXSTACK = 250;
@@ -106,36 +107,34 @@ public class DebugLib extends OneArgFunction {
private static final LuaString ACTIVELINES = valueOf("activelines");
public DebugLib() {
DEBUG_ENABLED = true;
}
public LuaValue call(LuaValue arg) {
private LuaTable init() {
DEBUG_ENABLED = true;
LuaTable t = new LuaTable();
bind(t, DebugLibV.class, NAMES);
bind(t, DebugLib.class, NAMES, DEBUG);
env.set("debug", t);
return t;
}
public static final class DebugLibV extends VarArgFunction {
protected DebugLib debuglib;
public Varargs invoke(Varargs args) {
switch ( opcode ) {
case DEBUG: return _debug(args);
case GETFENV: return _getfenv(args);
case GETHOOK: return _gethook(args);
case GETINFO: return _getinfo(args,this);
case GETLOCAL: return _getlocal(args);
case GETMETATABLE: return _getmetatable(args);
case GETREGISTRY: return _getregistry(args);
case GETUPVALUE: return _getupvalue(args);
case SETFENV: return _setfenv(args);
case SETHOOK: return _sethook(args);
case SETLOCAL: return _setlocal(args);
case SETMETATABLE: return _setmetatable(args);
case SETUPVALUE: return _setupvalue(args);
case TRACEBACK: return _traceback(args);
default: return NONE;
}
public Varargs invoke(Varargs args) {
switch ( opcode ) {
case INIT: return init();
case DEBUG: return _debug(args);
case GETFENV: return _getfenv(args);
case GETHOOK: return _gethook(args);
case GETINFO: return _getinfo(args,this);
case GETLOCAL: return _getlocal(args);
case GETMETATABLE: return _getmetatable(args);
case GETREGISTRY: return _getregistry(args);
case GETUPVALUE: return _getupvalue(args);
case SETFENV: return _setfenv(args);
case SETHOOK: return _sethook(args);
case SETLOCAL: return _setlocal(args);
case SETMETATABLE: return _setmetatable(args);
case SETUPVALUE: return _setupvalue(args);
case TRACEBACK: return _traceback(args);
default: return NONE;
}
}
@@ -383,7 +382,7 @@ public class DebugLib extends OneArgFunction {
int a=1;
LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning();
LuaValue func = args.optfunction(a++, null);
String str = args.optString(a++,"");
String str = args.optjstring(a++,"");
int count = args.optint(a++,0);
boolean call=false,line=false,rtrn=false;
for ( int i=0; i<str.length(); i++ )
@@ -413,7 +412,7 @@ public class DebugLib extends OneArgFunction {
int a=1;
LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning();
LuaValue func = args.arg(a++);
String what = args.optString(a++, "nSluf");
String what = args.optjstring(a++, "nSluf");
// find the stack info
DebugState ds = getDebugState( thread );
@@ -600,7 +599,7 @@ public class DebugLib extends OneArgFunction {
private static LuaValue _traceback(Varargs args) {
int a=1;
LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning();
String message = args.optString(a++, "stack traceback:");
String message = args.optjstring(a++, "stack traceback:");
int level = args.optint(a++,1);
String tb = DebugLib.traceback(thread, level);
return valueOf(message+"\n"+tb);

View File

@@ -172,114 +172,210 @@ public class IoLib extends OneArgFunction {
LuaTable filemethods;
public IoLib() {}
public IoLib() {
}
public LuaValue call(LuaValue arg) {
// io lib functions
LuaTable t = new LuaTable();
bindv(t, IO_NAMES );
bind(t, IoLibV.class, IO_NAMES );
// create file methods table
filemethods = new LuaTable();
bind(filemethods, FILE_NAMES, -1, FILE_CLOSE );
bind(filemethods, IoLibV.class, FILE_NAMES, FILE_CLOSE );
// set up file metatable
LuaTable mt = tableOf( new LuaValue[] { INDEX, bindv("__index",IO_INDEX) });
LuaTable mt = new LuaTable();
bind(mt, IoLibV.class, new String[] { "__index" }, IO_INDEX );
t.setmetatable( mt );
// all functions link to library instance
setLibInstance( t );
setLibInstance( filemethods );
setLibInstance( mt );
// return the table
env.set("io", t);
return t;
}
protected Varargs oncallv(int opcode, Varargs args) {
File f;
int n;
LuaValue v;
try {
switch ( opcode ) {
case IO_FLUSH: // io.flush() -> bool
checkopen(output());
outfile.flush();
return LuaValue.TRUE;
case IO_TMPFILE: // io.tmpfile() -> file
return tmpFile();
case IO_CLOSE: // io.close([file]) -> void
f = args.arg1().isnil()? output(): checkfile(args.arg1());
checkopen(f);
return ioclose(f);
case IO_INPUT: // io.input([file]) -> file
infile = args.arg1().isnil()? input(): args.arg1().isstring()?
ioopenfile(args.checkjstring(1),"r"):
checkfile(args.arg1());
return infile;
private void setLibInstance(LuaTable t) {
LuaValue[] k = t.keys();
for ( int i=0, n=k.length; i<n; i++ )
((IoLibV) t.get(k[i])).iolib = this;
}
case IO_OUTPUT: // io.output(filename) -> file
outfile = args.arg1().isnil()? output(): args.arg1().isstring()?
ioopenfile(args.checkjstring(1),"w"):
checkfile(args.arg1());
return outfile;
case IO_TYPE: // io.type(obj) -> "file" | "closed file" | nil
if ( (f=optfile(args.arg1())) != null )
return f.isclosed()? CLOSED_FILE: FILE;
return NIL;
case IO_POPEN: // io.popen(prog, [mode]) -> file
return openProgram(args.checkjstring(1),args.optString(2,"r"));
case IO_OPEN: // io.open(filename, [mode]) -> file | nil,err
return rawopenfile(args.checkjstring(1), args.optString(2,"r"));
case IO_LINES: // io.lines(filename) -> iterator
infile = args.arg1().isnil()? input(): ioopenfile(args.checkjstring(1),"r");
checkopen(infile);
return lines(infile);
case IO_READ: // io.read(...) -> (...)
checkopen(infile);
return ioread(infile,args);
case IO_WRITE: // io.write(...) -> void
checkopen(output());
return iowrite(outfile,args);
case FILE_CLOSE: // file:close() -> void
return ioclose(checkfile(args.arg1()));
case FILE_FLUSH: // file:flush() -> void
checkfile(args.arg1()).flush();
return LuaValue.TRUE;
case FILE_SETVBUF: // file:setvbuf(mode,[size]) -> void
f = checkfile(args.arg1());
f.setvbuf(args.checkjstring(2),args.optint(3, 1024));
return LuaValue.TRUE;
case FILE_LINES: // file:lines() -> iterator
return lines(checkfile(args.arg1()));
case FILE_READ: // file:read(...) -> (...)
f = checkfile(args.arg1());
return ioread(f,args.subargs(2));
case FILE_SEEK: // 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 FILE_WRITE: // file:write(...) -> void
f = checkfile(args.arg1());
return iowrite(f,args.subargs(2));
case IO_INDEX: // __index, returns a field
v = args.arg(2);
return v.equals(STDOUT)?output():
v.equals(STDIN)? input():
v.equals(STDERR)? errput(): NIL;
case LINES_ITER: // lines iterator(s,var) -> var'
f = checkfile(env);
return freadline(f);
}
} catch ( IOException ioe ) {
return errorresult(ioe);
public static final class IoLibV extends VarArgFunction {
public IoLib iolib;
public IoLibV() {
}
public IoLibV(LuaValue env, String name, int opcode, IoLib iolib) {
super();
this.env = env;
this.name = name;
this.opcode = opcode;
this.iolib = iolib;
}
public Varargs invoke(Varargs args) {
try {
switch ( opcode ) {
case IO_FLUSH: return iolib._io_flush();
case IO_TMPFILE: return iolib._io_tmpfile();
case IO_CLOSE: return iolib._io_close(args.arg1());
case IO_INPUT: return iolib._io_input(args.arg1());
case IO_OUTPUT: return iolib._io_output(args.arg1());
case IO_TYPE: return iolib._io_type(args.arg1());
case IO_POPEN: return iolib._io_popen(args.checkjstring(1),args.optjstring(2,"r"));
case IO_OPEN: return iolib._io_open(args.checkjstring(1), args.optjstring(2,"r"));
case IO_LINES: return iolib._io_lines(args.arg1());
case IO_READ: return iolib._io_read(args);
case IO_WRITE: return iolib._io_write(args);
case FILE_CLOSE: return iolib._file_close(args.arg1());
case FILE_FLUSH: return iolib._file_flush(args.arg1());
case FILE_SETVBUF: return iolib._file_setvbuf(args.arg1(),args.checkjstring(2),args.optint(3,1024));
case FILE_LINES: return iolib._file_lines(args.arg1());
case FILE_READ: return iolib._file_read(args.arg1(),args.subargs(2));
case FILE_SEEK: return iolib._file_seek(args.arg1(),args.optjstring(2,"cur"),args.optint(3,0));
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);
}
} catch ( IOException ioe ) {
return errorresult(ioe);
}
return NONE;
}
return NONE;
}
private File input() {
return infile!=null? infile: (infile=ioopenfile("-","r"));
}
// io.flush() -> bool
public Varargs _io_flush() throws IOException {
checkopen(output());
outfile.flush();
return LuaValue.TRUE;
}
// io.tmpfile() -> file
public Varargs _io_tmpfile() throws IOException {
return tmpFile();
}
// io.close([file]) -> void
public Varargs _io_close(LuaValue file) throws IOException {
File f = file.isnil()? output(): checkfile(file);
checkopen(f);
return ioclose(f);
}
// io.input([file]) -> file
public Varargs _io_input(LuaValue file) {
infile = file.isnil()? input():
file.isstring()? ioopenfile(file.checkjstring(),"r"):
checkfile(file);
return infile;
}
// io.output(filename) -> file
public Varargs _io_output(LuaValue filename) {
outfile = filename.isnil()? output():
filename.isstring()? ioopenfile(filename.checkjstring(),"w"):
checkfile(filename);
return outfile;
}
// io.type(obj) -> "file" | "closed file" | nil
public Varargs _io_type(LuaValue obj) {
File f = optfile(obj);
return f!=null?
f.isclosed()? CLOSED_FILE: FILE:
NIL;
}
// io.popen(prog, [mode]) -> file
public Varargs _io_popen(String prog, String mode) throws IOException {
return openProgram(prog, mode);
}
// io.open(filename, [mode]) -> file | nil,err
public Varargs _io_open(String filename, String mode) throws IOException {
return rawopenfile(filename, mode);
}
// io.lines(filename) -> iterator
public Varargs _io_lines(LuaValue filename) {
infile = filename.isnil()? input(): ioopenfile(filename.checkjstring(),"r");
checkopen(infile);
return lines(infile);
}
// io.read(...) -> (...)
public Varargs _io_read(Varargs args) throws IOException {
checkopen(infile);
return ioread(infile,args);
}
// io.write(...) -> void
public Varargs _io_write(Varargs args) throws IOException {
checkopen(output());
return iowrite(outfile,args);
}
// file:close() -> void
public Varargs _file_close(LuaValue file) throws IOException {
return ioclose(checkfile(file));
}
// file:flush() -> void
public Varargs _file_flush(LuaValue file) throws IOException {
checkfile(file).flush();
return LuaValue.TRUE;
}
// file:setvbuf(mode,[size]) -> void
public Varargs _file_setvbuf(LuaValue file, String mode, int size) {
checkfile(file).setvbuf(mode,size);
return LuaValue.TRUE;
}
// file:lines() -> iterator
public Varargs _file_lines(LuaValue file) {
return lines(checkfile(file));
}
// file:read(...) -> (...)
public Varargs _file_read(LuaValue file, Varargs subargs) throws IOException {
return ioread(checkfile(file),subargs);
}
// file:seek([whence][,offset]) -> pos | nil,error
public Varargs _file_seek(LuaValue file, String whence, int offset) throws IOException {
return valueOf( checkfile(file).seek(whence,offset) );
}
// file:write(...) -> void
public Varargs _file_write(LuaValue file, Varargs subargs) throws IOException {
return iowrite(checkfile(file),subargs);
}
// __index, returns a field
public Varargs _io_index(LuaValue v) {
return v.equals(STDOUT)?output():
v.equals(STDIN)? input():
v.equals(STDERR)? errput(): NIL;
}
// lines iterator(s,var) -> var'
public Varargs _lines_iter(LuaValue file) throws IOException {
return freadline(checkfile(file));
}
private File output() {
return outfile!=null? outfile: (outfile=ioopenfile("-","w"));
}
@@ -321,9 +417,7 @@ public class IoLib extends OneArgFunction {
private Varargs lines(final File f) {
try {
IoLib iter = (IoLib) getClass().newInstance();
iter.setfenv(f);
return iter.bindv("lnext",LINES_ITER);
return new IoLibV(f,"lnext",LINES_ITER,this);
} catch ( Exception e ) {
return error("lines: "+e);
}

View File

@@ -24,7 +24,6 @@ package org.luaj.vm2.lib;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
abstract public class LibFunction extends LuaFunction {
@@ -56,253 +55,6 @@ abstract public class LibFunction extends LuaFunction {
}
}
protected void bind0(LuaValue env, String[] names) {
bind(env, names, 0, 0);
}
protected void bind1(LuaValue env, String[] names) {
bind(env, names, 1, 0);
}
protected void bind2(LuaValue env, String[] names) {
bind(env, names, 2, 0);
}
protected void bind3(LuaValue env, String[] names) {
bind(env, names, 3, 0);
}
protected void bindv(LuaValue env, String[] names) {
bind(env, names, -1, 0);
}
protected void bind(LuaValue env, String[] names, int numargs, int firstopcode ) {
for ( int i=0, n=names.length; i<n; i++ ) {
int opcode = firstopcode + i;
String name = names[i];
LibFunction binding;
switch( numargs ) {
case 0: binding = bind0(name, opcode); break;
case 1: binding = bind1(name, opcode); break;
case 2: binding = bind2(name, opcode); break;
case 3: binding = bind3(name, opcode); break;
default: binding = bindv(name, opcode); break;
}
env.set(names[i], binding);
}
}
protected LibFunction bind0(String name, int opcode) {
return new ZeroArgBinding(name, opcode, this);
}
protected LibFunction bind1(String name, int opcode) {
return new OneArgBinding(name, opcode, this);
}
protected LibFunction bind2(String name, int opcode) {
return new TwoArgBinding(name, opcode, this);
}
protected LibFunction bind3(String name, int opcode) {
return new ThreeArgBinding(name, opcode, this);
}
protected LibFunction bindv(String name, int opcode) {
return new VarArgBinding(name, opcode, this);
}
/** called when a zero-arg function is invoked */
protected LuaValue oncall0(int opcode) {
return NIL;
}
/** called when a one-arg function is invoked */
protected LuaValue oncall1(int opcode, LuaValue arg) {
return NIL;
}
/** called when a two-arg function is invoked */
protected LuaValue oncall2(int opcode, LuaValue arg1, LuaValue arg2) {
return NIL;
}
/** called when a three-arg function is invoked */
protected LuaValue oncall3(int opcode, LuaValue arg1, LuaValue arg2, LuaValue arg3) {
return NIL;
}
/** called when a var-arg function is invoked */
protected Varargs oncallv(int opcode, Varargs args) {
return NONE;
}
/** Binding to a one-arg function */
private static class ZeroArgBinding extends LibFunction {
private final LibFunction delegate;
private ZeroArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String tojstring() {
return name;
}
public LuaValue call() {
return delegate.oncall0(opcode);
}
public LuaValue call(LuaValue arg) {
return delegate.oncall0(opcode);
}
public LuaValue call(LuaValue arg1, LuaValue arg2) {
return delegate.oncall0(opcode);
}
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
return delegate.oncall0(opcode);
}
public Varargs invoke(Varargs varargs) {
return delegate.oncall0(opcode);
}
}
/** Binding to a one-arg function */
private static class OneArgBinding extends LibFunction {
private final LibFunction delegate;
private OneArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String tojstring() {
return name;
}
public LuaValue call() {
return delegate.oncall1(opcode,NIL);
}
public LuaValue call(LuaValue arg) {
return delegate.oncall1(opcode,arg);
}
public LuaValue call(LuaValue arg1, LuaValue arg2) {
return delegate.oncall1(opcode,arg1);
}
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
return delegate.oncall1(opcode,arg1);
}
public Varargs invoke(Varargs varargs) {
return delegate.oncall1(opcode,varargs.arg1());
}
}
/** Binding to a two-arg function */
private static class TwoArgBinding extends LibFunction {
private final LibFunction delegate;
private TwoArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String tojstring() {
return name;
}
public LuaValue call() {
return delegate.oncall2(opcode,NIL,NIL);
}
public LuaValue call(LuaValue arg) {
return delegate.oncall2(opcode,arg,NIL);
}
public LuaValue call(LuaValue arg1, LuaValue arg2) {
return delegate.oncall2(opcode,arg1,arg2);
}
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
return delegate.oncall2(opcode,arg1,arg2);
}
public Varargs invoke(Varargs varargs) {
return delegate.oncall2(opcode,varargs.arg1(),varargs.arg(2));
}
}
/** Binding to a three-arg function */
private static class ThreeArgBinding extends LibFunction {
private final LibFunction delegate;
private ThreeArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String tojstring() {
return name;
}
public LuaValue call() {
return delegate.oncall3(opcode,NIL,NIL,NIL);
}
public LuaValue call(LuaValue arg) {
return delegate.oncall3(opcode,arg,NIL,NIL);
}
public LuaValue call(LuaValue arg1, LuaValue arg2) {
return delegate.oncall3(opcode,arg1,arg2,NIL);
}
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
return delegate.oncall3(opcode,arg1,arg2,arg3);
}
public Varargs invoke(Varargs varargs) {
return delegate.oncall3(opcode,varargs.arg1(),varargs.arg(2),varargs.arg(3));
}
}
/** Binding to a var-arg function */
private static class VarArgBinding extends LibFunction {
private final LibFunction delegate;
private VarArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String tojstring() {
return name;
}
public LuaValue call() {
return delegate.oncallv(opcode,NONE).arg1();
}
public LuaValue call(LuaValue arg) {
return delegate.oncallv(opcode,arg).arg1();
}
public LuaValue call(LuaValue arg1, LuaValue arg2) {
return delegate.oncallv(opcode,varargsOf(arg1,arg2)).arg1();
}
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
return delegate.oncallv(opcode,varargsOf(arg1,arg2,arg3)).arg1();
}
public Varargs invoke(Varargs varargs) {
return delegate.oncallv(opcode,varargs);
}
}
// -------- code generation helper functions --------
// allocate storage for upvalue, leave it empty
protected static LuaValue[] newupe() {
return new LuaValue[1];

View File

@@ -30,13 +30,13 @@ import org.luaj.vm2.Varargs;
/**
* Base implementation of OsLib, with simplified stub functions
* for library functions that cannot be implemented uniformly
* on J2se and J2me.
* on Jse and Jme.
*
* <p>
* This can be installed as-is on either platform, or extended
* and refined to be used in a complete J2se implementation.
* and refined to be used in a complete Jse implementation.
*
* <p>Contains limited implementations of features not supported well on J2me:
* <p>Contains limited implementations of features not supported well on Jme:
* <bl>
* <li>execute()</li>
* <li>remove()</li>
@@ -46,21 +46,22 @@ import org.luaj.vm2.Varargs;
*
* @see org.luaj.vm2.lib.jse.JseOsLib
*/
public class OsLib extends OneArgFunction {
public class OsLib extends VarArgFunction {
public static String TMP_PREFIX = ".luaj";
public static String TMP_SUFFIX = "tmp";
private static final int CLOCK = 0;
private static final int DATE = 1;
private static final int DIFFTIME = 2;
private static final int EXECUTE = 3;
private static final int EXIT = 4;
private static final int GETENV = 5;
private static final int REMOVE = 6;
private static final int RENAME = 7;
private static final int SETLOCALE = 8;
private static final int TIME = 9;
private static final int TMPNAME = 10;
private static final int INIT = 0;
private static final int CLOCK = 1;
private static final int DATE = 2;
private static final int DIFFTIME = 3;
private static final int EXECUTE = 4;
private static final int EXIT = 5;
private static final int GETENV = 6;
private static final int REMOVE = 7;
private static final int RENAME = 8;
private static final int SETLOCALE = 9;
private static final int TIME = 10;
private static final int TMPNAME = 11;
private static final String[] NAMES = {
"clock",
@@ -85,27 +86,29 @@ public class OsLib extends OneArgFunction {
public OsLib() {
}
public LuaValue call(LuaValue arg) {
public LuaValue init() {
LuaTable t = new LuaTable();
bindv(t, NAMES);
bind(t, this.getClass(), NAMES, CLOCK);
env.set("os", t);
return t;
}
protected Varargs oncallv(int opcode, Varargs args) {
public Varargs invoke(Varargs args) {
try {
switch ( opcode ) {
case INIT:
return init();
case CLOCK:
return valueOf(clock());
case DATE: {
String s = args.optString(1, null);
String s = args.optjstring(1, null);
double t = args.optdouble(2,-1);
return valueOf( date(s, t==-1? System.currentTimeMillis()/1000.: t) );
}
case DIFFTIME:
return valueOf(difftime(args.checkdouble(1),args.checkdouble(2)));
case EXECUTE:
return valueOf(execute(args.optString(1, null)));
return valueOf(execute(args.optjstring(1, null)));
case EXIT:
exit(args.optint(1, 0));
return NONE;
@@ -120,7 +123,7 @@ public class OsLib extends OneArgFunction {
rename(args.checkjstring(1), args.checkjstring(2));
return LuaValue.TRUE;
case SETLOCALE: {
String s = setlocale(args.optString(1,null), args.optString(2, "all"));
String s = setlocale(args.optjstring(1,null), args.optjstring(2, "all"));
return s!=null? valueOf(s): NIL;
}
case TIME:
@@ -284,6 +287,8 @@ public class OsLib extends OneArgFunction {
* @return String filename to use
*/
protected String tmpname() {
return TMP_PREFIX+(tmpnames++)+TMP_SUFFIX;
synchronized ( OsLib.class ) {
return TMP_PREFIX+(tmpnames++)+TMP_SUFFIX;
}
}
}

View File

@@ -52,7 +52,6 @@ public class PackageLib extends OneArgFunction {
private static final LuaString _PRELOAD = valueOf("preload");
private static final LuaString _PATH = valueOf("path");
private static final LuaString _SEEALL = valueOf("seeall");
private static final LuaString _LOADFILE = valueOf("loadfile");
private static final LuaString _SENTINEL = valueOf("\u0001");
private static final int MODULE = 0;
@@ -67,55 +66,73 @@ public class PackageLib extends OneArgFunction {
}
public LuaValue call(LuaValue arg) {
env.set("require", bind1("require",REQUIRE));
env.set("module", bindv("module",MODULE));
env.set("require", new PkgLib1(env,"require",REQUIRE,this));
env.set("module", new PkgLibV(env,"module",MODULE,this));
env.set( "package", PACKAGE=tableOf( new LuaValue[] {
_LOADED, LOADED=tableOf(),
_PRELOAD, tableOf(),
_PATH, valueOf(DEFAULT_LUA_PATH),
_LOADLIB, bindv("loadlib",LOADLIB),
_SEEALL, bind1("seeall",SEEALL),
_LOADLIB, new PkgLibV(env,"loadlib",LOADLIB,this),
_SEEALL, new PkgLib1(env,"seeall",SEEALL,this),
_LOADERS, listOf(new LuaValue[] {
bindv("preload_loader", PRELOAD_LOADER),
bindv("lua_loader", LUA_LOADER),
bindv("java_loader", JAVA_LOADER),
new PkgLibV(env,"preload_loader", PRELOAD_LOADER,this),
new PkgLibV(env,"lua_loader", LUA_LOADER,this),
new PkgLibV(env,"java_loader", JAVA_LOADER,this),
}) }) );
return env;
}
protected LuaValue oncall1(int opcode, LuaValue arg) {
switch ( opcode ) {
case REQUIRE:
return require(arg);
case SEEALL: {
LuaTable t = arg.checktable();
LuaValue m = t.getmetatable();
if ( m == null )
t.setmetatable(m=tableOf());
m.set( INDEX, LuaThread.getGlobals() );
return NONE;
public static final class PkgLib1 extends OneArgFunction {
PackageLib lib;
public PkgLib1(LuaValue env,String name, int opcode, PackageLib lib) {
this.env = env;
this.name = name;
this.opcode = opcode;
this.lib = lib;
}
public LuaValue call(LuaValue arg) {
switch ( opcode ) {
case REQUIRE:
return lib.require(arg);
case SEEALL: {
LuaTable t = arg.checktable();
LuaValue m = t.getmetatable();
if ( m == null )
t.setmetatable(m=tableOf());
m.set( INDEX, LuaThread.getGlobals() );
return NONE;
}
}
return NIL;
}
return NIL;
}
protected Varargs oncallv(int opcode, Varargs args) {
switch ( opcode ) {
case MODULE:
return module(args);
case LOADLIB:
return loadlib(args);
case PRELOAD_LOADER: {
return loader_preload(args);
public static final class PkgLibV extends VarArgFunction {
PackageLib lib;
public PkgLibV(LuaValue env,String name, int opcode, PackageLib lib) {
this.env = env;
this.name = name;
this.opcode = opcode;
this.lib = lib;
}
case LUA_LOADER: {
return loader_Lua(args);
public Varargs invoke(Varargs args) {
switch ( opcode ) {
case MODULE:
return lib.module(args);
case LOADLIB:
return loadlib(args);
case PRELOAD_LOADER: {
return lib.loader_preload(args);
}
case LUA_LOADER: {
return lib.loader_Lua(args);
}
case JAVA_LOADER: {
return lib.loader_Java(args);
}
}
return NONE;
}
case JAVA_LOADER: {
return loader_Java(args);
}
}
return NONE;
}
/** Allow packages to mark themselves as loaded */

View File

@@ -30,32 +30,25 @@ public class TableLib extends OneArgFunction {
public TableLib() {
}
public LuaValue call(LuaValue arg) {
private LuaTable init() {
LuaTable t = new LuaTable();
bind(t, TableLib1.class, new String[] {
"getn", // (table) -> number
"maxn", // (table) -> number
} );
bind(t, TableLib.class, new String[] { "getn", "maxn", }, 1 );
bind(t, TableLibV.class, 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
} );
"remove", "concat", "insert", "sort", "foreach", "foreachi", } );
env.set("table", t);
return t;
}
public static final class TableLib1 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 0: // init library
return init();
case 1: // "getn" (table) -> number
return arg.checktable().getn();
case 2: // "maxn" (table) -> number
return valueOf( arg.checktable().maxn());
}
return NIL;
}
public static final class TableLibV extends VarArgFunction {

View File

@@ -43,25 +43,28 @@ import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaUserdata;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.BaseLib;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.ThreeArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
public class LuajavaLib extends OneArgFunction {
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 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 = {
"bindClass",
"newInstance",
"new",
"createProxy",
"loadLib" };
"loadLib",
};
private static final Map classMetatables = new HashMap();
@@ -76,16 +79,15 @@ public class LuajavaLib extends OneArgFunction {
public LuajavaLib() {
}
public LuaValue call(LuaValue arg) {
LuaTable t = new LuaTable();
bindv( t, NAMES );
env.set("luajava", t);
return t;
}
protected Varargs oncallv(int opcode, Varargs args) {
public Varargs invoke(Varargs args) {
try {
switch ( opcode ) {
case INIT: {
LuaTable t = new LuaTable();
bind( t, LuajavaLib.class, NAMES, BINDCLASS );
env.set("luajava", t);
return t;
}
case BINDCLASS: {
final Class clazz = Class.forName(args.checkjstring(1));
return toUserdata( clazz, clazz );

View File

@@ -765,22 +765,22 @@ public class TypeTest extends TestCase {
public void testOptJavaString() {
assertEquals( "xyz", somenil.optjstring("xyz") );
assertEquals( null, somenil.optjstring(null) );
throwsError( sometrue, "optString", String.class, "xyz" );
throwsError( somefalse, "optString", String.class, "xyz" );
throwsError( sometrue, "optjstring", String.class, "xyz" );
throwsError( somefalse, "optjstring", String.class, "xyz" );
assertEquals( String.valueOf(zero), zero.optjstring("xyz") );
assertEquals( String.valueOf(intint), intint.optjstring("xyz") );
assertEquals( String.valueOf(longdouble), longdouble.optjstring("xyz") );
assertEquals( String.valueOf(doubledouble), doubledouble.optjstring("xyz") );
throwsError( somefunc, "optString", String.class, "xyz" );
throwsError( someclosure, "optString", String.class, "xyz" );
throwsError( somefunc, "optjstring", String.class, "xyz" );
throwsError( someclosure, "optjstring", String.class, "xyz" );
assertEquals( samplestringstring, stringstring.optjstring("xyz") );
assertEquals( samplestringint, stringint.optjstring("xyz") );
assertEquals( samplestringlong, stringlong.optjstring("xyz") );
assertEquals( samplestringdouble, stringdouble.optjstring("xyz") );
throwsError( thread, "optString", String.class, "xyz" );
throwsError( table, "optString", String.class, "xyz" );
throwsError( userdataobj, "optString", String.class, "xyz" );
throwsError( userdatacls, "optString", String.class, "xyz" );
throwsError( thread, "optjstring", String.class, "xyz" );
throwsError( table, "optjstring", String.class, "xyz" );
throwsError( userdataobj, "optjstring", String.class, "xyz" );
throwsError( userdatacls, "optjstring", String.class, "xyz" );
}
public void testOptLuaString() {