Re-seed Math.random() for each window/frame/context (475585, r=waldo,dolske).

This commit is contained in:
Andreas Gal 2010-03-18 08:27:26 -07:00
Родитель 9a11c3a885
Коммит 29e02cea42
4 изменённых файлов: 26 добавлений и 17 удалений

Просмотреть файл

@ -111,7 +111,6 @@ JSThreadData::init()
#ifdef JS_TRACER
InitJIT(&traceMonitor);
#endif
js_InitRandom(this);
}
void
@ -522,6 +521,8 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
JS_APPEND_LINK(&cx->link, &rt->contextList);
JS_UNLOCK_GC(rt);
js_InitRandom(cx);
/*
* If cx is the first context on this runtime, initialize well-known atoms,
* keywords, numbers, and strings. If one of these steps should fail, the

Просмотреть файл

@ -540,9 +540,6 @@ struct JSThreadData {
/* Property cache for faster call/get/set invocation. */
JSPropertyCache propertyCache;
/* Random number generator state, used by jsmath.cpp. */
int64 rngSeed;
/* Optional stack of heap-allocated scoped local GC roots. */
JSLocalRootStack *localRootStack;
@ -1394,6 +1391,9 @@ struct JSContext
/* Stored here to avoid passing it around as a parameter. */
uintN resolveFlags;
/* Random number generator state, used by jsmath.cpp. */
int64 rngSeed;
#ifdef JS_TRACER
/*
* State for the current tree execution. bailExit is valid if the tree has

Просмотреть файл

@ -434,38 +434,46 @@ static const jsdouble RNG_DSCALE = jsdouble(1LL << 53);
* Math.random() support, lifted from java.util.Random.java.
*/
static inline void
random_setSeed(JSThreadData *data, int64 seed)
random_setSeed(JSContext *cx, int64 seed)
{
data->rngSeed = (seed ^ RNG_MULTIPLIER) & RNG_MASK;
cx->rngSeed = (seed ^ RNG_MULTIPLIER) & RNG_MASK;
}
void
js_InitRandom(JSThreadData *data)
js_InitRandom(JSContext *cx)
{
/* Finally, set the seed from current time. */
random_setSeed(data, PRMJ_Now() / 1000);
/*
* Set the seed from current time. Since we have a RNG per context and we often bring
* up several contexts at the same time, we xor in some additional values, namely
* the context and its successor. We don't just use the context because it might be
* possible to reverse engineer the context pointer if one guesses the time right.
*/
random_setSeed(cx,
(PRMJ_Now() / 1000) ^
int64(cx) ^
int64(cx->link.next));
}
static inline uint64
random_next(JSThreadData *data, int bits)
random_next(JSContext *cx, int bits)
{
uint64 nextseed = data->rngSeed * RNG_MULTIPLIER;
uint64 nextseed = cx->rngSeed * RNG_MULTIPLIER;
nextseed += RNG_ADDEND;
nextseed &= RNG_MASK;
data->rngSeed = nextseed;
cx->rngSeed = nextseed;
return nextseed >> (48 - bits);
}
static inline jsdouble
random_nextDouble(JSThreadData *data)
random_nextDouble(JSContext *cx)
{
return jsdouble((random_next(data, 26) << 27) + random_next(data, 27)) / RNG_DSCALE;
return jsdouble((random_next(cx, 26) << 27) + random_next(cx, 27)) / RNG_DSCALE;
}
static JSBool
math_random(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble z = random_nextDouble(JS_THREAD_DATA(cx));
jsdouble z = random_nextDouble(cx);
return js_NewNumberInRootedValue(cx, z, vp);
}
@ -670,7 +678,7 @@ math_pow_tn(jsdouble d, jsdouble p)
static jsdouble FASTCALL
math_random_tn(JSContext *cx)
{
return random_nextDouble(JS_THREAD_DATA(cx));
return random_nextDouble(cx);
}
static jsdouble FASTCALL

Просмотреть файл

@ -51,7 +51,7 @@ extern JSObject *
js_InitMathClass(JSContext *cx, JSObject *obj);
extern void
js_InitRandom(JSThreadData *data);
js_InitRandom(JSContext *cx);
extern JSBool
js_math_ceil(JSContext *cx, uintN argc, jsval *vp);