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 stream InputStream to read, after having read the first byte already
|
||||
* @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
|
||||
* @throws IllegalArgumentException if the signature is bac
|
||||
* @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 )
|
||||
return compiler.load(stream, name, env);
|
||||
else {
|
||||
|
||||
@@ -420,6 +420,10 @@ public class LuaString extends LuaValue {
|
||||
return m_length;
|
||||
}
|
||||
|
||||
public int rawlen() {
|
||||
return m_length;
|
||||
}
|
||||
|
||||
public int luaByte(int index) {
|
||||
return m_bytes[m_offset + index] & 0x0FF;
|
||||
}
|
||||
|
||||
@@ -394,6 +394,10 @@ public class LuaTable extends LuaValue {
|
||||
return LuaInteger.valueOf(length());
|
||||
}
|
||||
|
||||
public int rawlen() {
|
||||
return length();
|
||||
}
|
||||
|
||||
/** Return table.maxn() as defined by lua 5.0.
|
||||
* <p>
|
||||
* Provided for compatibility, not a scalable operation.
|
||||
|
||||
@@ -2014,6 +2014,12 @@ public class LuaValue extends Varargs {
|
||||
*/
|
||||
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.
|
||||
* @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}
|
||||
|
||||
@@ -89,30 +89,29 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
private LuaValue next;
|
||||
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 = {
|
||||
"collectgarbage", // ( opt [,arg] ) -> value
|
||||
"error", // ( message [,level] ) -> ERR
|
||||
"setfenv", // (f, table) -> void
|
||||
"rawequal", // (v1, v2) -> boolean
|
||||
"rawget", // (table, index) -> value
|
||||
};
|
||||
private static final String[] LIBV_KEYS = {
|
||||
"assert", // ( v [,message] ) -> v, message | ERR
|
||||
"dofile", // ( filename ) -> result1, ...
|
||||
"getfenv", // ( [f] ) -> env
|
||||
"getmetatable", // ( object ) -> table
|
||||
"load", // ( func [,chunkname] ) -> chunk | nil, msg
|
||||
"loadfile", // ( [filename] ) -> chunk | nil, msg
|
||||
"loadstring", // ( string [,chunkname] ) -> chunk | nil, msg
|
||||
"load", // ( ld [, source [, mode [, env]]] ) -> chunk | nil, msg
|
||||
"loadfile", // ( [filename [, mode [, env]]] ) -> chunk | nil, msg
|
||||
"pcall", // (f, arg1, ...) -> status, result1, ...
|
||||
"xpcall", // (f, err) -> result1, ...
|
||||
"print", // (...) -> void
|
||||
"select", // (f, ...) -> value1, ...
|
||||
"unpack", // (list [,i [,j]]) -> result1, ...
|
||||
"type", // (v) -> value
|
||||
"rawequal", // (v1, v2) -> boolean
|
||||
"rawget", // (table, index) -> value
|
||||
"rawset", // (table, index, value) -> table
|
||||
"setmetatable", // (table, metatable) -> table
|
||||
"tostring", // (e) -> value
|
||||
"tonumber", // (e [,base]) -> value
|
||||
"pairs", // "pairs" (t) -> iter-func, t, nil
|
||||
"ipairs", // "ipairs", // (t) -> iter-func, t, 0
|
||||
@@ -130,6 +129,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
public LuaValue call(LuaValue arg) {
|
||||
env.set( "_G", env );
|
||||
env.set( "_VERSION", Lua._VERSION );
|
||||
bind( env, BaseLib1.class, LIB1_KEYS );
|
||||
bind( env, BaseLib2.class, LIB2_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);
|
||||
}
|
||||
|
||||
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 {
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
switch ( opcode ) {
|
||||
case 0: // "collectgarbage", // ( opt [,arg] ) -> value
|
||||
String s = arg1.checkjstring();
|
||||
int result = 0;
|
||||
if ( "collect".equals(s) ) {
|
||||
System.gc();
|
||||
return ZERO;
|
||||
@@ -173,36 +203,20 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
System.gc();
|
||||
return LuaValue.TRUE;
|
||||
} else {
|
||||
this.argerror(1, "gc op");
|
||||
this.argerror("gc op");
|
||||
}
|
||||
return NIL;
|
||||
case 1: // "error", // ( message [,level] ) -> ERR
|
||||
throw new LuaError( arg1.isnil()? null: arg1.tojstring(), arg2.optint(1) );
|
||||
case 2: { // "setfenv", // (f, table) -> void
|
||||
LuaTable t = arg2.checktable();
|
||||
LuaValue f = getfenvobj(arg1);
|
||||
if ( ! f.isfunction() && ! f.isclosure() )
|
||||
error("'setfenv' cannot change environment of given object");
|
||||
f.setfenv(t);
|
||||
return f.isthread()? NONE: f;
|
||||
}
|
||||
case 2: // "rawequal", // (v1, v2) -> boolean
|
||||
return valueOf(arg1.raweq(arg2));
|
||||
case 3: // "rawget", // (table, index) -> value
|
||||
return arg1.rawget(arg2);
|
||||
}
|
||||
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 {
|
||||
public BaseLib baselib;
|
||||
public Varargs invoke(Varargs args) {
|
||||
@@ -213,41 +227,34 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
return args;
|
||||
case 1: // "dofile", // ( filename ) -> result1, ...
|
||||
{
|
||||
Varargs v = args.isnil(1)?
|
||||
BaseLib.loadStream( baselib.STDIN, "=stdin" ):
|
||||
BaseLib.loadFile( args.checkjstring(1) );
|
||||
args.argcheck(args.isstring(1) || args.isnil(1), 1, "filename must be string or nil");
|
||||
String filename = args.isstring(1)? args.tojstring(1): null;
|
||||
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();
|
||||
}
|
||||
case 2: // "getfenv", // ( [f] ) -> env
|
||||
case 2: // "load", // ( ld [, source [, mode [, env]]] ) -> chunk | nil, msg
|
||||
{
|
||||
LuaValue f = getfenvobj(args.arg1());
|
||||
LuaValue e = f.getfenv();
|
||||
return e!=null? e: NIL;
|
||||
LuaValue ld = args.arg1();
|
||||
args.argcheck(ld.isstring() || ld.isfunction(), 1, "ld must be string or function");
|
||||
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();
|
||||
return mt!=null? mt.rawget(METATABLE).optvalue(mt): NIL;
|
||||
args.argcheck(args.isstring(1) || args.isnil(1), 1, "filename must be string or 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
|
||||
{
|
||||
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, ...
|
||||
case 4: // "pcall", // (f, arg1, ...) -> status, result1, ...
|
||||
{
|
||||
LuaValue func = args.checkvalue(1);
|
||||
LuaThread.CallStack cs = LuaThread.onCall(this);
|
||||
@@ -257,7 +264,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
cs.onReturn();
|
||||
}
|
||||
}
|
||||
case 8: // "xpcall", // (f, err) -> result1, ...
|
||||
case 5: // "xpcall", // (f, err) -> result1, ...
|
||||
{
|
||||
LuaThread.CallStack cs = LuaThread.onCall(this);
|
||||
try {
|
||||
@@ -266,7 +273,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
cs.onReturn();
|
||||
}
|
||||
}
|
||||
case 9: // "print", // (...) -> void
|
||||
case 6: // "print", // (...) -> void
|
||||
{
|
||||
LuaValue tostring = LuaThread.getGlobals().get("tostring");
|
||||
for ( int i=1, n=args.narg(); i<=n; i++ ) {
|
||||
@@ -278,7 +285,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
baselib.STDOUT.println();
|
||||
return NONE;
|
||||
}
|
||||
case 10: // "select", // (f, ...) -> value1, ...
|
||||
case 7: // "select", // (f, ...) -> value1, ...
|
||||
{
|
||||
int n = args.narg()-1;
|
||||
if ( args.arg1().equals(valueOf("#")) )
|
||||
@@ -288,34 +295,12 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
argerror(1,"index out of range");
|
||||
return args.subargs(i<0? n+i+2: i+1);
|
||||
}
|
||||
case 11: // "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 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
|
||||
case 8: { // "rawset", // (table, index, value) -> table
|
||||
LuaTable t = args.checktable(1);
|
||||
t.rawset(args.checknotnil(2), args.checkvalue(3));
|
||||
return t;
|
||||
}
|
||||
case 16: { // "setmetatable", // (table, metatable) -> table
|
||||
case 9: { // "setmetatable", // (table, metatable) -> table
|
||||
final LuaValue t = args.arg1();
|
||||
final LuaValue mt0 = t.getmetatable();
|
||||
if ( mt0!=null && !mt0.rawget(METATABLE).isnil() )
|
||||
@@ -323,17 +308,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
final LuaValue mt = args.checkvalue(2);
|
||||
return t.setmetatable(mt.isnil()? null: mt.checktable());
|
||||
}
|
||||
case 17: { // "tostring", // (e) -> 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
|
||||
case 10: { // "tonumber", // (e [,base]) -> value
|
||||
LuaValue arg1 = args.checkvalue(1);
|
||||
final int base = args.optint(2,10);
|
||||
if (base == 10) { /* standard conversion */
|
||||
@@ -344,13 +319,13 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
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 );
|
||||
case 20: // "ipairs", // (t) -> iter-func, t, 0
|
||||
case 12: // "ipairs", // (t) -> iter-func, t, 0
|
||||
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));
|
||||
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 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
|
||||
* @param env
|
||||
* @param mode
|
||||
* @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);
|
||||
if ( is == null )
|
||||
return varargsOf(NIL, valueOf("cannot open "+filename+": No such file or directory"));
|
||||
try {
|
||||
return loadStream(is, "@"+filename);
|
||||
return loadStream(is, "@"+filename, mode, env);
|
||||
} finally {
|
||||
try {
|
||||
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 {
|
||||
if ( is == null )
|
||||
return varargsOf(NIL, valueOf("not found: "+chunkname));
|
||||
return LoadState.load(is, chunkname, LuaThread.getGlobals());
|
||||
return LoadState.load(is, chunkname, mode, env);
|
||||
} catch (Exception e) {
|
||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
||||
}
|
||||
|
||||
@@ -76,14 +76,12 @@ public class DebugLib extends VarArgFunction {
|
||||
|
||||
static final String[] NAMES = {
|
||||
"debug",
|
||||
"getfenv",
|
||||
"gethook",
|
||||
"getinfo",
|
||||
"getlocal",
|
||||
"getmetatable",
|
||||
"getregistry",
|
||||
"getupvalue",
|
||||
"setfenv",
|
||||
"sethook",
|
||||
"setlocal",
|
||||
"setmetatable",
|
||||
@@ -93,19 +91,17 @@ public class DebugLib extends VarArgFunction {
|
||||
|
||||
private static final int INIT = 0;
|
||||
private static final int DEBUG = 1;
|
||||
private static final int GETFENV = 2;
|
||||
private static final int GETHOOK = 3;
|
||||
private static final int GETINFO = 4;
|
||||
private static final int GETLOCAL = 5;
|
||||
private static final int GETMETATABLE = 6;
|
||||
private static final int GETREGISTRY = 7;
|
||||
private static final int GETUPVALUE = 8;
|
||||
private static final int SETFENV = 9;
|
||||
private static final int SETHOOK = 10;
|
||||
private static final int SETLOCAL = 11;
|
||||
private static final int SETMETATABLE = 12;
|
||||
private static final int SETUPVALUE = 13;
|
||||
private static final int TRACEBACK = 14;
|
||||
private static final int GETHOOK = 2;
|
||||
private static final int GETINFO = 3;
|
||||
private static final int GETLOCAL = 4;
|
||||
private static final int GETMETATABLE = 5;
|
||||
private static final int GETREGISTRY = 6;
|
||||
private static final int GETUPVALUE = 7;
|
||||
private static final int SETHOOK = 8;
|
||||
private static final int SETLOCAL = 9;
|
||||
private static final int SETMETATABLE = 10;
|
||||
private static final int SETUPVALUE = 11;
|
||||
private static final int TRACEBACK = 12;
|
||||
|
||||
/* maximum stack for a Lua function */
|
||||
private static final int MAXSTACK = 250;
|
||||
@@ -153,14 +149,12 @@ public class DebugLib extends VarArgFunction {
|
||||
switch ( opcode ) {
|
||||
case INIT: return init();
|
||||
case DEBUG: return _debug(args);
|
||||
case GETFENV: return _getfenv(args);
|
||||
case GETHOOK: return _gethook(args);
|
||||
case GETINFO: return _getinfo(args,this);
|
||||
case GETLOCAL: return _getlocal(args);
|
||||
case GETMETATABLE: return _getmetatable(args);
|
||||
case GETREGISTRY: return _getregistry(args);
|
||||
case GETUPVALUE: return _getupvalue(args);
|
||||
case SETFENV: return _setfenv(args);
|
||||
case SETHOOK: return _sethook(args);
|
||||
case SETLOCAL: return _setlocal(args);
|
||||
case SETMETATABLE: return _setmetatable(args);
|
||||
@@ -438,19 +432,6 @@ public class DebugLib extends VarArgFunction {
|
||||
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) {
|
||||
int a=1;
|
||||
LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning();
|
||||
|
||||
@@ -42,7 +42,6 @@ import org.luaj.vm2.Varargs;
|
||||
* <li>atan</li>
|
||||
* <li>cosh</li>
|
||||
* <li>log</li>
|
||||
* <li>log10</li>
|
||||
* <li>sinh</li>
|
||||
* <li>tanh</li>
|
||||
* <li>atan2</li>
|
||||
|
||||
@@ -76,33 +76,30 @@ public class PackageLib extends OneArgFunction {
|
||||
public static PackageLib instance;
|
||||
|
||||
/** 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 */
|
||||
public LuaValue lua_loader;
|
||||
public LuaValue lua_searcher;
|
||||
|
||||
/** 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 _NAME = valueOf("_NAME");
|
||||
private static final LuaString _PACKAGE = valueOf("_PACKAGE");
|
||||
private static final LuaString _DOT = valueOf(".");
|
||||
private static final LuaString _LOADERS = valueOf("loaders");
|
||||
private static final LuaString _LOADED = valueOf("loaded");
|
||||
private static final LuaString _LOADLIB = valueOf("loadlib");
|
||||
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 _SEARCHERS = valueOf("searchers");
|
||||
private static final LuaString _SEARCHPATH = valueOf("searchpath");
|
||||
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() {
|
||||
instance = this;
|
||||
@@ -110,17 +107,16 @@ public class PackageLib extends OneArgFunction {
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
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[] {
|
||||
_LOADED, LOADED=tableOf(),
|
||||
_PRELOAD, tableOf(),
|
||||
_PATH, valueOf(DEFAULT_LUA_PATH),
|
||||
_LOADLIB, new PkgLibV(env,"loadlib",OP_LOADLIB,this),
|
||||
_SEEALL, new PkgLib1(env,"seeall",OP_SEEALL,this),
|
||||
_LOADERS, listOf(new LuaValue[] {
|
||||
preload_loader = new PkgLibV(env,"preload_loader", OP_PRELOAD_LOADER,this),
|
||||
lua_loader = new PkgLibV(env,"lua_loader", OP_LUA_LOADER,this),
|
||||
java_loader = new PkgLibV(env,"java_loader", OP_JAVA_LOADER,this),
|
||||
_SEARCHPATH, new PkgLibV(env,"searchpath",OP_SEARCHPATH,this),
|
||||
_SEARCHERS, listOf(new LuaValue[] {
|
||||
preload_searcher = new PkgLibV(env,"preload_searcher", OP_PRELOAD_SEARCHER,this),
|
||||
lua_searcher = new PkgLibV(env,"lua_searcher", OP_LUA_SEARCHER,this),
|
||||
java_searcher = new PkgLibV(env,"java_searcher", OP_JAVA_SEARCHER,this),
|
||||
}) }) );
|
||||
LOADED.set("package", PACKAGE);
|
||||
return env;
|
||||
@@ -138,14 +134,6 @@ public class PackageLib extends OneArgFunction {
|
||||
switch ( opcode ) {
|
||||
case OP_REQUIRE:
|
||||
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;
|
||||
}
|
||||
@@ -161,18 +149,24 @@ public class PackageLib extends OneArgFunction {
|
||||
}
|
||||
public Varargs invoke(Varargs args) {
|
||||
switch ( opcode ) {
|
||||
case OP_MODULE:
|
||||
return lib.module(args);
|
||||
case OP_LOADLIB:
|
||||
case OP_LOADLIB: {
|
||||
return loadlib(args);
|
||||
case OP_PRELOAD_LOADER: {
|
||||
return lib.loader_preload(args);
|
||||
}
|
||||
case OP_LUA_LOADER: {
|
||||
return lib.loader_Lua(args);
|
||||
case OP_PRELOAD_SEARCHER: {
|
||||
return lib.searcher_preload(args);
|
||||
}
|
||||
case OP_JAVA_LOADER: {
|
||||
return lib.loader_Java(args);
|
||||
case OP_LUA_SEARCHER: {
|
||||
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;
|
||||
@@ -184,6 +178,7 @@ public class PackageLib extends OneArgFunction {
|
||||
LOADED.set(name, value);
|
||||
}
|
||||
|
||||
|
||||
public void setLuaPath( String newLuaPath ) {
|
||||
PACKAGE.set( _PATH, valueOf(newLuaPath) );
|
||||
}
|
||||
@@ -193,102 +188,7 @@ public class PackageLib extends OneArgFunction {
|
||||
}
|
||||
|
||||
|
||||
// ======================== Module, 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)) );
|
||||
}
|
||||
// ======================== Package loading =============================
|
||||
|
||||
/**
|
||||
* require (modname)
|
||||
@@ -326,7 +226,7 @@ public class PackageLib extends OneArgFunction {
|
||||
}
|
||||
|
||||
/* else must load it; iterate over available loaders */
|
||||
LuaTable tbl = PACKAGE.get(_LOADERS).checktable();
|
||||
LuaTable tbl = PACKAGE.get(_SEARCHERS).checktable();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
LuaValue chunk = null;
|
||||
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"));
|
||||
}
|
||||
|
||||
LuaValue loader_preload( Varargs args ) {
|
||||
LuaValue searcher_preload( Varargs args ) {
|
||||
LuaString name = args.checkstring(1);
|
||||
LuaValue preload = PACKAGE.get(_PRELOAD).checktable();
|
||||
LuaValue val = preload.get(name);
|
||||
@@ -367,22 +267,40 @@ public class PackageLib extends OneArgFunction {
|
||||
val;
|
||||
}
|
||||
|
||||
LuaValue loader_Lua( Varargs args ) {
|
||||
String name = args.checkjstring(1);
|
||||
Varargs searcher_Lua( Varargs args ) {
|
||||
LuaString name = args.checkstring(1);
|
||||
InputStream is = null;
|
||||
|
||||
|
||||
// get package path
|
||||
LuaValue pp = PACKAGE.get(_PATH);
|
||||
if ( ! pp.isstring() )
|
||||
LuaValue path = PACKAGE.get(_PATH);
|
||||
if ( ! path.isstring() )
|
||||
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
|
||||
int e = -1;
|
||||
int n = path.length();
|
||||
StringBuffer sb = null;
|
||||
name = name.replace('.','/');
|
||||
name = name.replace(sep.charAt(0), rep.charAt(0));
|
||||
while ( e < n ) {
|
||||
|
||||
// find next template
|
||||
@@ -399,20 +317,22 @@ public class PackageLib extends OneArgFunction {
|
||||
filename = template.substring(0,q) + name + template.substring(q+1);
|
||||
}
|
||||
|
||||
// try loading the file
|
||||
Varargs v = BaseLib.loadFile(filename);
|
||||
if ( v.arg1().isfunction() )
|
||||
return v.arg1();
|
||||
// try opening the file
|
||||
InputStream is = BaseLib.FINDER.findResource(filename);
|
||||
if (is != null) {
|
||||
try { is.close(); } catch ( java.io.IOException ioe ) {}
|
||||
return valueOf(filename);
|
||||
}
|
||||
|
||||
// report error
|
||||
if ( sb == null )
|
||||
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 classname = toClassname( name );
|
||||
Class c = null;
|
||||
|
||||
@@ -65,7 +65,7 @@ public class TableLib extends OneArgFunction {
|
||||
LuaTable t = new LuaTable();
|
||||
bind(t, TableLib.class, new String[] { "getn", "maxn", }, 1 );
|
||||
bind(t, TableLibV.class, new String[] {
|
||||
"remove", "concat", "insert", "sort", "foreach", "foreachi", } );
|
||||
"remove", "concat", "insert", "sort", "foreach", "foreachi", "unpack", } );
|
||||
env.set("table", t);
|
||||
PackageLib.instance.LOADED.set("table", t);
|
||||
return t;
|
||||
@@ -117,6 +117,22 @@ public class TableLib extends OneArgFunction {
|
||||
case 5: { // "foreachi" (table, func) -> void
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -30,10 +30,13 @@ import java.util.Vector;
|
||||
|
||||
import org.luaj.vm2.LoadState;
|
||||
import org.luaj.vm2.Lua;
|
||||
import org.luaj.vm2.LuaClosure;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Print;
|
||||
import org.luaj.vm2.Varargs;
|
||||
import org.luaj.vm2.lib.DebugLib;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
import org.luaj.vm2.lua2java.Lua2Java;
|
||||
import org.luaj.vm2.luajc.LuaJC;
|
||||
@@ -55,6 +58,7 @@ public class lua {
|
||||
" -j use lua2java source-to-source compiler\n" +
|
||||
" -b use luajc bytecode-to-bytecode compiler (requires bcel on class path)\n" +
|
||||
" -n nodebug - do not load debug library by default\n" +
|
||||
" -p pretty-print the prototype\n" +
|
||||
" -- stop handling options\n" +
|
||||
" - execute stdin and stop handling options";
|
||||
|
||||
@@ -72,6 +76,7 @@ public class lua {
|
||||
boolean versioninfo = false;
|
||||
boolean processing = true;
|
||||
boolean nodebug = false;
|
||||
boolean print = false;
|
||||
boolean luajc = false;
|
||||
boolean lua2java = false;
|
||||
Vector libs = null;
|
||||
@@ -112,6 +117,9 @@ public class lua {
|
||||
case 'n':
|
||||
nodebug = true;
|
||||
break;
|
||||
case 'p':
|
||||
print = true;
|
||||
break;
|
||||
case '-':
|
||||
if ( args[i].length() > 2 )
|
||||
usageExit();
|
||||
@@ -190,7 +198,14 @@ public class lua {
|
||||
try {
|
||||
LuaFunction c;
|
||||
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 {
|
||||
script.close();
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
|
||||
LuaValue t = super.call(arg);
|
||||
bind( t, JseMathLib1.class, new String[] {
|
||||
"acos", "asin", "atan", "cosh",
|
||||
"exp", "log", "log10", "sinh",
|
||||
"exp", "log", "sinh",
|
||||
"tanh" } );
|
||||
bind( t, JseMathLib2.class, new String[] {
|
||||
"atan2", "pow", } );
|
||||
@@ -80,9 +80,8 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
|
||||
case 3: return valueOf(Math.cosh(arg.checkdouble()));
|
||||
case 4: return valueOf(Math.exp(arg.checkdouble()));
|
||||
case 5: return valueOf(Math.log(arg.checkdouble()));
|
||||
case 6: return valueOf(Math.log10(arg.checkdouble()));
|
||||
case 7: return valueOf(Math.sinh(arg.checkdouble()));
|
||||
case 8: return valueOf(Math.tanh(arg.checkdouble()));
|
||||
case 6: return valueOf(Math.sinh(arg.checkdouble()));
|
||||
case 7: return valueOf(Math.tanh(arg.checkdouble()));
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ public class LuaScriptEngine implements ScriptEngine, Compilable {
|
||||
try {
|
||||
InputStream ris = new Utf8Encoder(reader);
|
||||
try {
|
||||
final LuaFunction f = LoadState.load(ris, "script", null);
|
||||
final LuaFunction f = LoadState.load(ris, "script", "bt", null);
|
||||
if ( f.isclosure() ) {
|
||||
// most compiled functions are closures with prototypes
|
||||
final Prototype p = f.checkclosure().p;
|
||||
|
||||
@@ -123,7 +123,6 @@ public class FragmentsTest extends TestSuite {
|
||||
}
|
||||
|
||||
public void testArgParamUseNone() {
|
||||
// the name "arg" is treated specially, and ends up masking the argument value in 5.1
|
||||
runFragment( LuaValue.valueOf("string"),
|
||||
"function v(arg,...)\n" +
|
||||
" return type(arg)\n" +
|
||||
|
||||
@@ -93,22 +93,6 @@ public class MathLibTest extends TestCase {
|
||||
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() {
|
||||
tryMathOp( "rad", 0 );
|
||||
tryMathOp( "rad", 0.1 );
|
||||
|
||||
@@ -75,7 +75,7 @@ public class OrphanedThreadTest extends TestCase {
|
||||
"print('leakage in closure.3, arg is '..arg)\n" +
|
||||
"return 'done'\n";
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public class OrphanedThreadTest extends TestCase {
|
||||
"end\n" +
|
||||
"print( 'pcall-closre.result:', pcall( f, ... ) )\n";
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class OrphanedThreadTest extends TestCase {
|
||||
"end\n" +
|
||||
"load(f)()\n";
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ public class ScriptDrivenTest extends TestCase {
|
||||
}
|
||||
default:
|
||||
script = new FileInputStream(file);
|
||||
return LoadState.load(script, "=stdin", _G);
|
||||
return LoadState.load(script, "=stdin", "bt", _G);
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -108,7 +108,7 @@ public class DumpLoadEndianIntTest extends TestCase {
|
||||
|
||||
// load again using compiler
|
||||
is = new ByteArrayInputStream(dumped);
|
||||
f = LoadState.load(is, "dumped", _G);
|
||||
f = LoadState.load(is, "dumped", "bt", _G);
|
||||
r = f.call();
|
||||
actual = r.tojstring();
|
||||
assertEquals( expectedPostDump, actual );
|
||||
|
||||
@@ -152,6 +152,17 @@ printtables()
|
||||
print( 'pcall(rawset,t,"dd","zzz")', rawset(t,"dd","zzz"))
|
||||
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()
|
||||
print( 's["ee"]="ppp"' ); s["ee"]="ppp"
|
||||
printtables()
|
||||
|
||||
Reference in New Issue
Block a user