Add xpcall.
This commit is contained in:
@@ -54,6 +54,7 @@ public class BaseLib extends LFunction {
|
|||||||
"load",
|
"load",
|
||||||
"tostring",
|
"tostring",
|
||||||
"unpack",
|
"unpack",
|
||||||
|
"xpcall",
|
||||||
"next",
|
"next",
|
||||||
"_inext", // not public
|
"_inext", // not public
|
||||||
};
|
};
|
||||||
@@ -81,8 +82,9 @@ public class BaseLib extends LFunction {
|
|||||||
private static final int LOAD = 20;
|
private static final int LOAD = 20;
|
||||||
private static final int TOSTRING = 21;
|
private static final int TOSTRING = 21;
|
||||||
private static final int UNPACK = 22;
|
private static final int UNPACK = 22;
|
||||||
private static final int NEXT = 23;
|
private static final int XPCALL = 23;
|
||||||
private static final int INEXT = 24;
|
private static final int NEXT = 24;
|
||||||
|
private static final int INEXT = 25;
|
||||||
|
|
||||||
private static LFunction next;
|
private static LFunction next;
|
||||||
private static LFunction inext;
|
private static LFunction inext;
|
||||||
@@ -190,6 +192,29 @@ public class BaseLib extends LFunction {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case XPCALL: {
|
||||||
|
vm.checkany(3);
|
||||||
|
LValue errfun = vm.topointer(3);
|
||||||
|
vm.settop(2);
|
||||||
|
int s = vm.pcall( 0, Lua.LUA_MULTRET, 0 );
|
||||||
|
if ( s == 0 ) { // success, results are on stack above the xpcall
|
||||||
|
vm.pushboolean( true );
|
||||||
|
vm.replace( 1 );
|
||||||
|
} else { // error, error message is on the stack
|
||||||
|
vm.pushlvalue( errfun );
|
||||||
|
vm.insert( 1 );
|
||||||
|
s = vm.pcall( vm.gettop()-1, 1, 0 );
|
||||||
|
if ( s == 0 ) {
|
||||||
|
vm.pushboolean( false );
|
||||||
|
vm.insert( 1 );
|
||||||
|
} else { // error in error handler
|
||||||
|
vm.resettop();
|
||||||
|
vm.pushboolean(false);
|
||||||
|
vm.pushstring("error in error handling");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ERROR: {
|
case ERROR: {
|
||||||
vm.error(vm.checkstring(2), vm.optint(3,1));
|
vm.error(vm.checkstring(2), vm.optint(3,1));
|
||||||
break;
|
break;
|
||||||
@@ -197,7 +222,7 @@ public class BaseLib extends LFunction {
|
|||||||
case ASSERT: {
|
case ASSERT: {
|
||||||
if ( ! vm.toboolean(2) )
|
if ( ! vm.toboolean(2) )
|
||||||
vm.error( vm.optstring(3,"assertion failed!") );
|
vm.error( vm.optstring(3,"assertion failed!") );
|
||||||
vm.resettop();
|
vm.remove(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,26 +231,20 @@ public class BaseLib extends LFunction {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TONUMBER: {
|
case TONUMBER: {
|
||||||
vm.checkany(2);
|
int base = vm.optint(3, 10);
|
||||||
switch ( vm.type(2) ) {
|
if (base == 10) { /* standard conversion */
|
||||||
case Lua.LUA_TNUMBER:
|
vm.checkany(2);
|
||||||
break;
|
LValue v = vm.tolnumber(2);
|
||||||
case Lua.LUA_TSTRING:
|
vm.resettop();
|
||||||
LString s = vm.tolstring(2);
|
if ( ! v.isNil() )
|
||||||
int base = 10;
|
vm.pushlvalue(v);
|
||||||
if ( vm.isnumber(3) ) {
|
} else {
|
||||||
base = vm.tolnumber(3).toJavaInt();
|
if ( base < 2 || base > 36 )
|
||||||
if ( base < 2 || base > 36 )
|
vm.typerror(3, "base out of range");
|
||||||
vm.error("bad argument #2 to '?' (base out of range)");
|
LString s = vm.checklstring(2);
|
||||||
}
|
vm.resettop();
|
||||||
vm.pushlvalue( s.luaToNumber(base) );
|
vm.pushlvalue( s.luaToNumber(base) );
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vm.pushnil();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
vm.insert(1);
|
|
||||||
vm.settop(1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RAWGET: {
|
case RAWGET: {
|
||||||
@@ -307,10 +326,12 @@ public class BaseLib extends LFunction {
|
|||||||
vm.resettop();
|
vm.resettop();
|
||||||
if ( "collect".equals(s) )
|
if ( "collect".equals(s) )
|
||||||
System.gc();
|
System.gc();
|
||||||
else {
|
else if ( "count".equals(s) ) {
|
||||||
Runtime rt = Runtime.getRuntime();
|
Runtime rt = Runtime.getRuntime();
|
||||||
long used = rt.totalMemory() - rt.freeMemory();
|
long used = rt.totalMemory() - rt.freeMemory();
|
||||||
result = (int) (used >> 10);
|
result = (int) (used >> 10);
|
||||||
|
} else {
|
||||||
|
vm.typerror(2,"gc op");
|
||||||
}
|
}
|
||||||
vm.pushnumber(result);
|
vm.pushnumber(result);
|
||||||
break;
|
break;
|
||||||
@@ -319,7 +340,7 @@ public class BaseLib extends LFunction {
|
|||||||
dofile(vm);
|
dofile(vm);
|
||||||
break;
|
break;
|
||||||
case LOADSTRING:
|
case LOADSTRING:
|
||||||
loadstring(vm, vm.topointer(2), vm.tostring(3));
|
loadstring(vm, vm.checklstring(2), vm.optstring(3,"(string)"));
|
||||||
break;
|
break;
|
||||||
case LOAD:
|
case LOAD:
|
||||||
load(vm);
|
load(vm);
|
||||||
@@ -430,10 +451,8 @@ public class BaseLib extends LFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return true if loaded, false if error put onto stack
|
// return true if loaded, false if error put onto stack
|
||||||
private boolean loadstring(LuaState vm, LValue string, String chunkname) {
|
private boolean loadstring(LuaState vm, LString string, String chunkname) {
|
||||||
return loadis( vm,
|
return loadis( vm, string.toInputStream(), chunkname );
|
||||||
string.luaAsString().toInputStream(),
|
|
||||||
("".equals(chunkname)? "(string)": chunkname) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if loaded, false if error put onto stack
|
// return true if loaded, false if error put onto stack
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ checkallerrors('assert',{{nil,false},{'message'}},'message')
|
|||||||
|
|
||||||
-- collectgarbage
|
-- collectgarbage
|
||||||
banner('collectgarbage')
|
banner('collectgarbage')
|
||||||
checkallpass('collectgarbage',{{'collect','count'}})
|
checkallpass('collectgarbage',{{'collect','count'}},true)
|
||||||
checkallerrors('collectgarbage',{notanil},'bad argument #1')
|
checkallerrors('collectgarbage',{notanil},'bad argument #1')
|
||||||
|
|
||||||
-- dofile
|
-- dofile
|
||||||
@@ -132,8 +132,10 @@ checkallerrors('tonumber',{somenumber,{1,37,atable,afunction,aboolean}},'bad arg
|
|||||||
|
|
||||||
-- tostring
|
-- tostring
|
||||||
banner('tostring')
|
banner('tostring')
|
||||||
checkallpass('tostring',{notanil})
|
checkallpass('tostring',{{astring,anumber,aboolean}})
|
||||||
checkallpass('tostring',{anylua,{'anchor'}})
|
checkallpass('tostring',{{atable,afunction,athread}},true)
|
||||||
|
checkallpass('tostring',{{astring,anumber,aboolean},{'anchor'}})
|
||||||
|
checkallpass('tostring',{{atable,afunction,athread},{'anchor'}},true)
|
||||||
checkallerrors('tostring',{},'bad argument #1')
|
checkallerrors('tostring',{},'bad argument #1')
|
||||||
|
|
||||||
-- type
|
-- type
|
||||||
@@ -153,7 +155,8 @@ checkallerrors('unpack',{sometable,somenumber,nonnumber},'bad argument #3')
|
|||||||
|
|
||||||
-- xpcall
|
-- xpcall
|
||||||
banner('xpcall')
|
banner('xpcall')
|
||||||
checkallpass('xpcall', {notanil,notanil})
|
checkallpass('xpcall', {notanil,nonfunction})
|
||||||
|
checkallpass('xpcall', {notanil,{function(...)return 'aaa', 'bbb', #{...} end}})
|
||||||
checkallerrors('xpcall',{anylua},'bad argument #2')
|
checkallerrors('xpcall',{anylua},'bad argument #2')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user