Clear stack before any lua call.
This commit is contained in:
@@ -120,8 +120,13 @@ public class BaseLib extends LFunction {
|
|||||||
|
|
||||||
private void checkargtype(LuaState vm, int index, int type) {
|
private void checkargtype(LuaState vm, int index, int type) {
|
||||||
checkargexists( vm, index, type );
|
checkargexists( vm, index, type );
|
||||||
if ( vm.type(index) != type )
|
int t = vm.type(index);
|
||||||
vm.error("bad argument #"+(index-1)+" to '?' ("+Lua.TYPE_NAMES[type]+" expected, got "+vm.typename(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) {
|
public boolean luaStackCall(LuaState vm) {
|
||||||
@@ -139,13 +144,15 @@ public class BaseLib extends LFunction {
|
|||||||
}
|
}
|
||||||
case PAIRS:
|
case PAIRS:
|
||||||
case IPAIRS: {
|
case IPAIRS: {
|
||||||
LValue v = vm.topointer(2);
|
checkargtype(vm,2,Lua.LUA_TTABLE);
|
||||||
|
LTable v = vm.totable(2);
|
||||||
LValue r = v.luaPairs(id==PAIRS);
|
LValue r = v.luaPairs(id==PAIRS);
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushlvalue( r );
|
vm.pushlvalue( r );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GETMETATABLE: {
|
case GETMETATABLE: {
|
||||||
|
checkargexists(vm,2,Lua.LUA_TVALUE);
|
||||||
if ( 0 == vm.getmetatable(2) ) {
|
if ( 0 == vm.getmetatable(2) ) {
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushnil();
|
vm.pushnil();
|
||||||
@@ -156,8 +163,7 @@ public class BaseLib extends LFunction {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SETMETATABLE: {
|
case SETMETATABLE: {
|
||||||
if ( ! vm.istable(2) )
|
checkargtype(vm,2,Lua.LUA_TTABLE);
|
||||||
vm.error("bad argument #1 to '?' (table expected, got "+vm.typename(2)+")");
|
|
||||||
vm.setmetatable(2);
|
vm.setmetatable(2);
|
||||||
vm.remove(1);
|
vm.remove(1);
|
||||||
break;
|
break;
|
||||||
@@ -200,13 +206,14 @@ public class BaseLib extends LFunction {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TONUMBER: {
|
case TONUMBER: {
|
||||||
|
checkargexists(vm,2,Lua.LUA_TVALUE);
|
||||||
switch ( vm.type(2) ) {
|
switch ( vm.type(2) ) {
|
||||||
case Lua.LUA_TNUMBER:
|
case Lua.LUA_TNUMBER:
|
||||||
break;
|
break;
|
||||||
case Lua.LUA_TSTRING:
|
case Lua.LUA_TSTRING:
|
||||||
LString s = vm.tolstring(2);
|
LString s = vm.tolstring(2);
|
||||||
int base = 10;
|
int base = 10;
|
||||||
if ( vm.gettop() >= 3 ) {
|
if ( vm.isnumber(3) ) {
|
||||||
base = vm.tointeger(3);
|
base = vm.tointeger(3);
|
||||||
if ( base < 2 || base > 36 )
|
if ( base < 2 || base > 36 )
|
||||||
vm.error("bad argument #2 to '?' (base out of range)");
|
vm.error("bad argument #2 to '?' (base out of range)");
|
||||||
@@ -273,9 +280,8 @@ public class BaseLib extends LFunction {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SELECT: {
|
case SELECT: {
|
||||||
|
checkargexists(vm,2,Lua.LUA_TNUMBER);
|
||||||
int n = vm.gettop();
|
int n = vm.gettop();
|
||||||
if ( n < 2 )
|
|
||||||
vm.error( "bad argument #1 to '?' (number expected, got no value)" );
|
|
||||||
if ( vm.isnumber(2) ) {
|
if ( vm.isnumber(2) ) {
|
||||||
int index = vm.tointeger(2);
|
int index = vm.tointeger(2);
|
||||||
if ( index < 0 )
|
if ( index < 0 )
|
||||||
@@ -320,26 +326,27 @@ public class BaseLib extends LFunction {
|
|||||||
load(vm, vm.topointer(2), vm.tostring(3));
|
load(vm, vm.topointer(2), vm.tostring(3));
|
||||||
break;
|
break;
|
||||||
case TOSTRING: {
|
case TOSTRING: {
|
||||||
if ( vm.gettop() < 2 )
|
checkargexists(vm,2,Lua.LUA_TVALUE);
|
||||||
vm.error( "bad argument #1 to '?' (value expected)" );
|
|
||||||
LValue v = vm.topointer(2);
|
LValue v = vm.topointer(2);
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushlvalue( v.luaAsString() );
|
vm.pushlvalue( v.luaAsString() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UNPACK: {
|
case UNPACK: {
|
||||||
int n = vm.gettop();
|
checkargtype(vm,2,Lua.LUA_TTABLE);
|
||||||
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)+")" );
|
|
||||||
LTable list = vm.totable(2);
|
LTable list = vm.totable(2);
|
||||||
int i = vm.tointeger(3);
|
int n = vm.gettop();
|
||||||
int j = vm.tointeger(4);
|
int i=1,j;
|
||||||
if ( n <= 2 )
|
if ( n >= 3 ) {
|
||||||
i = 1;
|
checkargtype(vm,3,Lua.LUA_TNUMBER);
|
||||||
if ( n <= 3 )
|
i = vm.tointeger(3);
|
||||||
|
}
|
||||||
|
if ( n >= 4 ) {
|
||||||
|
checkargtype(vm,4,Lua.LUA_TNUMBER);
|
||||||
|
j = vm.tointeger(4);
|
||||||
|
} else {
|
||||||
j = list.luaLength();
|
j = list.luaLength();
|
||||||
|
}
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.checkstack(j+1-i);
|
vm.checkstack(j+1-i);
|
||||||
for ( int k=i; k<=j; k++ )
|
for ( int k=i; k<=j; k++ )
|
||||||
@@ -347,7 +354,11 @@ public class BaseLib extends LFunction {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NEXT: {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -474,11 +485,4 @@ public class BaseLib extends LFunction {
|
|||||||
closeSafely( baos );
|
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());
|
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;
|
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;
|
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);
|
calls[newcc] = new CallInfo(c, base, top, resultbase, nresults);
|
||||||
cc = newcc;
|
cc = newcc;
|
||||||
|
|
||||||
|
stackClear( top, base + c.p.maxstacksize );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -461,6 +463,12 @@ public class LuaState extends Lua {
|
|||||||
top = newTop;
|
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 */
|
/** execute instructions up to a yield, return, or call */
|
||||||
public void exec() {
|
public void exec() {
|
||||||
if ( cc < 0 )
|
if ( cc < 0 )
|
||||||
@@ -1460,7 +1468,18 @@ public class LuaState extends Lua {
|
|||||||
* string convertible to a number, and 0 otherwise.
|
* string convertible to a number, and 0 otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isnumber(int index) {
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user