mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
Added some checks for invalid numbers to love.math.setRandomState
--HG-- branch : RandomGenerator-2
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user