Added some checks for invalid numbers to love.math.setRandomState

--HG--
branch : RandomGenerator-2
This commit is contained in:
Alex Szpakowski
2013-08-04 17:04:52 -03:00
parent 0447d1e7c5
commit 674ad9247a
4 changed files with 52 additions and 13 deletions
+9
View File
@@ -45,6 +45,15 @@ RandomGenerator::RandomGenerator()
#endif
}
void RandomGenerator::setState(RandomGenerator::State state)
{
// 0 xor 0 is still 0, so Xorshift can't generate new numbers.
if (state.b64 == 0)
throw love::Exception("Invalid random state.");
rng_state = state;
}
uint64 RandomGenerator::rand()
{
rng_state.b64 ^= (rng_state.b64 << 13);
+10 -8
View File
@@ -23,6 +23,7 @@
// LOVE
#include "common/config.h"
#include "common/Exception.h"
#include "common/math.h"
#include "common/int.h"
#include "common/Object.h"
@@ -56,23 +57,24 @@ public:
* Set pseudo-random state.
* It's up to the implementation how to use this.
**/
inline void setState(State state)
{
rng_state = state;
}
void setState(State state);
/**
* Separately set the low and high parts of the pseudo-random state.
**/
inline void setState(uint32 low, uint32 high)
{
State newstate;
#ifdef LOVE_BIG_ENDIAN
rng_state.b32.a = high;
rng_state.b32.b = low;
newstate.b32.a = high;
newstate.b32.b = low;
#else
rng_state.b32.b = high;
rng_state.b32.a = low;
newstate.b32.b = high;
newstate.b32.a = low;
#endif
setState(newstate);
}
inline State getState() const
+8 -1
View File
@@ -34,7 +34,14 @@ namespace math
int w_setRandomState(lua_State *L)
{
Math::instance.setRandomState(luax_checkrandomstate(L, 1));
try
{
Math::instance.setRandomState(luax_checkrandomstate(L, 1));
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
return 0;
}
+25 -4
View File
@@ -21,20 +21,34 @@
#include "wrap_RandomGenerator.h"
#include <cmath>
#include <algorithm>
namespace love
{
namespace math
{
template <typename T>
static T checkrandomstate_part(lua_State *L, int idx)
{
double num = luaL_checknumber(L, idx);
double inf = std::numeric_limits<double>::infinity();
// Disallow conversions from infinity and NaN.
if (num == inf || num == -inf || num != num)
luaL_argerror(L, idx, "invalid random state");
return (T) num;
}
RandomGenerator::State luax_checkrandomstate(lua_State *L, int idx)
{
RandomGenerator::State s;
if (!lua_isnoneornil(L, idx + 1))
{
uint32 low = (uint32) luaL_checknumber(L, idx);
uint32 high = (uint32) luaL_checknumber(L, idx + 1);
uint32 low = checkrandomstate_part<uint32>(L, idx);
uint32 high = checkrandomstate_part<uint32>(L, idx + 1);
#ifdef LOVE_BIG_ENDIAN
s.b32.a = high;
@@ -45,7 +59,7 @@ RandomGenerator::State luax_checkrandomstate(lua_State *L, int idx)
#endif
}
else
s.b64 = (uint64) luaL_checknumber(L, idx);
s.b64 = checkrandomstate_part<uint64>(L, idx);
return s;
}
@@ -84,7 +98,14 @@ RandomGenerator *luax_checkrandomgenerator(lua_State *L, int idx)
int w_RandomGenerator_setState(lua_State *L)
{
RandomGenerator *rng = luax_checkrandomgenerator(L, 1);
rng->setState(luax_checkrandomstate(L, 2));
try
{
rng->setState(luax_checkrandomstate(L, 2));
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
return 0;
}