Clear stack before any lua call.
This commit is contained in:
@@ -109,7 +109,7 @@ public class BaseLib extends LFunction {
|
||||
vm.pushnil();
|
||||
vm.pushstring( message );
|
||||
}
|
||||
|
||||
|
||||
private void checkargexists(LuaState vm, int index, int type) {
|
||||
if ( vm.gettop() < index )
|
||||
vm.error("bad argument #"+(index-1)+" to '?' ("+
|
||||
@@ -120,8 +120,13 @@ public class BaseLib extends LFunction {
|
||||
|
||||
private void checkargtype(LuaState vm, int index, int type) {
|
||||
checkargexists( vm, index, type );
|
||||
if ( vm.type(index) != type )
|
||||
vm.error("bad argument #"+(index-1)+" to '?' ("+Lua.TYPE_NAMES[type]+" expected, got "+vm.typename(index)+")");
|
||||
int t = vm.type(index);
|
||||
if ( t != type ) {
|
||||
if ( type == Lua.LUA_TNUMBER && t == Lua.LUA_TSTRING && vm.isnumber(index) )
|
||||
return;
|
||||
vm.error("bad argument #"+(index-1)+" to '?' ("+
|
||||
Lua.TYPE_NAMES[type]+" expected, got "+vm.typename(index)+")");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean luaStackCall(LuaState vm) {
|
||||
@@ -139,13 +144,15 @@ public class BaseLib extends LFunction {
|
||||
}
|
||||
case PAIRS:
|
||||
case IPAIRS: {
|
||||
LValue v = vm.topointer(2);
|
||||
checkargtype(vm,2,Lua.LUA_TTABLE);
|
||||
LTable v = vm.totable(2);
|
||||
LValue r = v.luaPairs(id==PAIRS);
|
||||
vm.resettop();
|
||||
vm.pushlvalue( r );
|
||||
break;
|
||||
}
|
||||
case GETMETATABLE: {
|
||||
checkargexists(vm,2,Lua.LUA_TVALUE);
|
||||
if ( 0 == vm.getmetatable(2) ) {
|
||||
vm.resettop();
|
||||
vm.pushnil();
|
||||
@@ -156,8 +163,7 @@ public class BaseLib extends LFunction {
|
||||
break;
|
||||
}
|
||||
case SETMETATABLE: {
|
||||
if ( ! vm.istable(2) )
|
||||
vm.error("bad argument #1 to '?' (table expected, got "+vm.typename(2)+")");
|
||||
checkargtype(vm,2,Lua.LUA_TTABLE);
|
||||
vm.setmetatable(2);
|
||||
vm.remove(1);
|
||||
break;
|
||||
@@ -200,13 +206,14 @@ public class BaseLib extends LFunction {
|
||||
break;
|
||||
|
||||
case TONUMBER: {
|
||||
checkargexists(vm,2,Lua.LUA_TVALUE);
|
||||
switch ( vm.type(2) ) {
|
||||
case Lua.LUA_TNUMBER:
|
||||
break;
|
||||
case Lua.LUA_TSTRING:
|
||||
LString s = vm.tolstring(2);
|
||||
int base = 10;
|
||||
if ( vm.gettop() >= 3 ) {
|
||||
if ( vm.isnumber(3) ) {
|
||||
base = vm.tointeger(3);
|
||||
if ( base < 2 || base > 36 )
|
||||
vm.error("bad argument #2 to '?' (base out of range)");
|
||||
@@ -273,9 +280,8 @@ public class BaseLib extends LFunction {
|
||||
break;
|
||||
}
|
||||
case SELECT: {
|
||||
checkargexists(vm,2,Lua.LUA_TNUMBER);
|
||||
int n = vm.gettop();
|
||||
if ( n < 2 )
|
||||
vm.error( "bad argument #1 to '?' (number expected, got no value)" );
|
||||
if ( vm.isnumber(2) ) {
|
||||
int index = vm.tointeger(2);
|
||||
if ( index < 0 )
|
||||
@@ -320,26 +326,27 @@ public class BaseLib extends LFunction {
|
||||
load(vm, vm.topointer(2), vm.tostring(3));
|
||||
break;
|
||||
case TOSTRING: {
|
||||
if ( vm.gettop() < 2 )
|
||||
vm.error( "bad argument #1 to '?' (value expected)" );
|
||||
checkargexists(vm,2,Lua.LUA_TVALUE);
|
||||
LValue v = vm.topointer(2);
|
||||
vm.resettop();
|
||||
vm.pushlvalue( v.luaAsString() );
|
||||
break;
|
||||
}
|
||||
case UNPACK: {
|
||||
int n = vm.gettop();
|
||||
if ( n < 2 )
|
||||
vm.error( "bad argument #1 to '?' (table expected, got no value)" );
|
||||
if ( ! vm.istable(2) )
|
||||
vm.error( "bad argument #1 to '?' (table expected, got "+vm.typename(2)+")" );
|
||||
checkargtype(vm,2,Lua.LUA_TTABLE);
|
||||
LTable list = vm.totable(2);
|
||||
int i = vm.tointeger(3);
|
||||
int j = vm.tointeger(4);
|
||||
if ( n <= 2 )
|
||||
i = 1;
|
||||
if ( n <= 3 )
|
||||
int n = vm.gettop();
|
||||
int i=1,j;
|
||||
if ( n >= 3 ) {
|
||||
checkargtype(vm,3,Lua.LUA_TNUMBER);
|
||||
i = vm.tointeger(3);
|
||||
}
|
||||
if ( n >= 4 ) {
|
||||
checkargtype(vm,4,Lua.LUA_TNUMBER);
|
||||
j = vm.tointeger(4);
|
||||
} else {
|
||||
j = list.luaLength();
|
||||
}
|
||||
vm.resettop();
|
||||
vm.checkstack(j+1-i);
|
||||
for ( int k=i; k<=j; k++ )
|
||||
@@ -347,7 +354,11 @@ public class BaseLib extends LFunction {
|
||||
break;
|
||||
}
|
||||
case NEXT: {
|
||||
setResult( vm, next(vm, vm.topointer(2), vm.tointeger(3)) );
|
||||
checkargtype(vm,2,Lua.LUA_TTABLE);
|
||||
LTable t = vm.totable(2);
|
||||
LValue v = vm.topointer(3);
|
||||
vm.resettop();
|
||||
t.next(vm,v);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -474,11 +485,4 @@ public class BaseLib extends LFunction {
|
||||
closeSafely( baos );
|
||||
}
|
||||
}
|
||||
|
||||
private LValue next(LuaState vm, LValue table, int index) {
|
||||
throw new LuaErrorException("next() not supported yet");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -78,4 +78,9 @@ public class LNumber extends LValue {
|
||||
return new Short(toJavaShort());
|
||||
}
|
||||
|
||||
/** Convert to a number if possible, or nil otherwise */
|
||||
public LValue luaToNumber() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -635,4 +635,59 @@ public class LTable extends LValue {
|
||||
m_vector[j] = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave nil on top, or index,value pair
|
||||
* @param vm
|
||||
* @param index
|
||||
*/
|
||||
public void next(LuaState vm, LValue index) {
|
||||
|
||||
// look through vector first
|
||||
int start = index.toJavaInt();
|
||||
if ( start > 0 && start <= m_vector.length ) {
|
||||
for ( int i=start; i<m_vector.length; i++ ) {
|
||||
if ( m_vector[i] != LNil.NIL ) {
|
||||
vm.pushinteger(i+1);
|
||||
vm.pushlvalue(m_vector[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look up key first
|
||||
if ( index != LNil.NIL ) {
|
||||
if ( m_hashEntries != 0 && (start <= 0 || start > m_vector.length) ) {
|
||||
for ( int i=0; i<m_hashKeys.length; i++ ) {
|
||||
if ( index.luaBinCmpUnknown( Lua.OP_EQ, m_hashKeys[i] ) ) {
|
||||
start = m_vector.length+i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start looking
|
||||
if ( start < m_vector.length ) {
|
||||
if ( m_arrayEntries != 0 ) {
|
||||
for ( int i=start; i<m_vector.length; i++ ) {
|
||||
if ( m_vector[i] != LNil.NIL ) {
|
||||
vm.pushinteger(i+1);
|
||||
vm.pushlvalue(m_vector[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
start = m_vector.length;
|
||||
}
|
||||
if ( m_hashEntries != 0 ) {
|
||||
for ( int i=start-m_vector.length; i<m_hashKeys.length; i++ ) {
|
||||
if ( index.luaBinCmpUnknown( Lua.OP_EQ, m_hashKeys[i] ) ) {
|
||||
vm.pushlvalue(m_hashKeys[i]);
|
||||
vm.pushlvalue(m_hashValues[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vm.pushnil();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,4 +302,9 @@ public class LValue {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Convert to a number if possible, or nil otherwise */
|
||||
public LValue luaToNumber() {
|
||||
return LNil.NIL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -169,6 +169,8 @@ public class LuaState extends Lua {
|
||||
}
|
||||
calls[newcc] = new CallInfo(c, base, top, resultbase, nresults);
|
||||
cc = newcc;
|
||||
|
||||
stackClear( top, base + c.p.maxstacksize );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -461,6 +463,12 @@ public class LuaState extends Lua {
|
||||
top = newTop;
|
||||
}
|
||||
|
||||
private final void stackClear(int startIndex, int endIndex) {
|
||||
for (; startIndex < endIndex; startIndex++) {
|
||||
stack[startIndex] = LNil.NIL;
|
||||
}
|
||||
}
|
||||
|
||||
/** execute instructions up to a yield, return, or call */
|
||||
public void exec() {
|
||||
if ( cc < 0 )
|
||||
@@ -1460,9 +1468,20 @@ public class LuaState extends Lua {
|
||||
* string convertible to a number, and 0 otherwise.
|
||||
*/
|
||||
public boolean isnumber(int index) {
|
||||
return type(index) == Lua.LUA_TNUMBER;
|
||||
return tolnumber(index) != LNil.NIL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a value to an LNumber<span class="apii">[-0, +0, <em>-</em>]</span>
|
||||
*
|
||||
* <p>
|
||||
* Returns an LNumber if the value at the given acceptable index is a number or a
|
||||
* string convertible to a number, and LNil.NIL otherwise.
|
||||
*/
|
||||
public LValue tolnumber(int index) {
|
||||
return topointer(index).luaToNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a value is a string <span class="apii">[-0, +0, <em>m</em>]</span>
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user