ref: d3feec43652e759fc5186fab93bdded2f939f1b5
parent: 43c844510b4fa4a83d53068bf4dc5c17773815d4
author: Tor Andersson <tor.andersson@artifex.com>
date: Mon Feb 25 07:15:56 EST 2019
Issue #85: Use explicit seed in Math.random().
--- a/jsi.h
+++ b/jsi.h
@@ -203,6 +203,8 @@
js_Object *TypeError_prototype;
js_Object *URIError_prototype;
+ unsigned int seed; /* Math.random seed */
+
int nextref; /* for js_ref use */
js_Object *R; /* registry of hidden values */
js_Object *G; /* the global object */
--- a/jsmath.c
+++ b/jsmath.c
@@ -4,6 +4,32 @@
#include <time.h>
+#define JS_RAND_MAX (0x7fffffff)
+
+static unsigned int jsM_rand_temper(unsigned int x)
+{
+ x ^= x>>11;
+ x ^= x<<7 & 0x9D2C5680;
+ x ^= x<<15 & 0xEFC60000;
+ x ^= x>>18;
+ return x;
+}
+
+static int jsM_rand_r(unsigned int *seed)
+{
+ return jsM_rand_temper(*seed = *seed * 1103515245 + 12345)/2;
+}
+
+static double jsM_round(double x)
+{
+ if (isnan(x)) return x;
+ if (isinf(x)) return x;
+ if (x == 0) return x;
+ if (x > 0 && x < 0.5) return 0;
+ if (x < 0 && x >= -0.5) return -0;
+ return floor(x + 0.5);
+}
+
static void Math_abs(js_State *J)
{
js_pushnumber(J, fabs(js_tonumber(J, 1)));
@@ -68,23 +94,13 @@
static void Math_random(js_State *J)
{
- js_pushnumber(J, rand() / (RAND_MAX + 1.0));
+ js_pushnumber(J, jsM_rand_r(&J->seed) / (JS_RAND_MAX + 1.0));
}
-static double do_round(double x)
-{
- if (isnan(x)) return x;
- if (isinf(x)) return x;
- if (x == 0) return x;
- if (x > 0 && x < 0.5) return 0;
- if (x < 0 && x >= -0.5) return -0;
- return floor(x + 0.5);
-}
-
static void Math_round(js_State *J)
{
double x = js_tonumber(J, 1);
- js_pushnumber(J, do_round(x));
+ js_pushnumber(J, jsM_round(x));
}
static void Math_sin(js_State *J)
@@ -140,7 +156,7 @@
void jsB_initmath(js_State *J)
{
- srand(time(NULL));
+ J->seed = time(NULL);
js_pushobject(J, jsV_newobject(J, JS_CMATH, J->Object_prototype));
{