Refactor library initialization code.

This commit is contained in:
James Roseborough
2010-04-02 05:57:54 +00:00
parent 3a880788cc
commit 946503fc20
25 changed files with 864 additions and 747 deletions

View File

@@ -191,7 +191,7 @@ public class LuaValue extends Varargs {
public LuaValue getmetatable() { return null; }; public LuaValue getmetatable() { return null; };
public LuaValue setmetatable(LuaValue metatable) { return error("setmetatable not allowed for "+typename()); } public LuaValue setmetatable(LuaValue metatable) { return error("setmetatable not allowed for "+typename()); }
public LuaValue getfenv() { typerror("function or thread"); return null; } public LuaValue getfenv() { typerror("function or thread"); return null; }
public void setfenv(LuaValue env) { typerror("function or thread"); } public void setfenv(LuaValue env) { typerror("function or thread"); }
// function calls // function calls
public LuaValue call() { return unimplemented("call"); } public LuaValue call() { return unimplemented("call"); }

View File

@@ -47,12 +47,14 @@ import org.luaj.vm2.Varargs;
* *
* @see org.luaj.vm2.lib.jse.JseBaseLib * @see org.luaj.vm2.lib.jse.JseBaseLib
*/ */
public class BaseLib extends LuaTable implements ResourceFinder { public class BaseLib extends OneArgFunction implements ResourceFinder {
public static final String VERSION = "Luaj 2.0"; public static final String VERSION = "Luaj 2.0";
public static InputStream STDIN = null; public static BaseLib instance;
public static PrintStream STDOUT = System.out;
public static PrintStream STDERR = System.err; public InputStream STDIN = null;
public PrintStream STDOUT = System.out;
public PrintStream STDERR = System.err;
/** /**
* Singleton file opener for this Java ClassLoader realm. * Singleton file opener for this Java ClassLoader realm.
@@ -61,25 +63,32 @@ public class BaseLib extends LuaTable implements ResourceFinder {
*/ */
public static ResourceFinder FINDER; public static ResourceFinder FINDER;
private LuaValue next;
private LuaValue inext;
/** /**
* Construct a base libarary instance and initialize the functions in it. * Construct a base libarary instance.
*/ */
public BaseLib() { public BaseLib() {
this.set( "_G", this ); instance = this;
this.set( "_VERSION", VERSION ); }
LibFunction.bind( this, new BaseFunc1().getClass(), new String[] {
public LuaValue call(LuaValue arg) {
env.set( "_G", env );
env.set( "_VERSION", VERSION );
bind1( env, new String[] {
"getfenv", // ( [f] ) -> env "getfenv", // ( [f] ) -> env
"getmetatable", // ( object ) -> table "getmetatable", // ( object ) -> table
"tostring", // (e) -> value "tostring", // (e) -> value
} ); } );
LibFunction.bind( this, new BaseFunc2().getClass(), new String[] { bind2( env, new String[] {
"collectgarbage", // ( opt [,arg] ) -> value "collectgarbage", // ( opt [,arg] ) -> value
"error", // ( message [,level] ) -> ERR "error", // ( message [,level] ) -> ERR
"rawequal", // (v1, v2) -> boolean "rawequal", // (v1, v2) -> boolean
"setfenv", // (f, table) -> void "setfenv", // (f, table) -> void
"tonumber", // (e [,base]) -> value "tonumber", // (e [,base]) -> value
} ); } );
LibFunction.bind( this, new BaseFuncV().getClass(), new String[] { bindv( env, new String[] {
"assert", // ( v [,message] ) -> v, message | ERR "assert", // ( v [,message] ) -> v, message | ERR
"dofile", // ( filename ) -> result1, ... "dofile", // ( filename ) -> result1, ...
"load", // ( func [,chunkname] ) -> chunk | nil, msg "load", // ( func [,chunkname] ) -> chunk | nil, msg
@@ -94,22 +103,20 @@ public class BaseLib extends LuaTable implements ResourceFinder {
"rawget", // (table, index) -> value "rawget", // (table, index) -> value
"rawset", // (table, index, value) -> table "rawset", // (table, index, value) -> table
"setmetatable", // (table, metatable) -> table "setmetatable", // (table, metatable) -> table
"pairs", // "pairs" (t) -> iter-func, t, nil
"ipairs", // "ipairs", // (t) -> iter-func, t, 0
"next", // "next" ( table, [index] ) -> next-index, next-value
"__inext", // "inext" ( table, [int-index] ) -> next-index, next-value
} ); } );
// pairs and ipars need iterator functions // remember next, and inext for use in pairs and ipairs
// "next", // ( table, [index] ) -> next-index, next-value next = env.get("next");
// "inext", // not public ( table, [int-index] ) -> next-index, next-value inext = env.get("__inext");
// "ipairs", // (t) -> iter-func, t, 0
// "pairs", // (t) -> iter-func, t, nil
LuaValue next = new BaseIter(0,"next",null);
LuaValue inext = new BaseIter(1,"inext",null);
this.set( "pairs", new BaseIter(2,"pairs",next) );
this.set( "ipairs", new BaseIter(3,"ipairs",inext) );
this.set( "next", next );
// set the default resource finder if not set already // set the default resource finder if not set already
if ( FINDER == null ) if ( FINDER == null )
FINDER = this; FINDER = this;
return env;
} }
/** ResourceFinder implementation /** ResourceFinder implementation
@@ -121,253 +128,227 @@ public class BaseLib extends LuaTable implements ResourceFinder {
return c.getResourceAsStream(filename.startsWith("/")? filename: "/"+filename); return c.getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
} }
public static class BaseFunc1 extends OneArgFunction { protected LuaValue oncall1(int opcode, LuaValue arg) {
public LuaValue call(LuaValue arg) { switch ( opcode ) {
switch ( opcode ) { case 0: { // "getfenv", // ( [f] ) -> env
case 0: { // "getfenv", // ( [f] ) -> env if ( ! arg.isfunction() ) {
if ( ! arg.isfunction() ) { int i = arg.checkint();
int i = arg.checkint(); arg = (i==0)? (LuaValue) LuaThread.getRunning(): (LuaValue) LuaThread.getCallstackFunction(i-1);
arg = (i==0)? (LuaValue) LuaThread.getRunning(): (LuaValue) LuaThread.getCallstackFunction(i-1); if ( arg == null )
if ( arg == null ) LuaValue.argerror(1, "invalid level");
LuaValue.argerror(1, "invalid level");
}
return arg.getfenv();
} }
case 1: // "getmetatable", // ( object ) -> table return arg.getfenv();
LuaValue mt = arg.getmetatable();
return mt!=null? mt: NIL;
case 2: // "tostring", // (e) -> value
return arg.type() == LuaValue.TSTRING? arg: valueOf(arg.toString());
}
return NIL;
} }
case 1: // "getmetatable", // ( object ) -> table
LuaValue mt = arg.getmetatable();
return mt!=null? mt: NIL;
case 2: // "tostring", // (e) -> value
return arg.type() == LuaValue.TSTRING? arg: valueOf(arg.toString());
}
return NIL;
} }
public static class BaseFunc2 extends TwoArgFunction { protected LuaValue oncall2(int opcode, LuaValue arg1, LuaValue arg2) {
public LuaValue call(LuaValue arg1,LuaValue arg2) { switch ( opcode ) {
switch ( opcode ) { case 0: // "collectgarbage", // ( opt [,arg] ) -> value
case 0: // "collectgarbage", // ( opt [,arg] ) -> value String s = arg1.optString("collect");
String s = arg1.optString("collect"); int result = 0;
int result = 0; if ( "collect".equals(s) ) {
if ( "collect".equals(s) ) { System.gc();
System.gc(); return ZERO;
return ZERO;
}
else if ( "count".equals(s) ) {
Runtime rt = Runtime.getRuntime();
long used = rt.totalMemory() - rt.freeMemory();
return valueOf(used/1024.);
} else if ( "step".equals(s) ) {
System.gc();
return LuaValue.TRUE;
}
return NIL;
case 1: // "error", // ( message [,level] ) -> ERR
throw new LuaError( arg1.isnil()? null: arg1.toString() );
case 2: // "rawequal", // (v1, v2) -> boolean
return valueOf(arg1 == arg2);
case 3: { // "setfenv", // (f, table) -> void
LuaValue f = arg1;
if ( ! f.isfunction() ) {
int i = arg1.checkint();
f = (i==0)? (LuaValue) LuaThread.getRunning(): (LuaValue) LuaThread.getCallstackFunction(i-1);
if ( f == null )
LuaValue.argerror(1, "invalid level");
}
f.setfenv(arg2);
return f;
} }
case 4: // "tonumber", // (e [,base]) -> value else if ( "count".equals(s) ) {
final int base = arg2.optint(10); Runtime rt = Runtime.getRuntime();
if (base == 10) { /* standard conversion */ long used = rt.totalMemory() - rt.freeMemory();
return arg1.tonumber(); return valueOf(used/1024.);
} else { } else if ( "step".equals(s) ) {
if ( base < 2 || base > 36 ) System.gc();
argerror(2, "base out of range"); return LuaValue.TRUE;
final LuaString str = arg1.optstring(null);
return str!=null? str.tonumber(base): NIL;
}
} }
return NIL; return NIL;
case 1: // "error", // ( message [,level] ) -> ERR
throw new LuaError( arg1.isnil()? null: arg1.toString() );
case 2: // "rawequal", // (v1, v2) -> boolean
return valueOf(arg1 == arg2);
case 3: { // "setfenv", // (f, table) -> void
LuaValue f = arg1;
if ( ! f.isfunction() ) {
int i = arg1.checkint();
f = (i==0)? (LuaValue) LuaThread.getRunning(): (LuaValue) LuaThread.getCallstackFunction(i-1);
if ( f == null )
LuaValue.argerror(1, "invalid level");
}
f.setfenv(arg2);
return f;
} }
case 4: // "tonumber", // (e [,base]) -> value
final int base = arg2.optint(10);
if (base == 10) { /* standard conversion */
return arg1.tonumber();
} else {
if ( base < 2 || base > 36 )
argerror(2, "base out of range");
final LuaString str = arg1.optstring(null);
return str!=null? str.tonumber(base): NIL;
}
}
return NIL;
} }
public static class BaseFuncV extends VarArgFunction { protected Varargs oncallv(int opcode, Varargs args) {
private final BaseLib lib; switch ( opcode ) {
public BaseFuncV() { case 0: // "assert", // ( v [,message] ) -> v, message | ERR
this.lib = null; if ( !args.arg1().toboolean() ) error("assertion failed!");
} return args;
public BaseFuncV(BaseLib lib) { case 1: // "dofile", // ( filename ) -> result1, ...
this.lib = lib; {
} LuaValue chunk;
public Varargs invoke(Varargs args) { try {
switch ( opcode ) { String filename = args.checkString(1);
case 0: // "assert", // ( v [,message] ) -> v, message | ERR chunk = loadFile(filename).arg1();
if ( !args.arg1().toboolean() ) error("assertion failed!"); } catch ( IOException e ) {
return args; return error(e.getMessage());
case 1: // "dofile", // ( filename ) -> result1, ...
{
LuaValue chunk;
try {
String filename = args.checkString(1);
chunk = loadFile(filename).arg1();
} catch ( IOException e ) {
return error(e.getMessage());
}
return chunk.invoke();
} }
case 2: // "load", // ( func [,chunkname] ) -> chunk | nil, msg return chunk.invoke();
try { }
LuaValue func = args.checkfunction(1); case 2: // "load", // ( func [,chunkname] ) -> chunk | nil, msg
String chunkname = args.optString(2, "function"); try {
return LoadState.load(new StringInputStream(func), chunkname, LuaThread.getRunningEnv(env)); LuaValue func = args.checkfunction(1);
} catch ( Exception e ) { String chunkname = args.optString(2, "function");
return varargsOf(NIL, valueOf(e.getMessage())); return LoadState.load(new StringInputStream(func), chunkname, LuaThread.getRunningEnv(env));
} } catch ( Exception e ) {
case 3: // "loadfile", // ( [filename] ) -> chunk | nil, msg return varargsOf(NIL, valueOf(e.getMessage()));
{ }
try { case 3: // "loadfile", // ( [filename] ) -> chunk | nil, msg
String filename = args.checkString(1); {
return loadFile(filename); try {
} catch ( Exception e ) { String filename = args.checkString(1);
return varargsOf(NIL, valueOf(e.getMessage())); return loadFile(filename);
} } catch ( Exception e ) {
return varargsOf(NIL, valueOf(e.getMessage()));
} }
case 4: // "loadstring", // ( string [,chunkname] ) -> chunk | nil, msg }
case 4: // "loadstring", // ( string [,chunkname] ) -> chunk | nil, msg
try {
LuaString script = args.checkstring(1);
String chunkname = args.optString(2, "string");
return LoadState.load(script.toInputStream(),chunkname,LuaThread.getRunningEnv(env));
} catch ( Exception e ) {
return varargsOf(NIL, valueOf(e.getMessage()));
}
case 5: // "pcall", // (f, arg1, ...) -> status, result1, ...
try {
LuaThread.onCall(this);
try { try {
LuaString script = args.checkstring(1); return varargsOf(LuaValue.TRUE, args.arg1().invoke(args.subargs(2)));
String chunkname = args.optString(2, "string"); } finally {
return LoadState.load(script.toInputStream(),chunkname,LuaThread.getRunningEnv(env)); LuaThread.onReturn();
} catch ( Exception e ) { }
return varargsOf(NIL, valueOf(e.getMessage())); } catch ( LuaError le ) {
} String m = le.getMessage();
case 5: // "pcall", // (f, arg1, ...) -> status, result1, ... return varargsOf(FALSE, m!=null? valueOf(m): NIL);
} catch ( Exception e ) {
String m = e.getMessage();
return varargsOf(FALSE, valueOf(m!=null? m: e.toString()));
}
case 6: // "xpcall", // (f, err) -> result1, ...
try {
LuaThread.onCall(this);
try { try {
LuaThread.onCall(this); LuaThread thread = LuaThread.getRunning();
LuaValue olderr = thread.err;
try { try {
thread.err = args.arg(2);
return varargsOf(LuaValue.TRUE, args.arg1().invoke(args.subargs(2))); return varargsOf(LuaValue.TRUE, args.arg1().invoke(args.subargs(2)));
} finally { } finally {
LuaThread.onReturn(); thread.err = olderr;
} }
} catch ( LuaError le ) { } finally {
String m = le.getMessage(); LuaThread.onReturn();
return varargsOf(FALSE, m!=null? valueOf(m): NIL);
} catch ( Exception e ) {
String m = e.getMessage();
return varargsOf(FALSE, valueOf(m!=null? m: e.toString()));
} }
case 6: // "xpcall", // (f, err) -> result1, ... } catch ( Exception e ) {
try { try {
LuaThread.onCall(this); return args.arg(2).invoke(valueOf(e.getMessage()));
try { } catch ( Exception f ) {
LuaThread thread = LuaThread.getRunning(); return varargsOf(FALSE, valueOf(f.getMessage()));
LuaValue olderr = thread.err;
try {
thread.err = args.arg(2);
return varargsOf(LuaValue.TRUE, args.arg1().invoke(args.subargs(2)));
} finally {
thread.err = olderr;
}
} finally {
LuaThread.onReturn();
}
} catch ( Exception e ) {
try {
return args.arg(2).invoke(valueOf(e.getMessage()));
} catch ( Exception f ) {
return varargsOf(FALSE, valueOf(f.getMessage()));
}
} }
case 7: // "print", // (...) -> void
{
LuaValue tostring = env.get("tostring");
for ( int i=1, n=args.narg(); i<=n; i++ ) {
if ( i>1 ) STDOUT.write( '\t' );
LuaString s = tostring.call( args.arg(i) ).strvalue();
int z = s.indexOf((byte)0, 0);
STDOUT.write( s.m_bytes, s.m_offset, z>=0? z: s.m_length );
}
STDOUT.println();
return NONE;
}
case 8: // "select", // (f, ...) -> value1, ...
{
int n = args.narg()-1;
if ( args.arg1().equals(valueOf("#")) )
return valueOf(n);
int i = args.checkint(1);
if ( i == 0 || i < -n )
typerror(1,"index out of range");
return args.subargs(i<0? n+i+2: i+1);
}
case 9: // "unpack", // (list [,i [,j]]) -> result1, ...
{
int na = args.narg();
LuaTable t = args.checktable(1);
int n = t.length();
int i = na>=2? args.checkint(2): 1;
int j = na>=3? args.checkint(3): n;
n = j-i+1;
if ( n<0 ) return NONE;
if ( n==1 ) return t.get(i);
if ( n==2 ) return varargsOf(t.get(i),t.get(j));
LuaValue[] v = new LuaValue[n];
for ( int k=0; k<n; k++ )
v[k] = t.get(i+k);
return varargsOf(v);
}
case 10: // "type", // (v) -> value
return valueOf(args.checkvalue(1).typename());
case 11: // "rawget", // (table, index) -> value
return args.checktable(1).rawget(args.checkvalue(2));
case 12: { // "rawset", // (table, index, value) -> table
LuaTable t = args.checktable(1);
t.rawset(args.checknotnil(2), args.checkvalue(3));
return t;
}
case 13: { // "setmetatable", // (table, metatable) -> table
final LuaValue t = args.arg1();
final LuaValue mt = args.checkvalue(2);
t.setmetatable(mt.isnil()? null: mt.checktable());
return t;
} }
case 7: // "print", // (...) -> void
{
LuaValue tostring = env.get("tostring");
for ( int i=1, n=args.narg(); i<=n; i++ ) {
if ( i>1 ) STDOUT.write( '\t' );
LuaString s = tostring.call( args.arg(i) ).strvalue();
int z = s.indexOf((byte)0, 0);
STDOUT.write( s.m_bytes, s.m_offset, z>=0? z: s.m_length );
} }
STDOUT.println();
return NONE; return NONE;
} }
case 8: // "select", // (f, ...) -> value1, ...
{
int n = args.narg()-1;
if ( args.arg1().equals(valueOf("#")) )
return valueOf(n);
int i = args.checkint(1);
if ( i == 0 || i < -n )
typerror(1,"index out of range");
return args.subargs(i<0? n+i+2: i+1);
}
case 9: // "unpack", // (list [,i [,j]]) -> result1, ...
{
int na = args.narg();
LuaTable t = args.checktable(1);
int n = t.length();
int i = na>=2? args.checkint(2): 1;
int j = na>=3? args.checkint(3): n;
n = j-i+1;
if ( n<0 ) return NONE;
if ( n==1 ) return t.get(i);
if ( n==2 ) return varargsOf(t.get(i),t.get(j));
LuaValue[] v = new LuaValue[n];
for ( int k=0; k<n; k++ )
v[k] = t.get(i+k);
return varargsOf(v);
}
case 10: // "type", // (v) -> value
return valueOf(args.checkvalue(1).typename());
case 11: // "rawget", // (table, index) -> value
return args.checktable(1).rawget(args.checkvalue(2));
case 12: { // "rawset", // (table, index, value) -> table
LuaTable t = args.checktable(1);
t.rawset(args.checknotnil(2), args.checkvalue(3));
return t;
}
case 13: { // "setmetatable", // (table, metatable) -> table
final LuaValue t = args.arg1();
final LuaValue mt = args.checkvalue(2);
t.setmetatable(mt.isnil()? null: mt.checktable());
return t;
}
case 14: // "pairs" (t) -> iter-func, t, nil
return varargsOf( next, args.checktable(1) );
case 15: // "ipairs", // (t) -> iter-func, t, 0
return varargsOf( inext, args.checktable(1), ZERO );
case 16: // "next" ( table, [index] ) -> next-index, next-value
return args.arg1().next(args.arg(2));
case 17: // "inext" ( table, [int-index] ) -> next-index, next-value
return args.arg1().inext(args.arg(2));
}
return NONE;
}
private Varargs loadFile(String filename) throws IOException { private Varargs loadFile(String filename) throws IOException {
InputStream is = FINDER.findResource(filename); InputStream is = FINDER.findResource(filename);
if ( is == null ) if ( is == null )
return varargsOf(NIL, valueOf("not found: "+filename)); return varargsOf(NIL, valueOf("not found: "+filename));
try { try {
return LoadState.load(is, filename, LuaThread.getRunningEnv(env)); return LoadState.load(is, filename, LuaThread.getRunningEnv(env));
} finally { } finally {
is.close(); is.close();
}
} }
} }
public static class BaseIter extends VarArgFunction {
final LuaValue aux;
BaseIter(int opcode, String name, LuaValue aux) {
this.name = name;
this.opcode = opcode;
this.aux = aux;
}
public Varargs invoke(Varargs args) {
switch ( opcode ) {
case 0: // "next" ( table, [index] ) -> next-index, next-value
return args.arg1().next(args.arg(2));
case 1: // "inext" ( table, [int-index] ) -> next-index, next-value
return args.arg1().inext(args.arg(2));
case 2: // "pairs" (t) -> iter-func, t, nil
return varargsOf( aux, args.checktable(1), NIL );
case 3: // "ipairs", // (t) -> iter-func, t, 0
return varargsOf( aux, args.checktable(1), ZERO );
}
return NONE;
}
}
private static class StringInputStream extends InputStream { private static class StringInputStream extends InputStream {

View File

@@ -21,24 +21,13 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2.lib; package org.luaj.vm2.lib;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaValue; import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs; import org.luaj.vm2.Varargs;
public class CoroutineLib extends VarArgFunction { public class CoroutineLib extends ZeroArgFunction {
private static final String[] NAMES = {
"create",
"resume",
"running",
"status",
"yield",
"wrap",
"wrapped"
};
private static final int INIT = -1;
private static final int CREATE = 0; private static final int CREATE = 0;
private static final int RESUME = 1; private static final int RESUME = 1;
private static final int RUNNING = 2; private static final int RUNNING = 2;
@@ -48,21 +37,18 @@ public class CoroutineLib extends VarArgFunction {
private static final int WRAPPED = 6; private static final int WRAPPED = 6;
public CoroutineLib() { public CoroutineLib() {
name = "coroutine";;
opcode = INIT;
}
private CoroutineLib(String name, int opcode, LuaThread thread) {
super(name, opcode, thread);
} }
public Varargs invoke(Varargs args) { public LuaValue call() {
LuaTable t = new LuaTable();
bindv(t, new String[] {
"create", "resume", "running", "status", "yield", "wrap" });
env.set("coroutine", t);
return t;
}
protected Varargs oncallv(int opcode, Varargs args) {
switch ( opcode ) { switch ( opcode ) {
case INIT: {
LuaTable t = new LuaTable();
LibFunction.bind(t, this.getClass(), NAMES);
return t;
}
case CREATE: { case CREATE: {
final LuaValue func = args.checkfunction(1); final LuaValue func = args.checkfunction(1);
return new LuaThread(func, func.getfenv() ); return new LuaThread(func, func.getfenv() );
@@ -87,7 +73,9 @@ public class CoroutineLib extends VarArgFunction {
case WRAP: { case WRAP: {
final LuaValue func = args.checkfunction(1); final LuaValue func = args.checkfunction(1);
final LuaThread thread = new LuaThread(func, func.getfenv()); final LuaThread thread = new LuaThread(func, func.getfenv());
return new CoroutineLib("wrapped",WRAPPED,thread); CoroutineLib cl = new CoroutineLib();
cl.setfenv(thread);
return cl.bindv("wrapped",WRAPPED);
} }
case WRAPPED: { case WRAPPED: {
final LuaThread t = (LuaThread) env; final LuaThread t = (LuaThread) env;

View File

@@ -21,20 +21,19 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2.lib; package org.luaj.vm2.lib;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.Lua; import org.luaj.vm2.Lua;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaError; import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaFunction; import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.LuaString; import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaValue; import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.Varargs; import org.luaj.vm2.Varargs;
public class DebugLib extends VarArgFunction { public class DebugLib extends OneArgFunction {
public static final boolean CALLS = (null != System.getProperty("CALLS")); public static final boolean CALLS = (null != System.getProperty("CALLS"));
public static final boolean TRACE = (null != System.getProperty("TRACE")); public static final boolean TRACE = (null != System.getProperty("TRACE"));
@@ -59,7 +58,6 @@ public class DebugLib extends VarArgFunction {
"traceback", "traceback",
}; };
private static final int INIT = -1;
private static final int DEBUG = 0; private static final int DEBUG = 0;
private static final int GETFENV = 1; private static final int GETFENV = 1;
private static final int GETHOOK = 2; private static final int GETHOOK = 2;
@@ -105,49 +103,34 @@ public class DebugLib extends VarArgFunction {
private static final LuaString ACTIVELINES = valueOf("activelines"); private static final LuaString ACTIVELINES = valueOf("activelines");
public DebugLib() { public DebugLib() {
name = "debug"; }
opcode = INIT;
public LuaValue call(LuaValue arg) {
LuaTable t = new LuaTable();
bindv(t, NAMES);
env.set("debug", t);
if ( ! DEBUG_ENABLED )
DEBUG_ENABLED = true;
return t;
} }
public Varargs invoke(Varargs args) { protected Varargs oncallv(int opcode, Varargs args) {
switch ( opcode ) { switch ( opcode ) {
case INIT: { case DEBUG: return _debug(args);
LuaTable t = new LuaTable(0,20); case GETFENV: return _getfenv(args);
LibFunction.bind(t, this.getClass(), NAMES); case GETHOOK: return _gethook(args);
if ( ! DEBUG_ENABLED ) case GETINFO: return _getinfo(args);
DEBUG_ENABLED = true; case GETLOCAL: return _getlocal(args);
return t; case GETMETATABLE: return _getmetatable(args);
} case GETREGISTRY: return _getregistry(args);
case DEBUG: case GETUPVALUE: return _getupvalue(args);
return _debug(args); case SETFENV: return _setfenv(args);
case GETFENV: case SETHOOK: return _sethook(args);
return _getfenv(args); case SETLOCAL: return _setlocal(args);
case GETHOOK: case SETMETATABLE: return _setmetatable(args);
return _gethook(args); case SETUPVALUE: return _setupvalue(args);
case GETINFO: case TRACEBACK: return _traceback(args);
return _getinfo(args); default: return NONE;
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;
} }
} }

View File

@@ -33,7 +33,7 @@ import org.luaj.vm2.Varargs;
abstract abstract
public class IoLib extends VarArgFunction { public class IoLib extends OneArgFunction {
abstract abstract
protected class File extends LuaValue{ protected class File extends LuaValue{
@@ -56,7 +56,7 @@ public class IoLib extends VarArgFunction {
// delegate method access to file methods table // delegate method access to file methods table
public LuaValue get( LuaValue key ) { public LuaValue get( LuaValue key ) {
return env.get(FILEMETHODS).get(key); return filemethods.get(key);
} }
// essentially a userdata instance // essentially a userdata instance
@@ -115,41 +115,38 @@ public class IoLib extends VarArgFunction {
private File infile = null; private File infile = null;
private File outfile = null; private File outfile = null;
private File errfile = null; private File errfile = null;
private static final LuaValue STDIN = valueOf("stdin"); private static final LuaValue STDIN = valueOf("stdin");
private static final LuaValue STDOUT = valueOf("stdout"); private static final LuaValue STDOUT = valueOf("stdout");
private static final LuaValue STDERR = valueOf("stderr"); private static final LuaValue STDERR = valueOf("stderr");
private static final LuaValue FILE = valueOf("file"); private static final LuaValue FILE = valueOf("file");
private static final LuaValue CLOSED_FILE = valueOf("closed file"); private static final LuaValue CLOSED_FILE = valueOf("closed file");
private static final LuaValue FILEMETHODS = valueOf("__filemethods");
private static final int INIT = 0; private static final int IO_CLOSE = 0;
private static final int IO_INDEX = 1; private static final int IO_FLUSH = 1;
private static final int IO_CLOSE = 2; private static final int IO_INPUT = 2;
private static final int IO_FLUSH = 3; private static final int IO_LINES = 3;
private static final int IO_INPUT = 4; private static final int IO_OPEN = 4;
private static final int IO_LINES = 5; private static final int IO_OUTPUT = 5;
private static final int IO_OPEN = 6; private static final int IO_POPEN = 6;
private static final int IO_OUTPUT = 7; private static final int IO_READ = 7;
private static final int IO_POPEN = 8; private static final int IO_TMPFILE = 8;
private static final int IO_READ = 9; private static final int IO_TYPE = 9;
private static final int IO_TMPFILE = 10; private static final int IO_WRITE = 10;
private static final int IO_TYPE = 11;
private static final int IO_WRITE = 12;
private static final int FILE_CLOSE = 13; private static final int FILE_CLOSE = 11;
private static final int FILE_FLUSH = 14; private static final int FILE_FLUSH = 12;
private static final int FILE_LINES = 15; private static final int FILE_LINES = 13;
private static final int FILE_READ = 16; private static final int FILE_READ = 14;
private static final int FILE_SEEK = 17; private static final int FILE_SEEK = 15;
private static final int FILE_SETVBUF = 18; private static final int FILE_SETVBUF = 16;
private static final int FILE_WRITE = 19; private static final int FILE_WRITE = 17;
private static final int LINES_ITER = 20; private static final int IO_INDEX = 18;
private static final int LINES_ITER = 19;
public static final String[] IO_NAMES = { public static final String[] IO_NAMES = {
"__index",
"close", "close",
"flush", "flush",
"input", "input",
@@ -172,40 +169,36 @@ public class IoLib extends VarArgFunction {
"setvbuf", "setvbuf",
"write", "write",
}; };
LuaTable filemethods;
public IoLib() {} public IoLib() {}
protected LuaTable init() { public LuaValue call(LuaValue arg) {
// io lib functions // io lib functions
LuaTable t = new LuaTable(); LuaTable t = new LuaTable();
LibFunction.bind(t, this.getClass(), IO_NAMES, IO_INDEX ); bindv(t, IO_NAMES );
// let t be its own metatable
t.setmetatable( t );
// create file methods table // create file methods table
LuaTable filemethods = new LuaTable(); filemethods = new LuaTable();
LibFunction.bind(filemethods, this.getClass(), FILE_NAMES, FILE_CLOSE ); bind(filemethods, FILE_NAMES, -1, FILE_CLOSE );
t.set(FILEMETHODS, filemethods);
// set up file metatable
LuaTable mt = tableOf( new LuaValue[] { INDEX, bindv("__index",IO_INDEX) });
t.setmetatable( mt );
// return the table // return the table
env.set("io", t);
return t; return t;
} }
public Varargs invoke(Varargs args) { protected Varargs oncallv(int opcode, Varargs args) {
File f; File f;
int n; int n;
LuaValue v; LuaValue v;
try { try {
switch ( opcode ) { switch ( opcode ) {
case INIT: // init
return init();
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 IO_FLUSH: // io.flush() -> bool case IO_FLUSH: // io.flush() -> bool
checkopen(output()); checkopen(output());
outfile.flush(); outfile.flush();
@@ -245,6 +238,7 @@ public class IoLib extends VarArgFunction {
case IO_WRITE: // io.write(...) -> void case IO_WRITE: // io.write(...) -> void
checkopen(output()); checkopen(output());
return iowrite(outfile,args); return iowrite(outfile,args);
case FILE_CLOSE: // file:close() -> void case FILE_CLOSE: // file:close() -> void
return ioclose(checkfile(args.arg1())); return ioclose(checkfile(args.arg1()));
case FILE_FLUSH: // file:flush() -> void case FILE_FLUSH: // file:flush() -> void
@@ -266,6 +260,12 @@ public class IoLib extends VarArgFunction {
case FILE_WRITE: // file:write(...) -> void case FILE_WRITE: // file:write(...) -> void
f = checkfile(args.arg1()); f = checkfile(args.arg1());
return iowrite(f,args.subargs(2)); 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' case LINES_ITER: // lines iterator(s,var) -> var'
f = checkfile(env); f = checkfile(env);
return freadline(f); return freadline(f);
@@ -321,10 +321,8 @@ public class IoLib extends VarArgFunction {
private Varargs lines(final File f) throws Exception { private Varargs lines(final File f) throws Exception {
IoLib iter = (IoLib) getClass().newInstance(); IoLib iter = (IoLib) getClass().newInstance();
iter.opcode = LINES_ITER; iter.setfenv(f);
iter.name = "lnext"; return iter.bindv("lnext",LINES_ITER);
iter.env = f;
return iter;
} }
private static Varargs iowrite(File f, Varargs args) throws IOException { private static Varargs iowrite(File f, Varargs args) throws IOException {

View File

@@ -22,59 +22,264 @@
package org.luaj.vm2.lib; package org.luaj.vm2.lib;
import org.luaj.vm2.LuaFunction; import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue; import org.luaj.vm2.LuaValue;
; import org.luaj.vm2.Varargs;
abstract public class LibFunction extends LuaFunction { abstract public class LibFunction extends LuaFunction {
protected int opcode; protected LibFunction() {
protected String name;
public LibFunction() {
} }
protected void bind0(LuaValue env, String[] names) {
public LibFunction(String name, int opcode, LuaValue env) { bind(env, names, 0, 0);
super(env);
this.name = name;
this.opcode = opcode;
} }
protected void bind1(LuaValue env, String[] names) {
public String toString() { bind(env, names, 1, 0);
return name!=null? name: super.toString();
} }
protected void bind2(LuaValue env, String[] names) {
public static LuaTable bind( LuaTable table, Class libFuncClass, String[] names ) { bind(env, names, 2, 0);
return bind( table, libFuncClass, names, 0 );
} }
protected void bind3(LuaValue env, String[] names) {
/** Bind a set of names to class instances, put values into the table. */ bind(env, names, 3, 0);
public static LuaTable bind( LuaTable table, Class libFuncClass, String[] names, int firstOpcode ) { }
try { protected void bindv(LuaValue env, String[] names) {
for ( int i=0, n=names.length; i<n; i++ ) { bind(env, names, -1, 0);
LibFunction f = (LibFunction) libFuncClass.newInstance(); }
f.opcode = firstOpcode + i; protected void bind(LuaValue env, String[] names, int numargs, int firstopcode ) {
f.name = names[i]; for ( int i=0, n=names.length; i<n; i++ ) {
f.env = table; int opcode = firstopcode + i;
table.set( names[i], f ); 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;
} }
} catch (InstantiationException e) { env.set(names[i], binding);
throw new RuntimeException(e.toString());
} catch (IllegalAccessException e) {
throw new RuntimeException(e.toString());
} }
return table;
} }
/** Bind a complete set of names and classes , put values into the table. */ protected LibFunction bind0(String name, int opcode) {
public static LuaTable bind( LuaTable table, Class[] libFuncClasses, String[][] nameLists ) { return new ZeroArgBinding(name, opcode, this);
for ( int j=0, n=libFuncClasses.length; j<n; j++ ) { }
bind( table, libFuncClasses[j], nameLists[j] ); protected LibFunction bind1(String name, int opcode) {
} return new OneArgBinding(name, opcode, this);
return table; }
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 String name;
private final int opcode;
private final LibFunction delegate;
private ZeroArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String toString() {
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 String name;
private final int opcode;
private final LibFunction delegate;
private OneArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String toString() {
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 String name;
private final int opcode;
private final LibFunction delegate;
private TwoArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String toString() {
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 String name;
private final int opcode;
private final LibFunction delegate;
private ThreeArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String toString() {
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 String name;
private final int opcode;
private final LibFunction delegate;
private VarArgBinding(String name, int opcode, LibFunction delegate) {
this.name = name;
this.opcode = opcode;
this.delegate = delegate;
}
public String toString() {
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);
}
}
} }

View File

@@ -39,34 +39,31 @@ public class MathLib extends OneArgFunction {
public static MathLib MATHLIB = null; public static MathLib MATHLIB = null;
private static final LuaValue RANDOM = valueOf("__random"); private Random random;
public MathLib() { public MathLib() {
name = "math";
opcode = -1;
MATHLIB = this; MATHLIB = this;
} }
protected LuaTable init() { public LuaValue call(LuaValue arg) {
LuaTable t = new LuaTable(0,30); LuaTable t = new LuaTable(0,30);
t.set( "pi", Math.PI ); t.set( "pi", Math.PI );
t.set( "huge", LuaDouble.POSINF ); t.set( "huge", LuaDouble.POSINF );
LibFunction.bind( t, new MathLib().getClass(), new String[] { bind1( t, new String[] {
"abs", "ceil", "cos", "deg", "abs", "ceil", "cos", "deg",
"exp", "floor", "rad", "sin", "exp", "floor", "rad", "sin",
"sqrt", "tan" } ); "sqrt", "tan" } );
LibFunction.bind( t, new MathFunc2().getClass(), new String[] { bind2( t, new String[] {
"fmod", "ldexp", "pow", "random", "fmod", "ldexp", "pow", "random", } );
} ); bindv( t, new String[] {
LibFunction.bind( t, new MathFuncV().getClass(), new String[] {
"frexp", "max", "min", "modf", "frexp", "max", "min", "modf",
"randomseed" } ); "randomseed" } );
env.set("math", t);
return t; return t;
} }
public LuaValue call(LuaValue arg) { public LuaValue oncall1(int opcode, LuaValue arg) {
switch ( opcode ) { switch ( opcode ) {
case -1: return init();
case 0: return valueOf(Math.abs(arg.todouble())); case 0: return valueOf(Math.abs(arg.todouble()));
case 1: return valueOf(Math.ceil(arg.todouble())); case 1: return valueOf(Math.ceil(arg.todouble()));
case 2: return valueOf(Math.cos(arg.todouble())); case 2: return valueOf(Math.cos(arg.todouble()));
@@ -81,41 +78,37 @@ public class MathLib extends OneArgFunction {
return NIL; return NIL;
} }
public static class MathFunc2 extends TwoArgFunction { public LuaValue oncall2(int opcode,LuaValue arg1,LuaValue arg2) {
public LuaValue call(LuaValue arg1,LuaValue arg2) { switch ( opcode ) {
switch ( opcode ) { case 0: { // fmod
case 0: { // fmod double x = arg1.checkdouble();
double x = arg1.checkdouble(); double y = arg2.checkdouble();
double y = arg2.checkdouble(); double q = x/y;
double q = x/y; double f = x - y * (q>=0? Math.floor(q): Math.ceil(q));
double f = x - y * (q>=0? Math.floor(q): Math.ceil(q)); return valueOf( f );
return valueOf( f );
}
case 1: { // ldexp
double x = arg1.checkdouble();
double y = arg2.checkdouble()+1023.5;
long e = (long) ((0!=(1&((int)y)))? Math.floor(y): Math.ceil(y-1));
return valueOf(x * Double.longBitsToDouble(e << 52));
}
case 2: { // pow
return dpow(arg1.todouble(), arg2.todouble());
}
case 3: { // 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( random.nextDouble() );
int m = arg1.toint();
if ( arg2.isnil() )
return valueOf( 1 + random.nextInt(m) );
else
return valueOf( m + random.nextInt(arg2.toint()-m) );
}
}
return NIL;
} }
case 1: { // ldexp
double x = arg1.checkdouble();
double y = arg2.checkdouble()+1023.5;
long e = (long) ((0!=(1&((int)y)))? Math.floor(y): Math.ceil(y-1));
return valueOf(x * Double.longBitsToDouble(e << 52));
}
case 2: { // pow
return dpow(arg1.todouble(), arg2.todouble());
}
case 3: { // random
if ( random == null )
random = new Random();
if ( arg1.isnil() )
return valueOf( random.nextDouble() );
int m = arg1.toint();
if ( arg2.isnil() )
return valueOf( 1 + random.nextInt(m) );
else
return valueOf( m + random.nextInt(arg2.toint()-m) );
}
}
return NIL;
} }
/** compute power using installed math library, or default if there is no math library installed */ /** compute power using installed math library, or default if there is no math library installed */
@@ -155,42 +148,40 @@ public class MathLib extends OneArgFunction {
return p; return p;
} }
public static class MathFuncV extends VarArgFunction { public Varargs oncallv(int opcode,Varargs args) {
public Varargs invoke(Varargs args) { switch ( opcode ) {
switch ( opcode ) { case 0: { // frexp
case 0: { // frexp double x = args.checkdouble(1);
double x = args.checkdouble(1); if ( x == 0 ) return varargsOf(ZERO,ZERO);
if ( x == 0 ) return varargsOf(ZERO,ZERO); long bits = Double.doubleToLongBits( x );
long bits = Double.doubleToLongBits( x ); double m = ((bits & (~(-1L<<52))) + (1L<<52)) * ((bits >= 0)? (.5 / (1L<<52)): (-.5 / (1L<<52)));
double m = ((bits & (~(-1L<<52))) + (1L<<52)) * ((bits >= 0)? (.5 / (1L<<52)): (-.5 / (1L<<52))); double e = (((int) (bits >> 52)) & 0x7ff) - 1022;
double e = (((int) (bits >> 52)) & 0x7ff) - 1022; return varargsOf( valueOf(m), valueOf(e) );
return varargsOf( valueOf(m), valueOf(e) ); }
} case 1: { // max
case 1: { // max double m = args.checkdouble(1);
double m = args.checkdouble(1); for ( int i=2,n=args.narg(); i<=n; ++i )
for ( int i=2,n=args.narg(); i<=n; ++i ) m = Math.max(m,args.checkdouble(i));
m = Math.max(m,args.checkdouble(i)); return valueOf(m);
return valueOf(m); }
} case 2: { // min
case 2: { // min double m = args.checkdouble(1);
double m = args.checkdouble(1); for ( int i=2,n=args.narg(); i<=n; ++i )
for ( int i=2,n=args.narg(); i<=n; ++i ) m = Math.min(m,args.checkdouble(i));
m = Math.min(m,args.checkdouble(i)); return valueOf(m);
return valueOf(m); }
} case 3: { // modf
case 3: { // modf double x = args.checkdouble(1);
double x = args.checkdouble(1); double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x );
double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x ); double fracPart = x - intPart;
double fracPart = x - intPart; return varargsOf( valueOf(intPart), valueOf(fracPart) );
return varargsOf( valueOf(intPart), valueOf(fracPart) ); }
} case 4: { // randomseed
case 4: { // randomseed long seed = args.checklong(1);
long seed = args.checklong(1); random = new Random(seed);
env.set(RANDOM,userdataOf(new Random(seed)));
return NONE;
}
}
return NONE; return NONE;
} }
}
return NONE;
} }
} }

View File

@@ -35,10 +35,6 @@ abstract public class OneArgFunction extends LibFunction {
this.env = env; this.env = env;
} }
public OneArgFunction( String name, int opcode, LuaValue env ) {
super(name, opcode, env);
}
public final LuaValue call() { public final LuaValue call() {
return call(NIL); return call(NIL);
} }

View File

@@ -46,11 +46,10 @@ import org.luaj.vm2.Varargs;
* *
* @see org.luaj.vm2.lib.jse.JseOsLib * @see org.luaj.vm2.lib.jse.JseOsLib
*/ */
public class OsLib extends VarArgFunction { public class OsLib extends OneArgFunction {
public static String TMP_PREFIX = ".luaj"; public static String TMP_PREFIX = ".luaj";
public static String TMP_SUFFIX = "tmp"; public static String TMP_SUFFIX = "tmp";
private static final int INIT = -1;
private static final int CLOCK = 0; private static final int CLOCK = 0;
private static final int DATE = 1; private static final int DATE = 1;
private static final int DIFFTIME = 2; private static final int DIFFTIME = 2;
@@ -84,18 +83,18 @@ public class OsLib extends VarArgFunction {
* Create and OsLib instance. * Create and OsLib instance.
*/ */
public OsLib() { public OsLib() {
name = "os";
opcode = INIT;
} }
public Varargs invoke(Varargs args) { public LuaValue call(LuaValue arg) {
LuaTable t = new LuaTable();
bindv(t, NAMES);
env.set("os", t);
return t;
}
protected Varargs oncallv(int opcode, Varargs args) {
try { try {
switch ( opcode ) { switch ( opcode ) {
case INIT: {
LuaTable t = new LuaTable();
LibFunction.bind(t, getClass(), NAMES);
return t;
}
case CLOCK: case CLOCK:
return valueOf(clock()); return valueOf(clock());
case DATE: { case DATE: {

View File

@@ -32,87 +32,89 @@ import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs; import org.luaj.vm2.Varargs;
public class PackageLib extends LuaTable { public class PackageLib extends OneArgFunction {
public static String DEFAULT_LUA_PATH = "?.lua"; public static String DEFAULT_LUA_PATH = "?.lua";
public LuaValue _G = null; public InputStream STDIN = null;
public InputStream STDIN = null; public PrintStream STDOUT = System.out;
public PrintStream STDOUT = System.out; public LuaTable LOADED;
public LuaTable LOADED = null; public LuaTable PACKAGE;
public LuaTable PACKAGE = null;
private static final LuaString _M = LuaString.valueOf("_M"); private static final LuaString _M = valueOf("_M");
private static final LuaString _NAME = LuaString.valueOf("_NAME"); private static final LuaString _NAME = valueOf("_NAME");
private static final LuaString _PACKAGE = LuaString.valueOf("_PACKAGE"); private static final LuaString _PACKAGE = valueOf("_PACKAGE");
private static final LuaString _DOT = LuaString.valueOf("."); private static final LuaString _DOT = valueOf(".");
private static final LuaString _LOADERS = LuaString.valueOf("loaders"); private static final LuaString _LOADERS = valueOf("loaders");
private static final LuaString _LOADED = LuaString.valueOf("loaded"); private static final LuaString _LOADED = valueOf("loaded");
private static final LuaString _LOADLIB = LuaString.valueOf("loadlib"); private static final LuaString _LOADLIB = valueOf("loadlib");
private static final LuaString _PRELOAD = LuaString.valueOf("preload"); private static final LuaString _PRELOAD = valueOf("preload");
private static final LuaString _PATH = LuaString.valueOf("path"); private static final LuaString _PATH = valueOf("path");
private static final LuaString _SEEALL = LuaString.valueOf("seeall"); private static final LuaString _SEEALL = valueOf("seeall");
private static final LuaValue _SENTINEL = EMPTYSTRING; private static final LuaString _LOADFILE = valueOf("loadfile");
private static final LuaString _SENTINEL = valueOf("\u0001");
private static final int MODULE = 1; private static final int MODULE = 0;
private static final int REQUIRE = 2; private static final int REQUIRE = 1;
private static final int LOADLIB = 3; private static final int LOADLIB = 2;
private static final int SEEALL = 4; private static final int SEEALL = 3;
private static final int PRELOAD_LOADER = 5; private static final int PRELOAD_LOADER = 4;
private static final int LUA_LOADER = 6; private static final int LUA_LOADER = 5;
private static final int JAVA_LOADER = 7; private static final int JAVA_LOADER = 6;
public PackageLib() {
public PackageLib(LuaValue _G) { }
this._G = _G;
_G.set( "module", new PackageFuncV(MODULE, "module", _G) ); public LuaValue call(LuaValue arg) {
_G.set( "require", new PackageFuncV(REQUIRE, "require",_G) ); env.set("require", bind1("require",REQUIRE));
_G.set( "package", PACKAGE = tableOf( new LuaValue[] { env.set("module", bindv("module",MODULE));
env.set( "package", PACKAGE=tableOf( new LuaValue[] {
_LOADED, LOADED=tableOf(), _LOADED, LOADED=tableOf(),
_PRELOAD, tableOf(), _PRELOAD, tableOf(),
_PATH, valueOf(DEFAULT_LUA_PATH), _PATH, valueOf(DEFAULT_LUA_PATH),
_LOADLIB, new PackageFuncV(LOADLIB, "loadlib",_G), _LOADLIB, bindv("loadlib",LOADLIB),
_SEEALL, new PackageFuncV(SEEALL, "seeall",_G), _SEEALL, bind1("seeall",SEEALL),
_LOADERS, listOf(new LuaValue[] { _LOADERS, listOf(new LuaValue[] {
new PackageFuncV(PRELOAD_LOADER,"preload_loader",_G), bindv("preload_loader", PRELOAD_LOADER),
new PackageFuncV(LUA_LOADER, "lua_loader",_G), bindv("lua_loader", LUA_LOADER),
new PackageFuncV(JAVA_LOADER, "java_loader",_G), bindv("java_loader", JAVA_LOADER),
}), }) }) );
} ) ); return env;
} }
private class PackageFuncV extends VarArgFunction { protected LuaValue oncall1(int opcode, LuaValue arg) {
public PackageFuncV(int opcode, String name, LuaValue env) { switch ( opcode ) {
super(name, opcode, env); case REQUIRE:
} return require(arg);
public Varargs invoke(Varargs args) { case SEEALL: {
switch ( opcode ) { LuaTable t = arg.checktable();
case MODULE: LuaValue m = t.getmetatable();
return module(args); if ( m == null )
case REQUIRE: t.setmetatable(m=tableOf());
return require(args); m.set( INDEX, env );
case LOADLIB:
return loadlib(args);
case SEEALL: {
LuaTable t = args.checktable(1);
LuaValue m = t.getmetatable();
if ( m == null )
t.setmetatable(m=tableOf());
m.set( INDEX, env );
return NONE;
}
case PRELOAD_LOADER: {
return loader_preload(args);
}
case LUA_LOADER: {
return loader_Lua(args);
}
case JAVA_LOADER: {
return loader_Java(args);
}
}
return NONE; return NONE;
} }
}
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);
}
case LUA_LOADER: {
return loader_Lua(args);
}
case JAVA_LOADER: {
return loader_Java(args);
}
}
return NONE;
} }
/** Allow packages to mark themselves as loaded */ /** Allow packages to mark themselves as loaded */
@@ -159,7 +161,7 @@ public class PackageLib extends LuaTable {
if ( ! value.istable() ) { /* not found? */ if ( ! value.istable() ) { /* not found? */
/* try global variable (and create one if it does not exist) */ /* try global variable (and create one if it does not exist) */
module = findtable( _G, modname ); module = findtable( env, modname );
if ( module == null ) if ( module == null )
error( "name conflict for module '"+modname+"'" ); error( "name conflict for module '"+modname+"'" );
LOADED.set(modname, module); LOADED.set(modname, module);
@@ -249,8 +251,8 @@ public class PackageLib extends LuaTable {
* If there is any error loading or running the module, or if it cannot find any loader for * If there is any error loading or running the module, or if it cannot find any loader for
* the module, then require signals an error. * the module, then require signals an error.
*/ */
public Varargs require( Varargs args ) { public LuaValue require( LuaValue arg ) {
LuaString name = args.checkstring(1); LuaString name = arg.checkstring();
LuaValue loaded = LOADED.get(name); LuaValue loaded = LOADED.get(name);
if ( loaded.toboolean() ) { if ( loaded.toboolean() ) {
if ( loaded == _SENTINEL ) if ( loaded == _SENTINEL )
@@ -304,7 +306,7 @@ public class PackageLib extends LuaTable {
InputStream is = null; InputStream is = null;
// try to use loadfile for the file // try to use loadfile for the file
LuaValue loadfile = _G.get("loadfile"); LuaValue loadfile = env.get(_LOADFILE);
if ( ! loadfile.isfunction() ) if ( ! loadfile.isfunction() )
return valueOf("loadfile is not a function" ); return valueOf("loadfile is not a function" );
@@ -357,7 +359,7 @@ public class PackageLib extends LuaTable {
try { try {
c = Class.forName(classname); c = Class.forName(classname);
v = (LuaValue) c.newInstance(); v = (LuaValue) c.newInstance();
v.setfenv(_G); v.setfenv(env);
return v; return v;
} catch ( ClassNotFoundException cnfe ) { } catch ( ClassNotFoundException cnfe ) {
return valueOf("\n\tno class '"+classname+"'" ); return valueOf("\n\tno class '"+classname+"'" );

View File

@@ -37,23 +37,23 @@ public class StringLib extends OneArgFunction {
public static LuaTable instance; public static LuaTable instance;
public StringLib() { public StringLib() {
name = "string";
opcode = -1;
} }
public LuaValue call(LuaValue arg) { public LuaValue call(LuaValue arg) {
switch ( opcode ) { LuaTable t = new LuaTable();
case -1: { bind1(t, new String[] {
LuaTable t = new LuaTable(); "dump", "len", "lower", "reverse", "upper", } );
LibFunction.bind( t, getClass(), new String[] { bindv(t, new String[] {
"dump", "len", "lower", "reverse", "upper", } ); "byte", "char", "find", "format",
LibFunction.bind( t, new StringFuncV().getClass(), new String[] { "gmatch", "gsub", "match", "rep",
"byte", "char", "find", "format", "sub"} );
"gmatch", "gsub", "match", "rep", env.set("string", t);
"sub"} ); instance = t;
instance = t; return t;
return t; }
}
protected LuaValue oncall1(int opcode, LuaValue arg) {
switch ( opcode ) {
case 0: return dump(arg); // dump (function) case 0: return dump(arg); // dump (function)
case 1: return len(arg); // len (function) case 1: return len(arg); // len (function)
case 2: return lower(arg); // lower (function) case 2: return lower(arg); // lower (function)
@@ -61,25 +61,24 @@ public class StringLib extends OneArgFunction {
case 4: return upper(arg); // upper (function) case 4: return upper(arg); // upper (function)
} }
return NIL; return NIL;
}
public static class StringFuncV extends VarArgFunction {
public Varargs invoke(Varargs args) {
switch ( opcode ) {
case 0: return StringLib.byte_( args );
case 1: return StringLib.char_( args );
case 2: return StringLib.find( args );
case 3: return StringLib.format( args );
case 4: return StringLib.gmatch( args );
case 5: return StringLib.gsub( args );
case 6: return StringLib.match( args );
case 7: return StringLib.rep( args );
case 8: return StringLib.sub( args );
}
return NONE;
}
} }
protected Varargs oncallv(int opcode, Varargs args) {
switch ( opcode ) {
case 0: return StringLib.byte_( args );
case 1: return StringLib.char_( args );
case 2: return StringLib.find( args );
case 3: return StringLib.format( args );
case 4: return StringLib.gmatch( args );
case 5: return StringLib.gsub( args );
case 6: return StringLib.match( args );
case 7: return StringLib.rep( args );
case 8: return StringLib.sub( args );
}
return NONE;
}
/** /**
* string.byte (s [, i [, j]]) * string.byte (s [, i [, j]])
* *

View File

@@ -28,68 +28,66 @@ import org.luaj.vm2.Varargs;
public class TableLib extends OneArgFunction { public class TableLib extends OneArgFunction {
public TableLib() { public TableLib() {
name = "table";
opcode = -1;
} }
public LuaValue call(LuaValue arg) { public LuaValue call(LuaValue arg) {
LuaTable t = new LuaTable();
bind1(t, new String[] {
"getn", // (table) -> number
"maxn", // (table) -> number
} );
bindv(t, 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
} );
env.set("table", t);
return t;
}
protected LuaValue oncall1(int opcode, LuaValue arg) {
switch ( opcode ) { 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 0: return arg.checktable().getn();
case 1: return valueOf( arg.checktable().maxn()); case 1: return valueOf( arg.checktable().maxn());
} }
return NIL; return NIL;
} }
public static class TableFuncV extends VarArgFunction { protected Varargs oncallv(int opcode, Varargs args) {
public Varargs invoke(Varargs args) { switch ( opcode ) {
switch ( opcode ) { case 0: { // "remove" (table [, pos]) -> removed-ele
case 0: { // "remove" (table [, pos]) -> removed-ele LuaTable table = args.checktable(1);
LuaTable table = args.checktable(1); int pos = args.narg()>1? args.checkint(2): 0;
int pos = args.narg()>1? args.checkint(2): 0; return table.remove(pos);
return table.remove(pos); }
} case 1: { // "concat" (table [, sep [, i [, j]]]) -> string
case 1: { // "concat" (table [, sep [, i [, j]]]) -> string LuaTable table = args.checktable(1);
LuaTable table = args.checktable(1); return table.concat(
return table.concat( args.optstring(2,LuaValue.EMPTYSTRING),
args.optstring(2,LuaValue.EMPTYSTRING), args.optint(3,1),
args.optint(3,1), args.isvalue(4)? args.checkint(4): table.length() );
args.isvalue(4)? args.checkint(4): table.length() ); }
} case 2: { // "insert" (table, [pos,] value) -> prev-ele
case 2: { // "insert" (table, [pos,] value) -> prev-ele final LuaTable table = args.checktable(1);
final LuaTable table = args.checktable(1); final int pos = args.narg()>2? args.checkint(2): 0;
final int pos = args.narg()>2? args.checkint(2): 0; final LuaValue value = args.arg( args.narg()>2? 3: 2 );
final LuaValue value = args.arg( args.narg()>2? 3: 2 ); table.insert( pos, value );
table.insert( pos, value );
return NONE;
}
case 3: { // "sort" (table [, comp]) -> void
args.checktable(1).sort( args.optvalue(2,NIL) );
return NONE;
}
case 4: { // (table, func) -> void
return args.checktable(1).foreach( args.checkfunction(2) );
}
case 5: { // "foreachi" (table, func) -> void
return args.checktable(1).foreachi( args.checkfunction(2) );
}
}
return NONE; return NONE;
} }
case 3: { // "sort" (table [, comp]) -> void
args.checktable(1).sort( args.optvalue(2,NIL) );
return NONE;
}
case 4: { // (table, func) -> void
return args.checktable(1).foreach( args.checkfunction(2) );
}
case 5: { // "foreachi" (table, func) -> void
return args.checktable(1).foreachi( args.checkfunction(2) );
}
}
return NONE;
} }
} }

View File

@@ -35,10 +35,6 @@ abstract public class ThreeArgFunction extends LibFunction {
this.env = env; this.env = env;
} }
public ThreeArgFunction( String name, int opcode, LuaValue env ) {
super(name, opcode, env);
}
public final LuaValue call() { public final LuaValue call() {
return call(NIL, NIL, NIL); return call(NIL, NIL, NIL);
} }

View File

@@ -35,10 +35,6 @@ abstract public class TwoArgFunction extends LibFunction {
this.env = env; this.env = env;
} }
public TwoArgFunction( String name, int opcode, LuaValue env ) {
super(name, opcode, env);
}
public final LuaValue call() { public final LuaValue call() {
return call(NIL, NIL); return call(NIL, NIL);
} }

View File

@@ -33,10 +33,6 @@ abstract public class VarArgFunction extends LibFunction {
this.env = env; this.env = env;
} }
public VarArgFunction( String name, int opcode, LuaValue env ) {
super(name, opcode, env);
}
public final LuaValue call() { public final LuaValue call() {
return invoke(NONE).arg1(); return invoke(NONE).arg1();
} }

View File

@@ -35,10 +35,6 @@ abstract public class ZeroArgFunction extends LibFunction {
this.env = env; this.env = env;
} }
public ZeroArgFunction( String name, int opcode, LuaValue env ) {
super(name, opcode, env);
}
public LuaValue call(LuaValue arg) { public LuaValue call(LuaValue arg) {
return call(); return call();
} }

View File

@@ -22,7 +22,12 @@
package org.luaj.vm2.lib; package org.luaj.vm2.lib;
import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jme.JmeIoLib;
import org.luaj.vm2.lib.jse.JseBaseLib;
import org.luaj.vm2.lib.jse.JseIoLib;
import org.luaj.vm2.lib.jse.JseMathLib;
import org.luaj.vm2.lib.jse.JseOsLib;
import org.luaj.vm2.lib.jse.LuajavaLib;
public class JmePlatform { public class JmePlatform {
@@ -32,27 +37,24 @@ public class JmePlatform {
* @return Table of globals initialized with the standard JME libraries * @return Table of globals initialized with the standard JME libraries
*/ */
public static LuaTable standardGlobals() { public static LuaTable standardGlobals() {
LuaTable _G = new BaseLib(); LuaTable _G = new LuaTable();
new org.luaj.vm2.lib.PackageLib(_G); init(_G, new BaseLib());
set(_G, "coroutine", new org.luaj.vm2.lib.CoroutineLib() ); init(_G, new PackageLib());
set(_G, "io", new org.luaj.vm2.lib.jme.JseIoLib() ); init(_G, new TableLib());
set(_G, "math", new org.luaj.vm2.lib.MathLib() ); init(_G, new StringLib());
set(_G, "os", new org.luaj.vm2.lib.OsLib() ); init(_G, new CoroutineLib());
set(_G, "table", new org.luaj.vm2.lib.TableLib() ); init(_G, new JmeIoLib());
set(_G, "string", new org.luaj.vm2.lib.StringLib() );
return _G; return _G;
} }
public static LuaTable debugGlobals() { public static LuaTable debugGlobals() {
LuaTable _G = standardGlobals(); LuaTable _G = standardGlobals();
set(_G, "string", new org.luaj.vm2.lib.DebugLib() ); init(_G, new DebugLib());
return _G; return _G;
} }
private static void set( LuaTable _G, String name, LuaValue chunk ) { private static void init(LuaTable _G, LibFunction lib) {
chunk.setfenv(_G); lib.setfenv(_G);
LuaValue pkg = chunk.call(LuaValue.valueOf(name)); lib.call();
_G.set( name, pkg );
} }
} }

View File

@@ -37,18 +37,18 @@ import org.luaj.vm2.lib.IoLib;
* *
* Seek is not supported. * Seek is not supported.
*/ */
public class JseIoLib extends IoLib { public class JmeIoLib extends IoLib {
public JseIoLib() { public JmeIoLib() {
super(); super();
} }
protected File wrapStdin() throws IOException { protected File wrapStdin() throws IOException {
return new FileImpl(BaseLib.STDIN); return new FileImpl(BaseLib.instance.STDIN);
} }
protected File wrapStdout() throws IOException { protected File wrapStdout() throws IOException {
return new FileImpl(BaseLib.STDOUT); return new FileImpl(BaseLib.instance.STDOUT);
} }
protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException { protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException {

View File

@@ -22,8 +22,6 @@
package org.luaj.vm2.lib; package org.luaj.vm2.lib;
import org.luaj.vm2.LuaTable; 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.JseBaseLib;
import org.luaj.vm2.lib.jse.JseIoLib; import org.luaj.vm2.lib.jse.JseIoLib;
import org.luaj.vm2.lib.jse.JseMathLib; import org.luaj.vm2.lib.jse.JseMathLib;
@@ -38,22 +36,22 @@ public class JsePlatform {
* @return Table of globals initialized with the standard JSE libraries * @return Table of globals initialized with the standard JSE libraries
*/ */
public static LuaTable standardGlobals() { public static LuaTable standardGlobals() {
LuaTable _G = new JseBaseLib(); LuaTable _G = new LuaTable();
new org.luaj.vm2.lib.PackageLib(_G); init(_G, new JseBaseLib());
set(_G, "table", new org.luaj.vm2.lib.TableLib() ); init(_G, new PackageLib());
set(_G, "string", new org.luaj.vm2.lib.StringLib() ); init(_G, new TableLib());
set(_G, "coroutine", new org.luaj.vm2.lib.CoroutineLib() ); init(_G, new StringLib());
set(_G, "debug", new org.luaj.vm2.lib.DebugLib() ); init(_G, new CoroutineLib());
set(_G, "math", new org.luaj.vm2.lib.jse.JseMathLib() ); init(_G, new DebugLib());
set(_G, "io", new org.luaj.vm2.lib.jse.JseIoLib() ); init(_G, new JseMathLib());
set(_G, "os", new org.luaj.vm2.lib.jse.JseOsLib() ); init(_G, new JseIoLib());
set(_G, "luajava", new org.luaj.vm2.lib.jse.LuajavaLib() ); init(_G, new JseOsLib());
init(_G, new LuajavaLib());
return _G; return _G;
} }
private static void set( LuaTable _G, String name, LuaValue chunk ) { private static void init(LuaTable _G, LibFunction lib) {
chunk.setfenv(_G); lib.setfenv(_G);
LuaValue pkg = chunk.call(LuaValue.valueOf(name)); lib.call();
_G.set( name, pkg );
} }
} }

View File

@@ -38,12 +38,9 @@ import java.io.InputStream;
*/ */
public class JseBaseLib extends org.luaj.vm2.lib.BaseLib { public class JseBaseLib extends org.luaj.vm2.lib.BaseLib {
static {
STDIN = System.in;
}
/** Construct a JSE base library instance */ /** Construct a JSE base library instance */
public JseBaseLib() { public JseBaseLib() {
STDIN = System.in;
} }
/** /**

View File

@@ -21,6 +21,7 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2.lib.jse; package org.luaj.vm2.lib.jse;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -29,6 +30,7 @@ import java.io.RandomAccessFile;
import org.luaj.vm2.LuaError; import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaString; import org.luaj.vm2.LuaString;
import org.luaj.vm2.lib.BaseLib;
import org.luaj.vm2.lib.IoLib; import org.luaj.vm2.lib.IoLib;
/** /**
@@ -42,11 +44,11 @@ public class JseIoLib extends IoLib {
} }
protected File wrapStdin() throws IOException { protected File wrapStdin() throws IOException {
return new FileImpl(JseBaseLib.STDIN); return new FileImpl(BaseLib.instance.STDIN);
} }
protected File wrapStdout() throws IOException { protected File wrapStdout() throws IOException {
return new FileImpl(JseBaseLib.STDOUT); return new FileImpl(BaseLib.instance.STDOUT);
} }
protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException { protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException {

View File

@@ -21,10 +21,8 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2.lib.jse; package org.luaj.vm2.lib.jse;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue; import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.LibFunction; import org.luaj.vm2.lib.MathLib;
import org.luaj.vm2.lib.TwoArgFunction;
/** /**
* Math library implementation for use on JSE platform. * Math library implementation for use on JSE platform.
@@ -36,20 +34,21 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
public JseMathLib() {} public JseMathLib() {}
protected LuaTable init() { public LuaValue call(LuaValue arg) {
LuaTable t = super.init(); MathLib ml = new MathLib();
LibFunction.bind( t, this.getClass(), new String[] { ml.setfenv(env);
LuaValue t = ml.call(arg);
bind1( t, new String[] {
"acos", "asin", "atan", "cosh", "acos", "asin", "atan", "cosh",
"exp", "log", "log10", "sinh", "exp", "log", "log10", "sinh",
"tanh" } ); "tanh" } );
LibFunction.bind( t, new J2seMathFunc2().getClass(), new String[] { bind2( t, new String[] {
"atan2", "pow", } ); "atan2", "pow", } );
return t; return t;
} }
public LuaValue call(LuaValue arg) { public LuaValue oncall1(int opcode, LuaValue arg) {
switch ( opcode ) { switch ( opcode ) {
case -1: return init();
case 0: return valueOf(Math.acos(arg.todouble())); case 0: return valueOf(Math.acos(arg.todouble()));
case 1: return valueOf(Math.asin(arg.todouble())); case 1: return valueOf(Math.asin(arg.todouble()));
case 2: return valueOf(Math.atan(arg.todouble())); case 2: return valueOf(Math.atan(arg.todouble()));
@@ -62,15 +61,13 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
} }
return NIL; return NIL;
} }
public static class J2seMathFunc2 extends TwoArgFunction { public LuaValue oncall2(int opcode, LuaValue arg1, LuaValue arg2) {
public LuaValue call(LuaValue arg1,LuaValue arg2) { switch ( opcode ) {
switch ( opcode ) { case 0: return valueOf(Math.atan2(arg1.todouble(), arg2.todouble()));
case 0: return valueOf(Math.atan2(arg1.todouble(), arg2.todouble())); case 1: return valueOf(Math.pow(arg1.todouble(), arg2.todouble()));
case 1: return valueOf(Math.pow(arg1.todouble(), arg2.todouble()));
}
return NIL;
} }
return NIL;
} }
/** Faster, better version of pow() used by arithmetic operator ^ */ /** Faster, better version of pow() used by arithmetic operator ^ */

View File

@@ -43,23 +43,20 @@ import org.luaj.vm2.LuaUserdata;
import org.luaj.vm2.LuaValue; import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs; import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.LibFunction; import org.luaj.vm2.lib.LibFunction;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.ThreeArgFunction; import org.luaj.vm2.lib.ThreeArgFunction;
import org.luaj.vm2.lib.TwoArgFunction; import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction; import org.luaj.vm2.lib.VarArgFunction;
public class LuajavaLib extends VarArgFunction { public class LuajavaLib extends OneArgFunction {
private static final String LIBNAME = "luajava"; private static final int BINDCLASS = 0;
private static final int NEWINSTANCE = 1;
private static final int INIT = 0; private static final int NEW = 2;
private static final int BINDCLASS = 1; private static final int CREATEPROXY = 3;
private static final int NEWINSTANCE = 2; private static final int LOADLIB = 4;
private static final int NEW = 3;
private static final int CREATEPROXY = 4;
private static final int LOADLIB = 5;
private static final String[] NAMES = { private static final String[] NAMES = {
LIBNAME,
"bindClass", "bindClass",
"newInstance", "newInstance",
"new", "new",
@@ -73,18 +70,18 @@ public class LuajavaLib extends VarArgFunction {
} }
public LuajavaLib() { public LuajavaLib() {
name = LIBNAME;
opcode = INIT;
} }
public Varargs invoke(final Varargs args) { 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) {
try { try {
switch ( opcode ) { switch ( opcode ) {
case INIT: {
LuaTable t = new LuaTable(0,8);
LibFunction.bind( t, this.getClass(), NAMES );
return t;
}
case BINDCLASS: { case BINDCLASS: {
final Class clazz = Class.forName(args.checkString(1)); final Class clazz = Class.forName(args.checkString(1));
return toUserdata( clazz, clazz ); return toUserdata( clazz, clazz );

View File

@@ -55,7 +55,7 @@ public class LuaOperationsTest extends TestCase {
private final LuaValue stringlong = LuaValue.valueOf(samplestringlong); private final LuaValue stringlong = LuaValue.valueOf(samplestringlong);
private final LuaValue stringdouble = LuaValue.valueOf(samplestringdouble); private final LuaValue stringdouble = LuaValue.valueOf(samplestringdouble);
private final LuaTable table = LuaValue.listOf( new LuaValue[] { LuaValue.valueOf("aaa"), LuaValue.valueOf("bbb") } ); private final LuaTable table = LuaValue.listOf( new LuaValue[] { LuaValue.valueOf("aaa"), LuaValue.valueOf("bbb") } );
private final LuaFunction somefunc = new ZeroArgFunction("sample",0,table) { public LuaValue call() { return NONE;}}; private final LuaValue somefunc = new ZeroArgFunction(table) { public LuaValue call() { return NONE;}};
private final LuaThread thread = new LuaThread(somefunc,table); private final LuaThread thread = new LuaThread(somefunc,table);
private final Prototype proto = new Prototype(); private final Prototype proto = new Prototype();
private final LuaClosure someclosure = new LuaClosure(proto,table); private final LuaClosure someclosure = new LuaClosure(proto,table);
@@ -207,7 +207,7 @@ public class LuaOperationsTest extends TestCase {
// function tests // function tests
{ {
LuaFunction f = new ZeroArgFunction("f",0,_G) { public LuaValue call() { return env.get("a");}}; LuaFunction f = new ZeroArgFunction(_G) { public LuaValue call() { return env.get("a");}};
assertEquals( aaa, f.call() ); assertEquals( aaa, f.call() );
f.setfenv(newenv); f.setfenv(newenv);
assertEquals( newenv, f.getfenv() ); assertEquals( newenv, f.getfenv() );

View File

@@ -70,9 +70,9 @@ public class ScriptDrivenTest extends TestCase {
// override print() // override print()
final ByteArrayOutputStream output = new ByteArrayOutputStream(); final ByteArrayOutputStream output = new ByteArrayOutputStream();
final PrintStream oldps = BaseLib.STDOUT; final PrintStream oldps = BaseLib.instance.STDOUT;
final PrintStream ps = new PrintStream( output ); final PrintStream ps = new PrintStream( output );
BaseLib.STDOUT = ps; BaseLib.instance.STDOUT = ps;
// run the script // run the script
try { try {
@@ -85,7 +85,7 @@ public class ScriptDrivenTest extends TestCase {
assertEquals(expectedOutput, actualOutput); assertEquals(expectedOutput, actualOutput);
} finally { } finally {
BaseLib.STDOUT = oldps; BaseLib.instance.STDOUT = oldps;
ps.close(); ps.close();
} }
} catch ( IOException ioe ) { } catch ( IOException ioe ) {