Let all libraries implement invoke() instead of luaStackCall, correct off-by-one error on argument type check functions.
This commit is contained in:
@@ -120,112 +120,104 @@ public class BaseLib extends LFunction {
|
||||
vm.pushstring( message );
|
||||
}
|
||||
|
||||
public boolean luaStackCall(LuaState vm) {
|
||||
public int invoke(LuaState vm) {
|
||||
switch ( id ) {
|
||||
case PRINT: {
|
||||
int n = vm.gettop();
|
||||
vm.getglobal("tostring");
|
||||
for ( int i=2; i<=n; i++ ) {
|
||||
for ( int i=1; i<=n; i++ ) {
|
||||
vm.pushvalue(-1);
|
||||
vm.pushvalue(i);
|
||||
vm.call(1, 1);
|
||||
if ( vm.type(-1) != Lua.LUA_TSTRING )
|
||||
vm.error( "'tostring' must return a string to 'print'" );
|
||||
if ( i > 2 )
|
||||
if ( i > 1 )
|
||||
STDOUT.print( "\t" );
|
||||
STDOUT.print( vm.tostring(-1) );
|
||||
vm.poplvalue();
|
||||
}
|
||||
STDOUT.println();
|
||||
vm.resettop();
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
case IPAIRS: {
|
||||
LTable t = vm.checktable(2);
|
||||
vm.resettop();
|
||||
LTable t = vm.checktable(1);
|
||||
vm.pushfunction( inext );
|
||||
vm.pushlvalue( t );
|
||||
vm.pushinteger( 0 );
|
||||
break;
|
||||
return 3;
|
||||
}
|
||||
case PAIRS: {
|
||||
LTable t = vm.checktable(2);
|
||||
vm.resettop();
|
||||
LTable t = vm.checktable(1);
|
||||
vm.pushfunction( next );
|
||||
vm.pushlvalue( t );
|
||||
vm.pushnil();
|
||||
break;
|
||||
return 3;
|
||||
}
|
||||
case INEXT: {
|
||||
int i = vm.checkint(3) + 1;
|
||||
LTable t = vm.checktable(2);
|
||||
int i = vm.checkint(2) + 1;
|
||||
LTable t = vm.checktable(1);
|
||||
LValue v = t.get(i);
|
||||
vm.resettop();
|
||||
if ( !v.isNil() ) {
|
||||
vm.pushinteger(i);
|
||||
vm.pushlvalue(v);
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
case NEXT: {
|
||||
LTable t = vm.checktable(2);
|
||||
LValue k = vm.topointer(3);
|
||||
LTable t = vm.checktable(1);
|
||||
LValue k = vm.topointer(2);
|
||||
vm.resettop();
|
||||
t.next(vm,k,false);
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
case GETMETATABLE: {
|
||||
vm.checkany(2);
|
||||
if ( ! vm.getmetatable(2) ) {
|
||||
vm.resettop();
|
||||
vm.checkany(1);
|
||||
if ( ! vm.getmetatable(1) ) {
|
||||
vm.pushnil();
|
||||
return 1;
|
||||
} else {
|
||||
vm.replace(1);
|
||||
vm.settop(1);
|
||||
vm.getfield(-1,LValue.TM_METATABLE);
|
||||
if ( vm.isnil(-1) )
|
||||
vm.pop(1);
|
||||
else
|
||||
vm.remove(1);
|
||||
}
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case SETMETATABLE: {
|
||||
LTable t = vm.checktable(2);
|
||||
LValue v = vm.checkany(3);
|
||||
vm.argcheck(v.isTable() || v.isNil(), 3, "table or nil expected");
|
||||
LTable t = vm.checktable(1);
|
||||
LValue v = vm.checkany(2);
|
||||
vm.argcheck(v.isTable() || v.isNil(), 2, "table or nil expected");
|
||||
t = t.luaSetMetatable(v);
|
||||
vm.resettop();
|
||||
vm.pushlvalue(t);
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case TYPE: {
|
||||
LValue v = vm.checkany(2);
|
||||
vm.resettop();
|
||||
LValue v = vm.checkany(1);
|
||||
vm.pushlstring( v.luaGetTypeName() );
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case PCALL: {
|
||||
vm.checkany(2);
|
||||
vm.checkany(1);
|
||||
int n = vm.gettop();
|
||||
int s = vm.pcall( n-2, Lua.LUA_MULTRET, 0 );
|
||||
if ( s == 0 ) { // success, results are on stack above the pcall
|
||||
vm.remove( 1 );
|
||||
int s = vm.pcall( n-1, Lua.LUA_MULTRET, 0 );
|
||||
if ( s == 0 ) { // success, results are on stack
|
||||
vm.pushboolean( true );
|
||||
vm.insert( 1 );
|
||||
return -1;
|
||||
} else { // error, error message is on the stack
|
||||
vm.pushboolean( false );
|
||||
vm.insert( 1 );
|
||||
vm.insert( -2 );
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XPCALL: {
|
||||
LValue errfun = vm.checkany(3);
|
||||
vm.settop(2);
|
||||
vm.settop(1);
|
||||
int s = vm.pcall( 0, Lua.LUA_MULTRET, 0 );
|
||||
if ( s == 0 ) { // success, results are on stack above the xpcall
|
||||
if ( s == 0 ) { // success, results are on stack
|
||||
vm.pushboolean( true );
|
||||
vm.replace( 1 );
|
||||
vm.insert( 1 );
|
||||
return -1;
|
||||
} else { // error, error message is on the stack
|
||||
vm.pushlvalue( errfun );
|
||||
vm.insert( 1 );
|
||||
@@ -233,113 +225,105 @@ public class BaseLib extends LFunction {
|
||||
if ( s == 0 ) {
|
||||
vm.pushboolean( false );
|
||||
vm.insert( 1 );
|
||||
return -1;
|
||||
} else { // error in error handler
|
||||
vm.resettop();
|
||||
vm.pushboolean(false);
|
||||
vm.pushstring("error in error handling");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ERROR: {
|
||||
vm.error(vm.optstring(2,null), vm.optint(3,1));
|
||||
break;
|
||||
vm.error(vm.optstring(1,null), vm.optint(2,1));
|
||||
return 0;
|
||||
}
|
||||
case ASSERT: {
|
||||
if ( ! vm.toboolean(2) )
|
||||
vm.error( vm.optstring(3,"assertion failed!") );
|
||||
vm.remove(1);
|
||||
break;
|
||||
if ( ! vm.toboolean(1) )
|
||||
vm.error( vm.optstring(2,"assertion failed!") );
|
||||
return -1;
|
||||
}
|
||||
|
||||
case LOADFILE:
|
||||
loadfile(vm, vm.optstring(2,null));
|
||||
break;
|
||||
loadfile(vm, vm.optstring(1,null));
|
||||
return -1;
|
||||
|
||||
case TONUMBER: {
|
||||
int base = vm.optint(3, 10);
|
||||
int base = vm.optint(2, 10);
|
||||
if (base == 10) { /* standard conversion */
|
||||
vm.checkany(2);
|
||||
LValue v = vm.tolnumber(2);
|
||||
vm.resettop();
|
||||
vm.checkany(1);
|
||||
LValue v = vm.tolnumber(1);
|
||||
vm.pushlvalue(v);
|
||||
return 1;
|
||||
} else {
|
||||
if ( base < 2 || base > 36 )
|
||||
vm.typerror(3, "base out of range");
|
||||
LString s = vm.checklstring(2);
|
||||
vm.resettop();
|
||||
vm.argerror(2, "base out of range");
|
||||
LString s = vm.checklstring(1);
|
||||
vm.pushlvalue( s.luaToNumber(base) );
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RAWEQUAL: {
|
||||
LValue a = vm.checkany(2);
|
||||
LValue b = vm.checkany(3);
|
||||
vm.resettop();
|
||||
LValue a = vm.checkany(1);
|
||||
LValue b = vm.checkany(2);
|
||||
vm.pushboolean(a == b);
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case RAWGET: {
|
||||
LTable t = vm.checktable(2);
|
||||
LValue k = vm.checkany(3);
|
||||
vm.resettop();
|
||||
LTable t = vm.checktable(1);
|
||||
LValue k = vm.checkany(2);
|
||||
vm.pushlvalue( t.get( k ) );
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case RAWSET: {
|
||||
LTable t = vm.checktable(2);
|
||||
LValue k = vm.checkany(3);
|
||||
LValue v = vm.checkany(4);
|
||||
LTable t = vm.checktable(1);
|
||||
LValue k = vm.checkany(2);
|
||||
LValue v = vm.checkany(3);
|
||||
t.put( k, v );
|
||||
vm.resettop();
|
||||
vm.pushlvalue(t);
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case GETFENV: {
|
||||
LValue f = getfunc(vm, true);
|
||||
vm.resettop();
|
||||
vm.pushlvalue(f.luaGetEnv(vm._G));
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case SETFENV: {
|
||||
LTable t = vm.checktable(3);
|
||||
LValue f = getfunc(vm, false);
|
||||
if ( vm.isnumber(2) && vm.tointeger(2) == 0 ) {
|
||||
LTable t = vm.checktable(2);
|
||||
if ( vm.isnumber(1) && vm.tointeger(1) == 0 ) {
|
||||
vm._G = t;
|
||||
} else if ( (!(f instanceof LClosure)) || ! f.luaSetEnv(t) ) {
|
||||
} else {
|
||||
LValue f = getfunc(vm, false);
|
||||
if ( (!(f instanceof LClosure)) || ! f.luaSetEnv(t) )
|
||||
vm.error( "'setfenv' cannot change environment of given object" );
|
||||
}
|
||||
vm.resettop();
|
||||
vm.pushlvalue(f);
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
case SELECT: {
|
||||
vm.checkany(2);
|
||||
vm.checkany(1);
|
||||
int n = vm.gettop();
|
||||
if ( vm.isnumber(2) ) {
|
||||
int index = vm.tolnumber(2).toJavaInt();
|
||||
if ( vm.isnumber(1) ) {
|
||||
int index = vm.tolnumber(1).toJavaInt();
|
||||
if ( index < 0 )
|
||||
index += n-1;
|
||||
index += n;
|
||||
if ( index <= 0 )
|
||||
vm.typerror( 2, "index out of range" );
|
||||
vm.argerror( 1, "index out of range" );
|
||||
if ( index >= n )
|
||||
vm.resettop();
|
||||
return 0;
|
||||
else {
|
||||
for ( int i=0; i<=index; i++ )
|
||||
vm.remove(1);
|
||||
return n-index;
|
||||
}
|
||||
} else if ( vm.checkstring(2).equals( "#" ) ) {
|
||||
vm.resettop();
|
||||
vm.pushnumber( n - 2 );
|
||||
} else if ( vm.checkstring(1).equals( "#" ) ) {
|
||||
vm.pushnumber( n - 1 );
|
||||
return 1;
|
||||
} else {
|
||||
vm.typerror(2,"expected number or '#'");
|
||||
vm.typerror(1,"expected number or '#'");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case COLLECTGARBAGE: {
|
||||
String s = vm.optstring(2, "collect");
|
||||
String s = vm.optstring(1, "collect");
|
||||
int result = 0;
|
||||
vm.resettop();
|
||||
if ( "collect".equals(s) )
|
||||
System.gc();
|
||||
else if ( "count".equals(s) ) {
|
||||
@@ -347,33 +331,32 @@ public class BaseLib extends LFunction {
|
||||
long used = rt.totalMemory() - rt.freeMemory();
|
||||
result = (int) (used >> 10);
|
||||
} else {
|
||||
vm.typerror(2,"gc op");
|
||||
vm.argerror(2,"gc op");
|
||||
}
|
||||
vm.pushnumber(result);
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case DOFILE:
|
||||
dofile(vm);
|
||||
break;
|
||||
return -1;
|
||||
case LOADSTRING:
|
||||
loadstring(vm, vm.checklstring(2), vm.optstring(3,"(string)"));
|
||||
break;
|
||||
loadstring(vm, vm.checklstring(1), vm.optstring(2,"(string)"));
|
||||
return -1;
|
||||
case LOAD:
|
||||
load(vm);
|
||||
break;
|
||||
return -1;
|
||||
case TOSTRING: {
|
||||
LValue v = vm.checkany(2);
|
||||
vm.resettop();
|
||||
LValue v = vm.checkany(1);
|
||||
vm.pushlvalue( v.luaAsString() );
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case UNPACK: {
|
||||
LTable list = vm.checktable(2);
|
||||
LTable list = vm.checktable(1);
|
||||
int n = vm.gettop();
|
||||
int i = vm.optint(3,1);
|
||||
int i = vm.optint(2,1);
|
||||
int j;
|
||||
if ( n >= 4 ) {
|
||||
j = vm.checkint(4);
|
||||
if ( n >= 3 ) {
|
||||
j = vm.checkint(3);
|
||||
} else {
|
||||
j = list.luaLength();
|
||||
}
|
||||
@@ -381,21 +364,21 @@ public class BaseLib extends LFunction {
|
||||
vm.checkstack(j+1-i);
|
||||
for ( int k=i; k<=j; k++ )
|
||||
vm.pushlvalue(list.get(k));
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
LuaState.vmerror( "bad base id" );
|
||||
return 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static LValue getfunc (LuaState vm, boolean opt) {
|
||||
if ( vm.isfunction(2) )
|
||||
return vm.tofunction(2);
|
||||
if ( vm.isfunction(1) )
|
||||
return vm.tofunction(1);
|
||||
else {
|
||||
int level = opt? vm.optint(2, 1): vm.checkint(2);
|
||||
vm.argcheck(level >= 0, 2, "level must be non-negative");
|
||||
vm.argcheck(level-1 <= vm.cc, 2, "invalid level");
|
||||
int level = opt? vm.optint(1, 1): vm.checkint(1);
|
||||
vm.argcheck(level >= 0, 1, "level must be non-negative");
|
||||
vm.argcheck(level-1 <= vm.cc, 1, "invalid level");
|
||||
CallInfo ci = vm.getStackFrame(level-1);
|
||||
if ( ci == null || ci.closure == null )
|
||||
return LNil.NIL;
|
||||
@@ -483,7 +466,7 @@ public class BaseLib extends LFunction {
|
||||
|
||||
// if load succeeds, return 0 for success, 1 for error (as per lua spec)
|
||||
private void dofile( LuaState vm ) {
|
||||
String filename = vm.optstring(2,null);
|
||||
String filename = vm.optstring(1,null);
|
||||
if ( loadfile( vm, filename ) ) {
|
||||
vm.call(0, 0);
|
||||
} else {
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.lib;
|
||||
|
||||
import org.luaj.vm.LClosure;
|
||||
import org.luaj.vm.LFunction;
|
||||
import org.luaj.vm.LTable;
|
||||
import org.luaj.vm.LThread;
|
||||
@@ -79,21 +78,21 @@ public class CoroutineLib extends LFunction {
|
||||
this.thread = thread;
|
||||
}
|
||||
|
||||
public boolean luaStackCall( LuaState vm ) {
|
||||
public int invoke( LuaState vm ) {
|
||||
switch ( id ) {
|
||||
case INSTALL: {
|
||||
install(vm._G);
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
case CREATE: {
|
||||
LFunction c = vm.checkfunction(2);
|
||||
LFunction c = vm.checkfunction(1);
|
||||
vm.pushlvalue( new LThread( c, c.luaGetEnv(vm._G) ) );
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case RESUME: {
|
||||
LThread t = vm.checkthread(2);
|
||||
t.resumeFrom( vm, vm.gettop()-2 );
|
||||
return false;
|
||||
LThread t = vm.checkthread(1);
|
||||
t.resumeFrom( vm, vm.gettop()-1 );
|
||||
return -1;
|
||||
}
|
||||
case RUNNING: {
|
||||
LThread r = LThread.getRunning();
|
||||
@@ -102,39 +101,41 @@ public class CoroutineLib extends LFunction {
|
||||
} else {
|
||||
vm.pushnil();
|
||||
}
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case STATUS: {
|
||||
vm.pushstring( vm.checkthread(2).getStatus() );
|
||||
break;
|
||||
vm.pushstring( vm.checkthread(1).getStatus() );
|
||||
return 1;
|
||||
}
|
||||
case WRAP: {
|
||||
LFunction c = vm.checkfunction(2);
|
||||
LFunction c = vm.checkfunction(1);
|
||||
vm.pushlvalue( new CoroutineLib(WRAPPED,new LThread(c, c.luaGetEnv(vm._G))) );
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case YIELD: {
|
||||
LThread r = LThread.getRunning();
|
||||
if ( r == null )
|
||||
if ( r == null ) {
|
||||
vm.error("main thread can't yield");
|
||||
else {
|
||||
return r.yield();
|
||||
return 0;
|
||||
}
|
||||
r.yield();
|
||||
return -1;
|
||||
}
|
||||
case WRAPPED: {
|
||||
LThread t = this.thread;
|
||||
t.resumeFrom( vm, vm.gettop()-1 );
|
||||
if ( vm.toboolean(1) )
|
||||
t.resumeFrom( vm, vm.gettop() );
|
||||
if ( vm.toboolean(1) ) {
|
||||
vm.remove(1);
|
||||
else
|
||||
return -1;
|
||||
} else {
|
||||
vm.error( vm.tostring(2) );
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
default: {
|
||||
LuaState.vmerror( "bad coroutine id" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
vm.insert(1);
|
||||
vm.settop(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -108,88 +108,74 @@ public class DebugLib extends LFunction {
|
||||
return NAMES[id]+"()";
|
||||
}
|
||||
|
||||
public boolean luaStackCall( LuaState vm ) {
|
||||
public int invoke( LuaState vm ) {
|
||||
switch ( id ) {
|
||||
case INSTALL:
|
||||
install(vm);
|
||||
break;
|
||||
return 0;
|
||||
case DEBUG:
|
||||
debug(vm);
|
||||
break;
|
||||
return debug(vm);
|
||||
case GETFENV:
|
||||
getfenv(vm);
|
||||
break;
|
||||
return getfenv(vm);
|
||||
case GETHOOK:
|
||||
gethook(vm);
|
||||
break;
|
||||
return gethook(vm);
|
||||
case GETINFO:
|
||||
getinfo(vm);
|
||||
break;
|
||||
return getinfo(vm);
|
||||
case GETLOCAL:
|
||||
getlocal(vm);
|
||||
break;
|
||||
return getlocal(vm);
|
||||
case GETMETATABLE:
|
||||
getmetatable(vm);
|
||||
break;
|
||||
return getmetatable(vm);
|
||||
case GETREGISTRY:
|
||||
getregistry(vm);
|
||||
break;
|
||||
return getregistry(vm);
|
||||
case GETUPVALUE:
|
||||
getupvalue(vm);
|
||||
break;
|
||||
return getupvalue(vm);
|
||||
case SETFENV:
|
||||
setfenv(vm);
|
||||
break;
|
||||
return setfenv(vm);
|
||||
case SETHOOK:
|
||||
sethook(vm);
|
||||
break;
|
||||
return sethook(vm);
|
||||
case SETLOCAL:
|
||||
setlocal(vm);
|
||||
break;
|
||||
return setlocal(vm);
|
||||
case SETMETATABLE:
|
||||
setmetatable(vm);
|
||||
break;
|
||||
return setmetatable(vm);
|
||||
case SETUPVALUE:
|
||||
setupvalue(vm);
|
||||
break;
|
||||
return setupvalue(vm);
|
||||
case TRACEBACK:
|
||||
traceback(vm);
|
||||
break;
|
||||
return traceback(vm);
|
||||
default:
|
||||
LuaState.vmerror( "bad package id" );
|
||||
return 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// j2se subclass may wish to override and provide actual console here.
|
||||
// j2me platform has not System.in to provide console.
|
||||
protected void debug(LuaState vm) {
|
||||
vm.resettop();
|
||||
protected int debug(LuaState vm) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void gethook(LuaState vm) {
|
||||
protected int gethook(LuaState vm) {
|
||||
LuaState threadVm = vm;
|
||||
if ( vm.gettop() >= 2 )
|
||||
threadVm = vm.checkthread(2).vm;
|
||||
vm.resettop();
|
||||
threadVm = vm.checkthread(1).vm;
|
||||
vm.pushlvalue(threadVm.gethook());
|
||||
vm.pushinteger(threadVm.gethookmask());
|
||||
vm.pushinteger(threadVm.gethookcount());
|
||||
return 3;
|
||||
}
|
||||
|
||||
protected LuaState optthreadvm(LuaState vm, int index) {
|
||||
if ( ! vm.isthread(2) )
|
||||
if ( ! vm.isthread(index) )
|
||||
return vm;
|
||||
LuaState threadVm = vm.checkthread(2).vm;
|
||||
vm.remove(2);
|
||||
LuaState threadVm = vm.checkthread(index).vm;
|
||||
vm.remove(index);
|
||||
return threadVm;
|
||||
}
|
||||
|
||||
protected void sethook(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 2);
|
||||
LFunction func = vm.isnoneornil(2)? null: vm.checkfunction(2);
|
||||
String str = vm.optstring(3,"");
|
||||
int count = vm.optint(4,0);
|
||||
protected int sethook(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 1);
|
||||
LFunction func = vm.isnoneornil(1)? null: vm.checkfunction(2);
|
||||
String str = vm.optstring(2,"");
|
||||
int count = vm.optint(3,0);
|
||||
int mask = 0;
|
||||
for ( int i=0; i<str.length(); i++ )
|
||||
switch ( str.charAt(i) ) {
|
||||
@@ -198,41 +184,40 @@ public class DebugLib extends LFunction {
|
||||
case 'r': mask |= LuaState.LUA_MASKRET; break;
|
||||
}
|
||||
threadVm.sethook(func, mask, count);
|
||||
vm.resettop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void getfenv(LuaState vm) {
|
||||
LValue object = vm.topointer(2);
|
||||
protected int getfenv(LuaState vm) {
|
||||
LValue object = vm.topointer(1);
|
||||
LValue env = object.luaGetEnv(null);
|
||||
vm.resettop();
|
||||
vm.pushlvalue(env!=null? env: LNil.NIL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected void setfenv(LuaState vm) {
|
||||
LValue object = vm.topointer(2);
|
||||
LTable table = vm.checktable(3);
|
||||
protected int setfenv(LuaState vm) {
|
||||
LValue object = vm.topointer(1);
|
||||
LTable table = vm.checktable(2);
|
||||
object.luaSetEnv(table);
|
||||
vm.settop(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected void getinfo(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 2);
|
||||
String what = vm.optstring(3, "nSluf");
|
||||
protected int getinfo(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 1);
|
||||
String what = vm.optstring(2, "nSluf");
|
||||
|
||||
// find the stack info
|
||||
StackInfo si;
|
||||
if ( vm.isnumber(2) ) {
|
||||
int level = vm.tointeger(2);
|
||||
if ( vm.isnumber(1) ) {
|
||||
int level = vm.tointeger(1);
|
||||
si = getstackinfo(threadVm, level, 1)[0];
|
||||
if ( si == null ) {
|
||||
vm.resettop();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
LFunction func = vm.checkfunction(2);
|
||||
LFunction func = vm.checkfunction(1);
|
||||
si = findstackinfo(threadVm, func);
|
||||
}
|
||||
vm.resettop();
|
||||
|
||||
// look up info
|
||||
LTable info = new LTable();
|
||||
@@ -288,75 +273,75 @@ public class DebugLib extends LFunction {
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected void getlocal(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 2);
|
||||
int level = vm.checkint(2);
|
||||
int local = vm.checkint(3);
|
||||
protected int getlocal(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 1);
|
||||
int level = vm.checkint(1);
|
||||
int local = vm.checkint(2);
|
||||
StackInfo si = getstackinfo(threadVm, level, 1)[0];
|
||||
CallInfo ci = (si!=null? si.luainfo: null);
|
||||
LPrototype p = (ci!=null? ci.closure.p: null);
|
||||
LString name = (p!=null? p.getlocalname(local, ci.pc>0? ci.pc-1: 0): null);
|
||||
if ( name != null ) {
|
||||
LValue value = threadVm.stack[ci.base+(local-1)];
|
||||
vm.resettop();
|
||||
vm.pushlvalue( name );
|
||||
vm.pushlvalue( value );
|
||||
return 2;
|
||||
} else {
|
||||
vm.resettop();
|
||||
vm.pushnil();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setlocal(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 2);
|
||||
int level = vm.checkint(2);
|
||||
int local = vm.checkint(3);
|
||||
LValue value = vm.topointer(4);
|
||||
protected int setlocal(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 1);
|
||||
int level = vm.checkint(1);
|
||||
int local = vm.checkint(2);
|
||||
LValue value = vm.topointer(3);
|
||||
StackInfo si = getstackinfo(threadVm, level, 1)[0];
|
||||
CallInfo ci = (si!=null? si.luainfo: null);
|
||||
LPrototype p = (ci!=null? ci.closure.p: null);
|
||||
LString name = (p!=null? p.getlocalname(local, ci.pc>0? ci.pc-1: 0): null);
|
||||
if ( name != null ) {
|
||||
threadVm.stack[ci.base+(local-1)] = value;
|
||||
vm.resettop();
|
||||
vm.pushlvalue(name);
|
||||
} else {
|
||||
vm.resettop();
|
||||
vm.pushnil();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected void getmetatable(LuaState vm) {
|
||||
LValue object = vm.topointer(2);
|
||||
vm.resettop();
|
||||
protected int getmetatable(LuaState vm) {
|
||||
LValue object = vm.topointer(1);
|
||||
LValue mt = object.luaGetMetatable();
|
||||
if ( mt != null )
|
||||
vm.pushlvalue( object.luaGetMetatable() );
|
||||
else
|
||||
vm.pushnil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected void setmetatable(LuaState vm) {
|
||||
LValue object = vm.topointer(2);
|
||||
protected int setmetatable(LuaState vm) {
|
||||
LValue object = vm.topointer(1);
|
||||
try {
|
||||
if ( ! vm.isnoneornil(3) )
|
||||
if ( ! vm.isnoneornil(2) )
|
||||
object.luaSetMetatable(vm.checktable(3));
|
||||
else
|
||||
object.luaSetMetatable(null);
|
||||
vm.resettop();
|
||||
vm.pushboolean(true);
|
||||
return 1;
|
||||
} catch ( LuaErrorException e ) {
|
||||
vm.resettop();
|
||||
vm.pushboolean(false);
|
||||
vm.pushstring(e.toString());
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
protected void getregistry(LuaState vm) {
|
||||
vm.resettop();
|
||||
protected int getregistry(LuaState vm) {
|
||||
vm.pushlvalue( new LTable() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
private LString findupvalue(LClosure c, int up) {
|
||||
@@ -369,9 +354,9 @@ public class DebugLib extends LFunction {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void getupvalue(LuaState vm) {
|
||||
LFunction func = vm.checkfunction(2);
|
||||
int up = vm.checkint(3);
|
||||
protected int getupvalue(LuaState vm) {
|
||||
LFunction func = vm.checkfunction(1);
|
||||
int up = vm.checkint(2);
|
||||
vm.resettop();
|
||||
if ( func instanceof LClosure ) {
|
||||
LClosure c = (LClosure) func;
|
||||
@@ -379,16 +364,17 @@ public class DebugLib extends LFunction {
|
||||
if ( name != null ) {
|
||||
vm.pushlstring(name);
|
||||
vm.pushlvalue(c.upVals[up-1].getValue());
|
||||
return;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
vm.pushnil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected void setupvalue(LuaState vm) {
|
||||
LFunction func = vm.checkfunction(2);
|
||||
int up = vm.checkint(3);
|
||||
LValue value = vm.topointer(4);
|
||||
protected int setupvalue(LuaState vm) {
|
||||
LFunction func = vm.checkfunction(1);
|
||||
int up = vm.checkint(2);
|
||||
LValue value = vm.topointer(3);
|
||||
vm.resettop();
|
||||
if ( func instanceof LClosure ) {
|
||||
LClosure c = (LClosure) func;
|
||||
@@ -396,18 +382,19 @@ public class DebugLib extends LFunction {
|
||||
if ( name != null ) {
|
||||
c.upVals[up-1].setValue(value);
|
||||
vm.pushlstring(name);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
vm.pushnil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected void traceback(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 2);
|
||||
protected int traceback(LuaState vm) {
|
||||
LuaState threadVm = optthreadvm(vm, 1);
|
||||
String message = "";
|
||||
int level = vm.optint(3,1);
|
||||
if ( ! vm.isnoneornil(2) )
|
||||
message = vm.checkstring(2)+"\n";
|
||||
int level = vm.optint(2,1);
|
||||
if ( ! vm.isnoneornil(1) )
|
||||
message = vm.checkstring(1)+"\n";
|
||||
StackInfo[] s = getstackinfo(threadVm, level, 10);
|
||||
StringBuffer sb = new StringBuffer("stack traceback:");
|
||||
for ( int i=0; i<s.length; i++ ) {
|
||||
@@ -419,8 +406,8 @@ public class DebugLib extends LFunction {
|
||||
sb.append( si.tracename() );
|
||||
}
|
||||
}
|
||||
vm.resettop();
|
||||
vm.pushstring(message+sb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// =======================================================
|
||||
|
||||
@@ -214,7 +214,7 @@ public class IoLib extends LFunction {
|
||||
return LNil.NIL;
|
||||
}
|
||||
|
||||
public boolean luaStackCall( LuaState vm ) {
|
||||
public int invoke( LuaState vm ) {
|
||||
File f;
|
||||
int n;
|
||||
try {
|
||||
@@ -222,49 +222,47 @@ public class IoLib extends LFunction {
|
||||
/* Load the table library dynamically */
|
||||
case INSTALL:
|
||||
initialize(vm._G);
|
||||
break;
|
||||
return 0;
|
||||
case IO_CLOSE:
|
||||
f = vm.isnoneornil(2)?
|
||||
f = vm.isnoneornil(1)?
|
||||
output(vm):
|
||||
checkfile(vm,2);
|
||||
checkfile(vm,1);
|
||||
checkopen(vm, f);
|
||||
ioclose(vm,f);
|
||||
break;
|
||||
case IO_FLUSH:
|
||||
checkopen(vm,output(vm));
|
||||
OUTPUT.flush();
|
||||
vm.resettop();
|
||||
vm.pushboolean(true);
|
||||
break;
|
||||
return 1;
|
||||
case IO_INPUT:
|
||||
INPUT = vm.isnoneornil(2)?
|
||||
INPUT = vm.isnoneornil(1)?
|
||||
input(vm):
|
||||
vm.isstring(2)?
|
||||
ioopenfile(vm,vm.checkstring(2),"r"):
|
||||
checkfile(vm,2);
|
||||
vm.isstring(1)?
|
||||
ioopenfile(vm,vm.checkstring(1),"r"):
|
||||
checkfile(vm,1);
|
||||
setresult(vm, INPUT);
|
||||
break;
|
||||
case IO_LINES:
|
||||
INPUT = vm.isnoneornil(2)?
|
||||
INPUT = vm.isnoneornil(1)?
|
||||
input(vm):
|
||||
ioopenfile(vm,vm.checkstring(2),"r");
|
||||
ioopenfile(vm,vm.checkstring(1),"r");
|
||||
checkopen(vm, INPUT);
|
||||
vm.resettop();
|
||||
vm.pushlvalue(lines(vm,INPUT));
|
||||
break;
|
||||
return 1;
|
||||
case IO_OPEN:
|
||||
setresult(vm, rawopenfile(vm.checkstring(2), vm.optstring(3,"r")));
|
||||
setresult(vm, rawopenfile(vm.checkstring(1), vm.optstring(2,"r")));
|
||||
break;
|
||||
case IO_OUTPUT:
|
||||
OUTPUT = vm.isnoneornil(2)?
|
||||
OUTPUT = vm.isnoneornil(1)?
|
||||
output(vm):
|
||||
vm.isstring(2)?
|
||||
ioopenfile(vm,vm.checkstring(2),"w"):
|
||||
checkfile(vm,2);
|
||||
vm.isstring(1)?
|
||||
ioopenfile(vm,vm.checkstring(1),"w"):
|
||||
checkfile(vm,1);
|
||||
setresult(vm, OUTPUT);
|
||||
break;
|
||||
case IO_POPEN:
|
||||
setresult(vm, openProgram(vm.checkstring(2),vm.optstring(3, "r")));
|
||||
setresult(vm, openProgram(vm.checkstring(1),vm.optstring(2, "r")));
|
||||
break;
|
||||
case IO_READ:
|
||||
checkopen(vm, INPUT);
|
||||
@@ -274,54 +272,49 @@ public class IoLib extends LFunction {
|
||||
setresult(vm, tmpFile());
|
||||
break;
|
||||
case IO_TYPE:
|
||||
f = optfile(vm,2);
|
||||
vm.resettop();
|
||||
f = optfile(vm,1);
|
||||
if ( f != null )
|
||||
vm.pushstring(f.isclosed()? "closed file": "file");
|
||||
else
|
||||
vm.pushnil();
|
||||
break;
|
||||
return 1;
|
||||
case IO_WRITE:
|
||||
checkopen(vm, output(vm));
|
||||
iowrite( vm, OUTPUT );
|
||||
break;
|
||||
case FILE_CLOSE:
|
||||
f = checkfile(vm,2);
|
||||
f = checkfile(vm,1);
|
||||
ioclose(vm, f);
|
||||
break;
|
||||
case FILE_FLUSH:
|
||||
f = checkfile(vm,2);
|
||||
f = checkfile(vm,1);
|
||||
f.flush();
|
||||
vm.resettop();
|
||||
vm.pushboolean(true);
|
||||
break;
|
||||
return 1;
|
||||
case FILE_LINES:
|
||||
f = checkfile(vm,2);
|
||||
vm.resettop();
|
||||
f = checkfile(vm,1);
|
||||
vm.pushlvalue(lines(vm,f));
|
||||
break;
|
||||
return 1;
|
||||
case FILE_READ:
|
||||
f = checkfile(vm,2);
|
||||
vm.remove(2);
|
||||
f = checkfile(vm,1);
|
||||
vm.remove(1);
|
||||
ioread(vm, f);
|
||||
break;
|
||||
case FILE_SEEK:
|
||||
f = checkfile(vm,2);
|
||||
vm.remove(2);
|
||||
n = f.seek(vm.optstring(2,"cur"),vm.optint(3, 0));
|
||||
vm.resettop();
|
||||
f = checkfile(vm,1);
|
||||
vm.remove(1);
|
||||
n = f.seek(vm.optstring(1,"cur"),vm.optint(2, 0));
|
||||
vm.pushinteger(n);
|
||||
break;
|
||||
return 1;
|
||||
case FILE_SETVBUF:
|
||||
f = checkfile(vm,2);
|
||||
vm.remove(2);
|
||||
f.setvbuf(vm.checkstring(2),vm.optint(3, 1024));
|
||||
vm.resettop();
|
||||
f = checkfile(vm,1);
|
||||
vm.remove(1);
|
||||
f.setvbuf(vm.checkstring(1),vm.optint(2, 1024));
|
||||
vm.pushboolean(true);
|
||||
break;
|
||||
return 1;
|
||||
case FILE_WRITE:
|
||||
f = checkfile(vm,2);
|
||||
vm.remove(2);
|
||||
f = checkfile(vm,1);
|
||||
vm.remove(1);
|
||||
iowrite( vm, f );
|
||||
break;
|
||||
default:
|
||||
@@ -330,7 +323,7 @@ public class IoLib extends LFunction {
|
||||
} catch ( IOException ioe ) {
|
||||
seterrorresult(vm,ioe);
|
||||
}
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static void ioclose(LuaState vm, File f) throws IOException {
|
||||
@@ -373,7 +366,7 @@ public class IoLib extends LFunction {
|
||||
}
|
||||
|
||||
private static void iowrite(LuaState vm, File f) throws IOException {
|
||||
for ( int i=2, n=vm.gettop(); i<=n; i++ )
|
||||
for ( int i=1, n=vm.gettop(); i<=n; i++ )
|
||||
f.write( vm.checklstring(i) );
|
||||
vm.resettop();
|
||||
vm.pushboolean(true);
|
||||
@@ -381,7 +374,7 @@ public class IoLib extends LFunction {
|
||||
|
||||
private static void ioread(LuaState vm, File f) throws IOException {
|
||||
int i,n=vm.gettop();
|
||||
for ( i=2; i<=n; i++ ) {
|
||||
for ( i=1; i<=n; i++ ) {
|
||||
if ( vm.isnumber(i) ) {
|
||||
vm.pushlvalue(freadbytes(f,vm.tointeger(i)));
|
||||
} else {
|
||||
|
||||
@@ -25,10 +25,7 @@ import java.util.Random;
|
||||
|
||||
import org.luaj.vm.LDouble;
|
||||
import org.luaj.vm.LFunction;
|
||||
import org.luaj.vm.LInteger;
|
||||
import org.luaj.vm.LNumber;
|
||||
import org.luaj.vm.LTable;
|
||||
import org.luaj.vm.LValue;
|
||||
import org.luaj.vm.LuaState;
|
||||
import org.luaj.vm.Platform;
|
||||
|
||||
@@ -142,105 +139,89 @@ public class MathLib extends LFunction {
|
||||
vm.pushlvalue( LDouble.valueOf(d) );
|
||||
}
|
||||
|
||||
private static void setResult( LuaState vm, int i ) {
|
||||
vm.resettop();
|
||||
vm.pushlvalue( LInteger.valueOf(i) );
|
||||
}
|
||||
|
||||
private static void setResult(LuaState vm, LNumber mathop) {
|
||||
vm.resettop();
|
||||
vm.pushlvalue( mathop );
|
||||
}
|
||||
|
||||
public boolean luaStackCall( LuaState vm ) {
|
||||
public int invoke(LuaState vm) {
|
||||
if ( id > LAST_DOUBLE_ARG ) {
|
||||
setResult( vm, platform.mathop(id, vm.checknumber(2) ) );
|
||||
vm.pushlvalue( platform.mathop(id, vm.checknumber(1) ) );
|
||||
return 1;
|
||||
} else if ( id > LAST_IRREGULAR ) {
|
||||
setResult( vm, platform.mathop(id, vm.checknumber(2), vm.checknumber(3) ) );
|
||||
vm.pushlvalue( platform.mathop(id, vm.checknumber(1), vm.checknumber(2) ) );
|
||||
return 1;
|
||||
} else {
|
||||
switch ( id ) {
|
||||
case INSTALL:
|
||||
install( vm._G );
|
||||
break;
|
||||
return 0;
|
||||
case MAX: {
|
||||
int n = vm.gettop();
|
||||
double x = vm.checkdouble(2);
|
||||
for ( int i=3; i<=n; i++ )
|
||||
double x = vm.checkdouble(1);
|
||||
for ( int i=2; i<=n; i++ )
|
||||
x = Math.max(x, vm.checkdouble(i));
|
||||
setResult( vm, x );
|
||||
break;
|
||||
vm.pushnumber( x );
|
||||
return 1;
|
||||
}
|
||||
case MIN: {
|
||||
int n = vm.gettop();
|
||||
double x = vm.checkdouble(2);
|
||||
for ( int i=3; i<=n; i++ )
|
||||
double x = vm.checkdouble(1);
|
||||
for ( int i=2; i<=n; i++ )
|
||||
x = Math.min(x, vm.checkdouble(i));
|
||||
setResult(vm,x);
|
||||
break;
|
||||
vm.pushnumber( x );
|
||||
return 1;
|
||||
}
|
||||
case MODF: {
|
||||
double x = vm.checkdouble(2);
|
||||
double x = vm.checkdouble(1);
|
||||
double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x );
|
||||
double fracPart = x - intPart;
|
||||
vm.resettop();
|
||||
vm.pushnumber( intPart );
|
||||
vm.pushnumber( fracPart );
|
||||
break;
|
||||
return 2;
|
||||
}
|
||||
case CEIL:
|
||||
setResult( vm, (int) Math.ceil( vm.checkdouble(2) ) );
|
||||
break;
|
||||
vm.pushnumber( Math.ceil( vm.checkdouble(1) ) );
|
||||
return 1;
|
||||
case FLOOR:
|
||||
setResult( vm, (int) Math.floor( vm.checkdouble(2) ) );
|
||||
break;
|
||||
vm.pushnumber( Math.floor( vm.checkdouble(1) ) );
|
||||
return 1;
|
||||
case FREXP: {
|
||||
long bits = Double.doubleToLongBits( vm.checkdouble(2) );
|
||||
vm.resettop();
|
||||
long bits = Double.doubleToLongBits( vm.checkdouble(1) );
|
||||
vm.pushnumber( ((bits & (~(-1L<<52))) + (1L<<52)) * ((bits >= 0)? (.5 / (1L<<52)): (-.5 / (1L<<52))) );
|
||||
vm.pushinteger( (((int) (bits >> 52)) & 0x7ff) - 1022 );
|
||||
break;
|
||||
return 2;
|
||||
}
|
||||
case LDEXP: {
|
||||
double m = vm.checkdouble(2);
|
||||
int e = vm.checkint(3);
|
||||
vm.resettop();
|
||||
double m = vm.checkdouble(1);
|
||||
int e = vm.checkint(2);
|
||||
vm.pushnumber( m * Double.longBitsToDouble(((long)(e+1023)) << 52) );
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case RANDOM: {
|
||||
if ( random == null )
|
||||
random = new Random(1);
|
||||
switch ( vm.gettop() ) {
|
||||
case 1:
|
||||
vm.resettop();
|
||||
case 0:
|
||||
vm.pushnumber(random.nextDouble());
|
||||
break;
|
||||
case 2: {
|
||||
int m = vm.checkint(2);
|
||||
return 1;
|
||||
case 1: {
|
||||
int m = vm.checkint(1);
|
||||
vm.argcheck(1<=m, 1, "interval is empty");
|
||||
vm.resettop();
|
||||
vm.pushinteger(1+random.nextInt(m));
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
default: {
|
||||
int m = vm.checkint(2);
|
||||
int n = vm.checkint(3);
|
||||
int m = vm.checkint(1);
|
||||
int n = vm.checkint(2);
|
||||
vm.argcheck(m<=n, 2, "interval is empty");
|
||||
vm.resettop();
|
||||
vm.pushinteger(m+random.nextInt(n+1-m));
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RSEED:
|
||||
random = new Random( vm.checkint(2) );
|
||||
vm.resettop();
|
||||
break;
|
||||
random = new Random( vm.checkint(1) );
|
||||
return 0;
|
||||
default:
|
||||
LuaState.vmerror( "bad math id" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ public class OsLib extends LFunction {
|
||||
return NAMES[id]+"()";
|
||||
}
|
||||
|
||||
public boolean luaStackCall( LuaState vm ) {
|
||||
public int invoke( LuaState vm ) {
|
||||
LValue v;
|
||||
long t,t2;
|
||||
int c;
|
||||
@@ -131,72 +131,62 @@ public class OsLib extends LFunction {
|
||||
switch ( id ) {
|
||||
case INSTALL:
|
||||
install(vm._G, this);
|
||||
break;
|
||||
return 0;
|
||||
case CLOCK:
|
||||
vm.resettop();
|
||||
vm.pushnumber(clock());
|
||||
break;
|
||||
return 1;
|
||||
case DATE:
|
||||
s = vm.optstring(2, null);
|
||||
t = vm.optlong(3,-1);
|
||||
vm.resettop();
|
||||
s = vm.optstring(1, null);
|
||||
t = vm.optlong(2,-1);
|
||||
vm.pushlvalue( date(s, t==-1? System.currentTimeMillis(): t) );
|
||||
break;
|
||||
return 1;
|
||||
case DIFFTIME:
|
||||
t2 = vm.checklong(2);
|
||||
t = vm.checklong(3);
|
||||
vm.resettop();
|
||||
t2 = vm.checklong(1);
|
||||
t = vm.checklong(2);
|
||||
vm.pushnumber(difftime(t2,t));
|
||||
break;
|
||||
return 1;
|
||||
case EXECUTE:
|
||||
c = execute(vm.optstring(2, null));
|
||||
vm.resettop();
|
||||
c = execute(vm.optstring(1, null));
|
||||
vm.pushinteger(c);
|
||||
break;
|
||||
return 1;
|
||||
case EXIT:
|
||||
exit(vm.optint(2, 0));
|
||||
break;
|
||||
exit(vm.optint(1, 0));
|
||||
return 0;
|
||||
case GETENV:
|
||||
s = getenv(vm.checkstring(2));
|
||||
vm.resettop();
|
||||
s = getenv(vm.checkstring(1));
|
||||
vm.pushstring(s);
|
||||
break;
|
||||
return 1;
|
||||
case REMOVE:
|
||||
remove(vm.checkstring(2));
|
||||
vm.resettop();
|
||||
remove(vm.checkstring(1));
|
||||
vm.pushboolean(true);
|
||||
break;
|
||||
return 1;
|
||||
case RENAME:
|
||||
rename(vm.checkstring(2), vm.checkstring(3));
|
||||
vm.resettop();
|
||||
rename(vm.checkstring(1), vm.checkstring(2));
|
||||
vm.pushboolean(true);
|
||||
break;
|
||||
return 1;
|
||||
case SETLOCALE:
|
||||
s = setlocale(vm.optstring(2,null), vm.optstring(3, "all"));
|
||||
vm.resettop();
|
||||
s = setlocale(vm.optstring(1,null), vm.optstring(2, "all"));
|
||||
if ( s != null )
|
||||
vm.pushstring(s);
|
||||
else
|
||||
vm.pushnil();
|
||||
break;
|
||||
return 1;
|
||||
case TIME:
|
||||
t = time(vm.isnoneornil(2)? null: vm.checktable(2));
|
||||
vm.resettop();
|
||||
t = time(vm.isnoneornil(1)? null: vm.checktable(1));
|
||||
vm.pushnumber(t);
|
||||
break;
|
||||
return 1;
|
||||
case TMPNAME:
|
||||
vm.resettop();
|
||||
vm.pushstring(tmpname());
|
||||
break;
|
||||
return 1;
|
||||
default:
|
||||
LuaState.vmerror( "bad os id" );
|
||||
return 0;
|
||||
}
|
||||
} catch ( IOException e ) {
|
||||
vm.resettop();
|
||||
vm.pushnil();
|
||||
vm.pushstring(e.getMessage());
|
||||
return 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -115,45 +115,38 @@ public class PackageLib extends LFunction {
|
||||
return NAMES[id]+"()";
|
||||
}
|
||||
|
||||
public boolean luaStackCall( LuaState vm ) {
|
||||
public int invoke( LuaState vm ) {
|
||||
switch ( id ) {
|
||||
case INSTALL:
|
||||
install(vm._G);
|
||||
break;
|
||||
return 0;
|
||||
case MODULE:
|
||||
module(vm);
|
||||
break;
|
||||
return module(vm);
|
||||
case REQUIRE:
|
||||
require(vm);
|
||||
break;
|
||||
return require(vm);
|
||||
case LOADLIB:
|
||||
loadlib(vm);
|
||||
break;
|
||||
return loadlib(vm);
|
||||
case SEEALL: {
|
||||
LTable t = vm.checktable(2);
|
||||
LTable t = vm.checktable(1);
|
||||
LTable m = t.luaGetMetatable();
|
||||
if ( m == null )
|
||||
t.luaSetMetatable(m = new LTable());
|
||||
m.put(__INDEX, vm._G);
|
||||
vm.resettop();
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
case PRELOAD_LOADER: {
|
||||
loader_preload(vm);
|
||||
break;
|
||||
return loader_preload(vm);
|
||||
}
|
||||
case LUA_LOADER: {
|
||||
loader_Lua(vm);
|
||||
break;
|
||||
return loader_Lua(vm);
|
||||
}
|
||||
case JAVA_LOADER: {
|
||||
loader_Java(vm);
|
||||
break;
|
||||
return loader_Java(vm);
|
||||
}
|
||||
default:
|
||||
LuaState.vmerror( "bad package id" );
|
||||
return 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,8 +172,8 @@ public class PackageLib extends LFunction {
|
||||
* This function may receive optional options after the module name, where
|
||||
* each option is a function to be applied over the module.
|
||||
*/
|
||||
public static void module(LuaState vm) {
|
||||
LString modname = vm.checklstring(2);
|
||||
public static int module(LuaState vm) {
|
||||
LString modname = vm.checklstring(1);
|
||||
int n = vm.gettop();
|
||||
LValue value = LOADED.luaGetTable(vm, modname);
|
||||
LTable module;
|
||||
@@ -207,14 +200,14 @@ public class PackageLib extends LFunction {
|
||||
ci.closure.env = module;
|
||||
|
||||
// apply the functions
|
||||
for ( int i=3; i<=n; i++ ) {
|
||||
for ( int i=2; i<=n; i++ ) {
|
||||
vm.pushvalue( i ); /* get option (a function) */
|
||||
vm.pushlvalue( module ); /* module */
|
||||
vm.call( 1, 0 );
|
||||
}
|
||||
|
||||
// returns no results
|
||||
vm.resettop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,30 +271,29 @@ public class PackageLib extends LFunction {
|
||||
* If there is any error loading or running the module, or if it cannot find any loader for
|
||||
* the module, then require signals an error.
|
||||
*/
|
||||
public void require( LuaState vm ) {
|
||||
LString name = vm.checklstring(2);
|
||||
public int require( LuaState vm ) {
|
||||
LString name = vm.checklstring(1);
|
||||
LValue loaded = LOADED.luaGetTable(vm, name);
|
||||
if ( loaded.toJavaBoolean() ) {
|
||||
if ( loaded == _SENTINEL )
|
||||
vm.error("loop or previous error loading module '"+name+"'");
|
||||
vm.resettop();
|
||||
vm.pushlvalue( loaded );
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
vm.resettop();
|
||||
|
||||
/* else must load it; iterate over available loaders */
|
||||
LValue val = pckg.luaGetTable(vm, _LOADERS);
|
||||
if ( ! val.isTable() )
|
||||
vm.error( "'package.loaders' must be a table" );
|
||||
vm.pushlvalue(val);
|
||||
LTable tbl = (LTable) val;
|
||||
Vector v = new Vector();
|
||||
for ( int i=1; true; i++ ) {
|
||||
vm.rawgeti(1, i);
|
||||
if ( vm.isnil(-1) ) {
|
||||
LValue loader = tbl.get(i);
|
||||
if ( loader.isNil() ) {
|
||||
vm.error( "module '"+name+"' not found: "+v );
|
||||
}
|
||||
/* call loader with module name as argument */
|
||||
vm.pushlvalue(loader);
|
||||
vm.pushlstring(name);
|
||||
vm.call(1, 1);
|
||||
if ( vm.isfunction(-1) )
|
||||
@@ -321,45 +313,45 @@ public class PackageLib extends LFunction {
|
||||
if ( result == _SENTINEL ) { /* module did not set a value? */
|
||||
LOADED.luaSetTable(vm, name, result=LBoolean.TRUE ); /* _LOADED[name] = true */
|
||||
}
|
||||
vm.resettop();
|
||||
vm.pushlvalue(result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static void loadlib( LuaState vm ) {
|
||||
vm.checkstring(2);
|
||||
vm.resettop();
|
||||
public static int loadlib( LuaState vm ) {
|
||||
vm.checkstring(1);
|
||||
vm.pushnil();
|
||||
vm.pushstring("dynamic libraries not enabled");
|
||||
vm.pushstring("absent");
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
private void loader_preload( LuaState vm ) {
|
||||
LString name = vm.tolstring(2);
|
||||
private int loader_preload( LuaState vm ) {
|
||||
LString name = vm.tolstring(1);
|
||||
LValue preload = pckg.luaGetTable(vm, _PRELOAD);
|
||||
if ( ! preload.isTable() )
|
||||
vm.error("package.preload '"+name+"' must be a table");
|
||||
LValue val = preload.luaGetTable(vm, name);
|
||||
if ( val.isNil() )
|
||||
vm.pushstring("\n\tno field package.preload['"+name+"']");
|
||||
vm.resettop();
|
||||
else
|
||||
vm.pushlvalue(val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void loader_Lua( LuaState vm ) {
|
||||
String name = vm.tostring(2);
|
||||
private int loader_Lua( LuaState vm ) {
|
||||
String name = vm.tostring(1);
|
||||
InputStream is = findfile( vm, name, _PATH );
|
||||
if ( is != null ) {
|
||||
String filename = vm.tostring(-1);
|
||||
if ( ! BaseLib.loadis(vm, is, filename) )
|
||||
loaderror( vm, filename );
|
||||
}
|
||||
vm.insert(1);
|
||||
vm.settop(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void loader_Java( LuaState vm ) {
|
||||
String name = vm.tostring(2);
|
||||
private int loader_Java( LuaState vm ) {
|
||||
String name = vm.tostring(1);
|
||||
Class c = null;
|
||||
LValue v = null;
|
||||
try {
|
||||
@@ -371,8 +363,7 @@ public class PackageLib extends LFunction {
|
||||
} catch ( Exception e ) {
|
||||
vm.pushstring("\n\tjava load failed on '"+name+"', "+e );
|
||||
}
|
||||
vm.insert(1);
|
||||
vm.settop(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
private InputStream findfile(LuaState vm, String name, LString pname) {
|
||||
|
||||
@@ -92,58 +92,44 @@ public class StringLib extends LFunction {
|
||||
return NAMES[id]+"()";
|
||||
}
|
||||
|
||||
public boolean luaStackCall( LuaState vm ) {
|
||||
public int invoke( LuaState vm ) {
|
||||
switch ( id ) {
|
||||
case INSTALL:
|
||||
install( vm._G );
|
||||
break;
|
||||
return 0;
|
||||
case BYTE:
|
||||
StringLib.byte_( vm );
|
||||
break;
|
||||
return StringLib.byte_( vm );
|
||||
case CHAR:
|
||||
StringLib.char_( vm );
|
||||
break;
|
||||
return StringLib.char_( vm );
|
||||
case DUMP:
|
||||
StringLib.dump( vm );
|
||||
break;
|
||||
return StringLib.dump( vm );
|
||||
case FIND:
|
||||
StringLib.find( vm );
|
||||
break;
|
||||
return StringLib.find( vm );
|
||||
case FORMAT:
|
||||
StringLib.format( vm );
|
||||
break;
|
||||
return StringLib.format( vm );
|
||||
case GMATCH:
|
||||
StringLib.gmatch( vm );
|
||||
break;
|
||||
return StringLib.gmatch( vm );
|
||||
case GSUB:
|
||||
StringLib.gsub( vm );
|
||||
break;
|
||||
return StringLib.gsub( vm );
|
||||
case LEN:
|
||||
StringLib.len( vm );
|
||||
break;
|
||||
return StringLib.len( vm );
|
||||
case LOWER:
|
||||
StringLib.lower( vm );
|
||||
break;
|
||||
return StringLib.lower( vm );
|
||||
case MATCH:
|
||||
StringLib.match( vm );
|
||||
break;
|
||||
return StringLib.match( vm );
|
||||
case REP:
|
||||
StringLib.rep( vm );
|
||||
break;
|
||||
return StringLib.rep( vm );
|
||||
case REVERSE:
|
||||
StringLib.reverse( vm );
|
||||
break;
|
||||
return StringLib.reverse( vm );
|
||||
case SUB:
|
||||
StringLib.sub( vm );
|
||||
break;
|
||||
return StringLib.sub( vm );
|
||||
case UPPER:
|
||||
StringLib.upper( vm );
|
||||
break;
|
||||
return StringLib.upper( vm );
|
||||
|
||||
default:
|
||||
vm.error( "bad id" );
|
||||
return 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,22 +143,22 @@ public class StringLib extends LFunction {
|
||||
*
|
||||
* @param vm the calling vm
|
||||
*/
|
||||
static void byte_( LuaState vm ) {
|
||||
LString s = vm.checklstring(2);
|
||||
static int byte_( LuaState vm ) {
|
||||
LString s = vm.checklstring(1);
|
||||
int l = s.m_length;
|
||||
int posi = posrelat( vm.optint(3,1), l );
|
||||
int pose = posrelat( vm.optint(4,posi), l );
|
||||
vm.resettop();
|
||||
int posi = posrelat( vm.optint(2,1), l );
|
||||
int pose = posrelat( vm.optint(3,posi), l );
|
||||
int n,i;
|
||||
if (posi <= 0) posi = 1;
|
||||
if (pose > l) pose = l;
|
||||
if (posi > pose) return; /* empty interval; return no values */
|
||||
if (posi > pose) return 0; /* empty interval; return no values */
|
||||
n = (int)(pose - posi + 1);
|
||||
if (posi + n <= pose) /* overflow? */
|
||||
vm.error("string slice too long");
|
||||
vm.checkstack(n);
|
||||
for (i=0; i<n; i++)
|
||||
vm.pushinteger(s.luaByte(posi+i-1));
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,16 +172,16 @@ public class StringLib extends LFunction {
|
||||
*
|
||||
* @param vm the calling VM
|
||||
*/
|
||||
public static void char_( LuaState vm) {
|
||||
int n = vm.gettop()-1;
|
||||
public static int char_( LuaState vm) {
|
||||
int n = vm.gettop();
|
||||
byte[] bytes = new byte[n];
|
||||
for ( int i=0, a=2; i<n; i++, a++ ) {
|
||||
for ( int i=0, a=1; i<n; i++, a++ ) {
|
||||
int c = vm.checkint(a);
|
||||
vm.argcheck((c>=0 && c<256), a, "invalid value");
|
||||
bytes[i] = (byte) c;
|
||||
}
|
||||
vm.resettop();
|
||||
vm.pushlstring( bytes );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,15 +193,16 @@ public class StringLib extends LFunction {
|
||||
*
|
||||
* TODO: port dumping code as optional add-on
|
||||
*/
|
||||
static void dump( LuaState vm ) {
|
||||
LFunction f = vm.checkfunction(2);
|
||||
static int dump( LuaState vm ) {
|
||||
LFunction f = vm.checkfunction(1);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
DumpState.dump( ((LClosure)f).p, baos, true );
|
||||
vm.resettop();
|
||||
vm.pushlstring(baos.toByteArray());
|
||||
return 1;
|
||||
} catch (IOException e) {
|
||||
vm.error( e.getMessage() );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,8 +222,8 @@ public class StringLib extends LFunction {
|
||||
* If the pattern has captures, then in a successful match the captured values
|
||||
* are also returned, after the two indices.
|
||||
*/
|
||||
static void find( LuaState vm ) {
|
||||
str_find_aux( vm, true );
|
||||
static int find( LuaState vm ) {
|
||||
return str_find_aux( vm, true );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,11 +249,11 @@ public class StringLib extends LFunction {
|
||||
* This function does not accept string values containing embedded zeros,
|
||||
* except as arguments to the q option.
|
||||
*/
|
||||
static void format( LuaState vm ) {
|
||||
LString fmt = vm.checklstring( 2 );
|
||||
static int format( LuaState vm ) {
|
||||
LString fmt = vm.checklstring( 1 );
|
||||
final int n = fmt.length();
|
||||
LBuffer result = new LBuffer(n);
|
||||
int arg = 2;
|
||||
int arg = 1;
|
||||
|
||||
for ( int i = 0; i < n; ) {
|
||||
int c = fmt.luaByte( i++ );
|
||||
@@ -320,8 +307,8 @@ public class StringLib extends LFunction {
|
||||
}
|
||||
}
|
||||
|
||||
vm.resettop();
|
||||
vm.pushlstring( result.toLuaString() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static void addquoted(LBuffer buf, LString s) {
|
||||
@@ -528,11 +515,11 @@ public class StringLib extends LFunction {
|
||||
* For this function, a '^' at the start of a pattern does not work as an anchor,
|
||||
* as this would prevent the iteration.
|
||||
*/
|
||||
static void gmatch( LuaState vm ) {
|
||||
LString src = vm.checklstring( 2 );
|
||||
LString pat = vm.checklstring( 3 );
|
||||
vm.resettop();
|
||||
static int gmatch( LuaState vm ) {
|
||||
LString src = vm.checklstring( 1 );
|
||||
LString pat = vm.checklstring( 2 );
|
||||
vm.pushlvalue( new GMatchAux(vm, src, pat) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
static class GMatchAux extends LFunction {
|
||||
@@ -544,7 +531,7 @@ public class StringLib extends LFunction {
|
||||
this.ms = new MatchState(vm, src, pat);
|
||||
this.soffset = 0;
|
||||
}
|
||||
public boolean luaStackCall(LuaState vm) {
|
||||
public int invoke(LuaState vm) {
|
||||
vm.resettop();
|
||||
for ( ; soffset<srclen; soffset++ ) {
|
||||
ms.reset();
|
||||
@@ -553,11 +540,11 @@ public class StringLib extends LFunction {
|
||||
int soff = soffset;
|
||||
soffset = res;
|
||||
ms.push_captures( true, soff, res );
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
vm.pushnil();
|
||||
return false;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,12 +594,12 @@ public class StringLib extends LFunction {
|
||||
* x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
|
||||
* --> x="lua-5.1.tar.gz"
|
||||
*/
|
||||
static void gsub( LuaState vm ) {
|
||||
LString src = vm.checklstring(2);
|
||||
static int gsub( LuaState vm ) {
|
||||
LString src = vm.checklstring( 1 );
|
||||
final int srclen = src.length();
|
||||
LString p = vm.checklstring(3);
|
||||
LValue repl = vm.topointer( 4 );
|
||||
int max_s = vm.optint( 5, srclen + 1 );
|
||||
LString p = vm.checklstring( 2 );
|
||||
LValue repl = vm.topointer( 3 );
|
||||
int max_s = vm.optint( 4, srclen + 1 );
|
||||
final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^';
|
||||
|
||||
LBuffer lbuf = new LBuffer( srclen );
|
||||
@@ -637,9 +624,9 @@ public class StringLib extends LFunction {
|
||||
break;
|
||||
}
|
||||
lbuf.append( src.substring( soffset, srclen ) );
|
||||
vm.resettop();
|
||||
vm.pushlstring( lbuf.toLuaString() );
|
||||
vm.pushinteger( n );
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -648,10 +635,9 @@ public class StringLib extends LFunction {
|
||||
* Receives a string and returns its length. The empty string "" has length 0.
|
||||
* Embedded zeros are counted, so "a\000bc\000" has length 5.
|
||||
*/
|
||||
static void len( LuaState vm ) {
|
||||
int l = vm.checklstring(2).length();
|
||||
vm.resettop();
|
||||
vm.pushinteger( l );
|
||||
static int len( LuaState vm ) {
|
||||
vm.pushinteger( vm.checklstring(1).length() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,10 +647,9 @@ public class StringLib extends LFunction {
|
||||
* changed to lowercase. All other characters are left unchanged.
|
||||
* The definition of what an uppercase letter is depends on the current locale.
|
||||
*/
|
||||
static void lower( LuaState vm ) {
|
||||
String s = vm.checkstring(2).toLowerCase();
|
||||
vm.resettop();
|
||||
vm.pushstring( s );
|
||||
static int lower( LuaState vm ) {
|
||||
vm.pushstring( vm.checkstring(1).toLowerCase() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -676,8 +661,8 @@ public class StringLib extends LFunction {
|
||||
* A third, optional numerical argument init specifies where to start the
|
||||
* search; its default value is 1 and may be negative.
|
||||
*/
|
||||
static void match( LuaState vm ) {
|
||||
str_find_aux( vm, false );
|
||||
static int match( LuaState vm ) {
|
||||
return str_find_aux( vm, false );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -685,18 +670,16 @@ public class StringLib extends LFunction {
|
||||
*
|
||||
* Returns a string that is the concatenation of n copies of the string s.
|
||||
*/
|
||||
static void rep( LuaState vm ) {
|
||||
LString s = vm.checklstring(2);
|
||||
int n = vm.checkint( 3 );
|
||||
vm.resettop();
|
||||
if ( n >= 0 ) {
|
||||
static int rep( LuaState vm ) {
|
||||
LString s = vm.checklstring( 1 );
|
||||
int n = vm.checkint( 2 );
|
||||
final byte[] bytes = new byte[ s.length() * n ];
|
||||
int len = s.length();
|
||||
for ( int offset = 0; offset < bytes.length; offset += len ) {
|
||||
s.copyInto( 0, bytes, offset, len );
|
||||
}
|
||||
vm.pushlstring( bytes );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -704,14 +687,14 @@ public class StringLib extends LFunction {
|
||||
*
|
||||
* Returns a string that is the string s reversed.
|
||||
*/
|
||||
static void reverse( LuaState vm ) {
|
||||
LString s = vm.checklstring(2);
|
||||
static int reverse( LuaState vm ) {
|
||||
LString s = vm.checklstring(1);
|
||||
int n = s.length();
|
||||
byte[] b = new byte[n];
|
||||
for ( int i=0, j=n-1; i<n; i++, j-- )
|
||||
b[j] = (byte) s.luaByte(i);
|
||||
vm.resettop();
|
||||
vm.pushlstring( b );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -725,12 +708,12 @@ public class StringLib extends LFunction {
|
||||
* string.sub(s, -i)
|
||||
* returns a suffix of s with length i.
|
||||
*/
|
||||
static void sub( LuaState vm ) {
|
||||
final LString s = vm.checklstring(2);
|
||||
static int sub( LuaState vm ) {
|
||||
final LString s = vm.checklstring( 1 );
|
||||
final int l = s.length();
|
||||
|
||||
int start = posrelat( vm.checkint( 3 ), l );
|
||||
int end = posrelat( vm.optint( 4, -1 ), l );
|
||||
int start = posrelat( vm.checkint( 2 ), l );
|
||||
int end = posrelat( vm.optint( 3, -1 ), l );
|
||||
|
||||
if ( start < 1 )
|
||||
start = 1;
|
||||
@@ -744,6 +727,7 @@ public class StringLib extends LFunction {
|
||||
} else {
|
||||
vm.pushstring( "" );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -753,19 +737,18 @@ public class StringLib extends LFunction {
|
||||
* changed to uppercase. All other characters are left unchanged.
|
||||
* The definition of what a lowercase letter is depends on the current locale.
|
||||
*/
|
||||
static void upper( LuaState vm ) {
|
||||
String s = vm.checkstring(2).toUpperCase();
|
||||
vm.resettop();
|
||||
vm.pushstring(s);
|
||||
static int upper( LuaState vm ) {
|
||||
vm.pushstring(vm.checkstring(1).toUpperCase());
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility method implements both string.find and string.match.
|
||||
*/
|
||||
static void str_find_aux( LuaState vm, boolean find ) {
|
||||
LString s = vm.checklstring(2);
|
||||
LString pat = vm.checklstring(3);
|
||||
int init = vm.optint( 4 , 1 );
|
||||
static int str_find_aux( LuaState vm, boolean find ) {
|
||||
LString s = vm.checklstring( 1 );
|
||||
LString pat = vm.checklstring( 2 );
|
||||
int init = vm.optint( 3, 1 );
|
||||
|
||||
if ( init > 0 ) {
|
||||
init = Math.min( init - 1, s.length() );
|
||||
@@ -774,14 +757,13 @@ public class StringLib extends LFunction {
|
||||
}
|
||||
|
||||
boolean fastMatch = find && ( vm.toboolean( 5 ) || pat.indexOfAny( SPECIALS ) == -1 );
|
||||
vm.resettop();
|
||||
|
||||
if ( fastMatch ) {
|
||||
int result = s.indexOf( pat, init );
|
||||
if ( result != -1 ) {
|
||||
vm.pushinteger( result + 1 );
|
||||
vm.pushinteger( result + pat.length() );
|
||||
return;
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
MatchState ms = new MatchState( vm, s, pat );
|
||||
@@ -794,6 +776,7 @@ public class StringLib extends LFunction {
|
||||
}
|
||||
|
||||
int soff = init;
|
||||
vm.resettop();
|
||||
do {
|
||||
int res;
|
||||
ms.reset();
|
||||
@@ -805,11 +788,12 @@ public class StringLib extends LFunction {
|
||||
} else {
|
||||
ms.push_captures( true, soff, res );
|
||||
}
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
} while ( soff++ < s.length() && !anchor );
|
||||
}
|
||||
vm.pushnil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int posrelat( int pos, int len ) {
|
||||
|
||||
@@ -79,14 +79,14 @@ public class TableLib extends LFunction {
|
||||
return NAMES[id]+"()";
|
||||
}
|
||||
|
||||
public boolean luaStackCall( LuaState vm ) {
|
||||
public int invoke( LuaState vm ) {
|
||||
switch ( id ) {
|
||||
|
||||
/* Load the table library dynamically
|
||||
*/
|
||||
case INSTALL:
|
||||
install(vm._G);
|
||||
break;
|
||||
return 0;
|
||||
|
||||
|
||||
/* table.concat (table [, sep [, i [, j]]])
|
||||
@@ -96,25 +96,24 @@ public class TableLib extends LFunction {
|
||||
* If i is greater than j, returns the empty string.
|
||||
*/
|
||||
case CONCAT: {
|
||||
int n = vm.gettop();
|
||||
LTable table = vm.checktable(2);
|
||||
LString sep = vm.optlstring(3,null);
|
||||
int i = vm.optint(4,1);
|
||||
int j = vm.optint(5,-1);
|
||||
// int n = vm.gettop();
|
||||
LTable table = vm.checktable(1);
|
||||
LString sep = vm.optlstring(2,null);
|
||||
int i = vm.optint(3,1);
|
||||
int j = vm.optint(4,-1);
|
||||
if ( j == -1 )
|
||||
j = table.luaLength();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for ( int k=i; k<=j; k++ ) {
|
||||
LValue v = table.get(k);
|
||||
if ( ! v.isString() )
|
||||
vm.argerror(2, "table contains non-strings");
|
||||
vm.argerror(1, "table contains non-strings");
|
||||
v.luaConcatTo(baos);
|
||||
if ( k<j && sep!=null )
|
||||
sep.luaConcatTo( baos );
|
||||
}
|
||||
vm.resettop();
|
||||
vm.pushlstring( baos.toByteArray() );
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* table.getn (table)
|
||||
@@ -124,12 +123,10 @@ public class TableLib extends LFunction {
|
||||
case FOREACH:
|
||||
case FOREACHI:
|
||||
{
|
||||
LTable table = vm.checktable(2);
|
||||
LFunction function = vm.checkfunction(3);
|
||||
LValue result = table.foreach( vm, function, id==FOREACHI );
|
||||
vm.resettop();
|
||||
vm.pushlvalue( result );
|
||||
break;
|
||||
LTable table = vm.checktable(1);
|
||||
LFunction function = vm.checkfunction(2);
|
||||
vm.pushlvalue( table.foreach( vm, function, id==FOREACHI ) );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* table.getn (table)
|
||||
@@ -137,10 +134,9 @@ public class TableLib extends LFunction {
|
||||
* Get length of table t.
|
||||
*/
|
||||
case GETN: {
|
||||
LTable table = vm.checktable(2);
|
||||
vm.resettop();
|
||||
LTable table = vm.checktable(1);
|
||||
vm.pushinteger(table.luaLength());
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* table.insert (table, [pos,] value)
|
||||
@@ -150,20 +146,19 @@ public class TableLib extends LFunction {
|
||||
* table.insert(t,x) inserts x at the end of table t.
|
||||
*/
|
||||
case INSERT: {
|
||||
LTable table = vm.checktable(2);
|
||||
LTable table = vm.checktable(1);
|
||||
int pos = 0;
|
||||
switch ( vm.gettop() ) {
|
||||
case 3:
|
||||
case 2:
|
||||
break;
|
||||
case 4:
|
||||
pos = vm.checkint(3);
|
||||
case 3:
|
||||
pos = vm.checkint(2);
|
||||
break;
|
||||
default:
|
||||
vm.error( "wrong number of arguments to 'insert'" );
|
||||
}
|
||||
table.luaInsertPos( pos, vm.topointer(-1) );
|
||||
vm.resettop();
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* table.maxn (table)
|
||||
@@ -172,10 +167,9 @@ public class TableLib extends LFunction {
|
||||
* indices. (To do its job this function does a linear traversal of the whole table.)
|
||||
*/
|
||||
case MAXN: {
|
||||
LTable table = vm.checktable(2);
|
||||
vm.resettop();
|
||||
LTable table = vm.checktable(1);
|
||||
vm.pushlvalue( table.luaMaxN() );
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* table.remove (table [, pos])
|
||||
@@ -185,14 +179,11 @@ public class TableLib extends LFunction {
|
||||
* so that a call table.remove(t) removes the last element of table t.
|
||||
*/
|
||||
case REMOVE: {
|
||||
int n = vm.gettop();
|
||||
LTable table = vm.checktable(2);
|
||||
int pos = vm.optint(3,0);
|
||||
vm.resettop();
|
||||
LValue removed = table.luaRemovePos( pos );
|
||||
if ( removed != LNil.NIL )
|
||||
vm.pushlvalue( removed );
|
||||
break;
|
||||
LTable table = vm.checktable(1);
|
||||
int pos = vm.optint(2,0);
|
||||
LValue v = table.luaRemovePos( pos );
|
||||
vm.pushlvalue( v );
|
||||
return v.isNil()? 0: 1;
|
||||
}
|
||||
|
||||
/* table.sort (table [, comp])
|
||||
@@ -205,16 +196,15 @@ public class TableLib extends LFunction {
|
||||
* The sort algorithm is not stable; that is, elements considered equal by the given order may have their relative positions changed by the sort.
|
||||
*/
|
||||
case SORT: {
|
||||
LTable table = vm.checktable(2);
|
||||
LValue compare = (vm.isnoneornil(3)? (LValue) LNil.NIL: (LValue) vm.checkfunction(3));
|
||||
LTable table = vm.checktable(1);
|
||||
LValue compare = (vm.isnoneornil(2)? (LValue) LNil.NIL: (LValue) vm.checkfunction(2));
|
||||
table.luaSort( vm, compare );
|
||||
vm.resettop();
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
LuaState.vmerror( "bad table id" );
|
||||
return 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class LThread extends LValue implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean yield() {
|
||||
public void yield() {
|
||||
synchronized ( this ) {
|
||||
if ( status != STATUS_RUNNING )
|
||||
vm.error(this+" not running");
|
||||
@@ -99,7 +99,6 @@ public class LThread extends LValue implements Runnable {
|
||||
vm.error(this+" "+e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +156,7 @@ public class LThread extends LValue implements Runnable {
|
||||
vm.resettop();
|
||||
if ( this.vm.cc >= 0 ) {
|
||||
vm.pushboolean(status != STATUS_DEAD);
|
||||
this.vm.xmove(vm, this.vm.gettop() - 1);
|
||||
this.vm.xmove(vm, this.vm.gettop());
|
||||
} else {
|
||||
vm.pushboolean(true);
|
||||
this.vm.base = 0;
|
||||
|
||||
@@ -247,16 +247,12 @@ public class LuaState extends Lua {
|
||||
* @param javaFunction
|
||||
*/
|
||||
public void invokeJavaFunction(LFunction javaFunction) {
|
||||
int resultbase = base;
|
||||
int resultsneeded = nresults;
|
||||
++base;
|
||||
int nactual = javaFunction.invoke(this);
|
||||
debugAssert(nactual>=0);
|
||||
debugAssert(top-nactual>=base);
|
||||
System.arraycopy(stack, top-nactual, stack, base=resultbase, nactual);
|
||||
settop( nactual );
|
||||
if ( resultsneeded >= 0 )
|
||||
settop( resultsneeded );
|
||||
if (nactual < 0)
|
||||
nactual = top - base;
|
||||
System.arraycopy(stack, top-nactual, stack, --base, nactual);
|
||||
luaV_settop_fillabove( base+nactual );
|
||||
}
|
||||
|
||||
// ================== error processing =================
|
||||
@@ -1969,7 +1965,7 @@ public class LuaState extends Lua {
|
||||
* @param extramsg String to include in error message
|
||||
*/
|
||||
public void argerror(int narg, String extramsg) {
|
||||
error("bad argument #" + (narg - 1) + " (" + extramsg + ")");
|
||||
error("bad argument #" + (narg) + " (" + extramsg + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user