Improve math lib argument type checking.
This commit is contained in:
@@ -88,37 +88,64 @@ public class MathLib extends LFunction {
|
|||||||
vm.pushlvalue( value );
|
vm.pushlvalue( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setResult( LuaState vm, double d ) {
|
||||||
|
vm.resettop();
|
||||||
|
vm.pushlvalue( LDouble.valueOf(d) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setResult( LuaState vm, int i ) {
|
||||||
|
vm.resettop();
|
||||||
|
vm.pushlvalue( LInteger.valueOf(i) );
|
||||||
|
}
|
||||||
|
|
||||||
public boolean luaStackCall( LuaState vm ) {
|
public boolean luaStackCall( LuaState vm ) {
|
||||||
|
double x;
|
||||||
switch ( id ) {
|
switch ( id ) {
|
||||||
case INSTALL:
|
case INSTALL:
|
||||||
install( vm._G );
|
install( vm._G );
|
||||||
break;
|
break;
|
||||||
case ABS:
|
case ABS:
|
||||||
setResult( vm, abs( vm.topointer( 2 ) ) );
|
setResult( vm, Math.abs ( vm.checkdouble(2) ) );
|
||||||
break;
|
break;
|
||||||
case COS:
|
case COS:
|
||||||
setResult( vm, new LDouble( Math.cos ( vm.tonumber(2) ) ) );
|
setResult( vm, Math.cos ( vm.checkdouble(2) ) );
|
||||||
break;
|
break;
|
||||||
case MAX:
|
case MAX: {
|
||||||
setResult( vm, max( vm.topointer(2), vm.topointer(3) ) );
|
int n = vm.gettop();
|
||||||
|
x = vm.checkdouble(2);
|
||||||
|
for ( int i=3; i<=n; i++ )
|
||||||
|
x = Math.max(x, vm.checkdouble(i));
|
||||||
|
setResult( vm, x );
|
||||||
break;
|
break;
|
||||||
case MIN:
|
}
|
||||||
setResult( vm, min( vm.topointer(2), vm.topointer(3) ) );
|
case MIN: {
|
||||||
|
int n = vm.gettop();
|
||||||
|
x = vm.checkdouble(2);
|
||||||
|
for ( int i=3; i<=n; i++ )
|
||||||
|
x = Math.min(x, vm.checkdouble(i));
|
||||||
|
setResult(vm,x);
|
||||||
break;
|
break;
|
||||||
case MODF:
|
}
|
||||||
modf( vm );
|
case MODF: {
|
||||||
|
double v = vm.checkdouble(2);
|
||||||
|
double intPart = ( v > 0 ) ? Math.floor( v ) : Math.ceil( v );
|
||||||
|
double fracPart = v - intPart;
|
||||||
|
vm.resettop();
|
||||||
|
vm.pushnumber( intPart );
|
||||||
|
vm.pushnumber( fracPart );
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SIN:
|
case SIN:
|
||||||
setResult( vm, new LDouble( Math.sin( vm.tonumber(2) ) ) );
|
setResult( vm, Math.sin( vm.checkdouble(2) ) );
|
||||||
break;
|
break;
|
||||||
case SQRT:
|
case SQRT:
|
||||||
setResult( vm, new LDouble( Math.sqrt( vm.tonumber(2) ) ) );
|
setResult( vm, Math.sqrt( vm.checkdouble(2) ) );
|
||||||
break;
|
break;
|
||||||
case CEIL:
|
case CEIL:
|
||||||
setResult( vm, LInteger.valueOf( (int) Math.ceil( vm.tonumber(2) ) ) );
|
setResult( vm, (int) Math.ceil( vm.checkdouble(2) ) );
|
||||||
break;
|
break;
|
||||||
case FLOOR:
|
case FLOOR:
|
||||||
setResult( vm, LInteger.valueOf( (int) Math.floor( vm.tonumber(2) ) ) );
|
setResult( vm, (int) Math.floor( vm.checkdouble(2) ) );
|
||||||
break;
|
break;
|
||||||
case RANDOM: {
|
case RANDOM: {
|
||||||
if ( random == null )
|
if ( random == null )
|
||||||
@@ -129,14 +156,16 @@ public class MathLib extends LFunction {
|
|||||||
vm.pushnumber(random.nextDouble());
|
vm.pushnumber(random.nextDouble());
|
||||||
break;
|
break;
|
||||||
case 2: {
|
case 2: {
|
||||||
int m = vm.tointeger(2);
|
int m = vm.checkint(2);
|
||||||
|
vm.argcheck(1<=m, 1, "interval is empty");
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushinteger(1+random.nextInt(m));
|
vm.pushinteger(1+random.nextInt(m));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
int m = vm.tointeger(2);
|
int m = vm.checkint(2);
|
||||||
int n = vm.tointeger(3);
|
int n = vm.checkint(3);
|
||||||
|
vm.argcheck(m<=n, 2, "interval is empty");
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushinteger(m+random.nextInt(n+1-m));
|
vm.pushinteger(m+random.nextInt(n+1-m));
|
||||||
break;
|
break;
|
||||||
@@ -145,7 +174,7 @@ public class MathLib extends LFunction {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RANDOMSEED:
|
case RANDOMSEED:
|
||||||
random = new Random( vm.tointeger(2) );
|
random = new Random( vm.checkint(2) );
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -153,27 +182,5 @@ public class MathLib extends LFunction {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
private LValue abs( final LValue v ) {
|
|
||||||
LValue nv = v.luaUnaryMinus();
|
|
||||||
return max( v, nv );
|
|
||||||
}
|
|
||||||
|
|
||||||
private LValue max( LValue lhs, LValue rhs ) {
|
|
||||||
return rhs.luaBinCmpUnknown( Lua.OP_LT, lhs ) ? rhs: lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LValue min( LValue lhs, LValue rhs ) {
|
|
||||||
return rhs.luaBinCmpUnknown( Lua.OP_LT, lhs ) ? lhs: rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void modf( LuaState vm ) {
|
|
||||||
LValue arg = vm.topointer(2);
|
|
||||||
double v = arg.toJavaDouble();
|
|
||||||
double intPart = ( v > 0 ) ? Math.floor( v ) : Math.ceil( v );
|
|
||||||
double fracPart = v - intPart;
|
|
||||||
vm.resettop();
|
|
||||||
vm.pushnumber( intPart );
|
|
||||||
vm.pushnumber( fracPart );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2617,23 +2617,30 @@ public class LuaState extends Lua {
|
|||||||
/**
|
/**
|
||||||
* Report an error with an argument.
|
* Report an error with an argument.
|
||||||
*
|
*
|
||||||
* @param narg
|
* @param narg Stack index of the bad argument
|
||||||
* Stack index of the bad argument
|
* @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) {
|
||||||
// TODO: port ldebug.c and provide mode useful error messages.
|
|
||||||
error("bad argument #" + (narg - 1) + " (" + extramsg + ")");
|
error("bad argument #" + (narg - 1) + " (" + extramsg + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conditionally report an error with an argument.
|
||||||
|
*
|
||||||
|
* @param cond boolean condition that generates an error when false
|
||||||
|
* @param narg Stack index of the bad argument
|
||||||
|
* @param extramsg String to include in error message
|
||||||
|
*/
|
||||||
|
public void argcheck(boolean cond, int narg, String extramsg) {
|
||||||
|
if ( ! cond )
|
||||||
|
argerror(narg,extramsg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report a type error.
|
* Report a type error.
|
||||||
*
|
*
|
||||||
* @param narg
|
* @param narg Stack index of the bad argument
|
||||||
* Stack index of the bad argument
|
* @param typename Name of the type that was expected, such as "string"
|
||||||
* @param typename
|
|
||||||
* Name of the type that was expected
|
|
||||||
*/
|
*/
|
||||||
public void typerror(int narg, String typename) {
|
public void typerror(int narg, String typename) {
|
||||||
argerror(narg, typename + " expected, got " + typename(narg));
|
argerror(narg, typename + " expected, got " + typename(narg));
|
||||||
@@ -2642,11 +2649,8 @@ public class LuaState extends Lua {
|
|||||||
/**
|
/**
|
||||||
* Report a type error.
|
* Report a type error.
|
||||||
*
|
*
|
||||||
* @param narg
|
* @param narg Stack index of the bad argument
|
||||||
* Stack index of the bad argument
|
* @param typenum Constant value specifying the type of argument that was expected (i.e. LUA_TSTRING).
|
||||||
* @param typenum
|
|
||||||
* Constant value specifying the type of argument that was
|
|
||||||
* expected (i.e. LUA_TSTRING).
|
|
||||||
*/
|
*/
|
||||||
public void typerror(int narg, int typenum) {
|
public void typerror(int narg, int typenum) {
|
||||||
typerror(narg, TYPE_NAMES[typenum]);
|
typerror(narg, TYPE_NAMES[typenum]);
|
||||||
@@ -2713,6 +2717,17 @@ public class LuaState extends Lua {
|
|||||||
return checknumber(narg).toJavaLong();
|
return checknumber(narg).toJavaLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the function argument <code>narg</code> is a number and
|
||||||
|
* returns this number cast to a <code>double</code>.
|
||||||
|
* @param narg the argument number
|
||||||
|
* @throws LuaErrorException if the value cannot be converted to a double
|
||||||
|
* @return long value if the argument is a number or can be converted to double
|
||||||
|
*/
|
||||||
|
public double checkdouble(int narg) {
|
||||||
|
return checknumber(narg).toJavaDouble();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the function argument <code>narg</code> is a number and
|
* Checks whether the function argument <code>narg</code> is a number and
|
||||||
* returns this number.
|
* returns this number.
|
||||||
|
|||||||
Reference in New Issue
Block a user