Bug 774364 - Part 4: Add setRNGState testing function. r=sstangl

This commit is contained in:
Tooru Fujisawa 2015-08-07 07:42:17 +09:00
parent 8846688d5e
commit 33242877b6
2 changed files with 67 additions and 0 deletions

View File

@ -2761,6 +2761,23 @@ GetLcovInfo(JSContext* cx, unsigned argc, Value* vp)
return true;
}
#ifdef DEBUG
static bool
SetRNGState(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.requireAtLeast(cx, "SetRNGState", 1))
return false;
double seed;
if (!ToNumber(cx, args[0], &seed))
return false;
cx->compartment()->rngState = static_cast<uint64_t>(seed) & RNG_MASK;
return true;
}
#endif
static const JSFunctionSpecWithHelp TestingFunctions[] = {
JS_FN_HELP("gc", ::GC, 0, 0,
"gc([obj] | 'compartment' [, 'shrinking'])",
@ -3208,6 +3225,12 @@ gc::ZealModeHelpText),
" Generate LCOV tracefile for the given compartment. If no global are provided then\n"
" the current global is used as the default one.\n"),
#ifdef DEBUG
JS_FN_HELP("setRNGState", SetRNGState, 1, 0,
"setRNGState(seed)",
" Set this compartment's RNG state.\n"),
#endif
JS_FS_HELP_END
};

View File

@ -0,0 +1,44 @@
function test() {
// With this seed, state won't be reset in 10000 iteration. The result is
// deterministic and it can be used to check the correctness of
// implementation.
setRNGState(0x12341234);
function f() {
let x = [];
for (let i = 0; i < 10000; i++) {
x.push(Math.random());
}
return x;
}
let x = f();
assertEq(x[0], 0.3562073961260165);
assertEq(x[10], 0.9777930699941514);
assertEq(x[100], 0.9146259915430884);
assertEq(x[1000], 0.315983055288946);
assertEq(x[2000], 0.7132284805929497);
assertEq(x[3000], 0.9621073641614717);
assertEq(x[4000], 0.3928228025111996);
assertEq(x[5000], 0.555710685962832);
assertEq(x[6000], 0.5207553912782503);
assertEq(x[7000], 0.08268413491723015);
assertEq(x[8000], 0.031796243723989925);
assertEq(x[9000], 0.900683320457098);
assertEq(x[9999], 0.7750389203054577);
// With this seed, state will be reset before calculating high bits.
// The result is nondeterministic, but it should be in [0, 1) range.
setRNGState(0);
x = f();
assertEq(x[0] >= 0 && x[0] < 1, true);
// With this seed, high bits will be 0 and state will be reset before
// calculating low bits. The result is also nondeterministic, but it should
// be in [0, 1 / (1 << 26)) range.
setRNGState(0x615c0e462aa9);
x = f();
assertEq(x[0] >= 0 && x[0] < 1 / (1 << 26), true);
}
if (typeof setRNGState == "function")
test();