forked from MozillaSecurity/funfuzz
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgen-math.js
More file actions
126 lines (110 loc) · 3.23 KB
/
gen-math.js
File metadata and controls
126 lines (110 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
const NUM_MATH_FUNCTIONS = 6;
var binaryMathOps = [
" * ", " / ", " % ",
" + ", " - ",
" ** ",
" << ", " >> ", " >>> ",
" < ", " > ", " <= ", " >= ",
" == ", " != ",
" === ", " !== ",
" & ", " | ", " ^ ", " && ", " || ",
" , ",
];
var leftUnaryMathOps = [
" ! ", " + ", " - ", " ~ ",
];
// unaryMathFunctions and binaryMathFunctions updated on 2017-01-21 and added from:
// https://dxr.mozilla.org/mozilla-central/rev/3cedab21a7e65e6a1c4c2294ecfb5502575a46e3/js/src/jsmath.cpp#1330
// Update to the latest revision as needed.
var unaryMathFunctions = [
"abs",
"acos",
"acosh",
"asin",
"asinh",
"atan",
"atanh",
"cbrt",
"ceil",
"clz32",
"cos",
"cosh",
"exp",
"expm1",
// "floor", // avoid breaking rnd.
"fround",
"log",
"log2",
"log10",
"log1p",
// "random", // avoid breaking rnd. avoid non-determinism.
"round",
"sign",
"sin",
"sinh",
"sqrt",
"tan",
"tanh",
"trunc",
];
// n-ary functions will also be tested with varying numbers of parameters by makeFunction
var binaryMathFunctions = [
"atan2",
"hypot", // n-ary
"imul",
"max", // n-ary
"min", // n-ary
"pow",
];
function makeMathFunction(d, b, i)
{
if (rnd(TOTALLY_RANDOM) == 2) return totallyRandom(d, b);
var ivars = ["x", "y"];
if (rnd(10) == 0) {
// Also use variables from the enclosing scope
ivars = ivars.concat(b);
}
return "(function(x, y) { " + directivePrologue() + "return " + makeMathExpr(d, ivars, i) + "; })";
}
function makeMathExpr(d, b, i)
{
if (rnd(TOTALLY_RANDOM) == 2) return totallyRandom(d, b);
// As depth decreases, make it more likely to bottom out
if (d < rnd(5)) {
if (rnd(4)) {
return Random.index(b);
}
return Random.index(numericVals);
}
if (rnd(500) == 0 && d > 0)
return makeExpr(d - 1, b);
function r() { return makeMathExpr(d - 1, b, i); }
// Frequently, coerce both the inputs and outputs to the same "numeric sub-type"
// (asm.js formalizes this concept, but JITs may have their own variants)
var commonCoercion = rnd(10);
function mc(expr) {
switch(rnd(3) ? commonCoercion : rnd(10)) {
case 0: return "(" + " + " + expr + ")"; // f64 (asm.js)
case 1: return "Math.fround(" + expr + ")"; // f32
case 2: return "(" + expr + " | 0)"; // i32 (asm.js)
case 3: return "(" + expr + " >>> 0)"; // u32
default: return expr;
}
}
if (i > 0 && rnd(10) == 0) {
// Call a *lower-numbered* mathy function. (This avoids infinite recursion.)
return mc("mathy" + rnd(i) + "(" + mc(r()) + ", " + mc(r()) + ")");
}
if (rnd(20) == 0) {
return mc("(" + mc(r()) + " ? " + mc(r()) + " : " + mc(r()) + ")");
}
switch(rnd(4)) {
case 0: return mc("(" + mc(r()) + Random.index(binaryMathOps) + mc(r()) + ")");
case 1: return mc("(" + Random.index(leftUnaryMathOps) + mc(r()) + ")");
case 2: return mc("Math." + Random.index(unaryMathFunctions) + "(" + mc(r()) + ")");
default: return mc("Math." + Random.index(binaryMathFunctions) + "(" + mc(r()) + ", " + mc(r()) + ")");
}
}