Lua 5.2 compatibility updates to VM and base and package libraries.
This commit is contained in:
@@ -373,11 +373,12 @@ public class LoadState {
|
|||||||
* @param firstByte the first byte of the input stream
|
* @param firstByte the first byte of the input stream
|
||||||
* @param stream InputStream to read, after having read the first byte already
|
* @param stream InputStream to read, after having read the first byte already
|
||||||
* @param name Name to apply to the loaded chunk
|
* @param name Name to apply to the loaded chunk
|
||||||
|
* @param mode "b" for binary only, "t" for text only, "bt" for binary or text.
|
||||||
* @return {@link Prototype} that was loaded
|
* @return {@link Prototype} that was loaded
|
||||||
* @throws IllegalArgumentException if the signature is bac
|
* @throws IllegalArgumentException if the signature is bac
|
||||||
* @throws IOException if an IOException occurs
|
* @throws IOException if an IOException occurs
|
||||||
*/
|
*/
|
||||||
public static LuaFunction load( InputStream stream, String name, LuaValue env ) throws IOException {
|
public static LuaFunction load( InputStream stream, String name, String mode, LuaValue env ) throws IOException {
|
||||||
if ( compiler != null )
|
if ( compiler != null )
|
||||||
return compiler.load(stream, name, env);
|
return compiler.load(stream, name, env);
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -420,6 +420,10 @@ public class LuaString extends LuaValue {
|
|||||||
return m_length;
|
return m_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int rawlen() {
|
||||||
|
return m_length;
|
||||||
|
}
|
||||||
|
|
||||||
public int luaByte(int index) {
|
public int luaByte(int index) {
|
||||||
return m_bytes[m_offset + index] & 0x0FF;
|
return m_bytes[m_offset + index] & 0x0FF;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -393,7 +393,11 @@ public class LuaTable extends LuaValue {
|
|||||||
public LuaValue len() {
|
public LuaValue len() {
|
||||||
return LuaInteger.valueOf(length());
|
return LuaInteger.valueOf(length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int rawlen() {
|
||||||
|
return length();
|
||||||
|
}
|
||||||
|
|
||||||
/** Return table.maxn() as defined by lua 5.0.
|
/** Return table.maxn() as defined by lua 5.0.
|
||||||
* <p>
|
* <p>
|
||||||
* Provided for compatibility, not a scalable operation.
|
* Provided for compatibility, not a scalable operation.
|
||||||
|
|||||||
@@ -2014,6 +2014,12 @@ public class LuaValue extends Varargs {
|
|||||||
*/
|
*/
|
||||||
public int length() { return len().toint(); }
|
public int length() { return len().toint(); }
|
||||||
|
|
||||||
|
/** Get raw length of table or string without metatag processing.
|
||||||
|
* @return the length of the table or string.
|
||||||
|
* @throws LuaError if {@code this} is not a table or string.
|
||||||
|
*/
|
||||||
|
public int rawlen() { typerror("table or string"); return 0; }
|
||||||
|
|
||||||
/** Implementation of lua 5.0 getn() function.
|
/** Implementation of lua 5.0 getn() function.
|
||||||
* @return value of getn() as defined in lua 5.0 spec if {@code this} is a {@link LuaTable}
|
* @return value of getn() as defined in lua 5.0 spec if {@code this} is a {@link LuaTable}
|
||||||
* @throws LuaError if {@code this} is not a {@link LuaTable}
|
* @throws LuaError if {@code this} is not a {@link LuaTable}
|
||||||
|
|||||||
@@ -89,30 +89,29 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
private LuaValue next;
|
private LuaValue next;
|
||||||
private LuaValue inext;
|
private LuaValue inext;
|
||||||
|
|
||||||
|
private static final String[] LIB1_KEYS = {
|
||||||
|
"getmetatable", // ( object ) -> table
|
||||||
|
"rawlen", // (v) -> value
|
||||||
|
"tostring", // (e) -> value
|
||||||
|
"type", // (v) -> value
|
||||||
|
};
|
||||||
private static final String[] LIB2_KEYS = {
|
private static final String[] LIB2_KEYS = {
|
||||||
"collectgarbage", // ( opt [,arg] ) -> value
|
"collectgarbage", // ( opt [,arg] ) -> value
|
||||||
"error", // ( message [,level] ) -> ERR
|
"error", // ( message [,level] ) -> ERR
|
||||||
"setfenv", // (f, table) -> void
|
"rawequal", // (v1, v2) -> boolean
|
||||||
|
"rawget", // (table, index) -> value
|
||||||
};
|
};
|
||||||
private static final String[] LIBV_KEYS = {
|
private static final String[] LIBV_KEYS = {
|
||||||
"assert", // ( v [,message] ) -> v, message | ERR
|
"assert", // ( v [,message] ) -> v, message | ERR
|
||||||
"dofile", // ( filename ) -> result1, ...
|
"dofile", // ( filename ) -> result1, ...
|
||||||
"getfenv", // ( [f] ) -> env
|
"load", // ( ld [, source [, mode [, env]]] ) -> chunk | nil, msg
|
||||||
"getmetatable", // ( object ) -> table
|
"loadfile", // ( [filename [, mode [, env]]] ) -> chunk | nil, msg
|
||||||
"load", // ( func [,chunkname] ) -> chunk | nil, msg
|
|
||||||
"loadfile", // ( [filename] ) -> chunk | nil, msg
|
|
||||||
"loadstring", // ( string [,chunkname] ) -> chunk | nil, msg
|
|
||||||
"pcall", // (f, arg1, ...) -> status, result1, ...
|
"pcall", // (f, arg1, ...) -> status, result1, ...
|
||||||
"xpcall", // (f, err) -> result1, ...
|
"xpcall", // (f, err) -> result1, ...
|
||||||
"print", // (...) -> void
|
"print", // (...) -> void
|
||||||
"select", // (f, ...) -> value1, ...
|
"select", // (f, ...) -> value1, ...
|
||||||
"unpack", // (list [,i [,j]]) -> result1, ...
|
|
||||||
"type", // (v) -> value
|
|
||||||
"rawequal", // (v1, v2) -> boolean
|
|
||||||
"rawget", // (table, index) -> value
|
|
||||||
"rawset", // (table, index, value) -> table
|
"rawset", // (table, index, value) -> table
|
||||||
"setmetatable", // (table, metatable) -> table
|
"setmetatable", // (table, metatable) -> table
|
||||||
"tostring", // (e) -> value
|
|
||||||
"tonumber", // (e [,base]) -> value
|
"tonumber", // (e [,base]) -> value
|
||||||
"pairs", // "pairs" (t) -> iter-func, t, nil
|
"pairs", // "pairs" (t) -> iter-func, t, nil
|
||||||
"ipairs", // "ipairs", // (t) -> iter-func, t, 0
|
"ipairs", // "ipairs", // (t) -> iter-func, t, 0
|
||||||
@@ -130,6 +129,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
public LuaValue call(LuaValue arg) {
|
public LuaValue call(LuaValue arg) {
|
||||||
env.set( "_G", env );
|
env.set( "_G", env );
|
||||||
env.set( "_VERSION", Lua._VERSION );
|
env.set( "_VERSION", Lua._VERSION );
|
||||||
|
bind( env, BaseLib1.class, LIB1_KEYS );
|
||||||
bind( env, BaseLib2.class, LIB2_KEYS );
|
bind( env, BaseLib2.class, LIB2_KEYS );
|
||||||
bind( env, BaseLibV.class, LIBV_KEYS );
|
bind( env, BaseLibV.class, LIBV_KEYS );
|
||||||
|
|
||||||
@@ -156,12 +156,42 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
return c.getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
|
return c.getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final class BaseLib1 extends OneArgFunction {
|
||||||
|
public LuaValue call(LuaValue arg) {
|
||||||
|
switch ( opcode ) {
|
||||||
|
case 0: // "getmetatable", // ( object ) -> table
|
||||||
|
{
|
||||||
|
LuaValue mt = arg.getmetatable();
|
||||||
|
return mt!=null? mt.rawget(METATABLE).optvalue(mt): NIL;
|
||||||
|
}
|
||||||
|
case 1: // "rawlen", // (v) -> value
|
||||||
|
{
|
||||||
|
return valueOf(arg.rawlen());
|
||||||
|
}
|
||||||
|
case 2: // "tostring", // (e) -> value
|
||||||
|
{
|
||||||
|
LuaValue h = arg.metatag(TOSTRING);
|
||||||
|
if ( ! h.isnil() )
|
||||||
|
return h.call(arg);
|
||||||
|
LuaValue v = arg.tostring();
|
||||||
|
if ( ! v.isnil() )
|
||||||
|
return v;
|
||||||
|
return valueOf(arg.tojstring());
|
||||||
|
}
|
||||||
|
case 3: // "type", // (v) -> value
|
||||||
|
{
|
||||||
|
return valueOf(arg.typename());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static final class BaseLib2 extends TwoArgFunction {
|
static final class BaseLib2 extends TwoArgFunction {
|
||||||
public LuaValue call(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.checkjstring();
|
String s = arg1.checkjstring();
|
||||||
int result = 0;
|
|
||||||
if ( "collect".equals(s) ) {
|
if ( "collect".equals(s) ) {
|
||||||
System.gc();
|
System.gc();
|
||||||
return ZERO;
|
return ZERO;
|
||||||
@@ -173,35 +203,19 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
System.gc();
|
System.gc();
|
||||||
return LuaValue.TRUE;
|
return LuaValue.TRUE;
|
||||||
} else {
|
} else {
|
||||||
this.argerror(1, "gc op");
|
this.argerror("gc op");
|
||||||
}
|
}
|
||||||
return NIL;
|
return NIL;
|
||||||
case 1: // "error", // ( message [,level] ) -> ERR
|
case 1: // "error", // ( message [,level] ) -> ERR
|
||||||
throw new LuaError( arg1.isnil()? null: arg1.tojstring(), arg2.optint(1) );
|
throw new LuaError( arg1.isnil()? null: arg1.tojstring(), arg2.optint(1) );
|
||||||
case 2: { // "setfenv", // (f, table) -> void
|
case 2: // "rawequal", // (v1, v2) -> boolean
|
||||||
LuaTable t = arg2.checktable();
|
return valueOf(arg1.raweq(arg2));
|
||||||
LuaValue f = getfenvobj(arg1);
|
case 3: // "rawget", // (table, index) -> value
|
||||||
if ( ! f.isfunction() && ! f.isclosure() )
|
return arg1.rawget(arg2);
|
||||||
error("'setfenv' cannot change environment of given object");
|
|
||||||
f.setfenv(t);
|
|
||||||
return f.isthread()? NONE: f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LuaValue getfenvobj(LuaValue arg) {
|
|
||||||
if ( arg.isfunction() )
|
|
||||||
return arg;
|
|
||||||
int level = arg.optint(1);
|
|
||||||
arg.argcheck(level>=0, 1, "level must be non-negative");
|
|
||||||
if ( level == 0 )
|
|
||||||
return LuaThread.getRunning();
|
|
||||||
LuaValue f = LuaThread.getCallstackFunction(level);
|
|
||||||
arg.argcheck(f != null, 1, "invalid level");
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class BaseLibV extends VarArgFunction {
|
static final class BaseLibV extends VarArgFunction {
|
||||||
public BaseLib baselib;
|
public BaseLib baselib;
|
||||||
@@ -213,41 +227,34 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
return args;
|
return args;
|
||||||
case 1: // "dofile", // ( filename ) -> result1, ...
|
case 1: // "dofile", // ( filename ) -> result1, ...
|
||||||
{
|
{
|
||||||
Varargs v = args.isnil(1)?
|
args.argcheck(args.isstring(1) || args.isnil(1), 1, "filename must be string or nil");
|
||||||
BaseLib.loadStream( baselib.STDIN, "=stdin" ):
|
String filename = args.isstring(1)? args.tojstring(1): null;
|
||||||
BaseLib.loadFile( args.checkjstring(1) );
|
Varargs v = filename == null?
|
||||||
|
BaseLib.loadStream( baselib.STDIN, "=stdin", "bt", LuaThread.getGlobals() ):
|
||||||
|
BaseLib.loadFile( args.checkjstring(1), "bt", LuaThread.getGlobals() );
|
||||||
return v.isnil(1)? error(v.tojstring(2)): v.arg1().invoke();
|
return v.isnil(1)? error(v.tojstring(2)): v.arg1().invoke();
|
||||||
}
|
}
|
||||||
case 2: // "getfenv", // ( [f] ) -> env
|
case 2: // "load", // ( ld [, source [, mode [, env]]] ) -> chunk | nil, msg
|
||||||
{
|
{
|
||||||
LuaValue f = getfenvobj(args.arg1());
|
LuaValue ld = args.arg1();
|
||||||
LuaValue e = f.getfenv();
|
args.argcheck(ld.isstring() || ld.isfunction(), 1, "ld must be string or function");
|
||||||
return e!=null? e: NIL;
|
String source = args.optjstring(2, ld.isstring()? ld.tojstring(): "=(load)");
|
||||||
|
String mode = args.optjstring(3, "bt");
|
||||||
|
LuaValue env = args.optvalue(4, LuaThread.getGlobals());
|
||||||
|
return BaseLib.loadStream(ld.isstring()? ld.strvalue().toInputStream():
|
||||||
|
new StringInputStream(ld.checkfunction()), source, mode, env);
|
||||||
}
|
}
|
||||||
case 3: // "getmetatable", // ( object ) -> table
|
case 3: // "loadfile", // ( [filename [, mode [, env]]] ) -> chunk | nil, msg
|
||||||
{
|
{
|
||||||
LuaValue mt = args.checkvalue(1).getmetatable();
|
args.argcheck(args.isstring(1) || args.isnil(1), 1, "filename must be string or nil");
|
||||||
return mt!=null? mt.rawget(METATABLE).optvalue(mt): NIL;
|
String filename = args.isstring(1)? args.tojstring(1): null;
|
||||||
|
String mode = args.optjstring(2, "bt");
|
||||||
|
LuaValue env = args.optvalue(3, LuaThread.getGlobals());
|
||||||
|
return filename == null?
|
||||||
|
BaseLib.loadStream( baselib.STDIN, "=stdin", mode, env ):
|
||||||
|
BaseLib.loadFile( filename, mode, env );
|
||||||
}
|
}
|
||||||
case 4: // "load", // ( func [,chunkname] ) -> chunk | nil, msg
|
case 4: // "pcall", // (f, arg1, ...) -> status, result1, ...
|
||||||
{
|
|
||||||
LuaValue func = args.checkfunction(1);
|
|
||||||
String chunkname = args.optjstring(2, "function");
|
|
||||||
return BaseLib.loadStream(new StringInputStream(func), chunkname);
|
|
||||||
}
|
|
||||||
case 5: // "loadfile", // ( [filename] ) -> chunk | nil, msg
|
|
||||||
{
|
|
||||||
return args.isnil(1)?
|
|
||||||
BaseLib.loadStream( baselib.STDIN, "stdin" ):
|
|
||||||
BaseLib.loadFile( args.checkjstring(1) );
|
|
||||||
}
|
|
||||||
case 6: // "loadstring", // ( string [,chunkname] ) -> chunk | nil, msg
|
|
||||||
{
|
|
||||||
LuaString script = args.checkstring(1);
|
|
||||||
String chunkname = args.optjstring(2, "string");
|
|
||||||
return BaseLib.loadStream(script.toInputStream(),chunkname);
|
|
||||||
}
|
|
||||||
case 7: // "pcall", // (f, arg1, ...) -> status, result1, ...
|
|
||||||
{
|
{
|
||||||
LuaValue func = args.checkvalue(1);
|
LuaValue func = args.checkvalue(1);
|
||||||
LuaThread.CallStack cs = LuaThread.onCall(this);
|
LuaThread.CallStack cs = LuaThread.onCall(this);
|
||||||
@@ -257,7 +264,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
cs.onReturn();
|
cs.onReturn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 8: // "xpcall", // (f, err) -> result1, ...
|
case 5: // "xpcall", // (f, err) -> result1, ...
|
||||||
{
|
{
|
||||||
LuaThread.CallStack cs = LuaThread.onCall(this);
|
LuaThread.CallStack cs = LuaThread.onCall(this);
|
||||||
try {
|
try {
|
||||||
@@ -266,7 +273,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
cs.onReturn();
|
cs.onReturn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 9: // "print", // (...) -> void
|
case 6: // "print", // (...) -> void
|
||||||
{
|
{
|
||||||
LuaValue tostring = LuaThread.getGlobals().get("tostring");
|
LuaValue tostring = LuaThread.getGlobals().get("tostring");
|
||||||
for ( int i=1, n=args.narg(); i<=n; i++ ) {
|
for ( int i=1, n=args.narg(); i<=n; i++ ) {
|
||||||
@@ -278,7 +285,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
baselib.STDOUT.println();
|
baselib.STDOUT.println();
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
case 10: // "select", // (f, ...) -> value1, ...
|
case 7: // "select", // (f, ...) -> value1, ...
|
||||||
{
|
{
|
||||||
int n = args.narg()-1;
|
int n = args.narg()-1;
|
||||||
if ( args.arg1().equals(valueOf("#")) )
|
if ( args.arg1().equals(valueOf("#")) )
|
||||||
@@ -288,34 +295,12 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
argerror(1,"index out of range");
|
argerror(1,"index out of range");
|
||||||
return args.subargs(i<0? n+i+2: i+1);
|
return args.subargs(i<0? n+i+2: i+1);
|
||||||
}
|
}
|
||||||
case 11: // "unpack", // (list [,i [,j]]) -> result1, ...
|
case 8: { // "rawset", // (table, index, value) -> table
|
||||||
{
|
|
||||||
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 12: // "type", // (v) -> value
|
|
||||||
return valueOf(args.checkvalue(1).typename());
|
|
||||||
case 13: // "rawequal", // (v1, v2) -> boolean
|
|
||||||
return valueOf(args.checkvalue(1) == args.checkvalue(2));
|
|
||||||
case 14: // "rawget", // (table, index) -> value
|
|
||||||
return args.checktable(1).rawget(args.checkvalue(2));
|
|
||||||
case 15: { // "rawset", // (table, index, value) -> table
|
|
||||||
LuaTable t = args.checktable(1);
|
LuaTable t = args.checktable(1);
|
||||||
t.rawset(args.checknotnil(2), args.checkvalue(3));
|
t.rawset(args.checknotnil(2), args.checkvalue(3));
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
case 16: { // "setmetatable", // (table, metatable) -> table
|
case 9: { // "setmetatable", // (table, metatable) -> table
|
||||||
final LuaValue t = args.arg1();
|
final LuaValue t = args.arg1();
|
||||||
final LuaValue mt0 = t.getmetatable();
|
final LuaValue mt0 = t.getmetatable();
|
||||||
if ( mt0!=null && !mt0.rawget(METATABLE).isnil() )
|
if ( mt0!=null && !mt0.rawget(METATABLE).isnil() )
|
||||||
@@ -323,17 +308,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
final LuaValue mt = args.checkvalue(2);
|
final LuaValue mt = args.checkvalue(2);
|
||||||
return t.setmetatable(mt.isnil()? null: mt.checktable());
|
return t.setmetatable(mt.isnil()? null: mt.checktable());
|
||||||
}
|
}
|
||||||
case 17: { // "tostring", // (e) -> value
|
case 10: { // "tonumber", // (e [,base]) -> value
|
||||||
LuaValue arg = args.checkvalue(1);
|
|
||||||
LuaValue h = arg.metatag(TOSTRING);
|
|
||||||
if ( ! h.isnil() )
|
|
||||||
return h.call(arg);
|
|
||||||
LuaValue v = arg.tostring();
|
|
||||||
if ( ! v.isnil() )
|
|
||||||
return v;
|
|
||||||
return valueOf(arg.tojstring());
|
|
||||||
}
|
|
||||||
case 18: { // "tonumber", // (e [,base]) -> value
|
|
||||||
LuaValue arg1 = args.checkvalue(1);
|
LuaValue arg1 = args.checkvalue(1);
|
||||||
final int base = args.optint(2,10);
|
final int base = args.optint(2,10);
|
||||||
if (base == 10) { /* standard conversion */
|
if (base == 10) { /* standard conversion */
|
||||||
@@ -344,13 +319,13 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
return arg1.checkstring().tonumber(base);
|
return arg1.checkstring().tonumber(base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 19: // "pairs" (t) -> iter-func, t, nil
|
case 11: // "pairs" (t) -> iter-func, t, nil
|
||||||
return varargsOf( baselib.next, args.checktable(1), NIL );
|
return varargsOf( baselib.next, args.checktable(1), NIL );
|
||||||
case 20: // "ipairs", // (t) -> iter-func, t, 0
|
case 12: // "ipairs", // (t) -> iter-func, t, 0
|
||||||
return varargsOf( baselib.inext, args.checktable(1), ZERO );
|
return varargsOf( baselib.inext, args.checktable(1), ZERO );
|
||||||
case 21: // "next" ( table, [index] ) -> next-index, next-value
|
case 13: // "next" ( table, [index] ) -> next-index, next-value
|
||||||
return args.checktable(1).next(args.arg(2));
|
return args.checktable(1).next(args.arg(2));
|
||||||
case 22: // "inext" ( table, [int-index] ) -> next-index, next-value
|
case 14: // "inext" ( table, [int-index] ) -> next-index, next-value
|
||||||
return args.checktable(1).inext(args.arg(2));
|
return args.checktable(1).inext(args.arg(2));
|
||||||
}
|
}
|
||||||
return NONE;
|
return NONE;
|
||||||
@@ -376,14 +351,16 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Load from a named file, returning the chunk or nil,error of can't load
|
* Load from a named file, returning the chunk or nil,error of can't load
|
||||||
|
* @param env
|
||||||
|
* @param mode
|
||||||
* @return Varargs containing chunk, or NIL,error-text on error
|
* @return Varargs containing chunk, or NIL,error-text on error
|
||||||
*/
|
*/
|
||||||
public static Varargs loadFile(String filename) {
|
public static Varargs loadFile(String filename, String mode, LuaValue env) {
|
||||||
InputStream is = FINDER.findResource(filename);
|
InputStream is = FINDER.findResource(filename);
|
||||||
if ( is == null )
|
if ( is == null )
|
||||||
return varargsOf(NIL, valueOf("cannot open "+filename+": No such file or directory"));
|
return varargsOf(NIL, valueOf("cannot open "+filename+": No such file or directory"));
|
||||||
try {
|
try {
|
||||||
return loadStream(is, "@"+filename);
|
return loadStream(is, "@"+filename, mode, env);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
is.close();
|
is.close();
|
||||||
@@ -393,11 +370,11 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Varargs loadStream(InputStream is, String chunkname) {
|
public static Varargs loadStream(InputStream is, String chunkname, String mode, LuaValue env) {
|
||||||
try {
|
try {
|
||||||
if ( is == null )
|
if ( is == null )
|
||||||
return varargsOf(NIL, valueOf("not found: "+chunkname));
|
return varargsOf(NIL, valueOf("not found: "+chunkname));
|
||||||
return LoadState.load(is, chunkname, LuaThread.getGlobals());
|
return LoadState.load(is, chunkname, mode, env);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,14 +76,12 @@ public class DebugLib extends VarArgFunction {
|
|||||||
|
|
||||||
static final String[] NAMES = {
|
static final String[] NAMES = {
|
||||||
"debug",
|
"debug",
|
||||||
"getfenv",
|
|
||||||
"gethook",
|
"gethook",
|
||||||
"getinfo",
|
"getinfo",
|
||||||
"getlocal",
|
"getlocal",
|
||||||
"getmetatable",
|
"getmetatable",
|
||||||
"getregistry",
|
"getregistry",
|
||||||
"getupvalue",
|
"getupvalue",
|
||||||
"setfenv",
|
|
||||||
"sethook",
|
"sethook",
|
||||||
"setlocal",
|
"setlocal",
|
||||||
"setmetatable",
|
"setmetatable",
|
||||||
@@ -93,19 +91,17 @@ public class DebugLib extends VarArgFunction {
|
|||||||
|
|
||||||
private static final int INIT = 0;
|
private static final int INIT = 0;
|
||||||
private static final int DEBUG = 1;
|
private static final int DEBUG = 1;
|
||||||
private static final int GETFENV = 2;
|
private static final int GETHOOK = 2;
|
||||||
private static final int GETHOOK = 3;
|
private static final int GETINFO = 3;
|
||||||
private static final int GETINFO = 4;
|
private static final int GETLOCAL = 4;
|
||||||
private static final int GETLOCAL = 5;
|
private static final int GETMETATABLE = 5;
|
||||||
private static final int GETMETATABLE = 6;
|
private static final int GETREGISTRY = 6;
|
||||||
private static final int GETREGISTRY = 7;
|
private static final int GETUPVALUE = 7;
|
||||||
private static final int GETUPVALUE = 8;
|
private static final int SETHOOK = 8;
|
||||||
private static final int SETFENV = 9;
|
private static final int SETLOCAL = 9;
|
||||||
private static final int SETHOOK = 10;
|
private static final int SETMETATABLE = 10;
|
||||||
private static final int SETLOCAL = 11;
|
private static final int SETUPVALUE = 11;
|
||||||
private static final int SETMETATABLE = 12;
|
private static final int TRACEBACK = 12;
|
||||||
private static final int SETUPVALUE = 13;
|
|
||||||
private static final int TRACEBACK = 14;
|
|
||||||
|
|
||||||
/* maximum stack for a Lua function */
|
/* maximum stack for a Lua function */
|
||||||
private static final int MAXSTACK = 250;
|
private static final int MAXSTACK = 250;
|
||||||
@@ -153,14 +149,12 @@ public class DebugLib extends VarArgFunction {
|
|||||||
switch ( opcode ) {
|
switch ( opcode ) {
|
||||||
case INIT: return init();
|
case INIT: return init();
|
||||||
case DEBUG: return _debug(args);
|
case DEBUG: return _debug(args);
|
||||||
case GETFENV: return _getfenv(args);
|
|
||||||
case GETHOOK: return _gethook(args);
|
case GETHOOK: return _gethook(args);
|
||||||
case GETINFO: return _getinfo(args,this);
|
case GETINFO: return _getinfo(args,this);
|
||||||
case GETLOCAL: return _getlocal(args);
|
case GETLOCAL: return _getlocal(args);
|
||||||
case GETMETATABLE: return _getmetatable(args);
|
case GETMETATABLE: return _getmetatable(args);
|
||||||
case GETREGISTRY: return _getregistry(args);
|
case GETREGISTRY: return _getregistry(args);
|
||||||
case GETUPVALUE: return _getupvalue(args);
|
case GETUPVALUE: return _getupvalue(args);
|
||||||
case SETFENV: return _setfenv(args);
|
|
||||||
case SETHOOK: return _sethook(args);
|
case SETHOOK: return _sethook(args);
|
||||||
case SETLOCAL: return _setlocal(args);
|
case SETLOCAL: return _setlocal(args);
|
||||||
case SETMETATABLE: return _setmetatable(args);
|
case SETMETATABLE: return _setmetatable(args);
|
||||||
@@ -438,19 +432,6 @@ public class DebugLib extends VarArgFunction {
|
|||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Varargs _getfenv(Varargs args) {
|
|
||||||
LuaValue object = args.arg1();
|
|
||||||
LuaValue env = object.getfenv();
|
|
||||||
return env!=null? env: LuaValue.NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Varargs _setfenv(Varargs args) {
|
|
||||||
LuaValue object = args.arg1();
|
|
||||||
LuaTable table = args.checktable(2);
|
|
||||||
object.setfenv(table);
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static Varargs _getinfo(Varargs args, LuaValue level0func) {
|
protected static Varargs _getinfo(Varargs args, LuaValue level0func) {
|
||||||
int a=1;
|
int a=1;
|
||||||
LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning();
|
LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning();
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import org.luaj.vm2.Varargs;
|
|||||||
* <li>atan</li>
|
* <li>atan</li>
|
||||||
* <li>cosh</li>
|
* <li>cosh</li>
|
||||||
* <li>log</li>
|
* <li>log</li>
|
||||||
* <li>log10</li>
|
|
||||||
* <li>sinh</li>
|
* <li>sinh</li>
|
||||||
* <li>tanh</li>
|
* <li>tanh</li>
|
||||||
* <li>atan2</li>
|
* <li>atan2</li>
|
||||||
|
|||||||
@@ -76,51 +76,47 @@ public class PackageLib extends OneArgFunction {
|
|||||||
public static PackageLib instance;
|
public static PackageLib instance;
|
||||||
|
|
||||||
/** Loader that loads from preload table if found there */
|
/** Loader that loads from preload table if found there */
|
||||||
public LuaValue preload_loader;
|
public LuaValue preload_searcher;
|
||||||
|
|
||||||
/** Loader that loads as a lua script using the LUA_PATH */
|
/** Loader that loads as a lua script using the LUA_PATH */
|
||||||
public LuaValue lua_loader;
|
public LuaValue lua_searcher;
|
||||||
|
|
||||||
/** Loader that loads as a Java class. Class must have public constructor and be a LuaValue */
|
/** Loader that loads as a Java class. Class must have public constructor and be a LuaValue */
|
||||||
public LuaValue java_loader;
|
public LuaValue java_searcher;
|
||||||
|
|
||||||
private static final LuaString _M = valueOf("_M");
|
private static final LuaString _LOADED = valueOf("loaded");
|
||||||
private static final LuaString _NAME = valueOf("_NAME");
|
private static final LuaString _LOADLIB = valueOf("loadlib");
|
||||||
private static final LuaString _PACKAGE = valueOf("_PACKAGE");
|
private static final LuaString _PRELOAD = valueOf("preload");
|
||||||
private static final LuaString _DOT = valueOf(".");
|
private static final LuaString _PATH = valueOf("path");
|
||||||
private static final LuaString _LOADERS = valueOf("loaders");
|
private static final LuaString _SEARCHERS = valueOf("searchers");
|
||||||
private static final LuaString _LOADED = valueOf("loaded");
|
private static final LuaString _SEARCHPATH = valueOf("searchpath");
|
||||||
private static final LuaString _LOADLIB = valueOf("loadlib");
|
private static final LuaString _SENTINEL = valueOf("\u0001");
|
||||||
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 _SENTINEL = valueOf("\u0001");
|
|
||||||
|
|
||||||
private static final int OP_MODULE = 0;
|
|
||||||
private static final int OP_REQUIRE = 1;
|
|
||||||
private static final int OP_LOADLIB = 2;
|
|
||||||
private static final int OP_SEEALL = 3;
|
|
||||||
private static final int OP_PRELOAD_LOADER = 4;
|
|
||||||
private static final int OP_LUA_LOADER = 5;
|
|
||||||
private static final int OP_JAVA_LOADER = 6;
|
|
||||||
|
|
||||||
|
private static final int OP_REQUIRE = 0;
|
||||||
|
private static final int OP_LOADLIB = 1;
|
||||||
|
private static final int OP_SEARCHPATH = 2;
|
||||||
|
private static final int OP_PRELOAD_SEARCHER = 3;
|
||||||
|
private static final int OP_LUA_SEARCHER = 4;
|
||||||
|
private static final int OP_JAVA_SEARCHER = 5;
|
||||||
|
|
||||||
|
private static final String FILE_SEP = System.getProperty("file.separator");
|
||||||
|
|
||||||
public PackageLib() {
|
public PackageLib() {
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaValue call(LuaValue arg) {
|
public LuaValue call(LuaValue arg) {
|
||||||
env.set("require", new PkgLib1(env,"require",OP_REQUIRE,this));
|
env.set("require", new PkgLib1(env,"require",OP_REQUIRE,this));
|
||||||
env.set("module", new PkgLibV(env,"module",OP_MODULE,this));
|
|
||||||
env.set( "package", PACKAGE=tableOf( new LuaValue[] {
|
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 PkgLibV(env,"loadlib",OP_LOADLIB,this),
|
_LOADLIB, new PkgLibV(env,"loadlib",OP_LOADLIB,this),
|
||||||
_SEEALL, new PkgLib1(env,"seeall",OP_SEEALL,this),
|
_SEARCHPATH, new PkgLibV(env,"searchpath",OP_SEARCHPATH,this),
|
||||||
_LOADERS, listOf(new LuaValue[] {
|
_SEARCHERS, listOf(new LuaValue[] {
|
||||||
preload_loader = new PkgLibV(env,"preload_loader", OP_PRELOAD_LOADER,this),
|
preload_searcher = new PkgLibV(env,"preload_searcher", OP_PRELOAD_SEARCHER,this),
|
||||||
lua_loader = new PkgLibV(env,"lua_loader", OP_LUA_LOADER,this),
|
lua_searcher = new PkgLibV(env,"lua_searcher", OP_LUA_SEARCHER,this),
|
||||||
java_loader = new PkgLibV(env,"java_loader", OP_JAVA_LOADER,this),
|
java_searcher = new PkgLibV(env,"java_searcher", OP_JAVA_SEARCHER,this),
|
||||||
}) }) );
|
}) }) );
|
||||||
LOADED.set("package", PACKAGE);
|
LOADED.set("package", PACKAGE);
|
||||||
return env;
|
return env;
|
||||||
@@ -138,14 +134,6 @@ public class PackageLib extends OneArgFunction {
|
|||||||
switch ( opcode ) {
|
switch ( opcode ) {
|
||||||
case OP_REQUIRE:
|
case OP_REQUIRE:
|
||||||
return lib.require(arg);
|
return lib.require(arg);
|
||||||
case OP_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;
|
||||||
}
|
}
|
||||||
@@ -161,18 +149,24 @@ public class PackageLib extends OneArgFunction {
|
|||||||
}
|
}
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
switch ( opcode ) {
|
switch ( opcode ) {
|
||||||
case OP_MODULE:
|
case OP_LOADLIB: {
|
||||||
return lib.module(args);
|
|
||||||
case OP_LOADLIB:
|
|
||||||
return loadlib(args);
|
return loadlib(args);
|
||||||
case OP_PRELOAD_LOADER: {
|
|
||||||
return lib.loader_preload(args);
|
|
||||||
}
|
}
|
||||||
case OP_LUA_LOADER: {
|
case OP_PRELOAD_SEARCHER: {
|
||||||
return lib.loader_Lua(args);
|
return lib.searcher_preload(args);
|
||||||
}
|
}
|
||||||
case OP_JAVA_LOADER: {
|
case OP_LUA_SEARCHER: {
|
||||||
return lib.loader_Java(args);
|
return lib.searcher_Lua(args);
|
||||||
|
}
|
||||||
|
case OP_JAVA_SEARCHER: {
|
||||||
|
return lib.searcher_Java(args);
|
||||||
|
}
|
||||||
|
case OP_SEARCHPATH: {
|
||||||
|
String name = args.checkjstring(1);
|
||||||
|
String path = args.checkjstring(2);
|
||||||
|
String sep = args.optjstring(3, ".");
|
||||||
|
String rep = args.optjstring(4, FILE_SEP);
|
||||||
|
return lib.searchpath(name, path, sep, rep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NONE;
|
return NONE;
|
||||||
@@ -184,6 +178,7 @@ public class PackageLib extends OneArgFunction {
|
|||||||
LOADED.set(name, value);
|
LOADED.set(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setLuaPath( String newLuaPath ) {
|
public void setLuaPath( String newLuaPath ) {
|
||||||
PACKAGE.set( _PATH, valueOf(newLuaPath) );
|
PACKAGE.set( _PATH, valueOf(newLuaPath) );
|
||||||
}
|
}
|
||||||
@@ -193,102 +188,7 @@ public class PackageLib extends OneArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ======================== Module, Package loading =============================
|
// ======================== Package loading =============================
|
||||||
/**
|
|
||||||
* module (name [, ...])
|
|
||||||
*
|
|
||||||
* Creates a module. If there is a table in package.loaded[name], this table
|
|
||||||
* is the module. Otherwise, if there is a global table t with the given
|
|
||||||
* name, this table is the module. Otherwise creates a new table t and sets
|
|
||||||
* it as the value of the global name and the value of package.loaded[name].
|
|
||||||
* This function also initializes t._NAME with the given name, t._M with the
|
|
||||||
* module (t itself), and t._PACKAGE with the package name (the full module
|
|
||||||
* name minus last component; see below). Finally, module sets t as the new
|
|
||||||
* environment of the current function and the new value of
|
|
||||||
* package.loaded[name], so that require returns t.
|
|
||||||
*
|
|
||||||
* If name is a compound name (that is, one with components separated by
|
|
||||||
* dots), module creates (or reuses, if they already exist) tables for each
|
|
||||||
* component. For instance, if name is a.b.c, then module stores the module
|
|
||||||
* table in field c of field b of global a.
|
|
||||||
*
|
|
||||||
* This function may receive optional options after the module name, where
|
|
||||||
* each option is a function to be applied over the module.
|
|
||||||
*/
|
|
||||||
public Varargs module(Varargs args) {
|
|
||||||
LuaString modname = args.checkstring(1);
|
|
||||||
int n = args.narg();
|
|
||||||
LuaValue value = LOADED.get(modname);
|
|
||||||
LuaValue module;
|
|
||||||
if ( ! value.istable() ) { /* not found? */
|
|
||||||
|
|
||||||
/* try global variable (and create one if it does not exist) */
|
|
||||||
LuaValue globals = LuaThread.getGlobals();
|
|
||||||
module = findtable( globals, modname );
|
|
||||||
if ( module == null )
|
|
||||||
error( "name conflict for module '"+modname+"'" );
|
|
||||||
LOADED.set(modname, module);
|
|
||||||
} else {
|
|
||||||
module = (LuaTable) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* check whether table already has a _NAME field */
|
|
||||||
LuaValue name = module.get(_NAME);
|
|
||||||
if ( name.isnil() ) {
|
|
||||||
modinit( module, modname );
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the environment of the current function
|
|
||||||
LuaFunction f = LuaThread.getCallstackFunction(1);
|
|
||||||
if ( f == null )
|
|
||||||
error("no calling function");
|
|
||||||
if ( ! f.isclosure() )
|
|
||||||
error("'module' not called from a Lua function");
|
|
||||||
f.setfenv(module);
|
|
||||||
|
|
||||||
// apply the functions
|
|
||||||
for ( int i=2; i<=n; i++ )
|
|
||||||
args.arg(i).call( module );
|
|
||||||
|
|
||||||
// returns no results
|
|
||||||
return NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param table the table at which to start the search
|
|
||||||
* @param fname the name to look up or create, such as "abc.def.ghi"
|
|
||||||
* @return the table for that name, possible a new one, or null if a non-table has that name already.
|
|
||||||
*/
|
|
||||||
private static final LuaValue findtable(LuaValue table, LuaString fname) {
|
|
||||||
int b, e=(-1);
|
|
||||||
do {
|
|
||||||
e = fname.indexOf(_DOT, b=e+1 );
|
|
||||||
if ( e < 0 )
|
|
||||||
e = fname.m_length;
|
|
||||||
LuaString key = fname.substring(b, e);
|
|
||||||
LuaValue val = table.rawget(key);
|
|
||||||
if ( val.isnil() ) { /* no such field? */
|
|
||||||
LuaTable field = new LuaTable(); /* new table for field */
|
|
||||||
table.set(key, field);
|
|
||||||
table = field;
|
|
||||||
} else if ( ! val.istable() ) { /* field has a non-table value? */
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
table = val;
|
|
||||||
}
|
|
||||||
} while ( e < fname.m_length );
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final void modinit(LuaValue module, LuaString modname) {
|
|
||||||
/* module._M = module */
|
|
||||||
module.set(_M, module);
|
|
||||||
int e = modname.lastIndexOf(_DOT);
|
|
||||||
module.set(_NAME, modname );
|
|
||||||
module.set(_PACKAGE, (e<0? EMPTYSTRING: modname.substring(0,e+1)) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* require (modname)
|
* require (modname)
|
||||||
@@ -326,7 +226,7 @@ public class PackageLib extends OneArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* else must load it; iterate over available loaders */
|
/* else must load it; iterate over available loaders */
|
||||||
LuaTable tbl = PACKAGE.get(_LOADERS).checktable();
|
LuaTable tbl = PACKAGE.get(_SEARCHERS).checktable();
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
LuaValue chunk = null;
|
LuaValue chunk = null;
|
||||||
for ( int i=1; true; i++ ) {
|
for ( int i=1; true; i++ ) {
|
||||||
@@ -358,7 +258,7 @@ public class PackageLib extends OneArgFunction {
|
|||||||
return varargsOf(NIL, valueOf("dynamic libraries not enabled"), valueOf("absent"));
|
return varargsOf(NIL, valueOf("dynamic libraries not enabled"), valueOf("absent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaValue loader_preload( Varargs args ) {
|
LuaValue searcher_preload( Varargs args ) {
|
||||||
LuaString name = args.checkstring(1);
|
LuaString name = args.checkstring(1);
|
||||||
LuaValue preload = PACKAGE.get(_PRELOAD).checktable();
|
LuaValue preload = PACKAGE.get(_PRELOAD).checktable();
|
||||||
LuaValue val = preload.get(name);
|
LuaValue val = preload.get(name);
|
||||||
@@ -367,22 +267,40 @@ public class PackageLib extends OneArgFunction {
|
|||||||
val;
|
val;
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaValue loader_Lua( Varargs args ) {
|
Varargs searcher_Lua( Varargs args ) {
|
||||||
String name = args.checkjstring(1);
|
LuaString name = args.checkstring(1);
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
|
|
||||||
|
|
||||||
// get package path
|
// get package path
|
||||||
LuaValue pp = PACKAGE.get(_PATH);
|
LuaValue path = PACKAGE.get(_PATH);
|
||||||
if ( ! pp.isstring() )
|
if ( ! path.isstring() )
|
||||||
return valueOf("package.path is not a string");
|
return valueOf("package.path is not a string");
|
||||||
String path = pp.tojstring();
|
|
||||||
|
// get the searchpath function.
|
||||||
|
LuaValue searchpath = PACKAGE.get(_SEARCHPATH);
|
||||||
|
Varargs v = searchpath.invoke(varargsOf(name, path));
|
||||||
|
|
||||||
|
// Didd we get a result?
|
||||||
|
if (!v.isstring(1))
|
||||||
|
return v.arg(2).tostring();
|
||||||
|
LuaString filename = v.arg1().strvalue();
|
||||||
|
|
||||||
|
// Try to load the file.
|
||||||
|
v = BaseLib.loadFile(filename.tojstring(), "bt", LuaThread.getGlobals());
|
||||||
|
if ( v.arg1().isfunction() )
|
||||||
|
return LuaValue.varargsOf(v.arg1(), filename);
|
||||||
|
|
||||||
|
// report error
|
||||||
|
return varargsOf(NIL, valueOf("'"+filename+"': "+v.arg(2).tojstring()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Varargs searchpath(String name, String path, String sep, String rep) {
|
||||||
|
|
||||||
// check the path elements
|
// check the path elements
|
||||||
int e = -1;
|
int e = -1;
|
||||||
int n = path.length();
|
int n = path.length();
|
||||||
StringBuffer sb = null;
|
StringBuffer sb = null;
|
||||||
name = name.replace('.','/');
|
name = name.replace(sep.charAt(0), rep.charAt(0));
|
||||||
while ( e < n ) {
|
while ( e < n ) {
|
||||||
|
|
||||||
// find next template
|
// find next template
|
||||||
@@ -399,20 +317,22 @@ public class PackageLib extends OneArgFunction {
|
|||||||
filename = template.substring(0,q) + name + template.substring(q+1);
|
filename = template.substring(0,q) + name + template.substring(q+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try loading the file
|
// try opening the file
|
||||||
Varargs v = BaseLib.loadFile(filename);
|
InputStream is = BaseLib.FINDER.findResource(filename);
|
||||||
if ( v.arg1().isfunction() )
|
if (is != null) {
|
||||||
return v.arg1();
|
try { is.close(); } catch ( java.io.IOException ioe ) {}
|
||||||
|
return valueOf(filename);
|
||||||
|
}
|
||||||
|
|
||||||
// report error
|
// report error
|
||||||
if ( sb == null )
|
if ( sb == null )
|
||||||
sb = new StringBuffer();
|
sb = new StringBuffer();
|
||||||
sb.append( "\n\t'"+filename+"': "+v.arg(2) );
|
sb.append( "\n\t"+filename );
|
||||||
}
|
}
|
||||||
return valueOf(sb.toString());
|
return varargsOf(NIL, valueOf(sb.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaValue loader_Java( Varargs args ) {
|
LuaValue searcher_Java( Varargs args ) {
|
||||||
String name = args.checkjstring(1);
|
String name = args.checkjstring(1);
|
||||||
String classname = toClassname( name );
|
String classname = toClassname( name );
|
||||||
Class c = null;
|
Class c = null;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class TableLib extends OneArgFunction {
|
|||||||
LuaTable t = new LuaTable();
|
LuaTable t = new LuaTable();
|
||||||
bind(t, TableLib.class, new String[] { "getn", "maxn", }, 1 );
|
bind(t, TableLib.class, new String[] { "getn", "maxn", }, 1 );
|
||||||
bind(t, TableLibV.class, new String[] {
|
bind(t, TableLibV.class, new String[] {
|
||||||
"remove", "concat", "insert", "sort", "foreach", "foreachi", } );
|
"remove", "concat", "insert", "sort", "foreach", "foreachi", "unpack", } );
|
||||||
env.set("table", t);
|
env.set("table", t);
|
||||||
PackageLib.instance.LOADED.set("table", t);
|
PackageLib.instance.LOADED.set("table", t);
|
||||||
return t;
|
return t;
|
||||||
@@ -117,6 +117,22 @@ public class TableLib extends OneArgFunction {
|
|||||||
case 5: { // "foreachi" (table, func) -> void
|
case 5: { // "foreachi" (table, func) -> void
|
||||||
return args.checktable(1).foreachi( args.checkfunction(2) );
|
return args.checktable(1).foreachi( args.checkfunction(2) );
|
||||||
}
|
}
|
||||||
|
case 6: // "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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,13 @@ import java.util.Vector;
|
|||||||
|
|
||||||
import org.luaj.vm2.LoadState;
|
import org.luaj.vm2.LoadState;
|
||||||
import org.luaj.vm2.Lua;
|
import org.luaj.vm2.Lua;
|
||||||
|
import org.luaj.vm2.LuaClosure;
|
||||||
import org.luaj.vm2.LuaFunction;
|
import org.luaj.vm2.LuaFunction;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
|
import org.luaj.vm2.Print;
|
||||||
import org.luaj.vm2.Varargs;
|
import org.luaj.vm2.Varargs;
|
||||||
|
import org.luaj.vm2.lib.DebugLib;
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||||
import org.luaj.vm2.lua2java.Lua2Java;
|
import org.luaj.vm2.lua2java.Lua2Java;
|
||||||
import org.luaj.vm2.luajc.LuaJC;
|
import org.luaj.vm2.luajc.LuaJC;
|
||||||
@@ -55,6 +58,7 @@ public class lua {
|
|||||||
" -j use lua2java source-to-source compiler\n" +
|
" -j use lua2java source-to-source compiler\n" +
|
||||||
" -b use luajc bytecode-to-bytecode compiler (requires bcel on class path)\n" +
|
" -b use luajc bytecode-to-bytecode compiler (requires bcel on class path)\n" +
|
||||||
" -n nodebug - do not load debug library by default\n" +
|
" -n nodebug - do not load debug library by default\n" +
|
||||||
|
" -p pretty-print the prototype\n" +
|
||||||
" -- stop handling options\n" +
|
" -- stop handling options\n" +
|
||||||
" - execute stdin and stop handling options";
|
" - execute stdin and stop handling options";
|
||||||
|
|
||||||
@@ -72,6 +76,7 @@ public class lua {
|
|||||||
boolean versioninfo = false;
|
boolean versioninfo = false;
|
||||||
boolean processing = true;
|
boolean processing = true;
|
||||||
boolean nodebug = false;
|
boolean nodebug = false;
|
||||||
|
boolean print = false;
|
||||||
boolean luajc = false;
|
boolean luajc = false;
|
||||||
boolean lua2java = false;
|
boolean lua2java = false;
|
||||||
Vector libs = null;
|
Vector libs = null;
|
||||||
@@ -112,6 +117,9 @@ public class lua {
|
|||||||
case 'n':
|
case 'n':
|
||||||
nodebug = true;
|
nodebug = true;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
print = true;
|
||||||
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
if ( args[i].length() > 2 )
|
if ( args[i].length() > 2 )
|
||||||
usageExit();
|
usageExit();
|
||||||
@@ -190,7 +198,14 @@ public class lua {
|
|||||||
try {
|
try {
|
||||||
LuaFunction c;
|
LuaFunction c;
|
||||||
try {
|
try {
|
||||||
c = LoadState.load(script, chunkname, _G);
|
c = LoadState.load(script, chunkname, "bt", _G);
|
||||||
|
if (c instanceof LuaClosure) {
|
||||||
|
LuaClosure closure = (LuaClosure) c;
|
||||||
|
Print.print(closure.p);
|
||||||
|
// DebugLib.DEBUG_ENABLED = true;
|
||||||
|
} else {
|
||||||
|
System.out.println( "Not a LuaClosure: "+c);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
script.close();
|
script.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
|
|||||||
LuaValue t = super.call(arg);
|
LuaValue t = super.call(arg);
|
||||||
bind( t, JseMathLib1.class, new String[] {
|
bind( t, JseMathLib1.class, new String[] {
|
||||||
"acos", "asin", "atan", "cosh",
|
"acos", "asin", "atan", "cosh",
|
||||||
"exp", "log", "log10", "sinh",
|
"exp", "log", "sinh",
|
||||||
"tanh" } );
|
"tanh" } );
|
||||||
bind( t, JseMathLib2.class, new String[] {
|
bind( t, JseMathLib2.class, new String[] {
|
||||||
"atan2", "pow", } );
|
"atan2", "pow", } );
|
||||||
@@ -80,9 +80,8 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
|
|||||||
case 3: return valueOf(Math.cosh(arg.checkdouble()));
|
case 3: return valueOf(Math.cosh(arg.checkdouble()));
|
||||||
case 4: return valueOf(Math.exp(arg.checkdouble()));
|
case 4: return valueOf(Math.exp(arg.checkdouble()));
|
||||||
case 5: return valueOf(Math.log(arg.checkdouble()));
|
case 5: return valueOf(Math.log(arg.checkdouble()));
|
||||||
case 6: return valueOf(Math.log10(arg.checkdouble()));
|
case 6: return valueOf(Math.sinh(arg.checkdouble()));
|
||||||
case 7: return valueOf(Math.sinh(arg.checkdouble()));
|
case 7: return valueOf(Math.tanh(arg.checkdouble()));
|
||||||
case 8: return valueOf(Math.tanh(arg.checkdouble()));
|
|
||||||
}
|
}
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
|||||||
try {
|
try {
|
||||||
InputStream ris = new Utf8Encoder(reader);
|
InputStream ris = new Utf8Encoder(reader);
|
||||||
try {
|
try {
|
||||||
final LuaFunction f = LoadState.load(ris, "script", null);
|
final LuaFunction f = LoadState.load(ris, "script", "bt", null);
|
||||||
if ( f.isclosure() ) {
|
if ( f.isclosure() ) {
|
||||||
// most compiled functions are closures with prototypes
|
// most compiled functions are closures with prototypes
|
||||||
final Prototype p = f.checkclosure().p;
|
final Prototype p = f.checkclosure().p;
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ public class FragmentsTest extends TestSuite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testArgParamUseNone() {
|
public void testArgParamUseNone() {
|
||||||
// the name "arg" is treated specially, and ends up masking the argument value in 5.1
|
|
||||||
runFragment( LuaValue.valueOf("string"),
|
runFragment( LuaValue.valueOf("string"),
|
||||||
"function v(arg,...)\n" +
|
"function v(arg,...)\n" +
|
||||||
" return type(arg)\n" +
|
" return type(arg)\n" +
|
||||||
|
|||||||
@@ -93,22 +93,6 @@ public class MathLibTest extends TestCase {
|
|||||||
tryMathOp( "log", -9 );
|
tryMathOp( "log", -9 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLog10() {
|
|
||||||
supportedOnJ2me = false;
|
|
||||||
tryMathOp( "log10", 0.1 );
|
|
||||||
tryMathOp( "log10", .9 );
|
|
||||||
tryMathOp( "log10", 1. );
|
|
||||||
tryMathOp( "log10", 9 );
|
|
||||||
tryMathOp( "log10", 10 );
|
|
||||||
tryMathOp( "log10", 100 );
|
|
||||||
tryMathOp( "log10", -.1 );
|
|
||||||
tryMathOp( "log10", -.9 );
|
|
||||||
tryMathOp( "log10", -1. );
|
|
||||||
tryMathOp( "log10", -9 );
|
|
||||||
tryMathOp( "log10", -10 );
|
|
||||||
tryMathOp( "log10", -100 );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testRad() {
|
public void testRad() {
|
||||||
tryMathOp( "rad", 0 );
|
tryMathOp( "rad", 0 );
|
||||||
tryMathOp( "rad", 0.1 );
|
tryMathOp( "rad", 0.1 );
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class OrphanedThreadTest extends TestCase {
|
|||||||
"print('leakage in closure.3, arg is '..arg)\n" +
|
"print('leakage in closure.3, arg is '..arg)\n" +
|
||||||
"return 'done'\n";
|
"return 'done'\n";
|
||||||
LuaC.install();
|
LuaC.install();
|
||||||
function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", env);
|
function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", "bt", env);
|
||||||
doTest(LuaValue.TRUE, LuaValue.ZERO);
|
doTest(LuaValue.TRUE, LuaValue.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ public class OrphanedThreadTest extends TestCase {
|
|||||||
"end\n" +
|
"end\n" +
|
||||||
"print( 'pcall-closre.result:', pcall( f, ... ) )\n";
|
"print( 'pcall-closre.result:', pcall( f, ... ) )\n";
|
||||||
LuaC.install();
|
LuaC.install();
|
||||||
function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", env);
|
function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", "bt", env);
|
||||||
doTest(LuaValue.TRUE, LuaValue.ZERO);
|
doTest(LuaValue.TRUE, LuaValue.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ public class OrphanedThreadTest extends TestCase {
|
|||||||
"end\n" +
|
"end\n" +
|
||||||
"load(f)()\n";
|
"load(f)()\n";
|
||||||
LuaC.install();
|
LuaC.install();
|
||||||
function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", env);
|
function = LoadState.load(new ByteArrayInputStream(script.getBytes()), "script", "bt", env);
|
||||||
doTest(LuaValue.TRUE, LuaValue.ONE);
|
doTest(LuaValue.TRUE, LuaValue.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public class ScriptDrivenTest extends TestCase {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
script = new FileInputStream(file);
|
script = new FileInputStream(file);
|
||||||
return LoadState.load(script, "=stdin", _G);
|
return LoadState.load(script, "=stdin", "bt", _G);
|
||||||
}
|
}
|
||||||
} catch ( Exception e ) {
|
} catch ( Exception e ) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ public class DumpLoadEndianIntTest extends TestCase {
|
|||||||
|
|
||||||
// load again using compiler
|
// load again using compiler
|
||||||
is = new ByteArrayInputStream(dumped);
|
is = new ByteArrayInputStream(dumped);
|
||||||
f = LoadState.load(is, "dumped", _G);
|
f = LoadState.load(is, "dumped", "bt", _G);
|
||||||
r = f.call();
|
r = f.call();
|
||||||
actual = r.tojstring();
|
actual = r.tojstring();
|
||||||
assertEquals( expectedPostDump, actual );
|
assertEquals( expectedPostDump, actual );
|
||||||
|
|||||||
@@ -152,6 +152,17 @@ printtables()
|
|||||||
print( 'pcall(rawset,t,"dd","zzz")', rawset(t,"dd","zzz"))
|
print( 'pcall(rawset,t,"dd","zzz")', rawset(t,"dd","zzz"))
|
||||||
printtables()
|
printtables()
|
||||||
|
|
||||||
|
-- rawlen
|
||||||
|
print( 'pcall(rawlen, {})', pcall(rawlen, {}))
|
||||||
|
print( 'pcall(rawlen, {"a"})', pcall(rawlen, {'a'}))
|
||||||
|
print( 'pcall(rawlen, {"a","b"})', pcall(rawlen, {'a','b'}))
|
||||||
|
print( 'pcall(rawlen, "")', pcall(rawlen, ""))
|
||||||
|
print( 'pcall(rawlen, "a")', pcall(rawlen, 'a'))
|
||||||
|
print( 'pcall(rawlen, "ab")', pcall(rawlen, 'ab'))
|
||||||
|
print( 'pcall(rawlen, 1)', pcall(rawlen, 1))
|
||||||
|
print( 'pcall(rawlen, nil)', pcall(rawlen, nil))
|
||||||
|
print( 'pcall(rawlen)', pcall(rawlen))
|
||||||
|
|
||||||
printtables()
|
printtables()
|
||||||
print( 's["ee"]="ppp"' ); s["ee"]="ppp"
|
print( 's["ee"]="ppp"' ); s["ee"]="ppp"
|
||||||
printtables()
|
printtables()
|
||||||
|
|||||||
Reference in New Issue
Block a user