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