diff options
Diffstat (limited to 'js/src/jit-test/tests/ion')
920 files changed, 29518 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/ion/ArrayLengthGetPropertyIC.js b/js/src/jit-test/tests/ion/ArrayLengthGetPropertyIC.js new file mode 100644 index 0000000000..22197c7bef --- /dev/null +++ b/js/src/jit-test/tests/ion/ArrayLengthGetPropertyIC.js @@ -0,0 +1,54 @@ +function intLength (a, l) { + var res = 0; + for (var i = 0; i < l; i++) + res += a.length; + return res / l; +} + +function valueLength (a, l) { + var res = 0; + for (var i = 0; i < l; i++) + res += a.length; + return res / l; +} + +var denseArray = [0,1,2,3,4,5,6,7,8,9]; +var typedArray = new Uint8Array(10); +var hugeArray = new Array(4294967295); +var fakeArray1 = { length: 10 }; +var fakeArray2 = { length: 10.5 }; + +// Check the interpreter result and play with TI type objects. +assertEq(intLength(denseArray, 10), 10); +assertEq(intLength(typedArray, 10), 10); +// assertEq(intLength(fakeArray1, 10), 10); + +assertEq(valueLength(denseArray, 10), 10); +assertEq(valueLength(typedArray, 10), 10); +assertEq(valueLength(hugeArray , 10), 4294967295); +assertEq(valueLength(fakeArray2, 10), 10.5); + +// Heat up to compile (either JM / Ion) +assertEq(intLength(denseArray, 100), 10); +assertEq(valueLength(denseArray, 100), 10); + +// No bailout should occur during any of the following checks: + +// Check get-property length IC with dense array. +assertEq(intLength(denseArray, 1), 10); +assertEq(valueLength(denseArray, 1), 10); + +// Check get-property length IC with typed array. +assertEq(intLength(typedArray, 1), 10); +assertEq(valueLength(typedArray, 1), 10); + +// Check length which do not fit on non-double value. +assertEq(valueLength(hugeArray, 1), 4294967295); + +// Check object length property. +assertEq(intLength(fakeArray1, 1), 10); +assertEq(valueLength(fakeArray2, 1), 10.5); + +// Cause invalidation of intLength by returning a double. +assertEq(intLength(hugeArray, 1), 4294967295); +assertEq(intLength(fakeArray2, 1), 10.5); diff --git a/js/src/jit-test/tests/ion/ConvertElementsToDouble-Int32.js b/js/src/jit-test/tests/ion/ConvertElementsToDouble-Int32.js new file mode 100644 index 0000000000..bb3390416e --- /dev/null +++ b/js/src/jit-test/tests/ion/ConvertElementsToDouble-Int32.js @@ -0,0 +1,9 @@ +// Bug 1312488 + +function test(a) { + let x = 0; + for (let i = 0, len = a.length; i < len; i++) + x += a[i]; + return x; +} +assertEq(test([10.1, 10.2, 10.3, 10.4, 10]), 51); diff --git a/js/src/jit-test/tests/ion/InlineAddVTypeMonitor.js b/js/src/jit-test/tests/ion/InlineAddVTypeMonitor.js new file mode 100644 index 0000000000..af5b9532cf --- /dev/null +++ b/js/src/jit-test/tests/ion/InlineAddVTypeMonitor.js @@ -0,0 +1,17 @@ +// make sure AddV instruction is monitoring the output type when 'f' is inlined +// into the loop of 'g' +var x = {}; +var y = []; + +function f(i) { + return x + y; +} + +function g(m) { + var i; + for (i = 0; i < m; i++) { + f(i); + } +} + +g(101); diff --git a/js/src/jit-test/tests/ion/PurgeProtoChain.js b/js/src/jit-test/tests/ion/PurgeProtoChain.js new file mode 100644 index 0000000000..b6319464ab --- /dev/null +++ b/js/src/jit-test/tests/ion/PurgeProtoChain.js @@ -0,0 +1,10 @@ +// In a proto chain A-->B-->C, shadowing C.x with B.x must change C's shape. + +var C = {x: 1}; +var B = Object.create(C); +var A = Object.create(B); +for (var i = 0; i < 2000; i++) { + if (i == 1900) + B.x = 3; + assertEq(A.x, i < 1900 ? 1 : 3); +} diff --git a/js/src/jit-test/tests/ion/absd.js b/js/src/jit-test/tests/ion/absd.js new file mode 100644 index 0000000000..b0860965a9 --- /dev/null +++ b/js/src/jit-test/tests/ion/absd.js @@ -0,0 +1,7 @@ +var do_abs = function(x) { + return Math.abs(x); +} +var i; +for (i=0;i<50;i++) + do_abs(-1.5); +assertEq(do_abs(-2.5), 2.5); diff --git a/js/src/jit-test/tests/ion/andOr.js b/js/src/jit-test/tests/ion/andOr.js new file mode 100644 index 0000000000..ae92f5462b --- /dev/null +++ b/js/src/jit-test/tests/ion/andOr.js @@ -0,0 +1,31 @@ +function testBooleans(a, b) { + var res = 0; + if (a && b) res += 2; + if (b || a) res += 1; + return res; +} +assertEq(testBooleans(false, false), 0); +assertEq(testBooleans(false, true), 1); +assertEq(testBooleans(true, false), 1); +assertEq(testBooleans(true, true), 3); + +function testShortCircuit(a) { + var b = 0; + ++a && a++; + a || (b = 100); + return a + b; +} +assertEq(testShortCircuit(0), 2); +assertEq(testShortCircuit(-2), 100); +assertEq(testShortCircuit(-1), 100); + +function testValues(a, b) { + if (a && b) return 2; + if (b || a) return 1; + return 0; +} +assertEq(testValues(false, true), 1); +assertEq(testValues("foo", 22), 2); +assertEq(testValues(null, ""), 0); +assertEq(testValues(Math.PI, undefined), 1); +assertEq(testValues(Math.abs, 2.2), 2); diff --git a/js/src/jit-test/tests/ion/arguments-type-reflow.js b/js/src/jit-test/tests/ion/arguments-type-reflow.js new file mode 100644 index 0000000000..aaa03cc60f --- /dev/null +++ b/js/src/jit-test/tests/ion/arguments-type-reflow.js @@ -0,0 +1,17 @@ +// |jit-test| error: InternalError: too much recursion +// FIXME: this should not give an internal error once OSI lands. + +var forceReflow = false; + +function rec(x, self) { + if (x > 0) + self(x - 1, self); + else if (forceReflow) + self(NaN, self); +} + +for (var i = 0; i < 40; ++i) + rec(1, rec); + +forceReflow = true; +rec(1, rec); diff --git a/js/src/jit-test/tests/ion/arithstringtonumber.js b/js/src/jit-test/tests/ion/arithstringtonumber.js new file mode 100644 index 0000000000..56fb119dec --- /dev/null +++ b/js/src/jit-test/tests/ion/arithstringtonumber.js @@ -0,0 +1,19 @@ +var g_array = [0, 1]; + +function g(p) { + p = p - 0; + return g_array[p - 0]; +} + +function f() { + var q = 0; + for (var i = 0; i < 10; ++i) { + q += g("0x0"); + q += g("0x1"); + } + return q; +} + +for (var j = 0; j < 2; ++j) { + assertEq(f(), 10); +} diff --git a/js/src/jit-test/tests/ion/array-join-bug1137624-1.js b/js/src/jit-test/tests/ion/array-join-bug1137624-1.js new file mode 100644 index 0000000000..1a039dc688 --- /dev/null +++ b/js/src/jit-test/tests/ion/array-join-bug1137624-1.js @@ -0,0 +1,12 @@ + +try { + var x = ["a", {toString() { s = x.join("-"); }}]; + var a = x.join("a"); + var b = x.join("b"); + assertEq(a, b); +} catch (e) { + // Using assertion does not work. + quit(0); +} + +quit(3); diff --git a/js/src/jit-test/tests/ion/array-join-bug1137624-2.js b/js/src/jit-test/tests/ion/array-join-bug1137624-2.js new file mode 100644 index 0000000000..affceb37e7 --- /dev/null +++ b/js/src/jit-test/tests/ion/array-join-bug1137624-2.js @@ -0,0 +1,9 @@ + +function f() { + var x = 0; + var a = [{toString: () => x++}]; + for (var i=0; i<10000; i++) + a.join(""); + assertEq(x, 10000); +} +f(); diff --git a/js/src/jit-test/tests/ion/array-push-frozen-array.js b/js/src/jit-test/tests/ion/array-push-frozen-array.js new file mode 100644 index 0000000000..4dfe32daae --- /dev/null +++ b/js/src/jit-test/tests/ion/array-push-frozen-array.js @@ -0,0 +1,19 @@ +function maybeFreeze(arr, b) { + with(this) {}; // Don't inline this. + if (b) { + Object.freeze(arr); + } +} +function test() { + var arr = []; + for (var i = 0; i < 1800; i++) { + maybeFreeze(arr, i > 1500); + try { + arr.push(2); + assertEq(i <= 1500, true); + } catch(e) { + assertEq(e instanceof TypeError, true); + } + } +} +test(); diff --git a/js/src/jit-test/tests/ion/array-push-length-overflow.js b/js/src/jit-test/tests/ion/array-push-length-overflow.js new file mode 100644 index 0000000000..4f7ef485a0 --- /dev/null +++ b/js/src/jit-test/tests/ion/array-push-length-overflow.js @@ -0,0 +1,14 @@ +function maybeSetLength(arr, b) { + with(this) {}; + if (b) + arr.length = 0x7fffffff; +} +function test() { + var arr = []; + for (var i=0; i<2000; i++) { + maybeSetLength(arr, i > 1500); + var res = arr.push(2); + assertEq(res, i > 1500 ? 0x80000000 : i + 1); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/array-push-multiple-frozen.js b/js/src/jit-test/tests/ion/array-push-multiple-frozen.js new file mode 100644 index 0000000000..271f6cb07a --- /dev/null +++ b/js/src/jit-test/tests/ion/array-push-multiple-frozen.js @@ -0,0 +1,85 @@ +// |jit-test| --no-threads; skip-if: !('oomAtAllocation' in this) + +// This test case check's Ion ability to recover from an allocation failure in +// the inlining of Array.prototype.push, when given multiple arguments. Note, +// that the following are not equivalent in case of failures: +// +// arr = []; +// arr.push(1,2,3); // OOM ---> arr == [] +// +// arr = []; +// arr.push(1); +// arr.push(2); // OOM --> arr == [1] +// arr.push(3); + +function canIoncompile() { + while (true) { + var i = inIon(); + if (i) + return i; + } +} + +if (canIoncompile() != true) + quit(); +if ("gczeal" in this) + gczeal(0); + +function pushLimits(limit, offset, arr, freeze) { + arr = arr || []; + arr.push(0,1,2,3,4,5,6,7,8,9); + arr.length = offset; + var l = arr.length; + var was = inIon(); + oomAtAllocation(limit); + try { + for (var i = 0; i < 50; i++) + arr.push(0,1,2,3,4,5,6,7,8,9); + if (freeze) + arr.frozen(); + for (var i = 0; i < 100; i++) + arr.push(0,1,2,3,4,5,6,7,8,9); + } catch (e) { + // Catch OOM. + } + resetOOMFailure(); + assertEq(arr.length % 10, l); + // Check for a bailout. + var is = inIon(); + return was ? is ? 1 : 2 : 0; +} + +// We need this limit to be high enough to be able to OSR in the for-loop of +// pushLimits. +var limit = 1024 * 1024 * 1024; +while(true) { + var res = pushLimits(limit, 0); + + if (res == 0) { + limit = 1024 * 1024 * 1024; + } else if (res == 1) { // Started and finished in Ion. + if (limit <= 1) // If we are not in the Jit. + break; + // We want to converge quickly to a state where the memory is limited + // enough to cause failures in array.prototype.push. + limit = (limit / 2) | 0; + } else if (res == 2) { // Started in Ion, and finished in Baseline. + if (limit < 10) { + // This is used to offset the OOM location, such that we can test + // each steps of the Array.push function, when it is jitted. + for (var off = 1; off < 10; off++) { + var arr = []; + try { + pushLimits(limit, off, arr, true); + } catch (e) { + // Cacth OOM produced while generating the error message. + } + if (arr.length > 10) assertEq(arr[arr.length - 1], 9); + else assertEq(arr[arr.length - 1], arr.length - 1); + } + } + if (limit == 1) + break; + limit--; + } +} diff --git a/js/src/jit-test/tests/ion/array-push-multiple-with-funapply.js b/js/src/jit-test/tests/ion/array-push-multiple-with-funapply.js new file mode 100644 index 0000000000..b09fa9c440 --- /dev/null +++ b/js/src/jit-test/tests/ion/array-push-multiple-with-funapply.js @@ -0,0 +1,78 @@ +// |jit-test| --no-threads; skip-if: !('oomAtAllocation' in this) + +// This test case check's Ion ability to inline Array.prototype.push, when +// fun.apply is used and inlined with the set of arguments of the current +// function. Note, that the following are not equivalent in case of failures: +// +// arr = []; +// arr.push(1,2,3); // OOM ---> arr == [] +// +// arr = []; +// arr.push(1); +// arr.push(2); // OOM --> arr == [1] +// arr.push(3); + +function canIoncompile() { + while (true) { + var i = inIon(); + if (i) + return i; + } +} + +if (canIoncompile() != true) + quit(); +if ("gczeal" in this) + gczeal(0); + +function pushLimits(limit, offset) { + function pusher() { + Array.prototype.push.apply(arr, arguments) + } + var arr = [0,1,2,3,4,5,6,7]; + arr.length = offset; + var l = arr.length; + var was = inIon(); + oomAtAllocation(limit); + try { + for (var i = 0; i < 100; i++) + pusher(0,1,2,3,4,5,6,7); + } catch (e) { + // Catch OOM. + } + resetOOMFailure(); + assertEq(arr.length % 8, l); + // Check for a bailout. + var is = inIon(); + return was ? is ? 1 : 2 : 0; +} + + + +// We need this limit to be high enough to be able to OSR in the for-loop of +// pushLimits. +var limit = 1024 * 1024 * 1024; +while(true) { + var res = pushLimits(limit, 0); + print(limit, res); + + if (res == 0) { + limit = 1024 * 1024 * 1024; + } else if (res == 1) { // Started and finished in Ion. + // We want to converge quickly to a state where the memory is limited + // enough to cause failures in array.prototype.push. + limit = (limit / 1.5) | 0; + if (limit == 0) // If we are not in the Jit. + break; + } else if (res == 2) { // Started in Ion, and finished in Baseline. + if (limit < 10) { + // This is used to offset the OOM location, such that we can test + // each steps of the Array.push function, when it is jitted. + for (var off = 1; off < 8; off++) + pushLimits(limit, off); + } + if (limit == 1) + break; + limit--; + } +} diff --git a/js/src/jit-test/tests/ion/array-push-multiple.js b/js/src/jit-test/tests/ion/array-push-multiple.js new file mode 100644 index 0000000000..19c1a93e70 --- /dev/null +++ b/js/src/jit-test/tests/ion/array-push-multiple.js @@ -0,0 +1,72 @@ +// |jit-test| --no-threads; skip-if: !('oomAtAllocation' in this) + +// This test case check's Ion ability to recover from an allocation failure in +// the inlining of Array.prototype.push, when given multiple arguments. Note, +// that the following are not equivalent in case of failures: +// +// arr = []; +// arr.push(1,2,3); // OOM ---> arr == [] +// +// arr = []; +// arr.push(1); +// arr.push(2); // OOM --> arr == [1] +// arr.push(3); + +function canIoncompile() { + while (true) { + var i = inIon(); + if (i) + return i; + } +} + +if (canIoncompile() != true) + quit(); +if ("gczeal" in this) + gczeal(0); + +function pushLimits(limit, offset) { + var arr = [0,1,2,3,4,5,6,7,8,9]; + arr.length = offset; + var l = arr.length; + var was = inIon(); + oomAtAllocation(limit); + try { + for (var i = 0; i < 100; i++) + arr.push(0,1,2,3,4,5,6,7,8,9); + } catch (e) { + // Catch OOM. + } + resetOOMFailure(); + assertEq(arr.length % 10, l); + // Check for a bailout. + var is = inIon(); + return was ? is ? 1 : 2 : 0; +} + +// We need this limit to be high enough to be able to OSR in the for-loop of +// pushLimits. +var limit = 1024 * 1024 * 1024; +while(true) { + var res = pushLimits(limit, 0); + + if (res == 0) { + limit = 1024 * 1024 * 1024; + } else if (res == 1) { // Started and finished in Ion. + if (limit <= 1) // If we are not in the Jit. + break; + // We want to converge quickly to a state where the memory is limited + // enough to cause failures in array.prototype.push. + limit = (limit / 2) | 0; + } else if (res == 2) { // Started in Ion, and finished in Baseline. + if (limit < 10) { + // This is used to offset the OOM location, such that we can test + // each steps of the Array.push function, when it is jitted. + for (var off = 1; off < 10; off++) + pushLimits(limit, off); + } + if (limit == 1) + break; + limit--; + } +} diff --git a/js/src/jit-test/tests/ion/array-splice.js b/js/src/jit-test/tests/ion/array-splice.js new file mode 100644 index 0000000000..cb39a21ed5 --- /dev/null +++ b/js/src/jit-test/tests/ion/array-splice.js @@ -0,0 +1,38 @@ +function test1() { + // splice GetElement calls are observable and should be executed even if + // the return value of splice is unused. + Object.defineProperty(Object.prototype, "0", {get: function() { + c++; + }, set: function() {}}); + var arr = [,,,]; + var c = 0; + for (var i=0; i<100; i++) { + arr.splice(0, 1); + arr.length = 1; + } + + assertEq(c, 100); +} +test1(); + +function test2() { + var arr = []; + for (var i=0; i<100; i++) + arr.push(i); + for (var i=0; i<40; i++) + arr.splice(0, 2); + assertEq(arr.length, 20); + assertEq(arr[0], undefined); + assertEq(arr[1], 81); +} +test2(); + +function testNonArray() { + for (var i=0; i<10; i++) { + var o = {splice:[].splice, 0:"a", 1:"b", 2:"c", length:3}; + o.splice(0, 2); + assertEq(o.length, 1); + assertEq(o[0], "c"); + } +} +testNonArray(); diff --git a/js/src/jit-test/tests/ion/bailout-env.js b/js/src/jit-test/tests/ion/bailout-env.js new file mode 100644 index 0000000000..2edfaf2502 --- /dev/null +++ b/js/src/jit-test/tests/ion/bailout-env.js @@ -0,0 +1,54 @@ +function inner_env() { + let result = []; + + let x = 0; + result.push(() => x); + + var tmp = [1,2,3]; + for (let y in tmp) + result.push(() => tmp[y]) + + for (let z = 4; z < 7; z++) + result.push(() => z) + + return result; +} + +function outer_env() { + let result = inner_env(); + + var tmp = [7,8,9]; + for (let x in tmp) + result.push(() => tmp[x]) + + return result; +} + +function check_result(result, expectedLen) { + assertEq(result.length, expectedLen); + + for (var i = 0; i < expectedLen; ++i) + assertEq(result[i], i); +} + +// Wipeout jitcode +bailout(); +gc(); gc(); + +// Test lexical environment bailouts +for (var i = 0; i < 100; ++i) +{ + bailAfter(i); + + var result = inner_env().map(fn => fn()); + check_result(result, 7); +} + +// Test inlined lexical environment bailouts +for (var i = 0; i < 100; ++i) +{ + bailAfter(i); + + var result = outer_env().map(fn => fn()); + check_result(result, 10); +} diff --git a/js/src/jit-test/tests/ion/bailout-spread.js b/js/src/jit-test/tests/ion/bailout-spread.js new file mode 100644 index 0000000000..2b7105c735 --- /dev/null +++ b/js/src/jit-test/tests/ion/bailout-spread.js @@ -0,0 +1,53 @@ +function f1(a,b,c,d) { + if (a < 0) + throw arguments; + + return a + b + c + d; +} + +function f2(a,b,c,d,e) { + return f1(a,b,c,d*e); +} + +function f3(a,v) { + return f2(a, ...v); +} + +function f4(i, j) { + return f3(i, [j,3,4,5]); +} + +function f5(i) { + return f4(i, i); +} + +// Clean jitcode +gc(); gc(); + +// Test bailouts through spreadcall +for (var i = 0; i < 1000; ++i) +{ + bailAfter(i); + assertEq(f5(i), i+i+23); +} + +// Test exception unwind bailout through spreadcall +for (var i = 1; i < 100; ++i) +{ + let x; + + try { + f5(-i); + + // Unreachable + assertEq(1, 0); + } + catch (e) { + x = e; + } + + assertEq(x[0], -i); + assertEq(x[1], -i); + assertEq(x[2], 3); + assertEq(x[3], 20); +} diff --git a/js/src/jit-test/tests/ion/bailout-with-object-or-null.js b/js/src/jit-test/tests/ion/bailout-with-object-or-null.js new file mode 100644 index 0000000000..260a20933d --- /dev/null +++ b/js/src/jit-test/tests/ion/bailout-with-object-or-null.js @@ -0,0 +1,17 @@ + +function foo(p) { + this.f = p; +} +function use(v, a, b) { + var f = v.f; + g = f; + g = a + b; + if (f != null) + return; +} + +with({}){} + +for (var i = 0; i < 2000; i++) + use(new foo(i % 2 ? {} : null), 1, 2); +use(new foo(null), 2147483548, 1000); diff --git a/js/src/jit-test/tests/ion/bindname.js b/js/src/jit-test/tests/ion/bindname.js new file mode 100644 index 0000000000..be5eca2d03 --- /dev/null +++ b/js/src/jit-test/tests/ion/bindname.js @@ -0,0 +1,53 @@ +// Test the scope chain walk. +function test1() { + var x = 0; + function f1(addprop) { + function f2() { + eval(""); + function f3() { + eval(""); + function f4() { + for (var i=0; i<100; i++) { + x = x + i; + } + } + return f4; + } + return f3(); + } + var g = f2(); + g(); + if (addprop) + eval("var a1 = 3; var x = 33;"); + g(); + if (addprop) + assertEq(x, 4983); + return f2(); + } + + var g = f1(true); + g(); + g = f1(false); + eval("var y = 2020; var z = y + 3;"); + g(); + return x; +} +assertEq(test1(), 19800); + +// Test with non-cacheable objects on the scope chain. +function test2(o) { + var x = 0; + with ({}) { + with (o) { + var f = function() { + for (var i=0; i<100; i++) { + x++; + } + }; + } + } + f(); + assertEq(o.x, 110); + assertEq(x, 0); +} +test2({x: 10}); diff --git a/js/src/jit-test/tests/ion/bug-770309-mcall-bailout.js b/js/src/jit-test/tests/ion/bug-770309-mcall-bailout.js new file mode 100644 index 0000000000..9886a75a1d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug-770309-mcall-bailout.js @@ -0,0 +1,68 @@ + +// Test various code paths associated with fused getprop/poly inlining. + +function A(a) { this.a = a; } +A.prototype.foo = function (x) { return (x % 3) + this.a; }; + +function B(b) { this.b = b; } +B.prototype.foo = function (x) { return (x % 3) + this.b + 1; }; + +// c.foo() for some (c instanceof C) should always hit the fallback +// path of any fused poly inline cache created for it. +function C(c) { this.c = c; } +var GLOBX = {'x': function (x) { + if (x > 29500) + throw new Error("ERROR"); + return 2; +}}; +function C_foo1(x) { + return (x % 3) + this.c + GLOBX.x(x) + 1; +} +function C_foo2(x) { + return (x % 3) + this.c + GLOBX.x(x) + 2; +} +C.prototype.foo = C_foo1; + +// Create an array of As, Bs, and Cs. +function makeArray(n) { + var classes = [A, B, C]; + var arr = []; + for (var i = 0; i < n; i++) { + arr.push(new classes[i % 3](i % 3)); + } + return arr; +} + +// Call foo on them, sum up results into first elem of resultArray +function runner(arr, resultArray, len) { + for (var i = 0; i < len; i++) { + // This changes the type of returned value from C.foo(), leading to + // a bailout fater the call obj.foo() below. + var obj = arr[i]; + resultArray[0] += obj.foo(i); + } +} + +// Make an array of instance. +var resultArray = [0]; +var arr = makeArray(30000); + +// Run runner for a bit with C.prototype.foo being C_foo1 +runner(arr, resultArray, 100); + +// Run runner for a bit with C.prototype.foo being C_foo2 +C.prototype.foo = C_foo2; +runner(arr, resultArray, 100); + +// Run runner for a bit longer to force GLOBX.x to raise +// an error inside a call to C.prototype.foo within runner. +var gotError = false; +try { + runner(arr, resultArray, 30000); +} catch(err) { + gotError = true; +} + +// Check results. +assertEq(gotError, true); +assertEq(resultArray[0], 108859); diff --git a/js/src/jit-test/tests/ion/bug-870034.js b/js/src/jit-test/tests/ion/bug-870034.js new file mode 100644 index 0000000000..1bb6e095f5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug-870034.js @@ -0,0 +1,12 @@ +// |jit-test| --ion-eager +function f(b) { + var a = arguments; + if (b) + f(false); + else + g = { + apply:function(x,y) { "use asm"; function g() {} return g } + }; + g.apply(null, a); +} +f(true); diff --git a/js/src/jit-test/tests/ion/bug-952818.js b/js/src/jit-test/tests/ion/bug-952818.js new file mode 100644 index 0000000000..21c48f8f83 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug-952818.js @@ -0,0 +1,9 @@ +(function() { + eval("\ + (function() {\ + var f = function(){\ + f\ + }\ + })()\ + ") +})() diff --git a/js/src/jit-test/tests/ion/bug1000605.js b/js/src/jit-test/tests/ion/bug1000605.js new file mode 100644 index 0000000000..f2c78dbc1d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1000605.js @@ -0,0 +1,43 @@ +setJitCompilerOption("baseline.warmup.trigger", 0); +setJitCompilerOption("ion.warmup.trigger", 0); + +function ceil(a, b) { + return Math.ceil((a | 0) / (b | 0)) | 0; +} +function floor(a, b) { + return Math.floor((a | 0) / (b | 0)) | 0; +} +function round(a, b) { + return Math.round((a | 0) / (b | 0)) | 0; +} +function intdiv(a, b) { + return ((a | 0) / (b | 0)) | 0; +} + +// Always rounds up. +assertEq(ceil(5, 5), 1); +assertEq(ceil(4, 3), 2); +assertEq(ceil(5, 3), 2); +assertEq(ceil(-4, 3), -1); +assertEq(ceil(-5, 3), -1); + +// Always rounds down. +assertEq(floor(5, 5), 1); +assertEq(floor(4, 3), 1); +assertEq(floor(5, 3), 1); +assertEq(floor(-4, 3), -2); +assertEq(floor(-5, 3), -2); + +// Always rounds towards the nearest. +assertEq(round(5, 5), 1); +assertEq(round(4, 3), 1); +assertEq(round(5, 3), 2); +assertEq(round(-4, 3), -1); +assertEq(round(-5, 3), -2); + +// Always rounds towards zero. +assertEq(intdiv(5, 5), 1); +assertEq(intdiv(4, 3), 1); +assertEq(intdiv(5, 3), 1); +assertEq(intdiv(-4, 3), -1); +assertEq(intdiv(-5, 3), -1); diff --git a/js/src/jit-test/tests/ion/bug1000960.js b/js/src/jit-test/tests/ion/bug1000960.js new file mode 100644 index 0000000000..bf32f84439 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1000960.js @@ -0,0 +1,9 @@ +function testFloat32SetElemIC(a) { + for (var i = 0; i < a.length; i++) { + var r = Math.fround(Number.MAX_VALUE); + a[i] = r; + assertEq(a[i], r); + } +} +testFloat32SetElemIC(new Array(2048)); +testFloat32SetElemIC(new Float32Array(2048)); diff --git a/js/src/jit-test/tests/ion/bug1001222.js b/js/src/jit-test/tests/ion/bug1001222.js new file mode 100644 index 0000000000..98c7971bc6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1001222.js @@ -0,0 +1,5 @@ +function f(x, y) { + return +(x ? x : y), y >>> 0 +} +f(0, -0) +f(0, 2147483649) diff --git a/js/src/jit-test/tests/ion/bug1001378.js b/js/src/jit-test/tests/ion/bug1001378.js new file mode 100644 index 0000000000..f5953af24b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1001378.js @@ -0,0 +1,17 @@ +// Test that we don't incorrectly optimize out argument slots from resume +// points. + +function boo() { + return foo.arguments[0]; +} +function foo(a,b,c) { + if (a == 0) { + a ^= ""; + return boo(); + } +} +function inlined() { + return foo.apply({}, arguments); +} +assertEq(inlined(1,2,3), undefined); +assertEq(inlined(0,2,3), 0); diff --git a/js/src/jit-test/tests/ion/bug1001382.js b/js/src/jit-test/tests/ion/bug1001382.js new file mode 100644 index 0000000000..0c7044f2d4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1001382.js @@ -0,0 +1,10 @@ +var i = 0; +var expectedmatch = ''; +var expectedmatches = new Array(); +addThis(); +expectedmatch = null; +addThis(); +function addThis() { + Array(-2147483648, -2147483648); + expectedmatches[i] = expectedmatch; +} diff --git a/js/src/jit-test/tests/ion/bug1001850.js b/js/src/jit-test/tests/ion/bug1001850.js new file mode 100644 index 0000000000..e9b002d718 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1001850.js @@ -0,0 +1,110 @@ +function t1() { + assertEq(thisValue, this); +} + +thisValue = {}; +var f1 = t1.bind(thisValue); +f1() +f1() + +//////////////////////////////////////////////////////////// + +function t2() { + bailout(); +} + +var f2 = t2.bind(thisValue); +f2() +f2() + +//////////////////////////////////////////////////////////// + +function test3() { + function i3(a,b,c,d) { + bailout(); + } + + function t3(a,b,c,d) { + i3(a,b,c,d); + } + + var f3 = t3.bind(thisValue); + for (var i=0;i<10; i++) { + f3(1,2,3,4) + f3(1,2,3,4) + } +} +test3(); +test3(); + +//////////////////////////////////////////////////////////// + +function test4() { + this.a = 1; + var inner = function(a,b,c,d) { + bailout(); + } + + var t = function(a,b,c,d) { + assertEq(this.a, undefined); + inner(a,b,c,d); + assertEq(this.a, undefined); + } + + var f = t.bind(thisValue); + for (var i=0;i<5; i++) { + var res = f(1,2,3,4) + var res2 = new f(1,2,3,4) + assertEq(res, undefined); + assertEq(res2 == undefined, false); + } +} +test4(); +test4(); + +//////////////////////////////////////////////////////////// + +function test5() { + this.a = 1; + var inner = function(a,b,c,d) { + assertEq(a, 1); + assertEq(b, 2); + assertEq(c, 3); + assertEq(d, 1); + bailout(); + assertEq(a, 1); + assertEq(b, 2); + assertEq(c, 3); + assertEq(d, 1); + } + + var t = function(a,b,c,d) { + inner(a,b,c,d); + } + + var f = t.bind(thisValue, 1,2,3); + for (var i=0;i<5; i++) { + f(1,2,3,4) + } +} +test5(); +test5(); + +//////////////////////////////////////////////////////////// + +function test6() { + function i6(a,b,c,d) { + if (a == 1) + bailout(); + } + + function t6(a,b,c,d) { + i6(a,b,c,d); + } + + var f6 = t6.bind(thisValue, 1); + f6(1,2,3,4) + f6(0,2,3,4) +} +test6(); +test6(); diff --git a/js/src/jit-test/tests/ion/bug1003694.js b/js/src/jit-test/tests/ion/bug1003694.js new file mode 100644 index 0000000000..7999510f19 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1003694.js @@ -0,0 +1,9 @@ +function f(i) { + if (i >= 10) + return; + var d = 3 + Math.abs(); + f(i ? i + 1 : 1); + bailout(); +} + +f(0); diff --git a/js/src/jit-test/tests/ion/bug1005458.js b/js/src/jit-test/tests/ion/bug1005458.js new file mode 100644 index 0000000000..02c7ceb66a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1005458.js @@ -0,0 +1,5 @@ +(function(x) { + for (var y = 0; y < 1; y++) { + assertEq(Array.prototype.shift.call(arguments.callee.arguments), 0); + } +})(0) diff --git a/js/src/jit-test/tests/ion/bug1005590.js b/js/src/jit-test/tests/ion/bug1005590.js new file mode 100644 index 0000000000..4fe1363bee --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1005590.js @@ -0,0 +1,9 @@ +function f(x) { + "use asm" + return !(1 || x) +} +for (var j = 0; j < 1; j++) { + (function(x) { + +f(+x) + })() +} diff --git a/js/src/jit-test/tests/ion/bug1006885.js b/js/src/jit-test/tests/ion/bug1006885.js new file mode 100644 index 0000000000..20819433b3 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1006885.js @@ -0,0 +1,9 @@ +function checkConstruct(thing, buggy) { + try { + new thing(); + } catch (e) {} +} +var boundFunctionPrototype = Function.prototype.bind(); +checkConstruct(boundFunctionPrototype, true); +var boundBuiltin = Math.sin.bind(); +checkConstruct(boundBuiltin, true); diff --git a/js/src/jit-test/tests/ion/bug1007027.js b/js/src/jit-test/tests/ion/bug1007027.js new file mode 100644 index 0000000000..f98c14fe87 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1007027.js @@ -0,0 +1,5 @@ +// |jit-test| error: ReferenceError +(function(x) { + x = i ? 4 : 2 + y +})() diff --git a/js/src/jit-test/tests/ion/bug1007213.js b/js/src/jit-test/tests/ion/bug1007213.js new file mode 100644 index 0000000000..6366e1e3f0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1007213.js @@ -0,0 +1,21 @@ + +function getval(o) { + return obj.val +} +function f(x, o) { + var lhs = -(~x >>> 0) + var rhs = getval(o) + return (lhs - rhs >> 0) +} +function getObj(v) { + return { + val: v + } +} + +var obj = getObj(1) +assertEq(f(0, obj), 0) +assertEq(f(0, obj), 0) +obj = getObj('can has bug?') +obj = getObj(.5) +assertEq(f(0, obj), 1) diff --git a/js/src/jit-test/tests/ion/bug1015498.js b/js/src/jit-test/tests/ion/bug1015498.js new file mode 100644 index 0000000000..9276fe55bf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1015498.js @@ -0,0 +1,91 @@ +setJitCompilerOption("baseline.warmup.trigger", 10); +setJitCompilerOption("ion.warmup.trigger", 20); + +function myFloor(x) { + if(x >= 0) + return x - Math.abs(x % 1); + else + return x - Math.abs(1 + (x % 1)); +} + +function floorRangeTest(x) { + if(10 < x) { + if(x < 100) { + assertEq(Math.floor(x), myFloor(x)); + } + } + + if(-100 < x) { + if(x < -10) { + assertEq(Math.floor(x), myFloor(x)); + } + } + + if (-(4294967296 - 1) < x) { + if(x < 10) { + assertEq(Math.floor(x), myFloor(x)); + } + } + + if (-10 < x) { + if(x < 4294967296) { + assertEq(Math.floor(x), myFloor(x)); + } + } + + if (-2147483648 < x) { + if(x < 10) { + assertEq(Math.floor(x), myFloor(x)); + } + } + + if ((-2147483648 -1) < x) { + if(x < 10) { + assertEq(Math.floor(x), myFloor(x)); + } + } + + if (10 < x) { + if(x < 2147483648) { + assertEq(Math.floor(x), myFloor(x)); + } + } + + if (10 < x) { + if(x < 2147483649) { + assertEq(Math.floor(x), myFloor(x)); + } + } + + if (Math.pow(2,31) < x) { + if(x < Math.pow(2,33)) { + assertEq(Math.floor(x), myFloor(x)); + } + } +} + +var a = [Math.pow(2,31), Math.pow(2,33), -4294967296.4, 214748364.2, -50.4, 50.4]; + +for(var i = 0; i < 10; i++) { + for (var j = 0; j < a.length; j++) { + floorRangeTest(a[j]); + } +} + +for (var j = 0; j < 30; j++) { + (function() { + Math.floor(1.5); + })() +} + +for (var j = 0; j < 30; j++) { + (function() { + Math.floor(-1.5); + })() +} + +for (var j = 0; j < 30; j++) { + (function() { + Math.floor(-127.5); + })() +} diff --git a/js/src/jit-test/tests/ion/bug1018621.js b/js/src/jit-test/tests/ion/bug1018621.js new file mode 100644 index 0000000000..e9f530b63d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1018621.js @@ -0,0 +1,7 @@ +function strictSome(k) { + "use strict"; + for (var i = 0; i < args.length; i++) + assertEq(arguments[i], args[i], "wrong argument " + i); +} +args = [8, 6, 7, NaN, undefined, 0.3]; +strictSome.call(NaN, 8, 6, 7, NaN, undefined, 0.3); diff --git a/js/src/jit-test/tests/ion/bug1022081.js b/js/src/jit-test/tests/ion/bug1022081.js new file mode 100644 index 0000000000..f1e198849a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1022081.js @@ -0,0 +1,8 @@ +function f() { + (function() { + gc() + })() +} +enableGeckoProfiling() +f() +f() diff --git a/js/src/jit-test/tests/ion/bug1027510.js b/js/src/jit-test/tests/ion/bug1027510.js new file mode 100644 index 0000000000..62556086ae --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1027510.js @@ -0,0 +1,96 @@ +setJitCompilerOption("baseline.warmup.trigger", 10); +setJitCompilerOption("ion.warmup.trigger", 20); + +function myCeil(x) { + if(x >= 0) { + var r = Math.abs(x % 1); + if(r != 0) + return (x + 1) - r; + else + return x; + } + else + return x + Math.abs(x % 1); +} + +function ceilRangeTest(x) { + if(10 < x) { + if(x < 100) { + assertEq(Math.ceil(x), myCeil(x)); + } + } + + if(-100 < x) { + if(x < -10) { + assertEq(Math.ceil(x), myCeil(x)); + } + } + + if (-(4294967296 - 1) < x) { + if(x < 10) { + assertEq(Math.ceil(x), myCeil(x)); + } + } + + if (-10 < x) { + if(x < 4294967296) { + assertEq(Math.ceil(x), myCeil(x)); + } + } + + if (-2147483648 < x) { + if(x < 10) { + assertEq(Math.ceil(x), myCeil(x)); + } + } + + if ((-2147483648 -1) < x) { + if(x < 10) { + assertEq(Math.ceil(x), myCeil(x)); + } + } + + if (10 < x) { + if(x < 2147483648) { + assertEq(Math.ceil(x), myCeil(x)); + } + } + + if (10 < x) { + if(x < 2147483649) { + assertEq(Math.ceil(x), myCeil(x)); + } + } + + if (Math.pow(2,31) < x) { + if(x < Math.pow(2,33)) { + assertEq(Math.ceil(x), myCeil(x)); + } + } +} + +var a = [Math.pow(2,31), Math.pow(2,33), -4294967296.4, 214748364.2, -50.4, 50.4]; + +for(var i = 0; i < 10; i++) { + for (var j = 0; j < a.length; j++) { + ceilRangeTest(a[j]); + } +} + +for (var j = 0; j < 30; j++) { + (function() { + Math.ceil(1.5); + })() +} + +for (var j = 0; j < 30; j++) { + (function() { + Math.ceil(-1.5); + })() +} + +for (var j = 0; j < 30; j++) { + (function() { + Math.ceil(-127.5); + })() +} diff --git a/js/src/jit-test/tests/ion/bug1028910.js b/js/src/jit-test/tests/ion/bug1028910.js new file mode 100644 index 0000000000..25c0f7762e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1028910.js @@ -0,0 +1,14 @@ +setJitCompilerOption("ion.warmup.trigger", 4); + +var IsObject = getSelfHostedValue("IsObject") +function test(foo) { + if (IsObject(foo)) { + print(foo.test) + } + +} + +for (var i=0; i<10; i++) { + test(1) + test({}) +} diff --git a/js/src/jit-test/tests/ion/bug1033873.js b/js/src/jit-test/tests/ion/bug1033873.js new file mode 100644 index 0000000000..0caae6ff49 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1033873.js @@ -0,0 +1,6 @@ +function f() { + return __proto__ +} +f(); +f(); +assertEq(!!f(), true); diff --git a/js/src/jit-test/tests/ion/bug1034400.js b/js/src/jit-test/tests/ion/bug1034400.js new file mode 100644 index 0000000000..d55aaffc79 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1034400.js @@ -0,0 +1,28 @@ +var countG = 0; +function g() { + switch(countG++) { + case 0: return 42; + case 1: return "yo"; + case 2: return {}; + } +} + +var countFault = 0; +function uceFault() { + if (countFault++ == 4) + uceFault = function() { return true } + return false; +} + +function f() { + var x = !g(); + if (uceFault() || uceFault()) { + assertEq(x, false); + return 0; + } + return 1; +} + +f(); +f(); +f(); diff --git a/js/src/jit-test/tests/ion/bug1046597.js b/js/src/jit-test/tests/ion/bug1046597.js new file mode 100644 index 0000000000..cfd645143e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1046597.js @@ -0,0 +1,6 @@ +a = {} +b = __proto__ +for (i = 0; i < 10; i++) { + __proto__ &= a + a.__proto__ = b +} diff --git a/js/src/jit-test/tests/ion/bug1053074.js b/js/src/jit-test/tests/ion/bug1053074.js new file mode 100644 index 0000000000..8a9cf78b41 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1053074.js @@ -0,0 +1,12 @@ +function f(y) { + return 2147483648 < y >>> 0 +} +assertEq(f(0), false); +assertEq(f(-8), true); + +function g(y) { + var t = Math.floor(y); + return 2147483648 < t+2; +} +assertEq(g(0), false) +assertEq(g(2147483647), true) diff --git a/js/src/jit-test/tests/ion/bug1054047.js b/js/src/jit-test/tests/ion/bug1054047.js new file mode 100644 index 0000000000..42dedd718c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1054047.js @@ -0,0 +1,12 @@ + +function f() {} +function g() { + f.apply(this, arguments); +} + +var arr = []; +for (var j = 0; j < 128 /* 127 */; j++) + arr.push(0); + +for (var j = 0; j < 10000; j++) + g.apply(null, arr); diff --git a/js/src/jit-test/tests/ion/bug1054241.js b/js/src/jit-test/tests/ion/bug1054241.js new file mode 100644 index 0000000000..7c0cf0a26e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1054241.js @@ -0,0 +1,12 @@ +setJitCompilerOption("baseline.warmup.trigger", 10); +setJitCompilerOption("ion.warmup.trigger", 20); + +enableShellAllocationMetadataBuilder(); +(function(){ + for(var i = 0; i < 100; i++) { + try{ + var a = new Array(5); + throw 1; + } catch(e) {} + } +})(); diff --git a/js/src/jit-test/tests/ion/bug1054512.js b/js/src/jit-test/tests/ion/bug1054512.js new file mode 100644 index 0000000000..4da554dc64 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1054512.js @@ -0,0 +1,11 @@ +function f(x) { + x((x | 0) + x); +}; +try { + f(1); +} catch (e) {} +for (var k = 0; k < 1; ++k) { + try { + f(Symbol()); + } catch (e) {} +} diff --git a/js/src/jit-test/tests/ion/bug1054601.js b/js/src/jit-test/tests/ion/bug1054601.js new file mode 100644 index 0000000000..3332501739 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1054601.js @@ -0,0 +1,8 @@ + +(function() { + for (let x = 0; x < 1; ++x) { + if (x % 6 == 4) {} else { + return; + } + } +})() diff --git a/js/src/jit-test/tests/ion/bug1054753.js b/js/src/jit-test/tests/ion/bug1054753.js new file mode 100644 index 0000000000..a05f2be502 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1054753.js @@ -0,0 +1,13 @@ +// |jit-test| error: TypeError +g = (function() { + var Int32ArrayView = new Int32Array(); + function f() { + Int32ArrayView[Symbol() >> 2] + } + return f; +})(); +try { + g(); +} catch (e) {} +g(); + diff --git a/js/src/jit-test/tests/ion/bug1055762.js b/js/src/jit-test/tests/ion/bug1055762.js new file mode 100644 index 0000000000..54f09bf168 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1055762.js @@ -0,0 +1,13 @@ +// |jit-test| error: TypeError +function g() { + f(0); +} +function f(y) { + return (undefined <= y); +} +try { + g(); +} catch (e) {} +(function() { + f()() +})(); diff --git a/js/src/jit-test/tests/ion/bug1055864.js b/js/src/jit-test/tests/ion/bug1055864.js new file mode 100644 index 0000000000..0cf993cb43 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1055864.js @@ -0,0 +1,8 @@ +function f() {} +(function() { + f() +})() +function g() { + new f >> 0 +} +g() diff --git a/js/src/jit-test/tests/ion/bug1057580.js b/js/src/jit-test/tests/ion/bug1057580.js new file mode 100644 index 0000000000..7fe21b2ffc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1057580.js @@ -0,0 +1,15 @@ +// |jit-test| error: TypeError + +function testApplyCallHelper(f) { + for (var i = 0; i < 10; ++i) + f.call(this); +} +function testApplyCall() { + var r = testApplyCallHelper( + function (a0,a1,a2,a3,a4,a5,a6,a7) { + x = [a0,a1,a2,a3,a4,a5,a6,a7]; + } + ); + r += testApplyCallHelper(x); +} +testApplyCall(); diff --git a/js/src/jit-test/tests/ion/bug1057582.js b/js/src/jit-test/tests/ion/bug1057582.js new file mode 100644 index 0000000000..05ca5160a2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1057582.js @@ -0,0 +1,10 @@ +Object.defineProperty(Object.prototype, "0", {configurable: true}); +delete Object.prototype[0]; + +function makeArray() { + var arr = []; + for (var i = 0; i < 10; i++) + arr.push(true); + return arr; +} +makeArray(); diff --git a/js/src/jit-test/tests/ion/bug1057598.js b/js/src/jit-test/tests/ion/bug1057598.js new file mode 100644 index 0000000000..63c1bf01b2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1057598.js @@ -0,0 +1,18 @@ +// enableShellAllocationMetadataBuilder ignores its argument, because we don't +// permit metadata callbacks to run JS any more, so this test may be +// unnecessary. We'll preserve its structure just in case. +enableShellAllocationMetadataBuilder(function( r, ... d) {}); +setJitCompilerOption("ion.warmup.trigger", 20); +var uceFault = function (i) { + if (i > 98) + uceFault = function (i) { return true; }; +} +var uceFault_str_split = eval(`(${uceFault})`.replace('uceFault', 'uceFault_str_split')) +function rstr_split(i) { + var x = "str01234567899876543210rts".split("" + i); + if (uceFault_str_split(i) || uceFault_str_split(i)) { + } +} +for (i = 0; i < 100; i++) { + rstr_split(i); +} diff --git a/js/src/jit-test/tests/ion/bug1060387.js b/js/src/jit-test/tests/ion/bug1060387.js new file mode 100644 index 0000000000..27d43a8c50 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1060387.js @@ -0,0 +1,12 @@ +function foo() { + var obj = new Object(); + var index = [-0, 2147483648, 1073741825]; + for (var j in index) { + testProperty(index[j]); + } + function testProperty(i) { + obj[i] = '' + i; + } + assertEq(JSON.stringify(obj), '{"0":"0","1073741825":"1073741825","2147483648":"2147483648"}'); +} +foo(); diff --git a/js/src/jit-test/tests/ion/bug1060398.js b/js/src/jit-test/tests/ion/bug1060398.js new file mode 100644 index 0000000000..dc47a92e2f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1060398.js @@ -0,0 +1,16 @@ +function test() { + var c = 0; + for (var i=0; i<20; i++) { + var arr = [1]; + if (i > 5) + Object.defineProperty(arr, "length", { writable: false, value: 4 }); + try { + arr.push(2); + } catch(e) { + assertEq(e.toString().includes("length"), true); + c++; + } + } + assertEq(c, 14); +} +test(); diff --git a/js/src/jit-test/tests/ion/bug1062612.js b/js/src/jit-test/tests/ion/bug1062612.js new file mode 100644 index 0000000000..3df1d1ed68 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1062612.js @@ -0,0 +1,7 @@ +x = [0, 1, 1, 0, 1, 1]; +y = -1; +sum = 0; +for (var j = 0; j < x.length; ++j) { + sum = sum + (x[j] ? 0 : (y >>> 0)) | 0; +} +assertEq(sum, -2); diff --git a/js/src/jit-test/tests/ion/bug1063488.js b/js/src/jit-test/tests/ion/bug1063488.js new file mode 100644 index 0000000000..b6ad1a7106 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1063488.js @@ -0,0 +1,16 @@ + +function foo(a, b) { + var x = b[0]; + for (var i = 0; i < 5; i++) { + a[i + 1] = 0; + x += b[i]; + } + assertEq(x, 2); +} +function bar() { + for (var i = 0; i < 5; i++) { + var arr = [1,2,3,4,5,6]; + foo(arr, arr); + } +} +bar(); diff --git a/js/src/jit-test/tests/ion/bug1063653.js b/js/src/jit-test/tests/ion/bug1063653.js new file mode 100644 index 0000000000..9a0e162ef1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1063653.js @@ -0,0 +1,10 @@ + +function g(x) { + return (0 > (Math.max(x, x) || x)) +} +function f() { + return g(g() >> 0) +} +for (var k = 0; k < 1; ++k) { + f(); +} diff --git a/js/src/jit-test/tests/ion/bug1064537.js b/js/src/jit-test/tests/ion/bug1064537.js new file mode 100644 index 0000000000..60ddd8ceb2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1064537.js @@ -0,0 +1,17 @@ + +function test(a) { + return (a)?a:0; +} +function test2(a) { + return (a)?0:a; +} + +function isNegativeZero(x) { + return x===0 && (1/x)===-Infinity; +} + +test(0) +assertEq(isNegativeZero(test(-0)), false) +assertEq(isNegativeZero(test(-0)), false) +assertEq(isNegativeZero(test2(-0)), true) +assertEq(isNegativeZero(test2(-0)), true) diff --git a/js/src/jit-test/tests/ion/bug1066659.js b/js/src/jit-test/tests/ion/bug1066659.js new file mode 100644 index 0000000000..05aa1d4a9b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1066659.js @@ -0,0 +1,13 @@ + +function reportCompare (expected, actual) { + var actual_t = typeof actual; + var output = ""; + output += "x" + actual_t + " "; + expected != actual; + output += undefined; +} +gczeal(7,1); +for (var i=0; i<900; i++) { + reportCompare("abc", function() {}); + reportCompare(null, 10); +} diff --git a/js/src/jit-test/tests/ion/bug1070462.js b/js/src/jit-test/tests/ion/bug1070462.js new file mode 100644 index 0000000000..cbbc56c491 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1070462.js @@ -0,0 +1,4 @@ +// |jit-test| error: ReferenceError +with({}) { + let x = x += undefined +} diff --git a/js/src/jit-test/tests/ion/bug1070465.js b/js/src/jit-test/tests/ion/bug1070465.js new file mode 100644 index 0000000000..68946a3383 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1070465.js @@ -0,0 +1,5 @@ +// |jit-test| error: ReferenceError +{ + while (x && 0) {} + let x +} diff --git a/js/src/jit-test/tests/ion/bug1071879.js b/js/src/jit-test/tests/ion/bug1071879.js new file mode 100644 index 0000000000..0c90549c7c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1071879.js @@ -0,0 +1,39 @@ +// Test 1. +function g(f, inputs) { + for (var j = 0; j < 2; j++) { + try { + f(inputs[j]) + } catch (e) {} + } +} +function f(x) { + returnx > 0 ? x && Number.MIN_VALUE >> 0 : x; +}; +g(f, [-Number.E]) + +// Test 2. +function h(x) { + (x && 4294967296 >> 0)() +} +try { + h(Number.MAX_VALUE) + h() +} catch (e) {} + +// Test 3. +var arr = new Float64Array([1, 2, 3, 4, 5, 6, 7, 8, 9, -0]); +for (var i = 0; i < 10; i++) +{ + var el = +arr[i]; + print(String(el ? +0 : el)); +} + +// Test 4. +setIonCheckGraphCoherency() +function j(x) { + x(Math.hypot(x && 0, 4294967296)) +} +try { + j(Infinity) + j() +} catch (e) {} diff --git a/js/src/jit-test/tests/ion/bug1072188.js b/js/src/jit-test/tests/ion/bug1072188.js new file mode 100644 index 0000000000..dc13baf6a3 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1072188.js @@ -0,0 +1,24 @@ + +setJitCompilerOption("baseline.warmup.trigger", 10); +setJitCompilerOption("ion.warmup.trigger", 30); +var i; + +var uceFault = function (i) { + if (i > 98) + uceFault = function (i) { return true; }; + return false; +} + +var sqrt5 = Math.sqrt(5); +var phi = (1 + sqrt5) / 2; +function range_analysis_truncate(i) { + var fib = (Math.pow(phi, i) - Math.pow(1 - phi, i)) / sqrt5; + var x = (fib >> 8) * (fib >> 6); + if (uceFault(i) || uceFault(i)) + assertEq(x, (fib >> 8) * (fib >> 6)); + return x | 0; +} + +for (i = 0; i < 100; i++) { + range_analysis_truncate(i); +} diff --git a/js/src/jit-test/tests/ion/bug1072691.js b/js/src/jit-test/tests/ion/bug1072691.js new file mode 100644 index 0000000000..84204bc9f0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1072691.js @@ -0,0 +1,58 @@ +// Testcase 1. +try { + function g(x) { + (x | 0 && 0)() + } + (function(f, s) { + f() + })(g, []) +} catch (e) {} + +// Testcase 2. +function g2(f, inputs) { + for (var j = 0; j < 49; ++j) { + for (var k = 0; k < 49; ++k) { + try { + f() + } catch (e) {} + } + } +} +function f1(x, y) { + (x | 0 ? Number.MAX_VALUE | 0 : x | 0)(); +}; +function f2(y) { + f1(y | 0)(); +}; +g2(f2, [Number]) + +// Testcase 3. +function h(f) { + for (var j = 0; j < 99; ++j) { + for (var k = 0; k < 99; ++k) { + try { + f() + } catch (e) {} + } + } +} +function g3(x) { + (x | 0 ? Number.MAX_VALUE | 0 : x | 0) +} +h(g3, [Number]) + +// Testcase 4. +function m(f) { + f() +} +function g4(x) { + return x ? Math.fround(-Number.MIN_VALUE) : x +} +m(g4) +function h2(M) { + try { + (g4(-0 + M))() + } catch (e) {} +} +m(h2, [Math - Number]) + diff --git a/js/src/jit-test/tests/ion/bug1072911.js b/js/src/jit-test/tests/ion/bug1072911.js new file mode 100644 index 0000000000..44df7268f3 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1072911.js @@ -0,0 +1,14 @@ + +function X () {}; +function Y () {}; +function testCallProtoMethod() { + var a = [new X, new X, __proto__, new Y, new Y]; +} +testCallProtoMethod(); + +function testNot() { + var r; + for (var i = 0; i < 10; ++i) + r = []; +} +testNot(); diff --git a/js/src/jit-test/tests/ion/bug1073702.js b/js/src/jit-test/tests/ion/bug1073702.js new file mode 100644 index 0000000000..bd7d6df8a8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1073702.js @@ -0,0 +1,10 @@ +try { + let x = ((function f(y) { + if (y > 0) { + f(-1) + } + x + })(1)) +} catch (e) { + assertEq(e instanceof ReferenceError, true); +} diff --git a/js/src/jit-test/tests/ion/bug1073861.js b/js/src/jit-test/tests/ion/bug1073861.js new file mode 100644 index 0000000000..fe837c45c7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1073861.js @@ -0,0 +1,69 @@ +function a(a, b, c, g) { + for (;;) { + if (0 > c) return a; + a: { + for (;;) { + var k = a.forward[c]; + if (t(k)) + if (k.key < b) a = k; + else break a; + else break a + } + a = void 0 + } + null != + g && (g[c] = a); + c -= 1 + } +} + +function t(a) { + return null != a && !1 !== a +} + + +var d = {forward: [{},null,{}]} +for (var i=0; i < 1000; i++) { + a(d, 0, 1, null); + a(d, 0, 0, null); +} + + + + +function test(a) { + var t = a[0] + if (t) { + return t.test; + } +} + +function test2(a) { + var t = a[0] + if (t) { + if (t) { + return t.test; + } + } +} + +function test3(a) { + var t = a[0] + if (t !== null) { + if (t !== undefined) { + return t.test; + } + } +} + +var a = [{test:1}] +var b = [undefined] +assertEq(test(b), undefined) +assertEq(test(a), 1) +assertEq(test(a), 1) +assertEq(test2(b), undefined) +assertEq(test2(a), 1) +assertEq(test2(a), 1) +assertEq(test3(b), undefined) +assertEq(test3(a), 1) +assertEq(test3(a), 1) diff --git a/js/src/jit-test/tests/ion/bug1073928.js b/js/src/jit-test/tests/ion/bug1073928.js new file mode 100644 index 0000000000..990103d1fd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1073928.js @@ -0,0 +1,30 @@ +function f(y) { + var a = Math.fround(-0); + var b = ~Math.hypot(y > 0, 5); + assertEq(a, -0); + assertEq(b, -6); +} +f(-0); +f(1); + +function g(y, z) { + if (z == 0) { + var a = Math.fround(z); + var b = ~Math.hypot(y > 0, 5); + assertEq(a, -0); + assertEq(b, -6); + } +} +g(-0, -0); +g(1, -0); + +function h(y, z) { + if (z == -0) { + var a = Math.fround(z); + var b = ~Math.hypot(y > 0, 5); + assertEq(a, -0); + assertEq(b, -6); + } +} +h(-0, -0); +h(1, -0); diff --git a/js/src/jit-test/tests/ion/bug1074833.js b/js/src/jit-test/tests/ion/bug1074833.js new file mode 100644 index 0000000000..992d6cff8f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1074833.js @@ -0,0 +1,44 @@ + +var i = 0; +function cond() { + return i++ < 20; +} + +function inline() { + ({ b: 1 }) +} + +function f() { + do { + ({ b: 1 }) + } while (cond()) +} + +i = 0; +f(); + +function g() { + do { + if (cond()) { } + ({ b: 1 }) + } while (cond()) +} + +i = 0; +g(); + + +function h() { + do { + inline(); + } while (cond()) +} + +i = 0; +h(); + + +i = 0; +for (i = 0; cond(); i++) + ({ set: Math.w }); + diff --git a/js/src/jit-test/tests/ion/bug1076026.js b/js/src/jit-test/tests/ion/bug1076026.js new file mode 100644 index 0000000000..1bfacef0e0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1076026.js @@ -0,0 +1,9 @@ +(function f() { + let x = (new function() {}) + this.__defineGetter__("x", function() { + ({ + e: x + }) + }) +})(); +print(x) diff --git a/js/src/jit-test/tests/ion/bug1076091.js b/js/src/jit-test/tests/ion/bug1076091.js new file mode 100644 index 0000000000..a00f003c53 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1076091.js @@ -0,0 +1,11 @@ + +Object.defineProperty(this, "x", { + get: function() { + return this.y + } +}) +x +x +y = Int16Array +var y +assertEq(x, Int16Array) diff --git a/js/src/jit-test/tests/ion/bug1076283.js b/js/src/jit-test/tests/ion/bug1076283.js new file mode 100644 index 0000000000..939d6ab663 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1076283.js @@ -0,0 +1,10 @@ +function f() { + assertEq(typeof this, "object"); +} +this.f(); +function gg() { + for (var j = 0; j < 3; ++j) { + f(); + } +}; +gg(); diff --git a/js/src/jit-test/tests/ion/bug1077349.js b/js/src/jit-test/tests/ion/bug1077349.js new file mode 100644 index 0000000000..886e5088a6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1077349.js @@ -0,0 +1,20 @@ + +function boo() { + return foo.arguments[0]; +} + +function foo(a,b,c) { + if (a == 0) { + a ^= 4; + return boo(); + } + + return undefined; +} + +function inlined() { + return foo.apply({}, arguments); +} + +assertEq(inlined(1,2,3), undefined); +assertEq(inlined(0,1,2), 4); diff --git a/js/src/jit-test/tests/ion/bug1077427.js b/js/src/jit-test/tests/ion/bug1077427.js new file mode 100644 index 0000000000..27b0306f85 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1077427.js @@ -0,0 +1,12 @@ + +(function f() { + var i; + var x = 3; + var o1 = { a: x }; + var o2 = { a: 2 }; + for (i = 0; i < 5; i++) + o2.a = x; + Object.preventExtensions({ a: 1 }); + for (i = 0; i < 5; i++) + ; +})(); diff --git a/js/src/jit-test/tests/ion/bug1079062.js b/js/src/jit-test/tests/ion/bug1079062.js new file mode 100644 index 0000000000..f03f1e0524 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1079062.js @@ -0,0 +1,6 @@ +function f(y) { + return ((y ? y : 0) ? 0 : y) +} +m = [0xf] +f(m[0]) +assertEq(f(m[0]), 0) diff --git a/js/src/jit-test/tests/ion/bug1079850.js b/js/src/jit-test/tests/ion/bug1079850.js new file mode 100644 index 0000000000..20309d70d8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1079850.js @@ -0,0 +1,5 @@ +function foo() { + for(__key in null) + var key=startTest(VERSION) ? this : this; + if (key !== undefined) {} +} foo(); diff --git a/js/src/jit-test/tests/ion/bug1080991.js b/js/src/jit-test/tests/ion/bug1080991.js new file mode 100644 index 0000000000..5c9c3783aa --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1080991.js @@ -0,0 +1,5 @@ +(function(){ + for (var i = 0; i < 8; i++) { + var c = i + } +})() diff --git a/js/src/jit-test/tests/ion/bug1085298.js b/js/src/jit-test/tests/ion/bug1085298.js new file mode 100644 index 0000000000..2cac7298f9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1085298.js @@ -0,0 +1,7 @@ +function f(x, y) { + return (y | 0 && x ? y | 0 : 0) +} +m = [1] +assertEq(f(m[0], m[0]), 1) +assertEq(f(m[1], m[0]), 0) +assertEq(f(m[2], m[0]), 0) diff --git a/js/src/jit-test/tests/ion/bug1089761.js b/js/src/jit-test/tests/ion/bug1089761.js new file mode 100644 index 0000000000..b2940b6714 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1089761.js @@ -0,0 +1,14 @@ +var hits = 0; +for (var j = 0; j < 9; ++j) { + try { + (function() { + (function() { + eval("x") + let x + })() + })() + } catch (e) { + hits++; + } +} +assertEq(hits, 9); diff --git a/js/src/jit-test/tests/ion/bug1090037.js b/js/src/jit-test/tests/ion/bug1090037.js new file mode 100644 index 0000000000..a49e1266ee --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1090037.js @@ -0,0 +1,7 @@ +function f(x) { + Math.sin([] | 0 && x) +} +for (var j = 0; j < 1; j++) { + f(1 && 0) +} + diff --git a/js/src/jit-test/tests/ion/bug1090424.js b/js/src/jit-test/tests/ion/bug1090424.js new file mode 100644 index 0000000000..4fd53fe5de --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1090424.js @@ -0,0 +1,55 @@ + +let w +(function() { + testgt1 = function(x) { + return (-0x80000000 >= (x | 0)) +} + testgt2 = function(x) { + return (+0x7fffffff >= (x | 0)) +} + testgt3 = function(x) { + return ((x | 0) >= -0x80000000) +} + testgt4 = function(x) { + return ((x | 0) >= +0x7fffffff) +} + + testlt1 = function(x) { + return (-0x80000000 <= (x | 0)) +} + testlt2 = function(x) { + return (+0x7fffffff <= (x | 0)) +} + testlt3 = function(x) { + return ((x | 0) <= -0x80000000) +} + testlt4 = function(x) { + return ((x | 0) <= +0x7fffffff) +} + +})() +assertEq(testgt1(-0x80000000), true); +assertEq(testgt1(-0x80000000), true); +assertEq(testgt1(0), false); +assertEq(testgt2(0x7fffffff), true); +assertEq(testgt2(0x7fffffff), true); +assertEq(testgt2(0), true); +assertEq(testgt3(-0x80000000), true); +assertEq(testgt3(-0x80000000), true); +assertEq(testgt3(0), true); +assertEq(testgt4(0x7fffffff), true); +assertEq(testgt4(0x7fffffff), true); +assertEq(testgt4(0), false); + +assertEq(testlt1(-0x80000000), true); +assertEq(testlt1(-0x80000000), true); +assertEq(testlt1(0), true); +assertEq(testlt2(0x7fffffff), true); +assertEq(testlt2(0x7fffffff), true); +assertEq(testlt2(0), false); +assertEq(testlt3(-0x80000000), true); +assertEq(testlt3(-0x80000000), true); +assertEq(testlt3(0), false); +assertEq(testlt4(0x7fffffff), true); +assertEq(testlt4(0x7fffffff), true); +assertEq(testlt4(0), true); diff --git a/js/src/jit-test/tests/ion/bug1092833.js b/js/src/jit-test/tests/ion/bug1092833.js new file mode 100644 index 0000000000..64a74fb28f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1092833.js @@ -0,0 +1,49 @@ +// Test that lexicals work with functions with many bindings. + +(function() { + var a01 + var b02 + var c03 + var d04 + var e05 + var f06 + var g07 + var h08 + let i09 + var j10 + var k11 + var l12 + var m13 + var n14 + var o15 + (function n14() { + assertEq(i09, undefined); + })() +})(); + +try { + (function() { + var a01 + var b02 + var c03 + var d04 + var e05 + var f06 + var g07 + var h08 + let i09 + var j10 + var k11 + var l12 + var m13 + var n14 + var o15 + (function n14() { + i12++ + })() + let i12 + })() +} catch (e) { + assertEq(e instanceof ReferenceError, true); + assertEq(e.message.indexOf("i12") > 0, true); +} diff --git a/js/src/jit-test/tests/ion/bug1101576.js b/js/src/jit-test/tests/ion/bug1101576.js new file mode 100644 index 0000000000..354d9c274d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1101576.js @@ -0,0 +1,14 @@ +// Random chosen test: js/src/jit-test/tests/ion/bug928423.js +o = { + a: 1, + b: 1 +} +print(1); +for (var x = 0; x < 2; x++) { + print(2); + o["a1".substr(0, 1)] + o["b1".substr(0, 1)] +} +print(3); +// jsfunfuzz +"a" + "b" diff --git a/js/src/jit-test/tests/ion/bug1101821.js b/js/src/jit-test/tests/ion/bug1101821.js new file mode 100644 index 0000000000..e65e47b8cd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1101821.js @@ -0,0 +1,89 @@ + +// Makes it easier for fuzzers to get max or min statements with multiple arguments. +function test(a, b, c, d, e, f) { + var r = 0 + r += Math.max(a); + r += Math.max(a,b); + r += Math.max(a,b,c); + r += Math.max(a,b,c,d); + r += Math.max(a,b,c,d,e); + r += Math.max(a,b,c,d,e,f); + r += Math.min(a); + r += Math.min(a,b); + r += Math.min(a,b,c); + r += Math.min(a,b,c,d); + r += Math.min(a,b,c,d,e); + r += Math.min(a,b,c,d,e,f); + return r; +} +for (var i=0; i<10; i++) { + assertEq(test(12,5,32,6,18,2), 186); + assertEq(test(1,5,3,6,18,-10), 48); + assertEq(test(-19,5,20,6,18,1), -48); +} + +// Test max/min result up to 5 arguments. +for (var i=1; i<5; i++) { + var args = []; + for (var j=0; j<i; j++) + args[args.length] = "arg" + j; + var max = new Function(args, "return Math.max("+args.join(",")+");"); + var min = new Function(args, "return Math.min("+args.join(",")+");"); + + var input = []; + for (var j=0; j<i; j++) { + input[input.length] = j; + } + + permutate(input, function (a) { + var min_value = min.apply(undefined, a); + var max_value = max.apply(undefined, a); + assertEq(min_value, minimum(a)); + assertEq(max_value, maximum(a)); + }); +} + +function minimum(arr) { + var min = arr[0] + for (var i=1; i<arr.length; i++) { + if (min > arr[i]) + min = arr[i] + } + return min +} +function maximum(arr) { + var max = arr[0] + for (var i=1; i<arr.length; i++) { + if (max < arr[i]) + max = arr[i] + } + return max +} + +function permutate(array, callback) { + function p(array, index, callback) { + function swap(a, i1, i2) { + var t = a[i1]; + a[i1] = a[i2]; + a[i2] = t; + } + + if (index == array.length - 1) { + callback(array); + return 1; + } else { + var count = p(array, index + 1, callback); + for (var i = index + 1; i < array.length; i++) { + swap(array, i, index); + count += p(array, index + 1, callback); + swap(array, i, index); + } + return count; + } + } + + if (!array || array.length == 0) { + return 0; + } + return p(array, 0, callback); +} diff --git a/js/src/jit-test/tests/ion/bug1102187.js b/js/src/jit-test/tests/ion/bug1102187.js new file mode 100644 index 0000000000..2345567a6c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1102187.js @@ -0,0 +1,49 @@ + +function minmax() { + // The test cases for minmax with two operands. + // Test integer type. + var pair_min = Math.min(1, 2); + assertEq(pair_min, 1); + var pair_max = Math.max(1, 2); + assertEq(pair_max, 2); + + // Test double type. + pair_min = Math.min(1.2, 2.3); + assertEq(pair_min, 1.2); + pair_max = Math.max(1.2, 2.3); + assertEq(pair_max, 2.3); + + // Test float type. + var expt_min = Math.fround(1.2); + var expt_max = Math.fround(2.3); + pair_min = Math.min(Math.fround(1.2), Math.fround(2.3)); + assertEq(pair_min, expt_min); + pair_max = Math.max(Math.fround(1.2), Math.fround(2.3)); + assertEq(pair_max, expt_max); + + // The test cases for minmax with more than two operands. + // Test integer type. + pair_min = Math.min(1, 3, 2, 5, 4); + assertEq(pair_min, 1); + pair_max = Math.max(1, 3, 2, 5, 4); + assertEq(pair_max, 5); + + // Test double type. + pair_min = Math.min(1.1, 3.3, 2.2, 5.5, 4.4); + assertEq(pair_min, 1.1); + pair_max = Math.max(1.1, 3.3, 2.2, 5.5, 4.4); + assertEq(pair_max, 5.5); + + // Test float type. + expt_min = Math.fround(1.1); + expt_max = Math.fround(5.5); + pair_min = Math.min(Math.fround(1.1), Math.fround(3.3), Math.fround(2.2), + Math.fround(5.5), Math.fround(4.4)); + assertEq(pair_min, expt_min); + pair_max = Math.max(Math.fround(1.1), Math.fround(3.3), Math.fround(2.2), + Math.fround(5.5), Math.fround(4.4)); + assertEq(pair_max, expt_max); +} + +minmax(); +minmax(); diff --git a/js/src/jit-test/tests/ion/bug1105187-sink.js b/js/src/jit-test/tests/ion/bug1105187-sink.js new file mode 100644 index 0000000000..835f91848c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1105187-sink.js @@ -0,0 +1,9 @@ +// |jit-test| --ion-gvn=off; error:ReferenceError + +(function(x) { + x = +x + switch (y) { + case -1: + x = 0 + } +})() diff --git a/js/src/jit-test/tests/ion/bug1105574-ra-sink.js b/js/src/jit-test/tests/ion/bug1105574-ra-sink.js new file mode 100644 index 0000000000..d67966081b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1105574-ra-sink.js @@ -0,0 +1,11 @@ + +function f1(x) { + assertEq(Math.tan((((x >>> 0) | 0) >>> 0) | 0, f2()) < -1, !!x); +} +var f2 = function() { }; + +f1(0); +f2 = function() { }; +f1(0); +f1(0); +f1(-1); diff --git a/js/src/jit-test/tests/ion/bug1105684.js b/js/src/jit-test/tests/ion/bug1105684.js new file mode 100644 index 0000000000..fd2670cc8b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1105684.js @@ -0,0 +1,6 @@ +function f(x) { + Math.exp(x ? 0 : 1) +} +f(createIsHTMLDDA()) +f(createIsHTMLDDA()) + diff --git a/js/src/jit-test/tests/ion/bug1106171-sink.js b/js/src/jit-test/tests/ion/bug1106171-sink.js new file mode 100644 index 0000000000..26fb1e27d2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1106171-sink.js @@ -0,0 +1,19 @@ +// |jit-test| --ion-sink=on +// Sink Algorithm should not move instruction into merge blocks +// which have no corresponding pc. + +setJitCompilerOption("ion.warmup.trigger", 30); + +var o = { + a : 40, + b : true +}; + +function f(a, b) { + do { + if (a == 0) + return; + a--; + } while (true || this ? o.a-- : true); +} +f(200000, 0); diff --git a/js/src/jit-test/tests/ion/bug1107011-1.js b/js/src/jit-test/tests/ion/bug1107011-1.js new file mode 100644 index 0000000000..458d7dd12a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1107011-1.js @@ -0,0 +1,17 @@ +var f32 = new Float32Array(32); +function f(n) { + var x; + if (n > 10000) { + x = 4.5; + } else { + x = f32[0]; + } + f32[0] = (function() { + for(var f=0;f<4;++f) { + x=1; + } + })() < x; +} +for (var n = 0; n < 100; n++) + f(n); + diff --git a/js/src/jit-test/tests/ion/bug1107011-2.js b/js/src/jit-test/tests/ion/bug1107011-2.js new file mode 100644 index 0000000000..d59685ea05 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1107011-2.js @@ -0,0 +1,12 @@ +function foo() { + var x = 0, y = 0, a = new Float32Array(1); + function bar() { + x = y; + y = a[0]; + } + for (var i = 0; i < 1000; i++) { + bar(); + } +} +for (var i=0; i < 50; i++) + foo(); diff --git a/js/src/jit-test/tests/ion/bug1113139.js b/js/src/jit-test/tests/ion/bug1113139.js new file mode 100644 index 0000000000..31ae9e384b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1113139.js @@ -0,0 +1,9 @@ +var lfcode = new Array(); +lfcode.push = function(x) { eval("(function() { " + x + " })();"); }; +lfcode.push("\ +function error(str) { try { eval(str); } catch (e) { return e; } }\ +const YIELD_PAREN = error('(function*(){(for (y of (yield 1, 2)) y)})').message;\ +const GENEXP_YIELD = error('(function*(){(for (x of yield 1) x)})').message;\ +const GENERIC = error('(for)').message;\ +const eval = [];\ +"); diff --git a/js/src/jit-test/tests/ion/bug1115665.js b/js/src/jit-test/tests/ion/bug1115665.js new file mode 100644 index 0000000000..0ec96fc620 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1115665.js @@ -0,0 +1,8 @@ +Object.prototype[3] = 3 +x = Array() + function f() { + for (i = 0; i < 9; i++) { + if (Object[x++] != 0) {} + } + } +f() diff --git a/js/src/jit-test/tests/ion/bug1117099.js b/js/src/jit-test/tests/ion/bug1117099.js new file mode 100644 index 0000000000..fdb014a81b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1117099.js @@ -0,0 +1,10 @@ +// |jit-test| error: ReferenceError +function reportCompare (expected, actual, description) { + if (expected != actual) {} +} +reportCompare(1); +addThis(); +function addThis() { + for (var i=0; i<UBound; i++) + reportCompare( true | this && this ); +} diff --git a/js/src/jit-test/tests/ion/bug1122401.js b/js/src/jit-test/tests/ion/bug1122401.js new file mode 100644 index 0000000000..b547d0c7e3 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1122401.js @@ -0,0 +1,18 @@ +function f(x) { + return Math.round((x >>> 0) / 2) >> 0; +} +f(2); +assertEq(f(1), 1); + +function g(x, y) { + var x1 = 0; + var x2 = Math.tan(y); + var t1 = (x1 >>> 0); + var t2 = (x2 >>> 0); + var a = t1 / t2; + var sub = 1 - a; + var e = sub | 0; + return e; +} +g(8, 4) +assertEq(g(1, 0), 0); diff --git a/js/src/jit-test/tests/ion/bug1122839.js b/js/src/jit-test/tests/ion/bug1122839.js new file mode 100644 index 0000000000..02bd090a51 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1122839.js @@ -0,0 +1,11 @@ +x = ''; +Object.defineProperty(this, "y", { + get: function() { + return x + } +}) +y +x = 0 +x = new String; +y.__proto__ = [] +y diff --git a/js/src/jit-test/tests/ion/bug1123011.js b/js/src/jit-test/tests/ion/bug1123011.js new file mode 100644 index 0000000000..a1ced3f5ec --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1123011.js @@ -0,0 +1,8 @@ + +var global = this; +function f() { + return eval("'use strict'; this;"); +} +for (var j = 0; j < 5; ++j) { + assertEq(f(), global); +} diff --git a/js/src/jit-test/tests/ion/bug1123064.js b/js/src/jit-test/tests/ion/bug1123064.js new file mode 100644 index 0000000000..517bb8d46a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1123064.js @@ -0,0 +1,30 @@ + + +function toint32() { + + // The test case to trigger MToNumberInt32 operation. + var ToInteger = getSelfHostedValue("ToInteger"); + + // Case1: The input operand is constant int32. + var result = ToInteger(1); + assertEq(result, 1); + + // Case2: The input operand is constant double. + result = ToInteger(0.12); + assertEq(result, 0); + + // Case3: The input operand is constant float. + result = ToInteger(Math.fround(0.13)); + assertEq(result, 0); + + // Case4: The input operand is constant boolean. + result = ToInteger(true); + assertEq(result, 1); + + // Case5: The input operand is null. + result = ToInteger(null); + assertEq(result, 0); +} + +toint32(); +toint32(); diff --git a/js/src/jit-test/tests/ion/bug1128490.js b/js/src/jit-test/tests/ion/bug1128490.js new file mode 100644 index 0000000000..09963b9b26 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1128490.js @@ -0,0 +1,10 @@ + +for (var i = 0; i < 1000; ++i) { + function isNotEmpty(obj) { + for (var i = 0 ; i < arguments.length; i++) { + minorgc(); + var o = arguments[i]; + } + }; + isNotEmpty([1]); +} diff --git a/js/src/jit-test/tests/ion/bug1129977.js b/js/src/jit-test/tests/ion/bug1129977.js new file mode 100644 index 0000000000..b82fe7961f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1129977.js @@ -0,0 +1,10 @@ +gczeal(11); +function C(a, b) { + this.b=b; +} +evaluate('\ +Object.defineProperty(Object.prototype, "b", {set: function() {}});\ +var f = C.bind(0x2004, 2);\ +'); +for (var i=1; i<5000; ++i) + new f; diff --git a/js/src/jit-test/tests/ion/bug1130679.js b/js/src/jit-test/tests/ion/bug1130679.js new file mode 100644 index 0000000000..adb22aa804 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1130679.js @@ -0,0 +1,29 @@ + +function f(x) { + return x >>> 0 !== Math.imul(1, x >>> 0); +} +f(0) +assertEq(f(-1),true) + +function g(x) { + return 2147483647+x !== Math.imul(1, 2147483647+x); +} +g(0) +assertEq(g(1),true) + +function h(x) { + if (2147483647+x !== Math.imul(1, 2147483647+x)) + return true; + return (2147483647+x)|0 +} +h(0) +assertEq(h(1), true) + +function i2(x) { + return x === x +} +function i(x) { + return i2(0 / Math.sign(x > 0)) +} +i(1) +assertEq(i(-1), false) diff --git a/js/src/jit-test/tests/ion/bug1132128.js b/js/src/jit-test/tests/ion/bug1132128.js new file mode 100644 index 0000000000..b0d8dd1fdd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1132128.js @@ -0,0 +1,26 @@ +if (getJitCompilerOptions()["ion.warmup.trigger"] > 20) + setJitCompilerOption("ion.warmup.trigger", 20); +function callRegExpTest(i) { + var s = "" + i; + var re = /(\d+)/; + re.test(s); + assertEq(RegExp.$1, s); +} +function callRegExpExec(i) { + var s = "" + i; + var re = /(\d+)/; + var res = re.exec(s); + assertEq(RegExp.$1, s); + return res; +} +function callRegExpReplace(i) { + var s = "" + i; + var re = /(\d+)/; + s.replace(re, ""); + assertEq(RegExp.$1, s); +} +for (var i = 0; i < 60; i++) { + callRegExpTest(i); + callRegExpExec(i); + callRegExpReplace(i); +} diff --git a/js/src/jit-test/tests/ion/bug1132290.js b/js/src/jit-test/tests/ion/bug1132290.js new file mode 100644 index 0000000000..0799d150b7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1132290.js @@ -0,0 +1,10 @@ + +f = function() { + v = new Uint8Array() + function f(x) { + return x + v[0] | 0 + } + return f +}() +assertEq(f(0), 0) +assertEq(f(1), 0) diff --git a/js/src/jit-test/tests/ion/bug1132584.js b/js/src/jit-test/tests/ion/bug1132584.js new file mode 100644 index 0000000000..84bd3f7a00 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1132584.js @@ -0,0 +1,12 @@ +enableOsiPointRegisterChecks() +function f() {} +f.__defineGetter__("x", (function() { + this._ +})) +for (var i = 0; i < 3; i++) { + (function() { + for (var j = 0; j < 1; j++) { + f.x + 1 + } + })() +} diff --git a/js/src/jit-test/tests/ion/bug1132770.js b/js/src/jit-test/tests/ion/bug1132770.js new file mode 100644 index 0000000000..51f6a44d6f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1132770.js @@ -0,0 +1,4 @@ +// |jit-test| error: too much recursion +Object.defineProperty(this, "x", {set: function() { this.x = 2; }}); +setJitCompilerOption("ion.warmup.trigger", 30); +x ^= 1; diff --git a/js/src/jit-test/tests/ion/bug1133530.js b/js/src/jit-test/tests/ion/bug1133530.js new file mode 100644 index 0000000000..b658f41e7e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1133530.js @@ -0,0 +1,18 @@ +// |jit-test| error: InternalError +x = {}; +y = x; +if (x !== y) {} +Object.defineProperty(this, "x", { + get: function() { + Object.defineProperty(this, "y", { + get: function() { + return Proxy(this.y) + } + }); + } +}) +x; +g = newGlobal({newCompartment: true}); +g.parent = this +g.eval("Debugger(parent).onExceptionUnwind=(function(){})") +y; diff --git a/js/src/jit-test/tests/ion/bug1134074.js b/js/src/jit-test/tests/ion/bug1134074.js new file mode 100644 index 0000000000..524f5405af --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1134074.js @@ -0,0 +1,10 @@ + +setJitCompilerOption("ion.warmup.trigger", 30); +function bar(i) { + if (i >= 40) + return; + if ("aaa,bbb,ccc".split(",")[0].length != 3) + throw "???"; + bar(i + 1); +} +bar(0); diff --git a/js/src/jit-test/tests/ion/bug1135047.js b/js/src/jit-test/tests/ion/bug1135047.js new file mode 100644 index 0000000000..5cb6eb8de8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1135047.js @@ -0,0 +1,5 @@ +function j(x) { + return Math.pow(x, x) !== Math.pow(x, x) +} +j(-0) +assertEq(j(-undefined), true) diff --git a/js/src/jit-test/tests/ion/bug1138740.js b/js/src/jit-test/tests/ion/bug1138740.js new file mode 100644 index 0000000000..195717c976 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1138740.js @@ -0,0 +1,12 @@ + +with({}){} +x = new Int8Array(1) +function f(y) { + x[0] = y +} +f() +f(3) +f(7) +x.buffer; +f(0); +assertEq(x[0], 0); diff --git a/js/src/jit-test/tests/ion/bug1139152.js b/js/src/jit-test/tests/ion/bug1139152.js new file mode 100644 index 0000000000..9f3f9503c9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1139152.js @@ -0,0 +1,25 @@ +function toLiteralSource(value) { + if (value === null) { + return 'null'; + } + if (typeof value === 'string') { + return escapeString(value); + } + if (typeof value === 'number') { + return generateNumber(value); + } + if (typeof value === 'boolean') { + return value ? 'true' : 'false'; + } + value.test(); +} + +function test(x) { + var b = x ? true : {}; + return toLiteralSource(b); +} + +var output = true +for (var i=0; i<1000; i++) { + output = test(output) == 'true'; +} diff --git a/js/src/jit-test/tests/ion/bug1139368.js b/js/src/jit-test/tests/ion/bug1139368.js new file mode 100644 index 0000000000..f47dc73db7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1139368.js @@ -0,0 +1,10 @@ +// |jit-test| error: TypeError +function f() { + for (var i=2; i<2; i++) { + var a = /a/; + } + for (var i=0; i<2; i++) { + a.exec("aaa"); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1139376.js b/js/src/jit-test/tests/ion/bug1139376.js new file mode 100644 index 0000000000..28f0c3819b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1139376.js @@ -0,0 +1,13 @@ +// |jit-test| error:ReferenceError + +(function() { + var $10=0; + while (1) { + switch (stack.label & 2) { + case 1: + return $8|0; + case 49: + if ($10) {} + } + } +})()() diff --git a/js/src/jit-test/tests/ion/bug1140890.js b/js/src/jit-test/tests/ion/bug1140890.js new file mode 100644 index 0000000000..f58452a7bb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1140890.js @@ -0,0 +1,11 @@ +function isNegativeZero(x) { + return x===0 && (1/x)===-Infinity; +} +function f(y) { + return -(0 != 1 / y) - -Math.imul(1, !y) +} +x = [-0, Infinity] +for (var k = 0; k < 2; ++k) { + assertEq(isNegativeZero(f(x[k])), false); +} + diff --git a/js/src/jit-test/tests/ion/bug1143216.js b/js/src/jit-test/tests/ion/bug1143216.js new file mode 100644 index 0000000000..0bc0e9166a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1143216.js @@ -0,0 +1,17 @@ +// Note: This test produces a link error which is required to reproduce the +// original issue. +m = (function(stdlib, n, heap) { + "use asm" + var Float64ArrayView = new stdlib.Float64Array(heap) + var Int16ArrayView = new stdlib.Int16Array(heap) + function f(i0) { + i0 = i0 | 0 + i0 = i0 | 0 + Int16ArrayView[0] = (i0 << 0) + i0 + Float64ArrayView[0] + } + return f +})(this, {}, Array) +for (var j = 0; j < 9; j++) { + m() +} diff --git a/js/src/jit-test/tests/ion/bug1143878.js b/js/src/jit-test/tests/ion/bug1143878.js new file mode 100644 index 0000000000..7860b065ad --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1143878.js @@ -0,0 +1,10 @@ +function f(x, y) { + if (!y) + assertEq(x == x + x, false) +} +m = [true, null] +for (var j = 0; j < 2; ++j) { + for (var k = 0; k < 2; ++k) { + f(m[j], m[k]) + } +} diff --git a/js/src/jit-test/tests/ion/bug1146410.js b/js/src/jit-test/tests/ion/bug1146410.js new file mode 100644 index 0000000000..fd7caafda8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1146410.js @@ -0,0 +1,9 @@ +// |jit-test| error: TypeError +function foo() { + var ws = new WeakSet(); + ws.add({}); + for (var i = 0; i < 10; i++) + ws.add(WeakSet + ""); +} +foo(); +delete Math diff --git a/js/src/jit-test/tests/ion/bug1148883.js b/js/src/jit-test/tests/ion/bug1148883.js new file mode 100644 index 0000000000..3e8e3ae7e1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1148883.js @@ -0,0 +1,26 @@ +function retThis() { + return this; +} + +var res = (function() { + var x = "678901234567890"; + var g = retThis.bind("123456789012345" + x); + function f() { return g(); } + return f; +})()(); + +// res == new String(...) +assertEq("" + res, "123456789012345678901234567890"); + +function retArg0(a) { + return a; +} + +res = (function() { + var x = "678901234567890"; + var g = retArg0.bind(null, "123456789012345" + x); + function f() { return g(); } + return f; +})()(); + +assertEq(res, "123456789012345678901234567890"); diff --git a/js/src/jit-test/tests/ion/bug1148973-1.js b/js/src/jit-test/tests/ion/bug1148973-1.js new file mode 100644 index 0000000000..201b9466f2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1148973-1.js @@ -0,0 +1,16 @@ +Object.defineProperty(this, "x", { get: decodeURI, configurable: true }) +try { + String(b = new Proxy(function() { }, { + get: function(r, z) { + return x[z] + } + })) +} catch (e) {}; +var log = ""; +evaluate(` +try { + function x() {} + assertEq(String(b), "function () {}"); +} catch (e) { log += "e"; } +`); +assertEq(log, "e"); diff --git a/js/src/jit-test/tests/ion/bug1148973-2.js b/js/src/jit-test/tests/ion/bug1148973-2.js new file mode 100644 index 0000000000..97bbe40855 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1148973-2.js @@ -0,0 +1,8 @@ +var proto = {}; +var obj = Object.create(proto); +Object.defineProperty(proto, "x", { get: decodeURI, configurable: true }); +Object.defineProperty(obj, "z", { get: function () { return this.x; } }); +assertEq(obj.z, "undefined"); + +Object.defineProperty(proto, "x", { get: Math.sin, configurable: false }); +assertEq(obj.z, NaN); diff --git a/js/src/jit-test/tests/ion/bug1151323.js b/js/src/jit-test/tests/ion/bug1151323.js new file mode 100644 index 0000000000..f4c3ecf20c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1151323.js @@ -0,0 +1,8 @@ + +function map_test(cases) { + for (var i = 0; i < cases.length; i++) { + var expected = cases[i].expected; + } +} +map_test([{ input: 8, expected: 1114369}, { input: -1, expected: 0}]); +map_test([{ expected: 16777215}, { expected: 4294967241 }]); diff --git a/js/src/jit-test/tests/ion/bug1154971.js b/js/src/jit-test/tests/ion/bug1154971.js new file mode 100644 index 0000000000..ec49a88fcd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1154971.js @@ -0,0 +1,10 @@ + + +function f(x, y) { + return Math.imul(0, Math.imul(y | 0, x >> 0)) +} +for (var i = 0; i < 2; i++) { + try { + (f(1 ? 0 : undefined))() + } catch (e) {} +} diff --git a/js/src/jit-test/tests/ion/bug1155807.js b/js/src/jit-test/tests/ion/bug1155807.js new file mode 100644 index 0000000000..7dd3a6de5d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1155807.js @@ -0,0 +1,15 @@ + +for (var i = 0; i < 2; i++) { + setJitCompilerOption("ion.warmup.trigger", 8) + function f(state) { + this.s = state + } + f.prototype.g = function(v, y) { + this.t + } + x = ['', ''] + j = new f(false) + x.filter(j.g, j) + x.filter(j.g, new f(false)) + j.__proto__ = {} +} diff --git a/js/src/jit-test/tests/ion/bug1158632.js b/js/src/jit-test/tests/ion/bug1158632.js new file mode 100644 index 0000000000..b80dd0351d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1158632.js @@ -0,0 +1,13 @@ +for (var j = 0; j < 1; ++j) { + function f(x) { + x = 4294967295 >>> 4294967295 % x + switch (-1) { + case 1: + // case 0: + case -1: + x = 0; + // default: + } + } + f(); +} diff --git a/js/src/jit-test/tests/ion/bug1159899.js b/js/src/jit-test/tests/ion/bug1159899.js new file mode 100644 index 0000000000..10d930f3b9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1159899.js @@ -0,0 +1,5 @@ +function f(x) { + return ~~(x >>> 0) / (x >>> 0) | 0 +} +f(1) +assertEq(f(-1), 0); diff --git a/js/src/jit-test/tests/ion/bug1160884.js b/js/src/jit-test/tests/ion/bug1160884.js new file mode 100644 index 0000000000..7eb301688a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1160884.js @@ -0,0 +1,12 @@ +function foo(date) { + var F = date.split(" "); + var D = F[0].split("-"); + var C = F[1].split(":"); + return new Date(D[0], D[1], D[2], C[0], C[1], C[2]); +} +function test() { + with(this) {}; + for (var i = 0; i < 1200; i++) + foo("13-5-2015 18:30:" + i); +} +test(); diff --git a/js/src/jit-test/tests/ion/bug1165905.js b/js/src/jit-test/tests/ion/bug1165905.js new file mode 100644 index 0000000000..273e655e7d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1165905.js @@ -0,0 +1,7 @@ +// |jit-test| skip-if: !this.getJitCompilerOptions() || !this.getJitCompilerOptions()['ion.enable'] +load(libdir + "asserts.js"); +var oldOpts = getJitCompilerOptions(); +for (var k in oldOpts) + setJitCompilerOption(k, oldOpts[k]); +var newOpts = getJitCompilerOptions(); +assertDeepEq(oldOpts, newOpts); diff --git a/js/src/jit-test/tests/ion/bug1172498-2.js b/js/src/jit-test/tests/ion/bug1172498-2.js new file mode 100644 index 0000000000..10026fefc7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1172498-2.js @@ -0,0 +1,12 @@ +gczeal(2); +for (var x = 0; x < 99; x++) { + (function() { + return function() { + new function(y) { + return { + e: q => q, function() {} + } + } + } + })()() +} diff --git a/js/src/jit-test/tests/ion/bug1172498.js b/js/src/jit-test/tests/ion/bug1172498.js new file mode 100644 index 0000000000..705cc109b8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1172498.js @@ -0,0 +1,3 @@ +for(var e=1; e<10000; e++) { + new (function (c) { eval("var y"); }); +} diff --git a/js/src/jit-test/tests/ion/bug1181354.js b/js/src/jit-test/tests/ion/bug1181354.js new file mode 100644 index 0000000000..bef39feed6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1181354.js @@ -0,0 +1,9 @@ +for (a of []) {} +var log = ""; +(function() { + for (a of [,0]) {} + const y = "FOO"; + log += y; + function inner() { log += y; } +})() +assertEq(log, "FOO"); diff --git a/js/src/jit-test/tests/ion/bug1185957.js b/js/src/jit-test/tests/ion/bug1185957.js new file mode 100644 index 0000000000..f9ad9c9d7b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1185957.js @@ -0,0 +1,9 @@ +// |jit-test| error: TypeError + +class test { + constructor() {}; +} + +(function() { + test() +})(); diff --git a/js/src/jit-test/tests/ion/bug1186271.js b/js/src/jit-test/tests/ion/bug1186271.js new file mode 100644 index 0000000000..2e1513abb2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1186271.js @@ -0,0 +1,18 @@ +function f(x) { + return Math.imul(1, x >>> 0) / 9 | 0; +} +function g(x) { + return 1 * (x >>> 0) / 9 | 0; +} +function h(x) { + return (x >>> 0) / 9 | 0; +} + +assertEq(0, f(4294967296)); +assertEq(-238609294, f(2147483648)); + +assertEq(0, g(4294967296)); +assertEq(238609294, g(2147483648)); + +assertEq(0, h(4294967296)); +assertEq(238609294, h(2147483648)); diff --git a/js/src/jit-test/tests/ion/bug1188586.js b/js/src/jit-test/tests/ion/bug1188586.js new file mode 100644 index 0000000000..df5f166ba4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1188586.js @@ -0,0 +1,7 @@ +(function(y) { + for (var k = 0; k < 9; ++k) { + try { + y ** y == a; + } catch (e) {} + } +})(); diff --git a/js/src/jit-test/tests/ion/bug1189137.js b/js/src/jit-test/tests/ion/bug1189137.js new file mode 100644 index 0000000000..27c564195d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1189137.js @@ -0,0 +1,12 @@ + +var arr = []; +for (var i=0; i<2000; i++) + arr.push({amount: i > 1900 ? 1987654321 : 1}); + +function f() { + for (var i=0; i<arr.length; i++) { + arr[i].amount += 1987654321; + assertEq(arr[i].amount, i > 1900 ? 3975308642 : 1987654322); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1195588.js b/js/src/jit-test/tests/ion/bug1195588.js new file mode 100644 index 0000000000..706788ea55 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1195588.js @@ -0,0 +1,15 @@ +function m(f) { + for (var k = 0; k < 2; ++k) { + try { + f() + } catch (e) {} + } +} +function g(i) { + x +} +m(g) +function h() { + g(Math.sqrt(+((function() {}) < 1))) +} +m(h) diff --git a/js/src/jit-test/tests/ion/bug1195590.js b/js/src/jit-test/tests/ion/bug1195590.js new file mode 100644 index 0000000000..698ba011ca --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1195590.js @@ -0,0 +1,7 @@ +function f(x) { + try { + eval(x); + } catch (e) {} +}; +f("enableGeckoProfilingWithSlowAssertions();"); +f("enableTrackAllocations(); throw Error();"); diff --git a/js/src/jit-test/tests/ion/bug1196589.js b/js/src/jit-test/tests/ion/bug1196589.js new file mode 100644 index 0000000000..2e6c149429 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1196589.js @@ -0,0 +1,9 @@ + +function printStatus (msg) { + var lines = msg.split ("\n"); + for (var i=0; i<lines.length; i++) + lines[i]; +} +Object.prototype.length = function(){}; +var summary = 'Do not assert: !OBJ_GET_PROTO(cx, ctor)'; + printStatus (summary); diff --git a/js/src/jit-test/tests/ion/bug1196590.js b/js/src/jit-test/tests/ion/bug1196590.js new file mode 100644 index 0000000000..7a1cab095c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1196590.js @@ -0,0 +1,11 @@ + +function bar(x, i) { + if (i == 50) + x.length = 0; +} +function foo(x, j, n) { + for (var i = 0; i < n; i++) { + bar(x, i); + } +} +var a = foo([1,2,3,4], 3, 100); diff --git a/js/src/jit-test/tests/ion/bug1196648.js b/js/src/jit-test/tests/ion/bug1196648.js new file mode 100644 index 0000000000..315633a538 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1196648.js @@ -0,0 +1,18 @@ +h = function(m, foreign, n) { + "use asm"; + var ff = foreign.ff; + function f(x) { + x = +x; + ff(); + } + return f; +}(0, { + ff: function() { + return { + e: String.prototype.substring + }; + } +}, 0); +for (var k = 0; k < 999; k++) { + h(); +} diff --git a/js/src/jit-test/tests/ion/bug1197769.js b/js/src/jit-test/tests/ion/bug1197769.js new file mode 100644 index 0000000000..089258bc3d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1197769.js @@ -0,0 +1,12 @@ +// |jit-test| error:too much recursion +function test() { + var a = [""]; + var i = 0; + for (var e in a) { + if (i == 10) { + for (var g in []) {} + } + throw test(); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/bug1199898.js b/js/src/jit-test/tests/ion/bug1199898.js new file mode 100644 index 0000000000..a635b82977 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1199898.js @@ -0,0 +1,4 @@ +// |jit-test| error: TypeError +do { + for (var a of [{}]) {} +} while (4()); diff --git a/js/src/jit-test/tests/ion/bug1201459.js b/js/src/jit-test/tests/ion/bug1201459.js new file mode 100644 index 0000000000..841045d9fa --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1201459.js @@ -0,0 +1,5 @@ +// |jit-test| error:ReferenceError +function f() { + (x ? Math.fround(0) : x ? a : x) && b; +} +f(Math.fround); diff --git a/js/src/jit-test/tests/ion/bug1201469.js b/js/src/jit-test/tests/ion/bug1201469.js new file mode 100644 index 0000000000..5c709a9073 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1201469.js @@ -0,0 +1,16 @@ +f = (function() { + "use asm"; + var a; + function f() { + var b = -1; + } + return f; +})(); +for (var j = 0; j < 1; ++j) + f(); +setJitCompilerOption('ion.forceinlineCaches', 1); +Math.fround( + Math.fround() +); +for (var j = 0; j < 1; ++j) + (function() {})(); diff --git a/js/src/jit-test/tests/ion/bug1201850.js b/js/src/jit-test/tests/ion/bug1201850.js new file mode 100644 index 0000000000..4bb67c72b5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1201850.js @@ -0,0 +1,10 @@ +// |jit-test| error: too much recursion +var tokenCodes = { + get finally() { + if (tokenCodes[arr[i]] !== i) {} + } +}; +var arr = ['finally']; +for (var i = 0; i < arr.length; i++) { + if (tokenCodes[arr[i]] !== i) {} +} diff --git a/js/src/jit-test/tests/ion/bug1204165.js b/js/src/jit-test/tests/ion/bug1204165.js new file mode 100644 index 0000000000..b9d7486188 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1204165.js @@ -0,0 +1,10 @@ +var x; +function f() { + x = []; + for (var i = 0; i < 1; ++i) { + x.push(""); + } + [0].concat(x); +} +f(); +f(); diff --git a/js/src/jit-test/tests/ion/bug1204675.js b/js/src/jit-test/tests/ion/bug1204675.js new file mode 100644 index 0000000000..174aa0604e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1204675.js @@ -0,0 +1,13 @@ +function f(m, x) { + for (var i = 0; i < 2; ++i) { + print(m(x[0])); + } +} +function g() { + return false; +} +function h(y) { + return (y === 0); +} +f(g, [createIsHTMLDDA()]); +f(h, [false]); diff --git a/js/src/jit-test/tests/ion/bug1205842.js b/js/src/jit-test/tests/ion/bug1205842.js new file mode 100644 index 0000000000..a65ebf6602 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1205842.js @@ -0,0 +1,8 @@ +function f(x) { + (function() { + x = 0; + })(); +} +for (var k = 0; k < 9; k++) { + f(Math.fround(1)); +} diff --git a/js/src/jit-test/tests/ion/bug1207413.js b/js/src/jit-test/tests/ion/bug1207413.js new file mode 100644 index 0000000000..aedb8ece30 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1207413.js @@ -0,0 +1,14 @@ +// |jit-test| skip-if: !('oomAfterAllocations' in this) + +function first(a) { + return a[0]; +} + +try { + first([function() {}]); + first([function() {}]); + oomAfterAllocations(50); + first([function() {}]); +} catch(e) { + // ignore oom +} diff --git a/js/src/jit-test/tests/ion/bug1212298.js b/js/src/jit-test/tests/ion/bug1212298.js new file mode 100644 index 0000000000..a793ae1542 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1212298.js @@ -0,0 +1,8 @@ +function f() { + for (var e = 1; e < 3000; e++) { + (function(arguments) { + eval("var y"); + })(); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1212605.js b/js/src/jit-test/tests/ion/bug1212605.js new file mode 100644 index 0000000000..3841231a9a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1212605.js @@ -0,0 +1,3 @@ +// |jit-test| error: SyntaxError +s = newGlobal(); +evalcx("let NaN = 0;", s); diff --git a/js/src/jit-test/tests/ion/bug1213552.js b/js/src/jit-test/tests/ion/bug1213552.js new file mode 100644 index 0000000000..f1d475dd6d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1213552.js @@ -0,0 +1,4 @@ +this.x1 = 'y'; +// evalcx is like evaluate and not eval, and so can introduce a global let binding. +evalcx("let x1 = 'z';", this); +assertEq(x1, 'z'); diff --git a/js/src/jit-test/tests/ion/bug1214013.js b/js/src/jit-test/tests/ion/bug1214013.js new file mode 100644 index 0000000000..53001f05a3 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1214013.js @@ -0,0 +1,7 @@ +// |jit-test| error: SyntaxError + +var hits = 0; +with(f_arg => constructor.f_arg([3, 4, 5], null)) var length = 257751; +let get = () => 4, + hits = new Intl.Proxy([f_arg]), + y = ($ERROR < 1970) ? 1969 : 1970; diff --git a/js/src/jit-test/tests/ion/bug1214050.js b/js/src/jit-test/tests/ion/bug1214050.js new file mode 100644 index 0000000000..7cb214cb0d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1214050.js @@ -0,0 +1,6 @@ +eval(` + with ({}) { + var f = function() {}; + } + function f() {} +`); diff --git a/js/src/jit-test/tests/ion/bug1215600.js b/js/src/jit-test/tests/ion/bug1215600.js new file mode 100644 index 0000000000..abe433a8b4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1215600.js @@ -0,0 +1,25 @@ +// |jit-test| slow + +lfcode = Array() +lfcode.push("5") +lfcode.push("") +lfcode.push("3") +lfcode.push("oomTest(()=>{gc()})") +for (let i = 0; i < 10; i++) { + file = lfcode.shift() + loadFile(file) +} +function loadFile(lfVarx) { + try { + if (lfVarx.length != 1) + switch (lfRunTypeId) { + case 3: + function newFunc(x) { return Function(x)(); } + newFunc(lfVarx) + case 5: + for (lfLocal in this); + } + isNaN(); + lfRunTypeId = parseInt(lfVarx); + } catch (lfVare) {} +} diff --git a/js/src/jit-test/tests/ion/bug1215992.js b/js/src/jit-test/tests/ion/bug1215992.js new file mode 100644 index 0000000000..dd20be273d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1215992.js @@ -0,0 +1,6 @@ +// |jit-test| error: ReferenceError +(function() { + const x = ""; + x = y; + return x = z; +})(); diff --git a/js/src/jit-test/tests/ion/bug1216130.js b/js/src/jit-test/tests/ion/bug1216130.js new file mode 100644 index 0000000000..68731389f7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1216130.js @@ -0,0 +1,50 @@ +function Obj1(x) { this.x = x; } +function f1() { + var arr = [], o = {}; + for (var i=0; i<2500; i++) { + arr.push(new Obj1(o)); + if (i < 15) { + arr[i].x = undefined; + arr[i].x = Math; + } + } + for (var i=0; i<2500; i++) { + var y = (i > 2000) ? undefined : o; + arr[i].x = y; + } +} +f1(); + +function f2() { + var arr = [], p = {}; + for (var i=0; i<2500; i++) { + var x = (i < 2000) ? p : undefined; + var o = {x: x}; + if (i < 5) { + o.x = undefined; + o.x = p; + } + arr.push(o); + } + for (var i=0; i<2500; i++) { + assertEq(arr[i].x, i < 2000 ? p : undefined); + } +} +f2(); + +function f3() { + var arr = [], p = {}; + for (var i=0; i<2500; i++) { + var x = (i < 2000) ? p : true; + var o = {x: x}; + if (i < 5) { + o.x = true; + o.x = p; + } + arr.push(o); + } + for (var i=0; i<2500; i++) { + assertEq(arr[i].x, i < 2000 ? p : true); + } +} +f3(); diff --git a/js/src/jit-test/tests/ion/bug1216151.js b/js/src/jit-test/tests/ion/bug1216151.js new file mode 100644 index 0000000000..5f549ef516 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1216151.js @@ -0,0 +1,6 @@ +new function() { + var x = {}; + (function() { + return x; + })(); +} diff --git a/js/src/jit-test/tests/ion/bug1216157.js b/js/src/jit-test/tests/ion/bug1216157.js new file mode 100644 index 0000000000..1ec9497e40 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1216157.js @@ -0,0 +1,12 @@ +// |jit-test| skip-if: !('oomAfterAllocations' in this); allow-oom + +gcslice(0); // Start IGC, but don't mark anything. +function f(str) { + for (var i = 0; i < 10; i++) { + arr = /foo(ba(r))?/.exec(str); + var x = arr[oomAfterAllocations(100)] + " " + arr[1] + " " + 1899; + } +} +try { + f("foo"); +} catch(e) {} diff --git a/js/src/jit-test/tests/ion/bug1218065.js b/js/src/jit-test/tests/ion/bug1218065.js new file mode 100644 index 0000000000..f72febc11f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1218065.js @@ -0,0 +1,25 @@ +function f() { + const b = 0; + switch (1) { + case b = 0: + } +} +var err; +try { + f(); +} catch(e) { + err = e; +} +assertEq(err.name, "TypeError"); + +function g() { + const z = 0; + while (z = 1) {} +} +err = null; +try { + g(); +} catch(e) { + err = e; +} +assertEq(err.name, "TypeError"); diff --git a/js/src/jit-test/tests/ion/bug1219883.js b/js/src/jit-test/tests/ion/bug1219883.js new file mode 100644 index 0000000000..27d65f9c59 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1219883.js @@ -0,0 +1,14 @@ +function test() { + var arr = new Int8Array(400); + var idx = "384"; + arr[idx] = 9; + assertEq(arr[idx], 9); + idx = "1000"; + arr[idx] = 10; + assertEq(arr[idx], undefined); + idx = "-1"; + arr[idx] = 0; + assertEq(arr[idx], undefined); +} +for (var i=0; i<10; i++) + test(); diff --git a/js/src/jit-test/tests/ion/bug1222905.js b/js/src/jit-test/tests/ion/bug1222905.js new file mode 100644 index 0000000000..3e1dc53557 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1222905.js @@ -0,0 +1,14 @@ +for (var i = 0; i < 90; ++i) { + y = {x: 1}; +} + +Object.defineProperty(Object.prototype, "zz", {set: (v) => 1 }); + +function f() { + for (var i=0; i<1500; i++) { + y[0] = 0; + if (i > 1400) + y.zz = 3; + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1222917.js b/js/src/jit-test/tests/ion/bug1222917.js new file mode 100644 index 0000000000..2951b472f9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1222917.js @@ -0,0 +1,6 @@ +function f() { + var x = []; + for (var i=0; i<10; i++) + x.length = x; +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1225367.js b/js/src/jit-test/tests/ion/bug1225367.js new file mode 100644 index 0000000000..4889bb29ab --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1225367.js @@ -0,0 +1,17 @@ +function f() { + var hits = 0; + for (var T of [Float32Array, Float64Array, Float32Array]) { + var arr = new T(1); + try { + arr[0] = Symbol.iterator; + } catch(e) { hits++; } + } + for (var T of [Int32Array, Int16Array, Int8Array]) { + var arr = new T(1); + try { + arr[0] = Symbol.iterator; + } catch(e) { hits++; } + } + assertEq(hits, 6); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1226816.js b/js/src/jit-test/tests/ion/bug1226816.js new file mode 100644 index 0000000000..fc97c9c97d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1226816.js @@ -0,0 +1,11 @@ +// |jit-test| error: InternalError + +x = 1; +x; +function g(y) {} +g(this); +x = /x/; +function f() { + f(x.flags); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1228327.js b/js/src/jit-test/tests/ion/bug1228327.js new file mode 100644 index 0000000000..af9cda58a4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1228327.js @@ -0,0 +1,14 @@ +for (var i=0; i<2; i++) { + var o = {}; + Object.setPrototypeOf(o, null); + o = Object.create(o); + var p = {}; + Object.setPrototypeOf(p, o); +} +function f() { + for (var i=1; i<20; i++) + p[i] = i; + for (var i=0; i<1500; i++) + assertEq(p[0], undefined); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1228397.js b/js/src/jit-test/tests/ion/bug1228397.js new file mode 100644 index 0000000000..c229251ffa --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1228397.js @@ -0,0 +1,7 @@ +(function() { + f = (function(y) { + return y ? (2147483648 >>> 0) / 1 == -2147483648 : 2147483648; + }) + assertEq(f(0), 2147483648); + assertEq(f(1), false); +})() diff --git a/js/src/jit-test/tests/ion/bug1232859.js b/js/src/jit-test/tests/ion/bug1232859.js new file mode 100644 index 0000000000..4eefa634ee --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1232859.js @@ -0,0 +1,12 @@ +// |jit-test| error:recursion +x = /x/; +z = []; +y = Object.defineProperty(z, "valueOf", { + get: function() { + +y; + for (var i = 0; i < 1; i++) { + a = x.exec(0); + } + } +}) +z + ''; diff --git a/js/src/jit-test/tests/ion/bug1233331.js b/js/src/jit-test/tests/ion/bug1233331.js new file mode 100644 index 0000000000..11b8faafd1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1233331.js @@ -0,0 +1,12 @@ +// |jit-test| skip-if: !('oomTest' in this) + +x = 0; +try { + a; + b; +} catch (e) {} +var g = newGlobal(); +oomTest(function() { + return Debugger(g); +}); +eval("function g() {}"); diff --git a/js/src/jit-test/tests/ion/bug1233343.js b/js/src/jit-test/tests/ion/bug1233343.js new file mode 100644 index 0000000000..c3144053a8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1233343.js @@ -0,0 +1,36 @@ +function addRemove() { + dbg.addDebuggee(g); + f = dbg.getNewestFrame().older; +} +function removeAdd() { + dbg.addDebuggee(g); + var f = dbg.getNewestFrame(); + while (f) { + f = f.older; + } +} +function testInterrupt() { + g = newGlobal({newCompartment: true}); + dbg = new Debugger; + g.eval("" + function f() { + return g(); + }); + g.eval("" + function g() { + return h(); + }); + g.eval("" + function h() { + for (var i = 0; i < 100; i++) { + interruptIf(5); + } + }); + setInterruptCallback(function() { + toggleSeq(); + return true; + }); + g.f(); +} +toggleSeq = addRemove; +testInterrupt(); +toggleSeq = removeAdd; +testInterrupt(); + diff --git a/js/src/jit-test/tests/ion/bug1239075.js b/js/src/jit-test/tests/ion/bug1239075.js new file mode 100644 index 0000000000..d8e3a8868e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1239075.js @@ -0,0 +1,29 @@ + +function g0() { with({}){}; } +function f0(y, x) { + var a = y >>> 0; + a = a - 1 + 1; + g0(); // Capture the truncate result after the call. + var b = x / 2; // bailout. + return ~(a + b); +} +assertEq(f0(-1, 0), 0); +assertEq(f0(-1, 1), 0); + + +function g1() { with({}){}; } +function f1(y, x) { + var a = y >>> 0; + a = a - 1 + 1; + g1(); // Capture the truncate result after the call. + var b = Math.pow(x / 2, x); // bailout. + return ~(a + b); +} +assertEq(f1(-1, 0), -1); +assertEq(f1(-1, 1), 0); + +function f2(x) { + return ~(((~0 | 0) >>> 0 || 0) + Math.pow(Math.cos(x >>> 0), Math.atan2(0, x))) +} +assertEq(f2(0), -1); +assertEq(f2(-9999), 0); diff --git a/js/src/jit-test/tests/ion/bug1240521.js b/js/src/jit-test/tests/ion/bug1240521.js new file mode 100644 index 0000000000..5955705b7a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1240521.js @@ -0,0 +1,14 @@ +// |jit-test| allow-oom; skip-if: !('oomAfterAllocations' in this) + +var egc = 138; +function SwitchTest(value) { + switch (value) { + case 0: + break + case new Number: + result = 8 + case oomAfterAllocations(egc): + } +} +!(SwitchTest(4) === 4); +!(SwitchTest(true) === 2); diff --git a/js/src/jit-test/tests/ion/bug1244502.js b/js/src/jit-test/tests/ion/bug1244502.js new file mode 100644 index 0000000000..b0b3943cd5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1244502.js @@ -0,0 +1,12 @@ +function f(arg) { + bailout(); + assertEq(arguments.length, 2); + assertEq(arg, ""); + assertEq(arguments[0], ""); + assertEq(arguments[1], 0); +} +for (var i = 0; i < 100; ++i) { + (function() { + f.call(1, "", 0); + })(); +} diff --git a/js/src/jit-test/tests/ion/bug1246154.js b/js/src/jit-test/tests/ion/bug1246154.js new file mode 100644 index 0000000000..93508bc433 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1246154.js @@ -0,0 +1,5 @@ +setJitCompilerOption('ion.forceinlineCaches', 1); +enableGeckoProfiling(); +(function() { + -[]; +})(); diff --git a/js/src/jit-test/tests/ion/bug1246552.js b/js/src/jit-test/tests/ion/bug1246552.js new file mode 100644 index 0000000000..3a4aa7c8b0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1246552.js @@ -0,0 +1,11 @@ + +var t = 0; +var y = []; +y.toString = (function() { t += 1 }); +function test() { + for (var i = 0; i < 14; i++) { + String.prototype.sup.call(y); + } +} +test(); +assertEq(t, 14); diff --git a/js/src/jit-test/tests/ion/bug1247880.js b/js/src/jit-test/tests/ion/bug1247880.js new file mode 100644 index 0000000000..af5bbf93ad --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1247880.js @@ -0,0 +1,12 @@ +function f(x) { + var a = x; + a = Number ? a | 0 : 0; + a = a >>> 0; + a = Math.imul(0x100000001, a); + a = a % 2; + a = a | 0; + return a; +}; + +assertEq(f(0), 0); +assertEq(f(-1), -1); diff --git a/js/src/jit-test/tests/ion/bug1247909.js b/js/src/jit-test/tests/ion/bug1247909.js new file mode 100644 index 0000000000..7dd7efd0f7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1247909.js @@ -0,0 +1,12 @@ +// |jit-test| --ion-pgo=on; + +function test() { + foo(startTest("", c(""), + test([{ 0 : c(), 0 : toString("", c(), [], tab([])) }]) + )); + function f() {}; +} + +try { + test(); +} catch(e) {} diff --git a/js/src/jit-test/tests/ion/bug1247915.js b/js/src/jit-test/tests/ion/bug1247915.js new file mode 100644 index 0000000000..e66faf559b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1247915.js @@ -0,0 +1,7 @@ +// |jit-test| --ion-pgo=on + +evaluate(` + var i = 0; + while (!inIon()) + a = [] ? i: () => 5; +`); diff --git a/js/src/jit-test/tests/ion/bug1254197.js b/js/src/jit-test/tests/ion/bug1254197.js new file mode 100644 index 0000000000..d5ef9c902a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1254197.js @@ -0,0 +1,16 @@ +setJitCompilerOption("ion.warmup.trigger", 1); +function f(x) { + var w = []; + var i = 0; + for (var count = 0; count < 3; count++) { + for (var j = 0; j < 60; j++) { + if (j < 1) { + w[0] = x[i]; + } else { + w[0][0]; + } + } + i = 1; + } +} +f([NaN, 0]); diff --git a/js/src/jit-test/tests/ion/bug1261326.js b/js/src/jit-test/tests/ion/bug1261326.js new file mode 100644 index 0000000000..fb4f43de8f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1261326.js @@ -0,0 +1,11 @@ +x = x = ""; +function Obj1(x) { + this.x = x; +} +function f() { + var o = {}; + for (var i = 0; i < 1500; i++) + new Obj1(o); + Obj1(''); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1264948-1.js b/js/src/jit-test/tests/ion/bug1264948-1.js new file mode 100644 index 0000000000..1070275dce --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1264948-1.js @@ -0,0 +1,9 @@ +// |jit-test| error: ReferenceError + +var N = 70 * 1000; +var x = build("&&")(); +function build(operation) { + var a = []; + for (var i = 1; i != N - 1; ++i) a.push("f()"); + return new Function(a.join(operation)); +} diff --git a/js/src/jit-test/tests/ion/bug1265159.js b/js/src/jit-test/tests/ion/bug1265159.js new file mode 100644 index 0000000000..30d3443f18 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1265159.js @@ -0,0 +1,17 @@ + +var thrown = false; +try { + x = [0]; + for (var i = 0; i < 5; ++i) { + if (i == 3) + Object.freeze(x); + else + x.pop(); + } +} catch (e) { + thrown = true; + assertEq(e instanceof TypeError, true); +} + +assertEq(thrown, true); + diff --git a/js/src/jit-test/tests/ion/bug1269756.js b/js/src/jit-test/tests/ion/bug1269756.js new file mode 100644 index 0000000000..62af06b70f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1269756.js @@ -0,0 +1,7 @@ +// |jit-test| skip-if: !('oomTest' in this) + +oomTest(function() { + m = parseModule(`while (x && NaN) prototype; let x`); + m.declarationInstantiation(); + m.evaluation(); +}) diff --git a/js/src/jit-test/tests/ion/bug1273858-1.js b/js/src/jit-test/tests/ion/bug1273858-1.js new file mode 100644 index 0000000000..89769ffe58 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1273858-1.js @@ -0,0 +1,53 @@ +// |jit-test| --no-threads + +function t1() { + let x = []; + + for (let k = 0; k < 100; ++k) + x[k] = () => k; // Lexical capture + + try { + eval("k"); + throw false; + } + catch (e) { + if (!(e instanceof ReferenceError)) + throw "Loop index escaped block"; + } + + for (var i = 0; i < 100; ++i) + if (x[i]() != i) + throw "Bad let capture"; +} +t1(); +t1(); +t1(); +t1(); + +function t2() { + let x = []; + let y = {}; + + for (var i = 0; i < 100; ++i) + x[i] = i; + + for (const k of x) + y[k] = () => k; // Lexical capture + + try { + eval("k"); + throw false; + } + catch (e) { + if (!(e instanceof ReferenceError)) + throw "Loop index escaped block"; + } + + for (var i = 0; i < 100; ++i) + if (y[i]() != i) + throw "Bad const capture"; +} +t2(); +t2(); +t2(); +t2(); diff --git a/js/src/jit-test/tests/ion/bug1273858-2.js b/js/src/jit-test/tests/ion/bug1273858-2.js new file mode 100644 index 0000000000..6d274cf02b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1273858-2.js @@ -0,0 +1,46 @@ +// |jit-test| --no-threads + +function t1() { + let x = []; + + try + { + for (let k = 0; k < 100; ++k) + { + let w = () => k; // Lexical capture + + if (w() > 10) + { + throw () => w; // Lexical capture + } + + x[k] = w; + } + } + catch (e) + { + // 'w' and 'k' should leave scope as exception unwinds + + try { + eval("k"); + throw false; + } + catch (e) { + if (!(e instanceof ReferenceError)) + throw "Loop index escaped block"; + } + + try { + eval("w"); + throw false; + } + catch (e) { + if (!(e instanceof ReferenceError)) + throw "Local name escaped block"; + } + } +} +t1(); +t1(); +t1(); +t1(); diff --git a/js/src/jit-test/tests/ion/bug1279898.js b/js/src/jit-test/tests/ion/bug1279898.js new file mode 100644 index 0000000000..756120a6d9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1279898.js @@ -0,0 +1,19 @@ + +function f() { + var i32 = new Int32Array(1); + var f32 = new Float32Array(i32.buffer); + for (var i = 0; i < 3; i++) { + var a0 = +1; + var a3 = +4; + + i32[0] = a0; + var b0 = f32[0]; + + i32[0] = a3; + var b3 = f32[0]; + + assertEq(b0 != b3, true); + } +} + +f(); diff --git a/js/src/jit-test/tests/ion/bug1282944.js b/js/src/jit-test/tests/ion/bug1282944.js new file mode 100644 index 0000000000..83ca25cec1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1282944.js @@ -0,0 +1,13 @@ +// |jit-test| --ion-eager; skip-if: helperThreadCount() === 0 + +// (1) Poison an element in the ionLazyLinkList with a builder whose +// script is in a different compartment. +evaluate('offThreadCompileScript("var x = -1"); runOffThreadScript()', + { global: newGlobal() }); + +// (2) Spam the ionLazyLinkList with pending builders until it pops off the one +// for the other compartment's script. +for (var i = 0; i < 1000; ++i) { + offThreadCompileScript('var x = ' + i); + runOffThreadScript(); +} diff --git a/js/src/jit-test/tests/ion/bug1284491.js b/js/src/jit-test/tests/ion/bug1284491.js new file mode 100644 index 0000000000..eb8f15619b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1284491.js @@ -0,0 +1,14 @@ +// |jit-test| skip-if: !('oomTest' in this) + +loadFile(` + function SwitchTest(){ + switch(value) { + case 0:break + case isNaN: break + } + } + SwitchTest(); +`) +function loadFile(lfVarx) { + oomTest(function() { return eval(lfVarx); }) +} diff --git a/js/src/jit-test/tests/ion/bug1285217.js b/js/src/jit-test/tests/ion/bug1285217.js new file mode 100644 index 0000000000..31943a6d15 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1285217.js @@ -0,0 +1,11 @@ +function f() { + var o = { + x: 1 + }; + for (var i = 0; i < 300; i++) o = Object.create(o); + for (var i = 0; i < 15; i++) { + assertEq(o.x, 1); + eval(o.y, undefined); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1285218.js b/js/src/jit-test/tests/ion/bug1285218.js new file mode 100644 index 0000000000..bb32f0f66a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1285218.js @@ -0,0 +1,27 @@ +function test() { + var a1; var a2; var a3; var a4; var a5; var a6; var a7; var a8; var a9; + var a10; var a11; var a12; var a13; var a14; var a15; var a16; var a17; + var a18; var a19; var a20; var a21; var a22; var a23; var a24; var a25; + var a26; var a27; var a28; var a29; var a30; var a31; var a32; var a33; + var a34; var a35; var a36; var a37; var a38; var a39; var a40; var a41; + var a42; var a43; var a44; var a45; var a46; var a47; var a48; + for ( dbg = 30; dbg >=0; dbg-- ) {} + var a50; var a51; var a52; var a53; var a54; var a55; var a56; var a57; + var a58; var a59; var a60; var a61; var a62; var a63; var a64; var a65; + var a66; var a67; var a68; var a69; + var assertEq = ''; + var a71; var a72; + let onDebuggerStatement; + var a74; var a75; var a76; var a77; var a78; var a79; var a80; var a81; + var a82; var a83; var a84; var a85; var a86; var a87; var a88; var a89; + var a90; var a91; var a92; var a93; var a94; var a95; var a96; var a97; + var a98; var a99; var a100; var a101; var a102; var a103; var a104; var a105; + var a106; var a107; var a108; var a109; var a110; var a111; var a112; + if(a111 !== a2) + var a114; + var a115; var a116; var a117; var a120; var a121; var a122; var a123; + var a124; var a125; + for (var a126 = 1; a126 < ([1,2,3]).length -1; ++a126) 1; +} + +test(); diff --git a/js/src/jit-test/tests/ion/bug1287416.js b/js/src/jit-test/tests/ion/bug1287416.js new file mode 100644 index 0000000000..5fad180288 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1287416.js @@ -0,0 +1,3 @@ +for (var i = 0; i < 1; i++) { + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".split("x"); +}; diff --git a/js/src/jit-test/tests/ion/bug1293542.js b/js/src/jit-test/tests/ion/bug1293542.js new file mode 100644 index 0000000000..38c27125e4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1293542.js @@ -0,0 +1,11 @@ + +try { eval("3 ** 4") } catch (e) { + if (!(e instanceof SyntaxError)) + throw e; + quit(); +} + +var f = new Function("x", "return (x ** (1 / ~4294967297)) && x"); +for (var i = 0; i < 2; ++i) { + assertEq(f(-Infinity), 0); +} diff --git a/js/src/jit-test/tests/ion/bug1296667.js b/js/src/jit-test/tests/ion/bug1296667.js new file mode 100644 index 0000000000..4ad8cc70ea --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1296667.js @@ -0,0 +1,12 @@ +args = "" +for (i = 0; i < 2000; i++) { + args += "arg" + i; + if (i != 1999) args += ","; +} +MyFunc = MyObject = Function(args, "for (var i = 0; i < MyFunc.length; i++ ) break; eval('this.arg'+i +'=arg'+i) "); +new function TestCase() { + if (inIon()) + return; + for (var i=0; i<10; i++) {} + TestCase(eval("var EXP_1 = new MyObject; var EXP_2 = new MyObject; EXP_1 - EXP_2")); +} diff --git a/js/src/jit-test/tests/ion/bug1298354.js b/js/src/jit-test/tests/ion/bug1298354.js new file mode 100644 index 0000000000..69cbb67213 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1298354.js @@ -0,0 +1,21 @@ +// |jit-test| error: ReferenceError + +setJitCompilerOption("ion.warmup.trigger", 50); +setJitCompilerOption("offthread-compilation.enable", 0); +gcPreserveCode(); + +new Function(` + while (true) { + try { + var buf = new Uint8ClampedArray(-1); + } catch (e) { + break; + } + } + var caughtInvalidArguments = false; + while (true) { + var a = inIon() ? -true.get : 0; + while (x > 7 & 0) {} + } +`)(); + diff --git a/js/src/jit-test/tests/ion/bug1299007.js b/js/src/jit-test/tests/ion/bug1299007.js new file mode 100644 index 0000000000..6c82a95264 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1299007.js @@ -0,0 +1,41 @@ + +evalInFrame = function(global) { + dbgGlobal = newGlobal({newCompartment: true}) + dbg = new dbgGlobal.Debugger + return function(upCount, code) { + dbg.addDebuggee(global) + var frame = dbg.getNewestFrame().older + for (var i = 0; i < upCount; i++) + if (!frame) frame = older + completion = frame.eval(code) + } +}(this); +function h() { + evalInFrame(0, "") + evalInFrame(0, "i") + evalInFrame(0, "a.push") + evalInFrame(1, "a.pushy") +} +function g() { return h(); } +function f() { return g(); } +f() +evaluate(` +g() +g() +g() +g() +g() +g() +g() +g() +g() +g() +g() +g() +g() +g() +g() +g() +g() +h() +`); diff --git a/js/src/jit-test/tests/ion/bug1304640.js b/js/src/jit-test/tests/ion/bug1304640.js new file mode 100644 index 0000000000..6de29f8528 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1304640.js @@ -0,0 +1,10 @@ + +function f() { + return /x/; +} +function g() { + return (f() == f()); +} +for (var i = 0; i < 2; ++i) { + assertEq(g(), false); +} diff --git a/js/src/jit-test/tests/ion/bug1304643.js b/js/src/jit-test/tests/ion/bug1304643.js new file mode 100644 index 0000000000..40bf37d38e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1304643.js @@ -0,0 +1,7 @@ + +var x = Object.create(this); +var y = '1'; +for (var i = 0; i < 3; ++i) { + y += x.y; +} +assertEq(y, "11111111"); diff --git a/js/src/jit-test/tests/ion/bug1308802.js b/js/src/jit-test/tests/ion/bug1308802.js new file mode 100644 index 0000000000..eafe3c697c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1308802.js @@ -0,0 +1,8 @@ + +function test() { + for (var i = 0; i < 2; ++i) { + assertEq(Math.max(-0), -0); + } +} +test(); + diff --git a/js/src/jit-test/tests/ion/bug1311061.js b/js/src/jit-test/tests/ion/bug1311061.js new file mode 100644 index 0000000000..b852248bf1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1311061.js @@ -0,0 +1,5 @@ +// |jit-test| error:TypeError +function f() { + with(this) {}; +} +(new new Proxy(f, {get: f}))(); diff --git a/js/src/jit-test/tests/ion/bug1314438.js b/js/src/jit-test/tests/ion/bug1314438.js new file mode 100644 index 0000000000..bda1c7a2d7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1314438.js @@ -0,0 +1,6 @@ + +function g(x) { + return (-1 % x && Math.cos(8) >>> 0); +} +g(2); +assertEq(Object.is(g(-1), -0), true); diff --git a/js/src/jit-test/tests/ion/bug1314545.js b/js/src/jit-test/tests/ion/bug1314545.js new file mode 100644 index 0000000000..f833a8ae73 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1314545.js @@ -0,0 +1,31 @@ +function f() { + Object.prototype[0] = 10; + + var arr = []; + for (var i=3; i<20; i++) { + arr[0] = i; + Object.freeze(arr); + while (!inIon()) {} + } + assertEq(arr[0], 3); +} +f(); + +function g() { + var c = 0; + Object.defineProperty(Object.prototype, 18, {set: function() { c++; }}); + + var arrays = []; + for (var i=0; i<2; i++) + arrays.push([1, 2]); + + for (var i=0; i<20; i++) { + arrays[0][i] = 1; + arrays[1][i] = 2; + if (i === 0) + Object.freeze(arrays[0]); + while (!inIon()) {} + } + assertEq(c, 2); +} +g(); diff --git a/js/src/jit-test/tests/ion/bug1317943.js b/js/src/jit-test/tests/ion/bug1317943.js new file mode 100644 index 0000000000..10b36d3681 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1317943.js @@ -0,0 +1,14 @@ +"use strict"; +function test() { + for (var i=0; i<10; i++) { + try { + var arr = []; + arr[0] = 1; + Object.freeze(arr); + arr[0] = 2; + } catch (e) { + assertEq(e.toString().includes("TypeError: 0 is read-only"), true); + } + } +} +test(); diff --git a/js/src/jit-test/tests/ion/bug1318634.js b/js/src/jit-test/tests/ion/bug1318634.js new file mode 100644 index 0000000000..58448bb170 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1318634.js @@ -0,0 +1,20 @@ +var o1 = {get x() { return 1; }}; +var o2 = {get x() { return 2; }}; +var o3 = Object.create(o1); + +function f(o) { + return o.x; +} + +var res = 0; +for (var i=0; i<15; i++) { + res += f(o3); + res += f(o2); +} + +o1.y = 1; + +for (var i=0; i<110; i++) + res += f(o2); + +assertEq(res, 265); diff --git a/js/src/jit-test/tests/ion/bug1321437.js b/js/src/jit-test/tests/ion/bug1321437.js new file mode 100644 index 0000000000..98a60e9094 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1321437.js @@ -0,0 +1,14 @@ +function f(idx) { + "use strict"; + let z = [0, 1, 2, 3, 4, 5, 6, 7, 8, , , ]; + Object.freeze(z); + try { + z[idx] = 0; + } catch (e) { + return e.message; + } +} +assertEq(f(4), "4 is read-only"); +assertEq(f(-1), 'can\'t define property "-1": Array is not extensible'); +assertEq(f(9), "can't define property 9: Array is not extensible"); +assertEq(f(0xffffffff), 'can\'t define property "4294967295": Array is not extensible'); diff --git a/js/src/jit-test/tests/ion/bug1322932.js b/js/src/jit-test/tests/ion/bug1322932.js new file mode 100644 index 0000000000..0de9737eef --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1322932.js @@ -0,0 +1,12 @@ +// |jit-test| error: ReferenceError + +(function() { + for (var i = 0; i < 4; ++i) { + if (i % 3 == 0) { + for (var x in y) {} + } else { + continue; + } + } +})() + diff --git a/js/src/jit-test/tests/ion/bug1323854.js b/js/src/jit-test/tests/ion/bug1323854.js new file mode 100644 index 0000000000..7021d6a6d9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1323854.js @@ -0,0 +1,15 @@ + +g = (function () { + "use asm"; + function f(i0, d1) { + d1 = 4258326539 >>> 0; + switch (-8 && i0) { + case -1: + d1 = 0; + case 0: + } + } + return f; +})(); +g(); +g(); diff --git a/js/src/jit-test/tests/ion/bug1324521.js b/js/src/jit-test/tests/ion/bug1324521.js new file mode 100644 index 0000000000..38f9162fa2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1324521.js @@ -0,0 +1,6 @@ +function f() { + var args = arguments; + var i = 0; + while (!inIon()) args[i]; +}; +f(); diff --git a/js/src/jit-test/tests/ion/bug1326150.js b/js/src/jit-test/tests/ion/bug1326150.js new file mode 100644 index 0000000000..3c9047c983 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1326150.js @@ -0,0 +1,4 @@ +this.x = []; +Function.apply(null, this.x); +Object.defineProperty(this, "x", {get: valueOf}); +assertEq(evaluate("this.x;"), this); diff --git a/js/src/jit-test/tests/ion/bug1329933.js b/js/src/jit-test/tests/ion/bug1329933.js new file mode 100644 index 0000000000..582044feee --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1329933.js @@ -0,0 +1,10 @@ + +function g(f) { + for (var j = 0; j < 999; ++j) { + f(0 / 0); + } +} +function h(x) { + x < 1 ? 0 : Math.imul(x || 0); +} +g(h); diff --git a/js/src/jit-test/tests/ion/bug1330662.js b/js/src/jit-test/tests/ion/bug1330662.js new file mode 100644 index 0000000000..f4e561b7e0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1330662.js @@ -0,0 +1,8 @@ +setJitCompilerOption("ion.warmup.trigger", 50); +setJitCompilerOption("offthread-compilation.enable", 0); +gcPreserveCode(); + +for (i=0;i<10000;++i) { + a = inIon() ? 0 : 300; + buf = new Uint8ClampedArray(a); +} diff --git a/js/src/jit-test/tests/ion/bug1331058.js b/js/src/jit-test/tests/ion/bug1331058.js new file mode 100644 index 0000000000..ffb8f29196 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1331058.js @@ -0,0 +1,29 @@ +function foo(o, trigger) { + bar = function() { return o.getY(); }; + if (trigger) + assertEq(bar(), undefined); + return 1; +} +function O(o, trigger) { + this.a1 = 1; + this.a2 = 2; + this.a3 = 3; + this.a4 = 4; + this.x = foo(this, trigger); +} +O.prototype.getY = function() { + return this.x; +} +function test() { + with(this) {}; // No Ion. + var arr = []; + for (var i=0; i<100; i++) + arr.push(new O({y: i}, false)); + + for (var i=0; i<100; i++) + bar(); + + for (var i=0; i<300; i++) + arr.push(new O({y: i}, true)); +} +test(); diff --git a/js/src/jit-test/tests/ion/bug1331350.js b/js/src/jit-test/tests/ion/bug1331350.js new file mode 100644 index 0000000000..ea83bfa4fe --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1331350.js @@ -0,0 +1,56 @@ +// |jit-test| --ion-eager +function optimize(a, b) { + a = a | 0; + b = b | 0; + + if ((a & 3) === 0) { + a = a + 1 | 0 + } + + if ((a & 7) !== 0) { + a = a + 1 | 0 + } + + return a + b | 0 +} + +for (var i=0; i<20; i++) { + assertEq(optimize(4 | 0, 6 | 0), 12); + assertEq(optimize(7 | 0, 11 | 0), 19); +} + +function not_optimizable(a, b) { + a = a | 0; + b = b | 0; + + if ((a & 3) > 0) { + a = a + 1 | 0 + } + + if ((a & 3) >= 0) { + a = a + 1 | 0 + } + + if ((a & 7) < 0) { + a = a + 1 | 0 + } + + if ((a & 7) <= 0) { + a = a + 1 | 0 + } + + if ((b & 3) === 1) { + b = b + 1 | 0 + } + + if ((b & 7) !== 3) { + b = b + 1 | 0 + } + + return a + b | 0 +} + +for (var i=0; i<20; i++) { + assertEq(not_optimizable(4 | 0, 6 | 0), 12); + assertEq(not_optimizable(7 | 0, 11 | 0), 20); +} diff --git a/js/src/jit-test/tests/ion/bug1331405.js b/js/src/jit-test/tests/ion/bug1331405.js new file mode 100644 index 0000000000..e10b96347b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1331405.js @@ -0,0 +1,4 @@ +// |jit-test| error:ReferenceError + +++f(); +try {} catch (e) {} diff --git a/js/src/jit-test/tests/ion/bug1333946.js b/js/src/jit-test/tests/ion/bug1333946.js new file mode 100644 index 0000000000..1fa1b9c491 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1333946.js @@ -0,0 +1,8 @@ +// |jit-test| error: 42; + +for (var x of [0]) { + for (var i = 0; ; i++) { + if (i === 20000) + throw 42; + } +} diff --git a/js/src/jit-test/tests/ion/bug1334314.js b/js/src/jit-test/tests/ion/bug1334314.js new file mode 100644 index 0000000000..488fc90274 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1334314.js @@ -0,0 +1,16 @@ +// |jit-test| error: TypeError + +var g = newGlobal(); +g.parent = this; +g.eval("new Debugger(parent).onExceptionUnwind = function () { };"); + +function f() { + [[]] = []; +} +try { + f(); +} catch (e) {}; +try { + f(); +} catch (e) {}; +f(); diff --git a/js/src/jit-test/tests/ion/bug1342483-1.js b/js/src/jit-test/tests/ion/bug1342483-1.js new file mode 100644 index 0000000000..85c3cb48e6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1342483-1.js @@ -0,0 +1,6 @@ +// |jit-test| error: ReferenceError +for (var i = 0; i < 10; ++i) {} +for (var i = 0; i < 3; i++) { + throw eval(raisesException); + function ff() {} +} diff --git a/js/src/jit-test/tests/ion/bug1342483-2.js b/js/src/jit-test/tests/ion/bug1342483-2.js new file mode 100644 index 0000000000..1d5b808b04 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1342483-2.js @@ -0,0 +1,17 @@ +// |jit-test| error: () => g +function f() { + // Block Scope + { + // Lexical capture creates environment + function g() {} + var h = [() => g]; + + // OSR Re-Entry Point + for (;;) { break; } + + // Type Invalidation + Throw + throw h[0]; + } +} + +f(); diff --git a/js/src/jit-test/tests/ion/bug1342882.js b/js/src/jit-test/tests/ion/bug1342882.js new file mode 100644 index 0000000000..ff1fe001a0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1342882.js @@ -0,0 +1,3 @@ +// |jit-test| error: ReferenceError + +for (let [k, map = send.log += "" + map] of map) {} diff --git a/js/src/jit-test/tests/ion/bug1345160.js b/js/src/jit-test/tests/ion/bug1345160.js new file mode 100644 index 0000000000..e365ea3158 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1345160.js @@ -0,0 +1,9 @@ +function f() { + var o = [1, 2, 3]; + o.constructor = function() { + return new Uint8Array(3); + }; + for (var i=0; i<10; i++) + o.filter(x => true); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1352510.js b/js/src/jit-test/tests/ion/bug1352510.js new file mode 100644 index 0000000000..5c5e0e20af --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1352510.js @@ -0,0 +1,8 @@ +function maybeSetLength(arr, b) { + if (b) arr.length = 0x7fffffff; +} +var arr = []; +for (var i = 0; i < 2000; i++) { + maybeSetLength(arr, i > 1500); + var res = arr.push((0.017453)); +} diff --git a/js/src/jit-test/tests/ion/bug1354275.js b/js/src/jit-test/tests/ion/bug1354275.js new file mode 100644 index 0000000000..3d8d74af46 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1354275.js @@ -0,0 +1,16 @@ +// --ion-eager --ion-offthread-compile=off + +function f(t) { + for (var i = 0; i < 2; i++) { + try { + var x = 1; + Array(1); + x = 2; + Array(t); + } catch (e) { + assertEq(x, 2); + } + } +} +f(1); +f(-1); diff --git a/js/src/jit-test/tests/ion/bug1356822.js b/js/src/jit-test/tests/ion/bug1356822.js new file mode 100644 index 0000000000..0788933810 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1356822.js @@ -0,0 +1,15 @@ +const d = 0; +function f() { + var m = Math; + (function () { + d = m; + })() +} +for (var i = 0; i < 4; i++) { + try { + f(); + } catch (e) { + continue; + } + throw "Fail"; +} diff --git a/js/src/jit-test/tests/ion/bug1365518.js b/js/src/jit-test/tests/ion/bug1365518.js new file mode 100644 index 0000000000..30dc060c96 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1365518.js @@ -0,0 +1,13 @@ +function init() { + foo = () => 1; + bar = () => 2; + foo.__proto__ = function() {}; +} +function test() { + var arr = [foo, bar]; + for (var i = 0; i < 1300; i++) { + assertEq(arr[i % 2](), i % 2 + 1); + } +} +init(); +test(); diff --git a/js/src/jit-test/tests/ion/bug1365769-1.js b/js/src/jit-test/tests/ion/bug1365769-1.js new file mode 100644 index 0000000000..a586d0f1de --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1365769-1.js @@ -0,0 +1,16 @@ +// --ion-eager --ion-offthread-compile=off + +function f(t) { + for (var i = 0; i < 2; i++) { + try { + var x = 1; + new String(); // Creates a snapshot + x = 2; + new String(t); // Throws TypeError + } catch (e) { + assertEq(x, 2); + } + } +} + +f(Symbol()); diff --git a/js/src/jit-test/tests/ion/bug1365769-2.js b/js/src/jit-test/tests/ion/bug1365769-2.js new file mode 100644 index 0000000000..4999ad87ba --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1365769-2.js @@ -0,0 +1,16 @@ +// --ion-eager --ion-offthread-compile=off + +function f(t) { + for (var i = 0; i < 2; i++) { + try { + var x = 1; + new String(); + x = 2; + `${t}`; // Throws a TypeError + } catch (e) { + assertEq(x, 2); + } + } +} + +f(Symbol()); diff --git a/js/src/jit-test/tests/ion/bug1368360-1.js b/js/src/jit-test/tests/ion/bug1368360-1.js new file mode 100644 index 0000000000..9df4a0a06b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1368360-1.js @@ -0,0 +1,9 @@ +// |jit-test| error: ReferenceError +var t = {}; +function r(y) { return t.y = y; } +function g() { + for (let [x = r(x)] of x) {} +} +r(0); +r(0); +g(); diff --git a/js/src/jit-test/tests/ion/bug1368360-2.js b/js/src/jit-test/tests/ion/bug1368360-2.js new file mode 100644 index 0000000000..ff617fb76b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1368360-2.js @@ -0,0 +1,9 @@ +// |jit-test| error: ReferenceError +var t = {}; +function r(y) { return t.y = y; } +function g() { + for (let [x = r(x)] in x) {} +} +r(0); +r(0); +g(); diff --git a/js/src/jit-test/tests/ion/bug1370922.js b/js/src/jit-test/tests/ion/bug1370922.js new file mode 100644 index 0000000000..c8dc6d7577 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1370922.js @@ -0,0 +1,34 @@ +function f(y) { + return Math.min(0, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9); +} + +function g() { + return f({}); +} + +x = 0 + +for (var j = 0; j < 3000; j++) { + g([j]); + + if (inIon()) + break; +} diff --git a/js/src/jit-test/tests/ion/bug1379936.js b/js/src/jit-test/tests/ion/bug1379936.js new file mode 100644 index 0000000000..61d45bccd1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1379936.js @@ -0,0 +1,6 @@ +assertEq("".replace(/x/), ""); +(function () { + for (var i = 0; i < 2000; ++i) { + assertEq(/[^]/g.exec("abc")[0], "a"); + } +})() diff --git a/js/src/jit-test/tests/ion/bug1383591.js b/js/src/jit-test/tests/ion/bug1383591.js new file mode 100644 index 0000000000..f80b6c9e8d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1383591.js @@ -0,0 +1,20 @@ +function test() { + var count = 0; + function f(x) { + "use strict"; + if (x) { + Object.seal(this); + } + this[0] = 1; + } + for (var y of [1, 0, arguments, 1]) { + try { + var o = new f(y); + } catch (e) { + count++; + } + } + assertEq(count, 3); +} +test(); +test(); diff --git a/js/src/jit-test/tests/ion/bug1383972.js b/js/src/jit-test/tests/ion/bug1383972.js new file mode 100644 index 0000000000..116972766b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1383972.js @@ -0,0 +1,92 @@ +// |jit-test| --ion-limit-script-size=off; error:ReferenceError + +function f() { + for (var i = 0; i < 1; i++) { + let x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F, + x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F, + x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F, + x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F, + x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F, + x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F, + x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F, + x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F, + x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F, + x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F, + xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF, + xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF, + xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF, + xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF, + xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF, + xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7, xF8, xF9, xFA, xFB, xFC, xFD, xFE, xFF; + let y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y0A, y0B, y0C, y0D, y0E, y0F, + y10, y11, y12, y13, y14, y15, y16, y17, y18, y19, y1A, y1B, y1C, y1D, y1E, y1F, + y20, y21, y22, y23, y24, y25, y26, y27, y28, y29, y2A, y2B, y2C, y2D, y2E, y2F, + y30, y31, y32, y33, y34, y35, y36, y37, y38, y39, y3A, y3B, y3C, y3D, y3E, y3F, + y40, y41, y42, y43, y44, y45, y46, y47, y48, y49, y4A, y4B, y4C, y4D, y4E, y4F, + y50, y51, y52, y53, y54, y55, y56, y57, y58, y59, y5A, y5B, y5C, y5D, y5E, y5F, + y60, y61, y62, y63, y64, y65, y66, y67, y68, y69, y6A, y6B, y6C, y6D, y6E, y6F, + y70, y71, y72, y73, y74, y75, y76, y77, y78, y79, y7A, y7B, y7C, y7D, y7E, y7F, + y80, y81, y82, y83, y84, y85, y86, y87, y88, y89, y8A, y8B, y8C, y8D, y8E, y8F, + y90, y91, y92, y93, y94, y95, y96, y97, y98, y99, y9A, y9B, y9C, y9D, y9E, y9F, + yA0, yA1, yA2, yA3, yA4, yA5, yA6, yA7, yA8, yA9, yAA, yAB, yAC, yAD, yAE, yAF, + yB0, yB1, yB2, yB3, yB4, yB5, yB6, yB7, yB8, yB9, yBA, yBB, yBC, yBD, yBE, yBF, + yC0, yC1, yC2, yC3, yC4, yC5, yC6, yC7, yC8, yC9, yCA, yCB, yCC, yCD, yCE, yCF, + yD0, yD1, yD2, yD3, yD4, yD5, yD6, yD7, yD8, yD9, yDA, yDB, yDC, yDD, yDE, yDF, + yE0, yE1, yE2, yE3, yE4, yE5, yE6, yE7, yE8, yE9, yEA, yEB, yEC, yED, yEE, yEF, + yF0, yF1, yF2, yF3, yF4, yF5, yF6, yF7, yF8, yF9, yFA, yFB, yFC, yFD, yFE, yFF; + + if (b()) { + x00 = x01 = x02 = x03 = x04 = x05 = x06 = x07 = a(); + x08 = x09 = x0A = x0B = x0C = x0D = x0E = x0F = a(); + x10 = x11 = x12 = x13 = x14 = x15 = x16 = x17 = a(); + x18 = x19 = x1A = x1B = x1C = x1D = x1E = x1F = a(); + x20 = x21 = x22 = x23 = x24 = x25 = x26 = x27 = a(); + x28 = x29 = x2A = x2B = x2C = x2D = x2E = x2F = a(); + x30 = x31 = x32 = x33 = x34 = x35 = x36 = x37 = a(); + x38 = x39 = x3A = x3B = x3C = x3D = x3E = x3F = a(); + x40 = x41 = x42 = x43 = x44 = x45 = x46 = x47 = a(); + x48 = x49 = x4A = x4B = x4C = x4D = x4E = x4F = a(); + x50 = x51 = x52 = x53 = x54 = x55 = x56 = x57 = a(); + x58 = x59 = x5A = x5B = x5C = x5D = x5E = x5F = a(); + x60 = x61 = x62 = x63 = x64 = x65 = x66 = x67 = a(); + x68 = x69 = x6A = x6B = x6C = x6D = x6E = x6F = a(); + x70 = x71 = x72 = x73 = x74 = x75 = x76 = x77 = a(); + x78 = x79 = x7A = x7B = x7C = x7D = x7E = x7F = a(); + x80 = x81 = x82 = x83 = x84 = x85 = x86 = x87 = a(); + x88 = x89 = x8A = x8B = x8C = x8D = x8E = x8F = a(); + x90 = x91 = x92 = x93 = x94 = x95 = x96 = x97 = a(); + x98 = x99 = x9A = x9B = x9C = x9D = x9E = x9F = a(); + xA0 = xA1 = xA2 = xA3 = xA4 = xA5 = xA6 = xA7 = a(); + xA8 = xA9 = xAA = xAB = xAC = xAD = xAE = xAF = a(); + xB0 = xB1 = xB2 = xB3 = xB4 = xB5 = xB6 = xB7 = a(); + xB8 = xB9 = xBA = xBB = xBC = xBD = xBE = xBF = a(); + xC0 = xC1 = xC2 = xC3 = xC4 = xC5 = xC6 = xC7 = a(); + xC8 = xC9 = xCA = xCB = xCC = xCD = xCE = xCF = a(); + xD0 = xD1 = xD2 = xD3 = xD4 = xD5 = xD6 = xD7 = a(); + xD8 = xD9 = xDA = xDB = xDC = xDD = xDE = xDF = a(); + xE0 = xE1 = xE2 = xE3 = xE4 = xE5 = xE6 = xE7 = a(); + xE8 = xE9 = xEA = xEB = xEC = xED = xEE = xEF = a(); + xF0 = xF1 = xF2 = xF3 = xF4 = xF5 = xF6 = xF7 = a(); + xF8 = xF9 = xFA = xFB = xFC = xFD = xFE = xFF = a(); + } + + foo(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F, + x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F, + x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F, + x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F, + x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F, + x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F, + x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F, + x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F, + x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F, + x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F, + xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF, + xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF, + xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF, + xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF, + xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF, + xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7, xF8, xF9, xFA, xFB, xFC, xFD, xFE, xFF); + } +} + +f(); diff --git a/js/src/jit-test/tests/ion/bug1384737.js b/js/src/jit-test/tests/ion/bug1384737.js new file mode 100644 index 0000000000..7eb9630166 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1384737.js @@ -0,0 +1,8 @@ +function f(x) { + var count = 0; + for (var i = 0; i < x.length; ++i) + count++; + return count; +} +assertEq(f(Error()), 0); +assertEq(f([[]]), 1); diff --git a/js/src/jit-test/tests/ion/bug1394505.js b/js/src/jit-test/tests/ion/bug1394505.js new file mode 100644 index 0000000000..84979c046c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1394505.js @@ -0,0 +1,10 @@ +// |jit-test| skip-if: helperThreadCount() === 0 || !('oomTest' in this) + +for (let j = 0; j < 50; j++) { + if (j === 1) + oomTest(function() {}); + evalInWorker(` + for (let i = 0; i < 30; i++) + relazifyFunctions(); + `); +} diff --git a/js/src/jit-test/tests/ion/bug1395100.js b/js/src/jit-test/tests/ion/bug1395100.js new file mode 100644 index 0000000000..892ff7c12f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1395100.js @@ -0,0 +1,6 @@ +// |jit-test| --ion-eager; --no-threads; --arm-sim-icache-checks; --gc-zeal=14 +Object.getOwnPropertyNames(this); +for (var i = 0; i < 1; ++i) { + [Array]; + [ArrayBuffer]; +} diff --git a/js/src/jit-test/tests/ion/bug1397071.js b/js/src/jit-test/tests/ion/bug1397071.js new file mode 100644 index 0000000000..c6d290c84d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1397071.js @@ -0,0 +1,14 @@ +// |jit-test| --ion-limit-script-size=off +function f() { + var b1 = new ArrayBuffer(64); + for (var i = 0; i < 100; ++i) { + Object.defineProperty(b1, "x", { + configurable: true, + enumerable: true, + writable: true, + value: i + }); + assertEq(b1.x, i); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1401014.js b/js/src/jit-test/tests/ion/bug1401014.js new file mode 100644 index 0000000000..dd378948b0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1401014.js @@ -0,0 +1,52 @@ +// Prevent optimizing top-level +with ({}) { } + + +// Unboxed object constructor candidate +function Thing() { + this.a = {}; // Object || null + this.b = {}; // Object || null +} + +(new Thing()); +(new Thing()).a = null; +(new Thing()).b = null; + + +var arr = new Array(1000); +arr[0]; + +var ctx = new Thing(); + +function funPsh(t, x) { + t.a = x; +} + +function funBug(t, i) { + t.b = t.a; // GETPROP t.a + t.a = null; // SETPROP t.a + arr[i] = 0; // Bailout on uninitialized elements + return t.b; +} + +// Ion compile +for (var i = 0; i < 20000; ++i) { + funBug(ctx, 0); + funPsh(ctx, {}); +} + +// Invalidate +let tmp = { a: null, b: {} }; +funBug(tmp, 0); + +// Ion compile +for (var i = 0; i < 20000; ++i) { + funBug(ctx, 0); + funPsh(ctx, {}); +} + +// Trigger bailout +let res = funBug(ctx, 500); + +// Result should not be clobbered by |t.a = null| +assertEq(res === null, false); diff --git a/js/src/jit-test/tests/ion/bug1404636.js b/js/src/jit-test/tests/ion/bug1404636.js new file mode 100644 index 0000000000..c0652578ab --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1404636.js @@ -0,0 +1,6 @@ +x = new Uint32Array(4); +try { + Math.max(Uint32Array.prototype)(); +} catch (e) {} +x[3] = -1; +assertEq(x.toString(), "0,0,0,4294967295"); diff --git a/js/src/jit-test/tests/ion/bug1408412.js b/js/src/jit-test/tests/ion/bug1408412.js new file mode 100644 index 0000000000..a69749f9aa --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1408412.js @@ -0,0 +1,15 @@ +function g() { + return arguments.length; +} +function f() { + with(this) {}; + for (var i = 0; i < 100; i++) { + g(); + } + var s = "for (var j = 0; j < 1200; j++) assertEq(g("; + for (var i = 0; i < 5000; i++) + s += i + ","; + s += "1), 5001);"; + eval(s); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1410683.js b/js/src/jit-test/tests/ion/bug1410683.js new file mode 100644 index 0000000000..669662d4f9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1410683.js @@ -0,0 +1,17 @@ +class C {}; +C.prototype.a = "a"; +C.prototype.q = "q"; +C.prototype.NaN = NaN; +class D extends C { + foo(p) { + return super[p]; + } +} +function f() { + var d = new D(); + for (let p in C.prototype) { + assertEq(p, String(d.foo(p))); + } +} +f(); +f(); diff --git a/js/src/jit-test/tests/ion/bug1433496.js b/js/src/jit-test/tests/ion/bug1433496.js new file mode 100644 index 0000000000..e5ef04c8e0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1433496.js @@ -0,0 +1,6 @@ +// |jit-test| --spectre-mitigations=on; skip-if: getBuildConfiguration()['mips32'] || getBuildConfiguration()['mips64'] +function f() { + return arguments[arguments.length]; +} +for (var i = 0; i < 10; i++) + assertEq(f(), undefined); diff --git a/js/src/jit-test/tests/ion/bug1441012.js b/js/src/jit-test/tests/ion/bug1441012.js new file mode 100644 index 0000000000..de24e4a83f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1441012.js @@ -0,0 +1,14 @@ +if (getJitCompilerOptions()["ion.warmup.trigger"] > 30) + setJitCompilerOption("ion.warmup.trigger", 30); +function Iterate(items) { + for (var value of items) {} +} +var iterable = { + *[Symbol.iterator]() { + return "pass"; + (yield* iterable); + } +}; +for (var i = 0; i < 20; ++i) { + Iterate(iterable); +} diff --git a/js/src/jit-test/tests/ion/bug1450796.js b/js/src/jit-test/tests/ion/bug1450796.js new file mode 100644 index 0000000000..f004cfc955 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1450796.js @@ -0,0 +1,7 @@ +function f() { + var t = new Float32Array(1); + t[t.length] = 1; + return t[t.length]; +} +for (var i = 0; i < 5; i++) + assertEq(f(), undefined); diff --git a/js/src/jit-test/tests/ion/bug1452581.js b/js/src/jit-test/tests/ion/bug1452581.js new file mode 100644 index 0000000000..2836f4511e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1452581.js @@ -0,0 +1,16 @@ +// |jit-test| error:7 +var g = newGlobal({newCompartment: true}) +g.parent = this +g.eval("(" + function() { + Debugger(parent).onExceptionUnwind = function(frame) { + frame.older + } +} + ")()") +function f1(i) { + return f2(i|0); +}; +function f2(i) { + if (i === 0) throw 7; + return f1(i - 1); +} +f1(10); diff --git a/js/src/jit-test/tests/ion/bug1472132.js b/js/src/jit-test/tests/ion/bug1472132.js new file mode 100644 index 0000000000..025be31496 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1472132.js @@ -0,0 +1,11 @@ +function f() { + for (var i = 0; i < 1200; i++) { + var o1 = Reflect.construct(Array, [], Object); + var o2 = Reflect.construct(String, [""], Object); + var o3 = Reflect.construct(Int32Array, [0], Object); + assertEq(o1.__proto__, Object.prototype); + assertEq(o2.__proto__, Object.prototype); + assertEq(o3.__proto__, Object.prototype); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1473830.js b/js/src/jit-test/tests/ion/bug1473830.js new file mode 100644 index 0000000000..209b23a6c8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1473830.js @@ -0,0 +1,18 @@ + +y = []; +y.forEach(function() {}); + +x = []; +for (var i = 0; i < 100; ++i) { + x.push(undefined, 1); +} +x.sort(); +x.reverse(); + +x.forEach(function(j) { + "use strict"; + assertEq(this, 4); + if (j) { + x.forEach(function(z) { }); + } +}, 4);
\ No newline at end of file diff --git a/js/src/jit-test/tests/ion/bug1479394.js b/js/src/jit-test/tests/ion/bug1479394.js new file mode 100644 index 0000000000..ef33e35b20 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1479394.js @@ -0,0 +1,10 @@ +// |jit-test| skip-if: !('stackTest' in this) +var dbgGlobal = newGlobal({newCompartment: true}); +var dbg = new dbgGlobal.Debugger(this); +function f1() { + dbg.getNewestFrame().older; + throw new Error(); +} +function f2() { f1(); } +function f3() { f2(); } +stackTest(f3); diff --git a/js/src/jit-test/tests/ion/bug1484905.js b/js/src/jit-test/tests/ion/bug1484905.js new file mode 100644 index 0000000000..3a819ea815 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1484905.js @@ -0,0 +1,4 @@ +// |jit-test| --ion-limit-script-size=off; --ion-gvn=off +for (var i = 0; i < 1; ++i) { + "".replace(/x/, "").replace(/y/, "12"); +} diff --git a/js/src/jit-test/tests/ion/bug1492574.js b/js/src/jit-test/tests/ion/bug1492574.js new file mode 100644 index 0000000000..c1ce0c000a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1492574.js @@ -0,0 +1,18 @@ +// |jit-test| skip-if: !('oomTest' in this) + +function foo() {} +function foooooooooooooooooooooooooooooooo() {} +function fn(s) { + var o = {a:1} + eval(("f" + s) + "()"); + if (!('a' in o)) { + print("unreachable"); + } +} +for (var i = 0; i < 1100; i++) { + fn("oo"); +} +oomTest(new Function(` + let a = newRope("oooooooooooooooo","oooooooooooooooo"); + fn(a); +`)) diff --git a/js/src/jit-test/tests/ion/bug1493900-1.js b/js/src/jit-test/tests/ion/bug1493900-1.js new file mode 100644 index 0000000000..643c1943d6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1493900-1.js @@ -0,0 +1,17 @@ +function f() { + var objs = []; + for (var i = 0; i < 100; i++) { + objs[i] = {}; + } + var o = objs[0]; + var a = new Float64Array(1024); + function g(a, b) { + let p = b; + for (; p.x < 0; p = p.x) { + while (p === p) {} + } + for (var i = 0; i < 10000; ++i) {} + } + g(a, o); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1493900-2.js b/js/src/jit-test/tests/ion/bug1493900-2.js new file mode 100644 index 0000000000..7e7f5fdecd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1493900-2.js @@ -0,0 +1,7 @@ +function f(a, b) { + for (; b.x < 0; b = b.x) { + while (b === b) {}; + } + for (var i = 0; i < 99999; ++i) {} +} +f(0, 0); diff --git a/js/src/jit-test/tests/ion/bug1497107.js b/js/src/jit-test/tests/ion/bug1497107.js new file mode 100644 index 0000000000..c3c4942f88 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1497107.js @@ -0,0 +1,37 @@ +function makeChain(n, base) { + var curr = base; + for (var i = 0; i < n; i++) { + curr = Object.create(curr); + var propname = "level" + i; + curr[propname] = true; + } + return curr; +} + +function BaseClass() { + this.base = true; +} + +Object.defineProperty(BaseClass.prototype, "getter", {get: function() { with({}){}; return this.base; }}); + +function victim(arg) { + if (arg.getter) { + return 3; + } else { + return 4; + } +} + +let root = new BaseClass(); +let chains = []; +for (var i = 0; i < 6; i++) { + chains.push(makeChain(500, root)); +} + +with({}){}; +for (var i = 0; i < 1000 / 6; i++) { + with({}){}; + for (var j = 0; j < chains.length; j++) { + victim(chains[j]); + } +} diff --git a/js/src/jit-test/tests/ion/bug1502090.js b/js/src/jit-test/tests/ion/bug1502090.js new file mode 100644 index 0000000000..c7638e7e73 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1502090.js @@ -0,0 +1,13 @@ +function f(o) { + var a = [o]; + a.length = a[0]; + var useless = function() {} + var sz = Array.prototype.push.call(a, 42, 43); + (function(){ + sz; + })(new Boolean(false)); +} +for (var i = 0; i < 2; i++) { + f(1); +} +f(2); diff --git a/js/src/jit-test/tests/ion/bug1506968.js b/js/src/jit-test/tests/ion/bug1506968.js new file mode 100644 index 0000000000..2dadb1ccda --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1506968.js @@ -0,0 +1,14 @@ +// |jit-test| skip-if: typeof Intl === 'undefined' +function f(a, b) { + a.formatToParts(); + a.format(); +} +var a = new Intl.NumberFormat(); +f(a, []); +try { + f(); +} catch (e) {} +f(a, []); +try { + f(); +} catch (e) {} diff --git a/js/src/jit-test/tests/ion/bug1509482.js b/js/src/jit-test/tests/ion/bug1509482.js new file mode 100644 index 0000000000..26bda3b544 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1509482.js @@ -0,0 +1,18 @@ +let singleton = {x: 1}; + +let holder = {sing_prop: singleton} + +function makeChain(n, base) { + var curr = base; + for (var i = 0; i < n; i++) { + curr = Object.create(curr); + } + return curr; +} +let chain = makeChain(1000, holder); + +var x = 0; +for (var i = 0; i < 1111; i++) { + x += chain.sing_prop.x; + singleton.x = -singleton.x // Don't want it to be a constant. +} diff --git a/js/src/jit-test/tests/ion/bug1510684.js b/js/src/jit-test/tests/ion/bug1510684.js new file mode 100644 index 0000000000..514b934f32 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1510684.js @@ -0,0 +1,38 @@ +var verified = false; +function f(a) { + if (a < 10000) + return 5; + assertEq(g_fwd.caller.arguments.length, 0); + assertEq(h_fwd.caller.arguments.length, 0); + verified = true; + return 6; +} + +function g_fwd(x) { + with({}) {}; + return f(x); +} +function g(a) { + var x = a; + function inline() { + return g_fwd(x); + } + return inline(); +} + +function h_fwd(x) { + with({}) {}; + return g(x); +} +function h(a) { + var x = a; + function inline() { + return h_fwd(x); + } + return inline(); +} + +var i = 0; +while (!verified) { + h(i++); +} diff --git a/js/src/jit-test/tests/ion/bug1514625.js b/js/src/jit-test/tests/ion/bug1514625.js new file mode 100644 index 0000000000..4f4e27e864 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1514625.js @@ -0,0 +1,11 @@ +var i = 0; +evaluate(""); +while (--i >= 0) { + if (x > 0) { + continue; + } + switch (i) { + default: + i(i); + } +} diff --git a/js/src/jit-test/tests/ion/bug1518377-1.js b/js/src/jit-test/tests/ion/bug1518377-1.js new file mode 100644 index 0000000000..fc2869efc0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1518377-1.js @@ -0,0 +1,7 @@ +Object.prototype[Symbol.toPrimitive] = inIon; +which = function() {}; +for (var i = 0; i < 10; ++i) { + s = which[which[which]]; + a = which; + a += s + ""; +} diff --git a/js/src/jit-test/tests/ion/bug1518377-2.js b/js/src/jit-test/tests/ion/bug1518377-2.js new file mode 100644 index 0000000000..91902b20bf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1518377-2.js @@ -0,0 +1,16 @@ +g = (function(t, foreign) { + "use asm"; + var ff = foreign.ff; + function f() { ff() } + return f +})(this, { + ff: -0 || (this) ? inIon : a &= () => test() +}) + +function m(f) { + for (var i = 0; i < 100; ++i) { + f(); + } +} + +m(g); diff --git a/js/src/jit-test/tests/ion/bug1526840.js b/js/src/jit-test/tests/ion/bug1526840.js new file mode 100644 index 0000000000..08f1ec64ae --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1526840.js @@ -0,0 +1,13 @@ + +setJitCompilerOption("offthread-compilation.enable", 0); +setJitCompilerOption("baseline.warmup.trigger", 0); +setJitCompilerOption("ion.warmup.trigger", 0); + +for (let j = 0; j < 2; ++j) { + let z = j ? 0n : 1; + if (z) { + z = 0; + } else { + z = 0; + } +} diff --git a/js/src/jit-test/tests/ion/bug1527148.js b/js/src/jit-test/tests/ion/bug1527148.js new file mode 100644 index 0000000000..509dbb90b5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1527148.js @@ -0,0 +1,17 @@ +var log = ""; +function g() { + var x = []; + for (var k = 0; k < 2; ++k) { + x.push(k); + } + log += x; +} +for (var i = 0; i < 1; i++) { + f = function() {}; +} +g(); +Array.prototype.push = f; +g(); +f.__proto__ = []; +g(); +assertEq(log, "0,1"); diff --git a/js/src/jit-test/tests/ion/bug1528818.js b/js/src/jit-test/tests/ion/bug1528818.js new file mode 100644 index 0000000000..3a49e3f468 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1528818.js @@ -0,0 +1,11 @@ +function getarg(x) { + return arguments[x] +} +function f() { + var r = 0n; + for (var i=0;i<2000;++i) { + r += getarg(1+(i & 1), BigInt(0), 1n); + } + return r; +} +for (var i=0;i<2;++i) print(f()) diff --git a/js/src/jit-test/tests/ion/bug1538083.js b/js/src/jit-test/tests/ion/bug1538083.js new file mode 100644 index 0000000000..424c7fe1ef --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1538083.js @@ -0,0 +1,8 @@ +// Crashes with --no-threads --ion-eager. +x = [8589934592, -0]; +y = [0, 0]; +for (let i = 0; i < 2; ++i) { + y[i] = Math.trunc(Math.tan(x[i])); +} +assertEq(Object.is(y[0], 1), true); +assertEq(Object.is(y[1], -0), true); diff --git a/js/src/jit-test/tests/ion/bug1543166.js b/js/src/jit-test/tests/ion/bug1543166.js new file mode 100644 index 0000000000..ea67400c2b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1543166.js @@ -0,0 +1,17 @@ +function f() { + var arr = []; + for (var i = 0; i < 12; i++) { + // Create a new global to get "DOM" objects with different groups. + var g = newGlobal(); + var o = new g.FakeDOMObject(); + o[0] = 1; + arr.push(o); + } + var res; + for (var i = 0; i < 2000; i++) { + var o = arr[i % arr.length]; + res = o[0]; + } + return res; +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1544386-1.js b/js/src/jit-test/tests/ion/bug1544386-1.js new file mode 100644 index 0000000000..f78cba11f0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1544386-1.js @@ -0,0 +1,16 @@ +const arr = [{a: 0}, {a: 1}, {a: 2}, {a: 3}, {a: 4}]; +function f() { + if (arr.length == 0) { + arr[3] = {a: 5}; + } + var v = arr.pop(); + v.a; + for (var i = 0; i < 3000; i++) {} +} +var p = {}; +p.__proto__ = [{a: 0}, {a: 1}, {a: 2}]; +p[0] = -1.8629373288622089e-06; +arr.__proto__ = p; +for (var i = 0; i < 10; i++) { + f(); +} diff --git a/js/src/jit-test/tests/ion/bug1544386-2.js b/js/src/jit-test/tests/ion/bug1544386-2.js new file mode 100644 index 0000000000..69c3bad799 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1544386-2.js @@ -0,0 +1,10 @@ +x = []; +x.unshift(4, 8); +y = []; +relazifyFunctions(); +y[3] = 9; +y.__proto__ = x; +for (var i = 0; i < 2; ++i) { + y.shift(); +} +assertEq(y[0], 8); diff --git a/js/src/jit-test/tests/ion/bug1544792.js b/js/src/jit-test/tests/ion/bug1544792.js new file mode 100644 index 0000000000..b9bea59615 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1544792.js @@ -0,0 +1,13 @@ +var res = undefined; +function X() { + try { + foobar(); + } catch (e) { + res = this.hasOwnProperty("prop"); + } + this.prop = 1; +} +for (var i = 0; i < 50; i++) { + new X(); + assertEq(res, false); +} diff --git a/js/src/jit-test/tests/ion/bug1546228.js b/js/src/jit-test/tests/ion/bug1546228.js new file mode 100644 index 0000000000..35814a32e9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1546228.js @@ -0,0 +1,10 @@ +function Obj() { + this.a = 1; +} +Obj.prototype = this; + +function test() { + return o.a; +} +var o = new Obj(); +test(); diff --git a/js/src/jit-test/tests/ion/bug1556571.js b/js/src/jit-test/tests/ion/bug1556571.js new file mode 100644 index 0000000000..b1d69788ca --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1556571.js @@ -0,0 +1,14 @@ +// Ensure that convertDoubleToInt32 allows the -0 case. + +// If convertDoubleToInt32 fails on the -0 case, then 0 !== -0 below, +// so it will fall through to the default case. +function test(v) { + switch(v) { + case 0: return; + default: assertEq(true, false); break; + } +} + +for (var i = 0; i < 10000; i++) { + test(i % 2 === 0 ? 0 : -0); +} diff --git a/js/src/jit-test/tests/ion/bug1568397.js b/js/src/jit-test/tests/ion/bug1568397.js new file mode 100644 index 0000000000..c03bb0283d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1568397.js @@ -0,0 +1,50 @@ +// |jit-test| error:TypeError: can't access property +let obj = {x: 1}; +obj.x = 1.1; + +function Foo(val, phase){ + if (phase == 3) { + // Phase 3: Modify the prototype of this constructor. + Foo.prototype.__proto__ = proto; + } + + // Phase 4: Trigger the getter on the new proto. + this.d; + + this.c = val; + + if (phase == 2) { + // Phase 2: Stash |this| in a global variable. + g_partial = this; + + // Trigger Phase 3. + new Foo(1.1, 3); + } + this.b = 2.2; +} + +let proto = {get d() { + function accessC(arg){ + var tmp = arg.c; + return tmp.x; + } + + // Phase 5: Ion-compile |accessC|, using the stashed |this| from phase 2. + // This is a partially initialized object with a C property but not a B + // property. + for (var i = 0; i < 100000; i++) { + accessC(g_partial); + } + + // Phase 6: call |accessC| with |this|, which is a partially initialized + // object *without* a C (and B) property. + x = accessC(this); +}}; + +// Phase 1: Warm up the |Foo| constructor with normal data. +for(let i = 0;i < 100;i++){ + new Foo(obj, 1); +} + +// Trigger Phase 2. +new Foo(obj, 2); diff --git a/js/src/jit-test/tests/ion/bug1570926.js b/js/src/jit-test/tests/ion/bug1570926.js new file mode 100644 index 0000000000..7af36aa4ba --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1570926.js @@ -0,0 +1,18 @@ +if (getJitCompilerOptions()["baseline.warmup.trigger"] > 10) { + setJitCompilerOption("baseline.warmup.trigger", 10); +} +if (getJitCompilerOptions()["ion.warmup.trigger"] > 20) { + setJitCompilerOption("ion.warmup.trigger", 20); +} +setJitCompilerOption("offthread-compilation.enable", 0); + +var arr = [1, 2, 3, 4, 5]; +function f(x) { + for (var i = x; i < 5; i++) { + arr[i - 2]; + } +} +for (var i = 0; i < 15; i++) { + f(2); +} +assertEq(f(0), undefined); diff --git a/js/src/jit-test/tests/ion/bug1572051.js b/js/src/jit-test/tests/ion/bug1572051.js new file mode 100644 index 0000000000..cb897e9aad --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1572051.js @@ -0,0 +1,6 @@ +evaluate(` + for (var i = 0; i < 2000; i++) { + Array(Math, {}); + bailout(); + } +`); diff --git a/js/src/jit-test/tests/ion/bug1593175.js b/js/src/jit-test/tests/ion/bug1593175.js new file mode 100644 index 0000000000..ef3d8d601f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1593175.js @@ -0,0 +1,10 @@ +function f() { + f; +} +f(); +f(); +function g() { + typeof(f = []) + f > 2; +} +g(); +g(); diff --git a/js/src/jit-test/tests/ion/bug1598456.js b/js/src/jit-test/tests/ion/bug1598456.js new file mode 100644 index 0000000000..c4f7f96c1b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1598456.js @@ -0,0 +1,3 @@ +(function() { + if (arguments) {} +})(); diff --git a/js/src/jit-test/tests/ion/bug1598784.js b/js/src/jit-test/tests/ion/bug1598784.js new file mode 100644 index 0000000000..20803e2f09 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1598784.js @@ -0,0 +1,8 @@ +// |jit-test| error:ReferenceError +(function() { + switch (0) { + case 0: + f() = 0; + case -3: + } +})(); diff --git a/js/src/jit-test/tests/ion/bug1602190.js b/js/src/jit-test/tests/ion/bug1602190.js new file mode 100644 index 0000000000..fbd2ed6551 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1602190.js @@ -0,0 +1,13 @@ +function g(x) { + var z = true; + return (x ? 0.1 : (z ? Math.fround(1) : NaN)); +} +function f() { + var arr = [1]; + for (var i = 0; i < 550; ++i) { + for (var j = 0; j < 2; ++j) { + assertEq(g(arr[j]), j ? 1 : 0.1); + } + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1604631.js b/js/src/jit-test/tests/ion/bug1604631.js new file mode 100644 index 0000000000..bc7e7e4ca9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1604631.js @@ -0,0 +1,4 @@ +// |jit-test| error:can't access lexical declaration +x = []; +x.length; +evaluate("x.length; let x = 1"); diff --git a/js/src/jit-test/tests/ion/bug1605641.js b/js/src/jit-test/tests/ion/bug1605641.js new file mode 100644 index 0000000000..e8eded6a9b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1605641.js @@ -0,0 +1,8 @@ +// |jit-test| error:9 +function thrower() { + throw 9; +} +function f() { + return [...{} [thrower(...["foo"])]] = "undefined"; +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1607670-1.js b/js/src/jit-test/tests/ion/bug1607670-1.js new file mode 100644 index 0000000000..edab65959e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1607670-1.js @@ -0,0 +1,13 @@ +// Test written by André Bargull for bug 1380953. +var q = 0; +function fn() {} +var newTarget = Object.defineProperty(fn.bind(), "prototype", { + get() { + ++q; + return null; + } +}); +for (var i = 0; i < 100; ++i) { + Reflect.construct(fn, [], newTarget); +} +assertEq(q, 100); diff --git a/js/src/jit-test/tests/ion/bug1607670-2.js b/js/src/jit-test/tests/ion/bug1607670-2.js new file mode 100644 index 0000000000..9488fbf3ca --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1607670-2.js @@ -0,0 +1,15 @@ +function inner(X, T) { + return Reflect.construct(X, [], T); +} +function F() {} + +let handler = {}; +let P = new Proxy(F, handler); + +for (var i = 0; i < 2000; i += 1) { + with ({}) {} + inner(F, P); +} + +handler.get = function() {} +inner(F, P); diff --git a/js/src/jit-test/tests/ion/bug1607670-3.js b/js/src/jit-test/tests/ion/bug1607670-3.js new file mode 100644 index 0000000000..aaecb9cc8f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1607670-3.js @@ -0,0 +1,24 @@ +let c = 0; +function f1() { + c++; +} +function LoggingProxyHandlerWrapper(name, handler={}) { + return new Proxy(handler, { + get(x, id) { + return function (...args) { + return Reflect[id].apply(null, args); + }; + } + }); +} +function LoggingProxy(name, target) { + return new Proxy(f1, new LoggingProxyHandlerWrapper(name)); +} +function test() { + let proxy = new LoggingProxy("proto", {}); + for (let i = 0; i < 2000; i++) { + new proxy(); + } + assertEq(c, 2000); +} +test(); diff --git a/js/src/jit-test/tests/ion/bug1607670-4.js b/js/src/jit-test/tests/ion/bug1607670-4.js new file mode 100644 index 0000000000..de115bc531 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1607670-4.js @@ -0,0 +1,16 @@ +function F() {} +function G() {} + +function f() { + for (var i = 0; i < 10000; ++i) { + var o = Reflect.construct(F, []); + assertEq(Object.getPrototypeOf(o), F.prototype); + } + + for (var i = 0; i < 10000; ++i) { + var o = Reflect.construct(F, [], G); + assertEq(Object.getPrototypeOf(o), G.prototype); + } +} + +for (var i = 0; i < 2; ++i) f(); diff --git a/js/src/jit-test/tests/ion/bug1608256.js b/js/src/jit-test/tests/ion/bug1608256.js new file mode 100644 index 0000000000..4445a41157 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1608256.js @@ -0,0 +1,13 @@ +// |jit-test| --no-threads; --baseline-warmup-threshold=1; --ion-full-warmup-threshold=1 +function g(obj, v) { + obj.prop = v; +} +function f() { + var obj = {prop: 2}; + for (var j = 0; j < 20; j++) {} + for (var i = 0; i < 100; i++) { + g(/x/, 1); + g(obj, false); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1620215.js b/js/src/jit-test/tests/ion/bug1620215.js new file mode 100644 index 0000000000..70b95ca630 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1620215.js @@ -0,0 +1,15 @@ +function test(x) { + for (var i = 0; i < 10; ++i) { + // Create an IC specialized for lazy arguments when Baseline runs. + arguments[0]; + // De-optimize lazy arguments by accessing an out-of-bounds argument. + arguments[10]; + + // Overwrite |arguments| to get a Value type. + arguments = 0; + + for (var j = 0; j < 1500; j++) {} + return; + } +} +test(1); diff --git a/js/src/jit-test/tests/ion/bug1621268-1.js b/js/src/jit-test/tests/ion/bug1621268-1.js new file mode 100644 index 0000000000..940b358696 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1621268-1.js @@ -0,0 +1,9 @@ +// |jit-test| error:ReferenceError: can't access lexical declaration +function f() { + for (let x of [1]) { + let y = new Date(x); + `Cannot parse "${x}"`; + let x; + } +} +f();
\ No newline at end of file diff --git a/js/src/jit-test/tests/ion/bug1621268-2.js b/js/src/jit-test/tests/ion/bug1621268-2.js new file mode 100644 index 0000000000..1788a75c10 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1621268-2.js @@ -0,0 +1,6 @@ +function f() { + for (const x of []) { + for (let y of [y, y]) {} + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1629503-1.js b/js/src/jit-test/tests/ion/bug1629503-1.js new file mode 100644 index 0000000000..06508e7487 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1629503-1.js @@ -0,0 +1,13 @@ +// |jit-test| error: TypeError: invalid assignment to const +function f() { + const g = newGlobal({newCompartment: true}); + const dbg = new Debugger(g); + g.eval(`function f() {}`); + dbg.onEnterFrame = function(frame) { + [x, dbg] = []; + } + for (var i = 0; i < 5; i++) { + g.eval("f()"); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1629503-2.js b/js/src/jit-test/tests/ion/bug1629503-2.js new file mode 100644 index 0000000000..a51e7fced5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1629503-2.js @@ -0,0 +1,10 @@ +// |jit-test| error: TypeError: invalid assignment to const +function f() { + const x60 = [0, 1]; + const y81 = [...x60]; + { + const x60 = [0, 1]; + [...x60] = [42]; + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1640737.js b/js/src/jit-test/tests/ion/bug1640737.js new file mode 100644 index 0000000000..9a1609a283 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1640737.js @@ -0,0 +1,17 @@ +function g(arr) { + var res = []; + for (var i = 0; i < arr.length; i++) { + var el = arr[i]; + res.push(el); + } + return res; +} +function f() { + for (var i = 0; i < 2; i++) { + var obj = {__proto__: []}; + for (var j = 0; j < 1500; j++) { + g([13.37, obj]); + } + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug1650526.js b/js/src/jit-test/tests/ion/bug1650526.js new file mode 100644 index 0000000000..69934cf111 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1650526.js @@ -0,0 +1,9 @@ +for (let i = 0; i < 2; ++i) { + // Alternate between even and odd values. + let power = 1000 + i; + + // Math.pow(negative-int, large-negative-value) is +0 for even and -0 for odd values. + let expected = (power & 1) === 0 ? +0 : -0; + + assertEq(Math.pow(-3, -power), expected); +} diff --git a/js/src/jit-test/tests/ion/bug1655940-1.js b/js/src/jit-test/tests/ion/bug1655940-1.js new file mode 100644 index 0000000000..34880823cc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1655940-1.js @@ -0,0 +1,14 @@ +function f(t) { + for (var i = 0; i < 2; i++) { + try { + var x = 1; + new Int32Array(1); + x = 2; + new Int32Array(t); + } catch (e) { + assertEq(x, 2); + } + } +} +f(1); +f(-1); diff --git a/js/src/jit-test/tests/ion/bug1655940-2.js b/js/src/jit-test/tests/ion/bug1655940-2.js new file mode 100644 index 0000000000..d24a065f5f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1655940-2.js @@ -0,0 +1,15 @@ +function f(t) { + for (var i = 0; i < 2; i++) { + try { + var x = 1; + var {} = {}; + x = 2; + var {} = t; + } catch (e) { + assertEq(x, 2); + } + } +} +for (var t of [{}, null]) { + f(t); +} diff --git a/js/src/jit-test/tests/ion/bug1655940-3.js b/js/src/jit-test/tests/ion/bug1655940-3.js new file mode 100644 index 0000000000..a9d984dd68 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1655940-3.js @@ -0,0 +1,21 @@ +var ToObject = getSelfHostedValue("ToObject"); + +function f(arr) { + for (var i = 0; i < arr.length; i++) { + var v = arr[i]; + try { + var x = 1; + ToObject({}); + x = 2; + ToObject(v); + } catch (e) { + assertEq(x, 2); + } + } +} + +var a = []; +for (var i = 0; i < 50; i++) { + a.push({}, null); +} +f(a); diff --git a/js/src/jit-test/tests/ion/bug470143.js b/js/src/jit-test/tests/ion/bug470143.js new file mode 100644 index 0000000000..0b63d4f0a4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug470143.js @@ -0,0 +1,6 @@ +// Test that getname caches correctly handle typeof for missing names. +function f() { for (i = 0; i < 2000; ++i) { var k = typeof nosuchvar; } return k; } + +assertEq(f(), "undefined"); +this.nosuchvar = 5; +assertEq(f(), "number"); diff --git a/js/src/jit-test/tests/ion/bug669575-1.js b/js/src/jit-test/tests/ion/bug669575-1.js new file mode 100644 index 0000000000..bf0e05060a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug669575-1.js @@ -0,0 +1,25 @@ +function loopy(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31) { + var v2 = p2; + var v3 = p3; + var v5 = p5; + var v8 = p8; + var v10 = p10; + var v12 = p12; + var v14 = p14; + var v17 = p17; + var v18 = p18; + var v23 = p23; + var v26 = p26; + var v30 = p30; + while (v17) { + while (v5) { + v18 = v10 & v2; + v3 = v23 & v30; + } + while (v12) { + v23 = v26 & v14; + v5 = v8 & v26; + } + } +} +loopy(415,766,601,654,700,0,644,737,873,131,452,247,0,517,202,565,722,0,197,884,586,961,321,922,745,593,648,896,404,206,792,473) diff --git a/js/src/jit-test/tests/ion/bug669575-2.js b/js/src/jit-test/tests/ion/bug669575-2.js new file mode 100644 index 0000000000..d61e992039 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug669575-2.js @@ -0,0 +1,27 @@ +function loopy(p0) +{ + var r1 = p0; + var r2 = p0; + var r3 = p0; + var r4 = p0; + var r5 = p0; + var r6 = p0; + var r7 = p0; + + while (r2) { + while (r2) { + r1 = r4; + r5 = r6 & r1; + r3 = r4 & r3; + } + while (r2) { + r6 = r2; + r3 = r7; + } + } + + return 0; +} +loopy(0); + + diff --git a/js/src/jit-test/tests/ion/bug669575-3.js b/js/src/jit-test/tests/ion/bug669575-3.js new file mode 100644 index 0000000000..d8ad34ffbd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug669575-3.js @@ -0,0 +1,25 @@ +function loopy(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31) { + var v1 = p1; + var v2 = p2; + var v15 = p15; + var v16 = p16; + var v18 = p18; + var v20 = p20; + var v22 = p22; + var v23 = p23; + var v24 = p24; + var v26 = p26; + var v28 = p28; + var v30 = p30; + while (v30) { + while (v2) { + v20 = v23 & v24; + v18 = v2 & v22; + } + while (v26) { + v15 = v1 & v16; + v1 = v28 & v22; + } + } +} +loopy(415,766,0,654,700,132,644,737,873,131,452,247,185,517,202,565,722,991,197,884,586,961,321,922,745,593,0,896,404,206,0,473) diff --git a/js/src/jit-test/tests/ion/bug669950.js b/js/src/jit-test/tests/ion/bug669950.js new file mode 100644 index 0000000000..90d133ca70 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug669950.js @@ -0,0 +1,3 @@ +(function () { + var x = true ? 1 : 2; +})(); diff --git a/js/src/jit-test/tests/ion/bug670484.js b/js/src/jit-test/tests/ion/bug670484.js new file mode 100644 index 0000000000..81422f02f7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug670484.js @@ -0,0 +1,101 @@ +// Call a function with no arguments. +function a_g() { + return 5; +} + +function a_f(g) { + return g(); +} + +a_g(); +assertEq(a_f(a_g), 5); + +/////////////////////////////////////////////////////////////////////////////// +// Call a function with one argument. +function b_g(a) { + return a; +} + +function b_f(h,b) { + return h(5); +} +b_g(5); +assertEq(b_f(b_g,4), 5); + +/////////////////////////////////////////////////////////////////////////////// +// Try to confuse the register allocator. +function c_g(a) { + return a; +} +function c_f(h,b) { + var x = h(5); + var y = x + 1; + var z = h(h(y + x + 2)); + var k = 2 + z + 3; + return h(h(h(k))); +} +c_g(2); // prime g(). +assertEq(c_f(c_g,7), 18) + +/////////////////////////////////////////////////////////////////////////////// +// Fail during unboxing, get kicked to interpreter. +// Interpreter throws an exception; handle it. + +function d_f(a) { + return a(); // Call a known non-object. This fails in unboxing. +} +var d_x = 0; +try { + d_f(1); // Don't assert. +} catch(e) { + d_x = 1; +} +assertEq(d_x, 1); + +/////////////////////////////////////////////////////////////////////////////// +// Try passing an uncompiled function. + +function e_uncompiled(a,b,c) { + return eval("b"); +} +function e_f(h) { + return h(0,h(2,4,6),1); +} +assertEq(e_f(e_uncompiled),4); + +/////////////////////////////////////////////////////////////////////////////// +// Try passing a native function. + +function f_app(f,n) { + return f(n); +} +assertEq(f_app(Math.sqrt, 16), 4); + +/////////////////////////////////////////////////////////////////////////////// +// Handle the case where too few arguments are passed. +function g_g(a,b,c,d,e) { + return e; +} + +function g_f(g) { + return g(2); +} + +g_g(); +assertEq(g_f(g_g), undefined); + +/////////////////////////////////////////////////////////////////////////////// +// Don't assert when given a non-function object. +function h_f(a) { + return a(); +} + +var x = new Object(); +var h_ret = 0; +try { + h_f(x); // don't assert. +} catch (e) { + h_ret = 1; +} +assertEq(h_ret, 1); + diff --git a/js/src/jit-test/tests/ion/bug674507-1.js b/js/src/jit-test/tests/ion/bug674507-1.js new file mode 100644 index 0000000000..c13f4e376d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug674507-1.js @@ -0,0 +1,19 @@ +function branchy(v0,v1) { + var result = 0; + if (v0) { + if (v0 & v0) { + if (v1 & v0) { + } else { + result = v0 & v0 & v1; + } + } else { + if (v0 & v0 & v0) { + result = v1; + } + } + } else { + if (v0 & v1 & v0) { } + } + return result; +} +branchy(932,256,368) diff --git a/js/src/jit-test/tests/ion/bug674507-2.js b/js/src/jit-test/tests/ion/bug674507-2.js new file mode 100644 index 0000000000..457397922a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug674507-2.js @@ -0,0 +1,20 @@ +timeout(5); +function f0(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9) { + var v0; + var v1; + do { + if (p1) { + break; + continue; + } else { + } + v0 = (p0 | p7); + } while (v0); + if (((p5 + p3) + (p3 & (v0 | v0)))) { + v1 = p6; + v1 = p4; + v0 = (v1 ^ v1); + (v0 + ((v0 & p5) | v0)); + } +} +f0(2204,465,7905,3902,4658,4110,5703,2199,2681,5291); diff --git a/js/src/jit-test/tests/ion/bug674656.js b/js/src/jit-test/tests/ion/bug674656.js new file mode 100644 index 0000000000..8a19fd8e7f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug674656.js @@ -0,0 +1,21 @@ +timeout(1); +function f0(p0) { + var v0; + var v1; + var v2; + while (v0) { + do { + if (p0) { + if (v0 ^ p0) { + v1 = v2; + continue; + } + break; + } + } while (p0); + } +} +f0(0); + +/* Don't assert */ + diff --git a/js/src/jit-test/tests/ion/bug674664-1.js b/js/src/jit-test/tests/ion/bug674664-1.js new file mode 100644 index 0000000000..2408f631e1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug674664-1.js @@ -0,0 +1,17 @@ +timeout(5); +function f0() { + var v0; + v0 = v0; + v0 = v0; + v0; + while ((v0 + v0)) { + v0 = (v0 | v0); + } + v0 = (v0 + (v0 + ((v0 + ((v0 ^ v0) & (v0 | v0))) + v0))); + while (v0) { + v0 = v0; + break; + } +} +f0(); + diff --git a/js/src/jit-test/tests/ion/bug674664-2.js b/js/src/jit-test/tests/ion/bug674664-2.js new file mode 100644 index 0000000000..d2e0474574 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug674664-2.js @@ -0,0 +1,35 @@ +timeout(5); +function f0(p0,p1,p2,p3,p4,p5,p6,p7,p8) { + var v0; + p0; + v0 = p8; + if (v0) { + v0; + v0 = (p5 ^ (p2 ^ p6)); + if (p1) { + } else { + v0 = (((v0 & p6) ^ v0) + (v0 | p3)); + } + ((v0 + v0) + v0); + (v0 + ((p1 + ((v0 & v0) & p1)) & v0)); + p4; + p2; + v0 = v0; + } + p4; + while ((v0 ^ p0)) { + break; + (v0 ^ (p1 + p4)); + continue; + v0; + } + v0; + do { + continue; + v0 = p5; + break; + } while (v0); + v0 = v0; +} +f0(0,5695,59,475,4562,6803,6440,6004,0); + diff --git a/js/src/jit-test/tests/ion/bug674664-3.js b/js/src/jit-test/tests/ion/bug674664-3.js new file mode 100644 index 0000000000..ce5a828d57 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug674664-3.js @@ -0,0 +1,10 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +function f0(p0) { + var v0; + do { + v0 = p0; + } while (v0); + if (v0 & p0) + v0 = (p0 & v0); +} +f0(0); diff --git a/js/src/jit-test/tests/ion/bug674694.js b/js/src/jit-test/tests/ion/bug674694.js new file mode 100644 index 0000000000..cbe5afe809 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug674694.js @@ -0,0 +1,63 @@ +// Don't assert in the type analyzer. +timeout(5); +function f0(p0,p1,p2,p3) { + var v0; + var v1; + var v2; + var v3; + var v4; + var v5; + var v6; + do { + continue; + } while ((v1 ^ p2)); + if (v5) { + p3; + while (p2) { + p0; + if (p2) { + } else { + break; + v3 = p0; + } + p0; + break; + while (((v3 & v0) | p2)) { + if (p2) { + break; + } + } + } + } else { + v2 = p1; + v3 = p2; + v4; + ((p3 | p3) + (v1 + p1)); + } + v6 = (p0 + p3); + v3 = v3; + v2 = v1; + while (((v3 & p0) + v1)) { + v6 = (v5 + p1); + while (((p3 + (v4 + v3)) + v6)) { + v6 = (v2 | (v1 + (v0 | v2))); + break; + v3 = p0; + v0; + } + do { + while (p2) { + } + v3 = p0; + do { + v2 = v5; + } while (p2); + continue; + } while ((((p2 & p2) & p0) + p2)); + v2 = p0; + v5 = v1; + } + v6 = (v4 & (v5 + v5)); +} +f0(0,0,0,0); + diff --git a/js/src/jit-test/tests/ion/bug675381.js b/js/src/jit-test/tests/ion/bug675381.js new file mode 100644 index 0000000000..30f987bad2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug675381.js @@ -0,0 +1,17 @@ +function f0(p0,p1) { + var v0; + var v1; + while (p0) { + if (p0) { + v1 = v0 + p0; + v0 = v1; + } + v0 = p1; + if (v1) { + while (v1); + break; + } + } +} +f0(); +/* Don't assert. */ diff --git a/js/src/jit-test/tests/ion/bug677066-2.js b/js/src/jit-test/tests/ion/bug677066-2.js new file mode 100644 index 0000000000..14267cda2c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677066-2.js @@ -0,0 +1,7 @@ +function f0(p0) { + var v0; + if (v0) + v0 = p0; + return v0; +} +assertEq(f0(0), undefined); diff --git a/js/src/jit-test/tests/ion/bug677066.js b/js/src/jit-test/tests/ion/bug677066.js new file mode 100644 index 0000000000..8b4a44c478 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677066.js @@ -0,0 +1,9 @@ +function f0() { + var v0 = 1; + if (v0 | 0) { + } else { + v0 = v0 + v0; + } + return v0; +} +assertEq(f0(), 1); diff --git a/js/src/jit-test/tests/ion/bug677073-2.js b/js/src/jit-test/tests/ion/bug677073-2.js new file mode 100644 index 0000000000..48ac1bbe90 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677073-2.js @@ -0,0 +1,11 @@ +// Don't assert. +function f0() { + var v0; + var v1; + while (v1) { + v1 = v0 + v1; + v0 = v1 + v1; + } + return v0; +} +assertEq(f0(), undefined); diff --git a/js/src/jit-test/tests/ion/bug677073.js b/js/src/jit-test/tests/ion/bug677073.js new file mode 100644 index 0000000000..df308b6a81 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677073.js @@ -0,0 +1,9 @@ +// Don't assert. +function a(p0) { + var x = 0; + if (p0|0) { + x = p0; + } + return x; +} +assertEq(a(1), 1); diff --git a/js/src/jit-test/tests/ion/bug677074.js b/js/src/jit-test/tests/ion/bug677074.js new file mode 100644 index 0000000000..4d67823184 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677074.js @@ -0,0 +1,6 @@ +function f0(p0,p1) { + if (p0) { + p1 + p1; + } else if (p0); +} +print(f0(0,0)); diff --git a/js/src/jit-test/tests/ion/bug677080.js b/js/src/jit-test/tests/ion/bug677080.js new file mode 100644 index 0000000000..5a47ae7da0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677080.js @@ -0,0 +1,8 @@ +function f0(p0) { + var v0; + if (v0) + v0 = (p0 & p0); + while (v0 & v0) + break; +} +print(f0(0)); diff --git a/js/src/jit-test/tests/ion/bug677163.js b/js/src/jit-test/tests/ion/bug677163.js new file mode 100644 index 0000000000..f884e79efe --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677163.js @@ -0,0 +1,9 @@ +function f0() { + var v0; + do { + v0 = (v0 & v0) + v0; + continue; + } while (v0); +} +assertEq(f0(), undefined); + diff --git a/js/src/jit-test/tests/ion/bug677455.js b/js/src/jit-test/tests/ion/bug677455.js new file mode 100644 index 0000000000..3d57ae22da --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677455.js @@ -0,0 +1,14 @@ +function f0(p0) { + var v0 = 0; + var v1; + var v2; + if (v1) + v2 = v1 + v1; + v1 | v2; + if (v0) { + while (p0) + v2 = v1 + v2; + v2 = v0; + } +} +assertEq(f0(1), undefined); diff --git a/js/src/jit-test/tests/ion/bug677715-2.js b/js/src/jit-test/tests/ion/bug677715-2.js new file mode 100644 index 0000000000..8ad4b951d7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677715-2.js @@ -0,0 +1,9 @@ +function f0(p0) { + var v0 = 4558.3; + var v1; + var v2; + loop0: while (((v2 + p0) & p0)) { + v2 = (p0 | p0); + } +} +assertEq(f0(7852), undefined); diff --git a/js/src/jit-test/tests/ion/bug677715-3.js b/js/src/jit-test/tests/ion/bug677715-3.js new file mode 100644 index 0000000000..91191e750f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677715-3.js @@ -0,0 +1,10 @@ +function f0(p0) { + var v0 = 3; + var v1; + var v2; + loop0: while (((v2 + p0) & p0)) { + v2 = (p0 | p0); + } + return v0; +} +assertEq(f0(7852), 3); diff --git a/js/src/jit-test/tests/ion/bug677715-4.js b/js/src/jit-test/tests/ion/bug677715-4.js new file mode 100644 index 0000000000..4fbc365b5c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677715-4.js @@ -0,0 +1,10 @@ +function f0(p0) { + var v0 = -16; + var v1; + var v2; + loop0: while (((v2 + p0) & p0)) { + v2 = (p0 | p0); + } + return v0; +} +assertEq(f0(7852), -16); diff --git a/js/src/jit-test/tests/ion/bug677715.js b/js/src/jit-test/tests/ion/bug677715.js new file mode 100644 index 0000000000..8910858dbf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677715.js @@ -0,0 +1,9 @@ +function f0(p0) { + var v0 = 4558; + var v1; + var v2; + loop0: while (((v2 + p0) & p0)) { + v2 = (p0 | p0); + } +} +assertEq(f0(7852), undefined); diff --git a/js/src/jit-test/tests/ion/bug677730.js b/js/src/jit-test/tests/ion/bug677730.js new file mode 100644 index 0000000000..e4e429e6bd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677730.js @@ -0,0 +1,4 @@ +function f0(p) { + return p + 1; +} +assertEq(f0(0x7fffffff), 0x80000000); diff --git a/js/src/jit-test/tests/ion/bug677774-1.js b/js/src/jit-test/tests/ion/bug677774-1.js new file mode 100644 index 0000000000..412060be52 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677774-1.js @@ -0,0 +1,16 @@ +function min(a, b) { + + if (a < b) { + return a; + } + else { + return b; + } +} + +assertEq(min(6, 5), 5); +assertEq(min(42, 1337), 42); +assertEq(min(-12, 6), -12) +assertEq(min(5, -6), -6) +assertEq(min(-3, -2), -3) +assertEq(min(-5, -6), -6) diff --git a/js/src/jit-test/tests/ion/bug677774-2.js b/js/src/jit-test/tests/ion/bug677774-2.js new file mode 100644 index 0000000000..a02d011af2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677774-2.js @@ -0,0 +1,8 @@ +function f(a, b) { return a > b; } + +assertEq(f(5, 6), false) +assertEq(f(1337, 42), true) +assertEq(f(-12, 6), false) +assertEq(f(5, -6), true) +assertEq(f(-3, -2), false) +assertEq(f(-5, -6), true) diff --git a/js/src/jit-test/tests/ion/bug677871.js b/js/src/jit-test/tests/ion/bug677871.js new file mode 100644 index 0000000000..d56206948c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug677871.js @@ -0,0 +1,18 @@ +function f0(p0,p1,p2,p3,p4,p5,p6) { + var v0; + var v1; + if (v1) { + do { + v0 = v0 + p3; + v1 = p3 + p3 + v1 + v0; + if (v1) { + v0 = v0 + p1 + p4 + p2 + p0 + v1; + continue; + } + break; + } while (v0); + } + v0 + v1; +} +assertEq(f0(1,2,3,4,5,6), undefined); + diff --git a/js/src/jit-test/tests/ion/bug678106.js b/js/src/jit-test/tests/ion/bug678106.js new file mode 100644 index 0000000000..34ab6584d9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug678106.js @@ -0,0 +1,32 @@ +function f_localinc(x) { + var a = x; + var b = a++; + + var c = b+b+b+b+b+b+b+b+b+b; + return a + c; +} +assertEq(f_localinc(1), 12) +function f_localdec(x) { + var a = x; + var b = a--; + + var c = b+b+b+b+b+b+b+b+b+b; + return a + c; +} +assertEq(f_localdec(1), 10) +function f_inclocal(x) { + var a = x; + var b = ++a; + + var c = b+b+b+b+b+b+b+b+b+b; + return a + c; +} +assertEq(f_inclocal(1), 22) +function f_declocal(x) { + var a = x; + var b = --a; + + var c = b+b+b+b+b+b+b+b+b+b; + return a + c; +} +assertEq(f_declocal(1), 0) diff --git a/js/src/jit-test/tests/ion/bug678239-1.js b/js/src/jit-test/tests/ion/bug678239-1.js new file mode 100644 index 0000000000..8a8f19ac16 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug678239-1.js @@ -0,0 +1,5 @@ +function f(x) { + x = x + 1; + return x; +} +assertEq(f(3), 4) diff --git a/js/src/jit-test/tests/ion/bug678239-2.js b/js/src/jit-test/tests/ion/bug678239-2.js new file mode 100644 index 0000000000..2b16a7cc9d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug678239-2.js @@ -0,0 +1,7 @@ +function f(x, y, z) { + if (1) + x = z; + return x + y; +} + +assertEq(f(0, 2, {}), "[object Object]2") diff --git a/js/src/jit-test/tests/ion/bug678353.js b/js/src/jit-test/tests/ion/bug678353.js new file mode 100644 index 0000000000..714192d12c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug678353.js @@ -0,0 +1,28 @@ +function f_arginc(a) { + var b = a++; + + var c = b+b+b+b+b+b+b+b+b+b; + return a + c; +} +assertEq(f_arginc(1), 12) +function f_argdec(a) { + var b = a--; + + var c = b+b+b+b+b+b+b+b+b+b; + return a + c; +} +assertEq(f_argdec(1), 10) +function f_incarg(a) { + var b = ++a; + + var c = b+b+b+b+b+b+b+b+b+b; + return a + c; +} +assertEq(f_incarg(1), 22) +function f_decarg(a) { + var b = --a; + + var c = b+b+b+b+b+b+b+b+b+b; + return a + c; +} +assertEq(f_decarg(1), 0) diff --git a/js/src/jit-test/tests/ion/bug678620.js b/js/src/jit-test/tests/ion/bug678620.js new file mode 100644 index 0000000000..9c2def3294 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug678620.js @@ -0,0 +1,6 @@ +function f0() { + var v0; + (++v0) ^ (v0--); +} +print(f0()); + diff --git a/js/src/jit-test/tests/ion/bug678625.js b/js/src/jit-test/tests/ion/bug678625.js new file mode 100644 index 0000000000..6fde67ea59 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug678625.js @@ -0,0 +1,8 @@ +function foldme() { + var v0 = 0x7fffffff; + var v1 = 1; + var v2 = v0 + v1; + return v2; +} +assertEq(foldme(),2147483648); + diff --git a/js/src/jit-test/tests/ion/bug678798.js b/js/src/jit-test/tests/ion/bug678798.js new file mode 100644 index 0000000000..7ad4d8e2b5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug678798.js @@ -0,0 +1,9 @@ +function f0() { + var v0; + if ((v0 ^ v0) + 1) { + return 3; + } else { + return 4; + } +} +assertEq(f0(), 3); diff --git a/js/src/jit-test/tests/ion/bug679493-2.js b/js/src/jit-test/tests/ion/bug679493-2.js new file mode 100644 index 0000000000..4cb089c1c2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug679493-2.js @@ -0,0 +1,30 @@ +// IM: Test generated code +function neg(x) { + return -x; +} +assertEq(neg(0), -0); +assertEq(neg(1), -1); +assertEq(neg(-1), 1); +assertEq(neg(-2147483648), 2147483648); +assertEq(neg(-1.3), 1.3); +assertEq(neg(1.45), -1.45); + +// IM: Test constant folding +function neg2(){ + var x = 1; + var y = -x; + return y; +} +assertEq(neg2(), -1); +function neg3(){ + var x = 0; + var y = -x; + return y; +} +assertEq(neg3(), -0); +function neg4(){ + var x = -2147483648; + var y = -x; + return y; +} +assertEq(neg4(), 2147483648); diff --git a/js/src/jit-test/tests/ion/bug679493.js b/js/src/jit-test/tests/ion/bug679493.js new file mode 100644 index 0000000000..91e54a001d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug679493.js @@ -0,0 +1,37 @@ +// Normal checks: +function mul(x, y) { + return x*y; +} +assertEq(mul(1, 2), 2); +assertEq(mul(0, 2), 0); +assertEq(mul(0, -1), -0); +assertEq(mul(100000000, 20000), 2000000000000); +assertEq(mul(0, -2), -0); +assertEq(mul(0, 0), 0); + +// Constant * value checks: +assertEq(function(x){return x*1}(4), 4); +assertEq(function(x){return x*1}(0), 0); +assertEq(function(x){return x*1}(-4), -4); +assertEq(function(x){return x*2}(4), 8); +assertEq(function(x){return x*2}(0), 0); +assertEq(function(x){return x*2}(-4), -8); +assertEq(function(x){return x*2}(2000000000), 4000000000); +assertEq(function(x){return x*5}(4), 20); +assertEq(function(x){return x*5}(0), 0); +assertEq(function(x){return x*5}(-4), -20); +assertEq(function(x){return x*0}(0), 0); +assertEq(function(x){return x*0}(5), 0); +assertEq(function(x){return x*0}(-5), -0); +assertEq(function(x){return x*-5}(4), -20); +assertEq(function(x){return x*-5}(0), -0); +assertEq(function(x){return x*-5}(-4), 20); +assertEq(function(x){return x*20000}(100000000), 2000000000000); + +// Constant folding +assertEq(function(){var x=5; return x*4}(), 20); +assertEq(function(){var x=5; return x*-4}(), -20); +assertEq(function(){var x=0; return x*4}(), 0); +assertEq(function(){var x=0; return x*0}(), 0); +assertEq(function(){var x=0; return x*-4}(), -0); +assertEq(function(){var x=20000; return x*100000000}(), 2000000000000); diff --git a/js/src/jit-test/tests/ion/bug679581.js b/js/src/jit-test/tests/ion/bug679581.js new file mode 100644 index 0000000000..21933ae9c2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug679581.js @@ -0,0 +1,11 @@ +function f0(p0) { + var v0; + var v1 = 0; + var v2 = (v0 ^ v0) + v0; + if (p0 | 0) + v1 = v0; + do break; while (v0); + p0 ^ v1; +} +print(f0(1)); + diff --git a/js/src/jit-test/tests/ion/bug679794.js b/js/src/jit-test/tests/ion/bug679794.js new file mode 100644 index 0000000000..8def13cb62 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug679794.js @@ -0,0 +1,7 @@ +function f0() { + var v0 = 0.1; + while (0) { + v0 = v0 + 1.7; + } +} +f0(); diff --git a/js/src/jit-test/tests/ion/bug680432.js b/js/src/jit-test/tests/ion/bug680432.js new file mode 100644 index 0000000000..f98e028683 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug680432.js @@ -0,0 +1,46 @@ +function f0(p0) { + var v0 = 0.5; + var v1 = 1.5; + var v2 = 2.5; + var v3 = 3.5; + var v4 = 4.5; + var v5 = 5.5; + var v6 = 6.5; + var v7 = 7.5; + var v8 = 8.5; + var v9 = 9.5; + var v10 = 10.5; + var v11 = 11.5; + var v12 = 12.5; + var v13 = 13.5; + var v14 = 14.5; + var v15 = 15.5; + var v16 = 16.5; + // 0.125 is used to avoid the oracle choice for int32. + while (0) { + // p0 = false; + var tmp = v0; + v0 = 0.125 + v0 + v1; + v1 = 0.125 + v1 + v2; + v2 = 0.125 + v2 + v3; + v3 = 0.125 + v3 + v4; + v4 = 0.125 + v4 + v5; + v5 = 0.125 + v5 + v6; + v6 = 0.125 + v6 + v7; + v7 = 0.125 + v7 + v8; + v8 = 0.125 + v8 + v9; + v9 = 0.125 + v9 + v10; + v10 = 0.125 + v10 + v11; + v11 = 0.125 + v11 + v12; + v12 = 0.125 + v12 + v13; + v13 = 0.125 + v13 + v14; + v14 = 0.125 + v14 + v15; + v15 = 0.125 + v15 + v16; + v16 = 0.125 + v16 + tmp; + } + return 0.5 + v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10 + v11 + v12 + v13 + v14 + v15 + v16; +} + +// expect 145 +assertEq(f0(false), 145); + diff --git a/js/src/jit-test/tests/ion/bug680619.js b/js/src/jit-test/tests/ion/bug680619.js new file mode 100644 index 0000000000..f35556cb8f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug680619.js @@ -0,0 +1,13 @@ +function f0() { + var v0 = 5000; + if (v0) { + if (v0) { + v0 = v0 * v0; + } else { + return; + } + v0 = v0 * v0; + } + return v0; +} +assertEq(f0(), 625000000000000); diff --git a/js/src/jit-test/tests/ion/bug680621.js b/js/src/jit-test/tests/ion/bug680621.js new file mode 100644 index 0000000000..358caffcfc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug680621.js @@ -0,0 +1,10 @@ +// Don't assert. +function f0(p0) { + var v0 = 0 < 0; + var v1; + v1 + p0; + if (v0) + v1 = p0 | 0; +} +f0(5000); + diff --git a/js/src/jit-test/tests/ion/bug681185.js b/js/src/jit-test/tests/ion/bug681185.js new file mode 100644 index 0000000000..e93f34b625 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug681185.js @@ -0,0 +1,276 @@ +function test_lsh(x, y) { + return x << y; +} + +function test_ursh(x, y) { + return x >>> y; +} + +function test_rsh(x, y) { + return x >> y; +} + +var x = 1; +assertEq(test_rsh(x, -1), 0); +assertEq(test_rsh(-1, x), -1); +assertEq(test_ursh(x, -1), 0); +assertEq(test_ursh(-1, x), 2147483647); +assertEq(test_lsh(x, -1), -2147483648); +assertEq(test_lsh(-1, x), -2); +assertEq(test_rsh(x, 1), 0); +assertEq(test_rsh(1, x), 0); +assertEq(test_ursh(x, 1), 0); +assertEq(test_ursh(1, x), 0); +assertEq(test_lsh(x, 1), 2); +assertEq(test_lsh(1, x), 2); +assertEq(test_rsh(x, 0), 1); +assertEq(test_rsh(0, x), 0); +assertEq(test_ursh(x, 0), 1); +assertEq(test_ursh(0, x), 0); +assertEq(test_lsh(x, 0), 1); +assertEq(test_lsh(0, x), 0); +assertEq(test_rsh(x, 0xffffffff), 0); +assertEq(test_rsh(0xffffffff, x), -1); +assertEq(test_ursh(x, 0xffffffff), 0); +assertEq(test_ursh(0xffffffff, x), 2147483647); +assertEq(test_lsh(x, 0xffffffff), -2147483648); +assertEq(test_lsh(0xffffffff, x), -2); +assertEq(test_rsh(x, "10.6"), 0); +assertEq(test_rsh("10.6", x), 5); +assertEq(test_ursh(x, "10.6"), 0); +assertEq(test_ursh("10.6", x), 5); +assertEq(test_lsh(x, "10.6"), 1024); +assertEq(test_lsh("10.6", x), 20); +assertEq(test_rsh(x, 2147483648), 1); +assertEq(test_rsh(2147483648, x), -1073741824); +assertEq(test_ursh(x, 2147483648), 1); +assertEq(test_ursh(2147483648, x), 1073741824); +assertEq(test_lsh(x, 2147483648), 1); +assertEq(test_lsh(2147483648, x), 0); +assertEq(test_rsh(x, 4294967296), 1); +assertEq(test_rsh(4294967296, x), 0); +assertEq(test_ursh(x, 4294967296), 1); +assertEq(test_ursh(4294967296, x), 0); +assertEq(test_lsh(x, 4294967296), 1); +assertEq(test_lsh(4294967296, x), 0); +assertEq(test_rsh(x, undefined), 1); +assertEq(test_rsh(undefined, x), 0); +assertEq(test_ursh(x, undefined), 1); +assertEq(test_ursh(undefined, x), 0); +assertEq(test_lsh(x, undefined), 1); +assertEq(test_lsh(undefined, x), 0); +assertEq(test_rsh(x, null), 1); +assertEq(test_rsh(null, x), 0); +assertEq(test_ursh(x, null), 1); +assertEq(test_ursh(null, x), 0); +assertEq(test_lsh(x, null), 1); +assertEq(test_lsh(null, x), 0); +assertEq(test_rsh(x, false), 1); +assertEq(test_rsh(false, x), 0); +assertEq(test_ursh(x, false), 1); +assertEq(test_ursh(false, x), 0); +assertEq(test_lsh(x, false), 1); +assertEq(test_lsh(false, x), 0); +assertEq(test_rsh(x, true), 0); +assertEq(test_rsh(true, x), 0); +assertEq(test_ursh(x, true), 0); +assertEq(test_ursh(true, x), 0); +assertEq(test_lsh(x, true), 2); +assertEq(test_lsh(true, x), 2); +assertEq(test_rsh(x, -1.5), 0); +assertEq(test_rsh(-1.5, x), -1); +assertEq(test_ursh(x, -1.5), 0); +assertEq(test_ursh(-1.5, x), 2147483647); +assertEq(test_lsh(x, -1.5), -2147483648); +assertEq(test_lsh(-1.5, x), -2); + +var x = 0; +assertEq(test_rsh(x, -1), 0); +assertEq(test_rsh(-1, x), -1); +assertEq(test_ursh(x, -1), 0); +assertEq(test_ursh(-1, x), 4294967295); +assertEq(test_lsh(x, -1), 0); +assertEq(test_lsh(-1, x), -1); +assertEq(test_rsh(x, 1), 0); +assertEq(test_rsh(1, x), 1); +assertEq(test_ursh(x, 1), 0); +assertEq(test_ursh(1, x), 1); +assertEq(test_lsh(x, 1), 0); +assertEq(test_lsh(1, x), 1); +assertEq(test_rsh(x, 0), 0); +assertEq(test_rsh(0, x), 0); +assertEq(test_ursh(x, 0), 0); +assertEq(test_ursh(0, x), 0); +assertEq(test_lsh(x, 0), 0); +assertEq(test_lsh(0, x), 0); +assertEq(test_rsh(x, 0xffffffff), 0); +assertEq(test_rsh(0xffffffff, x), -1); +assertEq(test_ursh(x, 0xffffffff), 0); +assertEq(test_ursh(0xffffffff, x), 4294967295); +assertEq(test_lsh(x, 0xffffffff), 0); +assertEq(test_lsh(0xffffffff, x), -1); +assertEq(test_rsh(x, "10.6"), 0); +assertEq(test_rsh("10.6", x), 10); +assertEq(test_ursh(x, "10.6"), 0); +assertEq(test_ursh("10.6", x), 10); +assertEq(test_lsh(x, "10.6"), 0); +assertEq(test_lsh("10.6", x), 10); +assertEq(test_rsh(x, 2147483648), 0); +assertEq(test_rsh(2147483648, x), -2147483648); +assertEq(test_ursh(x, 2147483648), 0); +assertEq(test_ursh(2147483648, x), 2147483648); +assertEq(test_lsh(x, 2147483648), 0); +assertEq(test_lsh(2147483648, x), -2147483648); +assertEq(test_rsh(x, 4294967296), 0); +assertEq(test_rsh(4294967296, x), 0); +assertEq(test_ursh(x, 4294967296), 0); +assertEq(test_ursh(4294967296, x), 0); +assertEq(test_lsh(x, 4294967296), 0); +assertEq(test_lsh(4294967296, x), 0); +assertEq(test_rsh(x, undefined), 0); +assertEq(test_rsh(undefined, x), 0); +assertEq(test_ursh(x, undefined), 0); +assertEq(test_ursh(undefined, x), 0); +assertEq(test_lsh(x, undefined), 0); +assertEq(test_lsh(undefined, x), 0); +assertEq(test_rsh(x, null), 0); +assertEq(test_rsh(null, x), 0); +assertEq(test_ursh(x, null), 0); +assertEq(test_ursh(null, x), 0); +assertEq(test_lsh(x, null), 0); +assertEq(test_lsh(null, x), 0); +assertEq(test_rsh(x, false), 0); +assertEq(test_rsh(false, x), 0); +assertEq(test_ursh(x, false), 0); +assertEq(test_ursh(false, x), 0); +assertEq(test_lsh(x, false), 0); +assertEq(test_lsh(false, x), 0); +assertEq(test_rsh(x, true), 0); +assertEq(test_rsh(true, x), 1); +assertEq(test_ursh(x, true), 0); +assertEq(test_ursh(true, x), 1); +assertEq(test_lsh(x, true), 0); +assertEq(test_lsh(true, x), 1); +assertEq(test_rsh(x, -1.5), 0); +assertEq(test_rsh(-1.5, x), -1); +assertEq(test_ursh(x, -1.5), 0); +assertEq(test_ursh(-1.5, x), 4294967295); +assertEq(test_lsh(x, -1.5), 0); +assertEq(test_lsh(-1.5, x), -1); + +var x = -1; +assertEq(test_rsh(x, -1), -1); +assertEq(test_rsh(-1, x), -1); +assertEq(test_ursh(x, -1), 1); +assertEq(test_ursh(-1, x), 1); +assertEq(test_lsh(x, -1), -2147483648); +assertEq(test_lsh(-1, x), -2147483648); +assertEq(test_rsh(x, 1), -1); +assertEq(test_rsh(1, x), 0); +assertEq(test_ursh(x, 1), 2147483647); +assertEq(test_ursh(1, x), 0); +assertEq(test_lsh(x, 1), -2); +assertEq(test_lsh(1, x), -2147483648); +assertEq(test_rsh(x, 0), -1); +assertEq(test_rsh(0, x), 0); +assertEq(test_ursh(x, 0), 4294967295); +assertEq(test_ursh(0, x), 0); +assertEq(test_lsh(x, 0), -1); +assertEq(test_lsh(0, x), 0); +assertEq(test_rsh(x, 0xffffffff), -1); +assertEq(test_rsh(0xffffffff, x), -1); +assertEq(test_ursh(x, 0xffffffff), 1); +assertEq(test_ursh(0xffffffff, x), 1); +assertEq(test_lsh(x, 0xffffffff), -2147483648); +assertEq(test_lsh(0xffffffff, x), -2147483648); +assertEq(test_rsh(x, "10.6"), -1); +assertEq(test_rsh("10.6", x), 0); +assertEq(test_ursh(x, "10.6"), 4194303); +assertEq(test_ursh("10.6", x), 0); +assertEq(test_lsh(x, "10.6"), -1024); +assertEq(test_lsh("10.6", x), 0); +assertEq(test_rsh(x, 2147483648), -1); +assertEq(test_rsh(2147483648, x), -1); +assertEq(test_ursh(x, 2147483648), 4294967295); +assertEq(test_ursh(2147483648, x), 1); +assertEq(test_lsh(x, 2147483648), -1); +assertEq(test_lsh(2147483648, x), 0); +assertEq(test_rsh(x, 4294967296), -1); +assertEq(test_rsh(4294967296, x), 0); +assertEq(test_ursh(x, 4294967296), 4294967295); +assertEq(test_ursh(4294967296, x), 0); +assertEq(test_lsh(x, 4294967296), -1); +assertEq(test_lsh(4294967296, x), 0); +assertEq(test_rsh(x, undefined), -1); +assertEq(test_rsh(undefined, x), 0); +assertEq(test_ursh(x, undefined), 4294967295); +assertEq(test_ursh(undefined, x), 0); +assertEq(test_lsh(x, undefined), -1); +assertEq(test_lsh(undefined, x), 0); +assertEq(test_rsh(x, null), -1); +assertEq(test_rsh(null, x), 0); +assertEq(test_ursh(x, null), 4294967295); +assertEq(test_ursh(null, x), 0); +assertEq(test_lsh(x, null), -1); +assertEq(test_lsh(null, x), 0); +assertEq(test_rsh(x, false), -1); +assertEq(test_rsh(false, x), 0); +assertEq(test_ursh(x, false), 4294967295); +assertEq(test_ursh(false, x), 0); +assertEq(test_lsh(x, false), -1); +assertEq(test_lsh(false, x), 0); +assertEq(test_rsh(x, true), -1); +assertEq(test_rsh(true, x), 0); +assertEq(test_ursh(x, true), 2147483647); +assertEq(test_ursh(true, x), 0); +assertEq(test_lsh(x, true), -2); +assertEq(test_lsh(true, x), -2147483648); +assertEq(test_rsh(x, -1.5), -1); +assertEq(test_rsh(-1.5, x), -1); +assertEq(test_ursh(x, -1.5), 1); +assertEq(test_ursh(-1.5, x), 1); +assertEq(test_lsh(x, -1.5), -2147483648); +assertEq(test_lsh(-1.5, x), -2147483648); + + + +assertEq(test_ursh(0, -2147483648), 0); +assertEq(test_ursh(0, 2147483648), 0); +assertEq(test_ursh(0, 45), 0); +assertEq(test_ursh(0, -45), 0); +assertEq(test_ursh(100, -2147483648), 100); +assertEq(test_ursh(100, 2147483648), 100); +assertEq(test_ursh(100, 45), 0); +assertEq(test_ursh(100, -45), 0); +assertEq(test_ursh(-100, -2147483648), 4294967196); +assertEq(test_ursh(-100, 2147483648), 4294967196); +assertEq(test_ursh(-100, 45), 524287); +assertEq(test_ursh(-100, -45), 8191); + + + +function test1() { + var i = 0; + return 2147483647 >>> i; +} +assertEq(test1(), 2147483647); +function test2() { + var i = 1; + return 2147483647 >>> i; +} +assertEq(test2(), 1073741823); +function test3() { + var i = 0; + return -1 >>> i; +} +assertEq(test3(), 4294967295); +function test4() { + var i = 3; + return -1 >>> i; +} +assertEq(test4(), 536870911); +function test5() { + var i = 0; + return -3648 >>> i; +} +assertEq(test5(), 4294963648); diff --git a/js/src/jit-test/tests/ion/bug682210.js b/js/src/jit-test/tests/ion/bug682210.js new file mode 100644 index 0000000000..974dc8dc39 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug682210.js @@ -0,0 +1,7 @@ +function test() { + for (var x = 1; x < 1; x++) { + for (var y=1; y < 1; y++) { + } + } +} +test(); diff --git a/js/src/jit-test/tests/ion/bug684362.js b/js/src/jit-test/tests/ion/bug684362.js new file mode 100644 index 0000000000..9a83b053d7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug684362.js @@ -0,0 +1,14 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +function f(a) { + var k = a; + T: for (;;) { + for (;;) { + for (;;) { + if (k) + continue; + break T; + } + } + } +} +f(0); diff --git a/js/src/jit-test/tests/ion/bug684384.js b/js/src/jit-test/tests/ion/bug684384.js new file mode 100644 index 0000000000..b3f3f45437 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug684384.js @@ -0,0 +1,58 @@ +// Labeled break tests. +function f1() { + foo: + if ([1]) { + bar: + for (var i=0; i<100; i++) { + if (i > 60) + break foo; + } + assertEq(0, 1); + } + assertEq(i, 61); + return true; +} +assertEq(f1(), true); + +// Label with no breaks. +function f2() { + foo: + if ([1]) { + for (var i=0; i<100; i++) { + } + } + assertEq(i, 100); + return true; +} +assertEq(f2(), true); + +// No breaks and early return. +function f3() { + foo: { + if (true) { + for (var i=0; i<100; i++) { + } + } + return false; + } + assertEq(i, 100); + return true; +} +assertEq(f3(), false); + +// Multiple breaks. +function f4() { + foo: { + if (true) { + for (var i=0; i<100; i++) + if (i > 70) + break foo; + if (i > 80) + break foo; + } + break foo; + } + assertEq(i, 71); + return true; +} +assertEq(f4(), true); diff --git a/js/src/jit-test/tests/ion/bug691597.js b/js/src/jit-test/tests/ion/bug691597.js new file mode 100644 index 0000000000..348c8617dc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug691597.js @@ -0,0 +1,5 @@ +// |jit-test| error: TypeError +function f() { + -null(); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug691603.js b/js/src/jit-test/tests/ion/bug691603.js new file mode 100644 index 0000000000..6c27b80e8a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug691603.js @@ -0,0 +1,11 @@ +// |jit-test| error: ReferenceError +function bitsinbyte(b) { + while(m<0x100) { } +} +function TimeFunc(func) { + for(var y=0; y<256; y++) func(y); +} +function nestedExit2() { + TimeFunc(bitsinbyte); +} +assertEq(nestedExit2(), "ok"); diff --git a/js/src/jit-test/tests/ion/bug691747.js b/js/src/jit-test/tests/ion/bug691747.js new file mode 100644 index 0000000000..117899d69d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug691747.js @@ -0,0 +1,11 @@ +function reportCompare(actual) { return - ++actual + "'"; } +var UBound = 0; +var actualvalues = []; +for (var li = 0; li < 6; ++li) addThis(); +function addThis() { + UBound++; + for (var i=0; i<UBound; i++) { + reportCompare(actualvalues[i]); + } +} +for (var li = 0; li < 3; ++li) addThis(); diff --git a/js/src/jit-test/tests/ion/bug692208.js b/js/src/jit-test/tests/ion/bug692208.js new file mode 100644 index 0000000000..e63119bdef --- /dev/null +++ b/js/src/jit-test/tests/ion/bug692208.js @@ -0,0 +1,10 @@ +// |jit-test| error: ReferenceError +SwitchTest( 0, 126 ); +function SwitchTest( input, expect ) { + switch ( input ) { + case (7): + default: + result += 32; + case 4: + } +} diff --git a/js/src/jit-test/tests/ion/bug692211.js b/js/src/jit-test/tests/ion/bug692211.js new file mode 100644 index 0000000000..b9df225325 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug692211.js @@ -0,0 +1,8 @@ +// |jit-test| error: TypeError +function TimeFunc(func) { + for(var y=0; y<256; y++) func(y); +} +function nestedExit2() { + TimeFunc(TimeFunc); +} +assertEq(nestedExit2(), "ok"); diff --git a/js/src/jit-test/tests/ion/bug692213.js b/js/src/jit-test/tests/ion/bug692213.js new file mode 100644 index 0000000000..2dc5dc4d73 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug692213.js @@ -0,0 +1,6 @@ +function X(n) { + while ((n--)) { + switch ( n ) { default : } + } +} +(X)(0); diff --git a/js/src/jit-test/tests/ion/bug692215.js b/js/src/jit-test/tests/ion/bug692215.js new file mode 100644 index 0000000000..631a356a81 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug692215.js @@ -0,0 +1,7 @@ +function test1() { + var src = "switch(x) {\n"; + for (var i=-1; i<4; i++) { + src += (i >= 0) ? src : "default:\n"; + } +} +test1(); diff --git a/js/src/jit-test/tests/ion/bug695017.js b/js/src/jit-test/tests/ion/bug695017.js new file mode 100644 index 0000000000..44a5dbc89d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug695017.js @@ -0,0 +1,7 @@ +function f() { + var n = null; + return n++; +} + +print(f()); +assertEq(f(), 0); diff --git a/js/src/jit-test/tests/ion/bug701956.js b/js/src/jit-test/tests/ion/bug701956.js new file mode 100644 index 0000000000..f073e17f9b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug701956.js @@ -0,0 +1,13 @@ +function test() { + function f(arr, i) { + arr[3] |= i; + } + + var a = [1, 2, 3, 4, 5]; + + for (var i=0; i<100; i++) { + f(a, i * 2); + } + assertEq(a[3], 254); +} +test(); diff --git a/js/src/jit-test/tests/ion/bug701958.js b/js/src/jit-test/tests/ion/bug701958.js new file mode 100644 index 0000000000..6320ef3a6c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug701958.js @@ -0,0 +1,12 @@ +function f(v) +{ + return v.x + v.x + v.y; +} + +assertEq(f({ x: 1, y: 2 }), 4); +assertEq(f({ __proto__: {x: 1, y: 2} }), 4); +assertEq(f({ __proto__: {x: 0, y: 2}, x: 1 }), 4); + +// Ensure there is no aliasing. +var global = 1; +assertEq(f(Object.defineProperty({ y : 2 }, "x", { get : function(){ return global++; } })), 5); diff --git a/js/src/jit-test/tests/ion/bug701964.js b/js/src/jit-test/tests/ion/bug701964.js new file mode 100644 index 0000000000..a3f9f0fd2c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug701964.js @@ -0,0 +1,36 @@ +load(libdir + 'array-compare.js'); + +function f(v) { + return v.length; +} + +function g(v) { + return v.length; +} + +function h(v) { + return v.length; +} + +function aliasCheck(v) { + v[0] = v.length; + v[1] = v.length; + v[2] = v.length; + return v; +} + +for(let i = 41; i; i--) { + assertEq(f([]), 0); + assertEq(f([0]), 1); + assertEq(f([0, 1]), 2); + assertEq(f([0, 1, 2]), 3); + assertEq(g(""), 0); + assertEq(g("1"), 1); + assertEq(g("12"), 2); + assertEq(g("123"), 3); + assertEq(h({}), undefined); + assertEq(h({a: 1}), undefined); + assertEq(h({a: 1, b: 2}), undefined); + assertEq(h({a: 1, b: 2, length: 3}), 3); + assertEq(arraysEqual(aliasCheck([0, 1, 2]), [3, 3, 3]), true); +} diff --git a/js/src/jit-test/tests/ion/bug703376.js b/js/src/jit-test/tests/ion/bug703376.js new file mode 100644 index 0000000000..cc88c6011c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug703376.js @@ -0,0 +1,29 @@ +var global = 1; + +function test1(x) { + global = 2; + var k = global; + global = x; + global = x + 1; + k = global + global; + return k; +} + +for (var i=0; i<60; i++) { + assertEq(test1(i), i + 1 + i + 1); +} + +function test2(x) { + global = 2; + var k = global; + + for (var i=0; i<10; i++) { + k = global; + global = i + x; + } + return k; +} + +for (i=0; i<50; i++) { + assertEq(test2(i), i + 8); +} diff --git a/js/src/jit-test/tests/ion/bug705351.js b/js/src/jit-test/tests/ion/bug705351.js new file mode 100644 index 0000000000..10073b8de2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug705351.js @@ -0,0 +1,38 @@ +var a = 1.1; +function f1() { + return a + 0.2; +} +function test1() { + for (var i=0; i<100; i++) { + assertEq(f1(), 1.3); + } + a = 20; + assertEq(f1(), 20.2); +} +test1(); + +function f2(arr) { + return arr[2] + 0.2; +} +function test2() { + var a = [1.1, 2.2, 3.3, 4.4]; + for (var i=0; i<100; i++) { + assertEq(f2(a), 3.5); + } + a[2] = 123; + assertEq(f2(a), 123.2); +} +test2(); + +function f3(arr, idx) { + return arr[idx] + 0.2; +} +function test3() { + var a = [1.1, 2.2, 3.3, 4.4]; + for (var i=0; i<100; i++) { + assertEq(f3(a, 2), 3.5); + } + a[2] = 123; + assertEq(f3(a, 2), 123.2); +} +test3(); diff --git a/js/src/jit-test/tests/ion/bug706692.js b/js/src/jit-test/tests/ion/bug706692.js new file mode 100644 index 0000000000..d302545903 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug706692.js @@ -0,0 +1,21 @@ +// |jit-test| error: TypeError + +// Bailout from a stack with multiple ion frames of different flavors. +function f(obj,b,c) { + return obj(); // Throw error. +} + +function g(f,obj) { + return f(obj); // Call f() with insufficient arguments, generating a RectifierFrame. +} + +function h(f, g, obj) { + return g(f, obj); // EntryFrame. Generate a JSFrame. +} + +f(); // Prime f(). +g(); // Prime g(). +var obj = new Object(); + +h(f,g,obj); + diff --git a/js/src/jit-test/tests/ion/bug706699.js b/js/src/jit-test/tests/ion/bug706699.js new file mode 100644 index 0000000000..26370f3976 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug706699.js @@ -0,0 +1,16 @@ +// |jit-test| error: 2 +function g(x, y) { + return x + y; +} + +function f(g, x, y) { + // return x + y; + return g(x, y); +} + +assertEq(g(4, 5), 9); + +obj = { valueOf: function () { throw 2; } }; + +print(f(g, obj, 2)); + diff --git a/js/src/jit-test/tests/ion/bug710983.js b/js/src/jit-test/tests/ion/bug710983.js new file mode 100644 index 0000000000..86e47460a1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug710983.js @@ -0,0 +1,19 @@ +function g() { } + +g(); + + +function f(a, g) { + var x; + if (a) { + x = 12; + print(a); + x = a + 19; + } else { + x = 20 + a; + g(a); + x += a; + } + return a + x + 12; +} +assertEq(f(0, g), 32); diff --git a/js/src/jit-test/tests/ion/bug714397.js b/js/src/jit-test/tests/ion/bug714397.js new file mode 100644 index 0000000000..6da4fac954 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug714397.js @@ -0,0 +1,17 @@ +// Don't assert. Reduced from a modified SS 1.0 crypto-md5. + +function g() +{ + return 0; +} + +function f() +{ + for(var i = 0; i < 100; i++) { + g(0); + g(0); + } +} + + +f(); diff --git a/js/src/jit-test/tests/ion/bug716504.js b/js/src/jit-test/tests/ion/bug716504.js new file mode 100644 index 0000000000..dff77c6932 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug716504.js @@ -0,0 +1,10 @@ +function f(x, from, to) { + var y = 0; + for (var i=from; i<to; i++) { + y = i * x; + } + return y; +} + +assertEq(f(0, 0, 200), 0); +assertEq(f(0, -10, -5), -0); diff --git a/js/src/jit-test/tests/ion/bug716624-1.js b/js/src/jit-test/tests/ion/bug716624-1.js new file mode 100644 index 0000000000..4e517c73e9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug716624-1.js @@ -0,0 +1,88 @@ +function get_value_undefined(o) { + return o.value +} + +function get_value_null(o) { + return o.value +} + +function get_value_int(o) { + return o.value +} + +function get_value_effectfull(o) { + return o.value +} + +var count = 0 +var o_undefined = {value: undefined} +var o_null = {value: null} +var o_int = {value: 3} +var o_effectfull = {} +Object.defineProperty(o_effectfull, "value", { get: function () { count++; return undefined; } }); + +// compiled as undefined +for(var i=0; i<42; i++) + get_value_undefined(o_undefined) + +// compiled as null +for(var i=0; i<42; i++) + get_value_null(o_null) + +// compiled as int +for(var i=0; i<42; i++) + get_value_int(o_int) + +// compiled as effectfull property access +for(var i=0; i<42; i++) + get_value_effectfull(o_effectfull) + +// Note: +// because of bug 715111 when there is an invalidation we have bogus values on the stack. +// So we get wrong values. Therefor I run them twice. On as 'warmup'. Second time to test + +count = 0 +assertEq(get_value_undefined(o_undefined), undefined); +get_value_undefined(o_null) +assertEq(get_value_undefined(o_null), null); +get_value_undefined(o_int) +assertEq(get_value_undefined(o_int), 3); +get_value_undefined(o_effectfull) +assertEq(get_value_undefined(o_effectfull), undefined); +assertEq(get_value_undefined(o_undefined), undefined); +assertEq(count, 2); + +count = 0 +assertEq(get_value_null(o_null), null); +get_value_null(o_undefined) +assertEq(get_value_null(o_undefined), undefined); +get_value_null(o_int) +assertEq(get_value_null(o_int), 3); +get_value_null(o_effectfull) +assertEq(get_value_null(o_effectfull), undefined); +assertEq(get_value_null(o_null), null); +assertEq(count, 2); + +count = 0 + +assertEq(get_value_int(o_int), 3); +get_value_int(o_null) +assertEq(get_value_int(o_null), null); +get_value_int(o_undefined) +assertEq(get_value_int(o_undefined), undefined); +get_value_int(o_effectfull) +assertEq(get_value_int(o_effectfull), undefined); +assertEq(get_value_int(o_int), 3); +assertEq(count, 2); + +count = 0 + +assertEq(get_value_effectfull(o_effectfull), undefined); +get_value_effectfull(o_null) +assertEq(get_value_effectfull(o_null), null); +get_value_effectfull(o_undefined) +assertEq(get_value_effectfull(o_undefined), undefined); +get_value_effectfull(o_int) +assertEq(get_value_effectfull(o_int), 3); +assertEq(get_value_effectfull(o_effectfull), undefined); +assertEq(count, 2); diff --git a/js/src/jit-test/tests/ion/bug716624-2.js b/js/src/jit-test/tests/ion/bug716624-2.js new file mode 100644 index 0000000000..9f6531e6b9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug716624-2.js @@ -0,0 +1,8 @@ +function getprop (obj) { + return obj.nonexist; +} + +for (var n = 0; n < 100; n++) { + var a = (n % 2) ? ((n % 3) ? new Object() : new Object()) : new Object(); + getprop(a); +} diff --git a/js/src/jit-test/tests/ion/bug716743.js b/js/src/jit-test/tests/ion/bug716743.js new file mode 100644 index 0000000000..ed19cbabcf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug716743.js @@ -0,0 +1,3 @@ +(function(o) { + o.p +})({}) diff --git a/js/src/jit-test/tests/ion/bug716853.js b/js/src/jit-test/tests/ion/bug716853.js new file mode 100644 index 0000000000..e158efcd24 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug716853.js @@ -0,0 +1,12 @@ +function sieve() { + for (var i=0; i<100; i++) { } +} +sieve(); +gc(); + +function fib(n) { + if (n < 2) + return 1; + return fib(n-2) + fib(n-1); +} +fib(20); diff --git a/js/src/jit-test/tests/ion/bug716895.js b/js/src/jit-test/tests/ion/bug716895.js new file mode 100644 index 0000000000..1ea31d759b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug716895.js @@ -0,0 +1,14 @@ +// Don't segfault. Reduced from V8 deltablue. + +function output(c, dir) { + return (dir) ? c.v1 : c.v1; +} + +var constraint = { + v1 : {} +} + +for (i=0; i<100; i++){ + output(constraint, 0) + output(constraint, 1); +} diff --git a/js/src/jit-test/tests/ion/bug717466.js b/js/src/jit-test/tests/ion/bug717466.js new file mode 100644 index 0000000000..cd1b7b3e2c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug717466.js @@ -0,0 +1,82 @@ +function Person(){} +function Ninja(){} +Ninja.prototype = new Person(); +function House(){} + +var empty = {}; +var person = new Person(); +var ninja = new Ninja(); +var house = new House(); +var string = new String(); +var bindNinja = Ninja.bind({}); + +var array = {}; +array.__proto__ = Array.prototype; +var array2 = {}; +array2.__proto__ = array.prototype; + +function test(v, v2) { + return v instanceof v2; +} +function test2(v, v2) { + return v instanceof v2; +} +function test3(v, v2) { + return v instanceof v2; +} +function test4(v, v2) { + return v instanceof v2; +} + +// Test if specialized for object works +for (var i=0; i!=41; i++) { + assertEq(test(person, Person), true); + assertEq(test(empty, Person), false); + assertEq(test(ninja, Person), true); + assertEq(test(house, Person), false); + assertEq(test(string, Person), false); + assertEq(test(new bindNinja(), Person), true); + assertEq(test(new Ninja(), bindNinja), true); + assertEq(test(string, String), true); + assertEq(test(array, Array), true); + assertEq(test(empty, Object), true); + + // Test if bailout works + assertEq(test(0.1, Object), false); + + // Should generate TypeError + var err = false; + try { + test(0.1, 5); + } catch (e) { err = true; } + assertEq(err, true); + + // Should generate TypeError + var err = false; + try { + test(empty, empty); + } catch (e) { err = true; } + assertEq(err, true); + + // Should generate TypeError + var err = false; + try { + test(5.0, empty); + } catch (e) { err = true; } + assertEq(err, true); +} + +// Test if specialized for non-object lhs +for (var i=0; i!=41; i++) { + assertEq(test2(0.1, Object), false); +} + +// Check if we don't regress on https://bugzilla.mozilla.org/show_bug.cgi?id=7635 +function Foo() {}; +theproto = {}; +Foo.prototype = theproto; + +for (var i=0; i!=41; i++) { + assertEq(test3(theproto, Foo), false); +} + diff --git a/js/src/jit-test/tests/ion/bug718850.js b/js/src/jit-test/tests/ion/bug718850.js new file mode 100644 index 0000000000..7f3e281f8b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug718850.js @@ -0,0 +1,10 @@ +// Don't abort during SSA construction. +function f() { + var i = 0; + while (i < 100 && 1 == 1) { + i++; + } + return i; +} + +assertEq(f(), 100); diff --git a/js/src/jit-test/tests/ion/bug719231.js b/js/src/jit-test/tests/ion/bug719231.js new file mode 100644 index 0000000000..0a803859c5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug719231.js @@ -0,0 +1,10 @@ +// Don't abort in IonBuilder. +function f() { + // For loop with missing condition. + for (var y = 0; ; y++) { + if (y == 55) break; + } + return y; +} + +assertEq(f(), 55); diff --git a/js/src/jit-test/tests/ion/bug719346.js b/js/src/jit-test/tests/ion/bug719346.js new file mode 100644 index 0000000000..1fbc0a74f8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug719346.js @@ -0,0 +1,15 @@ +// Try to GC some ion code that involves an IC on x64. + +var o = { + bar: function () { return 1; } +} + +function f(o) { + for (var i = 0; i < 100; i++) + o.bar(); +} + +f(o); + +// Don't segfault. +gc(); diff --git a/js/src/jit-test/tests/ion/bug719774.js b/js/src/jit-test/tests/ion/bug719774.js new file mode 100644 index 0000000000..e0ffb412a3 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug719774.js @@ -0,0 +1,30 @@ +Date.prototype.format1 = function() { + return "" + this.getMonth() + this.getFullYear(); +} +function f(d) { + for (var i=0; i<60; i++) { + assertEq(d.format1(), "91987"); + } +} +f(new Date("10/10/1987 1:11:11")); + +var global = 0; +function f1() { + return global++; +} +function g1() { + return f1() + f1(); +} +var result = 0; +for (var i=0; i<100; i++) + result += g1(); +assertEq(result, 19900); + +function g2() { + var a = []; + var b = []; + a.push(1); + return a.length + b.length; +} +for (var i=0; i<100; i++) + assertEq(g2(), 1); diff --git a/js/src/jit-test/tests/ion/bug720169.js b/js/src/jit-test/tests/ion/bug720169.js new file mode 100644 index 0000000000..5d80a9a146 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug720169.js @@ -0,0 +1,8 @@ +function foo() { + var x = 0; + var y = 0; + while (x++ < 100) + y++; + assertEq(y, 100); +} +foo(); diff --git a/js/src/jit-test/tests/ion/bug723040.js b/js/src/jit-test/tests/ion/bug723040.js new file mode 100644 index 0000000000..a7ae7ea1a2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug723040.js @@ -0,0 +1,16 @@ +function f(x) { + for (var i=0; i<50; i++) { + assertEq(x == null, false); + assertEq(x == undefined, false); + assertEq(x != null, true); + assertEq(x != undefined, true); + assertEq(x === null, false); + assertEq(x === undefined, false); + assertEq(x !== null, true); + assertEq(x !== undefined, true); + assertEq(x < null, false); + assertEq(x >= null, true); + } +} +f(10); +f(0); diff --git a/js/src/jit-test/tests/ion/bug723271.js b/js/src/jit-test/tests/ion/bug723271.js new file mode 100644 index 0000000000..c261652b63 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug723271.js @@ -0,0 +1,23 @@ +function addConstraint(blaat) { + return blaat.v1 +} + +function ScaleConstraint() { + this.direction = null + this.v1 = {}; + addConstraint(this); +} + +function EqualityConstraint() { + this.v1 = {}; + addConstraint(this); +} + +function deltaBlue() { + new EqualityConstraint(); + new ScaleConstraint(); +} + +for (var n = 0; n<100; n++) { + deltaBlue() +} diff --git a/js/src/jit-test/tests/ion/bug724517.js b/js/src/jit-test/tests/ion/bug724517.js new file mode 100644 index 0000000000..1f3a8d4190 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724517.js @@ -0,0 +1,10 @@ +function fannkuch() { + var perm = []; + var k = 3.3; + for (var j = 0; j < 10; j++) { + var k2 = NaN >> 1; + for (var i = 0; i < 10; i++) { } + perm[0]; + } +} +fannkuch(); diff --git a/js/src/jit-test/tests/ion/bug724530.js b/js/src/jit-test/tests/ion/bug724530.js new file mode 100644 index 0000000000..47b0a892c4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724530.js @@ -0,0 +1,10 @@ +function fannkuch() { + var perm = []; + var k = undefined; + for (var j = 0; j < 50; j++) { + for (var i = 0; i < 0; i++) { + perm[k - 1] = 0; + } + } +} +fannkuch(); diff --git a/js/src/jit-test/tests/ion/bug724562.js b/js/src/jit-test/tests/ion/bug724562.js new file mode 100644 index 0000000000..b59c9917e7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724562.js @@ -0,0 +1,15 @@ +function fannkuch(n) { + var perm1 = Array(n); + for (var i = 0; i < n; i++) { }; + var r = n; + do { + while (r != 1) { r--; } + for (var z=0; z<50; z++) { + while (i < r) { + perm1[i]; + i++; + } + } + } while(false); +} +fannkuch(18); diff --git a/js/src/jit-test/tests/ion/bug724654.js b/js/src/jit-test/tests/ion/bug724654.js new file mode 100644 index 0000000000..59e552c66b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724654.js @@ -0,0 +1,14 @@ +de = N = K = E = l = p = n = function() {} +function e() {} +function tryItOut(code) { + d = f = Function(code) + f() +} +function t() {} +function ne() {} +a = eval +function r() {} +s = v = false +function f4() {} +o = 9 +tryItOut("for(b in((Object.create)(this))){}") diff --git a/js/src/jit-test/tests/ion/bug724788.js b/js/src/jit-test/tests/ion/bug724788.js new file mode 100644 index 0000000000..9b2115de20 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724788.js @@ -0,0 +1,29 @@ +// |jit-test| error: ReferenceError +o0 = TypeError.prototype.__proto__ +o1 = new Proxy({}, {}) +o13 = {}.__proto__ +var o15 = Object.prototype +o31 = (new Uint32Array(100)).buffer +function f2(o) { + try { + ({ + x: [eval("o")][0] + }.x.__defineGetter__("toString", function() { + return o26; + })); + } catch (e) {} +} +function f3(o) { + try { + +o31 + } catch (e) {} +} +function f19(o) { + for (var x in eval("o")) { + eval("o")[x]; + } +} +f2(o15) +f3(o0) +f19(o13) + diff --git a/js/src/jit-test/tests/ion/bug724944.js b/js/src/jit-test/tests/ion/bug724944.js new file mode 100644 index 0000000000..0b73ca7a77 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724944.js @@ -0,0 +1,18 @@ +function TestCase(n, d, e, a) { + return function writeHeaderToLog( string ) {}; +} +var SECTION = "15.1.2.5-2"; +for ( var CHARCODE = 0; CHARCODE < 256; CHARCODE += 16 ) { + new TestCase( SECTION, unescape( "%" + (ToHexString(CHARCODE)).substring(0,1) ) ); +} +function ToHexString( n ) { + var hex = new Array(); + for ( var mag = 1; Math.pow(16,mag) <= n ; mag++ ) { } + for ( index = 0, mag -= 1; mag > 0; index++, mag-- ) { } + var string =""; + switch ( hex[index] ) { + case 10: + string += "A"; + } + return string; +} diff --git a/js/src/jit-test/tests/ion/bug724975.js b/js/src/jit-test/tests/ion/bug724975.js new file mode 100644 index 0000000000..745e2db409 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724975.js @@ -0,0 +1,11 @@ +LastIndexOf("hello", "ll", 5); +function LastIndexOf(string, search, position) { + var j = 0; + for (;;) { + for (;;) { + if (string != search) break; + } + if (j++ > 100) + break; + } +} diff --git a/js/src/jit-test/tests/ion/bug724976.js b/js/src/jit-test/tests/ion/bug724976.js new file mode 100644 index 0000000000..01b7f0421e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724976.js @@ -0,0 +1,4 @@ +function g(a) {} +for(var i = 0; i < 10000; i++) { + g(0 || 1); +} diff --git a/js/src/jit-test/tests/ion/bug724999.js b/js/src/jit-test/tests/ion/bug724999.js new file mode 100644 index 0000000000..56f0eb7ec8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug724999.js @@ -0,0 +1,7 @@ +function nsieve(m){ + for (var z=0; z<10; z++) { + for (var k=0; k<m; k++) { } + break; + } +} +nsieve(100); diff --git a/js/src/jit-test/tests/ion/bug725000.js b/js/src/jit-test/tests/ion/bug725000.js new file mode 100644 index 0000000000..e2b9e54f94 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug725000.js @@ -0,0 +1,9 @@ +function f(s) { + var q; + for (var i = 0; i < 10000; i++) + q = ~s; + return q; +} +var obj = { valueOf: function () { return 3; } } +assertEq(f(obj), -4); + diff --git a/js/src/jit-test/tests/ion/bug725003.js b/js/src/jit-test/tests/ion/bug725003.js new file mode 100644 index 0000000000..45564529d5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug725003.js @@ -0,0 +1,15 @@ +function TestCase(n, d, e, a) { + this.name = n; + this.description = d; + this.expect = e; + this.actual = a; + this.passed = getTestCaseResult(e, a); + this.reason = ''; +} +function getTestCaseResult(expected, actual) {} +var obj = new Function(); +for (var i = 0; i < 100; i++) { + obj['-1'] = new Array(); + assertEq(obj['-1'] == null, false); + obj = new TestCase(); +} diff --git a/js/src/jit-test/tests/ion/bug725011.js b/js/src/jit-test/tests/ion/bug725011.js new file mode 100644 index 0000000000..c736aa7ab5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug725011.js @@ -0,0 +1,8 @@ +// |jit-test| error: InternalError +DoWhile( new DoWhileObject( (/[\u0076\u0095]/gm ), 1, 0 )); +function DoWhileObject( value, iterations, endvalue ) {} +function DoWhile( object ) { + do { + throw DoWhile(1), "", i < test; + } while( object.value ); +} diff --git a/js/src/jit-test/tests/ion/bug725061.js b/js/src/jit-test/tests/ion/bug725061.js new file mode 100644 index 0000000000..1946bb1c5c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug725061.js @@ -0,0 +1,12 @@ +function testInt(n, result) { + var x = 0; + for (var i = 0; i < 15; i++) { + if (x % 2 == 0) + x = 10; + else + x %= 0; + } + for (var i = 0; i < 15; i++) { } +} +testInt(2147483647, 2147483647); +testInt(-2147483648, -2147483648); diff --git a/js/src/jit-test/tests/ion/bug725067.js b/js/src/jit-test/tests/ion/bug725067.js new file mode 100644 index 0000000000..ae522a770d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug725067.js @@ -0,0 +1,11 @@ +var o0 = []; +var o4 = {}; +var o5 = Math; +function f6(o) { o[("Keywords")] = o;}; +for(var i=0; i<20; i++) { + f6(o0); + f6(o4); + f6(o5); + print(i); +} +gc(); diff --git a/js/src/jit-test/tests/ion/bug726180.js b/js/src/jit-test/tests/ion/bug726180.js new file mode 100644 index 0000000000..01b0816e41 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug726180.js @@ -0,0 +1,14 @@ +function orTestHelper(a, b, n) +{ + var k = 0; + for (var i = 0; i < n; i++) { + if (a || b) + return 1; + } + return 0; +} + +orTestHelper("", NaN, 30) +orTestHelper("", null, 30); +var x = orTestHelper("", 1, 5) +assertEq(x, 1) diff --git a/js/src/jit-test/tests/ion/bug728033.js b/js/src/jit-test/tests/ion/bug728033.js new file mode 100644 index 0000000000..f9d920eec7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug728033.js @@ -0,0 +1,8 @@ +a = {} +o14 = [].__proto__ +function g(o) { + o.f = o14 +} +for (let i = 0; i < 50; i++) { + g(a) +} diff --git a/js/src/jit-test/tests/ion/bug728187.js b/js/src/jit-test/tests/ion/bug728187.js new file mode 100644 index 0000000000..ecfb3dddd5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug728187.js @@ -0,0 +1,10 @@ +function f(x) { + if (x.y()) {}; +} +f({y: function() {}}); +try { + f(10); + assertEq(0, 1); +} catch(e) { + assertEq(e instanceof TypeError, true); +} diff --git a/js/src/jit-test/tests/ion/bug728188.js b/js/src/jit-test/tests/ion/bug728188.js new file mode 100644 index 0000000000..5289e0dc2b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug728188.js @@ -0,0 +1,9 @@ +// |jit-test| error:TypeError + +delete String.prototype.indexOf; + +function enterFunc (funcName) { + funcName.indexOf(); +} +enterFunc(new Array("foo")); +enterFunc(new String("Foo")); diff --git a/js/src/jit-test/tests/ion/bug729573.js b/js/src/jit-test/tests/ion/bug729573.js new file mode 100644 index 0000000000..f8cf3318df --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729573.js @@ -0,0 +1,18 @@ +function TestCase(n, d, e, a) { + return function writeHeaderToLog( string ) {}; +} +var SECTION = "11.7.2"; +for ( power = 0; power <= 32; power++ ) { + shiftexp = Math.pow( 2, power ); + for ( addexp = 0; addexp <= 32; addexp++ ) { + new TestCase( SECTION, SignedRightShift( shiftexp, addexp ), shiftexp >> addexp ); + } +} +function ToInt32BitString( n ) { + var b = ""; + return b; +} +function SignedRightShift( s, a ) { + s = ToInt32BitString( s ); + s = s.substring( 0, 1 | Math && 0xffffffff + 2 ); +} diff --git a/js/src/jit-test/tests/ion/bug729788.js b/js/src/jit-test/tests/ion/bug729788.js new file mode 100644 index 0000000000..8297e2a1ea --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729788.js @@ -0,0 +1,25 @@ +var msPerDay = 86400000; +function Day(t) { + return Math.floor(t / msPerDay); +} +function YearFromTime(t) { + sign = 1 + year = sign < 0 +} +function MonthFromTime(t) { + DayWithinYear(t) + function DayWithinYear(t) { return Day(t) - YearFromTime(); } + function WeekDay(t) { + weekday = Day(t) + 4 + return (weekday < 0 ? weekday : weekday); + } + time = year + for (var last_sunday = time; WeekDay(last_sunday) == 0;) {} +} +addTestCase(0, 946684800000); +function addTestCase(startms, newms) { + UTCDateFromTime(newms) +} +function UTCDateFromTime(t) { + MonthFromTime(t) +} diff --git a/js/src/jit-test/tests/ion/bug729795.js b/js/src/jit-test/tests/ion/bug729795.js new file mode 100644 index 0000000000..e2050a9dff --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729795.js @@ -0,0 +1,2 @@ +var summary = 'TM: never abort on =='; +for(i=0;i<500;++(summary)) { var r = (void 0) == null; break;} diff --git a/js/src/jit-test/tests/ion/bug729798.js b/js/src/jit-test/tests/ion/bug729798.js new file mode 100644 index 0000000000..470a6c788c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729798.js @@ -0,0 +1,6 @@ +function q2(n) { + var c = []; + var e = /foo$/.test(c) && c.match(/(.*)foo$/); +} +for (var x = 500; x < 5000; x += 500) +var y2 = q2(x); diff --git a/js/src/jit-test/tests/ion/bug729814.js b/js/src/jit-test/tests/ion/bug729814.js new file mode 100644 index 0000000000..d6a6080cba --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729814.js @@ -0,0 +1,9 @@ +j = 0; +out1: +for (i = 0; ; j++) + if (j == 50) + break out1; +while (++i < 100) {} + +assertEq(j, 50); +assertEq(i, 100); diff --git a/js/src/jit-test/tests/ion/bug729884.js b/js/src/jit-test/tests/ion/bug729884.js new file mode 100644 index 0000000000..f6a7304e61 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729884.js @@ -0,0 +1,3 @@ +function x() {} +evaluate("var x = JSON.stringify({});"); +evaluate("for (a = 0; a < 13; ++a) { if (!x) { } }"); diff --git a/js/src/jit-test/tests/ion/bug729899-1.js b/js/src/jit-test/tests/ion/bug729899-1.js new file mode 100644 index 0000000000..b91e0d5cde --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729899-1.js @@ -0,0 +1,19 @@ +var lfcode = new Array(); +lfcode.push("function addThis() {}"); +lfcode.push("\ +var UBound = 0;\ +var expectedvalues = [];\ +addThis();\ +function addThis() {\ + expectedvalues[UBound] = expect;\ + UBound++;\ +}\ +"); +lfcode.push("\ + var expect = 'No Crash';\ + for (var i = 0; i < (2 << 16); i++) addThis();\ +"); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + try { evaluate(file); } catch(lfVare) {} +} diff --git a/js/src/jit-test/tests/ion/bug729899-2.js b/js/src/jit-test/tests/ion/bug729899-2.js new file mode 100644 index 0000000000..f23c868d8a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729899-2.js @@ -0,0 +1,9 @@ +load(libdir + "immutable-prototype.js"); + +function f2() { + if (globalPrototypeChainIsMutable()) + __proto__ = null; +} + +for (var j = 0; j < 50; j++) + f2(); diff --git a/js/src/jit-test/tests/ion/bug729902-1.js b/js/src/jit-test/tests/ion/bug729902-1.js new file mode 100644 index 0000000000..5b214fb98b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729902-1.js @@ -0,0 +1,11 @@ +var x = 2; +outer: +while (x == 10) { + while (x == 10) { + if (x < (null )) + continue outer; + while (x < 10) { + ((function() {}).abstract) = 0; + } + } +} diff --git a/js/src/jit-test/tests/ion/bug729902-2.js b/js/src/jit-test/tests/ion/bug729902-2.js new file mode 100644 index 0000000000..38e6bdbeab --- /dev/null +++ b/js/src/jit-test/tests/ion/bug729902-2.js @@ -0,0 +1,13 @@ +function f() { + var i = 0; + outer: + for (var x = 0; x < 10; x++) { + while (true) { + if (i > 150) + continue outer; + i++; + } + } + assertEq(i, 151); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug730115.js b/js/src/jit-test/tests/ion/bug730115.js new file mode 100644 index 0000000000..8fb04e9719 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug730115.js @@ -0,0 +1,5 @@ +for (var power = 0; power < 20; power++) { + for (var count = 0; count < 1000; count++) { } + continue; + gc( start, (new Date(t)).getTimezoneOffset() ); +} diff --git a/js/src/jit-test/tests/ion/bug730152.js b/js/src/jit-test/tests/ion/bug730152.js new file mode 100644 index 0000000000..fe4ecfe14f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug730152.js @@ -0,0 +1,4 @@ +if (typeof verifybarriers !== "undefined") { + for (var i = 0; i < 30; i++) {} + for (i in Function("gc(verifybarriers()); yield")()) {} +} diff --git a/js/src/jit-test/tests/ion/bug730977-implement-jsop-delprop.js b/js/src/jit-test/tests/ion/bug730977-implement-jsop-delprop.js new file mode 100644 index 0000000000..3939c7d383 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug730977-implement-jsop-delprop.js @@ -0,0 +1,51 @@ + +function makeThing(i) +{ + var thing = {}; + thing.foo = i; + thing.bar = "bar_" + i; + Object.defineProperty(thing, 'baz', {'configurable':false, 'value':[i]}); + return thing; +} +function makeArray(count) +{ + var arr = new Array(count); + for(var i = 0; i < count; i++) { + arr[i] = makeThing(i); + } + return arr; +} +function delBar(obj) +{ + assertEq(Object.getOwnPropertyDescriptor(obj, 'bar') === undefined, false); + assertEq(delete obj.bar, true); + assertEq(Object.getOwnPropertyDescriptor(obj, 'bar') === undefined, true); +} +function delBaz(obj) +{ + var s = delete obj.baz; + assertEq(Object.getOwnPropertyDescriptor(obj, 'baz') === undefined, false); + assertEq(delete obj.baz, false); + assertEq(Object.getOwnPropertyDescriptor(obj, 'baz') === undefined, false); +} +function delNonexistentThingy(obj) +{ + assertEq(Object.getOwnPropertyDescriptor(obj, 'thingy') === undefined, true); + assertEq(delete obj.thingy, true); + assertEq(Object.getOwnPropertyDescriptor(obj, 'thingy') === undefined, true); +} +function testDelProp() +{ + var arr = makeArray(10000); + for(var i = 0; i < 10000; i++) { + var obj = arr[i]; + assertEq(Object.getOwnPropertyDescriptor(obj, 'foo') === undefined, false); + assertEq(delete obj.foo, true); + assertEq(Object.getOwnPropertyDescriptor(obj, 'foo') === undefined, true); + delBar(obj); + delBaz(obj); + delNonexistentThingy(obj); + } +} + +testDelProp(); diff --git a/js/src/jit-test/tests/ion/bug731820.js b/js/src/jit-test/tests/ion/bug731820.js new file mode 100644 index 0000000000..1b34688e68 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug731820.js @@ -0,0 +1,29 @@ +function BigInteger(a, b, c) { + this.array = new Array(); + if (a != null) { + var this_array = this.array; + this.t = 0; + var i = a.length; + while (--i >= 0) { + this_array[this.t++] = 0; + } + } +} +function bnpCopyTo(r, g) { + var this_array = g.array; + for (var i = g.t - 1; i >= 0; --i) + r.array[i] = g.array[i]; + r.t = g.t; +} +function montConvert(x) { + var r = new BigInteger(null); + r.t = 56; + return r; +} +var ba = new Array(); +a = new BigInteger(ba); +new BigInteger("afdsafdsafdsaafdsafdsafdsafdsafdsafdsafdsafdsafdsafdsfds"); +g = montConvert(a); +var r = new BigInteger(null); +bnpCopyTo(r, g); + diff --git a/js/src/jit-test/tests/ion/bug732758.js b/js/src/jit-test/tests/ion/bug732758.js new file mode 100644 index 0000000000..91da521c79 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732758.js @@ -0,0 +1,42 @@ +function tryItOut(code) { + try { + f = Function(code) + } catch (r) {} + v = tryRunning(f, code) + x = String; + for (e in v) {} +} +function tryRunning() { + try { + rv = f(); + return rv; + } catch (r) { + x = String; + } +} +__proto__.__defineSetter__("x", function() {}); +tryItOut("/()/;\"\"()"); +tryItOut("}"); +tryItOut(""); +tryItOut("o"); +tryItOut(")"); +tryItOut("("); +tryItOut(")"); +tryItOut("}"); +tryItOut("}"); +tryItOut(")"); +tryItOut(")"); +tryItOut(""); +tryItOut("l;function u(){/j/}"); +tryItOut("("); +tryItOut("t"); +tryItOut("("); +tryItOut(")"); +tryItOut("("); +tryItOut(""); +tryItOut("{t:g}"); +tryItOut("r"); +tryItOut("p"); +tryItOut("gc()"); +tryItOut("verifybarriers()"); +tryItOut("/**/yield"); diff --git a/js/src/jit-test/tests/ion/bug732846.js b/js/src/jit-test/tests/ion/bug732846.js new file mode 100644 index 0000000000..d33ea66c35 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732846.js @@ -0,0 +1,6 @@ +var BUGNUMBER = { + valueOf: function() { + ++undefined; + } +}; +BUGNUMBER + 1; diff --git a/js/src/jit-test/tests/ion/bug732847.js b/js/src/jit-test/tests/ion/bug732847.js new file mode 100644 index 0000000000..8c343fa6e8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732847.js @@ -0,0 +1,20 @@ +try{} catch (x) {} + +var callStack = []; +function currentFunc() { + return callStack[0]; +} +function reportFailure () { + var funcName = currentFunc(); + // play with the result to cause a SEGV. + var prefix = (funcName) ? funcName : ""; + // Use OSR to compile the function at the end of the first run. + for (var i=0; i < 50; i++) ; +} + +callStack[0] = 'test'; +// Run and compile with a string as result of currentFunc. +reportFailure(); +callStack[0] = undefined; +// Use previously compiled code with the string assumption. +reportFailure(); diff --git a/js/src/jit-test/tests/ion/bug732849.js b/js/src/jit-test/tests/ion/bug732849.js new file mode 100644 index 0000000000..169c4c9071 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732849.js @@ -0,0 +1,2 @@ +a = []; +evaluate("if ('1234' + '' != (01 )) { var a = [];}"); diff --git a/js/src/jit-test/tests/ion/bug732850.js b/js/src/jit-test/tests/ion/bug732850.js new file mode 100644 index 0000000000..7824d77f0e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732850.js @@ -0,0 +1,24 @@ +var gTestcases = new Array(); +var gTc = gTestcases.length; +function TestCase(n, d, e, a) { + this.passed = getTestCaseResult(e, a); + gTestcases[gTc++] = this; +} +function getTestCaseResult(expected, actual) { + if (typeof expected != 'number') + return actual == expected; + return Math.abs(actual - expected) <= 1E-10; +} +function test() { + for ( gTc=0; gTc < gTestcases.length; gTc++ ) { + gTestcases[gTc].passed = writeTestCaseResult(gTestcases[gTc].description +" = "+ gTestcases[gTc].actual); + } + function writeTestCaseResult( expect, actual, string ) { + var passed = getTestCaseResult( expect, actual ); + } +} +var SECTION = "15.4.2.1-1"; +new TestCase( SECTION, eval("var arr = (new Array(1,2)); arr[0]") ); +new TestCase( SECTION, "var arr = (new Array(1,2)); String(arr)", "1,2", (this.abstract++)); +test(); +new TestCase( SECTION, "VAR1 = NaN; VAR2=1; VAR1 -= VAR2", Number.NaN, eval("VAR1 = Number.NaN; VAR2=1; VAR1 -= VAR2")); diff --git a/js/src/jit-test/tests/ion/bug732851.js b/js/src/jit-test/tests/ion/bug732851.js new file mode 100644 index 0000000000..6e249c716d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732851.js @@ -0,0 +1,11 @@ +var OMIT = {}; +var WRITABLES = [true, false, OMIT]; +{ + var desc = {}; + function put(field, value) { + return desc[field] = value; + } + WRITABLES.forEach(function(writable) { + put("writable", writable) + }); +}; diff --git a/js/src/jit-test/tests/ion/bug732858.js b/js/src/jit-test/tests/ion/bug732858.js new file mode 100644 index 0000000000..307939a4fb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732858.js @@ -0,0 +1,9 @@ +var g; +function store() { + return g = "v"; +} +function dump() { + return +store(); +} +for (var i = 0; i < 2; i++) + dump(); diff --git a/js/src/jit-test/tests/ion/bug732859.js b/js/src/jit-test/tests/ion/bug732859.js new file mode 100644 index 0000000000..bde07e7baf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732859.js @@ -0,0 +1,19 @@ +function TestCase(n, d, e, a) { + return function writeHeaderToLog( string ) {}; +} +var SECTION = "15.1.2.4"; +for ( var CHARCODE = 128; CHARCODE < 256; CHARCODE++ ) { + new TestCase( SECTION, "%"+ToHexString(CHARCODE), escape(String.fromCharCode(CHARCODE))); +} +function ToHexString( n ) { + var hex = new Array(); + hex[hex.length] = n % 16; + var string =""; + for ( var index = 0 ; index < hex.length ; index++ ) { + switch ( hex[index] ) { + case 10: + string += "A"; + case 11: + } + } +} diff --git a/js/src/jit-test/tests/ion/bug732860.js b/js/src/jit-test/tests/ion/bug732860.js new file mode 100644 index 0000000000..85af47e2c9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732860.js @@ -0,0 +1,21 @@ +function trySetProperty(o, p, v, strict) { + function strictSetProperty() { + "use strict"; + o[p] = v; + } + try { + strictSetProperty(); + } catch (e) { + return "throw"; + } +} + +//var objs = [[0], [1]]; +var objs = [{a: 0}, {a: 1}]; + +for (var i = 0, sz = objs.length; i < sz; i++) { + var o = objs[i]; + var o2 = Object.preventExtensions(o); + print(i +' ' + o); + assertEq(trySetProperty(o, "baz", 17, true), "throw", "object " + i); +} diff --git a/js/src/jit-test/tests/ion/bug732862.js b/js/src/jit-test/tests/ion/bug732862.js new file mode 100644 index 0000000000..e88d4d3ccb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732862.js @@ -0,0 +1,6 @@ +function testReallyDeepNestedExit() { + for (var i = 0; i < 5*4; i++) {} + for (var o = schedule = i = 9 ; i < 5; i++) {} +} +assertEq(testReallyDeepNestedExit(), undefined); + diff --git a/js/src/jit-test/tests/ion/bug732863.js b/js/src/jit-test/tests/ion/bug732863.js new file mode 100644 index 0000000000..59059acc14 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732863.js @@ -0,0 +1,20 @@ +// Compiled +function TestCase(a) { } + +// Not compiled (try) +function reportCompare (actual) { + TestCase(actual); + try { } catch(ex) { } +} + +// Compiled +function addThis(bound) { + actualvalues[bound] = undefined + actual; + reportCompare(actualvalues[bound]); +} + +var actual = ''; +var actualvalues = []; +addThis(0); +actual = NaN; +addThis(1); diff --git a/js/src/jit-test/tests/ion/bug732864.js b/js/src/jit-test/tests/ion/bug732864.js new file mode 100644 index 0000000000..abcfb8df6a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug732864.js @@ -0,0 +1,22 @@ +function BigInteger() { } +function bnpCopyTo(g) { + var this_array = g.array; + for (var i = g.t; i >= 0; --i) + ; + g.t = g.t; +} +function bnpFromString(n) { + n.t = 0; + var i = 100; + while (--i >= 0) { + n.t++; + } +} +n = new BigInteger(); +n.array = new Array(); +bnpFromString(n); + +g = new BigInteger(); +g.array = new Array(); +g.t = 100; +bnpCopyTo(g); diff --git a/js/src/jit-test/tests/ion/bug734383.js b/js/src/jit-test/tests/ion/bug734383.js new file mode 100644 index 0000000000..b3cb55a9ce --- /dev/null +++ b/js/src/jit-test/tests/ion/bug734383.js @@ -0,0 +1,15 @@ +function foo(a, b) { + var s = "foo"; + for (var j = 0; j < 5; j++) + s += a[b[j]]; + return s; +} + +var a = {a:"zero", b:"one", c:"two", d:"three", e:"four"}; +var b = ["a", "b", "c", "d", "e"]; + +for (var i=0; i<9; i++) + assertEq(foo(a, b), "foozeroonetwothreefour"); + +a.e = 4; +assertEq(foo(a, b), "foozeroonetwothree4"); diff --git a/js/src/jit-test/tests/ion/bug736135-2.js b/js/src/jit-test/tests/ion/bug736135-2.js new file mode 100644 index 0000000000..c174168a1b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug736135-2.js @@ -0,0 +1,23 @@ +function test(a, b) { + var y = a*b; + return y + y; +} + +function negzero(x) { + return x===0 && (1/x)===-Infinity; +} + +var a = 0; +var b = 0; +for(var i=0; i<58; i++) { + var o = test(a, b); + + // Test returns + // * 0, if i < 50 + // * -0, if i >= 50 + assertEq(negzero(o), i>50); + + if (i == 50) { + a = -1 + } +} diff --git a/js/src/jit-test/tests/ion/bug736135.js b/js/src/jit-test/tests/ion/bug736135.js new file mode 100644 index 0000000000..df3a504ce3 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug736135.js @@ -0,0 +1,38 @@ +var g; +function test(a, b) { + + g = 0; + for(var i=0; i<100; i++) { + g += i + } + + var t = a*b; + + for(var i=0; i<100; i++) { + t += x.y; + return t; + } + +} + +function negzero(x) { + return x===0 && (1/x)===-Infinity; +} + + +var x = {y:0}; +var a = 0; +var b = 0; +for(var i=0; i<58; i++) { + var o = test(a, b); + + // Test returns + // * 0, if i < 50 + // * -0, if i >= 50 + assertEq(negzero(o), i>50); + + if (i == 50) { + a = -1 + x.y = -0 + } +} diff --git a/js/src/jit-test/tests/ion/bug736141.js b/js/src/jit-test/tests/ion/bug736141.js new file mode 100644 index 0000000000..b003eed45e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug736141.js @@ -0,0 +1,18 @@ +function test(i) { + return i * 0 + 0; +} + +for(var i=0; i<100; i++){ + var x = test(-i); + assertEq((x===0 && (1/x)===-Infinity), false); // value should be 0, not -0 +} + +function test2(i) { + return 0 - i; +} + +for(var i=-100; i<100; i++){ + var x = test2(-i); + assertEq(x, i); +} + diff --git a/js/src/jit-test/tests/ion/bug739854.js b/js/src/jit-test/tests/ion/bug739854.js new file mode 100644 index 0000000000..226c17425b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug739854.js @@ -0,0 +1,12 @@ +function test(x) { + switch(x) { + case 0: + return 0; + default: + return -1; + } +} + +for(var i=0; i<100; i++) { + assertEq(test(-0), 0); +} diff --git a/js/src/jit-test/tests/ion/bug741202.js b/js/src/jit-test/tests/ion/bug741202.js new file mode 100644 index 0000000000..d386963535 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug741202.js @@ -0,0 +1,9 @@ +var o = {valueOf: function() { return -0x80000000; }}; +var s = {valueOf: function() { return 0; }}; + +for (var i = 0; i < 70; i++) { + assertEq(o >>> 1, 0x40000000); + assertEq(o >>> 0, 0x80000000); + assertEq(1 >>> s, 1); + assertEq(-1 >>> s, 0xffffffff); +} diff --git a/js/src/jit-test/tests/ion/bug741241.js b/js/src/jit-test/tests/ion/bug741241.js new file mode 100644 index 0000000000..5c26c41c52 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug741241.js @@ -0,0 +1,36 @@ + +function f1() {}; +new f1(); + +function f2() { + try{} catch (x) {} +}; +new f2(); + +function f3() { + for (var j = 0; j < 100; j++) {} +}; +new f3(); + +function notEager1(){ + function g1() {}; + new g1(); +} +for (var i = 0; i < 100; i++) + notEager1(); + +function notEager2(){ + function g2() {}; + new g2(); +} +for (var i = 0; i < 100; i++) + notEager2(); + +function notEager3(){ + function g3() { + for (var j = 0; j < 100; j++) {} + }; + new g3(); +} +for (var i = 0; i < 100; i++) + notEager3(); diff --git a/js/src/jit-test/tests/ion/bug743099.js b/js/src/jit-test/tests/ion/bug743099.js new file mode 100644 index 0000000000..48bfffee4d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug743099.js @@ -0,0 +1,9 @@ +function Day( t ) {} +function WeekDay( t ) { + var weekday = (Day(t)+4) % 7; + return( weekday < 0 ? 7 + weekday : weekday ); +} +var expect = 'No Error'; +for (var i = 0; i < 50; i++) { + var [] = [expect ? WeekDay(i.a) : true], print; +} diff --git a/js/src/jit-test/tests/ion/bug746370.js b/js/src/jit-test/tests/ion/bug746370.js new file mode 100644 index 0000000000..c8158eb21a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug746370.js @@ -0,0 +1,7 @@ +var a = ['p', 'q', 'r', 's', 't']; +var o = {p:1, q:2, r:(1), s:4, t:5}; +for (var i in o) { + delete o.p; +} +for (var i of a) + assertEq(o.hasOwnProperty(i), i != 'p'); diff --git a/js/src/jit-test/tests/ion/bug747271.js b/js/src/jit-test/tests/ion/bug747271.js new file mode 100644 index 0000000000..176a44a583 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug747271.js @@ -0,0 +1,18 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +function randomFloat () { + // note that in fuzz-testing, this can used as the size of a buffer to allocate. + // so it shouldn't return astronomic values. The maximum value 10000000 is already quite big. + var fac = 1.0; + var r = Math.random(); + if (r < 0.25) + fac = 10; + else if (r < 0.7) + fac = 10000000; + else if (r < 0.8) + fac = NaN; + return -0.5*fac + Math.random() * fac; +} + +for (var i = 0; i < 100000; i++) + randomFloat(); + diff --git a/js/src/jit-test/tests/ion/bug750588.js b/js/src/jit-test/tests/ion/bug750588.js new file mode 100644 index 0000000000..6fa44d9cce --- /dev/null +++ b/js/src/jit-test/tests/ion/bug750588.js @@ -0,0 +1,13 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: + +function S() { + var t = new Float32Array(1); + var k = 0; + var xx = 19; + var gridRes = 64; + for (var i = 0; i < 100; i++) { + t[k] = -1 + 2 * xx / gridRes; + } + return t[0]; +} +assertEq(S(), -0.40625); diff --git a/js/src/jit-test/tests/ion/bug754713-1.js b/js/src/jit-test/tests/ion/bug754713-1.js new file mode 100644 index 0000000000..cfe4dfe877 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug754713-1.js @@ -0,0 +1,16 @@ +// Don't eliminate a phi if it has no SSA uses but its value is still +// observable in the interpreter. +var t = 100; +function foo(ox) { + var x = ox; + var n = 0; + for (var i = 0; i < 90; i++) { + n += x.f.g; + if (i >= 80) + t; + } +} +function f() {} +function g() {} +f.prototype = {f:g}; +foo(new f()); diff --git a/js/src/jit-test/tests/ion/bug754713-2.js b/js/src/jit-test/tests/ion/bug754713-2.js new file mode 100644 index 0000000000..5a099411c2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug754713-2.js @@ -0,0 +1,29 @@ +// Don't eliminate a phi if it has no SSA uses but its value is still +// observable in the interpreter. +var t1 = 100; +function test1(x) { + // g(x) is inlined with --ion-eager, but don't mark the phi + // for x as unused. + for (var i = 0; i < 90; i++) { + f1(x); + if (i >= 80) + t1; + } +} + +function f1(x) {}; +test1(2); + +var t2 = 100; +function test2(g) { + // g(x) is inlined with --ion-eager, but don't mark the phi + // for g as unused. + for (var i = 0; i < 90; i++) { + g(); + if (i >= 80) + t2; + } +} + +function f2() {}; +test2(f2); diff --git a/js/src/jit-test/tests/ion/bug754713-3.js b/js/src/jit-test/tests/ion/bug754713-3.js new file mode 100644 index 0000000000..a3b6405bfc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug754713-3.js @@ -0,0 +1,9 @@ +var t = 100; +function f(x) { + for (var i = 0; i < 90; i++) { + [(x, 2)]; + if (i >= 80) + t; + } +} +f(2); diff --git a/js/src/jit-test/tests/ion/bug754713-4.js b/js/src/jit-test/tests/ion/bug754713-4.js new file mode 100644 index 0000000000..84afc4554d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug754713-4.js @@ -0,0 +1,6 @@ +function f(x) { + var y = (x < 0) ? 1 : 2; + Math.floor(0); // bailout +} +Math.floor(0); +f(1); diff --git a/js/src/jit-test/tests/ion/bug754720.js b/js/src/jit-test/tests/ion/bug754720.js new file mode 100644 index 0000000000..9c8d813fe6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug754720.js @@ -0,0 +1,64 @@ +function f2(a) { + return f2.arguments; +} + +// The first eager-compiled call will bailout, do not assert. +f2(); + +var o; +o = f2(); +assertEq(o.length, 0); + +o = f2(21); +assertEq(o.length, 1); +assertEq(o[0], 21); + +o = f2(21,42); +assertEq(o.length, 2); +assertEq(o[0], 21); +assertEq(o[1], 42); + +// 100 arguments. +o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); +for (var i in o) + assertEq(o[i], i % 10); + +// 200 arguments. +o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); +for (var i in o) + assertEq(o[i], i % 10); + +// 300 arguments. +o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); +for (var i in o) + assertEq(o[i], i % 10); diff --git a/js/src/jit-test/tests/ion/bug755157.js b/js/src/jit-test/tests/ion/bug755157.js new file mode 100644 index 0000000000..6238d67c5f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug755157.js @@ -0,0 +1,4 @@ +gczeal(2,50); +for (var j = 0; j < 100000; ++j) { + (-0).toString(); +} diff --git a/js/src/jit-test/tests/ion/bug755832.js b/js/src/jit-test/tests/ion/bug755832.js new file mode 100644 index 0000000000..76008cb4a4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug755832.js @@ -0,0 +1,6 @@ +var x; +function f(o) { + o.prop = x = 3; +} +f({}); +f(1); diff --git a/js/src/jit-test/tests/ion/bug756235.js b/js/src/jit-test/tests/ion/bug756235.js new file mode 100644 index 0000000000..9b9a7181e8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug756235.js @@ -0,0 +1,18 @@ +// |jit-test| slow; + +gczeal(2); +try { + function complex(aReal, aImag) { + let Z = new complex(0.0, 0.0); + } + function f(trace) { + const width = 60; + const height = 60; + for (let img_x = 0; img_x < width; ((function() {}).abstract)) { + for (let img_y = 0; img_y < height; img_y++) { + let C = new complex(-2 + (img_x / width) * 3, -1.5 + (img_y / height) * 3); + } + } + } + var timenonjit = f(false); +} catch(exc1) {} diff --git a/js/src/jit-test/tests/ion/bug756238.js b/js/src/jit-test/tests/ion/bug756238.js new file mode 100644 index 0000000000..fe719917f9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug756238.js @@ -0,0 +1,6 @@ +// |jit-test| error: ReferenceError + +outer: + for (var elem in {x:1}) + if (p > "q") + continue outer; diff --git a/js/src/jit-test/tests/ion/bug756240.js b/js/src/jit-test/tests/ion/bug756240.js new file mode 100644 index 0000000000..df737daaf6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug756240.js @@ -0,0 +1,12 @@ +function f() { + var x = 10; + var g = function(x, Int8Array, arr, f) { + for (var i = 0; i < 10; ++i) { + gc(); + } + } + for (var i = 0; i < 10; ++i) { + g(100 * i + x); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/bug756247.js b/js/src/jit-test/tests/ion/bug756247.js new file mode 100644 index 0000000000..83de1c57d5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug756247.js @@ -0,0 +1,13 @@ +function foo(i) { + var n = 0; + for (var i = 0; i < false; i++) + n = a++; + assertEq(n, 0); +} +var a = foo(10); + +function bar(x) { + var y = +(x ? x : "foo"); + assertEq(y, 10); +} +bar(10); diff --git a/js/src/jit-test/tests/ion/bug756780.js b/js/src/jit-test/tests/ion/bug756780.js new file mode 100644 index 0000000000..a252d2c24c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug756780.js @@ -0,0 +1,9 @@ +gczeal(4); +var i = (29); +var status = ''; +var statusmessages = new Array(); +addThis(); +addThis(); +function addThis() { + return statusmessages[i] = status; +} diff --git a/js/src/jit-test/tests/ion/bug756781.js b/js/src/jit-test/tests/ion/bug756781.js new file mode 100644 index 0000000000..aba3b7a3e1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug756781.js @@ -0,0 +1,19 @@ +function AddTestCase( description, expect, actual ) { + new TestCase( SECTION, description, expect, actual ); +} +function TestCase(n, d, e, a) {} +var SECTION = "String/match-004.js"; +re = /0./; +s = 10203040506070809000; +Number.prototype.match = String.prototype.match; +AddRegExpCases( re, "re = " + re , s, String(s), 1, ["02"]); +AddRegExpCases( re, re, s, ["02"]); +function AddRegExpCases( + regexp, str_regexp, string, str_string, index, matches_array ) { + if ( regexp.exec(string) == null || matches_array == null ) { + AddTestCase( string.match(regexp) ); + } + AddTestCase( string.match(regexp).input ); + gczeal(4); +} + diff --git a/js/src/jit-test/tests/ion/bug758181.js b/js/src/jit-test/tests/ion/bug758181.js new file mode 100644 index 0000000000..117c6a2c53 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug758181.js @@ -0,0 +1,13 @@ +function Ld(a) { + var sum = 0; + for (var d = 5; 0 <= d; d--) + sum += a[d]; + return sum; +} +var arr = [0, 1, 2, 3, 4, 5, 6]; + +for (var i=0; i < 50; i++) + assertEq(Ld(arr), 15); + +var arr2 = [0, 1, 2, 3]; +assertEq(Ld(arr2), NaN); diff --git a/js/src/jit-test/tests/ion/bug758991.js b/js/src/jit-test/tests/ion/bug758991.js new file mode 100644 index 0000000000..093a75249a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug758991.js @@ -0,0 +1,16 @@ +// Don't treat f.caller as a singleton property access, it +// has a non-default getter. +function f(obj) { + return f.caller; +} +function g(obj) { + return f(obj); +} +function gg(obj) { + return f.call(obj, obj); +} + +assertEq(g({}), g); + +actual = gg(function() {}); +assertEq(actual, gg); diff --git a/js/src/jit-test/tests/ion/bug759213.js b/js/src/jit-test/tests/ion/bug759213.js new file mode 100644 index 0000000000..5d597b4efb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug759213.js @@ -0,0 +1,9 @@ +// |jit-test| error: ReferenceError +function testNestedForIn() { + var a = {x: 1, y: (/\\u00fd[]/ ), z: 3}; + for (var p1 in a) + for (var { w } = 0 ; ; ) + testJSON(t); +} + +assertEq(testNestedForIn(), 'xx xy xz yx yy yz zx zy zz '); diff --git a/js/src/jit-test/tests/ion/bug760103.js b/js/src/jit-test/tests/ion/bug760103.js new file mode 100644 index 0000000000..4c20c72d28 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug760103.js @@ -0,0 +1,21 @@ +function test1() { + for (var i = 0; i <= 90; i++) { + var x = i/10.0; + if (Math.round(x) !== Math.floor(x + 0.5)) + assertEq(0, 1); + } +} +test1(); + +function test2() { + for (var i = -5; i >= -90; i--) { + if (i === -5) + x = -0.500000000000001; + else + x = i/10.0; + + if (Math.round(x) !== Math.floor(x + 0.5)) + assertEq(0, 1); + } +} +test2(); diff --git a/js/src/jit-test/tests/ion/bug761835.js b/js/src/jit-test/tests/ion/bug761835.js new file mode 100644 index 0000000000..01b831ee5d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug761835.js @@ -0,0 +1,154 @@ +// |jit-test| error: TypeError +function BigInteger(a,b,c) { + this.array = new Array(); + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else this.fromString(a,b); +} +function nbi() { return new BigInteger(null); } +function am3(i,x,w,j,c,n) {} +setupEngine = function(fn, bits) { + dbits = bits; + BI_DB = dbits; + BI_DM = ((1<<dbits)-1); +} +function intAt(s,i) {} +function bnpFromInt(x) {} +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } +function bnpFromString(s,b) { + var this_array = this.array; + if(b == 16) k = 4; + this.t = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(sh == 0) + this_array[this.t++] = x; + else if(sh+k > BI_DB) { + this_array[this.t++] = (x>>(BI_DB-sh)); + } + sh += k; + } +} +function bnAbs() { return (this.s<0)?this.negate():this; } +function nbits(x) { + var r = 1, t; + return r; +} +function bnBitLength() {} +function bnpDLShiftTo(n,r) { + var this_array = this.array; + var r_array = r.array; + for(i = this.t-1; i >= 0; --i) r_array[i+n] = this_array[i]; + r.t = this.t+n; +} +function bnpLShiftTo(n,r) { + var bs = n%BI_DB; + var ds = Math.floor(n/BI_DB), c = (this.s<<bs)&BI_DM, i; + r.t = this.t+ds+1; +} +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + var pt = this.abs(); + var y = nbi(), ts = this.s, ms = m.s; + var pm_array = pm.array; + var nsh = BI_DB-nbits(pm_array[pm.t-1]); + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + var ys = y.t; + var i = r.t, j = i-ys, t = (q==null)?nbi():q; + y.dlShiftTo(j,t); + BigInteger.ONE.dlShiftTo(ys,t); +} +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); +} +function Montgomery(m) { + this.m = m; +} +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); +} +function montRevert(x) { + var r = nbi(); + return r; +} +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +function bnpIsEven() {} +function bnpExp(e,z) { + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + return z.revert(r); +} +function bnModPowInt(e,m) { + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; +BigInteger.ONE = nbv(1); +function parseBigInt(str,r) { + return new BigInteger(str,r); +} +function pkcs1pad2(s,n) { + var ba = new Array(); + return new BigInteger(ba); +} +function RSAKey() { +} +function RSASetPublic(N,E) { + this.n = parseBigInt(N,16); +} +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + var c = this.doPublic(m); + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} +RSAKey.prototype.doPublic = RSADoPublic; +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) { + this.p = parseBigInt(P,16); +} +function RSADoPrivate(x) { + var xp = x.mod(this.p).modPow(this.dmp1, this.p); +} +function RSADecrypt(ctext) { + var c = parseBigInt(ctext, 16); + var m = this.doPrivate(c); +} +RSAKey.prototype.doPrivate = RSADoPrivate; +RSAKey.prototype.setPrivateEx = RSASetPrivateEx; +RSAKey.prototype.decrypt = RSADecrypt; +nValue="a5261939975948bb7a58dffe5ff54e65f0498f9175f5a09288810b8975871e99af3b5dd94057b0fc07535f5f97444504fa35169d461d0d30cf0192e307727c065168c788771c561a9400fb49175e9e6aa4e23fe11af69e9412dd23b0cb6684c4c2429bce139e848ab26d0829073351f4acd36074eafd036a5eb83359d2a698d3"; +eValue="10001"; +dValue="8e9912f6d3645894e8d38cb58c0db81ff516cf4c7e5a14c7f1eddb1459d2cded4d8d293fc97aee6aefb861859c8b6a3d1dfe710463e1f9ddc72048c09751971c4a580aa51eb523357a3cc48d31cfad1d4a165066ed92d4748fb6571211da5cb14bc11b6e2df7c1a559e6d5ac1cd5c94703a22891464fba23d0d965086277a161"; +pValue="d090ce58a92c75233a6486cb0a9209bf3583b64f540c76f5294bb97d285eed33aec220bde14b2417951178ac152ceab6da7090905b478195498b352048f15e7d"; +qValue="cab575dc652bb66df15a0359609d51d1db184750c00c6698b90ef3465c99655103edbf0d54c56aec0ce3c4d22592338092a126a0cc49f65a4a30d222b411e58f"; +dmp1Value="1a24bca8e273df2f0e47c199bbf678604e7df7215480c77c8db39f49b000ce2cf7500038acfff5433b7d582a01f1826e6f4d42e1c57f5e1fef7b12aabc59fd25"; +dmq1Value="3d06982efbbe47339e1f6d36b1216b8a741d410b0c662f54f7118b27b9a4ec9d914337eb39841d8666f3034408cf94f5b62f11c402fc994fe15a05493150d9fd"; +coeffValue="3a3e731acd8960b7ff9eb81a7ff93bd1cfa74cbd56987db58b4594fb09c09084db1734c8143f98b602b981aaa9243ca28deb69b5b280ee8dcee0fd2625e53250"; +setupEngine(am3, 28); +function check_correctness(text, hash) { + var RSA = new RSAKey(); + RSA.setPublic(nValue, eValue); + RSA.setPrivateEx(nValue, eValue, dValue, pValue, qValue, dmp1Value, dmq1Value, coeffValue); + var encrypted = RSA.encrypt(text); + var decrypted = RSA.decrypt(encrypted); +} +check_correctness("Hello! I am some text.", "142b19b40fee712ab9468be296447d38c7dfe81a7850f11ae6aa21e49396a4e90bd6ba4aa385105e15960a59f95447dfad89671da6e08ed42229939583753be84d07558abb4feee4d46a92fd31d962679a1a5f4bf0fb7af414b9a756e18df7e6d1e96971cc66769f3b27d61ad932f2211373e0de388dc040557d4c3c3fe74320"); diff --git a/js/src/jit-test/tests/ion/bug761854.js b/js/src/jit-test/tests/ion/bug761854.js new file mode 100644 index 0000000000..d2e907e696 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug761854.js @@ -0,0 +1,57 @@ +var gTestcases = new Array(); +function TestCase(n, d, e, a) { + this.name = n; + this.description = d; + this.expect = e; + this.actual = a; + this.passed = getTestCaseResult(e, a); + options.stackvalues = []; +function getTestCaseResult(expected, actual) { } +} +var lfcode = new Array(); +lfcode.push("3"); +lfcode.push("var statusitems = [];\ +var actualvalues = [];\ +var expectedvalues = [];\ +actual = '$a$^'.replace(/\\$\\^/, '--');\ +actual = 'ababc'.replace(/abc/, '--');\ +actual = 'ababc'.replace(/abc/g, '--');\ +"); +lfcode.push("\ +var SECTION = \"15.4.4.3-1\";\ +new TestCase( SECTION, \"Array.prototype.join.length\", 1, Array.prototype.join.length );\ +new TestCase( SECTION, \"delete Array.prototype.join.length\", false, delete Array.prototype.join.length );\ +new TestCase( SECTION, \"delete Array.prototype.join.length; Array.prototype.join.length\", 1, eval(\"delete Array.prototype.join.length; Array.prototype.join.length\") );\ +new TestCase( SECTION, eval(\"var TEST_ARRAY = new Array(); TEST_ARRAY.join()\") );\ +new TestCase( SECTION, eval(\"var TEST_ARRAY = new Array(); TEST_ARRAY.join(' ')\") );\ +new TestCase( SECTION, eval(\"var TEST_ARRAY = new Array(null, void 0, true, false, 123, new Object(), new Boolean(true) ); TEST_ARRAY.join('&')\") );\ +new TestCase( SECTION, eval(\"var TEST_ARRAY = new Array(null, void 0, true, false, 123, new Object(), new Boolean(true) ); TEST_ARRAY.join('')\") );\ +new TestCase( SECTION, eval(\"var TEST_ARRAY = new Array(null, void 0, true, false, 123, new Object(), new Boolean(true) ); TEST_ARRAY.join(void 0)\") );\ +new TestCase( SECTION, eval(\"var TEST_ARRAY = new Array(null, void 0, true, false, 123, new Object(), new Boolean(true) ); TEST_ARRAY.join()\") );\ +new TestCase( SECTION, eval(\"var TEST_ARRAY = new Array(true); TEST_ARRAY.join('\\v')\") );\ +SEPARATOR = \"\\t\";\ +new TestCase( SECTION,TEST_ARRAY.join( SEPARATOR ) );\ +"); +lfcode.push("new TestCase( assertEq, \"String.prototype.toString()\", \"\", String.prototype.toString() );\ +new TestCase( SECTION, \"(new String()).toString()\", \"\", (new String()).toString() );\ +new TestCase( SECTION, \"(new String(\\\"\\\")).toString()\", \"\", (new String(\"\")).toString() );\ +new TestCase( SECTION, \"(new String( String() )).toString()\",\"\", (new String(String())).toString() );\ +gczeal(4);\ +new TestCase( SECTION, \"(new String( 0 )).toString()\", \"0\", (new String((1))).toString() );\ +"); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file); +} +function loadFile(lfVarx) { + try { + if (lfVarx.substr(-3) == ".js") { + } else if (!isNaN(lfVarx)) { + lfRunTypeId = lfVarx; + } else { + switch (lfRunTypeId) { + default: evaluate(lfVarx); + } + } + } catch (lfVare) {} +} diff --git a/js/src/jit-test/tests/ion/bug762547.js b/js/src/jit-test/tests/ion/bug762547.js new file mode 100644 index 0000000000..8e9c20b5be --- /dev/null +++ b/js/src/jit-test/tests/ion/bug762547.js @@ -0,0 +1,14 @@ +if (typeof(gcPreserveCode) == "function") + gcPreserveCode(); + +function testStrict() { + var n = 10, a = []; + for (var i = 0; i < 10; ++i) { + a[0] = (gc()); + a[1] = (n !== 10); + a[0x2 ] = (n === null); + a[3] = (n == null); + } + return ; +} +testStrict(); diff --git a/js/src/jit-test/tests/ion/bug764432.js b/js/src/jit-test/tests/ion/bug764432.js new file mode 100644 index 0000000000..fad51db769 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug764432.js @@ -0,0 +1,7 @@ +function test() { + for (var i=0; i<100000; i++) { + var a = -0x80000000; + assertEq(a >>> 32, 2147483648); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/bug764792.js b/js/src/jit-test/tests/ion/bug764792.js new file mode 100644 index 0000000000..056aa0c7af --- /dev/null +++ b/js/src/jit-test/tests/ion/bug764792.js @@ -0,0 +1,7 @@ +test(); +function test() { + for (var i=0; i<2; ++i) {}; + try {} catch ([ q ]) { + function g() {} + } +} diff --git a/js/src/jit-test/tests/ion/bug765454.js b/js/src/jit-test/tests/ion/bug765454.js new file mode 100644 index 0000000000..d91bd87b67 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug765454.js @@ -0,0 +1,26 @@ +var seen = -1; + +// Test to make sure the jits get the number of calls, and return value +// of setters correct. We should not be affected by whether the setter +// modifies its argument or returns some value. +function setter(x) { + this.val = x; + x = 255; + bailout(); + seen++; + assertEq(seen, this.val); + return 5; +} + +function F(){} +Object.defineProperty(F.prototype, "value" , ({set: setter})); + +function test() { + var obj = new F(); + var itrCount = 10000; + for(var i = 0; i < itrCount; i++) { + assertEq(obj.value = i, i); + assertEq(obj.val, i); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/bug765477.js b/js/src/jit-test/tests/ion/bug765477.js new file mode 100644 index 0000000000..abb3623ccf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug765477.js @@ -0,0 +1,8 @@ +function f(useArg2, arg2, expect) { + var args = arguments; + if (useArg2) + args = arg2; + assertEq(args.length, expect); +} +f(false, 0, 3); +f(false, 0, 3); diff --git a/js/src/jit-test/tests/ion/bug765478.js b/js/src/jit-test/tests/ion/bug765478.js new file mode 100644 index 0000000000..0cd9db3ea8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug765478.js @@ -0,0 +1,8 @@ +function test1() { + var input = arguments[undefined]; +} +function test2() { + return arguments["length"]; +} +test1(); +test2(); diff --git a/js/src/jit-test/tests/ion/bug765480.js b/js/src/jit-test/tests/ion/bug765480.js new file mode 100644 index 0000000000..fac2296e9d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug765480.js @@ -0,0 +1,9 @@ + +function fannkuch() { + for (var j = 0; j < 50; j++) { + for (var i = 0; i < 0; i++) { + arguments, Array; + } + } +} +fannkuch(); diff --git a/js/src/jit-test/tests/ion/bug766218.js b/js/src/jit-test/tests/ion/bug766218.js new file mode 100644 index 0000000000..9ac5744f24 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug766218.js @@ -0,0 +1,66 @@ +// Test strict-equality with a constant boolean. +function test1() { + var a = [{}, false, true, 0]; + var res = 0; + + for (var i=0; i<100; i++) { + if (a[i % 4] === false) + res += 1; + } + assertEq(res, 25); + + res = 0; + for (var i=0; i<100; i++) { + if (true !== a[i % 4]) + res += 1; + } + assertEq(res, 75); + + res = 0; + for (var i=0; i<100; i++) { + res += (a[i % 4] === true); + } + assertEq(res, 25); + + res = 0; + for (var i=0; i<100; i++) { + res += (false !== a[i % 4]); + } + assertEq(res, 75); +} +test1(); + +// Test strict-equality with non-constant boolean. +var TRUE = true; +var FALSE = false; + +function test2() { + var a = [{}, false, true, 0]; + var res = 0; + + for (var i=0; i<100; i++) { + if (a[i % 4] === FALSE) + res += 1; + } + assertEq(res, 25); + + res = 0; + for (var i=0; i<100; i++) { + if (TRUE !== a[i % 4]) + res += 1; + } + assertEq(res, 75); + + res = 0; + for (var i=0; i<100; i++) { + res += (a[i % 4] === TRUE); + } + assertEq(res, 25); + + res = 0; + for (var i=0; i<100; i++) { + res += (FALSE !== a[i % 4]); + } + assertEq(res, 75); +} +test2(); diff --git a/js/src/jit-test/tests/ion/bug767665.js b/js/src/jit-test/tests/ion/bug767665.js new file mode 100644 index 0000000000..01b378ff5c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug767665.js @@ -0,0 +1,11 @@ +var failures = 0; +function a() { + return new Array(-1); +} +for (var j = 0; j < 61; ++j) { + try { + a(); + ++failures; + } catch (e) { + } +} diff --git a/js/src/jit-test/tests/ion/bug768436.js b/js/src/jit-test/tests/ion/bug768436.js new file mode 100644 index 0000000000..b01ac0f255 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug768436.js @@ -0,0 +1,18 @@ +function f() { + return new ({}); +} +function g() { + return ({})(); +} +try { + f(); + assertEq(0, 1); +} catch (e) { + assertEq(e instanceof TypeError, true); +} +try { + g(); + assertEq(0, 1); +} catch (e) { + assertEq(e instanceof TypeError, true); +} diff --git a/js/src/jit-test/tests/ion/bug770235.js b/js/src/jit-test/tests/ion/bug770235.js new file mode 100644 index 0000000000..a368442222 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug770235.js @@ -0,0 +1,6 @@ +a = this; +with(evalcx('')) this.__defineGetter__("x", Function); +AddSplitCases( "splitme", "", "''", ["s", "p", "l", "i", "t", "m", "e"] ); +function AddSplitCases( string, separator, str_sep, split_array ) { + for ( var matches = 0; matches < 5; (a.x) ) { matches++; } +} diff --git a/js/src/jit-test/tests/ion/bug770762.js b/js/src/jit-test/tests/ion/bug770762.js new file mode 100644 index 0000000000..6bfa975567 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug770762.js @@ -0,0 +1,18 @@ +function first(a) { + return a[0]; +} +function g() { + first([function() {}])(); +} +first([function() {}]); +first([function() {}]); +first([function() {}]); +first([function() {}]); +first([function() {}]); +first([function() {}]); +first([function() {}]); +first([function() {}]); +first([function() {}]); +first([function() {}]); +g(); +g(); diff --git a/js/src/jit-test/tests/ion/bug772901.js b/js/src/jit-test/tests/ion/bug772901.js new file mode 100644 index 0000000000..164afd1517 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug772901.js @@ -0,0 +1,7 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: + +function f(x) { + delete ((x)++); + arguments[0] !== undefined; +} +f(1, x = [f.ArrayBuffer, undefined], this, this, this) ; diff --git a/js/src/jit-test/tests/ion/bug773587.js b/js/src/jit-test/tests/ion/bug773587.js new file mode 100644 index 0000000000..91df924eca --- /dev/null +++ b/js/src/jit-test/tests/ion/bug773587.js @@ -0,0 +1,6 @@ +StrictEquality(true, new Boolean(true), false, 0); +function StrictEquality(x, y, expect, i) { + result = ( x === y ); + if (i < 100) + StrictEquality(y.environment !== Set.environment, true, false, i + 1); +} diff --git a/js/src/jit-test/tests/ion/bug774006.js b/js/src/jit-test/tests/ion/bug774006.js new file mode 100644 index 0000000000..6037628ab8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug774006.js @@ -0,0 +1,43 @@ + +// Test IonMonkey SetElementIC when ran with --ion-eager. + +function setelem(o, i, v) { + o[i] = v; +} + +var arr = new Array(); +var obj = {}; + +setelem(arr, "prop0", 2); +setelem(arr, 0, 2); // invalidate +setelem(arr, 1, 1); // recompile with setElemIC + +setelem(arr, 0, 0); // set known element. +setelem(arr, 2, 2); // push last element. +setelem(arr, 4, 4); // test out-of-bounds. +setelem(arr, "prop0", 0); +setelem(arr, "prop1", 1); + +setelem(obj, "prop0", 2); +setelem(obj, 0, 2); +setelem(obj, 1, 1); + +setelem(obj, 0, 0); +setelem(obj, 2, 2); +setelem(obj, 4, 4); +setelem(obj, "prop0", 0); +setelem(obj, "prop1", 1); + +assertEq(arr.prop0, 0); +assertEq(arr.prop1, 1); +assertEq(arr[0], 0); +assertEq(arr[1], 1); +assertEq(arr[2], 2); +assertEq(arr[4], 4); + +assertEq(obj.prop0, 0); +assertEq(obj.prop1, 1); +assertEq(obj[0], 0); +assertEq(obj[1], 1); +assertEq(obj[2], 2); +assertEq(obj[4], 4); diff --git a/js/src/jit-test/tests/ion/bug774644.js b/js/src/jit-test/tests/ion/bug774644.js new file mode 100644 index 0000000000..b5a38b5ed0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug774644.js @@ -0,0 +1,10 @@ +// |jit-test| error: ReferenceError +function YearFromTime() {} +addTestCase(); +function addTestCase() { + var start = -62126352000000; + YearFromTime(); + var stop = -62094729600000; + for (var d = start; d < stop; d >>= 86400000) + new TestCase(); +} diff --git a/js/src/jit-test/tests/ion/bug776687.js b/js/src/jit-test/tests/ion/bug776687.js new file mode 100644 index 0000000000..15784c2e1f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug776687.js @@ -0,0 +1,8 @@ +(function() { + for (var a = 0; a < 9; a++) { + if (arguments[a]) { + while (arguments[a]) + ; + } + } +})() diff --git a/js/src/jit-test/tests/ion/bug776748.js b/js/src/jit-test/tests/ion/bug776748.js new file mode 100644 index 0000000000..aa586254ac --- /dev/null +++ b/js/src/jit-test/tests/ion/bug776748.js @@ -0,0 +1,23 @@ +var eCount = 0; +var funs = [function () {}, function () {}]; +function someElement(a) { + ++eCount; + var i = (eCount >= 8) ? 1 : 0; + return a[i] +} +var recursionGuard = 0; +function recursiveThing() { + someElement(funs); + if (++recursionGuard % 2) { + e1(); + } +} +function e1() { + try {} catch (e) {} + someElement(funs); + recursiveThing() +} +recursiveThing() +gc(); +recursiveThing() +recursiveThing() diff --git a/js/src/jit-test/tests/ion/bug779125.js b/js/src/jit-test/tests/ion/bug779125.js new file mode 100644 index 0000000000..1bfd292579 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug779125.js @@ -0,0 +1,7 @@ +function test() { + for (var i = 0; i < 60; i++) { + x = ''.charAt(-1); + assertEq(x, ""); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/bug779245.js b/js/src/jit-test/tests/ion/bug779245.js new file mode 100644 index 0000000000..c3a230f943 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug779245.js @@ -0,0 +1,14 @@ +// |jit-test| error: InternalError: too much recursion +function printStatus (msg) { + msg.split("\n"); +} +function enterFunc () { + return undefined; +} +test(); +function test() { + enterFunc(); + printStatus(""); + for (let j = 0; false;) ; + new test(); +} diff --git a/js/src/jit-test/tests/ion/bug779595.js b/js/src/jit-test/tests/ion/bug779595.js new file mode 100644 index 0000000000..e68c7eb54a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug779595.js @@ -0,0 +1,7 @@ +var SECTION = "15.5.4.10-1"; +function testInt8Array(L) { + var f = new Int8Array(8); +} +for (var i = 0; i < 13000; ++i) { + testInt8Array(SECTION,this); +} diff --git a/js/src/jit-test/tests/ion/bug779812.js b/js/src/jit-test/tests/ion/bug779812.js new file mode 100644 index 0000000000..1302210ad0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug779812.js @@ -0,0 +1,6 @@ +// |jit-test| error: ReferenceError +gczeal(2,1); +(function () { + var m = {} + return { stringify: stringify }; +})(); diff --git a/js/src/jit-test/tests/ion/bug779841.js b/js/src/jit-test/tests/ion/bug779841.js new file mode 100644 index 0000000000..cbfb39116e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug779841.js @@ -0,0 +1,7 @@ +// |jit-test| error: TypeError + +function outer2() { + "use strict"; + new (function () {}).arguments +} +outer2(); diff --git a/js/src/jit-test/tests/ion/bug780842.js b/js/src/jit-test/tests/ion/bug780842.js new file mode 100644 index 0000000000..16a480a0b6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug780842.js @@ -0,0 +1,8 @@ +// |jit-test| --ion-eager;error:TypeError + +function testUKeyUObject(a, key1, key2, key3) { + assertEq(a[-1](), "hi"); +} +for (var i = 0; i < 5; i++) { + testUKeyUObject({}, "a", "b", "c"); +} diff --git a/js/src/jit-test/tests/ion/bug782087.js b/js/src/jit-test/tests/ion/bug782087.js new file mode 100644 index 0000000000..472a0fa3e7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug782087.js @@ -0,0 +1,11 @@ +test(); +function test() { + var n = 12000; + var start = new Date(); + var mceil = Math.floor; + for (i = 3; i<= n; i+=2) {} + var end = mceil (); + var timetaken = end - start; + timetaken = timetaken / 1000; + return timetaken; +} diff --git a/js/src/jit-test/tests/ion/bug783590.js b/js/src/jit-test/tests/ion/bug783590.js new file mode 100644 index 0000000000..9d277e02c9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug783590.js @@ -0,0 +1,13 @@ +// |jit-test| error: TypeError + +var glob = this; +var arr = []; +Object.defineProperty(arr, 0, { + get: (function() { + glob.__proto__; + }) +}); +try { + arr.pop(); +} catch (e) {} +arr.pop(); diff --git a/js/src/jit-test/tests/ion/bug784385.js b/js/src/jit-test/tests/ion/bug784385.js new file mode 100644 index 0000000000..52d331d977 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug784385.js @@ -0,0 +1,9 @@ +Object.defineProperty(Object.prototype, "a", { + set: function(a) { eval(""); return 123; } +}); +var obj = {}; +var obj2 = {x: 1}; +for (var i = 0; i < 100; i++) { + var res = (obj.a = obj2); + res.x = 0xbeef; +} diff --git a/js/src/jit-test/tests/ion/bug786107.js b/js/src/jit-test/tests/ion/bug786107.js new file mode 100644 index 0000000000..6676c00c00 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug786107.js @@ -0,0 +1,10 @@ +function writeHeaderToLog( string ) {} +writeHeaderToLog(-0, this); +gczeal(4); +writeHeaderToLog(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); diff --git a/js/src/jit-test/tests/ion/bug787921.js b/js/src/jit-test/tests/ion/bug787921.js new file mode 100644 index 0000000000..0435644060 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug787921.js @@ -0,0 +1,13 @@ +// |jit-test| error: InternalError: too much recursion +function TestCase(n, d, e, a) { + this.bugnumber = typeof(BUGNUMER) != 'undefined' ? BUGNUMBER : ''; + this.type = (typeof window == 'undefined' ? 'shell' : 'browser'); + gTestcases[gTc++] = this; + if (optionName) {} + {} {} {} // Seems to be required to crash +} +function f() {} +function g(n, h) { + var t = g(TestCase.toString()); +} +g(80, f); diff --git a/js/src/jit-test/tests/ion/bug789300.js b/js/src/jit-test/tests/ion/bug789300.js new file mode 100644 index 0000000000..41438b6419 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug789300.js @@ -0,0 +1,4 @@ +function f() { + return (NaN ? 4 : 5); +} +assertEq(f(), 5); diff --git a/js/src/jit-test/tests/ion/bug789420.js b/js/src/jit-test/tests/ion/bug789420.js new file mode 100644 index 0000000000..5debca5bf5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug789420.js @@ -0,0 +1,38 @@ +function g1(x, y) { + return 0 & y; +} +var c1 = 0; +function f1() { + for (var i=0; i<100; i++) { + g1(i, i); + g1(i, {valueOf: function() { c1++; return 0; }}); + } +} +f1(); +assertEq(c1, 100); + +function g2(x, y) { + ~y; +} +var c2 = 0; +function f2() { + for (var i=0; i<100; i++) { + g2(i, i); + g2(i, {valueOf: function() { c2++; return 0; }}); + } +} +f2(); +assertEq(c2, 100); + +function g3(x, y) { + return 0 >>> y; +} +var c3 = 0; +function f3() { + for (var i=0; i<100; i++) { + g3(i, i); + g3(i, {valueOf: function() { c3++; return 0; }}); + } +} +f3(); +assertEq(c3, 100); diff --git a/js/src/jit-test/tests/ion/bug790479.js b/js/src/jit-test/tests/ion/bug790479.js new file mode 100644 index 0000000000..c7ecdbb350 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug790479.js @@ -0,0 +1,16 @@ +function f() {}; +function g() { + f(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); +} +g(); +g(); +g(); diff --git a/js/src/jit-test/tests/ion/bug792166-1.js b/js/src/jit-test/tests/ion/bug792166-1.js new file mode 100644 index 0000000000..b620c9fb66 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug792166-1.js @@ -0,0 +1,8 @@ +Object.defineProperty(Object.prototype, 'x', { + set: function() {} +}); +var obj = {}; +for (var i = 0; i < 100 ; ++i) { + obj.x = 1; + delete obj.x; +} diff --git a/js/src/jit-test/tests/ion/bug792166-2.js b/js/src/jit-test/tests/ion/bug792166-2.js new file mode 100644 index 0000000000..4a7adc9fc0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug792166-2.js @@ -0,0 +1,8 @@ +try { + __defineGetter__("eval", function() { + this["__proto__"] + }) + delete this["__proto__"] + this["__proto__"] +} catch (e) {} +eval diff --git a/js/src/jit-test/tests/ion/bug792220.js b/js/src/jit-test/tests/ion/bug792220.js new file mode 100644 index 0000000000..7b588f042d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug792220.js @@ -0,0 +1,12 @@ +var p = new Proxy({}, { + has : function(id) {} +}); +RegExp.prototype.__proto__ = p; +function f() { + if (/a/.exec("a")) + return 1; + return 0; +} +delete RegExp.prototype.test; +f(); + diff --git a/js/src/jit-test/tests/ion/bug792234.js b/js/src/jit-test/tests/ion/bug792234.js new file mode 100644 index 0000000000..3fc9661dee --- /dev/null +++ b/js/src/jit-test/tests/ion/bug792234.js @@ -0,0 +1,7 @@ + +function foo() { + return '' / undefined; +} + +foo(); +assertEq(foo(), NaN); diff --git a/js/src/jit-test/tests/ion/bug792944.js b/js/src/jit-test/tests/ion/bug792944.js new file mode 100644 index 0000000000..0c4d54bbcd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug792944.js @@ -0,0 +1,13 @@ +function whoo() { + (new Object()).foo() +} +Object.prototype.foo = function() { return undefined }; +whoo(); +Object.prototype.foo = undefined; +gc(); +try { + whoo(); + assertEq(0, 1); +} catch(e) { + assertEq(e instanceof TypeError, true); +} diff --git a/js/src/jit-test/tests/ion/bug798819.js b/js/src/jit-test/tests/ion/bug798819.js new file mode 100644 index 0000000000..1a602bb6ba --- /dev/null +++ b/js/src/jit-test/tests/ion/bug798819.js @@ -0,0 +1,10 @@ +if (!this.gcPreserveCode) + gcPreserveCode = function() {}; +this.toString = (function() { + x.filter(function() {}) +}); +x = [0, 0, 0, 0, 0, 0, 0]; +gcPreserveCode() +print(this) +gc(); +this + '' diff --git a/js/src/jit-test/tests/ion/bug798823.js b/js/src/jit-test/tests/ion/bug798823.js new file mode 100644 index 0000000000..bd823c82f2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug798823.js @@ -0,0 +1,37 @@ +function g() { + switch (0) { + default: + w = newGlobal(''); + } + return function(f, code) { + try { + evalcx(code, w) + } catch (e) {} + } +} + +function f(code) { + h(Function(code), code); +} +h = g() +f("\ + x = [];\ + y = new Set;\ + z = [];\ + Object.defineProperty(x, 5, {\ + get: (function(j) {}),\ + });\ + Object.defineProperty(z, 3, {});\ + z[9] = 1;\ + x.shift();\ +"); +f("\ + z.every(function() {\ + x.filter(function(j) {\ + if (j) {} else {\ + y.add()\ + }\ + });\ + return 2\ + })\ +"); diff --git a/js/src/jit-test/tests/ion/bug798946.js b/js/src/jit-test/tests/ion/bug798946.js new file mode 100644 index 0000000000..13ba070dbf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug798946.js @@ -0,0 +1,16 @@ +// Don't assert with --ion-eager. +function RandBool() { var x = Math.random() >= 0.5; return x; } +var CHARS = "aaa"; +function RandStr() { + var c = Math.floor(Math.random() * CHARS.length); +} +function RandVal() { + return RandBool() ? RandStr() : RandStr(); +} +function GenerateSpecPermutes(matchVals, resultArray) { + var maxPermuteBody = (1 << matchVals.length) - 1; + for(var bod_pm = 0; bod_pm <= maxPermuteBody; bod_pm++) + for(var k = 0; k < matchVals.length; k++) + var body = ((bod_pm & (1 << k)) > 0) ? null : RandVal(); +} +GenerateSpecPermutes(["foo", "bar", "zing"]); diff --git a/js/src/jit-test/tests/ion/bug799185-2.js b/js/src/jit-test/tests/ion/bug799185-2.js new file mode 100644 index 0000000000..7a5350cfd7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug799185-2.js @@ -0,0 +1,51 @@ +function test(aLauncher) { + var result = null; + + let prefs = 0; + let bundle = 1; + + if (!bundle) { + // Check to see if the user wishes to auto save to the default download + // folder without prompting. Note that preference might not be set. + let autodownload = false; + try { + autodownload = !!autodownload; + } catch (e) { } + + if (autodownload) { + // Retrieve the user's default download directory + let dnldMgr = 2; + let defaultFolder = 3; + + try { + result = 42; + } + catch (ex) { + if (result == 12) { + let prompter = 4; + return; + } + } + + // Check to make sure we have a valid directory, otherwise, prompt + if (result) + return result; + } + } + + // Use file picker to show dialog. + var picker = 0; + if (picker) { + // aSuggestedFileExtension includes the period, so strip it + picker = 1; + } + else { + try { + picker = aLauncher.MIMEInfo.primaryExtension; + } + catch (ex) { } + } + return result; + } + +test({}); diff --git a/js/src/jit-test/tests/ion/bug799185-3.js b/js/src/jit-test/tests/ion/bug799185-3.js new file mode 100644 index 0000000000..6077264c04 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug799185-3.js @@ -0,0 +1,9 @@ +// |jit-test| error: TypeError +function processNode(self) { + try { + if (self) return; + undefined.z; + } finally { + } +}; +processNode(); diff --git a/js/src/jit-test/tests/ion/bug799185-4.js b/js/src/jit-test/tests/ion/bug799185-4.js new file mode 100644 index 0000000000..964e5c9f20 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug799185-4.js @@ -0,0 +1,12 @@ +function foo(aObject) +{ + try { } + catch (ex) { + if (ex.name != "TypeError") + throw ex; + } + try { Object.getPrototypeOf(aObject); } + catch (ex) { } +} + +foo(true); diff --git a/js/src/jit-test/tests/ion/bug799185-5.js b/js/src/jit-test/tests/ion/bug799185-5.js new file mode 100644 index 0000000000..ba54359818 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug799185-5.js @@ -0,0 +1,26 @@ +function foo(aObject) +{ + try { + try { + if (!aObject) + return; + } + catch (ex) { + if (ex.name != "TypeError") + throw ex; + } + finally { + } + undefined.x; + } + catch (ex) { + if (ex.name != "TypeError") + throw ex; + if (ex.name != "TypeError") + throw ex; + } + finally { + } +} + +foo(true); diff --git a/js/src/jit-test/tests/ion/bug799185-6.js b/js/src/jit-test/tests/ion/bug799185-6.js new file mode 100644 index 0000000000..2980cfa596 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug799185-6.js @@ -0,0 +1,19 @@ +function f(a, b, c) { + while (a) { + let x; + if (b) { + if (c) { + d(); + break; // hidden LEAVEBLOCK, then GOTO + } + break; // another hidden LEAVEBLOCK, then GOTO + } + } + null.x; +} + +try { + f(); +} catch (x) { + ; +} diff --git a/js/src/jit-test/tests/ion/bug799185-7.js b/js/src/jit-test/tests/ion/bug799185-7.js new file mode 100644 index 0000000000..86cc0c8afc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug799185-7.js @@ -0,0 +1,66 @@ +var y = undefined; + +try {} catch (x) { + try {} catch (x) { + try {} catch (x) { + } + } +} + +while (false) { + try {} catch ({x,y}) { + try {} catch ({a,b,c,d}) { + if (b) break; + if (c) continue; + } + } finally {} +} + +Label1: +for (let foo = 0; foo < 0; foo++) { + Label2: + for (let bar = 0; bar < 0; bar++) { + if (foo) { + if (bar) + break Label2; + continue Label2; + } else { + if (bar) + break Label1; + continue Label1; + } + } +} + +Label3: +for (let foo = 0; foo < 0; foo++) { + Label4: + for (let bar = 0; bar < 0; bar++) { + if (foo) { + if (bar) + continue Label4; + break Label4; + } else { + if (bar) + continue Label3; + break Label3; + } + } +} + +switch (42) { +default: + try {} catch (x) { + if (x + 1) { + if (x) + break; + break; + } + } + break; +} + +try { + null.x; +} catch (x) { +} diff --git a/js/src/jit-test/tests/ion/bug799185-8.js b/js/src/jit-test/tests/ion/bug799185-8.js new file mode 100644 index 0000000000..b84bcab9ee --- /dev/null +++ b/js/src/jit-test/tests/ion/bug799185-8.js @@ -0,0 +1,19 @@ +// |jit-test| error: TypeError +function testBitOrInconvertibleObjectInconvertibleObject() { + var o1 = {}; + var count2 = 0; + function toString2() { + ++count2; + if (count2 == 95) return {}; + } + var o2 = { toString: toString2 }; + try { + for (var i = 0; i < 100; i++) + var q = o1 | o2; + } catch (e) { + if (i !== 94) + return gc(); + this.bar.foo ^ this + } +} +testBitOrInconvertibleObjectInconvertibleObject() diff --git a/js/src/jit-test/tests/ion/bug799185-9.js b/js/src/jit-test/tests/ion/bug799185-9.js new file mode 100644 index 0000000000..96e6433462 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug799185-9.js @@ -0,0 +1,12 @@ + +function f() { + try {} catch (x) { + return; + } finally { + null.x; + } +} + +try { + f(); +} catch (x) {} diff --git a/js/src/jit-test/tests/ion/bug800179.js b/js/src/jit-test/tests/ion/bug800179.js new file mode 100644 index 0000000000..91b9d87db2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug800179.js @@ -0,0 +1,24 @@ +// |jit-test| error: TypeError + +try { + x = [] + y = function() {} + t = Uint8ClampedArray + Object.defineProperty(x, 1, { + get: (function() { + for (v of t) {} + }) + }) + Object.defineProperty(x, 8, { + configurable: t + }).reverse() +} catch (e) {} +Object.defineProperty([], 1, { + configurable: true, + get: (function() { + for (j = 0; j < 50; ++j) { + y() + } + }) +}).pop() +x.map(y) diff --git a/js/src/jit-test/tests/ion/bug804064.js b/js/src/jit-test/tests/ion/bug804064.js new file mode 100644 index 0000000000..453b6b890d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug804064.js @@ -0,0 +1,22 @@ +function f (v, i) { + var c = v[i]; + switch (c) { + case 0: + assertEq(v[i], 0); + break; + case 1: + assertEq(v[i], 1); + break; + default: + assertEq(c === 0 || c === 1, false); + } +} + +var v = [ + 0, 0.0, 0.1, 1, 1.0, 1.1, + null, undefined, true, false, {}, "", "0", "1", + { valueOf: function () { return 0; } }, + { valueOf: function () { return 1; } } +]; +for (var i = 0; i < 100; i++) + f(v, i % v.length); diff --git a/js/src/jit-test/tests/ion/bug807035.js b/js/src/jit-test/tests/ion/bug807035.js new file mode 100644 index 0000000000..f8ec4b8f63 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug807035.js @@ -0,0 +1,6 @@ + +x = [0, 0, 0, 0, 0, 0, 0, 0] +y = ({}).__proto__ +x.sort(function() { + y.z +}) diff --git a/js/src/jit-test/tests/ion/bug807047.js b/js/src/jit-test/tests/ion/bug807047.js new file mode 100644 index 0000000000..89fedd2d8a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug807047.js @@ -0,0 +1,9 @@ +function f(code) { + eval(code) +} +f("\ + function h({x}) {\ + print(x)\ + }\ + h(/x/);\ +") diff --git a/js/src/jit-test/tests/ion/bug808023.js b/js/src/jit-test/tests/ion/bug808023.js new file mode 100644 index 0000000000..56bcf75bcb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug808023.js @@ -0,0 +1,7 @@ +// |jit-test| error: TypeError +t = "" +function f(code) { + eval("(function(){" + code + "})")() +} +evalcx("") +f("var r=({a:1})[\"\"];t(r)") diff --git a/js/src/jit-test/tests/ion/bug809021.js b/js/src/jit-test/tests/ion/bug809021.js new file mode 100644 index 0000000000..c4c3d436be --- /dev/null +++ b/js/src/jit-test/tests/ion/bug809021.js @@ -0,0 +1,73 @@ +// nactuals > nformals +function testOverflow() { + var called = false; + function f(a) { + assertEq(a, 173); + assertEq(arguments.length, 2); + assertEq(arguments[0], a); + assertEq(arguments[1], a); + called = true; + } + + for (var i=0; i<10; i++) + [173, 173, 173].sort(f); + assertEq(called, true); +} +testOverflow(); + +// nactuals == nformals +function testEqual() { + var called = false; + function f(a, b) { + assertEq(a, 173); + assertEq(arguments.length, 2); + assertEq(arguments[0], a); + assertEq(arguments[1], b); + called = true; + } + + for (var i=0; i<10; i++) + [173, 173, 173].sort(f); + assertEq(called, true); +} +testEqual(); + +// nactuals < nformals +function testUnderflow() { + var called = false; + function f(a, b, c) { + assertEq(a, 173); + assertEq(c, undefined); + assertEq(arguments.length, 2); + assertEq(arguments[0], a); + assertEq(arguments[1], b); + called = true; + } + + for (var i=0; i<10; i++) + [173, 173, 173].sort(f); + assertEq(called, true); +} +testUnderflow(); + +function testUnderflowMany() { + var called = 0; + function f(a, b, c, d, e, f, g, h) { + assertEq(a, 173); + assertEq(arguments.length, 3); + assertEq(arguments[0], a); + assertEq(arguments[1] < 3, true); + assertEq(c.length, 3); + assertEq(d, undefined); + assertEq(e, undefined); + assertEq(f, undefined); + assertEq(g, undefined); + assertEq(h, undefined); + called += 1; + } + + for (var i=0; i<10; i++) + [173, 173, 173].map(f); + assertEq(called, 30); +} +testUnderflowMany(); diff --git a/js/src/jit-test/tests/ion/bug809472.js b/js/src/jit-test/tests/ion/bug809472.js new file mode 100644 index 0000000000..662d6e524c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug809472.js @@ -0,0 +1,19 @@ +function test1(x) { + return (x*((2<<23)-1))|0 +} +function test2(x) { + return (x*((2<<22)-1))|0 +} +function test3(x) { + return (x*((2<<21)-1))|0 +} +function test4(x) { + var b = x + x + 3 + return (b*b) | 0 +} +//MAX_INT +var x = 0x7ffffffe; +assertEq(test1(x), 2113929216); +assertEq(test2(x), 2130706434); +assertEq(test3(x), 2139095042); +assertEq(test4(x), 0); diff --git a/js/src/jit-test/tests/ion/bug810253.js b/js/src/jit-test/tests/ion/bug810253.js new file mode 100644 index 0000000000..2c8685fd91 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug810253.js @@ -0,0 +1,8 @@ +function f(x) { + // Enter via OSR. + for (var j = 0; j < 100; j++) { }; + + for (var i = 0; i < arguments.length; i++) + assertEq(arguments[i], i); +}; +f(0, 1, 2, 3); diff --git a/js/src/jit-test/tests/ion/bug813784.js b/js/src/jit-test/tests/ion/bug813784.js new file mode 100644 index 0000000000..d3b0767135 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug813784.js @@ -0,0 +1,184 @@ +/* Test an inlined argument returns the arguments from the right function */ +function get_arg_2() { return arguments[2]; } +function test() { return get_arg_2(1,2,3); } + +assertEq(test("a","b","c"), 3); +assertEq(test("a","b","c"), 3); + +/* Test the right length of the argument vector gets returned */ +function arg_len() { return arguments.length; } +function test2() { return arg_len(1,2,3); } + +assertEq(test2("a","b","c","d"), 3); +assertEq(test2("a","b","c","d"), 3); + +/* Test returning the argument vector */ +function get_arg() { return arguments; } +function test3() { return get_arg(1,2,3) } + +var arg = test3("a","b","c","d","e"); +assertEq(arg.length, 3); +assertEq(arg[0], 1); +assertEq(arg[1], 2); +assertEq(arg[2], 3); +var arg = test3("a","b","c","d","e"); +assertEq(arg.length, 3); +assertEq(arg[0], 1); +assertEq(arg[1], 2); +assertEq(arg[2], 3); + +/* Test funapply with arguments */ +function return0(a, b, c) { return 0; } +function funapply() { return return0.apply(undefined, arguments); } +function test4() { return funapply(1,2,3) } + +assertEq(test4("a","b","c","d","e"), 0); +assertEq(test4("a","b","c","d","e"), 0); + +/* Test if funapply gets the right arguments */ +function apply3(a, b, c) { + assertEq(a,1) + assertEq(b,2) + assertEq(c,3) +} +function funapply2() { return apply3.apply(undefined, arguments); } +function test5() { return funapply2(1,2,3) } + +test5("a","b","c","d","e"); +test5("a","b","c","d","e"); + +/* Test funapply when argument vector has less args than callee and callee known */ +function apply_fun1(a, b, c) { assertEq(c, undefined) } +function funapply3() { return apply_fun1.apply(undefined, arguments); } +function test7() { return funapply3(1,2) } + +test7("a","b","c","d","e"); +test7("a","b","c","d","e"); + +/* Test funapply when argument vector has less args than callee and callee unknown */ +var fun; +function apply_fun2(a, b, c) { assertEq(c, undefined) } +function funapply4() { return fun.apply(undefined, arguments); } +function test8() { return funapply4(1,2) } + +fun = apply_fun1; +test8("a","b","c","d","e"); +fun = apply_fun2; +test8("a","b","c","d","e"); +fun = apply_fun1; +test8("a","b","c","d","e"); +fun = apply_fun2; +test8("a","b","c","d","e"); + +//////////// + +function dumpArgs(i) { if (i == 90) return funapply5.arguments.length; return [i]; } +function funapply5() { return dumpArgs.apply(undefined, arguments); } +function test9(i) { return funapply5(i); } + +assertEq(test9(89)[0], 89); +assertEq(test9(90), 1); + +///////////// + +function notinlined() { + assertEq(arguments[0], 4); + assertEq(arguments[1], 5); + assertEq(arguments[2], 6); +} + +function inline2(a) { return notinlined(4,5,6); } +function inline() { return inline2(1,2,3); } +function base1() { return inline(-1,-2,-3); } + +base1(10,11,12); +base1(10,11,12); + +//////////////// + +function inlined(a) { + if (a == 11) { + a = undefined; + return arguments; + } +} + +function inline4(a) { return inlined(a,5,6); } +function inline3(a) { return inline4(a,2,3); } +function base2(a) { return inline3(a,-2,-3); } + +var args = base2(10,11,12); +assertEq(args, undefined); +var args = base2(11,11,12); +assertEq(args[0], undefined); +assertEq(args[1], 5); +assertEq(args[2], 6); +var args = base2(10,11,12); +assertEq(args, undefined); +var args = base2(11,11,12); +assertEq(args[0], undefined); +assertEq(args[1], 5); +assertEq(args[2], 6); + +////////////////// + +function arg_len2() { assertEq(arguments.length, 4); } +function bailing_arg_len(a) { + if (a == 90) { + bailout(); + arg_len.apply(undefined, arguments); + } + assertEq(arguments.length, 4); + return arguments; +} +function test10(i) { return bailing_arg_len(i,2,3,4); } + +var args = test10(1, "b"); +assertEq(args.length, 4) +assertEq(args[0], 1) +assertEq(args[1], 2) +assertEq(args[2], 3) +assertEq(args[3], 4) + +var args = test10(90, 'b'); +assertEq(args.length, 4) +assertEq(args[0], 90) +assertEq(args[1], 2) +assertEq(args[2], 3) +assertEq(args[3], 4) + +//////////// + +function dumpArgs11(i) { return funapply11.arguments; eval(""); } +function funapply11(i) { return dumpArgs11(i); } +function test11(i) { return funapply11(i); } + +assertEq(test11(89)[0], 89); +assertEq(test11(90)[0], 90); + +//////////// + +function dumpArgs12(i) { if (i == 90) return funapply12.arguments; return [i]; } +function noion12(i) { return dumpArgs12(i); eval(""); } +function funapply12(i) { return noion12(i); } +function test12(i) { return funapply12(i); } + +assertEq(test12("89")[0], "89"); +assertEq(test12("90")[0], "90"); + +//////////// + +function f13(i) { if (i == "90") return f13.arguments; return [i]; } +function test13(i,b) { return f13(i,b); } + +assertEq(test13("89", 1)[0], "89"); +assertEq(test13("90", 2)[1], 2); + +/////////// + +function noion14(i) { if (i == 2) { return funapply14.arguments; } return [i]; eval(""); } +function funapply14(i) { if (i == 90) { i = "2"; } return noion14(i); } +function test14(i) { return funapply14(i); } + +assertEq(test14("89")[0], "89"); +assertEq(test14("90")[0], "2"); diff --git a/js/src/jit-test/tests/ion/bug816492.js b/js/src/jit-test/tests/ion/bug816492.js new file mode 100644 index 0000000000..c3c5d84fa5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug816492.js @@ -0,0 +1,8 @@ +function TestCase(n, d, e, a) {} +function reportCompare () { + var testcase = new TestCase(); +} +reportCompare(); +schedulegc(10); +this.TestCase=Number; +reportCompare(4294967295.5); diff --git a/js/src/jit-test/tests/ion/bug816786.js b/js/src/jit-test/tests/ion/bug816786.js new file mode 100644 index 0000000000..dde7409632 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug816786.js @@ -0,0 +1,38 @@ +var g; +function test(a, b) { + + g = 0; + for(var i=0; i<100; i++) { + g += i + } + + var t = a*b; + + for(var i=0; i<100; i++) { + t = x.y + t; + return t; + } + +} + +function negzero(x) { + return x===0 && (1/x)===-Infinity; +} + + +var x = {y:0}; +var a = 0; +var b = 0; +for(var i=0; i<58; i++) { + var o = test(a, b); + + // Test returns + // * 0, if i < 50 + // * -0, if i >= 50 + assertEq(negzero(o), i>50); + + if (i == 50) { + a = -1 + x.y = -0 + } +} diff --git a/js/src/jit-test/tests/ion/bug818023.js b/js/src/jit-test/tests/ion/bug818023.js new file mode 100644 index 0000000000..d572aaf243 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug818023.js @@ -0,0 +1,53 @@ +Function.prototype.callX = Function.prototype.call; +var x; +function f() { + x = f.caller; + return x; +} + +function g() { + return f.callX(null); +} + +function h1() { + // native + return ([0].map(f))[0]; +} + +function h2() { + // self-hosted + x = null; + [0].forEach(f); + return x; +} + +function k() { + x = null; + [0, 1].sort(f); + return x; +} + +function l() { + return f(); +} + +assertEq(g(), g); +assertEq(h1(), h1); +assertEq(h2(), h2); +assertEq(k(), k); +assertEq(l(), l); + +var baz; +var foo = {callX: function() { return "m"; }}; +function bar() { + return baz.caller; +} +function m() { + return baz.callX(null); +} + +baz = foo; +assertEq(m(), "m"); +baz = bar; +assertEq(m(), m); +assertEq(m(), m); diff --git a/js/src/jit-test/tests/ion/bug819611.js b/js/src/jit-test/tests/ion/bug819611.js new file mode 100644 index 0000000000..f5b662935b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug819611.js @@ -0,0 +1,6 @@ +// |jit-test| --ion-eager +x = [0, 0] +Object.freeze(x).map(function() { + x.length = 6 +}) +assertEq(x.length,2); diff --git a/js/src/jit-test/tests/ion/bug819794.js b/js/src/jit-test/tests/ion/bug819794.js new file mode 100644 index 0000000000..919c5c47db --- /dev/null +++ b/js/src/jit-test/tests/ion/bug819794.js @@ -0,0 +1,7 @@ +x = []; +x[2] = 1; +x.unshift(0); +x.unshift(0); +x.sort(function() { + return Math.abs(4) +}) diff --git a/js/src/jit-test/tests/ion/bug819865.js b/js/src/jit-test/tests/ion/bug819865.js new file mode 100644 index 0000000000..db198594ef --- /dev/null +++ b/js/src/jit-test/tests/ion/bug819865.js @@ -0,0 +1,2 @@ +(function x() { return (x == x); })(); + diff --git a/js/src/jit-test/tests/ion/bug820873.js b/js/src/jit-test/tests/ion/bug820873.js new file mode 100644 index 0000000000..d50e1b19bb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug820873.js @@ -0,0 +1,28 @@ + +var lfcode = new Array(); +lfcode.push("3"); +lfcode.push("with(evalcx('')) this.__defineGetter__('x', Function);"); +lfcode.push("gczeal(2)"); +lfcode.push("4"); +lfcode.push("\ + var log = '';\ + for (var { m } = i = 0 ; ; i++) {\ + log += x; \ + if (x === 6)\ + a.slow = true; if (i > 1000) break;\ + }\ +"); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file) +} +function loadFile(lfVarx) { + if (!isNaN(lfVarx)) { + lfRunTypeId = parseInt(lfVarx); + } else { + switch (lfRunTypeId) { + case 3: function newFunc(x) { new Function(x)(); }; newFunc(lfVarx); break; + case 4: eval("(function() { " + lfVarx + " })();"); break; + } + } +} diff --git a/js/src/jit-test/tests/ion/bug821788.js b/js/src/jit-test/tests/ion/bug821788.js new file mode 100644 index 0000000000..520b7919c2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug821788.js @@ -0,0 +1,13 @@ + +var appendToActual = function(s) { + actual += s + ','; +} +gczeal(2,(3)); +actual = ''; +function loop(f) {} +function f(j, k) { + var g = function(a, b, c) {} + for (k = 0; k < 5; ++k) + appendToActual(loop(g)); +} +f(1); diff --git a/js/src/jit-test/tests/ion/bug821794.js b/js/src/jit-test/tests/ion/bug821794.js new file mode 100644 index 0000000000..4cc5257ed0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug821794.js @@ -0,0 +1,10 @@ + +gczeal(2); +function bitsinbyte() { + var summary = true[0]; +} +function TimeFunc(func) { + for(var y=0; y<11000; y++) + func(); +} +TimeFunc(bitsinbyte); diff --git a/js/src/jit-test/tests/ion/bug822938.js b/js/src/jit-test/tests/ion/bug822938.js new file mode 100644 index 0000000000..3e28c42056 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug822938.js @@ -0,0 +1,9 @@ + +(function f(i) { + // Add an OSR block which does not define the callee. + for (; false; ) {}; + + // Use the callee. + if (i) + f(i - 1); +})(50); diff --git a/js/src/jit-test/tests/ion/bug824347.js b/js/src/jit-test/tests/ion/bug824347.js new file mode 100644 index 0000000000..5e48c33ba7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug824347.js @@ -0,0 +1,11 @@ +function g() { } +function f(b) { + var test; + if (b) { + g.apply(null, arguments); + var test = 1; + } else { + f(false); + } +} +f(true); diff --git a/js/src/jit-test/tests/ion/bug824473.js b/js/src/jit-test/tests/ion/bug824473.js new file mode 100644 index 0000000000..93726b845f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug824473.js @@ -0,0 +1,41 @@ +function dumpArgs(i) { if (i == 90) return funapply.arguments.length; return [i]; } +function funapply() { return dumpArgs.apply(undefined, arguments); } +function test(i) { return funapply(i); } + +assertEq(test(89)[0], 89); +assertEq(test(90), 1); + +function dumpArgs2(i,b) { if (i == 90) return funapply2.arguments.length; return [i]; } +function funapply2() { return dumpArgs2.apply(undefined, arguments); } +function test2(i,b) { return funapply2(i,b); } + +assertEq(test2(89, 10)[0], 89); +assertEq(test2(90, 10), 2); + +function dumpArgs3(i,b) { if (i == 90) return funapply3.arguments.length; return [i]; } +function funapply3() { return dumpArgs3.apply(undefined, arguments); } +function test3(i,b, c) { return funapply3(i,b,c); } + +assertEq(test3(89, 10, 11)[0], 89); +assertEq(test3(90, 10, 11), 3); + +function dumpArgs4(i) { if (i == 90) return funapply4.arguments.length; return [i]; } +function funapply4() { return dumpArgs4.apply(undefined, arguments); } +function test4(i,b) { return funapply4(i,b,1,2); } + +assertEq(test4(89,10)[0], 89); +assertEq(test4(90,10), 4); + +function dumpArgs5(i,j,k,l) { if (i == 90) return funapply5.arguments.length*10 + l; return [i]; } +function funapply5() { return dumpArgs5.apply(undefined, arguments); } +function test5(i,b) { return funapply5(i,b,1,2); } + +assertEq(test5(89,10)[0], 89); +assertEq(test5(90,10), 42); + +function dumpArgs6(i) { if (i == 90) return funapply6.arguments.length; return [i]; } +function funapply6() { return dumpArgs6.apply(undefined, arguments); } +function test6(i) { return funapply6(i,1,2,3); } + +assertEq(test6(89)[0], 89); +assertEq(test6(90), 4); diff --git a/js/src/jit-test/tests/ion/bug824863.js b/js/src/jit-test/tests/ion/bug824863.js new file mode 100644 index 0000000000..32627b9c6e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug824863.js @@ -0,0 +1,53 @@ +Module = {}; +var Runtime = { + alignMemory: function alignMemory(size, quantum) { + return Math.ceil((size) / (quantum ? quantum : 4)) * (quantum ? quantum : 4); + }, +} +function assert(condition, text) { + throw text; +} +STACK_ROOT = STACKTOP = Runtime.alignMemory(1); +function _main() { + var __stackBase__ = STACKTOP; + var label; + label = 2; + while (1) { + switch (label) { + case 2: + var $f = __stackBase__; + var $1 = __stackBase__ + 12; + var $2 = __stackBase__ + 24; + var $3 = $f | 0; + var $4 = $f + 4 | 0; + var $5 = $f + 8 | 0; + var $_0 = $1 | 0; + var $_1 = $1 + 4 | 0; + var $_2 = $1 + 8 | 0; + var $j_012 = 0; + label = 4; + break; + case 4: + assertEq($_2, 24); + if (($j_012 | 0) != 110) { + var $j_012 = $j_012 + 1; + break; + } + var $23 = $i_014 + 1 | 0; + if (($23 | 0) != 110) { + var $i_014 = $23; + var $j_012 = 0; + label = 4; + break; + } + default: + assert(0, "bad label: " + label); + } + } +} +try { + _main(0, [], 0); + assertEq(0, 1); +} catch(e) { + assertEq(e, "bad label: 4"); +} diff --git a/js/src/jit-test/tests/ion/bug825599.js b/js/src/jit-test/tests/ion/bug825599.js new file mode 100644 index 0000000000..9a08ff150d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug825599.js @@ -0,0 +1,27 @@ +var typedSwitch0 = function (a) { + switch (a) { + case null: + return 0; + case 1.1: + return 1; + case "2": + return 2; + case 3: + return 3; + } + return 4; +}; + +// reuse the same function for testing with different inputs & type. +var typedSwitch1 = eval(`(${typedSwitch0})`); +var typedSwitch2 = eval(`(${typedSwitch0})`); +var typedSwitch3 = eval(`(${typedSwitch0})`); +var typedSwitch4 = eval(`(${typedSwitch0})`); + +for (var i = 0; i < 100; i++) { + assertEq(typedSwitch0(null), 0); + assertEq(typedSwitch1(1.1), 1); + assertEq(typedSwitch2("2"), 2); + assertEq(typedSwitch3(3), 3); + assertEq(typedSwitch4(undefined), 4); +} diff --git a/js/src/jit-test/tests/ion/bug825705.js b/js/src/jit-test/tests/ion/bug825705.js new file mode 100644 index 0000000000..ebd30c21c8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug825705.js @@ -0,0 +1,8 @@ +// Test 1: When constructing x, we shouldn't take the prototype for this. +// it will crash if that happens +evalcx("\ + var x = newGlobal().Object;\ + function f() { return new x; }\ + f();\ + f();\ +", newGlobal()); diff --git a/js/src/jit-test/tests/ion/bug825716.js b/js/src/jit-test/tests/ion/bug825716.js new file mode 100644 index 0000000000..ef1ee10a78 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug825716.js @@ -0,0 +1,3 @@ +(function() { + assertEq(["" % null][0], NaN); +})(); diff --git a/js/src/jit-test/tests/ion/bug827082.js b/js/src/jit-test/tests/ion/bug827082.js new file mode 100644 index 0000000000..9add78d6bc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug827082.js @@ -0,0 +1,2 @@ +// |jit-test| error: TypeError +new [].sort() diff --git a/js/src/jit-test/tests/ion/bug827659-1.js b/js/src/jit-test/tests/ion/bug827659-1.js new file mode 100644 index 0000000000..f56ef46e3c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug827659-1.js @@ -0,0 +1,11 @@ +function f() { + return y.byteOffset; +} +var y; +for (var j = 0; j < 1; ++j) { + y = new Float32Array(); +} +f(); +y = 0; +assertEq(f(), undefined); +assertEq(f(), undefined); diff --git a/js/src/jit-test/tests/ion/bug827821-2.js b/js/src/jit-test/tests/ion/bug827821-2.js new file mode 100644 index 0000000000..f1231320a4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug827821-2.js @@ -0,0 +1,58 @@ +s = newGlobal(''); +function f(code) { + try { + evalcx(code, s) + } catch (e) {} +} +f("\ + options('strict');\ + var x;\ + y='';\ + Object.preventExtensions(this);\ + y=new String;\ + y.toString=(function(){x=new Iterator});\ +"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("var z;"); +f("\ + Iterator=String.prototype.toUpperCase;\ + v=(function(){});\ + Object.defineProperty(Function,0,({enumerable:x}));\ +") diff --git a/js/src/jit-test/tests/ion/bug827821-3.js b/js/src/jit-test/tests/ion/bug827821-3.js new file mode 100644 index 0000000000..0db37061fc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug827821-3.js @@ -0,0 +1,13 @@ +// |jit-test| error: TypeError +function TestCase(n, d, e, a) {} +function reportCompare (expected, actual, description) { + var testcase = new TestCase(); +} +eval("(function() { \ +var summary = 'Do not hang/crash, blah blah blah';\ +var actual = 'No Crash';\ +var expect = 'No Crash';\ +reportCompare(expect, actual, summary);\ +})();"); +eval("(function() { TestCase = Object.prototype.toString; })();"); +eval("gc(); reportCompare();"); diff --git a/js/src/jit-test/tests/ion/bug830269.js b/js/src/jit-test/tests/ion/bug830269.js new file mode 100644 index 0000000000..df4fbde99c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug830269.js @@ -0,0 +1,12 @@ +function f(g,y,z,w) { + return g.apply(undefined, arguments); +} + +function outer() { + var g = function() {}; + for (var i = 0; i < 20000; i++) + f(g,2,3,4,5); + f(g,2,3,4,5); +} + +outer(); diff --git a/js/src/jit-test/tests/ion/bug831087.js b/js/src/jit-test/tests/ion/bug831087.js new file mode 100644 index 0000000000..fb672075df --- /dev/null +++ b/js/src/jit-test/tests/ion/bug831087.js @@ -0,0 +1,15 @@ +function isNegZero(x) { + return x===0 && (1/x)===-Infinity; +} + +try { + for (y = 0; y < 1; y++) { + x = y; + } +} catch (e) {} + +function f() { + (x /= -9) +} +f() +assertEq(isNegZero(this.x), true); diff --git a/js/src/jit-test/tests/ion/bug831424-1.js b/js/src/jit-test/tests/ion/bug831424-1.js new file mode 100644 index 0000000000..a83a326f03 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug831424-1.js @@ -0,0 +1,16 @@ +// |jit-test| error: TypeError +x = []; +Object.defineProperty(this, "y", { + get: function() { + FakeDOMObject.caller + } +}); +Object.defineProperty(x, 3, { + get: function() { + y[13]; + } +}); +(function() { + x.shift(); +})(); + diff --git a/js/src/jit-test/tests/ion/bug831424-2.js b/js/src/jit-test/tests/ion/bug831424-2.js new file mode 100644 index 0000000000..bbd7b0ce6b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug831424-2.js @@ -0,0 +1,16 @@ +// |jit-test| error: TypeError +x = []; +Object.defineProperty(this, "y", { + get: function() { + print.caller + } +}); +Object.defineProperty(x, 3, { + get: function() { + y[13]; + } +}); +(function() { + x.shift(); +})(); + diff --git a/js/src/jit-test/tests/ion/bug832058.js b/js/src/jit-test/tests/ion/bug832058.js new file mode 100644 index 0000000000..22dd37a4e0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug832058.js @@ -0,0 +1,16 @@ +// |jit-test| +function f(c) { + var b = arguments; + if (c == 1) + b = 1; + return b; +} + +evaluate("f('a', 'b', 'c', 'd', 'e');"); +function test(){ + var args = f('a', (0), 'c'); + var s; + for (var v of args) + s += v; +} +test(); diff --git a/js/src/jit-test/tests/ion/bug833076.js b/js/src/jit-test/tests/ion/bug833076.js new file mode 100644 index 0000000000..a2ab5d35a7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug833076.js @@ -0,0 +1,6 @@ + +eval("(function() { " + "\ +var Constr = function( ... property) {};\ +Constr.prototype = 0.0;\ +var c = new Constr( ) ;\ +" + " })();"); diff --git a/js/src/jit-test/tests/ion/bug835178.js b/js/src/jit-test/tests/ion/bug835178.js new file mode 100644 index 0000000000..ec23951924 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug835178.js @@ -0,0 +1,30 @@ +function boo() { return foo.arguments[0] } +function foo(a,b,c) { if (a == 0) {a = 2; return boo();} return a } +function inlined() { return foo.apply({}, arguments); } +function test(a,b,c) { return inlined(a,b,c) } + +assertEq(test(1,2,3), 1); +assertEq(test(0,2,3), 2); + +function g(a) { if (g.arguments[1]) return true; return false; }; +function f() { return g(false, true); }; +function h() { return f(false, false); } + +assertEq(h(false, false), true); +assertEq(h(false, false), true); + +function g2(a) { if (a) { if (g2.arguments[1]) return true; return false; } return true; }; +function f2(a) { return g2(a, true); }; +function h2(a) { return f2(a, false); } + +assertEq(h2(false, false), true); +assertEq(h2(true, false), true); + +// Currently disabled for now, but in testsuite to be sure +function g3(a) { return a }; +function f3(a) { a = 3; return g3.apply({}, arguments); }; +function h3(a) { return f3(a); } + +assertEq(h3(0), 3); +assertEq(h3(0), 3); + diff --git a/js/src/jit-test/tests/ion/bug835496.js b/js/src/jit-test/tests/ion/bug835496.js new file mode 100644 index 0000000000..0c40c0106c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug835496.js @@ -0,0 +1,6 @@ +// |jit-test| error: TypeError + +(function([{x}]) {})({ + t: 0, + "1": 0 +}) diff --git a/js/src/jit-test/tests/ion/bug836102.js b/js/src/jit-test/tests/ion/bug836102.js new file mode 100644 index 0000000000..3fbcbede64 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug836102.js @@ -0,0 +1,26 @@ +function t() { + var x = 0x123456789abcd; + x = x + x; // x = 640511947003802 + x = x + x; // x = 1281023894007604 + x = x + x; // x = 2562047788015208 + x = x + x; // x = 5124095576030416 + x = x + x; // x = 10248191152060832 + assertEq(x+1 | 0, -248153696) +} +t() + +function t2() { + var x = -0x123456789abcd; + x = x + x; + x = x + x; + x = x + x; + x = x + x; + x = x + x; + assertEq(x + 7 | 0, 248153704) +} +t2() + +function t() { + var x = 4294967296+1; + assertEq(x|0, 1); +} diff --git a/js/src/jit-test/tests/ion/bug836274.js b/js/src/jit-test/tests/ion/bug836274.js new file mode 100644 index 0000000000..f1960c2dd9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug836274.js @@ -0,0 +1,13 @@ +function dumpArgs6(i) { + if (i == 90) + return funapply6.arguments.length; + return [i]; +} +function funapply6() { + return dumpArgs6.apply({}, arguments); +} +function test6(i) { + return funapply6(i,1,2,3); +} +test6(89)[0] +test6(0.2) diff --git a/js/src/jit-test/tests/ion/bug836705.js b/js/src/jit-test/tests/ion/bug836705.js new file mode 100644 index 0000000000..aa13c082e1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug836705.js @@ -0,0 +1,12 @@ + +Object.prototype[3] = 3; +var sjcl = { + cipher: {}, +}; +sjcl.cipher.aes = function (a) { + d = a.slice(0); + for (a=0; a < 60; a++) { + c = d[a - 1]; + } +}; +new sjcl.cipher.aes([0xffffffff, 0xffffffff]); diff --git a/js/src/jit-test/tests/ion/bug837312.js b/js/src/jit-test/tests/ion/bug837312.js new file mode 100644 index 0000000000..75c326813e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug837312.js @@ -0,0 +1,7 @@ +function bind(f) { + return f.call.apply(f.bind, arguments); +} +function g(a, b) {} +for(var i=0; i<20; ++i) { + g.call(undefined, {}, bind(function(){})); +} diff --git a/js/src/jit-test/tests/ion/bug839315.js b/js/src/jit-test/tests/ion/bug839315.js new file mode 100644 index 0000000000..88446a7d23 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug839315.js @@ -0,0 +1,18 @@ +function f(x) { + switch(x) { + case 0: + case 100: + } +} +f(""); +evaluate('f({})', { noScriptRval : true }); + +function g(x) { + switch(x) { + case 0.1: + case 100: + } +} + +g(false); +evaluate('g({})', { noScriptRval : true }); diff --git a/js/src/jit-test/tests/ion/bug843866.js b/js/src/jit-test/tests/ion/bug843866.js new file mode 100644 index 0000000000..53f3b3a669 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug843866.js @@ -0,0 +1,8 @@ +function g(f) {} +function f(b) { + g.apply(null, arguments); + + if (b < 10) + f(b+1); +} +f(0); diff --git a/js/src/jit-test/tests/ion/bug843875.js b/js/src/jit-test/tests/ion/bug843875.js new file mode 100644 index 0000000000..3f648a4f2f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug843875.js @@ -0,0 +1,8 @@ + +function writeHeaderToLog( string ) { } +var input = [ 0xfffffff0, 101 ]; +var arr = new Uint32Array(input.length); +var expected = [ 0xffffffff, 101 ]; +for (var i=0; i<arr.length; i++) { + arr[i] = writeHeaderToLog[i] = expected[i] = i * 8; +} diff --git a/js/src/jit-test/tests/ion/bug844059.js b/js/src/jit-test/tests/ion/bug844059.js new file mode 100644 index 0000000000..d4bbe5c664 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug844059.js @@ -0,0 +1,12 @@ + +function assertArraysFirstEqual(a, b) { + assertEq(a[0], b[0]); +} + +function check(b) { + var a = deserialize(serialize(b)); + assertArraysFirstEqual(a, b); +} + +check(new Int8Array(1)); +check(new Float64Array(1)); diff --git a/js/src/jit-test/tests/ion/bug844364.js b/js/src/jit-test/tests/ion/bug844364.js new file mode 100644 index 0000000000..c94514c803 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug844364.js @@ -0,0 +1,6 @@ + +function f() { + eval("this") +} +f() +f() diff --git a/js/src/jit-test/tests/ion/bug844452.js b/js/src/jit-test/tests/ion/bug844452.js new file mode 100644 index 0000000000..bcbaf1f0ac --- /dev/null +++ b/js/src/jit-test/tests/ion/bug844452.js @@ -0,0 +1,10 @@ +function reportCompare (expected, actual) { + return expected != actual; +} + +function wrap() { + reportCompare(true, true); +} + +reportCompare('', ''); +wrap(); diff --git a/js/src/jit-test/tests/ion/bug844459.js b/js/src/jit-test/tests/ion/bug844459.js new file mode 100644 index 0000000000..b1901d7747 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug844459.js @@ -0,0 +1,7 @@ + + +function testEvalThrow(x, y) { + eval(""); +} +for (var i = 0; i < 5; i++) + testEvalThrow.call(""); diff --git a/js/src/jit-test/tests/ion/bug846330.js b/js/src/jit-test/tests/ion/bug846330.js new file mode 100644 index 0000000000..c07b3dbc5e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug846330.js @@ -0,0 +1,9 @@ + +function outer(code) { + function inner() { + eval(code); + } + inner(); +} +outer("1"); +outer("assertEq(typeof arguments, 'object');"); diff --git a/js/src/jit-test/tests/ion/bug847412.js b/js/src/jit-test/tests/ion/bug847412.js new file mode 100644 index 0000000000..90a297d25b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug847412.js @@ -0,0 +1,19 @@ + +var gTestcases = new Array(); +var gTc = gTestcases.length; +function TestCase( a) { + this.actual = a; + gTestcases[gTc++] = this; +} +function test() { + for ( gTc=0; gTc < gTestcases.length; gTc++ ) { + gTestcases[gTc].actual.toString() + } +} +function testOverwritingSparseHole() { + for (var i = 0; i < 50; i++) + new TestCase(eval("VAR1 = 0; VAR2 = -1; VAR1 %= VAR2; VAR1")); +} +testOverwritingSparseHole(); +test(); +JSON.stringify(this); diff --git a/js/src/jit-test/tests/ion/bug848319.js b/js/src/jit-test/tests/ion/bug848319.js new file mode 100644 index 0000000000..8f8f46457a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug848319.js @@ -0,0 +1,25 @@ +function test() { + for(var i=0; i<2; i++) { + var a = /a/; + assertEq(a.lastIndex, 0); + a.exec("aaa"); + assertEq(a.lastIndex, 0); + } + + for(var i=0; i<2; i++) { + var a = /a/g; + assertEq(a.lastIndex, 0); + a.exec("aaa"); + assertEq(a.lastIndex, 1); + } + + for(var i=0; i<2; i++) { + var a = /a/y; + assertEq(a.lastIndex, 0); + a.exec("aaa"); + assertEq(a.lastIndex, 1); + } +} + +test(); +test(); diff --git a/js/src/jit-test/tests/ion/bug848733.js b/js/src/jit-test/tests/ion/bug848733.js new file mode 100644 index 0000000000..68d0cde460 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug848733.js @@ -0,0 +1,11 @@ +var a = [1]; +function f(x) { + var round = Math.round; + for (var i=0; i<20; i++) { + a[0] = round(a[0]); + if (x > 500) + a[0] = "a"; + } +} +for (var i=0; i<550; i++) + f(i); diff --git a/js/src/jit-test/tests/ion/bug848803.js b/js/src/jit-test/tests/ion/bug848803.js new file mode 100644 index 0000000000..09718882a9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug848803.js @@ -0,0 +1,34 @@ +var JSIL = {};
+JSIL.TypeNameParseState = function ()
+{
+ this.input = 15;
+ this.pos = 0
+};
+JSIL.TypeNameParseState.prototype.substr = function (e)
+{
+ return e;
+};
+JSIL.TypeNameParseState.prototype.moveNext = function ()
+{
+ this.pos += 1;
+ return this.pos < this.input;
+};
+JSIL.TypeNameParseResult = function () {};
+JSIL.ParseTypeNameImpl = function (n)
+{
+ var i = new JSIL.TypeNameParseState()
+ var u = new JSIL.TypeNameParseResult;
+ while (i.moveNext())
+ {
+ if (n)
+ {
+ while (true)
+ u.assembly = 1
+ }
+ u.assembly = i.substr(i.pos + 1);
+ }
+ return u
+};
+
+var u = JSIL.ParseTypeNameImpl(false)
+assertEq(u.assembly, 15)
diff --git a/js/src/jit-test/tests/ion/bug849781-2.js b/js/src/jit-test/tests/ion/bug849781-2.js new file mode 100644 index 0000000000..031ded4272 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug849781-2.js @@ -0,0 +1,9 @@ +function assertArraysFirstEqual(a, b) { + if (a.length != b.length) {} +} +function check(b) { + var a = deserialize(serialize(b)); + assertArraysFirstEqual(a, b); +} +check(new Int8Array(1)); +evaluate("check(['a', 'b']);"); diff --git a/js/src/jit-test/tests/ion/bug849781.js b/js/src/jit-test/tests/ion/bug849781.js new file mode 100644 index 0000000000..3818b97ef9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug849781.js @@ -0,0 +1,8 @@ +function c0(i) { print(i) } +function c1() { c0.apply({}, arguments); } +function c2() { c1.apply({}, arguments); } +function c3(a) { c2(a); } +c3(1); +c3(1); +c3(""); +c3(""); diff --git a/js/src/jit-test/tests/ion/bug850099.js b/js/src/jit-test/tests/ion/bug850099.js new file mode 100644 index 0000000000..79f36e9962 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug850099.js @@ -0,0 +1,4 @@ +var buf = serialize(-1); +var nbuf = serialize(undefined); +for (var j = 0 ; j < 5; j++) + buf[j + 8] = nbuf[j]; diff --git a/js/src/jit-test/tests/ion/bug851064.js b/js/src/jit-test/tests/ion/bug851064.js new file mode 100644 index 0000000000..e7af13aa21 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug851064.js @@ -0,0 +1,13 @@ +var base = "azertyuiopqsdfghjklmwxcvbn"; +function createRopedString() { + var test = ""; + for (var i=0; i<2; i++) { + test += base; + } + return test; +} + +assertEq(createRopedString().substr(0,10), base.substr(0,10)); +assertEq(createRopedString().substr(0,26), base.substr(0,26)); +assertEq(createRopedString().substr(26,10), base.substr(0,10)); +assertEq(createRopedString().substr(24,10), base.substr(24,2) + base.substr(0,8)); diff --git a/js/src/jit-test/tests/ion/bug851067.js b/js/src/jit-test/tests/ion/bug851067.js new file mode 100644 index 0000000000..79f3b1b1ef --- /dev/null +++ b/js/src/jit-test/tests/ion/bug851067.js @@ -0,0 +1,6 @@ +function toPrinted(value) { + value = String(value); +} +String = Array; +toPrinted(123); +evaluate('toPrinted("foo");'); diff --git a/js/src/jit-test/tests/ion/bug851792.js b/js/src/jit-test/tests/ion/bug851792.js new file mode 100644 index 0000000000..598bf4f8ed --- /dev/null +++ b/js/src/jit-test/tests/ion/bug851792.js @@ -0,0 +1,135 @@ +// Based on tests/ion/typed-arrays-1.js, but with string indexes +function testInt8() { + var arr1 = new Int8Array(50); + var arr2 = new Uint8Array(50); + var arr3 = new Uint8ClampedArray(50); + + for (var i=0; i<arr1.length; i++) { + arr1[i] = arr2[i] = arr3[i] = i * 8; + } + var res = 0; + for (var i=0; i<arr1.length; i++) { + res += arr1[i+""] + arr2[i+""] + arr3[i+""] + arr2["10".concat("")]; + } + assertEq(res, 18334); +} +testInt8(); + +function testInt16() { + var arr1 = new Int16Array(70); + var arr2 = new Uint16Array(70); + + for (var i=0; i<arr1.length; i++) { + arr1[i] = arr2[i] = i * 1000; + } + var res = 0; + for (var i=0; i<arr1.length; i++) { + res += arr1[i+""] + arr2[i+""] + arr2["1".concat("")] + arr1["3".concat("")]; + } + assertEq(res, 2423024); +} +testInt16(); + +function testInt32() { + var arr = new Int32Array(60); + arr[0] = -50; + for (var i=1; i<arr.length; i++) { + arr[i] = arr[(i-1)+""] + arr["0".concat("")]; + ++arr[0]; + } + assertEq(arr[(arr.length-1)+""], -1289); +} +testInt32(); + +function testUint32() { + function sum(arr) { + var res = 0; + for (var i=0; i<arr.length; i++) { + res += arr[i+""]; + } + return res; + } + var arr = new Uint32Array(100); + for (var i=0; i<arr.length; i++) { + arr[i] = i; + } + + // Compile sum() to read int32 values. + assertEq(sum(arr), 4950); + + // Add a large uint32 so that the sum no longer fits in an + // int32. sum() should be recompiled to return a double. + arr[50] = 0xffffeeee; + assertEq(sum(arr), 4294967826); +} +testUint32(); + +function testFloat() { + var arr1 = new Float32Array(75); + var arr2 = new Float64Array(75); + arr1[0] = arr2[0] = Math.PI * 1234567.8; + + for (var i=1; i<75; i++) { + arr1[i] = arr1[(i-1)+""] + arr1[0]; + arr2[i] = arr2[(i-1)+""] + arr2[0]; + } + assertEq(arr1["74".concat("")] > 290888255, true); + assertEq(arr1["74".concat("")] < 290888257, true); + + assertEq(arr2["74".concat("")] > 290888184, true); + assertEq(arr2["74".concat("")] < 290888185, true); +} +testFloat(); + +function testCanonicalNaN() { + // NaN values have to be canonicalized. Otherwise, malicious scripts could + // construct arbitrary Value's (due to our NaN boxing Value representation). + var buf = new ArrayBuffer(16); + var uint32 = new Uint32Array(buf); + var f64 = new Float64Array(buf); + var f32 = new Float32Array(buf); + + // Evil: write a JSVAL_TYPE_OBJECT type tag... + uint32[0] = 0xffffff87; + uint32[1] = 0xffffff87; + + // Make sure this value is interpreted as a double. + for (var i=0; i<3; i++) { + assertEq(isNaN(f64["0".concat("")]), true); + assertEq(isNaN(f32["0".concat("")]), true); + } +} +testCanonicalNaN(); + +function testOutOfBounds() { + var buf = new ArrayBuffer(16); + var uint32 = new Uint32Array(buf); + + uint32[0] = 0; + uint32[1] = 1; + + for (var i=0; i<3; i++) { + assertEq(uint32["0".concat("")], 0); + assertEq(uint32["1".concat("")], 1); + assertEq(uint32["2".concat("")], 0); + assertEq(uint32["17".concat("")], undefined); + } +} +testOutOfBounds(); + +function testStrangeIndexes() { + var buf = new ArrayBuffer(16); + var uint32 = new Uint32Array(buf); + + uint32[0] = 0; + uint32[1] = 1; + + indexes = ["0", "1", "2", "3", "17", "3.5", "NaN", "undefined", "null"]; + solutions = [0, 1, 0, 0, undefined, undefined, undefined, undefined, undefined]; + + for (var i=0; i<indexes.length; i++) { + assertEq(uint32[indexes[i]], solutions[i]); + } +} +testStrangeIndexes(); + diff --git a/js/src/jit-test/tests/ion/bug852140.js b/js/src/jit-test/tests/ion/bug852140.js new file mode 100644 index 0000000000..159e2d57e4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug852140.js @@ -0,0 +1,8 @@ +function reportCompare (expected, actual) { + if (expected != actual) {} +} +function exitFunc (funcName) { + return reportCompare(undefined, ''); +} +reportCompare('', ''); +exitFunc(); diff --git a/js/src/jit-test/tests/ion/bug852342.js b/js/src/jit-test/tests/ion/bug852342.js new file mode 100644 index 0000000000..c2fee0c8fc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug852342.js @@ -0,0 +1,12 @@ + +function A(a) { } +function B(b) { this.b = b; } +function C(c) {} +function makeArray(n) { + var classes = [A, B, C]; + var arr = []; + for (var i = (" "); i < n; i++) { + arr.push(new classes[i % 3](i % 3)); + } +} +makeArray(30000); diff --git a/js/src/jit-test/tests/ion/bug855514.js b/js/src/jit-test/tests/ion/bug855514.js new file mode 100644 index 0000000000..8cc7776047 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug855514.js @@ -0,0 +1,25 @@ +var b = 1.5; +var arr; +function f_int(arr, index) { + for (var i=0; i<100; i++) { + arr[index]++; + } +} +arr = [1, 2, 3]; +f_int(arr, "1"); +assertEq(arr[1], 102); +arr = [1, 2, 3]; +f_int(arr, 1); +assertEq(arr[1], 102); + +function f_double(arr, index) { + for (var i=0; i<100; i++) { + arr[+Math.pow(index,1.0)*1.5/b]++; + } +} +arr = [1, 2, 3]; +f_double(arr, 1.0); +assertEq(arr[1], 102); +arr = [1, 2, 3]; +f_double(arr, NaN); +assertEq(arr[1], 2); diff --git a/js/src/jit-test/tests/ion/bug858586.js b/js/src/jit-test/tests/ion/bug858586.js new file mode 100644 index 0000000000..73e10872d4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug858586.js @@ -0,0 +1,30 @@ +// This test case was created before %TypedArrayPrototype%.toString was +// implemented. Now that we've got %TypedArrayPrototype%.toString the test will +// attempt to create a 300300001 character long string and either timeout or +// throw an oom error. Restore the original behavior by replacing toString with +// Object.prototype.toString. +Uint8ClampedArray.prototype.toString = Object.prototype.toString; + +function A(a) { this.a = a; } +A.prototype.foo = function (x) {}; +function B(b) { this.b = b; } +B.prototype.foo = function (x) {}; +function C(c) {} +function makeArray(n) { + var classes = [A, B, C]; + var arr = []; + for (var i = 0; i < n; i++) { + arr.push(new classes[i % 3](i % 3)); + } + return arr; +} +function runner(arr, resultArray, len) { + for (var i = 0; i < len; i++) { + var obj = arr[i]; + resultArray[0] += new obj.foo(i); + } +} +var resultArray = [0]; +var arr = makeArray(30000); +C.prototype.foo = Uint8ClampedArray; +runner(arr, resultArray, 30000); diff --git a/js/src/jit-test/tests/ion/bug858617.js b/js/src/jit-test/tests/ion/bug858617.js new file mode 100644 index 0000000000..b322e72bf4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug858617.js @@ -0,0 +1,18 @@ +function TestCase(e, a) { + getTestCaseResult(e, a); +}; +function reportCompare (expected, actual) { + new TestCase(expected, actual); +} +function enterFunc() {} +function getTestCaseResult(expected, actual) { + return actual == expected; +} +reportCompare('', ''); +evaluate("\ +test();\ +function test() {\ + enterFunc();\ + reportCompare();\ +}\ +"); diff --git a/js/src/jit-test/tests/ion/bug860838-1.js b/js/src/jit-test/tests/ion/bug860838-1.js new file mode 100644 index 0000000000..087ae9841e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug860838-1.js @@ -0,0 +1,39 @@ +var counter = 0; +function inc() { return counter++ } +var imp = { inc:inc }; + +function FFI1(stdlib, foreign) { + "use asm"; + + var inc = foreign.inc; + + function g() { + return inc()|0 + } + + return g +} + +function FFI2(stdlib, foreign) { + "use asm"; + + var inc=foreign.inc; + + function g() { + inc() + } + + return g +} + + +var f = FFI2(this, imp); // produces AOT-compiled version +f() +assertEq(counter, 1); + +var f = FFI1(this, imp); // produces AOT-compiled version + +assertEq(f(), 1); +assertEq(counter, 2); +assertEq(f(), 2); +assertEq(counter, 3); diff --git a/js/src/jit-test/tests/ion/bug860838-2.js b/js/src/jit-test/tests/ion/bug860838-2.js new file mode 100644 index 0000000000..df1e47e086 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug860838-2.js @@ -0,0 +1,28 @@ +function func1() { return "123" } +function func2(a,b,c,d,e) { return "123" } +var imp = { func1:func1, func2:func2 }; + +function FFI1(stdlib, foreign) { + "use asm"; + + var func1 = foreign.func1; + var func2 = foreign.func2; + + function g() { + return func1()|0 + } + + function h() { + return func2()|0 + } + + return {g:g, h:h}; +} + +var f = FFI1(this, imp); // produces AOT-compiled version + +assertEq(f.g(), 123); +assertEq(f.g(), 123); + +assertEq(f.h(), 123); +assertEq(f.h(), 123); diff --git a/js/src/jit-test/tests/ion/bug860838-3.js b/js/src/jit-test/tests/ion/bug860838-3.js new file mode 100644 index 0000000000..a24862bb98 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug860838-3.js @@ -0,0 +1,44 @@ + +var buf = new ArrayBuffer(4096); +var f64 = new Float64Array(buf); +var i32 = new Int32Array(buf); +var u32 = new Uint32Array(buf); + +function ffi(d) { + str = String(d); +} + + +function FFI1(glob, imp, b) { + "use asm"; + + var i8=new glob.Int8Array(b);var u8=new glob.Uint8Array(b); + var i16=new glob.Int16Array(b);var u16=new glob.Uint16Array(b); + var i32=new glob.Int32Array(b);var u32=new glob.Uint32Array(b); + var f32=new glob.Float32Array(b);var f64=new glob.Float64Array(b); + + var ffi=imp.ffi; + + function g() { + ffi(+f64[0]) + } + return g +} + +g = FFI1(this, {ffi:ffi}, buf); + + +// that sounds dangerous! +var a = [0,1,0xffff0000,0x7fff0000,0xfff80000,0x7ff80000,0xfffc0000,0x7ffc0000,0xffffffff,0x0000ffff,0x00008fff7]; +for (i of a) { + for (j of a) { + u32[0] = i; + u32[1] = j; + + print(f64[0]+" (input)"); + //assertEq(f(), f64[0]); + + g(); + assertEq(str, String(f64[0])); + } +} diff --git a/js/src/jit-test/tests/ion/bug860838-4.js b/js/src/jit-test/tests/ion/bug860838-4.js new file mode 100644 index 0000000000..88804d2b4c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug860838-4.js @@ -0,0 +1,54 @@ +function DiagModule(stdlib, foreign) { + "use asm"; + + var sqrt = stdlib.Math.sqrt; + var test = foreign.test; + var foo = foreign.foo; + + function square(x) { + x = x|0; + return ((x|0)+(x|0))|0; + } + + function diag() { + var x = 0.0; + while(1) { + test(1, x); + x = x+1.0 + if (x > 15.0) + return 0; + } + return 0; + } + + function diag_1() { + foo(); + return 0; + } + + + return { diag: diag, diag_1:diag_1 }; +} + +var foreign = { + test:function(a,b) { + print(a+":"+b) + var c = [0.0]; + if (b > 10) + return c[1]; + return c[0]; + }, + foo:function() { + with({}) {}; + gc(); + } +} + +// make sure foreign is compiled + +var fast = DiagModule(this, foreign); // produces AOT-compiled version +print(fast.diag_1()); // 5 +gc() +print(fast.diag()); // 5 + + diff --git a/js/src/jit-test/tests/ion/bug860838.js b/js/src/jit-test/tests/ion/bug860838.js new file mode 100644 index 0000000000..60de82349f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug860838.js @@ -0,0 +1,51 @@ +enableOsiPointRegisterChecks(); + +function DiagModule(stdlib, foreign) { + "use asm"; + + var sqrt = stdlib.Math.sqrt; + var test = foreign.test; + + function square(x) { + x = x|0; + return ((x|0)+(x|0))|0; + } + + function diag() { + var x = 0.0; + while(1) { + test(1, x); + x = x+1.0 + if (x > 15.0) + return 0; + } + return 0; + } + + function diag_1() { + test(); + return 0; + } + + + return { diag: diag, diag_1:diag_1 }; +} + +var foreign = { + test:function(a,b) { + print(a+":"+b) + var c = [0.0]; + if (b > 10) + return c[1]; + return c[0]; + } +} + +// make sure foreign is compiled + +var fast = DiagModule(this, foreign); // produces AOT-compiled version +print(fast.diag()); // 5 +gc() +print(fast.diag()); // 5 + + diff --git a/js/src/jit-test/tests/ion/bug861165.js b/js/src/jit-test/tests/ion/bug861165.js new file mode 100644 index 0000000000..f6b469715b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug861165.js @@ -0,0 +1,83 @@ +// IM has the following fastpaths: +// - constant index (constant) +// - need negative int check (neg) +// - needs hole check (hole) +// So to test everything we have to do: +// constant | neg | hole +// test 1: 0 0 0 +// test 2: 1 0 0 +// test 3: 0 1 0 +// test 4: 1 1 0 +// test 5: 0 0 1 +// test 6: 1 0 1 +// test 7: 0 1 1 +// test 8: 1 1 1 + +function test1(index, a) { + if (index < 0) + index = -index + return index in a; +} +assertEq(test1(1, [1,2]), true); + +function test2(a) { + return 0 in a; +} +assertEq(test2([1,2]), true); + +function test3(index, a) { + return index in a; +} + +var arr3 = []; +arr3["-1073741828"] = 17; +assertEq(test3(-1073741828, arr3), true); + +function test4(a) { + return -1073741828 in a; +} +assertEq(test4(arr3), true); + + +function test5(index, a) { + if (index < 0) + index = -index + return index in a; +} +var arr5 = []; +arr5[0] = 1 +arr5[1] = 1 +arr5[2] = 1 +arr5[4] = 1 +assertEq(test5(1, arr5), true); +assertEq(test5(3, arr5), false); + +function test7a(a) { + return 3 in a; +} +function test7b(a) { + return 4 in a; +} +assertEq(test7a(arr5), false); +assertEq(test7b(arr5), true); + +function test8(index, a) { + return index in a; +} +arr5["-1073741828"] = 17; +assertEq(test8(-1073741828, arr5), true); +assertEq(test8(3, arr5), false); +assertEq(test8(0, arr5), true); + +function test9a(a) { + return 0 in a; +} +function test9b(a) { + return 3 in a; +} +function test9c(a) { + return -1073741828 in a; +} +assertEq(test9a(arr5), true); +assertEq(test9b(arr5), false); +assertEq(test9c(arr5), true); diff --git a/js/src/jit-test/tests/ion/bug861419.js b/js/src/jit-test/tests/ion/bug861419.js new file mode 100644 index 0000000000..20496f6620 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug861419.js @@ -0,0 +1,18 @@ + +arguments = []; +try { + arguments.toSource = (function() { + __proto__.y = x + }) + y = this + print(x = 8) + a = arguments + for (v of this) {} +} catch (e) {} +function f() { + "HELLO " + y +} +f() +f() +y = 1[7] +f() diff --git a/js/src/jit-test/tests/ion/bug861439.js b/js/src/jit-test/tests/ion/bug861439.js new file mode 100644 index 0000000000..f06dae6a65 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug861439.js @@ -0,0 +1,14 @@ + +try { + x = evalcx('') + toSource = (function() { + x = (new WeakMap).get(function() {}) + }) + valueOf = (function() { + schedulezone(x) + }) + this + '' + for (v of this) {} +} catch (e) {} +gc() +this + 1 diff --git a/js/src/jit-test/tests/ion/bug862100.js b/js/src/jit-test/tests/ion/bug862100.js new file mode 100644 index 0000000000..4ba973c040 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug862100.js @@ -0,0 +1,14 @@ + +function TestCase(n, d, e, a) {} +function reportCompare (expected, actual, description) { + new TestCase("", description, expected, actual); +} +new TestCase( "", "", 0, Number(new Number()) ); +reportCompare(true, true); +evaluate("\ +function TestCase(n, d, e, a) {}\ +test_negation(-2147483648, 2147483648);\ +test_negation(2147483647, -2147483647);\ +function test_negation(value, expected) {\ + reportCompare(expected, '', '-(' + value + ') == ' + expected);\ +}"); diff --git a/js/src/jit-test/tests/ion/bug862357.js b/js/src/jit-test/tests/ion/bug862357.js new file mode 100644 index 0000000000..2a44c525d5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug862357.js @@ -0,0 +1,22 @@ +// |jit-test| error: ReferenceError +function TestCase(e, a) { + return this.passed = (e == a); +} +function reportCompare (expected, actual) { + var expected_t = typeof expected; + var actual_t = typeof actual; + if (expected_t != actual_t) + printStatus(); + new TestCase(expected, actual); +} +var expect = ''; +reportCompare(expect, ''); +try { + test(); +} catch(exc1) {} +function test() { + var { expect } = ''; + for (var a = 1; a < 2; ++a) + reportCompare(expect, ''); +} +test(); diff --git a/js/src/jit-test/tests/ion/bug863261.js b/js/src/jit-test/tests/ion/bug863261.js new file mode 100644 index 0000000000..6e05f7be25 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug863261.js @@ -0,0 +1,12 @@ +// |jit-test| error: InternalError: too much recursion +function TestCase(d) { + toPrinted(d) +} +function toPrinted(value) {} +function reportCompare (expected, actual, description) { + if (typeof description == "undefined") + toPrinted(expected); + new TestCase(description); + reportCompare(); +} +reportCompare(Math['LN2'], Math['LN2'], 0); diff --git a/js/src/jit-test/tests/ion/bug863755.js b/js/src/jit-test/tests/ion/bug863755.js new file mode 100644 index 0000000000..6c59de480d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug863755.js @@ -0,0 +1,20 @@ +function TestCase( e, a) { + getTestCaseResult(e, a); +} +function getTestCaseResult(expected, actual) {} +var msPerSecond = 1000; +var TIME_0000 = (function () { })(); +var now = new Date(); +var TIME_NOW = now.valueOf(); +function msFromTime(t) { + var ms = t % msPerSecond; + return ((ms < 0) ? msPerSecond + ms : ms ); +} +new TestCase(false, eval("true, false")); +addTestCase( TIME_NOW ); +addTestCase( TIME_0000 ); +function addTestCase( t ) { + for ( m = 0; m <= 1000; m+=100 ) { + new TestCase(msFromTime(t), (new Date(t)).getMilliseconds()); + } +} diff --git a/js/src/jit-test/tests/ion/bug866611.js b/js/src/jit-test/tests/ion/bug866611.js new file mode 100644 index 0000000000..ce399d9b61 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug866611.js @@ -0,0 +1,5 @@ +// |jit-test| error: InternalError +y = 'x' +for (var i=0; i<100; i++) + y += y; +print(y.length); diff --git a/js/src/jit-test/tests/ion/bug867820.js b/js/src/jit-test/tests/ion/bug867820.js new file mode 100644 index 0000000000..2ee5c63234 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug867820.js @@ -0,0 +1,18 @@ + +function AddTestCase(expect, actual) { + new TestCase(expect, actual); +} +function TestCase(e, a) { + this.expect = e; + getTestCaseResult(e, a); +} +function getTestCaseResult(expected, actual) { + if (actual != expected) {} +} +AddRegExpCases(false, Math.pow(2,31)); +AddRegExpCases("", Math.pow(2,30) - 1); +function AddRegExpCases(m, l) { + AddTestCase(""); + AddTestCase(m, true); + AddTestCase(l, 0); +} diff --git a/js/src/jit-test/tests/ion/bug870328.js b/js/src/jit-test/tests/ion/bug870328.js new file mode 100644 index 0000000000..f5f0b1e9d5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug870328.js @@ -0,0 +1,7 @@ +var g = newGlobal("same-compartment"); +try { + evalcx("'use strict'; (function() { x = 33; })()", g); + assertEq(0, 1); +} catch(e) { + assertEq(e.toString().includes("variable x"), true); +} diff --git a/js/src/jit-test/tests/ion/bug870356.js b/js/src/jit-test/tests/ion/bug870356.js new file mode 100644 index 0000000000..a634a18161 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug870356.js @@ -0,0 +1,33 @@ +function f1(x) { + return Math.round(x); +} +assertEq(f1(3.3), 3); +assertEq(f1(-2.842170943040401e-14), -0); + +function f2(x) { + return Math.round(x); +} +assertEq(f2(3.3), 3); +assertEq(f2(-1.3), -1); +assertEq(f2(-1.8), -2); +assertEq(f2(-0.9), -1); +assertEq(f2(-0.6), -1); +assertEq(f2(-0.4), -0); + +function f3(x) { + return Math.round(x); +} +assertEq(f3(0.1), 0); +assertEq(f3(-0.5), -0); + +function f4(x) { + return Math.round(x); +} +assertEq(f4(0.1), 0); +assertEq(f4(-0), -0); + +function f5(x) { + return Math.round(x); +} +assertEq(f5(2.9), 3); +assertEq(f5(NaN), NaN); diff --git a/js/src/jit-test/tests/ion/bug872331.js b/js/src/jit-test/tests/ion/bug872331.js new file mode 100644 index 0000000000..fe32ea2220 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug872331.js @@ -0,0 +1,10 @@ + +function d(t) { + if (t >= undefined) {} +} +function s() { + d(null); +} +d(3); +s(); +s(); diff --git a/js/src/jit-test/tests/ion/bug875452.js b/js/src/jit-test/tests/ion/bug875452.js new file mode 100644 index 0000000000..27a1de4ac7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug875452.js @@ -0,0 +1,26 @@ +// |jit-test| --ion-eager + +function causeBreak(t, n, r) { + gcPreserveCode(); + gc(); +} + +function centralizeGetProp(p) +{ + p.someProp; +} + +var handler = {}; + +function test() { + var p = new Proxy({}, handler); + + var count = 5; + for (var i = 0; i < count; i++) { + centralizeGetProp(p); + } + handler.get = causeBreak; + centralizeGetProp(p); +} + +test(); diff --git a/js/src/jit-test/tests/ion/bug875656.js b/js/src/jit-test/tests/ion/bug875656.js new file mode 100644 index 0000000000..202ef2d0fa --- /dev/null +++ b/js/src/jit-test/tests/ion/bug875656.js @@ -0,0 +1,2 @@ +enableGeckoProfiling(); +Object.getOwnPropertyNames(this); diff --git a/js/src/jit-test/tests/ion/bug875804.js b/js/src/jit-test/tests/ion/bug875804.js new file mode 100644 index 0000000000..670fce9ca9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug875804.js @@ -0,0 +1,11 @@ + +eval('(function () {\ +function* range(n) {\ + for (var i = 0; i < 5000; i++)\ + yield i;\ +}\ +var r = range(10);\ +var i = 0;\ +for (var x of r)\ + assertEq(x,i++);\ +' + '})();'); diff --git a/js/src/jit-test/tests/ion/bug876465.js b/js/src/jit-test/tests/ion/bug876465.js new file mode 100644 index 0000000000..010848bdda --- /dev/null +++ b/js/src/jit-test/tests/ion/bug876465.js @@ -0,0 +1,20 @@ +function initialize() {}; +function test() { +eval("\ +var Class = {\ + create : function() {\ + return function() {\ + this.initialize.apply(this, arguments);\ + }\ + }\ +};\ +var Foo = Class.create();\ +Foo.prototype = {\ + initialize : function() {\ + this.bar = Foo();\ + }\ +};\ +var foo = new Foo();\ +"); +} +test(); diff --git a/js/src/jit-test/tests/ion/bug877936-2.js b/js/src/jit-test/tests/ion/bug877936-2.js new file mode 100644 index 0000000000..df57275337 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug877936-2.js @@ -0,0 +1,5 @@ +rex = RegExp("()()()()()()()()()()(z)?(y)"); +a = ["sub"]; +a[230] = '' + "a" +f = Function.apply(null, a); +"xyz".replace(rex, f); diff --git a/js/src/jit-test/tests/ion/bug877936.js b/js/src/jit-test/tests/ion/bug877936.js new file mode 100644 index 0000000000..a0d0e62dcd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug877936.js @@ -0,0 +1,44 @@ +try{} catch(e){} + +function test(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a) { + return 0; +} + + +test(); +test(); + +///////////////////// + +function test2() { + return 0; +} + +var a = 1; +test2(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a); +test2(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a); + +///////////////////// + +function test4() { + test3() +} + +function test3(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a) { + return 0; +} + +test4(); + +///////////////////// + +function test6() { + test5.apply({}, []) +} + +function test5() { + return 0; +} + +test6(); +test6(); diff --git a/js/src/jit-test/tests/ion/bug878444.js b/js/src/jit-test/tests/ion/bug878444.js new file mode 100644 index 0000000000..4b5e9f66a2 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug878444.js @@ -0,0 +1,26 @@ +function g() +{ + function f(v) { + v = +v; + var infinity = 0.0; + var three = 0.0; + var nan = 0.; + var result = 0; + + infinity = 1.0 / 0.0; + three = v + 2.0; + nan = (infinity % three); + result = ~~(nan + 42.0); + + return result | 0; + } + return f +} + +g = g() +var x; +for(i=0; i < 20000; ++i) +{ + x = g(1.0) +} +assertEq(x, 0); diff --git a/js/src/jit-test/tests/ion/bug878510.js b/js/src/jit-test/tests/ion/bug878510.js new file mode 100644 index 0000000000..05b84976d9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug878510.js @@ -0,0 +1,20 @@ +function neg0(x) { + return x===0 && (1/x)===-Infinity; +} + +function test(x,y) { + if (x == 1.1) + return 0; + else if (x == "a") + return 0; + return x*y +} + +var t = 0; +for(var i=0; i<1005; i++) { + test(1.1) + test("a") + t = test((i<1003)?i:-0, 0); +} + +assertEq(neg0(t), true); diff --git a/js/src/jit-test/tests/ion/bug882323.js b/js/src/jit-test/tests/ion/bug882323.js new file mode 100644 index 0000000000..010e8e7335 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug882323.js @@ -0,0 +1,23 @@ +var ints = new Int8Array(16); +ints[0] = 42; +function intElementAt(index) { + return ints[index]; +} +assertEq(intElementAt(16), undefined); +assertEq(intElementAt(0), 42); + +var floats = new Float64Array(16); +floats[0] = 3.14; +function floatElementAt(index) { + return floats[index]; +} +assertEq(floatElementAt(16), undefined); +assertEq(floatElementAt(0), 3.14); + +var uints = new Uint32Array(16); +uints[0] = 123; +function uintElementAt(index) { + return uints[index]; +} +assertEq(uintElementAt(16), undefined); +assertEq(uintElementAt(0), 123); diff --git a/js/src/jit-test/tests/ion/bug882565-1.js b/js/src/jit-test/tests/ion/bug882565-1.js new file mode 100644 index 0000000000..84db9258ff --- /dev/null +++ b/js/src/jit-test/tests/ion/bug882565-1.js @@ -0,0 +1,21 @@ +function zero() { return 0; } +function f(x, a) { + var test = 0x7fffffff; + + for (var i=0; i<100; i++) + { + if (i == 0) { + test += 1; + var t = (test > zero()) * (0xffffffff >>> x); + } + var test2 = test | 0; + return [test2,t]; + } +} +var t = f(0, ""); +assertEq(t[0], 0x80000000 | 0); +assertEq(t[1], 0xffffffff >>> 0); + +var t = f(0); +assertEq(t[0], 0x80000000 | 0); +assertEq(t[1], 0xffffffff >>> 0); diff --git a/js/src/jit-test/tests/ion/bug882565.js b/js/src/jit-test/tests/ion/bug882565.js new file mode 100644 index 0000000000..5e51ac7927 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug882565.js @@ -0,0 +1,4 @@ +function zero() { return 0; } +function f(x) { return (0xffffffff > zero()) * (0xffffffff >>> x); } +assertEq(f(0), 4294967295); +assertEq(f(0), 4294967295); diff --git a/js/src/jit-test/tests/ion/bug883490.js b/js/src/jit-test/tests/ion/bug883490.js new file mode 100644 index 0000000000..2fb27fda52 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug883490.js @@ -0,0 +1,33 @@ +//|jit-test| error: TypeError +function coerceForeign(stdlib, foreign) +{ + "use asm"; + + var g = foreign.g; + var h = foreign.h; + + function f() { + +g(0); + +g(1); + +g(2); + +h(2); + +h(3); + } + + return f; +} +function blaat() { + +} + +var t = coerceForeign(undefined, { + g: function(a) { + if (a == 2) + var blaat = new blaat(); + }, + h: function(b) { + print(b); + } +}) + +t(); diff --git a/js/src/jit-test/tests/ion/bug885660.js b/js/src/jit-test/tests/ion/bug885660.js new file mode 100644 index 0000000000..f7fed17dc1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug885660.js @@ -0,0 +1,23 @@ +function ff(parsedTypeName, defaultContext) { + var context = null; + + if (context === null) + context = defaultContext; + + if (parsedTypeName.genericArguments !== null) { + for (var i = 0; i < 0; i++) {} + } + + var foo = parsedTypeName.type; + assertEq(typeof context, "object"); + return foo; +} +function test() { + var parsedTypeName = {genericArguments: null}; + for (var i=0; i<140; i++) { + if (i > 100) + parsedTypeName.x = {}; + ff(parsedTypeName, {}); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/bug886243.js b/js/src/jit-test/tests/ion/bug886243.js new file mode 100644 index 0000000000..a28030e686 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug886243.js @@ -0,0 +1,9 @@ +function f(x) +{ + if (Math.imul(0xffffffff, x)) { + return -x; + } + return 1; +} +f(0); +f(0); diff --git a/js/src/jit-test/tests/ion/bug886246.js b/js/src/jit-test/tests/ion/bug886246.js new file mode 100644 index 0000000000..ab6144edde --- /dev/null +++ b/js/src/jit-test/tests/ion/bug886246.js @@ -0,0 +1,11 @@ +function f(x) +{ + x = x|0; + return ~~((x ? 1.0e60 : 1.0e60) + 1.0); +} + +var r = -1; +for(var i = 0; i < 20000; i++) { + r = f(); +} +assertEq(r, 0); diff --git a/js/src/jit-test/tests/ion/bug888568.js b/js/src/jit-test/tests/ion/bug888568.js new file mode 100644 index 0000000000..82102865f4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug888568.js @@ -0,0 +1,5 @@ +function f() { + return (42.0 + Math.abs(1.0e60)) | 0; +} +assertEq(f(), 0); +assertEq(f(), 0); diff --git a/js/src/jit-test/tests/ion/bug889186.js b/js/src/jit-test/tests/ion/bug889186.js new file mode 100644 index 0000000000..b1a08d37c1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug889186.js @@ -0,0 +1,6 @@ +function f() +{ + return (4 >>> 0) > ((0 % (1 == 2)) >>> 0); +} +assertEq(f(), true); +assertEq(f(), true); diff --git a/js/src/jit-test/tests/ion/bug889451.js b/js/src/jit-test/tests/ion/bug889451.js new file mode 100644 index 0000000000..5c7c9ce4e6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug889451.js @@ -0,0 +1,18 @@ +/* +js> (((-1 >>> 1) + 1) * Math.pow(2, 52 - 30) + 1) & 1 +0 +js> (((-1 >> 1) + 1) * Math.pow(2, 52 - 30) + 1) & 1 +1 +*/ + +function f(x) { + if (x >= 0) { + // if it does not fail, try with lower power of 2. + return (((x >>> 1) + 1) * 4194304 /* 2 ** (52 - 30) */ + 1) & 1; + } + return 2; +} + +assertEq(f(-1 >>> 1), 1); +assertEq(f(-1 >>> 0), 0); +assertEq(f(-1 >>> 0), 0); diff --git a/js/src/jit-test/tests/ion/bug890722.js b/js/src/jit-test/tests/ion/bug890722.js new file mode 100644 index 0000000000..c06221915d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug890722.js @@ -0,0 +1,29 @@ + +// Test setting return value; + +function bail() { bailout(); } +function bail2() { bailout(); return 2; } + +// Test 1: Test setting/getting return value in ionmonkey +function test() { + return evalcx("1;"); +} +assertEq(test(), 1) + +// Test 3: Test ion -> baseline +function test2() { + return evaluate("1; bail2();"); +} +assertEq(test2(), 2) + +// Test 3: Test ion -> baseline +function test3() { + return evaluate("1; bail2(); 3"); +} +assertEq(test3(), 3) + +// Test4: Test baseline -> ion entering (very fragile, since iterations need to be precise, before it gets tested) +function test4() { + return evaluate("1; for(var i=0; i<1097; i++) { 3; };"); +} +assertEq(test4(), 3) diff --git a/js/src/jit-test/tests/ion/bug892426.js b/js/src/jit-test/tests/ion/bug892426.js new file mode 100644 index 0000000000..37e0c40f78 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug892426.js @@ -0,0 +1,9 @@ +function selfsetelem(o, i) { + o[i] = o; +} +var arr = new Array(); +selfsetelem(arr, "prop0"); +selfsetelem(arr, 0); +selfsetelem(arr, 1); +selfsetelem(arr, 0); +arr.prop0.toString(); diff --git a/js/src/jit-test/tests/ion/bug892794.js b/js/src/jit-test/tests/ion/bug892794.js new file mode 100644 index 0000000000..dd9a6236c4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug892794.js @@ -0,0 +1,13 @@ +// |jit-test| --ion-eager + +function test0(v) { + return (2147483648-Math.max(1.1,-(((2<<(-v|v))-3)|0)))|0; +} +assertEq(test0(1.6), 2147483645); +assertEq(test0(437348122.9), 2147483646); + +function test1(v) { + return (2147483648+Math.min(v,0))|0; +} +assertEq(test1(2.1), -2147483648) +assertEq(test1(-0.1), 2147483647) diff --git a/js/src/jit-test/tests/ion/bug893732.js b/js/src/jit-test/tests/ion/bug893732.js new file mode 100644 index 0000000000..fe7f0d6a42 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug893732.js @@ -0,0 +1,14 @@ + +var arr = new Int8Array(100); +function f(a) { + for(var i=0; i<30; i++) { + x = a[85.3]; + } +} +f(arr); + +var buf = serialize(new Date(NaN)); +var n = -(8.64e15 + 1); +var nbuf = serialize(n); +for (var j = 0; j < 8; j++) + buf[j + (0.00000000123)] = nbuf[j]; diff --git a/js/src/jit-test/tests/ion/bug893853.js b/js/src/jit-test/tests/ion/bug893853.js new file mode 100644 index 0000000000..e07d7440e9 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug893853.js @@ -0,0 +1,9 @@ + +function f() {} +new EvalTest(); +function EvalTest() { + with (this) { + f(EvalTest) + } +} +evaluate("var obj = new f(1, 'x');"); diff --git a/js/src/jit-test/tests/ion/bug894786-2.js b/js/src/jit-test/tests/ion/bug894786-2.js new file mode 100644 index 0000000000..836ffe7136 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug894786-2.js @@ -0,0 +1,91 @@ + +function f56(x) { + var a = x >>> 0; // Range = [0 .. UINT32_MAX] (bits = 32) + var b = 0x800000; // == 2^23 (bits = 24) + if (a > 0) { + // Beta node: Range [1 .. UINT32_MAX] (bits = 32) + var c = a * b; // Range = [0 .. +inf] (bits = a.bits + b.bits - 1 = 55) + var d = c + 1; // Range = [0 .. +inf] (bits = c.bits + 1 = 56) + return (d | 0) & 1; + } else { + return 1; + } +} + +function f55(x) { + var a = x >>> 0; // Range = [0 .. UINT32_MAX] (bits = 32) + var b = 0x400000; // == 2^22 (bits = 23) + if (a > 0) { + // Beta node: Range [1 .. UINT32_MAX] (bits = 32) + var c = a * b; // Range = [0 .. +inf] (bits = a.bits + b.bits - 1 = 54) + var d = c + 1; // Range = [0 .. +inf] (bits = c.bits + 1 = 55) + return (d | 0) & 1; + } else { + return 1; + } +} + +// Still returns 1, because the top-level bit is not represented. +function f54(x) { + var a = x >>> 0; // Range = [0 .. UINT32_MAX] (bits = 32) + var b = 0x200000; // == 2^21 (bits = 22) + if (a > 0) { + // Beta node: Range [1 .. UINT32_MAX] (bits = 32) + var c = a * b; // Range = [0 .. +inf] (bits = a.bits + b.bits - 1 = 53) + var d = c + 1; // Range = [1 .. +inf] (bits = c.bits + 1 = 54) + return (d | 0) & 1; + } else { + return 1; + } +} + +// Can safely truncate after these operations. (the mantissa has 53 bits) +function f53(x) { + var a = x >>> 0; // Range = [0 .. UINT32_MAX] (bits = 32) + var b = 0x100000; // == 2^20 (bits = 21) + if (a > 0) { + // Beta node: Range [1 .. UINT32_MAX] (bits = 32) + var c = a * b; // Range = [0 .. +inf] (bits = a.bits + b.bits - 1 = 52) + var d = c + 1; // Range = [1 .. +inf] (bits = c.bits + 1 = 53) + return (d | 0) & 1; + } else { + return 1; + } +} + +function f52(x) { + var a = x >>> 0; // Range = [0 .. UINT32_MAX] (bits = 32) + var b = 0x80000; // == 2^19 (bits = 20) + if (a > 0) { + // Beta node: Range [1 .. UINT32_MAX] (bits = 32) + var c = a * b; // Range = [0 .. +inf] (bits = a.bits + b.bits - 1 = 51) + var d = c + 1; // Range = [1 .. +inf] (bits = c.bits + 1 = 52) + return (d | 0) & 1; + } else { + return 1; + } +} + +function f51(x) { + var a = x >>> 0; // Range = [0 .. UINT32_MAX] (bits = 32) + var b = 0x40000; // == 2^18 (bits = 19) + if (a > 0) { + // Beta node: Range [1 .. UINT32_MAX] (bits = 32) + var c = a * b; // Range = [0 .. +inf] (bits = a.bits + b.bits - 1 = 50) + var d = c + 1; // Range = [1 .. +inf] (bits = c.bits + 1 = 51) + return (d | 0) & 1; + } else { + return 1; + } +} + +var e = Math.pow(2, 32); +for (var i = 1; i < e; i = i * 1.5) { + var x = i >>> 0; + assertEq(f56(x) , (x >= Math.pow(2, 30)) ? 0 : 1); + assertEq(f55(x), (x >= Math.pow(2, 31)) ? 0 : 1); + assertEq(f54(x), 1); + assertEq(f53(x), 1); + assertEq(f52(x), 1); + assertEq(f51(x), 1); +} diff --git a/js/src/jit-test/tests/ion/bug894786.js b/js/src/jit-test/tests/ion/bug894786.js new file mode 100644 index 0000000000..216062ec29 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug894786.js @@ -0,0 +1,9 @@ +(function() { + "use asm"; + function f(z) + { + z = z|0; + return (((0xc0000000 >>> z) >> 0) % -1)|0; + } + return f; +})()(0); diff --git a/js/src/jit-test/tests/ion/bug894794.js b/js/src/jit-test/tests/ion/bug894794.js new file mode 100644 index 0000000000..7001fce883 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug894794.js @@ -0,0 +1,7 @@ +(function() { + for (var j = 0; j < 1; ++j) { + var r = ((0x7fffffff - (0x80000000 | 0)) | 0) % 10000; + assertEq(r, -1); + } +})(); + diff --git a/js/src/jit-test/tests/ion/bug897747.js b/js/src/jit-test/tests/ion/bug897747.js new file mode 100644 index 0000000000..d7917b023d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug897747.js @@ -0,0 +1,6 @@ +function f(z) +{ + return (((0x80000000 | 0) % (0x80000001 | z)) | 0) % 100000 +} +assertEq(f(0), -1); +assertEq(f(0), -1); diff --git a/js/src/jit-test/tests/ion/bug898047.js b/js/src/jit-test/tests/ion/bug898047.js new file mode 100644 index 0000000000..ff47079e1c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug898047.js @@ -0,0 +1,23 @@ +function g(aa) { + assertEq(aa, 123); +} +function f(x, yy) { + if (yy < 0) { + for (var j=0; j<100; j++) {} + } + var o = yy < 2000 ? o1 : o2; + o.fun.apply(22, arguments); +} + +function test() { + o1 = {}; + o1.fun = g; + + o2 = {}; + o2.x = 3; + o2.fun = g; + + for (var i=0; i<3000; i++) + f(123, i); +} +test(); diff --git a/js/src/jit-test/tests/ion/bug898857.js b/js/src/jit-test/tests/ion/bug898857.js new file mode 100644 index 0000000000..1a054cc1db --- /dev/null +++ b/js/src/jit-test/tests/ion/bug898857.js @@ -0,0 +1,6 @@ +function fillHeap() { + var x = 1, tmp; + for (var i = 0; i < 50000; ++i) + tmp <<= x / 3; +} +RegExp({ toString: fillHeap }); diff --git a/js/src/jit-test/tests/ion/bug901086.js b/js/src/jit-test/tests/ion/bug901086.js new file mode 100644 index 0000000000..7853f63c78 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug901086.js @@ -0,0 +1,15 @@ +enableGeckoProfiling(); +function foo(obj,x,y,z) { + if (!y) + assertEq(0, 1); + obj.x = x; + return y + z; +} +function bar() { + var objz = {x:2} + for(var i = 0; i < 1100; i++) { + foo(objz,1,2,3); + foo(objz, false, "bar", "foo"); + } +} +bar(); diff --git a/js/src/jit-test/tests/ion/bug901391.js b/js/src/jit-test/tests/ion/bug901391.js new file mode 100644 index 0000000000..dd0304350a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug901391.js @@ -0,0 +1,4 @@ +function testPartition() { + if( "null" || new testPartition()) {} +} +testPartition(); diff --git a/js/src/jit-test/tests/ion/bug904315.js b/js/src/jit-test/tests/ion/bug904315.js new file mode 100644 index 0000000000..64239408f6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug904315.js @@ -0,0 +1,15 @@ + +function g(o, idx, exp) { + for (var i=0; i<3000; i++) { + assertEq(o[idx], exp); + } +} +function f() { + var o = []; + for (var i=1; i<100; i++) { + o[-i] = 1; + } + g(o, 50, undefined); + g(o, -50, 1); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug905166.js b/js/src/jit-test/tests/ion/bug905166.js new file mode 100644 index 0000000000..59591b2eb5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug905166.js @@ -0,0 +1,9 @@ +function test() { + LastIndexOf("hello"); + LastIndexOf("hello"); + eval(""); + function LastIndexOf(s) { + x = Math.min(Math.max(Math.pow(-1, 0.5), 0), s.length); + 0 <= x; + } +} test(); diff --git a/js/src/jit-test/tests/ion/bug905986.js b/js/src/jit-test/tests/ion/bug905986.js new file mode 100644 index 0000000000..955be16e4d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug905986.js @@ -0,0 +1,4 @@ +function testPartition() { + if(0.1 || new testPartition()) {} +} +testPartition(); diff --git a/js/src/jit-test/tests/ion/bug905999.js b/js/src/jit-test/tests/ion/bug905999.js new file mode 100644 index 0000000000..b8f33d8fbb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug905999.js @@ -0,0 +1,11 @@ +// |jit-test| --ion-eager +function reportCompare (expected) { + typeof expected; +} +var expect = 'No Crash'; +var array = new Array(10); +for (var i = 0; i != array.length; ++i) { + gc(); +} +var expect = array.length; +reportCompare(expect); diff --git a/js/src/jit-test/tests/ion/bug906035.js b/js/src/jit-test/tests/ion/bug906035.js new file mode 100644 index 0000000000..09d0af7d61 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug906035.js @@ -0,0 +1,9 @@ +// |jit-test| --ion-eager +function y() { return "foo,bar"; } +function x() { + var z = y().split(','); + for (var i = 0; i < z.length; i++) {} +} +gczeal(2); +Object.prototype.length = function () {}; +x(); diff --git a/js/src/jit-test/tests/ion/bug906284.js b/js/src/jit-test/tests/ion/bug906284.js new file mode 100644 index 0000000000..8b7e0ea72d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug906284.js @@ -0,0 +1,15 @@ +"use strict" +function f() { + h = {} +} +var c = 0; +for (var i=0; i<3; i++) { + try { + new f(); + assertEq(0, 1); + } catch(e) { + c++; + assertEq(e.message.includes("undeclared variable"), true); + } +} +assertEq(c, 3); diff --git a/js/src/jit-test/tests/ion/bug908903.js b/js/src/jit-test/tests/ion/bug908903.js new file mode 100644 index 0000000000..b5c5c87a8b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug908903.js @@ -0,0 +1,54 @@ + +function f(x) { + return x + 1; +} + +setJitCompilerOption("ion.warmup.trigger", 2); +setJitCompilerOption("baseline.warmup.trigger", 0); + +assertEq(f(1), 2); // warm-up == 1 => eagerly compile with baseline. +assertEq(f(0.5), 1.5); // warm-up == 2 => normaly compile with ion. + // invalidate for unexpect output. + + +function normal() { + setJitCompilerOption("ion.warmup.trigger", 8); + setJitCompilerOption("baseline.warmup.trigger", 5); +} + +function eager() { + setJitCompilerOption("ion.warmup.trigger", 0); +} + +function h(x) { + return x + 1; +} + +function g(x) { + normal(); + return h(x) + 1; +} + +normal(); +for (var i = 0; i < 10; i++) { + eager(); + assertEq(g(i), i + 2); +} + + +// Check for wrong arguments. +try { + setJitCompilerOption("not.an.option", 51); + assertEq(false, true); +} catch (x) { } + +try { + var ion = { warmup: { trigger: null } }; + setJitCompilerOption(ion.warmup.trigger, 42); + assertEq(false, true); +} catch (x) { } + +try { + setJitCompilerOption("ion.warmup.trigger", "32"); + assertEq(false, true); +} catch (x) { } diff --git a/js/src/jit-test/tests/ion/bug909401.js b/js/src/jit-test/tests/ion/bug909401.js new file mode 100644 index 0000000000..a79e6c271a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug909401.js @@ -0,0 +1,26 @@ +var TZ_PST = -8; +var TZ_DIFF = GetTimezoneOffset(); +var PST_DIFF = TZ_DIFF - TZ_PST; +function GetTimezoneOffset() {} +function adjustResultArray(ResultArray) { + var t = ResultArray[TIME] - PST_DIFF; + ResultArray[UTC_YEAR] = YearFromTime(t); +} +function TimeInYear( y ) {} +function YearFromTime( t ) { + var sign = ( t < 0 ) ? -1 : 1; + var year = ( sign < 0 ) ? 1969 : 1970; + for ( var timeToTimeZero = t; ; ) { + timeToTimeZero -= sign * TimeInYear(year) + break; + } + return ( year ); +} +gczeal(4); +evaluate("\ +var TIME = 0;\ +var UTC_YEAR = 1;\ +adjustResultArray([]);\ +adjustResultArray([946684800000-1]);\ +adjustResultArray([]);\ +", { noScriptRval : true }); diff --git a/js/src/jit-test/tests/ion/bug909505.js b/js/src/jit-test/tests/ion/bug909505.js new file mode 100644 index 0000000000..9b08aef2bd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug909505.js @@ -0,0 +1,5 @@ +function f(type) { + for (var i = 0; i < 3; i++) {} + assertEq((new String) instanceof type, true); +} +f(String); diff --git a/js/src/jit-test/tests/ion/bug909601.js b/js/src/jit-test/tests/ion/bug909601.js new file mode 100644 index 0000000000..01d481597e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug909601.js @@ -0,0 +1,10 @@ +// |jit-test| --ion-eager +for (var i=0; i<3; i++) + z = new Int32Array; + +function f() { + z.__proto__ = 2; +} + +for (var i=0; i<3; i++) + f(); diff --git a/js/src/jit-test/tests/ion/bug909997.js b/js/src/jit-test/tests/ion/bug909997.js new file mode 100644 index 0000000000..91d5c69bb3 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug909997.js @@ -0,0 +1,42 @@ +// getJitCompilerOptions will always return array with zeros when JIT is +// disabled. Therefore we quit now. +if (inJit() == 'Baseline is disabled.') { + print("JIT is disabled."); + quit(); +} + +var wait = 100; + +var method_A = function() { + for (var t = 0; t < wait; ++t) {} +} + +var method_B = function() { + for (var t = 0; t < wait; ++t) {} +} + +var method_C = function() { + for (var t = 0; t < wait; ++t) {} +} + +var method_D = function() { + for (var t = 0; t < wait; ++t) {} +} + +var func = [method_A, method_B, method_C, method_D] + +for (var n = 0; n < 4; ++n) { + try { + setJitCompilerOption("baseline.enable", n & 1); + setJitCompilerOption("ion.enable", n & 2 ? 1: 0); + } catch(e) { + if (e.toString().includes("on the stack")) + continue; + throw e; + } + var opt = getJitCompilerOptions(); + assertEq(opt["baseline.enable"], n & 1); + assertEq(opt["ion.enable"], n & 2 ? 1 : 0); + for (var i = 0; i < 1001; ++i) + func[n](); +} diff --git a/js/src/jit-test/tests/ion/bug911369.js b/js/src/jit-test/tests/ion/bug911369.js new file mode 100644 index 0000000000..90240b29cb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug911369.js @@ -0,0 +1,14 @@ +var a = []; +var count = 0; +a.valueOf = function() { + ++count; +} +function f(a) { + 6 - a; +} + +f(3); +for (var i=0; i<10; i++) + f(a); + +assertEq(count, 10); diff --git a/js/src/jit-test/tests/ion/bug911707.js b/js/src/jit-test/tests/ion/bug911707.js new file mode 100644 index 0000000000..86f61f2fea --- /dev/null +++ b/js/src/jit-test/tests/ion/bug911707.js @@ -0,0 +1,5 @@ +// |jit-test| --ion-eager +x = [ "CNY", "TWD", "invalid" ]; +Object.freeze(x).map(function() { + x.length = 6 +}) diff --git a/js/src/jit-test/tests/ion/bug912152.js b/js/src/jit-test/tests/ion/bug912152.js new file mode 100644 index 0000000000..4c429fa46a --- /dev/null +++ b/js/src/jit-test/tests/ion/bug912152.js @@ -0,0 +1,7 @@ + +function foo() { + try { + this.f = 0; + } finally {} +} +new foo(); diff --git a/js/src/jit-test/tests/ion/bug913749.js b/js/src/jit-test/tests/ion/bug913749.js new file mode 100644 index 0000000000..e48310272f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug913749.js @@ -0,0 +1,33 @@ +y = new Float32Array(11); +x = []; + +Object.defineProperty(x, 18, { + get: (function() { + y.length; + }), +}); +JSON.stringify(this); + +y = undefined; + +// The exact error message varies nondeterministically. Accept several +// variations on the theme. +var variations = [ + `y is undefined`, + `can't access property "length" of undefined`, + `can't access property "length", y is undefined`, + `undefined has no properties`, +]; + +var hits = 0; +for (var i = 0; i < 3; i++) { + try { + x.toString(); + } catch (e) { + assertEq(e.constructor.name, 'TypeError'); + if (!variations.includes(e.message)) + throw new Error(`expected one of ${JSON.stringify(variations)}; got ${String(e.message)}`); + hits++; + } +} +assertEq(hits, 3); diff --git a/js/src/jit-test/tests/ion/bug914098.js b/js/src/jit-test/tests/ion/bug914098.js new file mode 100644 index 0000000000..353533f696 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug914098.js @@ -0,0 +1,16 @@ +// |jit-test| error: ReferenceError + +function ygTreeView(id) {}; +function ygNode() {} +ygNode.prototype.init = function () { + this.children = []; +} +ygTextNode.prototype = new ygNode; +function ygTextNode() { + this.init(it.next.bind(it), StopIteration) +} +userTree = new ygTreeView("userTree") +addMenuNode(userTree) +function addMenuNode(tree) { + new ygTextNode({}, tree.root, false) +} diff --git a/js/src/jit-test/tests/ion/bug914341.js b/js/src/jit-test/tests/ion/bug914341.js new file mode 100644 index 0000000000..2f0bb3174d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug914341.js @@ -0,0 +1,5 @@ +function f() { + assertEq(typeof eval("this"), "object"); +} +for (var i=0; i<5; i++) + f(); diff --git a/js/src/jit-test/tests/ion/bug915301.js b/js/src/jit-test/tests/ion/bug915301.js new file mode 100644 index 0000000000..6e9f6eed91 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug915301.js @@ -0,0 +1,23 @@ +setJitCompilerOption("ion.warmup.trigger", 50); +var f32 = new Float32Array(32); +f32[0] = 0; + +function g(x) { + eval(""); // don't inline + return x + 4; +} + +function f(n) { + var x; + if (n > 10000) { + x = 4.5; + } else { + x = f32[0]; + } + f32[0] = g(x); +} + +for (var n = 0; n < 100; n++) + f(n); + +assertEq(f32[0], 400); diff --git a/js/src/jit-test/tests/ion/bug915608.js b/js/src/jit-test/tests/ion/bug915608.js new file mode 100644 index 0000000000..20aa7a2c52 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug915608.js @@ -0,0 +1,8 @@ +function f1() { + var b = new Float32Array(50); + for (var i=0; i < 100; true ? ++i : x.foo()) { + var x = b[i]; + typeof x; + } +} +f1(); diff --git a/js/src/jit-test/tests/ion/bug915903.js b/js/src/jit-test/tests/ion/bug915903.js new file mode 100644 index 0000000000..37ba24fe8e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug915903.js @@ -0,0 +1,10 @@ +x = {}; +x.toString = (function(stdlib, heap) { + Int8ArrayView = new stdlib.Int8Array(heap); + Float32ArrayView = new stdlib.Float32Array(heap); + function f() { + Int8ArrayView[0] = Float32ArrayView[0] + } + return f +})(this, ArrayBuffer); +x + 1 diff --git a/js/src/jit-test/tests/ion/bug916712.js b/js/src/jit-test/tests/ion/bug916712.js new file mode 100644 index 0000000000..b02b13ef37 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug916712.js @@ -0,0 +1,7 @@ +var e = new Error(); +function test() { + var arr = new Float32Array(1); + for (var Number in e) {} + var a = arr [0]; + switch (a) {} +} test(); diff --git a/js/src/jit-test/tests/ion/bug916752.js b/js/src/jit-test/tests/ion/bug916752.js new file mode 100644 index 0000000000..13b7af5f69 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug916752.js @@ -0,0 +1,20 @@ +function test() { return "x,y,z"; }; +function testClear() { + test().split(','); +} +loadFile("1"); +loadFile("testClear();"); +loadFile("2"); +loadFile("gc();"); +loadFile("testClear();"); +loadFile("new test(0);"); +function loadFile(lfVarx) { + if (lfVarx.substr(-3) != ".js" && lfVarx.length != 1) { + switch (lfRunTypeId) { + case 2: new Function(lfVarx)(); break; + default: evaluate(lfVarx); break; + } + } else if (!isNaN(lfVarx)) { + lfRunTypeId = parseInt(lfVarx); + } +} diff --git a/js/src/jit-test/tests/ion/bug919118.js b/js/src/jit-test/tests/ion/bug919118.js new file mode 100644 index 0000000000..413a8a89ad --- /dev/null +++ b/js/src/jit-test/tests/ion/bug919118.js @@ -0,0 +1,13 @@ +setJitCompilerOption("ion.warmup.trigger", 50); + +var f32 = new Float32Array(1); +f32[0] = 13; +var str = "CAN HAS cheezburger? OKTHXBYE"; +var c; + +function f() { + c = str[ f32[0] ]; +} + +for(var n = 100; n; --n) f(); +print (c); diff --git a/js/src/jit-test/tests/ion/bug921035.js b/js/src/jit-test/tests/ion/bug921035.js new file mode 100644 index 0000000000..33b8c5c5a8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug921035.js @@ -0,0 +1,14 @@ +// |jit-test| error: TypeError + +function $ERROR() {} +function testMultipleArgumentsObjects() { + var testargs = arguments; + var f = function (which) { + var args = [ testargs ]; + return args[which][0]; + }; + var arr = [0, 0, 0, 0, 1]; + for (var i = 0; i < arr.length; i++) + $ERROR[i] = f(arr[i]); +} +testMultipleArgumentsObjects() diff --git a/js/src/jit-test/tests/ion/bug922118.js b/js/src/jit-test/tests/ion/bug922118.js new file mode 100644 index 0000000000..0c1829a3be --- /dev/null +++ b/js/src/jit-test/tests/ion/bug922118.js @@ -0,0 +1,30 @@ +var lfcode = new Array(); +lfcode.push("1"); +lfcode.push(""); +lfcode.push("0"); +lfcode.push("function arguments() { };"); +lfcode.push("1"); +lfcode.push("\ +var GLOBAL_PROPERTIES = new Array();\ +var i = 0;\ +for ( p in this ) {\ +if (p.startsWith('a')) GLOBAL_PROPERTIES[i++] = p;\ +}\ +for ( i = 0; i < GLOBAL_PROPERTIES.length; i++ ) {\ + eval(GLOBAL_PROPERTIES[i]);\ +}\ +"); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file) +} +function loadFile(lfVarx) { + if (lfVarx.substr(-3) != ".js" && lfVarx.length != 1) { + switch (lfRunTypeId) { + case 0: evaluate(lfVarx); break; + case 1: eval(lfVarx); break; + } + } else if (!isNaN(lfVarx)) { + lfRunTypeId = parseInt(lfVarx); + } +} diff --git a/js/src/jit-test/tests/ion/bug924538.js b/js/src/jit-test/tests/ion/bug924538.js new file mode 100644 index 0000000000..b84a5c924b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug924538.js @@ -0,0 +1,9 @@ +// Don't die a float32-related death. +function testFloat32SetElemIC(a) { + for (var i = 0; i < a.length; i++) { + var r = Math.fround(Math.random()); + a[i] = r; + } +} +testFloat32SetElemIC(new Array(2048)); +testFloat32SetElemIC(new Uint8ClampedArray(2048)); diff --git a/js/src/jit-test/tests/ion/bug925067-1.js b/js/src/jit-test/tests/ion/bug925067-1.js new file mode 100644 index 0000000000..13e14b643b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug925067-1.js @@ -0,0 +1,25 @@ +var c = 0; +function g(o) { + try { + for(;;) + o.next(); + } catch(e) { + c += e; + } + return o.x; +} +function f() { + var o = {x: 0, next: function() { + if (this.x++ > 100) + throw 3; + }}; + + g(o); + assertEq(o.x, 102); + + o.x = 0; + g(o); + assertEq(o.x, 102); +} +f(); +assertEq(c, 6); diff --git a/js/src/jit-test/tests/ion/bug925067-2.js b/js/src/jit-test/tests/ion/bug925067-2.js new file mode 100644 index 0000000000..e56e7c9a51 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug925067-2.js @@ -0,0 +1,16 @@ +// |jit-test| error: 4 +function g(o) { + if (o.x >= 0) { + for(;;) + o.next(); + } + return o.x; +} +function f() { + var o = {x: 0, next: function() { + if (this.x++ > 100) + throw 4; + }}; + g(o); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug925067-3.js b/js/src/jit-test/tests/ion/bug925067-3.js new file mode 100644 index 0000000000..aad4d88a8f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug925067-3.js @@ -0,0 +1,20 @@ +// |jit-test| error: 4 +function h(o) { + o.next(); +} +function g(o) { + for (var i=0; i<5; i++) {}; + if (o.x >= 0) { + for(;;) + h(o); + } + return o.x; +} +function f() { + var o = {x: 0, next: function() { + if (this.x++ > 100) + throw 4; + }}; + g(o); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug925305.js b/js/src/jit-test/tests/ion/bug925305.js new file mode 100644 index 0000000000..7278ce0abd --- /dev/null +++ b/js/src/jit-test/tests/ion/bug925305.js @@ -0,0 +1,14 @@ +function testFloat32SetElemIC(a) { + for (var i = 0; i < a.length; i++) { + var r = Math.fround(Math.random()); + a[i] = r; + assertEq(a[i], r); + } +} + +testFloat32SetElemIC(new Array(2048)); +testFloat32SetElemIC(new Array(2048)); + +enableOsiPointRegisterChecks(); +testFloat32SetElemIC(new Array(2048)); +testFloat32SetElemIC(new Float64Array(2048)); diff --git a/js/src/jit-test/tests/ion/bug925308.js b/js/src/jit-test/tests/ion/bug925308.js new file mode 100644 index 0000000000..9950af3ddc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug925308.js @@ -0,0 +1,18 @@ +// |jit-test| error: ReferenceError + +var lfcode = new Array(); +lfcode.push("3"); +lfcode.push("enableGeckoProfiling();foo();"); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file) +} +function loadFile(lfVarx) { + if (lfVarx.substr(-3) != ".js" && lfVarx.length != 1) { + switch (lfRunTypeId) { + default: function newFunc(x) { new Function(x)(); }; newFunc(lfVarx); break; + } + } else if (!isNaN(lfVarx)) { + lfRunTypeId = parseInt(lfVarx); + } +} diff --git a/js/src/jit-test/tests/ion/bug927389.js b/js/src/jit-test/tests/ion/bug927389.js new file mode 100644 index 0000000000..ee5347faaf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug927389.js @@ -0,0 +1,4 @@ +(function () { + var x = 0 || 1.1; + x >> x; +})(); diff --git a/js/src/jit-test/tests/ion/bug928423.js b/js/src/jit-test/tests/ion/bug928423.js new file mode 100644 index 0000000000..171e545576 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug928423.js @@ -0,0 +1,14 @@ +function f(o, p) { + try {} catch(e) {}; + return o[p]; +} +function test() { + var o = {foo: 1, bar: 2, foobar: 3}; + + for (var i = 0; i < 30; i++) { + assertEq(f(o, "foo1".substr(0, 3)), 1); + assertEq(f(o, "bar1".substr(0, 3)), 2); + assertEq(f(o, "foobar1".substr(0, 6)), 3); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/bug928542.js b/js/src/jit-test/tests/ion/bug928542.js new file mode 100644 index 0000000000..d79c929feb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug928542.js @@ -0,0 +1,10 @@ + +called = 0; +function foo() { + this.what(); + this.random = 0; + this.what = 1; +} +foo.prototype.what = function() { called = 1; } +new foo(); +assertEq(called, 1); diff --git a/js/src/jit-test/tests/ion/bug928625.js b/js/src/jit-test/tests/ion/bug928625.js new file mode 100644 index 0000000000..1b5058e33f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug928625.js @@ -0,0 +1,3 @@ +var summary = true; +evaluate("var summary = 'Array slice when arrays length is assigned';"); +evaluate('var summary;'); diff --git a/js/src/jit-test/tests/ion/bug930327.js b/js/src/jit-test/tests/ion/bug930327.js new file mode 100644 index 0000000000..496b6e342e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug930327.js @@ -0,0 +1,12 @@ +// |jit-test| error: ReferenceError + +function MyObject( value ) { + this.value = value; + value &= value; +} +ForIn_1(new MyObject(true)); +function ForIn_1( object) { + for ( property in object ) { + object[property] == eval(property) + } +} diff --git a/js/src/jit-test/tests/ion/bug930990.js b/js/src/jit-test/tests/ion/bug930990.js new file mode 100644 index 0000000000..1846f28b9c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug930990.js @@ -0,0 +1,8 @@ +var f32 = new Float32Array(10); +f32[0] = 5; +var i = 0; +do { + f32[i + 1] = f32[i] - 1; + i += 1; +} while (f32[i]); + diff --git a/js/src/jit-test/tests/ion/bug930993.js b/js/src/jit-test/tests/ion/bug930993.js new file mode 100644 index 0000000000..bf4074c918 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug930993.js @@ -0,0 +1,6 @@ +x = {}; +y = x; +x.toString = function() { + new Int8Array(ArrayBuffer)[0] = new Float32Array(ArrayBuffer)[0]; +} +print(x << y); diff --git a/js/src/jit-test/tests/ion/bug931496.js b/js/src/jit-test/tests/ion/bug931496.js new file mode 100644 index 0000000000..7502dd08bc --- /dev/null +++ b/js/src/jit-test/tests/ion/bug931496.js @@ -0,0 +1,11 @@ + +function* g() { + yield +} +g() +function f() { + g() +} +try { + new f +} catch (e) {} diff --git a/js/src/jit-test/tests/ion/bug936740.js b/js/src/jit-test/tests/ion/bug936740.js new file mode 100644 index 0000000000..bf4a933786 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug936740.js @@ -0,0 +1,26 @@ +function ceil(x) { + return Math.ceil(x); +} + +// Compiled as Ceil(double -> int32) +assertEq(ceil(1.1), 2); +assertEq(ceil(-1.1), -1); +assertEq(ceil(-3), -3); + +// As we use the identity Math.ceil(x) == -Math.floor(-x) and Floor(-0) bails out, +// this should bail out. +assertEq(ceil(0), 0); +assertEq(ceil(0), 0); + +// Reuses the Ceil(double -> int32) path +assertEq(ceil(1.1), 2); +assertEq(ceil(-1.1), -1); +assertEq(ceil(-3), -3); + +// Bails out and then compiles as Ceil(double -> double) +assertEq(ceil(-0), -0); +assertEq(ceil(Math.pow(2, 32)), Math.pow(2, 32)); +assertEq(ceil(-0), -0); + +// Still works but not inlined as double -> int32 (it still uses double -> double) +assertEq(ceil(1.5), 2); diff --git a/js/src/jit-test/tests/ion/bug939868-2.js b/js/src/jit-test/tests/ion/bug939868-2.js new file mode 100644 index 0000000000..8ba8d7bc24 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug939868-2.js @@ -0,0 +1,47 @@ +function f(x,y,z) { + var z; + if (x) { + if (y) { + z = 0xfffffff; + } else { + z = 0xfffffff; + } + assertFloat32(z, false); + } else { + z = Math.fround(z); + assertFloat32(z, true); + } + assertFloat32(z, false); + return z; +} + +function g(x,y,z) { + var z; + if (x) { + if (y) { + z = 3; + } else { + z = 6; + } + assertFloat32(z, false); + } else { + z = Math.fround(z); + assertFloat32(z, true); + } + assertFloat32(z, true); + return z; +} + +setJitCompilerOption("ion.warmup.trigger", 50); + +for (var n = 100; n--; ) { + assertEq(f(0,1,2), 2); + assertEq(f(0,0,2), 2); + assertEq(f(1,0,2), 0xfffffff); + assertEq(f(1,1,2), 0xfffffff); + + assertEq(g(0,1,2), 2); + assertEq(g(0,0,2), 2); + assertEq(g(1,0,2), 6); + assertEq(g(1,1,2), 3); +} diff --git a/js/src/jit-test/tests/ion/bug939868.js b/js/src/jit-test/tests/ion/bug939868.js new file mode 100644 index 0000000000..fbf7f03c46 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug939868.js @@ -0,0 +1,3 @@ +function f(x, y) { return x || Math.fround(y); } +assertEq(f(0, 0), 0); +assertEq(f(0xfffffff, 0), 0xfffffff); diff --git a/js/src/jit-test/tests/ion/bug940635.js b/js/src/jit-test/tests/ion/bug940635.js new file mode 100644 index 0000000000..62e1eb5533 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug940635.js @@ -0,0 +1,7 @@ +function f(y) { + return (y > 0) == y; +} +assertEq(f(0), true); +assertEq(f(0), true); +assertEq(f(null), false); +assertEq(f(null), false); diff --git a/js/src/jit-test/tests/ion/bug940846.js b/js/src/jit-test/tests/ion/bug940846.js new file mode 100644 index 0000000000..587e24db29 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug940846.js @@ -0,0 +1,15 @@ +function a(f, i) { + results = [] + for (var k = 0; k < 10; ++k) { + gc(); + try { + results.push(f(i[k])); + } catch (e) { + results.push(e); + } + } +} +g = (function(x, y) { + return Math.fround((x ? Math.f : m0) ? w : Math.fround()) +}) +a(g, [Number.MAX_VALUE]) diff --git a/js/src/jit-test/tests/ion/bug942550.js b/js/src/jit-test/tests/ion/bug942550.js new file mode 100644 index 0000000000..16344f0848 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug942550.js @@ -0,0 +1,6 @@ +function pow(x,y) { + return Math.pow(x,y); +} +var x = pow(3, -.5); +var y = pow(3, -.5); +assertEq(x, y); diff --git a/js/src/jit-test/tests/ion/bug942604.js b/js/src/jit-test/tests/ion/bug942604.js new file mode 100644 index 0000000000..068b5e2ab6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug942604.js @@ -0,0 +1,11 @@ +for (var j = 0; j < 999; ++j) { + try { + (function() { + function f(x) { + x = (new Float32Array)[i >> 2]; + {}(w) = arguments[0] + } + return f + })()(); + } catch (e) {} +} diff --git a/js/src/jit-test/tests/ion/bug944080.js b/js/src/jit-test/tests/ion/bug944080.js new file mode 100644 index 0000000000..3f6889ce0b --- /dev/null +++ b/js/src/jit-test/tests/ion/bug944080.js @@ -0,0 +1,17 @@ + +function intLength (a, l) { + var res = 0; + for (var i = 0; i < l; i++) + res += a.length; +} +intLength([0,1,2,3,4,5,6,7,8,9], 10) +intLength(new Uint8Array(10), 10) +function test() { + var a = "abc".split(""); + var res = 0; + for (var i=0; i<20; i++) + res += a.length; + return res; +} +Object.prototype.length = function(){}; +assertEq(test(), 60); diff --git a/js/src/jit-test/tests/ion/bug945294.js b/js/src/jit-test/tests/ion/bug945294.js new file mode 100644 index 0000000000..4ad35c07a0 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug945294.js @@ -0,0 +1,22 @@ +// |jit-test| error:is not a function +var arr = []; + +var C = function () {}; +C.prototype.dump = function () {}; +arr[0] = new C; + +C = function () {}; +C.prototype.dump = this; +arr[1] = new C; + +function f() { + for (var i = 0; i < arr.length; i++) + arr[i].dump(); +} + +try { + f(); +} catch (exc) { + assertEq(exc.message.includes("is not a function"), true); +} +f(); diff --git a/js/src/jit-test/tests/ion/bug945512.js b/js/src/jit-test/tests/ion/bug945512.js new file mode 100644 index 0000000000..e0e6412209 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug945512.js @@ -0,0 +1,12 @@ + +var handler = { + has: function (name) { + assertEq(1, 2); + } +}; + +for (var i=0; i<10; i++) { + var regex = /undefined/; + regex.__proto__ = new Proxy(function() {}, handler) +} + diff --git a/js/src/jit-test/tests/ion/bug945811.js b/js/src/jit-test/tests/ion/bug945811.js new file mode 100644 index 0000000000..1425dafebb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug945811.js @@ -0,0 +1,17 @@ +function toPrinted(value) {} +function reportCompare (expected, actual, description) { + if (expected != actual) + + toPrinted(actual) +} +test(); +function test() { + reportCompare(); + try { + test(); + } catch (e) { + try { + new test(); + } catch(e) {} + } + reportCompare(); +} diff --git a/js/src/jit-test/tests/ion/bug946284.js b/js/src/jit-test/tests/ion/bug946284.js new file mode 100644 index 0000000000..58bb8a37b6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug946284.js @@ -0,0 +1,5 @@ +function f(x) { + return x.length / 2 +} +f("") +assertEq(f(undefined + ""), 4.5); diff --git a/js/src/jit-test/tests/ion/bug946969.js b/js/src/jit-test/tests/ion/bug946969.js new file mode 100644 index 0000000000..b2fb187324 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug946969.js @@ -0,0 +1,6 @@ +function f() { + return Math.abs(~(Math.tan())); +} + +for (var i=0; i<1000; i++) + assertEq(f(i), 1); diff --git a/js/src/jit-test/tests/ion/bug950462.js b/js/src/jit-test/tests/ion/bug950462.js new file mode 100644 index 0000000000..4b0abe32ba --- /dev/null +++ b/js/src/jit-test/tests/ion/bug950462.js @@ -0,0 +1,2 @@ +for (var i = 0; i < 5; i++) + [,][i] = 3.14159; diff --git a/js/src/jit-test/tests/ion/bug950764.js b/js/src/jit-test/tests/ion/bug950764.js new file mode 100644 index 0000000000..9953b024e6 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug950764.js @@ -0,0 +1,19 @@ +function g( +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a, a, +a, a, a, a, a, a, a, a, a +) {} +function f() { + g(); +} +new f; diff --git a/js/src/jit-test/tests/ion/bug953164.js b/js/src/jit-test/tests/ion/bug953164.js new file mode 100644 index 0000000000..41868cda8d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug953164.js @@ -0,0 +1,20 @@ +function test(a) { + var total = 0; + for (var i=0; i<100; i++) { + + var j = 1; + var b = a.a + if (b) { + j += b.test; + } + total += j; + } + print(total) +} + +var a1 = {"a": {"test":1}}; +var a2 = {"a": undefined}; +test(a1) +test(a2) +test(a1) +test(a2) diff --git a/js/src/jit-test/tests/ion/bug956156.js b/js/src/jit-test/tests/ion/bug956156.js new file mode 100644 index 0000000000..36e1d9bc5e --- /dev/null +++ b/js/src/jit-test/tests/ion/bug956156.js @@ -0,0 +1,7 @@ +// |jit-test| error:TypeError +function f() { + ((function g(x) { + g(x.slice) + })([])) +} +new f diff --git a/js/src/jit-test/tests/ion/bug958381.js b/js/src/jit-test/tests/ion/bug958381.js new file mode 100644 index 0000000000..98fc48edaa --- /dev/null +++ b/js/src/jit-test/tests/ion/bug958381.js @@ -0,0 +1,4 @@ +function f(x) { + return (x != x) != Math.fround(x) +} +assertEq(f(0), f(0)); diff --git a/js/src/jit-test/tests/ion/bug958432.js b/js/src/jit-test/tests/ion/bug958432.js new file mode 100644 index 0000000000..b8ae50a432 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug958432.js @@ -0,0 +1,27 @@ +function h(i, i) { + i = ([Infinity([])])(1 ? l : arguments) +} +for (var j = 0; j < 2; ++j) { + try { + h(-Number, -Number) + } catch (e) {} +} + +function f() { + function f(i0, i1) { + i0 = i0 | 0; + i = i1 | 0; + switch (1) { + case -3: + switch (f) {} + } { + return 0 + }(arguments) + } + return f +}; +for (var j = 0; j < 5; ++j) { + (function(x) { + f()(f()(x, f()())) + })() +} diff --git a/js/src/jit-test/tests/ion/bug964229-2.js b/js/src/jit-test/tests/ion/bug964229-2.js new file mode 100644 index 0000000000..0ccbd7c019 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug964229-2.js @@ -0,0 +1,58 @@ +function test1(re, test) { + return re.test(test); +} + +assertEq(true, test1(/undefined/, undefined)); +assertEq(true, test1(/undefined/, undefined)); + +function test2(re, test) { + return re.test(test); +} + +assertEq(true, test2(/null/, null)); +assertEq(true, test2(/null/, null)); + +function test3(re, test) { + return re.test(test); +} + +assertEq(true, test3(/0/, 0)); +assertEq(true, test3(/0/, 0)); + +function test4(re, test) { + return re.test(test); +} + +assertEq(true, test4(/12.12/, 12.12)); +assertEq(true, test4(/12.12/, 12.12)); + +function test5(re, test) { + return re.test(test); +} + +assertEq(true, test5(/true/, true)); +assertEq(true, test5(/false/, false)); +assertEq(true, test5(/true/, true)); +assertEq(true, test5(/false/, false)); + +function test6(re, test) { + return re.test(test); +} + +assertEq(true, test6(/object/, {})); +assertEq(true, test6(/object/, {})); + +assertEq(true, test1(/test/, "test")); +assertEq(true, test1(/test/, "test")); +assertEq(true, test1(/undefined/, undefined)); +assertEq(true, test1(/undefined/, undefined)); +assertEq(true, test1(/null/, null)); +assertEq(true, test1(/null/, null)); +assertEq(true, test1(/0.1/, 0.1)); +assertEq(true, test1(/0.1/, 0.1)); +assertEq(true, test1(/20000/, 20000)); +assertEq(true, test1(/20000/, 20000)); +assertEq(true, test1(/object/, {})); +assertEq(true, test1(/object/, {})); + + diff --git a/js/src/jit-test/tests/ion/bug964229.js b/js/src/jit-test/tests/ion/bug964229.js new file mode 100644 index 0000000000..7c018b5105 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug964229.js @@ -0,0 +1,26 @@ +a = 'a'; +b = 0 +var i=0; +exhaustiveSliceTest("exhaustive slice test 1", a); +var i=1; +exhaustiveSliceTest("exhaustive slice test 2", b); +exhaustiveSliceTest("exhaustive slice test 3", 0); +var i=0; +var executed = false; +try { + exhaustiveSliceTest("exhaustive slice test 4", 0); +} catch(e) { + executed = true; +} +assertEq(executed, true); + +function exhaustiveSliceTest(testname, a) { + print(testname) + for (var y = 0; y < 2; y++) + { + print(a.length) + if (a.length == 2 || i == 1) + return 0; + var b = a.slice(0,0); + } +} diff --git a/js/src/jit-test/tests/ion/bug965712.js b/js/src/jit-test/tests/ion/bug965712.js new file mode 100644 index 0000000000..634fb33d8f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug965712.js @@ -0,0 +1,2 @@ +var result = "D1D1D1D1D1D1D1D1D1D1".replace(/d1/ig,1); +assertEq(result, "1111111111"); diff --git a/js/src/jit-test/tests/ion/bug966926.js b/js/src/jit-test/tests/ion/bug966926.js new file mode 100644 index 0000000000..204a35c4eb --- /dev/null +++ b/js/src/jit-test/tests/ion/bug966926.js @@ -0,0 +1,12 @@ +var f32 = new Float32Array(32); +function f(n) { + var x; + if (n > 10000) { + x = (0); + } else { + x = f32[0]; + } + g('' + (x)); +} +function g(y){} +f(0); diff --git a/js/src/jit-test/tests/ion/bug969203.js b/js/src/jit-test/tests/ion/bug969203.js new file mode 100644 index 0000000000..bf44b94d72 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug969203.js @@ -0,0 +1,4 @@ +var f = function (x) { + return Math.tan(Math.fround(Math.log(Math.fround(Math.exp(x))))); +} +assertEq(f(1), f(1)); diff --git a/js/src/jit-test/tests/ion/bug973118.js b/js/src/jit-test/tests/ion/bug973118.js new file mode 100644 index 0000000000..67ab4ebe74 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug973118.js @@ -0,0 +1,4 @@ +function h(x) { return +x == x }; +h(false) +assertEq(h(null), false); +assertEq(h(null), false); diff --git a/js/src/jit-test/tests/ion/bug975290.js b/js/src/jit-test/tests/ion/bug975290.js new file mode 100644 index 0000000000..147db84be7 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug975290.js @@ -0,0 +1,6 @@ +for (var j = 0; j < 9999; ++j) { + (function() { + Math.pow(Math.fround(), Math.fround(0)) + })(); +} + diff --git a/js/src/jit-test/tests/ion/bug976110.js b/js/src/jit-test/tests/ion/bug976110.js new file mode 100644 index 0000000000..0886fc3110 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug976110.js @@ -0,0 +1,91 @@ +var asmdiv2 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 2)>>>0; + return z|0; + } + return f; +})() + +var plaindiv2 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 2)>>>0; + return z|0; +} + +var k2 = 0xf0000000; + +assertEq(asmdiv2(k2), 0x78000000); +assertEq(plaindiv2(k2), 0x78000000); + +var asmdiv3 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 3)>>>0; + return z|0; + } + return f; +})() + +var plaindiv3 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 3)>>>0; + return z|0; +} + +var k3 = 3<<30; + +assertEq(asmdiv3(k3), 1<<30); +assertEq(plaindiv3(k3), 1<<30); + +var asmdiv7 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 7)>>>0; + return z|0; + } + return f; +})() + +var plaindiv7 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 7)>>>0; + return z|0; +} + +var k7 = (1<<29)*7 + 4; + +assertEq(asmdiv7(k7), 1<<29); +assertEq(plaindiv7(k7), 1<<29); + +var asmmod3 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) % 3)>>>0; + return z|0; + } + return f; +})() + +var plainmod3 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) % 3)>>>0; + return z|0; +} + +var kmod = (3<<30) + 2; + +assertEq(asmmod3(kmod), 2); +assertEq(plainmod3(kmod), 2); diff --git a/js/src/jit-test/tests/ion/bug977966.js b/js/src/jit-test/tests/ion/bug977966.js new file mode 100644 index 0000000000..6d80c5c376 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug977966.js @@ -0,0 +1,125 @@ +// |jit-test| --ion-eager + +function join_check() { + var lengthWasCalled = false; + var obj = {"0": "", "1": ""}; + Object.defineProperty(obj, "length", { + get : function(){ lengthWasCalled = true; return 2; }, + enumerable : true, + configurable : true + }); + + var res = Array.prototype.join.call(obj, { toString: function () { + if (lengthWasCalled) + return "good"; + else + return "bad"; + }}) + + assertEq(res, "good"); +} +function split(i) { + var x = (i + "->" + i).split("->"); + assertEq(x[0], "" + i); + return i; +} + +function join(i) { + var x = [i, i].join("->"); + assertEq(x, i + "->" + i); + return i; +} + +function split_join(i) { + var x = (i + "-" + i).split("-").join("->"); + assertEq(x, i + "->" + i); + return i; +} + +function split_join_2(i) { + var x = (i + "-" + i).split("-"); + x.push("" + i); + var res = x.join("->"); + assertEq(res, i + "->" + i + "->" + i); + return i; +} + +function resumeHere() { bailout(); } + +function split_join_3(i) { + var x = (i + "-" + i).split("-"); + resumeHere(); + var res = x.join("->"); + assertEq(res, i + "->" + i); + return i; +} + +function trip(i) { + if (i == 99) + assertEq(myjoin.arguments[1][0], "" + i) +} + +function myjoin(i, x) { + trip(i); + return x.join("->"); +} + +function split_join_4(i) { + var x = (i + "-" + i).split("-"); + var res = myjoin(i, x); + assertEq(res, i + "->" + i); + return i; +} + +function split_join_5(i) { + var s = "abca"; + assertEq(s.split("a").join("") + i, "bc" + i); +} + +function split_join_two_byte_char(i) { + var s1 = "ab"; + assertEq(s1.split("").join("\u03c0"), "a\u03c0b"); + var s2 = i + "\u03c0" + i; + assertEq(s2.split("\u03c0").join("-"), i + "-" + i); +} + +function split_join_underflow(i) +{ + var s = ""; + assertEq(s.split("").join("x" + i), ""); +} + +// Check that we do not consider the string argument of join as a replacement +// pattern, as the string replace primitive is supposed to do. +function split_join_pattern(i) { + var s = i + "-" + i; + assertEq(s.split("-").join("$`$&$'"), i + "$`$&$'" + i); + assertEq(s.replace("-", "$`$&$'"), "" + i + i + "-" + i + i); +} + +// Check that, as opposed to String.replace, we are doing a global replacement +// as String.split does. +function split_join_multiple(i) { + var s1 = i + "-\n-" + i + "-\n-" + i; + assertEq(s1.split("-\n-").join("-") , i + "-" + i + "-" + i); + assertEq(s1.replace("-\n-", "-") , i + "-" + i + "-\n-" + i); + + var s2 = "abc"; + assertEq(s2.split("").join("" + i) , "a" + i + "b" + i + "c"); + assertEq(s2.replace("", "" + i) , i + "abc"); +} + +for (var i = 0; i < 1000; ++i) { + join_check(i); + split(i); + join(i); + split_join(i); + split_join_2(i); + split_join_3(i); + split_join_4(i); + split_join_5(i); + split_join_pattern(i); + split_join_multiple(i); + split_join_two_byte_char(i); + split_join_underflow(i); +} diff --git a/js/src/jit-test/tests/ion/bug980119.js b/js/src/jit-test/tests/ion/bug980119.js new file mode 100644 index 0000000000..b6778164b1 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug980119.js @@ -0,0 +1,9 @@ + +s = newGlobal() +evalcx("\ + x = new Uint8ClampedArray;\ + x.__proto__ = [];\ +", s); +evalcx("\ + x[0]\ +", s); diff --git a/js/src/jit-test/tests/ion/bug981325.js b/js/src/jit-test/tests/ion/bug981325.js new file mode 100644 index 0000000000..809b4da798 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug981325.js @@ -0,0 +1,7 @@ +function f(x) { + return Math.fround() ? x : x >> 0; +} +function g() { + return (f() !== Math.fround(0)) +} +assertEq(g(), g()); diff --git a/js/src/jit-test/tests/ion/bug984018.js b/js/src/jit-test/tests/ion/bug984018.js new file mode 100644 index 0000000000..ef144a85db --- /dev/null +++ b/js/src/jit-test/tests/ion/bug984018.js @@ -0,0 +1,62 @@ +var x = 0; +function test() { + function sincos1(a, b) { + var sa = Math.sin(a); + var sb = Math.sin(b); + var ca = Math.cos(a); + var cb = Math.cos(b); + var ra = sa * sa + ca * ca; + var rb = sb * sb + cb * cb; + var dec = 100000; + + assertEq(Math.round(ra * dec) / dec, Math.round(rb * dec) / dec); + + ca = Math.cos(a); + cb = Math.cos(b); + sa = Math.sin(a); + sb = Math.sin(b); + + var ra = sa * sa + ca * ca; + var rb = sb * sb + cb * cb; + + assertEq(Math.round(ra * dec) / dec, Math.round(rb * dec) / dec); + return ra; + } + + function sincos2(x) { + var s1 = Math.sin(x); + var c1 = Math.cos(x); + + var c2 = Math.cos(x); + var s2 = Math.sin(x); + + return (s1 * s1 + c1 * c1) - (s2 * s2 + c2 * c2); + } + + function bailoutHere() { bailout(); } + + function sincos3(x) { + var s = Math.sin(x); + bailoutHere(); + var c = Math.cos(x); + assertEq(Math.round(s * s + c * c), 1); + return s; + } + + function sincos4(x) { + if (x < 2500) + x = Math.sin(x); + else + x = Math.cos(x); + return x; + } + + for (var i=0; i<5000; i++) { + x += sincos1(x, x + 1); + x += sincos2(x); + x += sincos3(x); + x += sincos4(i); + } +} +x += 1; +test(); diff --git a/js/src/jit-test/tests/ion/bug984830.js b/js/src/jit-test/tests/ion/bug984830.js new file mode 100644 index 0000000000..a8c2db1ab8 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug984830.js @@ -0,0 +1,16 @@ +function getTestCaseResult(expected, actual) { + if (actual != expected) + return Math.abs(actual - expected) <= 1E-10; +} +function InstanceOf(object, constructor) { + while ( object != null ) + object = object.__proto__; +} +function WorkerBee () {} +function Engineer () {} +Engineer.prototype = new WorkerBee(); +var pat = new Engineer(); +getTestCaseResult(pat.__proto__.__proto__.__proto__.__proto__ == Object.prototype); +getTestCaseResult(InstanceOf(pat, Engineer)); +evaluate("getTestCaseResult( Object.prototype.__proto__ );", + { isRunOnce: true }); diff --git a/js/src/jit-test/tests/ion/bug989586.js b/js/src/jit-test/tests/ion/bug989586.js new file mode 100644 index 0000000000..c21876dbab --- /dev/null +++ b/js/src/jit-test/tests/ion/bug989586.js @@ -0,0 +1,15 @@ +function t() { + var iter = 0; + function a(w) { + var a = new Array(w); + assertEq(a.length, w); + } + function r() { + a(3); + a(4); + } + for (var i=0; i<100; i++) { + r(); + } +} +t(); diff --git a/js/src/jit-test/tests/ion/bug991457.js b/js/src/jit-test/tests/ion/bug991457.js new file mode 100644 index 0000000000..6b9099ed2c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug991457.js @@ -0,0 +1,64 @@ +function test() { + this.init(); + for (var i=0; i<10; i++) { + delete this.blocks[10][9]; + this.collapse_blocks(); + } + this.look_for_holes(); +} +test.prototype.init = function() { + this.blocks = new Array(20); + for (var x=0; x<this.blocks.length; x++) { + this.blocks[x] = new Array(10); + for (var y=0; y<this.blocks[x].length; y++) { + this.blocks[x][y] = {}; + } + } +} +test.prototype.move_block = function(x,y,x1,y1) { + this.blocks[x][y] = this.blocks[x1][y1]; + if (this.blocks[x][y]) + delete this.blocks[x1][y1]; +} +test.prototype.collapse_blocks = function() { + var didSomething=0; + do { + didSomething=0; + for (var x=0; x<this.blocks.length; x++) + for (var y=1; y<this.blocks[x].length; y++) { + if (!this.blocks[x][y] && this.blocks[x][y-1]) { + this.move_block(x,y,x,y-1); + didSomething=1; + } + } + } while (didSomething); + + do { + didSomething = 0; + for (var x=0; x<this.blocks.length-1; x++) { + if (!this.blocks[x][9] && this.blocks[x+1][9]) { + for (var y=0; y<this.blocks[x].length; y++) + this.move_block(x,y,x+1,y); + didSomething = 1; + } + } + } while (didSomething); +} +test.prototype.look_for_holes = function() { + var was_empty = false; + var n_empty = 0; + for (var x=0; x<this.blocks.length; x++) { + var empty = true; + for (var y=0; y<this.blocks[x].length; y++) { + if (this.blocks[x][y]) { + empty = false; + n_empty++; + } + } + if (was_empty) + assertEq(empty, true); + was_empty = empty; + } + assertEq(n_empty, 190); +} +new test(); diff --git a/js/src/jit-test/tests/ion/bug994016.js b/js/src/jit-test/tests/ion/bug994016.js new file mode 100644 index 0000000000..326dfdc5df --- /dev/null +++ b/js/src/jit-test/tests/ion/bug994016.js @@ -0,0 +1,48 @@ + +function test(x) { + return typeof x != "object" +} + +var obj = {}; +var func = function() {}; + +assertEq(test(""), true) +assertEq(test(""), true) +assertEq(test(1), true) +assertEq(test(1), true) +assertEq(test(1.5), true) +assertEq(test(1.5), true) +assertEq(test(undefined), true) +assertEq(test(undefined), true) +assertEq(test(func), true) +assertEq(test(func), true) + +function test2(x) { + return typeof x != "string" +} + +assertEq(test2(1), true) +assertEq(test2(1), true) +assertEq(test2(1.5), true) +assertEq(test2(1.5), true) +assertEq(test2(undefined), true) +assertEq(test2(undefined), true) +assertEq(test2(func), true) +assertEq(test2(func), true) +assertEq(test2(obj), true) +assertEq(test2(obj), true) + +function test3(x) { + return typeof x != "undefined" +} + +assertEq(test3(1), true) +assertEq(test3(1), true) +assertEq(test3(1.5), true) +assertEq(test3(1.5), true) +assertEq(test3(func), true) +assertEq(test3(func), true) +assertEq(test3(obj), true) +assertEq(test3(obj), true) +assertEq(test(""), true) +assertEq(test(""), true) diff --git a/js/src/jit-test/tests/ion/bug995673.js b/js/src/jit-test/tests/ion/bug995673.js new file mode 100644 index 0000000000..1310efac77 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug995673.js @@ -0,0 +1,16 @@ +var total = 0 + +x = [ [] ] +x[0].valueOf = function () { + total++; +} +function f(y) { + y != Math.abs() +} +(function() { + f() + f(x[0]) + f(x[0]) +})() + +assertEq(total, 2) diff --git a/js/src/jit-test/tests/ion/bug995675.js b/js/src/jit-test/tests/ion/bug995675.js new file mode 100644 index 0000000000..81f9c1b070 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug995675.js @@ -0,0 +1,5 @@ +function f(x) { + return Math.cos(~(~Math.pow(Number.MAX_VALUE, x))) +} +f(-0) +assertEq(f(undefined - undefined), 1) diff --git a/js/src/jit-test/tests/ion/bug995817.js b/js/src/jit-test/tests/ion/bug995817.js new file mode 100644 index 0000000000..6a46771854 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug995817.js @@ -0,0 +1,17 @@ +setJitCompilerOption('baseline.warmup.trigger', 1); +let r; +(function() { + function f() { + return (1 + -1 / 0) << null; + } + assertEq(f(), 0); + assertEq(f(), 0); + + function g(x,y) { + var a = x|0; + var b = y|0; + return (a / b + a / b) | 0; + } + assertEq(g(3,4), 1); + assertEq(g(3,4), 1); +})(); diff --git a/js/src/jit-test/tests/ion/bug995826.js b/js/src/jit-test/tests/ion/bug995826.js new file mode 100644 index 0000000000..062869e8bf --- /dev/null +++ b/js/src/jit-test/tests/ion/bug995826.js @@ -0,0 +1,5 @@ +function f(x) { + return Math.round(-Math.tan(x > 0)) +} +f(2) +assertEq(f(-1), -0); diff --git a/js/src/jit-test/tests/ion/bug998059.js b/js/src/jit-test/tests/ion/bug998059.js new file mode 100644 index 0000000000..fc2c68d7f5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug998059.js @@ -0,0 +1,25 @@ +// Test various ways of changing the behavior of |typedArray.length|. + +function addLengthProperty() { + var x = new Uint16Array(); + Object.defineProperty(x, "length", {value:1}); + for (var i = 0; i < 5; i++) + assertEq(x.length, 1); +} +addLengthProperty(); + +function changePrototype() { + var x = new Uint16Array(); + x.__proto__ = [0]; + for (var i = 0; i < 5; i++) + assertEq(x.length, 1); +} +changePrototype(); + +function redefineLengthProperty() { + var x = new Uint16Array(); + Object.defineProperty(Uint16Array.prototype, "length", {value:1}); + for (var i = 0; i < 5; i++) + assertEq(x.length, 1); +} +redefineLengthProperty(); diff --git a/js/src/jit-test/tests/ion/callTypeBarriers.js b/js/src/jit-test/tests/ion/callTypeBarriers.js new file mode 100644 index 0000000000..94f9683dce --- /dev/null +++ b/js/src/jit-test/tests/ion/callTypeBarriers.js @@ -0,0 +1,25 @@ +function fixProto(x) { + x.__proto__ = x.__proto__; +} + +function bar() { + + function foo(count) { + if (count) + return 10; + return "foo"; + } + fixProto(foo); + + function g(x, i) { + var t; + for (var j = 0; j < 200; j++) + t = x(i); + return t; + } + var D; + for (var i = 0; i < 100; i++) + D = g(foo, -99 + i); + return D; +} +print(bar()); diff --git a/js/src/jit-test/tests/ion/callgname.js b/js/src/jit-test/tests/ion/callgname.js new file mode 100644 index 0000000000..74b3cd8f1f --- /dev/null +++ b/js/src/jit-test/tests/ion/callgname.js @@ -0,0 +1,43 @@ +function g1(x) { + return x + 1; +} +function f1() { + var y = 0; + for (var i=0; i<100; i++) { + y += g1(g1(i)); + } + return y; +} +g1(10); +assertEq(f1(), 5150); + +x = 1; +other = newGlobal("same-compartment"); +other.eval("f = function() { return x; }; x = 2;"); + +h = other.f; + +function testOtherGlobal() { + var y = 0; + for (var i=0; i<100; i++) { + y += h(); + } + return y; +} +h(); +assertEq(testOtherGlobal(), 200); + +// Note: this test requires on On-Stack Invalidation. +f2 = function() { + return x; +} +function test2() { + var y = 0; + for (var i=0; i<50; i++) { + y += f2(); + } + return y; +} +assertEq(test2(), 50); +f2 = h; +assertEq(test2(), 100); diff --git a/js/src/jit-test/tests/ion/callobj-tdz.js b/js/src/jit-test/tests/ion/callobj-tdz.js new file mode 100644 index 0000000000..fff872a23e --- /dev/null +++ b/js/src/jit-test/tests/ion/callobj-tdz.js @@ -0,0 +1,14 @@ +// CallObject with TDZ arguments +function test( + a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, + {} = () => { + with ({}) {}; + return a00; + }) { +} + +// Warm-up JITs +for (var i = 0; i < 2000; ++i) { + test(); +} diff --git a/js/src/jit-test/tests/ion/ceil.js b/js/src/jit-test/tests/ion/ceil.js new file mode 100644 index 0000000000..1f058cf073 --- /dev/null +++ b/js/src/jit-test/tests/ion/ceil.js @@ -0,0 +1,65 @@ +setJitCompilerOption("baseline.warmup.trigger", 10); +setJitCompilerOption("ion.warmup.trigger", 20); + +//var log = print; +var log = function(x){} + +function ceil(x) { + // A nice but not always efficient polyfill. + return -Math.floor(-x); +} + +function doubleCheck(g) { + for (var j = 0; j < 200; j++) { + var i = j; + assertEq(g(i), i); + assertEq(g(i+.5), i+1); + assertEq(g(-i), -i); + assertEq(g(-i-.5), -i); + } +} + +function floatCheck(g, val) { + for (var j = 0; j < 200; j++) { + var i = Math.fround(j); + assertEq(g(i), i); + assertEq(g(i+.5), i+1); + assertEq(g(-i), -i); + assertEq(g(-i-.5), -i); + } +} + +function testBailout(value) { + var dceil = eval('(function(x) { return Math.ceil(x) })'); + log('start double'); + doubleCheck(dceil); + log('bailout'); + // At this point, the compiled code should bailout, if 'value' is in the + // edge case set. + assertEq(dceil(value), ceil(value)); + + var fceil = eval('(function(x) { return Math.ceil(Math.fround(x)) })'); + log('start float'); + floatCheck(fceil, value); + log('bailout'); + assertEq(fceil(Math.fround(value)), ceil(Math.fround(value))); +} + +var INT_MAX = Math.pow(2, 31) - 1; +var INT_MIN = INT_MAX + 1 | 0; +var UINT_MAX = Math.pow(2, 32) - 1; + +// Values in ]-1; -0] +testBailout(-0); +testBailout(-.5); +// Values outside the INT32 range, when represented in either double or +// single precision +testBailout(INT_MAX + .5); +testBailout(INT_MIN - 129); +// (UINT_MAX; +inf] have special behavior on ARM +testBailout(UINT_MAX); +testBailout(UINT_MAX + .5); +testBailout(UINT_MAX + 1); +testBailout(UINT_MAX + 2); +// BatNaN +testBailout(NaN); diff --git a/js/src/jit-test/tests/ion/close-iterators-1.js b/js/src/jit-test/tests/ion/close-iterators-1.js new file mode 100644 index 0000000000..6a1fbd96f4 --- /dev/null +++ b/js/src/jit-test/tests/ion/close-iterators-1.js @@ -0,0 +1,11 @@ +// |jit-test| error: InternalError +// from bug 729797, bug732852 as well +var patterns = new Array(); +patterns[0] = ''; +test(); +function test() { + for (i in patterns) { + s = patterns[i]; + status =(test)(s); + } +} diff --git a/js/src/jit-test/tests/ion/compare-char.js b/js/src/jit-test/tests/ion/compare-char.js new file mode 100644 index 0000000000..e63d69decc --- /dev/null +++ b/js/src/jit-test/tests/ion/compare-char.js @@ -0,0 +1,189 @@ +function IsASCIIAlphaString_CharCodeAt(s) { + for (var i = 0; i < s.length; i++) { + var c = s.charCodeAt(i); + if (!((0x41 <= c && c <= 0x5A) || (0x61 <= c && c <= 0x7A))) + return false; + } + return true; +} + +function IsASCIIAlphaString_CharAt(s) { + for (var i = 0; i < s.length; i++) { + var c = s.charAt(i); + if (!(("A" <= c && c <= "Z") || ("a" <= c && c <= "z"))) + return false; + } + return true; +} + +function IsASCIIAlphaString_GetElem(s) { + for (var i = 0; i < s.length; i++) { + var c = s[i]; + if (!(("A" <= c && c <= "Z") || ("a" <= c && c <= "z"))) + return false; + } + return true; +} + +function IsASCIIAlphaString_GetElem_GetElem(s) { + var range = "AZaz"; + for (var i = 0; i < s.length; i++) { + var c = s[i]; + if (!((range[0] <= c && c <= range[1]) || (range[2] <= c && c <= range[3]))) + return false; + } + return true; +} + +function IsGreekOrCyrillicString_CharCodeAt(s) { + // U+0370 (GREEK CAPITAL LETTER HETA) + // U+03FF (GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL) + // U+0400 (CYRILLIC CAPITAL LETTER IE WITH GRAVE) + // U+052F (CYRILLIC SMALL LETTER EL WITH DESCENDER) + for (var i = 0; i < s.length; i++) { + var c = s.charCodeAt(i); + if (!((0x0370 <= c && c <= 0x03FF) || (0x400 <= c && c <= 0x052F))) + return false; + } + return true; +} + +function IsGreekOrCyrillicString_CharAt(s) { + for (var i = 0; i < s.length; i++) { + var c = s.charAt(i); + if (!(("Ͱ" <= c && c <= "Ͽ") || ("Ѐ" <= c && c <= "ԯ"))) + return false; + } + return true; +} + +function IsGreekOrCyrillicString_GetElem(s) { + for (var i = 0; i < s.length; i++) { + var c = s[i]; + if (!(("Ͱ" <= c && c <= "Ͽ") || ("Ѐ" <= c && c <= "ԯ"))) + return false; + } + return true; +} + +function IsGreekOrCyrillicString_GetElem_GetElem(s) { + var range = "ͰϿЀԯ"; + for (var i = 0; i < s.length; i++) { + var c = s[i]; + if (!((range[0] <= c && c <= range[1]) || (range[2] <= c && c <= range[3]))) + return false; + } + return true; +} + +function main() { + function compareLatin1() { + var strings = ["ABCABCABC", "abcabcabc"]; + var compare = "aAbD"; + var q = 0; + for (var i = 0; i < 200; ++i) { + var str = strings[i & 1]; + for (var j = 0; j < str.length; ++j) { + if (str[j] === "a") + q++; + if ("A" == str[j]) + q++; + if (str[j] != "b") + q++; + if ("D" !== str[j]) + q++; + if (str[j] === compare[0]) + q++; + if (compare[1] == str[j]) + q++; + if (str[j] != compare[2]) + q++; + if (compare[3] !== str[j]) + q++; + } + } + assertEq(q, 100*3*2 + 100*3*2 + 100*15*2 + 100*18*2); + } + function compareTwoByte() { + var strings = ["āĉœāĉœāĉœ", "abcabcabc"]; + var compare = "œĉāƉ"; + var q = 0; + for (var i = 0; i < 200; ++i) { + var str = strings[i & 1]; + for (var j = 0; j < str.length; ++j) { + if ("œ" === str[j]) + q++; + if (str[j] == "ĉ") + q++; + if ("ā" != str[j]) + q++; + if (str[j] !== "Ɖ") + q++; + if (compare[0] === str[j]) + q++; + if (str[j] == compare[1]) + q++; + if (compare[2] != str[j]) + q++; + if (str[j] !== compare[3]) + q++; + } + } + assertEq(q, 100*3*2 + 100*3*2 + 100*15*2 + 100*18*2); + } + function compareRangeLatin1() { + var strings = [ + "ABCABCABC", // all upper + "abcabcabc", // all lower + "abcABCabc", // lower and upper + "abcabc123", // characters below limit + "abc[_]ABC", // characters between limit + "ABC{|}abc", // characters above limit + "!#$456_~ÿ", // no matches at all + "aBcZyyZUU", // - + ]; + for (var i = 0; i < 200; ++i) { + var str = strings[i & 7]; + var resultCharCodeAt = IsASCIIAlphaString_CharCodeAt(str); + var resultCharAt = IsASCIIAlphaString_CharAt(str); + var resultGetElem = IsASCIIAlphaString_GetElem(str); + var resultGetElemGetElem = IsASCIIAlphaString_GetElem_GetElem(str); + + assertEq(resultCharAt, resultCharCodeAt); + assertEq(resultGetElem, resultCharCodeAt); + assertEq(resultGetElemGetElem, resultCharCodeAt); + } + } + function compareRangeTwoByte() { + var strings = [ + "αβγΑΒΓαβγ", // all Greek + "АБВабвАБВ", // all Cyrillic + "αβγабвАБΓ", // Greek and Cyrillic + "αβγāēōАБВ", // characters below limit + "αβγԱԲԳАБВ", // characters above limit + "abcāēōԱԲԳ", // no matches at all + "𝐀𝐁𝐂𝐀𝐁𝐂𝐀𝐁𝐂", // (non-BMP) + "abcabcabc", // - + ]; + for (var i = 0; i < 200; ++i) { + var str = strings[i & 7]; + var resultCharCodeAt = IsGreekOrCyrillicString_CharCodeAt(str); + var resultCharAt = IsGreekOrCyrillicString_CharAt(str); + var resultGetElem = IsGreekOrCyrillicString_GetElem(str); + var resultGetElemGetElem = IsGreekOrCyrillicString_GetElem_GetElem(str); + + assertEq(resultCharAt, resultCharCodeAt); + assertEq(resultGetElem, resultCharCodeAt); + assertEq(resultGetElemGetElem, resultCharCodeAt); + } + } + + compareLatin1(); + compareTwoByte(); + compareRangeLatin1(); + compareRangeTwoByte(); +} + +for (var i = 0; i < 15; ++i) { + main(); +} diff --git a/js/src/jit-test/tests/ion/compare-string.js b/js/src/jit-test/tests/ion/compare-string.js new file mode 100644 index 0000000000..db5d295417 --- /dev/null +++ b/js/src/jit-test/tests/ion/compare-string.js @@ -0,0 +1,131 @@ +function compareToAtom(a) { + return a == 'test-test-test-test-test-test-test-test'; +} + +function compareToAtomStrict(a) { + return a === 'test-test-test-test-test-test-test-test'; +} + +function compareToAtomNe(a) { + return a != 'test-test-test-test-test-test-test-test'; +} + +function compareToAtomNeStrict(a) { + return a !== 'test-test-test-test-test-test-test-test'; +} + +function compareToAtomLessThan(a) { + return a < 'test-test-test-test-test-test-test-test'; +} + +function compareToAtomLessThanOrEquals(a) { + return a <= 'test-test-test-test-test-test-test-test'; +} + +function compareToAtomGreaterThan(a) { + return a > 'test-test-test-test-test-test-test-test'; +} + +function compareToAtomGreaterThanOrEquals(a) { + return a >= 'test-test-test-test-test-test-test-test'; +} + +var st = 'st-test-test-test-test-test-test-test'; + +function compareToRope(a) { + return a == ('te' + st); +} + +function compareToRopeStrict(a) { + return a === ('te' + st); +} + +function compareToRopeNe(a) { + var st = 'st-test-test-test-test-test-test-test'; + return a != ('te' + st); +} + +function compareToRopeNeStrict(a) { + var st = 'st-test-test-test-test-test-test-test'; + return a !== ('te' + st); +} + +function compareToRopeLessThan(a) { + var st = 'st-test-test-test-test-test-test-test'; + return a < ('te' + st); +} + +function compareToRopeLessThanOrEquals(a) { + var st = 'st-test-test-test-test-test-test-test'; + return a <= ('te' + st); +} + +function compareToRopeGreaterThan(a) { + var st = 'st-test-test-test-test-test-test-test'; + return a > ('te' + st); +} + +function compareToRopeGreaterThanOrEquals(a) { + var st = 'st-test-test-test-test-test-test-test'; + return a >= ('te' + st); +} + +function main() { + // |test| must be longer than |JSFatInlineString::MAX_LENGTH_LATIN1| to + // ensure the above functions create ropes when concatenating strings. + var test = 'test-test-test-test-test-test-test-test'; + var foobar = 'foobar'; + + assertEq(compareToAtom(test), true); + assertEq(compareToAtom(foobar), false); + + assertEq(compareToAtomStrict(test), true); + assertEq(compareToAtomStrict(foobar), false); + + assertEq(compareToAtomNe(test), false); + assertEq(compareToAtomNe(foobar), true); + + assertEq(compareToAtomNeStrict(test), false); + assertEq(compareToAtomNeStrict(foobar), true); + + assertEq(compareToAtomLessThan(test), false); + assertEq(compareToAtomLessThan(foobar), true); + + assertEq(compareToAtomLessThanOrEquals(test), true); + assertEq(compareToAtomLessThanOrEquals(foobar), true); + + assertEq(compareToAtomGreaterThan(test), false); + assertEq(compareToAtomGreaterThan(foobar), false); + + assertEq(compareToAtomGreaterThanOrEquals(test), true); + assertEq(compareToAtomGreaterThanOrEquals(foobar), false); + + + assertEq(compareToRope(test), true); + assertEq(compareToRope(foobar), false); + + assertEq(compareToRopeStrict(test), true); + assertEq(compareToRopeStrict(foobar), false); + + assertEq(compareToRopeNe(test), false); + assertEq(compareToRopeNe(foobar), true); + + assertEq(compareToRopeNeStrict(test), false); + assertEq(compareToRopeNeStrict(foobar), true); + + assertEq(compareToRopeLessThan(test), false); + assertEq(compareToRopeLessThan(foobar), true); + + assertEq(compareToRopeLessThanOrEquals(test), true); + assertEq(compareToRopeLessThanOrEquals(foobar), true); + + assertEq(compareToRopeGreaterThan(test), false); + assertEq(compareToRopeGreaterThan(foobar), false); + + assertEq(compareToRopeGreaterThanOrEquals(test), true); + assertEq(compareToRopeGreaterThanOrEquals(foobar), false); +} + +for (var i = 0; i < 10000; i++) { + main(); +} diff --git a/js/src/jit-test/tests/ion/compareAll.js b/js/src/jit-test/tests/ion/compareAll.js new file mode 100644 index 0000000000..58d82b4a43 --- /dev/null +++ b/js/src/jit-test/tests/ion/compareAll.js @@ -0,0 +1,279 @@ +load(libdir + 'array-compare.js'); + +function compareIAndSet(v) { + var res = 0; + var c; + var i = 0; + c = (v > 1); + res |= (c << i); + i++; + c = (v >= 2); + res |= (c << i); + i++; + c = (v < 3); + res |= (c << i); + i++; + c = (v <= 4); + res |= (c << i); + i++; + c = (v == 5); + res |= (c << i); + i++; + c = (v != 6); + res |= (c << i); + i++; + c = (v === 7); + res |= (c << i); + i++; + c = (v !== 8); + res |= (c << i); + i++; + return res; +} + +function compareIAndBranch(v) { + var res = 0; + var c = 1; + var i = 0; + if (v > 1) + res |= (c << i); + i++; + if (v >= 2) + res |= (c << i); + i++; + if (v < 3) + res |= (c << i); + i++; + if (v <= 4) + res |= (c << i); + i++; + if (v == 5) + res |= (c << i); + i++; + if (v != 6) + res |= (c << i); + i++; + if (v === 7) + res |= (c << i); + i++; + if (v !== 8) + res |= (c << i); + i++; + if (v) + res |= (c << i); + i++; + return res; +} + +function compareDAndSet(v) { + var res = 0; + var c; + var i = 0; + c = (v > 1.5); + res |= (c << i); + i++; + c = (v >= 2.5); + res |= (c << i); + i++; + c = (v < 3.5); + res |= (c << i); + i++; + c = (v <= 4.5); + res |= (c << i); + i++; + c = (v == 5.5); + res |= (c << i); + i++; + c = (v != 6.5); + res |= (c << i); + i++; + c = (v === 7.5); + res |= (c << i); + i++; + c = (v !== 8.5); + res |= (c << i); + i++; + c = (v !== 0.0); + res |= (c << i); + i++; + return res; +} + +function compareDAndBranch(v) { + var res = 0; + var c = 1; + var i = 0; + if (v > 1.5) + res |= (c << i); + i++; + if (v >= 2.5) + res |= (c << i); + i++; + if (v < 3.5) + res |= (c << i); + i++; + if (v <= 4.5) + res |= (c << i); + i++; + if (v == 5.5) + res |= (c << i); + i++; + if (v != 6.5) + res |= (c << i); + i++; + if (v === 7.5) + res |= (c << i); + i++; + if (v !== 8.5) + res |= (c << i); + i++; + if (v) + res |= (c << i); + i++; + return res; +} + +function compareSAndSet(v) { + var res = 0; + var c; + var i = 0; + c = (v > "a"); + res |= (c << i); + i++; + c = (v >= "b"); + res |= (c << i); + i++; + c = (v < "c"); + res |= (c << i); + i++; + c = (v <= "d"); + res |= (c << i); + i++; + c = (v == "e"); + res |= (c << i); + i++; + c = (v != "f"); + res |= (c << i); + i++; + c = (v === "g"); + res |= (c << i); + i++; + c = (v !== "h"); + res |= (c << i); + i++; + return res; +} + +function compareSAndBranch(v) { + var res = 0; + var c = 1; + var i = 0; + if (v > "a") + res |= (c << i); + i++; + if (v >= "b") + res |= (c << i); + i++; + if (v < "c") + res |= (c << i); + i++; + if (v <= "d") + res |= (c << i); + i++; + if (v == "e") + res |= (c << i); + i++; + if (v != "f") + res |= (c << i); + i++; + if (v === "g") + res |= (c << i); + i++; + if (v !== "h") + res |= (c << i); + i++; + if (v) + res |= (c << i); + i++; + return res; +} + +var expected = [ + // compareIAndSet + 172, 175, 171, 171, 179, 131, 227, 35, + // compareIAndBranch + 428, 431, 427, 427, 435, 387, 483, 291, + // compareDAndSet + 428, 428, 431, 427, 427, 435, 387, 483, 291, 416, + // compareDAndBranch + 428, 428, 431, 427, 427, 435, 387, 483, 291, 160, 172, + // compareSAndSet + 172, 175, 171, 171, 179, 131, 227, 35, 172, + // compareSAndBranch + 428, 431, 427, 427, 435, 387, 483, 291, 172 +]; + +var result = [ + compareIAndSet(1), + compareIAndSet(2), + compareIAndSet(3), + compareIAndSet(4), + compareIAndSet(5), + compareIAndSet(6), + compareIAndSet(7), + compareIAndSet(8), + + compareIAndBranch(1), + compareIAndBranch(2), + compareIAndBranch(3), + compareIAndBranch(4), + compareIAndBranch(5), + compareIAndBranch(6), + compareIAndBranch(7), + compareIAndBranch(8), + + compareDAndSet(0.5), + compareDAndSet(1.5), + compareDAndSet(2.5), + compareDAndSet(3.5), + compareDAndSet(4.5), + compareDAndSet(5.5), + compareDAndSet(6.5), + compareDAndSet(7.5), + compareDAndSet(8.5), + compareDAndSet(NaN), + + compareDAndBranch(0.5), + compareDAndBranch(1.5), + compareDAndBranch(2.5), + compareDAndBranch(3.5), + compareDAndBranch(4.5), + compareDAndBranch(5.5), + compareDAndBranch(6.5), + compareDAndBranch(7.5), + compareDAndBranch(8.5), + compareDAndBranch(NaN), + compareDAndBranch(0.0), + + compareSAndSet("a"), + compareSAndSet("b"), + compareSAndSet("c"), + compareSAndSet("d"), + compareSAndSet("e"), + compareSAndSet("f"), + compareSAndSet("g"), + compareSAndSet("h"), + compareSAndSet(""), + + compareSAndBranch("a"), + compareSAndBranch("b"), + compareSAndBranch("c"), + compareSAndBranch("d"), + compareSAndBranch("e"), + compareSAndBranch("f"), + compareSAndBranch("g"), + compareSAndBranch("h"), + compareSAndBranch("") +]; + +assertEq(arraysEqual(result, expected), true); diff --git a/js/src/jit-test/tests/ion/condswitch.js b/js/src/jit-test/tests/ion/condswitch.js new file mode 100644 index 0000000000..2ab0a43e44 --- /dev/null +++ b/js/src/jit-test/tests/ion/condswitch.js @@ -0,0 +1,104 @@ +// This test case is made to be run with --ion-eager. + +function ret2() { + return 2; +} + +// Check with default case in the middle. +function test0(x) { + var res = 0; + switch (x) { + case (res |= 0x40, 1): // x === 1 + res |= 0x1; + default: // otherwise + res |= 0x2; + case (res |= 0x80, ret2()): // x === 2 + res |= 0x4; + case (res |= 0x100, 1 + ret2()): // x === 3 + res |= 0x8; + break; + case (res |= 0x200, 0): // x === 0 + res |= 0x10; + } + res |= 0x20; + return res; +} + +assertEq(test0(0), 0x40 | 0x80 | 0x100 | 0x200 | 0x10 | 0x20); +assertEq(test0(1), 0x40 | 0x1 | 0x2 | 0x4 | 0x8 | 0x20); +assertEq(test0(2), 0x40 | 0x80 | 0x4 | 0x8 | 0x20); +assertEq(test0(3), 0x40 | 0x80 | 0x100 | 0x8 | 0x20); +assertEq(test0(4), 0x40 | 0x80 | 0x100 | 0x200 | 0x2 | 0x4 | 0x8 | 0x20); + +// Check with no default and only one case. +function test1(x) { + var res = 0; + switch (x) { + case (res |= 0x1, ret2()): // x === 2 + res |= 0x2; + } + res |= 0x4; + return res; +} + +assertEq(test1(1), 0x1 | 0x4); // default. +assertEq(test1(2), 0x1 | 0x2 | 0x4); // case. + +// Check with default case identical to a case. +function test2(x) { + var res = 0; + switch (x) { + case (res |= 0x1, 0): + res |= 0x10; + break; + default: + case (res |= 0x2, 1): + res |= 0x20; + break; + case (res |= 0x4, ret2()): // x === 2 + res |= 0x40; + } + res |= 0x100; + return res; +} + +assertEq(test2(0), 0x1 | 0x10 | 0x100); +assertEq(test2(1), 0x1 | 0x2 | 0x20 | 0x100); +assertEq(test2(2), 0x1 | 0x2 | 0x4 | 0x40 | 0x100); +assertEq(test2(3), 0x1 | 0x2 | 0x4 | 0x20 | 0x100); + +// Check a non-break, non-empty default at the end. +function test3(x) { + var res = 0; + switch (x) { + case (res |= 0x1, 1): + res |= 0x10; + case (res |= 0x2, ret2()): // x === 2 + res |= 0x20; + default: + res |= 0x40; + } + res |= 0x100; + return res; +} + +assertEq(test3(1), 0x1 | 0x10 | 0x20 | 0x40 | 0x100); +assertEq(test3(2), 0x1 | 0x2 | 0x20 | 0x40 | 0x100); +assertEq(test3(3), 0x1 | 0x2 | 0x40 | 0x100); + +// Check cfg in condition of non-last case with no break. (reverse post order failure ?) +function test4(x) { + var res = 0; + switch (x) { + case (res |= 0x1, (x ? 1 : 0)): + res |= 0x10; + case (res |= 0x2, ret2()): // x === 2 + res |= 0x20; + } + res |= 0x100; + return res; +} + +assertEq(test4(0), 0x1 | 0x10 | 0x20 | 0x100); +assertEq(test4(1), 0x1 | 0x10 | 0x20 | 0x100); +assertEq(test4(2), 0x1 | 0x2 | 0x20 | 0x100); diff --git a/js/src/jit-test/tests/ion/context-override.js b/js/src/jit-test/tests/ion/context-override.js new file mode 100644 index 0000000000..b45f51c03c --- /dev/null +++ b/js/src/jit-test/tests/ion/context-override.js @@ -0,0 +1,2 @@ +// |jit-test| --no-ion-for-main-context +assertEq(inIon(), "Ion is disabled."); diff --git a/js/src/jit-test/tests/ion/dce-with-rinstructions.js b/js/src/jit-test/tests/ion/dce-with-rinstructions.js new file mode 100644 index 0000000000..e85dad6101 --- /dev/null +++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js @@ -0,0 +1,1738 @@ +// |jit-test| --ion-limit-script-size=off + +setJitCompilerOption("baseline.warmup.trigger", 9); +setJitCompilerOption("ion.warmup.trigger", 20); +var i; + +var warp = true; + +// Prevent GC from cancelling/discarding Ion compilations. +gczeal(0); + +var config = getBuildConfiguration(); +var max = 200; + +// Check that we are able to remove the operation inside recover test functions (denoted by "rop..."), +// when we inline the first version of uceFault, and ensure that the bailout is correct +// when uceFault is replaced (which cause an invalidation bailout) + +var uceFault = function (i) { + if (i > 98) + uceFault = function (i) { return true; }; + return false; +} + +var uceFault_bitnot_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitnot_number')); +function rbitnot_number(i) { + var x = ~i; + if (uceFault_bitnot_number(i) || uceFault_bitnot_number(i)) + assertEq(x, -100 /* = ~99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_bitnot_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitnot_object')); +function rbitnot_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = ~o; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_bitnot_object(i) || uceFault_bitnot_object(i)) + assertEq(x, -100 /* = ~99 */); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_bitand_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitand_number')); +function rbitand_number(i) { + var x = 1 & i; + if (uceFault_bitand_number(i) || uceFault_bitand_number(i)) + assertEq(x, 1 /* = 1 & 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_bitand_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitand_object')); +function rbitand_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = o & i; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_bitand_object(i) || uceFault_bitand_object(i)) + assertEq(x, 99); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_bitor_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitor_number')); +function rbitor_number(i) { + var x = i | -100; /* -100 == ~99 */ + if (uceFault_bitor_number(i) || uceFault_bitor_number(i)) + assertEq(x, -1) /* ~99 | 99 = -1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_bitor_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitor_object')); +function rbitor_object(i) { + var t = i; + var o = { valueOf: function() { return t; } }; + var x = o | -100; + t = 1000; + if (uceFault_bitor_object(i) || uceFault_bitor_object(i)) + assertEq(x, -1); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_bitxor_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitxor_number')); +function rbitxor_number(i) { + var x = 1 ^ i; + if (uceFault_bitxor_number(i) || uceFault_bitxor_number(i)) + assertEq(x, 98 /* = 1 XOR 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_bitxor_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitxor_object')); +function rbitxor_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = 1 ^ o; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_bitxor_object(i) || uceFault_bitxor_object(i)) + assertEq(x, 98 /* = 1 XOR 99 */); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_lsh_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_lsh_number')); +function rlsh_number(i) { + var x = i << 1; + if (uceFault_lsh_number(i) || uceFault_lsh_number(i)) + assertEq(x, 198); /* 99 << 1 == 198 */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_lsh_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_lsh_object')); +function rlsh_object(i) { + var t = i; + var o = { valueOf: function() { return t; } }; + var x = o << 1; + t = 1000; + if (uceFault_lsh_object(i) || uceFault_lsh_object(i)) + assertEq(x, 198); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_rsh_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_rsh_number')); +function rrsh_number(i) { + var x = i >> 1; + if (uceFault_rsh_number(i) || uceFault_rsh_number(i)) + assertEq(x, 49 /* = 99 >> 1 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_rsh_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_rsh_object')); +function rrsh_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = o >> 1; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_rsh_object(i) || uceFault_rsh_object(i)) + assertEq(x, 49 /* = 99 >> 1 */); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_ursh_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_ursh_number')); +function rursh_number(i) { + var x = i >>> 1; + if (uceFault_ursh_number(i) || uceFault_ursh_number(i)) + assertEq(x, 49 /* = 99 >>> 1 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_ursh_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_ursh_object')); +function rursh_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = o >>> 1; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_ursh_object(i) || uceFault_ursh_object(i)) + assertEq(x, 49 /* = 99 >>> 1 */); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_signextend8_1 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_signextend8_1')); +function rsignextend8_1(i) { + var x = (i << 24) >> 24; + if (uceFault_signextend8_1(i) || uceFault_signextend8_1(i)) + assertEq(x, 99 /* = (99 << 24) >> 24 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_signextend8_2 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_signextend8_2')); +function rsignextend8_2(i) { + var x = ((-1 * i) << 24) >> 24; + if (uceFault_signextend8_2(i) || uceFault_signextend8_2(i)) + assertEq(x, -99 /* = (-99 << 24) >> 24 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_signextend16_1 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_signextend16_1')); +function rsignextend16_1(i) { + var x = (i << 16) >> 16; + if (uceFault_signextend16_1(i) || uceFault_signextend16_1(i)) + assertEq(x, 99 /* = (99 << 16) >> 16 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_signextend16_2 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_signextend16_2')); +function rsignextend16_2(i) { + var x = ((-1 * i) << 16) >> 16; + if (uceFault_signextend16_2(i) || uceFault_signextend16_2(i)) + assertEq(x, -99 /* = (-99 << 16) >> 16 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_add_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_add_number')); +function radd_number(i) { + var x = 1 + i; + if (uceFault_add_number(i) || uceFault_add_number(i)) + assertEq(x, 100 /* = 1 + 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_add_float = eval(`(${uceFault})`.replace('uceFault', 'uceFault_add_float')); +function radd_float(i) { + var t = Math.fround(1/3); + var fi = Math.fround(i); + var x = Math.fround(Math.fround(Math.fround(Math.fround(t + fi) + t) + fi) + t); + if (uceFault_add_float(i) || uceFault_add_float(i)) + assertEq(x, 199); /* != 199.00000002980232 (when computed with double additions) */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_add_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_add_object')); +function radd_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = o + i; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_add_object(i) || uceFault_add_object(i)) + assertEq(x, 198); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_sub_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sub_number')); +function rsub_number(i) { + var x = 1 - i; + if (uceFault_sub_number(i) || uceFault_sub_number(i)) + assertEq(x, -98 /* = 1 - 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_sub_float = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sub_float')); +function rsub_float(i) { + var t = Math.fround(1/3); + var fi = Math.fround(i); + var x = Math.fround(Math.fround(Math.fround(Math.fround(t - fi) - t) - fi) - t); + if (uceFault_sub_float(i) || uceFault_sub_float(i)) + assertEq(x, -198.3333282470703); /* != -198.33333334326744 (when computed with double subtractions) */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_sub_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sub_object')); +function rsub_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = o - i; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_sub_object(i) || uceFault_sub_object(i)) + assertEq(x, 0); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_mul_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_mul_number')); +function rmul_number(i) { + var x = 2 * i; + if (uceFault_mul_number(i) || uceFault_mul_number(i)) + assertEq(x, 198 /* = 2 * 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_mul_overflow = eval(`(${uceFault})`.replace('uceFault', 'uceFault_mul_overflow')); +function rmul_overflow(i) { + var x = Math.pow(2, i * 16 / 99) | 0; + x = x * x; + if (uceFault_mul_overflow(i) || uceFault_mul_overflow(i)) + assertEq(x, Math.pow(2, 32)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_mul_float = eval(`(${uceFault})`.replace('uceFault', 'uceFault_mul_float')); +function rmul_float(i) { + var t = Math.fround(1/3); + var fi = Math.fround(i); + var x = Math.fround(Math.fround(Math.fround(Math.fround(t * fi) * t) * fi) * t); + if (uceFault_mul_float(i) || uceFault_mul_float(i)) + assertEq(x, 363); /* != 363.0000324547301 (when computed with double multiplications) */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_mul_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_mul_object')); +function rmul_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = o * i; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_mul_object(i) || uceFault_mul_object(i)) + assertEq(x, 9801); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_imul_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_imul_number')); +function rimul_number(i) { + var x = Math.imul(2, i); + if (uceFault_imul_number(i) || uceFault_imul_number(i)) + assertEq(x, 198 /* = 2 * 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_imul_overflow = eval(`(${uceFault})`.replace('uceFault', 'uceFault_imul_overflow')); +function rimul_overflow(i) { + var x = Math.pow(2, i * 16 / 99) | 0; + x = Math.imul(x, x); + if (uceFault_imul_overflow(i) || uceFault_imul_overflow(i)) + assertEq(x, 0); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_imul_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_imul_object')); +function rimul_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = Math.imul(o, i); /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_imul_object(i) || uceFault_imul_object(i)) + assertEq(x, 9801); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_div_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_div_number')); +function rdiv_number(i) { + var x = 1 / i; + if (uceFault_div_number(i) || uceFault_div_number(i)) + assertEq(x, 0.010101010101010102 /* = 1 / 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_div_float = eval(`(${uceFault})`.replace('uceFault', 'uceFault_div_float')); +function rdiv_float(i) { + var t = Math.fround(1/3); + var fi = Math.fround(i); + var x = Math.fround(Math.fround(Math.fround(Math.fround(t / fi) / t) / fi) / t); + if (uceFault_div_float(i) || uceFault_div_float(i)) + assertEq(x, 0.0003060912131331861); /* != 0.0003060912060598955 (when computed with double divisions) */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_div_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_div_object')); +function rdiv_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = o / i; /* computed with t == i, not 1000 */ + t = 1000; + if (uceFault_div_object(i) || uceFault_div_object(i)) + assertEq(x, 1); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_mod_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_mod_number')); +function rmod_number(i) { + var x = i % 98; + if (uceFault_mod_number(i) || uceFault_mod_number(i)) + assertEq(x, 1); /* 99 % 98 = 1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_mod_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_mod_object')); +function rmod_object(i) { + var t = i; + var o = { valueOf: function() { return t; } }; + var x = o % 98; /* computed with t == i, not 1000 */ + t = 1000; + if(uceFault_mod_object(i) || uceFault_mod_object(i)) + assertEq(x, 1); /* 99 % 98 = 1 */ + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_not_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_not_number')); +function rnot_number(i) { + var x = !i; + if (uceFault_not_number(i) || uceFault_not_number(i)) + assertEq(x, false /* = !99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_not_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_not_object')); +function rnot_object(i) { + var o = createIsHTMLDDA(); + var x = !o; + if(uceFault_not_object(i) || uceFault_not_object(i)) + assertEq(x, true /* = !undefined = !document.all = !createIsHTMLDDA() */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_concat_string = eval(`(${uceFault})`.replace('uceFault', 'uceFault_concat_string')); +function rconcat_string(i) { + var x = "s" + i.toString(); + if (uceFault_concat_string(i) || uceFault_concat_string(i)) + assertEq(x, "s99"); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_concat_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_concat_number')); +function rconcat_number(i) { + var x = "s" + i; + if (uceFault_concat_number(i) || uceFault_concat_number(i)) + assertEq(x, "s99"); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_string_length = eval(`(${uceFault})`.replace('uceFault', 'uceFault_string_length')); +function rstring_length(i) { + var x = i.toString().length; + if (uceFault_string_length(i) || uceFault_string_length(i)) + assertEq(x, 2); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_arguments_length_1 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arguments_length_1')); +function rarguments_length_1(i) { + var x = arguments.length; + if (uceFault_arguments_length_1(i) || uceFault_arguments_length_1(i)) + assertEq(x, 1); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_arguments_length_3 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arguments_length_3')); +function rarguments_length_3(i) { + var x = arguments.length; + if (uceFault_arguments_length_3(i) || uceFault_arguments_length_3(i)) + assertEq(x, 3); + assertRecoveredOnBailout(x, true); + return i; +} + +function ret_argumentsLength() { return arguments.length; } + +var uceFault_inline_arguments_length_1 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_inline_arguments_length_1')); +function rinline_arguments_length_1(i) { + var x = ret_argumentsLength.apply(this, arguments); + if (uceFault_inline_arguments_length_1(i) || uceFault_inline_arguments_length_1(i)) + assertEq(x, 1); + // We cannot garantee that the function would be inlined + // assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_inline_arguments_length_3 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_inline_arguments_length_3')); +function rinline_arguments_length_3(i) { + var x = ret_argumentsLength.apply(this, arguments); + if (uceFault_inline_arguments_length_3(i) || uceFault_inline_arguments_length_3(i)) + assertEq(x, 3); + // We cannot garantee that the function would be inlined + // assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_floor_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_floor_number')); +function rfloor_number(i) { + var x = Math.floor(i + 0.1111); + if (uceFault_floor_number(i) || uceFault_floor_number(i)) + assertEq(x, i); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_floor_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_floor_object')); +function rfloor_object(i) { + var t = i + 0.1111; + var o = { valueOf: function () { return t; } }; + var x = Math.floor(o); + t = 1000.1111; + if (uceFault_floor_object(i) || uceFault_floor_object(i)) + assertEq(x, i); + assertRecoveredOnBailout(x, false); + return i; +} + +let uceFault_floor_double = eval(`(${uceFault})`.replace('uceFault', 'uceFault_floor_double')); +function rfloor_double(i) { + const x = Math.floor(i + (-1 >>> 0)); + if (uceFault_floor_double(i) || uceFault_floor_double(i)) + assertEq(x, 99 + (-1 >>> 0)); /* = i + 2 ^ 32 - 1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_ceil_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_ceil_number')); +function rceil_number(i) { + var x = Math.ceil(-i - 0.12010799100); + if (uceFault_ceil_number(i) || uceFault_ceil_number(i)) + assertEq(x, -i); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_ceil_double = eval(`(${uceFault})`.replace('uceFault', 'uceFault_ceil_double')); +function rceil_double(i) { + const x = Math.ceil(i + (-1 >>> 0)); + if (uceFault_ceil_double(i) || uceFault_ceil_double(i)) + assertEq(x, 99 + (-1 >>> 0)); /* = i + 2 ^ 32 - 1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_round_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_round')); +function rround_number(i) { + var x = Math.round(i + 1.4); + if (uceFault_round_number(i) || uceFault_round_number(i)) + assertEq(x, 100); /* = i + 1*/ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_round_double = eval(`(${uceFault})`.replace('uceFault', 'uceFault_round_double')); +function rround_double(i) { + var x = Math.round(i + (-1 >>> 0)); + if (uceFault_round_double(i) || uceFault_round_double(i)) + assertEq(x, 99 + (-1 >>> 0)); /* = i + 2 ^ 32 - 1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_trunc_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_trunc_number')); +function rtrunc_number(i) { + var x = Math.trunc(-i - 0.12010799100); + if (uceFault_trunc_number(i) || uceFault_trunc_number(i)) + assertEq(x, -i); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_trunc_double = eval(`(${uceFault})`.replace('uceFault', 'uceFault_trunc_double')); +function rtrunc_double(i) { + const x = Math.trunc(i + (-1 >>> 0)); + if (uceFault_trunc_double(i) || uceFault_trunc_double(i)) + assertEq(x, 99 + (-1 >>> 0)); /* = i + 2 ^ 32 - 1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_Char_Code_At = eval(`(${uceFault})`.replace('uceFault', 'uceFault_Char_Code_At')); +function rcharCodeAt(i) { + var s = "aaaaa"; + var x = s.charCodeAt(i % 4); + if (uceFault_Char_Code_At(i) || uceFault_Char_Code_At(i)) + assertEq(x, 97 ); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_from_char_code = eval(`(${uceFault})`.replace('uceFault', 'uceFault_from_char_code')); +function rfrom_char_code(i) { + var x = String.fromCharCode(i); + if (uceFault_from_char_code(i) || uceFault_from_char_code(i)) + assertEq(x, "c"); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_from_char_code_non_ascii = eval(`(${uceFault})`.replace('uceFault', 'uceFault_from_char_code_non_ascii')); +function rfrom_char_code_non_ascii(i) { + var x = String.fromCharCode(i * 100); + if (uceFault_from_char_code_non_ascii(i) || uceFault_from_char_code_non_ascii(i)) + assertEq(x, "\u26AC"); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_pow_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_pow_number')); +function rpow_number(i) { + var x = Math.pow(i, 3.14159); + if (uceFault_pow_number(i) || uceFault_pow_number(i)) + assertEq(x, Math.pow(99, 3.14159)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_pow_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_pow_object')); +function rpow_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = Math.pow(o, 3.14159); /* computed with t == i, not 1.5 */ + t = 1.5; + if (uceFault_pow_object(i) || uceFault_pow_object(i)) + assertEq(x, Math.pow(99, 3.14159)); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_powhalf_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_powhalf_number')); +function rpowhalf_number(i) { + var x = Math.pow(i, 0.5); + if (uceFault_powhalf_number(i) || uceFault_powhalf_number(i)) + assertEq(x, Math.pow(99, 0.5)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_powhalf_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_powhalf_object')); +function rpowhalf_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = Math.pow(o, 0.5); /* computed with t == i, not 1.5 */ + t = 1.5; + if (uceFault_powhalf_object(i) || uceFault_powhalf_object(i)) + assertEq(x, Math.pow(99, 0.5)); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_min_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_min_number')); +function rmin_number(i) { + var x = Math.min(i, i-1, i-2.1); + if (uceFault_min_number(i) || uceFault_min_number(i)) + assertEq(x, i-2.1); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_min_float = eval(`(${uceFault})`.replace('uceFault', 'uceFault_min_float')); +function rmin_float(i) { + var x = Math.fround(Math.min(Math.fround(i), Math.fround(13.37))); + if (uceFault_min_number(i) || uceFault_min_number(i)) + assertEq(x, Math.fround(13.37)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_min_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_min_object')); +function rmin_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = Math.min(o, o-1, o-2.1) + t = 1000; + if (uceFault_min_object(i) || uceFault_min_object(i)) + assertEq(x, i-2.1); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_max_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_max_number')); +function rmax_number(i) { + var x = Math.max(i, i-1, i-2.1); + if (uceFault_max_number(i) || uceFault_max_number(i)) + assertEq(x, i); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_max_float = eval(`(${uceFault})`.replace('uceFault', 'uceFault_max_float')); +function rmax_float(i) { + var x = Math.fround(Math.max(Math.fround(-i), Math.fround(13.37))); + if (uceFault_max_number(i) || uceFault_max_number(i)) + assertEq(x, Math.fround(13.37)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_max_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_max_object')); +function rmax_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = Math.max(o, o-1, o-2.1) + t = 1000; + if (uceFault_max_object(i) || uceFault_max_object(i)) + assertEq(x, i); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_abs = eval(`(${uceFault})`.replace('uceFault', 'uceFault_abs')); +function rabs_number(i) { + var x = Math.abs(i-42); + if (uceFault_abs(i) || uceFault_abs(i)) + assertEq(x, 57); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_abs_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_abs_object')); +function rabs_object(i) { + var t = -i; + var o = { valueOf: function() { return t; } }; + var x = Math.abs(o); /* computed with t == i, not 1000 */ + t = 1000; + if(uceFault_abs_object(i) || uceFault_abs_object(i)) + assertEq(x, 99); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_sqrt_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sqrt_number')); +function rsqrt_number(i) { + var x = Math.sqrt(i); + if (uceFault_sqrt_number(i) || uceFault_sqrt_number(i)) + assertEq(x, Math.sqrt(99)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_sqrt_float = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sqrt_float')); +function rsqrt_float(i) { + var x = Math.fround(Math.sqrt(Math.fround(i))); + if (uceFault_sqrt_float(i) || uceFault_sqrt_float(i)) + assertEq(x, Math.fround(Math.sqrt(Math.fround(99)))); /* != 9.9498743710662 (when computed with double sqrt) */ + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_sqrt_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sqrt_object')); +function rsqrt_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = Math.sqrt(o); /* computed with t == i, not 1.5 */ + t = 1.5; + if (uceFault_sqrt_object(i) || uceFault_sqrt_object(i)) + assertEq(x, Math.sqrt(99)); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_atan2_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_atan2_number')); +function ratan2_number(i) { + var x = Math.atan2(i, i+1); + if (uceFault_atan2_number(i) || uceFault_atan2_number(i)) + assertEq(x, Math.atan2(99, 100)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_atan2_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_atan2_object')); +function ratan2_object(i) { + var t = i; + var o = { valueOf: function () { return t; } }; + var x = Math.atan2(o, o+1); + t = 1000; + if (uceFault_atan2_object(i) || uceFault_atan2_object(i)) + assertEq(x, Math.atan2(i, i+1)); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_str_split = eval(`(${uceFault})`.replace('uceFault', 'uceFault_str_split')) +function rstr_split(i) { + var x = "str01234567899876543210rts".split("" + i); + if (uceFault_str_split(i) || uceFault_str_split(i)) + assertEq(x[0], "str012345678"); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_regexp_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_exec')) +function rregexp_exec(i) { + var re = new RegExp("(str)\\d+" + i + "\\d+rts"); + var res = re.exec("str01234567899876543210rts"); + if (uceFault_regexp_exec(i) || uceFault_regexp_exec(i)) + assertEq(res[1], "str"); + assertRecoveredOnBailout(res, false); + return i; +} +var uceFault_regexp_y_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_y_exec')) +function rregexp_y_exec(i) { + var re = new RegExp("(str)\\d+" + (i % 10), "y"); + var res = re.exec("str00123456789"); + if (uceFault_regexp_y_exec(i) || uceFault_regexp_y_exec(i)) + assertEq(res[1], "str"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_regexp_y_literal_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_y_literal_exec')) +function rregexp_y_literal_exec(i) { + var re = /(str)\d*0/y; + var res = re.exec("str00123456789"); + if (uceFault_regexp_y_literal_exec(i) || uceFault_regexp_y_literal_exec(i)) + assertEq(res[1], "str"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_regexp_g_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_g_exec')) +function rregexp_g_exec(i) { + var re = new RegExp("(str)\\d+" + (i % 10), "g"); + var res = re.exec("str00123456789str00123456789"); + if (uceFault_regexp_g_exec(i) || uceFault_regexp_g_exec(i)) + assertEq(res[1], "str"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_regexp_g_literal_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_g_literal_exec')) +function rregexp_g_literal_exec(i) { + var re = /(str)\d*0/g; + var res = re.exec("str00123456789str00123456789"); + if (uceFault_regexp_g_literal_exec(i) || uceFault_regexp_g_literal_exec(i)) + assertEq(res[1], "str"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_regexp_i_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_i_exec')) +function rregexp_i_exec(i) { + var re = new RegExp("(str)\\d+" + (i % 10), "i"); + var res = re.exec("STR00123456789"); + if (uceFault_regexp_i_exec(i) || uceFault_regexp_i_exec(i)) + assertEq(res[1], "STR"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_regexp_i_literal_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_i_literal_exec')) +function rregexp_i_literal_exec(i) { + var re = /(str)\d*0/i; + var res = re.exec("STR00123456789"); + if (uceFault_regexp_i_literal_exec(i) || uceFault_regexp_i_literal_exec(i)) + assertEq(res[1], "STR"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + + +var uceFault_regexp_m_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_m_exec')) +function rregexp_m_exec(i) { + var re = new RegExp("^(str)\\d+" + (i % 10), "m"); + var res = re.exec("abc\nstr00123456789"); + if (uceFault_regexp_m_exec(i) || uceFault_regexp_m_exec(i)) + assertEq(res[1], "str"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_regexp_m_literal_exec = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_m_literal_exec')) +function rregexp_m_literal_exec(i) { + var re = /^(str)\d*0/m; + var res = re.exec("abc\nstr00123456789"); + if (uceFault_regexp_m_literal_exec(i) || uceFault_regexp_m_literal_exec(i)) + assertEq(res[1], "str"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_regexp_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_test')) +function rregexp_test(i) { + var re = new RegExp("str\\d+" + i + "\\d+rts"); + var res = re.test("str01234567899876543210rts"); + if (uceFault_regexp_test(i) || uceFault_regexp_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_y_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_y_test')) +function rregexp_y_test(i) { + var re = new RegExp("str\\d+" + (i % 10), "y"); + var res = re.test("str00123456789"); + if (uceFault_regexp_y_test(i) || uceFault_regexp_y_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_regexp_y_literal_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_y_literal_test')) +function rregexp_y_literal_test(i) { + var re = /str\d*0/y; + var res = re.test("str00123456789"); + if (uceFault_regexp_y_literal_test(i) || uceFault_regexp_y_literal_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_regexp_g_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_g_test')) +function rregexp_g_test(i) { + var re = new RegExp("str\\d+" + (i % 10), "g"); + var res = re.test("str00123456789str00123456789"); + if (uceFault_regexp_g_test(i) || uceFault_regexp_g_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_regexp_g_literal_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_g_literal_test')) +function rregexp_g_literal_test(i) { + var re = /str\d*0/g; + var res = re.test("str00123456789str00123456789"); + if (uceFault_regexp_g_literal_test(i) || uceFault_regexp_g_literal_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_regexp_i_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_i_test')) +function rregexp_i_test(i) { + var re = new RegExp("str\\d+" + (i % 10), "i"); + var res = re.test("STR00123456789"); + if (uceFault_regexp_i_test(i) || uceFault_regexp_i_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_regexp_i_literal_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_i_literal_test')) +function rregexp_i_literal_test(i) { + var re = /str\d*0/i; + var res = re.test("STR00123456789"); + if (uceFault_regexp_i_literal_test(i) || uceFault_regexp_i_literal_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_regexp_m_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_m_test')) +function rregexp_m_test(i) { + var re = new RegExp("^str\\d+" + (i % 10), "m"); + var res = re.test("abc\nstr00123456789"); + if (uceFault_regexp_m_test(i) || uceFault_regexp_m_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_regexp_m_literal_test = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_m_literal_test')) +function rregexp_m_literal_test(i) { + var re = /^str\d*0/m; + var res = re.test("abc\nstr00123456789"); + if (uceFault_regexp_m_literal_test(i) || uceFault_regexp_m_literal_test(i)) + assertEq(res, true); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_regexp_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_replace')) +function rregexp_replace(i) { + var re = new RegExp("str\\d+" + (i % 10)); + var res = "str00123456789".replace(re, "abc"); + if (uceFault_regexp_replace(i) || uceFault_regexp_replace(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_y_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_y_replace')) +function rregexp_y_replace(i) { + var re = new RegExp("str\\d+" + (i % 10), "y"); + re.test("str00123456789"); + assertEq(re.lastIndex == 0, false); + + var res = "str00123456789".replace(re, "abc"); + + assertEq(re.lastIndex, 0); + + assertEq(res, "str00123456789"); + + res = "str00123456789".replace(re, "abc"); + assertEq(re.lastIndex == 0, false); + + if (uceFault_regexp_y_replace(i) || uceFault_regexp_y_replace(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_y_literal_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_y_literal_replace')) +function rregexp_y_literal_replace(i) { + var re = /str\d+9/y; + re.test("str00123456789"); + assertEq(re.lastIndex == 0, false); + + var res = "str00123456789".replace(re, "abc"); + + assertEq(re.lastIndex, 0); + + assertEq(res, "str00123456789"); + + res = "str00123456789".replace(re, "abc"); + assertEq(re.lastIndex == 0, false); + + if (uceFault_regexp_y_literal_replace(i) || uceFault_regexp_y_literal_replace(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_g_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_g_replace')) +function rregexp_g_replace(i) { + var re = new RegExp("str\\d+" + (i % 10), "g"); + re.test("str00123456789"); + assertEq(re.lastIndex == 0, false); + + var res = "str00123456789".replace(re, "abc"); + + // replace will always zero the lastIndex field, even if it was not zero before. + assertEq(re.lastIndex == 0, true); + + if (uceFault_regexp_g_replace(i) || uceFault_regexp_g_replace(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_g_literal_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_g_literal_replace')) +function rregexp_g_literal_replace(i) { + var re = /str\d+9/g; + re.test("str00123456789"); + assertEq(re.lastIndex == 0, false); + + var res = "str00123456789".replace(re, "abc"); + + // replace will zero the lastIndex field. + assertEq(re.lastIndex == 0, true); + + if (uceFault_regexp_g_literal_replace(i) || uceFault_regexp_g_literal_replace(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_i_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_i_replace')) +function rregexp_i_replace(i) { + var re = new RegExp("str\\d+" + (i % 10), "i"); + re.test("STR00123456789"); + assertEq(re.lastIndex == 0, true); + + var res = "STR00123456789".replace(re, "abc"); + + assertEq(re.lastIndex == 0, true); + + if (uceFault_regexp_i_replace(i) || uceFault_regexp_i_replace(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_i_literal_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_i_literal_replace')) +function rregexp_i_literal_replace(i) { + var re = /str\d+9/i; + re.test("STR00123456789"); + assertEq(re.lastIndex == 0, true); + + var res = "str00123456789".replace(re, "abc"); + + assertEq(re.lastIndex == 0, true); + + if (uceFault_regexp_i_literal_replace(i) || uceFault_regexp_i_literal_replace(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_m_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_m_replace')) +function rregexp_m_replace(i) { + var re = new RegExp("^str\\d+" + (i % 10), "m"); + re.test("abc\nstr00123456789"); + assertEq(re.lastIndex == 0, true); + + var res = "abc\nstr00123456789".replace(re, "abc"); + + assertEq(re.lastIndex == 0, true); + + if (uceFault_regexp_m_replace(i) || uceFault_regexp_m_replace(i)) + assertEq(res, "abc\nabc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_regexp_m_literal_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_regexp_m_literal_replace')) +function rregexp_m_literal_replace(i) { + var re = /^str\d+9/m; + re.test("abc\nstr00123456789"); + assertEq(re.lastIndex == 0, true); + + var res = "abc\nstr00123456789".replace(re, "abc"); + + assertEq(re.lastIndex == 0, true); + + if (uceFault_regexp_m_literal_replace(i) || uceFault_regexp_m_literal_replace(i)) + assertEq(res, "abc\nabc"); + assertRecoveredOnBailout(res, false); + return i; +} + +var uceFault_string_replace = eval(`(${uceFault})`.replace('uceFault', 'uceFault_string_replace')) +function rstring_replace(i) { + var re = /str\d+9/; + + assertEq(re.lastIndex == 0, true); + var res = "str00123456789".replace(re, "abc"); + if (uceFault_string_replace(i) || uceFault_string_replace(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_string_replace_y = eval(`(${uceFault})`.replace('uceFault', 'uceFault_string_replace_y')) +function rstring_replace_y(i) { + var re = /str\d+9/y; + + assertEq(re.lastIndex == 0, true); + var res = "str00123456789".replace(re, "abc"); + if (uceFault_string_replace_y(i) || uceFault_string_replace_y(i)) + assertEq(res, "abc"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, false); + return i; +} + +var uceFault_string_replace_g = eval(`(${uceFault})`.replace('uceFault', 'uceFault_string_replace_g')) +function rstring_replace_g(i) { + var re = /str\d+9/g; + + assertEq(re.lastIndex == 0, true); + var res = "str00123456789str00123456789".replace(re, "abc"); + if (uceFault_string_replace_g(i) || uceFault_string_replace_g(i)) + assertEq(res, "abcabc"); + assertRecoveredOnBailout(res, false); + assertEq(re.lastIndex == 0, true); + return i; +} + +var uceFault_typeof = eval(`(${uceFault})`.replace('uceFault', 'uceFault_typeof')) +function rtypeof(i) { + var inputs = [ {}, [], 1, true, undefined, function(){}, null, Symbol() ]; + var types = [ "object", "object", "number", "boolean", "undefined", "function", "object", "symbol"]; + + var x = typeof (inputs[i % inputs.length]); + var y = types[i % types.length]; + + if (uceFault_typeof(i) || uceFault_typeof(i)) + assertEq(x, y); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_todouble_value = eval(`(${uceFault})`.replace('uceFault', 'uceFault_todouble_value')) +function rtodouble_value(i) { + var a = 1; + if (i == 1000) a = "1"; + + var x = a < 8.1; + + if (uceFault_todouble_value(i) || uceFault_todouble_value(i)) + assertEq(x, true); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_todouble_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_todouble_number')); +function rtodouble_number(i) { + var x = Math.fround(Math.fround(i) + Math.fround(i)) + 1; + if (uceFault_todouble_number(i) || uceFault_todouble_number(i)) + assertEq(2 * i + 1, x); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_tofloat32_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_tofloat32_number')); +function rtofloat32_number(i) { + var x = Math.fround(i + 0.1111111111); + if (uceFault_tofloat32_number(i) || uceFault_tofloat32_number(i)) + assertEq(x, Math.fround(99.1111111111)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_tofloat32_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_tofloat32_object')); +function rtofloat32_object(i) { + var t = i + 0.1111111111; + var o = { valueOf: function () { return t; } }; + var x = Math.fround(o); + t = 1000.1111111111; + if (uceFault_tofloat32_object(i) || uceFault_tofloat32_object(i)) + assertEq(x, Math.fround(99.1111111111)); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_trunc_to_int32_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_trunc_to_int32_number')); +function rtrunc_to_int32_number(i) { + var x = (i + 0.12) | 0; + if (uceFault_trunc_to_int32_number(i) || uceFault_trunc_to_int32_number(i)) + assertEq(x, (i + 0.12) | 0); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_trunc_to_int32_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_trunc_to_int32_object')); +function rtrunc_to_int32_object(i) { + var t1 = i + 0.12; + var o1 = { valueOf: function() { return t1; } }; + var x = o1 | 0; + t1 = 777.12; + if (uceFault_trunc_to_int32_object(i) || uceFault_trunc_to_int32_object(i)) + assertEq(x, (i + 0.12) | 0); + assertRecoveredOnBailout(x, false); +} + +var uceFault_trunc_to_int32_string = eval(`(${uceFault})`.replace('uceFault', 'uceFault_trunc_to_int32_string')); +function rtrunc_to_int32_string(i) { + var x = (i + "0") | 0; + if (uceFault_trunc_to_int32_string(i) || uceFault_trunc_to_int32_string(i)) + assertEq(x, (i + "0") | 0); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_hypot_number_2args = eval(`(${uceFault})`.replace('uceFault', 'uceFault_hypot_number_2args')); +function rhypot_number_2args(i) { + var x = Math.hypot(i, i + 1); + if (uceFault_hypot_number_2args(i) || uceFault_hypot_number_2args(i)) + assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1))); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_hypot_number_3args = eval(`(${uceFault})`.replace('uceFault', 'uceFault_hypot_number_3args')); +function rhypot_number_3args(i) { + var x = Math.hypot(i, i + 1, i + 2); + if (uceFault_hypot_number_3args(i) || uceFault_hypot_number_3args(i)) + assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1) + (i + 2) * (i + 2))); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_hypot_number_4args = eval(`(${uceFault})`.replace('uceFault', 'uceFault_hypot_number_4args')); +function rhypot_number_4args(i) { + var x = Math.hypot(i, i + 1, i + 2, i + 3); + if (uceFault_hypot_number_4args(i) || uceFault_hypot_number_4args(i)) + assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1) + (i + 2) * (i + 2) + (i + 3) * (i + 3))); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_hypot_object_2args = eval(`(${uceFault})`.replace('uceFault', 'uceFault_hypot_object_2args')); +function rhypot_object_2args(i) { + var t0 = i; + var t1 = i + 1; + var o0 = { valueOf: function () { return t0; } }; + var o1 = { valueOf: function () { return t1; } }; + var x = Math.hypot(o0, o1); + t0 = 1000; + t1 = 2000; + if (uceFault_hypot_object_2args(i) || uceFault_hypot_object_2args(i) ) + assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1))); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_hypot_object_3args = eval(`(${uceFault})`.replace('uceFault', 'uceFault_hypot_object_3args')); +function rhypot_object_3args(i) { + var t0 = i; + var t1 = i + 1; + var t2 = i + 2; + var o0 = { valueOf: function () { return t0; } }; + var o1 = { valueOf: function () { return t1; } }; + var o2 = { valueOf: function () { return t2; } }; + var x = Math.hypot(o0, o1, o2); + t0 = 1000; + t1 = 2000; + t2 = 3000; + if (uceFault_hypot_object_3args(i) || uceFault_hypot_object_3args(i) ) + assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1) + (i + 2) * (i + 2))); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_hypot_object_4args = eval(`(${uceFault})`.replace('uceFault', 'uceFault_hypot_object_4args')); +function rhypot_object_4args(i) { + var t0 = i; + var t1 = i + 1; + var t2 = i + 2; + var t3 = i + 3; + var o0 = { valueOf: function () { return t0; } }; + var o1 = { valueOf: function () { return t1; } }; + var o2 = { valueOf: function () { return t2; } }; + var o3 = { valueOf: function () { return t3; } }; + var x = Math.hypot(o0, o1, o2, o3); + t0 = 1000; + t1 = 2000; + t2 = 3000; + t3 = 4000; + if (uceFault_hypot_object_4args(i) || uceFault_hypot_object_4args(i) ) + assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1) + (i + 2) * (i + 2) + (i + 3) * (i + 3))); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_random = eval(`(${uceFault})`.replace('uceFault', 'uceFault_random')); +function rrandom(i) { + // setRNGState() exists only in debug builds + if(config.debug) setRNGState(2, 1+i); + + var x = Math.random(); + if (uceFault_random(i) || uceFault_random(i)) { + // TODO(Warp): Conditional operator ?: prevents recovering operands. + // assertEq(x, config.debug ? setRNGState(2, 1+i) || Math.random() : x); + if (config.debug) { + assertEq(x, setRNGState(2, 1+i) || Math.random()); + } else { + assertEq(x, x); + } + } + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_sin_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sin_number')); +function rsin_number(i) { + var x = Math.sin(i); + if (uceFault_sin_number(i) || uceFault_sin_number(i)) + assertEq(x, Math.sin(i)); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_sin_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sin_object')); +function rsin_object(i) { + var t = i; + var o = { valueOf: function() { return t; } }; + var x = Math.sin(o); + t = 777; + if (uceFault_sin_object(i) || uceFault_sin_object(i)) + assertEq(x, Math.sin(i)); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_log_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_log_number')); +function rlog_number(i) { + var x = Math.log(i); + if (uceFault_log_number(i) || uceFault_log_number(i)) + assertEq(x, Math.log(99) /* log(99) */); + assertRecoveredOnBailout(x, true); + return i; +} + +var uceFault_log_object = eval(`(${uceFault})`.replace('uceFault', 'uceFault_log_object')); +function rlog_object(i) { + var t = i; + var o = { valueOf: function() { return t; } }; + var x = Math.log(o); /* Evaluated with t == i, not t == 1000 */ + t = 1000; + if (uceFault_log_object(i) || uceFault_log_object(i)) + assertEq(x, Math.log(99) /* log(99) */); + assertRecoveredOnBailout(x, false); + return i; +} + +var uceFault_sign_number = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sign_number')); +function rsign_number(i) { + var x = Math.sign(-i - 0.12010799100); + if (uceFault_sign_number(i) || uceFault_sign_number(i)) + assertEq(x, Math.sign(-10)); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_sign_double = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sign_double')); +function rsign_double(i) { + const x = Math.sign(i + (-1 >>> 0)); + if (uceFault_sign_double(i) || uceFault_sign_double(i)) + assertEq(x, Math.sign(10)); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_add_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_add_bigint')); +function rbigintadd(i) { + var x = 1n + i; + if (uceFault_add_bigint(i) || uceFault_add_bigint(i)) + assertEq(x, 100n /* = 1 + 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_sub_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_sub_bigint')); +function rbigintsub(i) { + var x = 1n - i; + if (uceFault_sub_bigint(i) || uceFault_sub_bigint(i)) + assertEq(x, -98n /* = 1 - 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_mul_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_mul_bigint')); +function rbigintmul(i) { + var x = 2n * i; + if (uceFault_mul_bigint(i) || uceFault_mul_bigint(i)) + assertEq(x, 198n /* = 2 * 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_div_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_div_bigint')); +function rbigintdiv(i) { + var x = i / 3n; + if (uceFault_div_bigint(i) || uceFault_div_bigint(i)) + assertEq(x, 33n /* = 99 / 3 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_mod_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_mod_bigint')); +function rbigintmod(i) { + var x = i % 2n; + if (uceFault_mod_bigint(i) || uceFault_mod_bigint(i)) + assertEq(x, 1n /* = 99 % 2 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_pow_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_pow_bigint')); +function rbigintpow(i) { + var x = i ** 2n; + if (uceFault_pow_bigint(i) || uceFault_pow_bigint(i)) + assertEq(x, 9801n /* = 99 ** 2 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_inc_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_inc_bigint')); +function rbigintinc(i) { + var x = i; + x++; + if (uceFault_inc_bigint(i) || uceFault_inc_bigint(i)) + assertEq(x, 100n /* = 99 + 1 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_dec_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_dec_bigint')); +function rbigintdec(i) { + var x = i; + x--; + if (uceFault_dec_bigint(i) || uceFault_dec_bigint(i)) + assertEq(x, 98n /* = 99 - 1 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_neg_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_neg_bigint')); +function rbigintneg(i) { + var x = -i; + if (uceFault_neg_bigint(i) || uceFault_neg_bigint(i)) + assertEq(x, -99n); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_bitand_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitand_bigint')); +function rbigintbitand(i) { + var x = 1n & i; + if (uceFault_bitand_bigint(i) || uceFault_bitand_bigint(i)) + assertEq(x, 1n /* = 1 & 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_bitor_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitor_bigint')); +function rbigintbitor(i) { + var x = i | -100n; /* -100 == ~99 */ + if (uceFault_bitor_bigint(i) || uceFault_bitor_bigint(i)) + assertEq(x, -1n) /* ~99 | 99 = -1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_bitxor_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitxor_bigint')); +function rbigintbitxor(i) { + var x = 1n ^ i; + if (uceFault_bitxor_bigint(i) || uceFault_bitxor_bigint(i)) + assertEq(x, 98n /* = 1 XOR 99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_bitnot_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bitnot_bigint')); +function rbigintbitnot(i) { + var x = ~i; + if (uceFault_bitnot_bigint(i) || uceFault_bitnot_bigint(i)) + assertEq(x, -100n /* = ~99 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_lsh_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_lsh_bigint')); +function rbigintlsh(i) { + var x = i << 1n; + if (uceFault_lsh_bigint(i) || uceFault_lsh_bigint(i)) + assertEq(x, 198n); /* 99 << 1 == 198 */ + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_rsh_bigint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_rsh_bigint')); +function rbigintrsh(i) { + var x = i >> 1n; + if (uceFault_rsh_bigint(i) || uceFault_rsh_bigint(i)) + assertEq(x, 49n /* = 99 >> 1 */); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_bigintasint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bigintasint')); +function rbigintasint(i) { + var x = BigInt.asIntN(6, i); + if (uceFault_bigintasint(i) || uceFault_bigintasint(i)) + assertEq(x, -29n); + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_bigintasuint = eval(`(${uceFault})`.replace('uceFault', 'uceFault_bigintasuint')); +function rbigintasuint(i) { + var x = BigInt.asUintN(6, i); + if (uceFault_bigintasuint(i) || uceFault_bigintasuint(i)) + assertEq(x, 35n); + assertRecoveredOnBailout(x, true); + return i; +} + +for (j = 100 - max; j < 100; j++) { + with({}){} // Do not Ion-compile this loop. + let i = j < 2 ? (Math.abs(j) % 50) + 2 : j; + rbitnot_number(i); + rbitnot_object(i); + rbitand_number(i); + rbitand_object(i); + rbitor_number(i); + rbitor_object(i); + rbitxor_number(i); + rbitxor_object(i); + rlsh_number(i); + rlsh_object(i); + rrsh_number(i); + rrsh_object(i); + rursh_number(i); + rursh_object(i); + rsignextend8_1(i); + rsignextend8_2(i); + rsignextend16_1(i); + rsignextend16_2(i); + radd_number(i); + radd_float(i); + radd_object(i); + rsub_number(i); + rsub_float(i); + rsub_object(i); + rmul_number(i); + rmul_overflow(i); + rmul_float(i); + rmul_object(i); + rimul_number(i); + rimul_overflow(i); + rimul_object(i); + rdiv_number(i); + rdiv_float(i); + rdiv_object(i); + rmod_number(i); + rmod_object(i); + rnot_number(i); + rnot_object(i); + rconcat_string(i); + rconcat_number(i); + rstring_length(i); + rarguments_length_1(i); + rarguments_length_3(i, 0, 1); + rinline_arguments_length_1(i); + rinline_arguments_length_3(i, 0, 1); + rfloor_number(i); + rfloor_double(i); + rfloor_object(i); + rceil_number(i); + rceil_double(i); + rround_number(i); + rround_double(i); + rtrunc_number(i); + rtrunc_double(i); + rcharCodeAt(i); + rfrom_char_code(i); + rfrom_char_code_non_ascii(i); + rpow_number(i); + rpow_object(i); + rpowhalf_number(i); + rpowhalf_object(i); + rmin_number(i); + rmin_float(i); + rmin_object(i); + rmax_number(i); + rmax_float(i); + rmax_object(i); + rabs_number(i); + rabs_object(i); + rsqrt_number(i); + rsqrt_float(i); + rsqrt_object(i); + ratan2_number(i); + ratan2_object(i); + if (!warp) { + // TODO(Warp): Warp doesn't currently support a compiler constraints like + // system to elide checks for modified built-ins. Additionally this test + // requires to inline the self-hosted function and to elide all type + // checks before the StringSplitString intrinsic is called. + rstr_split(i); + } + rregexp_exec(i); + rregexp_y_exec(i); + rregexp_y_literal_exec(i); + rregexp_g_exec(i); + rregexp_g_literal_exec(i); + rregexp_i_exec(i); + rregexp_i_literal_exec(i); + rregexp_m_exec(i); + rregexp_m_literal_exec(i); + rregexp_test(i); + rregexp_y_test(i); + rregexp_y_literal_test(i); + rregexp_g_test(i); + rregexp_g_literal_test(i); + rregexp_i_test(i); + rregexp_i_literal_test(i); + rregexp_m_test(i); + rregexp_m_literal_test(i); + rregexp_replace(i); + rregexp_y_replace(i); + rregexp_y_literal_replace(i); + rregexp_g_replace(i); + rregexp_g_literal_replace(i); + rregexp_i_replace(i); + rregexp_i_literal_replace(i); + rregexp_m_replace(i); + rregexp_m_literal_replace(i); + rstring_replace(i); + rstring_replace_y(i); + rstring_replace_g(i); + rtypeof(i); + rtodouble_value(i); + rtodouble_number(i); + rtofloat32_number(i); + rtofloat32_object(i); + rtrunc_to_int32_number(i); + rtrunc_to_int32_object(i); + if (!warp) { + // TODO(Warp): Bitwise operations on strings not optimised in Warp. + rtrunc_to_int32_string(i); + } + rhypot_number_2args(i); + rhypot_number_3args(i); + rhypot_number_4args(i); + rhypot_object_2args(i); + rhypot_object_3args(i); + rhypot_object_4args(i); + rrandom(i); + rsin_number(i); + rsin_object(i); + rlog_number(i); + rlog_object(i); + rsign_number(i); + rsign_double(i); + rbigintadd(BigInt(i)); + rbigintsub(BigInt(i)); + rbigintmul(BigInt(i)); + rbigintdiv(BigInt(i)); + rbigintmod(BigInt(i)); + rbigintpow(BigInt(i)); + rbigintinc(BigInt(i)); + rbigintdec(BigInt(i)); + rbigintneg(BigInt(i)); + rbigintbitand(BigInt(i)); + rbigintbitor(BigInt(i)); + rbigintbitxor(BigInt(i)); + rbigintbitnot(BigInt(i)); + rbigintlsh(BigInt(i)); + rbigintrsh(BigInt(i)); + rbigintasint(BigInt(i)); + rbigintasuint(BigInt(i)); +} + +// Test that we can refer multiple time to the same recover instruction, as well +// as chaining recover instructions. + +function alignedAlloc($size, $alignment) { + var $1 = $size + 4 | 0; + var $2 = $alignment - 1 | 0; + var $3 = $1 + $2 | 0; + var $4 = malloc($3); +} + +function malloc($bytes) { + var $189 = undefined; + var $198 = $189 + 8 | 0; +} + +for (i = 0; i < 50; i++) + alignedAlloc(608, 16); diff --git a/js/src/jit-test/tests/ion/dense-elem-write-barrier.js b/js/src/jit-test/tests/ion/dense-elem-write-barrier.js new file mode 100644 index 0000000000..79fda227da --- /dev/null +++ b/js/src/jit-test/tests/ion/dense-elem-write-barrier.js @@ -0,0 +1,22 @@ +var arr = []; +for (var i=0; i<20; i++) { + arr.push(new Int32Array(2000)); +} +arr.push([null, null]); + +function test(o, x) { + assertEq(o[0], x); +} + +function f() { + for (var i=0; i<3100; i++) { + var o = arr[i % arr.length]; + if (o.length > 10 || i > 2000) { + var val = (i > 3000 ? 1 : null); + o[0] = val; + if (o.length < 5) + test(o, val); + } + } +} +f(); diff --git a/js/src/jit-test/tests/ion/directEval.js b/js/src/jit-test/tests/ion/directEval.js new file mode 100644 index 0000000000..e9ba89d129 --- /dev/null +++ b/js/src/jit-test/tests/ion/directEval.js @@ -0,0 +1,10 @@ + +// test scope iteration when throwing from within an eval. +function testEvalThrow(x, y) { + x = 5; + for (var i in [1,2,3]) + eval("x += 5; if (i == 2) throw 0"); + assertEq(x, 10); +} +for (var i = 0; i < 5; i++) + try { testEvalThrow.call({}, 3); } catch (e) { assertEq(e, 0); } diff --git a/js/src/jit-test/tests/ion/div-by-constant-bug1555153.js b/js/src/jit-test/tests/ion/div-by-constant-bug1555153.js new file mode 100644 index 0000000000..b217f2cf4b --- /dev/null +++ b/js/src/jit-test/tests/ion/div-by-constant-bug1555153.js @@ -0,0 +1,5 @@ +x = [99999999999999999999999999, -(2 ** 53 - 2)]; +res = [0, 2 / 3]; +for (let i = 0; i < 2; ++i) { + assertEq((x[i] | 0) / 3, res[i]); +} diff --git a/js/src/jit-test/tests/ion/divmodself.js b/js/src/jit-test/tests/ion/divmodself.js new file mode 100644 index 0000000000..524d46d022 --- /dev/null +++ b/js/src/jit-test/tests/ion/divmodself.js @@ -0,0 +1,664 @@ +// |jit-test| --ion-eager + +// bug 944963 +function bug944963(x, y) { + (+(xy))(y % y) +} +for (var i = 0; i < 10; i++) { + try { + (function() { + bug944963(0, (~Math.fround(-8))) + })() + } catch (e) {} +} + +// bug 900437 +function bug900437() { + var x = 0.0; + for (var i = 0; i < 10; i++) + -("") >> (x / x); +} +bug900437(); +bug900437(); + +// bug 715460 +function f(x) { + var a = x; + return a / 10; +} +function g(x) { + var y = x + 1; + return y / y; +} +for (var i=0; i<10; i++) + assertEq(f(i * 10), i); +for (var i=0; i<10; i++) + assertEq(g(i), 1); + +// bug 939893 +function bug939893() { + bug_g(); +} +function bug_g() { + bug_h(undefined >>> 0, +undefined); +} +function bug_h(x) { + Math.max(x ? ((x / x) | 0) : 0); +} +for (var a = 0; a < 2; ++a) { + bug939893(); +} + +// bug 945860 +function bug945860(x) { + return (x % x); +} +for (var i = 0; i < 2; i++) { + try { + (function() { + assertEq(bug945860(1), 0); + })() + } catch (e) {} +} + +// Assorted tests. + +function sdiv_truncate(y) { + return (y / y)|0; +} +assertEq(sdiv_truncate(5), 1); +assertEq(sdiv_truncate(1), 1); +assertEq(sdiv_truncate(-1), 1); +assertEq(sdiv_truncate(0), 0); +assertEq(sdiv_truncate(-0), 0); +assertEq(sdiv_truncate(1.1), 1); +assertEq(sdiv_truncate(-1.1), 1); +assertEq(sdiv_truncate(Infinity), 0); +assertEq(sdiv_truncate(NaN), 0); +assertEq(sdiv_truncate(undefined), 0); +assertEq(sdiv_truncate(null), 0); + +function sdiv(y) { + return y / y; +} +assertEq(sdiv(5), 1); +assertEq(sdiv(1), 1); +assertEq(sdiv(-1), 1); +assertEq(sdiv(0), NaN); +assertEq(sdiv(-0), NaN); +assertEq(sdiv(1.1), 1); +assertEq(sdiv(-1.1), 1); +assertEq(sdiv(Infinity), NaN); +assertEq(sdiv(NaN), NaN); +assertEq(sdiv(undefined), NaN); +assertEq(sdiv(null), NaN); + +function udiv_truncate(y) { + var yu = y>>>0; + return (yu / yu)|0; +} +assertEq(udiv_truncate(5), 1); +assertEq(udiv_truncate(1), 1); +assertEq(udiv_truncate(-1), 1); +assertEq(udiv_truncate(0), 0); +assertEq(udiv_truncate(-0), 0); +assertEq(udiv_truncate(1.1), 1); +assertEq(udiv_truncate(-1.1), 1); +assertEq(udiv_truncate(Infinity), 0); +assertEq(udiv_truncate(NaN), 0); +assertEq(udiv_truncate(undefined), 0); +assertEq(udiv_truncate(null), 0); + +function shifted_udiv_truncate(y) { + var yu = y>>>1; + return (yu / yu)|0; +} +assertEq(shifted_udiv_truncate(5), 1); +assertEq(shifted_udiv_truncate(2), 1); +assertEq(shifted_udiv_truncate(1), 0); +assertEq(shifted_udiv_truncate(-1), 1); +assertEq(shifted_udiv_truncate(0), 0); +assertEq(shifted_udiv_truncate(-0), 0); +assertEq(shifted_udiv_truncate(1.1), 0); +assertEq(shifted_udiv_truncate(-1.1), 1); +assertEq(shifted_udiv_truncate(Infinity), 0); +assertEq(shifted_udiv_truncate(NaN), 0); +assertEq(shifted_udiv_truncate(undefined), 0); +assertEq(shifted_udiv_truncate(null), 0); + +function udiv(y) { + var yu = y>>>0; + return yu / yu; +} +assertEq(udiv(5), 1); +assertEq(udiv(1), 1); +assertEq(udiv(-1), 1); +assertEq(udiv(0), NaN); +assertEq(udiv(-0), NaN); +assertEq(udiv(1.1), 1); +assertEq(udiv(-1.1), 1); +assertEq(udiv(Infinity), NaN); +assertEq(udiv(NaN), NaN); +assertEq(udiv(undefined), NaN); +assertEq(udiv(null), NaN); + +function shifted_udiv(y) { + var yu = y>>>1; + return yu / yu; +} +assertEq(shifted_udiv(5), 1); +assertEq(shifted_udiv(2), 1); +assertEq(shifted_udiv(1), NaN); +assertEq(shifted_udiv(-1), 1); +assertEq(shifted_udiv(0), NaN); +assertEq(shifted_udiv(-0), NaN); +assertEq(shifted_udiv(1.1), NaN); +assertEq(shifted_udiv(-1.1), 1); +assertEq(shifted_udiv(Infinity), NaN); +assertEq(shifted_udiv(NaN), NaN); +assertEq(shifted_udiv(undefined), NaN); +assertEq(shifted_udiv(null), NaN); + +function smod_truncate(y) { + return (y % y)|0; +} +assertEq(smod_truncate(5), 0); +assertEq(smod_truncate(1), 0); +assertEq(smod_truncate(-1), 0); +assertEq(smod_truncate(0), 0); +assertEq(smod_truncate(-0), 0); +assertEq(smod_truncate(1.1), 0); +assertEq(smod_truncate(-1.1), 0); +assertEq(smod_truncate(Infinity), 0); +assertEq(smod_truncate(NaN), 0); +assertEq(smod_truncate(undefined), 0); +assertEq(smod_truncate(null), 0); + +function smod(y) { + return y % y; +} +assertEq(smod(5), 0); +assertEq(smod(1), 0); +assertEq(smod(-1), -0); +assertEq(smod(0), NaN); +assertEq(smod(-0), NaN); +assertEq(smod(1.1), 0); +assertEq(smod(-1.1), -0); +assertEq(smod(Infinity), NaN); +assertEq(smod(NaN), NaN); +assertEq(smod(undefined), NaN); +assertEq(smod(null), NaN); + +function umod_truncate(y) { + var yu = y>>>0; + return (yu % yu)|0; +} +assertEq(umod_truncate(5), 0); +assertEq(umod_truncate(1), 0); +assertEq(umod_truncate(-1), 0); +assertEq(umod_truncate(0), 0); +assertEq(umod_truncate(-0), 0); +assertEq(umod_truncate(1.1), 0); +assertEq(umod_truncate(-1.1), 0); +assertEq(umod_truncate(Infinity), 0); +assertEq(umod_truncate(NaN), 0); +assertEq(umod_truncate(undefined), 0); +assertEq(umod_truncate(null), 0); + +function shifted_umod_truncate(y) { + var yu = y>>>1; + return (yu % yu)|0; +} +assertEq(shifted_umod_truncate(5), 0); +assertEq(shifted_umod_truncate(2), 0); +assertEq(shifted_umod_truncate(1), 0); +assertEq(shifted_umod_truncate(-1), 0); +assertEq(shifted_umod_truncate(0), 0); +assertEq(shifted_umod_truncate(-0), 0); +assertEq(shifted_umod_truncate(1.1), 0); +assertEq(shifted_umod_truncate(-1.1), 0); +assertEq(shifted_umod_truncate(Infinity), 0); +assertEq(shifted_umod_truncate(NaN), 0); +assertEq(shifted_umod_truncate(undefined), 0); +assertEq(shifted_umod_truncate(null), 0); + +function umod(y) { + var yu = y>>>0; + return yu % yu; +} +assertEq(umod(5), 0); +assertEq(umod(1), 0); +assertEq(umod(-1), 0); +assertEq(umod(0), NaN); +assertEq(umod(-0), NaN); +assertEq(umod(1.1), 0); +assertEq(umod(-1.1), 0); +assertEq(umod(Infinity), NaN); +assertEq(umod(NaN), NaN); +assertEq(umod(undefined), NaN); +assertEq(umod(null), NaN); + +function shifted_umod(y) { + var yu = y>>>1; + return yu % yu; +} +assertEq(shifted_umod(5), 0); +assertEq(shifted_umod(2), 0); +assertEq(shifted_umod(1), NaN); +assertEq(shifted_umod(-1), 0); +assertEq(shifted_umod(0), NaN); +assertEq(shifted_umod(-0), NaN); +assertEq(shifted_umod(1.1), NaN); +assertEq(shifted_umod(-1.1), 0); +assertEq(shifted_umod(Infinity), NaN); +assertEq(shifted_umod(NaN), NaN); +assertEq(shifted_umod(undefined), NaN); +assertEq(shifted_umod(null), NaN); + +function sdiv_truncate_nonzero(y) { + if (y == 0) return -202; + return (y / y)|0; +} +assertEq(sdiv_truncate_nonzero(5), 1); +assertEq(sdiv_truncate_nonzero(1), 1); +assertEq(sdiv_truncate_nonzero(-1), 1); +assertEq(sdiv_truncate_nonzero(0), -202); +assertEq(sdiv_truncate_nonzero(-0), -202); +assertEq(sdiv_truncate_nonzero(1.1), 1); +assertEq(sdiv_truncate_nonzero(-1.1), 1); +assertEq(sdiv_truncate_nonzero(Infinity), 0); +assertEq(sdiv_truncate_nonzero(NaN), 0); +assertEq(sdiv_truncate_nonzero(undefined), 0); +assertEq(sdiv_truncate_nonzero(null), 0); + +function sdiv_nonzero(y) { + if (y == 0) return -202; + return y / y; +} +assertEq(sdiv_nonzero(5), 1); +assertEq(sdiv_nonzero(1), 1); +assertEq(sdiv_nonzero(-1), 1); +assertEq(sdiv_nonzero(0), -202); +assertEq(sdiv_nonzero(-0), -202); +assertEq(sdiv_nonzero(1.1), 1); +assertEq(sdiv_nonzero(-1.1), 1); +assertEq(sdiv_nonzero(Infinity), NaN); +assertEq(sdiv_nonzero(NaN), NaN); +assertEq(sdiv_nonzero(undefined), NaN); +assertEq(sdiv_nonzero(null), NaN); + +function udiv_truncate_nonzero(y) { + var yu = y>>>0; + if (yu == 0) return -202; + return (yu / yu)|0; +} +assertEq(udiv_truncate_nonzero(5), 1); +assertEq(udiv_truncate_nonzero(1), 1); +assertEq(udiv_truncate_nonzero(-1), 1); +assertEq(udiv_truncate_nonzero(0), -202); +assertEq(udiv_truncate_nonzero(-0), -202); +assertEq(udiv_truncate_nonzero(1.1), 1); +assertEq(udiv_truncate_nonzero(-1.1), 1); +assertEq(udiv_truncate_nonzero(Infinity), -202); +assertEq(udiv_truncate_nonzero(NaN), -202); +assertEq(udiv_truncate_nonzero(undefined), -202); +assertEq(udiv_truncate_nonzero(null), -202); + +function shifted_udiv_truncate_nonzero(y) { + var yu = y>>>1; + if (yu == 0) return -202; + return (yu / yu)|0; +} +assertEq(shifted_udiv_truncate_nonzero(5), 1); +assertEq(shifted_udiv_truncate_nonzero(2), 1); +assertEq(shifted_udiv_truncate_nonzero(1), -202); +assertEq(shifted_udiv_truncate_nonzero(-1), 1); +assertEq(shifted_udiv_truncate_nonzero(0), -202); +assertEq(shifted_udiv_truncate_nonzero(-0), -202); +assertEq(shifted_udiv_truncate_nonzero(1.1), -202); +assertEq(shifted_udiv_truncate_nonzero(-1.1), 1); +assertEq(shifted_udiv_truncate_nonzero(Infinity), -202); +assertEq(shifted_udiv_truncate_nonzero(NaN), -202); +assertEq(shifted_udiv_truncate_nonzero(undefined), -202); +assertEq(shifted_udiv_truncate_nonzero(null), -202); + +function udiv_nonzero(y) { + var yu = y>>>0; + if (yu == 0) return -202; + return yu / yu; +} +assertEq(udiv_nonzero(5), 1); +assertEq(udiv_nonzero(1), 1); +assertEq(udiv_nonzero(-1), 1); +assertEq(udiv_nonzero(0), -202); +assertEq(udiv_nonzero(-0), -202); +assertEq(udiv_nonzero(1.1), 1); +assertEq(udiv_nonzero(-1.1), 1); +assertEq(udiv_nonzero(Infinity), -202); +assertEq(udiv_nonzero(NaN), -202); +assertEq(udiv_nonzero(undefined), -202); +assertEq(udiv_nonzero(null), -202); + +function shifted_udiv_nonzero(y) { + var yu = y>>>1; + if (yu == 0) return -202; + return yu / yu; +} +assertEq(shifted_udiv_nonzero(5), 1); +assertEq(shifted_udiv_nonzero(2), 1); +assertEq(shifted_udiv_nonzero(1), -202); +assertEq(shifted_udiv_nonzero(-1), 1); +assertEq(shifted_udiv_nonzero(0), -202); +assertEq(shifted_udiv_nonzero(-0), -202); +assertEq(shifted_udiv_nonzero(1.1), -202); +assertEq(shifted_udiv_nonzero(-1.1), 1); +assertEq(shifted_udiv_nonzero(Infinity), -202); +assertEq(shifted_udiv_nonzero(NaN), -202); +assertEq(shifted_udiv_nonzero(undefined), -202); +assertEq(shifted_udiv_nonzero(null), -202); + +function smod_truncate_nonzero(y) { + if (y == 0) return -202; + return (y % y)|0; +} +assertEq(smod_truncate_nonzero(5), 0); +assertEq(smod_truncate_nonzero(1), 0); +assertEq(smod_truncate_nonzero(-1), 0); +assertEq(smod_truncate_nonzero(0), -202); +assertEq(smod_truncate_nonzero(-0), -202); +assertEq(smod_truncate_nonzero(1.1), 0); +assertEq(smod_truncate_nonzero(-1.1), 0); +assertEq(smod_truncate_nonzero(Infinity), 0); +assertEq(smod_truncate_nonzero(NaN), 0); +assertEq(smod_truncate_nonzero(undefined), 0); +assertEq(smod_truncate_nonzero(null), 0); + +function smod_nonzero(y) { + if (y == 0) return -202; + return y % y; +} +assertEq(smod_nonzero(5), 0); +assertEq(smod_nonzero(1), 0); +assertEq(smod_nonzero(-1), -0); +assertEq(smod_nonzero(0), -202); +assertEq(smod_nonzero(-0), -202); +assertEq(smod_nonzero(1.1), 0); +assertEq(smod_nonzero(-1.1), -0); +assertEq(smod_nonzero(Infinity), NaN); +assertEq(smod_nonzero(NaN), NaN); +assertEq(smod_nonzero(undefined), NaN); +assertEq(smod_nonzero(null), NaN); + +function umod_truncate_nonzero(y) { + var yu = y>>>0; + if (yu == 0) return -202; + return (yu % yu)|0; +} +assertEq(umod_truncate_nonzero(5), 0); +assertEq(umod_truncate_nonzero(1), 0); +assertEq(umod_truncate_nonzero(-1), 0); +assertEq(umod_truncate_nonzero(0), -202); +assertEq(umod_truncate_nonzero(-0), -202); +assertEq(umod_truncate_nonzero(1.1), 0); +assertEq(umod_truncate_nonzero(-1.1), 0); +assertEq(umod_truncate_nonzero(Infinity), -202); +assertEq(umod_truncate_nonzero(NaN), -202); +assertEq(umod_truncate_nonzero(undefined), -202); +assertEq(umod_truncate_nonzero(null), -202); + +function shifted_umod_truncate_nonzero(y) { + var yu = y>>>1; + if (yu == 0) return -202; + return (yu % yu)|0; +} +assertEq(shifted_umod_truncate_nonzero(5), 0); +assertEq(shifted_umod_truncate_nonzero(2), 0); +assertEq(shifted_umod_truncate_nonzero(1), -202); +assertEq(shifted_umod_truncate_nonzero(-1), 0); +assertEq(shifted_umod_truncate_nonzero(0), -202); +assertEq(shifted_umod_truncate_nonzero(-0), -202); +assertEq(shifted_umod_truncate_nonzero(1.1), -202); +assertEq(shifted_umod_truncate_nonzero(-1.1), 0); +assertEq(shifted_umod_truncate_nonzero(Infinity), -202); +assertEq(shifted_umod_truncate_nonzero(NaN), -202); +assertEq(shifted_umod_truncate_nonzero(undefined), -202); +assertEq(shifted_umod_truncate_nonzero(null), -202); + +function umod_nonzero(y) { + var yu = y>>>0; + if (yu == 0) return -202; + return yu % yu; +} +assertEq(umod_nonzero(5), 0); +assertEq(umod_nonzero(1), 0); +assertEq(umod_nonzero(-1), 0); +assertEq(umod_nonzero(0), -202); +assertEq(umod_nonzero(-0), -202); +assertEq(umod_nonzero(1.1), 0); +assertEq(umod_nonzero(-1.1), 0); +assertEq(umod_nonzero(Infinity), -202); +assertEq(umod_nonzero(NaN), -202); +assertEq(umod_nonzero(undefined), -202); +assertEq(umod_nonzero(null), -202); + +function shifted_umod_nonzero(y) { + var yu = y>>>1; + if (yu == 0) return -202; + return yu % yu; +} +assertEq(shifted_umod_nonzero(5), 0); +assertEq(shifted_umod_nonzero(2), 0); +assertEq(shifted_umod_nonzero(1), -202); +assertEq(shifted_umod_nonzero(-1), 0); +assertEq(shifted_umod_nonzero(0), -202); +assertEq(shifted_umod_nonzero(-0), -202); +assertEq(shifted_umod_nonzero(1.1), -202); +assertEq(shifted_umod_nonzero(-1.1), 0); +assertEq(shifted_umod_nonzero(Infinity), -202); +assertEq(shifted_umod_nonzero(NaN), -202); +assertEq(shifted_umod_nonzero(undefined), -202); +assertEq(shifted_umod_nonzero(null), -202); + +function sdiv_truncate_positive(y) { + if (y <= 0) return -202; + return (y / y)|0; +} +assertEq(sdiv_truncate_positive(5), 1); +assertEq(sdiv_truncate_positive(1), 1); +assertEq(sdiv_truncate_positive(-1), -202); +assertEq(sdiv_truncate_positive(0), -202); +assertEq(sdiv_truncate_positive(-0), -202); +assertEq(sdiv_truncate_positive(1.1), 1); +assertEq(sdiv_truncate_positive(-1.1), -202); +assertEq(sdiv_truncate_positive(Infinity), 0); +assertEq(sdiv_truncate_positive(NaN), 0); +assertEq(sdiv_truncate_positive(undefined), 0); +assertEq(sdiv_truncate_positive(null), -202); + +function sdiv_positive(y) { + if (y <= 0) return -202; + return y / y; +} +assertEq(sdiv_positive(5), 1); +assertEq(sdiv_positive(1), 1); +assertEq(sdiv_positive(-1), -202); +assertEq(sdiv_positive(0), -202); +assertEq(sdiv_positive(-0), -202); +assertEq(sdiv_positive(1.1), 1); +assertEq(sdiv_positive(-1.1), -202); +assertEq(sdiv_positive(Infinity), NaN); +assertEq(sdiv_positive(NaN), NaN); +assertEq(sdiv_positive(undefined), NaN); +assertEq(sdiv_positive(null), -202); + +function udiv_truncate_positive(y) { + var yu = y>>>0; + if (yu <= 0) return -202; + return (yu / yu)|0; +} +assertEq(udiv_truncate_positive(5), 1); +assertEq(udiv_truncate_positive(1), 1); +assertEq(udiv_truncate_positive(-1), 1); +assertEq(udiv_truncate_positive(0), -202); +assertEq(udiv_truncate_positive(-0), -202); +assertEq(udiv_truncate_positive(1.1), 1); +assertEq(udiv_truncate_positive(-1.1), 1); +assertEq(udiv_truncate_positive(Infinity), -202); +assertEq(udiv_truncate_positive(NaN), -202); +assertEq(udiv_truncate_positive(undefined), -202); +assertEq(udiv_truncate_positive(null), -202); + +function shifted_udiv_truncate_positive(y) { + var yu = y>>>1; + if (yu <= 0) return -202; + return (yu / yu)|0; +} +assertEq(shifted_udiv_truncate_positive(5), 1); +assertEq(shifted_udiv_truncate_positive(2), 1); +assertEq(shifted_udiv_truncate_positive(1), -202); +assertEq(shifted_udiv_truncate_positive(-1), 1); +assertEq(shifted_udiv_truncate_positive(0), -202); +assertEq(shifted_udiv_truncate_positive(-0), -202); +assertEq(shifted_udiv_truncate_positive(1.1), -202); +assertEq(shifted_udiv_truncate_positive(-1.1), 1); +assertEq(shifted_udiv_truncate_positive(Infinity), -202); +assertEq(shifted_udiv_truncate_positive(NaN), -202); +assertEq(shifted_udiv_truncate_positive(undefined), -202); +assertEq(shifted_udiv_truncate_positive(null), -202); + +function udiv_positive(y) { + var yu = y>>>0; + if (yu <= 0) return -202; + return yu / yu; +} +assertEq(udiv_positive(5), 1); +assertEq(udiv_positive(1), 1); +assertEq(udiv_positive(-1), 1); +assertEq(udiv_positive(0), -202); +assertEq(udiv_positive(-0), -202); +assertEq(udiv_positive(1.1), 1); +assertEq(udiv_positive(-1.1), 1); +assertEq(udiv_positive(Infinity), -202); +assertEq(udiv_positive(NaN), -202); +assertEq(udiv_positive(undefined), -202); +assertEq(udiv_positive(null), -202); + +function shifted_udiv_positive(y) { + var yu = y>>>1; + if (yu <= 0) return -202; + return yu / yu; +} +assertEq(shifted_udiv_positive(5), 1); +assertEq(shifted_udiv_positive(2), 1); +assertEq(shifted_udiv_positive(1), -202); +assertEq(shifted_udiv_positive(-1), 1); +assertEq(shifted_udiv_positive(0), -202); +assertEq(shifted_udiv_positive(-0), -202); +assertEq(shifted_udiv_positive(1.1), -202); +assertEq(shifted_udiv_positive(-1.1), 1); +assertEq(shifted_udiv_positive(Infinity), -202); +assertEq(shifted_udiv_positive(NaN), -202); +assertEq(shifted_udiv_positive(undefined), -202); +assertEq(shifted_udiv_positive(null), -202); + +function smod_truncate_positive(y) { + if (y <= 0) return -202; + return (y % y)|0; +} +assertEq(smod_truncate_positive(5), 0); +assertEq(smod_truncate_positive(1), 0); +assertEq(smod_truncate_positive(-1), -202); +assertEq(smod_truncate_positive(0), -202); +assertEq(smod_truncate_positive(-0), -202); +assertEq(smod_truncate_positive(1.1), 0); +assertEq(smod_truncate_positive(-1.1), -202); +assertEq(smod_truncate_positive(Infinity), 0); +assertEq(smod_truncate_positive(NaN), 0); +assertEq(smod_truncate_positive(undefined), 0); +assertEq(smod_truncate_positive(null), -202); + +function smod_positive(y) { + if (y <= 0) return -202; + return y % y; +} +assertEq(smod_positive(5), 0); +assertEq(smod_positive(1), 0); +assertEq(smod_positive(-1), -202); +assertEq(smod_positive(0), -202); +assertEq(smod_positive(-0), -202); +assertEq(smod_positive(1.1), 0); +assertEq(smod_positive(-1.1), -202); +assertEq(smod_positive(Infinity), NaN); +assertEq(smod_positive(NaN), NaN); +assertEq(smod_positive(undefined), NaN); +assertEq(smod_positive(null), -202); + +function umod_truncate_positive(y) { + var yu = y>>>0; + if (yu <= 0) return -202; + return (yu % yu)|0; +} +assertEq(umod_truncate_positive(5), 0); +assertEq(umod_truncate_positive(1), 0); +assertEq(umod_truncate_positive(-1), 0); +assertEq(umod_truncate_positive(0), -202); +assertEq(umod_truncate_positive(-0), -202); +assertEq(umod_truncate_positive(1.1), 0); +assertEq(umod_truncate_positive(-1.1), 0); +assertEq(umod_truncate_positive(Infinity), -202); +assertEq(umod_truncate_positive(NaN), -202); +assertEq(umod_truncate_positive(undefined), -202); +assertEq(umod_truncate_positive(null), -202); + +function shifted_umod_truncate_positive(y) { + var yu = y>>>1; + if (yu <= 0) return -202; + return (yu % yu)|0; +} +assertEq(shifted_umod_truncate_positive(5), 0); +assertEq(shifted_umod_truncate_positive(2), 0); +assertEq(shifted_umod_truncate_positive(1), -202); +assertEq(shifted_umod_truncate_positive(-1), 0); +assertEq(shifted_umod_truncate_positive(0), -202); +assertEq(shifted_umod_truncate_positive(-0), -202); +assertEq(shifted_umod_truncate_positive(1.1), -202); +assertEq(shifted_umod_truncate_positive(-1.1), 0); +assertEq(shifted_umod_truncate_positive(Infinity), -202); +assertEq(shifted_umod_truncate_positive(NaN), -202); +assertEq(shifted_umod_truncate_positive(undefined), -202); +assertEq(shifted_umod_truncate_positive(null), -202); + +function umod_positive(y) { + var yu = y>>>0; + if (yu <= 0) return -202; + return yu % yu; +} +assertEq(umod_positive(5), 0); +assertEq(umod_positive(1), 0); +assertEq(umod_positive(-1), 0); +assertEq(umod_positive(0), -202); +assertEq(umod_positive(-0), -202); +assertEq(umod_positive(1.1), 0); +assertEq(umod_positive(-1.1), 0); +assertEq(umod_positive(Infinity), -202); +assertEq(umod_positive(NaN), -202); +assertEq(umod_positive(undefined), -202); +assertEq(umod_positive(null), -202); + +function shifted_umod_positive(y) { + var yu = y>>>1; + if (yu <= 0) return -202; + return yu % yu; +} +assertEq(shifted_umod_positive(5), 0); +assertEq(shifted_umod_positive(2), 0); +assertEq(shifted_umod_positive(1), -202); +assertEq(shifted_umod_positive(-1), 0); +assertEq(shifted_umod_positive(0), -202); +assertEq(shifted_umod_positive(-0), -202); +assertEq(shifted_umod_positive(1.1), -202); +assertEq(shifted_umod_positive(-1.1), 0); +assertEq(shifted_umod_positive(Infinity), -202); +assertEq(shifted_umod_positive(NaN), -202); +assertEq(shifted_umod_positive(undefined), -202); +assertEq(shifted_umod_positive(null), -202); diff --git a/js/src/jit-test/tests/ion/double-array-loop-phi.js b/js/src/jit-test/tests/ion/double-array-loop-phi.js new file mode 100644 index 0000000000..b12a9b5f37 --- /dev/null +++ b/js/src/jit-test/tests/ion/double-array-loop-phi.js @@ -0,0 +1,11 @@ +function f() { + for (var i = 0; i < 600; i++) { + var arr = [1.1, ([...[]], 2.2), i]; + for (var j = 0; j < 2; j++) { + var idx = j === 1 ? 2 : 0; + var exp = j === 1 ? i + 1 : 2.1; + assertEq(arr[idx] + 1, exp); + } + } +} +f(); diff --git a/js/src/jit-test/tests/ion/doubleArrays.js b/js/src/jit-test/tests/ion/doubleArrays.js new file mode 100644 index 0000000000..4622c3f29e --- /dev/null +++ b/js/src/jit-test/tests/ion/doubleArrays.js @@ -0,0 +1,51 @@ + +function testPushConvert() { + var x = []; + for (var i = 0; i < 10; i++) + x.push(i + .5); + for (var i = 0; i < 5; i++) + x.push(i); + var res = 0; + for (var i = 0; i < x.length; i++) + res += x[i]; + assertEq(res, 60); +} +testPushConvert(); + +function testArrayInitializer() { + var x = [.5,1.5,2.5,3]; + var res = 0; + for (var i = 0; i < x.length; i++) + res += x[i]; + assertEq(res, 7.5); +} +for (var i = 0; i < 5; i++) + testArrayInitializer(); + +function testArrayConstructor() { + var x = Array(.5,1.5,2.5,3); + var res = 0; + for (var i = 0; i < x.length; i++) + res += x[i]; + assertEq(res, 7.5); +} +for (var i = 0; i < 5; i++) + testArrayConstructor(); + +function addInt(a) { + // inhibit ion + try { + a[0] = 10; + } catch (e) {} +} + +function testBaseline() { + var x = Array(.5,1.5,2.5,3); + addInt(x); + var res = 0; + for (var i = 0; i < x.length; i++) + res += x[i]; + assertEq(res, 17); +} +for (var i = 0; i < 5; i++) + testBaseline(); diff --git a/js/src/jit-test/tests/ion/doubleComparisons.js b/js/src/jit-test/tests/ion/doubleComparisons.js new file mode 100644 index 0000000000..e9f78382a6 --- /dev/null +++ b/js/src/jit-test/tests/ion/doubleComparisons.js @@ -0,0 +1,88 @@ + +function gen_f(x) { + var f = "{\n" + + " var x = " + x + ";\n" + + " if (x)\n" + + " return true;\n" + + " return false;\n" + + "}"; + return new Function(f); +} + +function run_f(x) { + return gen_f(x)(); +} + +function gen_k(x, op, y) { + var f = "{\n" + + " var x = " + x + ";\n" + + " var y = " + y + ";\n" + + " if (x " + op + " y)\n" + + " return true;\n" + + " return false;\n" + + "}"; + return new Function(f); +} + +function run_k(x, op, y) { + return gen_k(x, op, y)(); +} + +function gen_r(x, op, y) { + var f = "{\n" + + " var x = " + x + ";\n" + + " var y = " + y + ";\n" + + " return x " + op + " y;\n" + + "}"; + return new Function(f); +} + +function run_r(x, op, y) { + return gen_r(x, op, y)(); +} + +assertEq(run_f("1 / 0"), true); +assertEq(run_f("0 / 0"), false); +assertEq(run_f("-0"), false); +assertEq(run_f(1.3), true); + +// Ordered results. +assertEq(run_k(1.3, ">", 2.3), false); +assertEq(run_k(2.3, ">", 2.3), false); +assertEq(run_k(2.4, ">", 2.3), true); +assertEq(run_k(1.3, ">=", 2.3), false); +assertEq(run_k(2.3, ">=", 2.3), true); +assertEq(run_k(2.4, ">=", 2.3), true); +assertEq(run_k(1.3, "<", 2.3), true); +assertEq(run_k(2.3, "<", 2.3), false); +assertEq(run_k(2.4, "<", 2.3), false); +assertEq(run_k(1.3, "<", 2.3), true); +assertEq(run_k(2.3, "<=", 2.3), true); +assertEq(run_k(2.4, "<", 2.3), false); + +// Unordered results. +assertEq(run_k("NaN", "<", 2.5), false); +assertEq(run_k("NaN", "<=", 2.5), false); +assertEq(run_k("NaN", ">", 2.5), false); +assertEq(run_k("NaN", ">=", 2.5), false); + +// Ordered results. +assertEq(run_r(1.3, ">", 2.3), false); +assertEq(run_r(2.3, ">", 2.3), false); +assertEq(run_r(2.4, ">", 2.3), true); +assertEq(run_r(1.3, ">=", 2.3), false); +assertEq(run_r(2.3, ">=", 2.3), true); +assertEq(run_r(2.4, ">=", 2.3), true); +assertEq(run_r(1.3, "<", 2.3), true); +assertEq(run_r(2.3, "<", 2.3), false); +assertEq(run_r(2.4, "<", 2.3), false); +assertEq(run_r(1.3, "<", 2.3), true); +assertEq(run_r(2.3, "<=", 2.3), true); +assertEq(run_r(2.4, "<", 2.3), false); + +// Unordered results. +assertEq(run_r("NaN", "<", 2.5), false); +assertEq(run_r("NaN", "<=", 2.5), false); +assertEq(run_r("NaN", ">", 2.5), false); +assertEq(run_r("NaN", ">=", 2.5), false); + diff --git a/js/src/jit-test/tests/ion/eliminate-type-barrier.js b/js/src/jit-test/tests/ion/eliminate-type-barrier.js new file mode 100644 index 0000000000..75cc9a200a --- /dev/null +++ b/js/src/jit-test/tests/ion/eliminate-type-barrier.js @@ -0,0 +1,41 @@ +function foo(a) { + var y = 0; + for (var i = 0; i < 10; i++) { + var x = a[i]; + z = x.f; + if (x.h != null) + y = x.f.g; + } + return y; +} + +function foo2(a) { + var y = 0; + for (var i = 0; i < 10; i++) { + var x = a[i]; + if (x.f !== undefined) { + if (x.h != null) + y = x.f.g; + } + } + return y; +} + +a = []; +for (var i = 0; i < 10; i++) + a[i] = {f:null, h:null}; +for (var i = 0; i < 10; i++) { + a[i].f = {g:0}; + a[i].h = {}; +} +var q = a[0].h; +a[0].f = null; +a[0].h = null; + +foo(a); +foo2(a); + +a[0].h = q; + +try { foo(a); } catch (e) {} +try { foo2(a); } catch (e) {} diff --git a/js/src/jit-test/tests/ion/eliminate-unreachable-1.js b/js/src/jit-test/tests/ion/eliminate-unreachable-1.js new file mode 100644 index 0000000000..2cece911ac --- /dev/null +++ b/js/src/jit-test/tests/ion/eliminate-unreachable-1.js @@ -0,0 +1,32 @@ +// Test for one annoying case of the EliminateUnreachableCode +// optimization. Here the dominators change and also phis are +// eliminated. + +function test1(v) { + var i = 0; + if (v) { + if (v) { + i += 1; + } else { + i += 10; + } + i += 100; + } else { + if (v) { + i += 1000; + } else { + i += 10000; + } + i += 100000; + } + i += 1000000; + return i; +} + +function test() { + assertEq(test1(true), 1000101); + assertEq(test1(false), 1110000); +} + +for (var i = 0; i < 100; i++) + test(); diff --git a/js/src/jit-test/tests/ion/eliminate-unreachable-2.js b/js/src/jit-test/tests/ion/eliminate-unreachable-2.js new file mode 100644 index 0000000000..3671e6399b --- /dev/null +++ b/js/src/jit-test/tests/ion/eliminate-unreachable-2.js @@ -0,0 +1,28 @@ +// Test for one annoying case of the EliminateUnreachableCode +// optimization. Here the dominator of print("Goodbye") changes to be +// the print("Hello") after optimization. + +function test1(v) { + if (v) { + if (v) { + assertEq(v, v); + } else { + assertEq(0, 1); + } + } else { + if (v) { + assertEq(0, 1); + } else { + assertEq(v, v); + } + } + assertEq(v, v); +} + +function test() { + test1(true); + test1(false); +} + +for (var i = 0; i < 100; i++) + test(); diff --git a/js/src/jit-test/tests/ion/entryOverflowBailout.js b/js/src/jit-test/tests/ion/entryOverflowBailout.js new file mode 100644 index 0000000000..bae6301810 --- /dev/null +++ b/js/src/jit-test/tests/ion/entryOverflowBailout.js @@ -0,0 +1,220 @@ +var o; +var f1; +var counter = 0; + +function f2(a) { + bailout(); + return f2.arguments; +}; + +var restartCode = "counter = 0; " + f2.toString(); + +// We need to reevaluate this function everytime, otherwise it is flagged as +// having an argument object and it would not be re-entered. + +// This test case is checking that f.arguments reflects the overflow or the +// underflow of arguments after a bailout. Due to the way bailouts are +// recovered we need to check for the intial frame and for any other JS frame +// below. +// +// To produce a JSFrame, we need to avoid the 'Hot' counters of f1 to be the +// same as f2, because IonMonkey will try to inline f2 in f1, and not +// compiling/calling f2 separately. This explain why we ignore the 5 first call +// of f1 by returning immediately. +// +// Bailouts are caused by calling an object function, which is expected to be a +// function by IonMonkey. So bailout() cause a bailout in the currently +// compiled function. +// +// To avoid any preventive effect to re-enter f2, we re-evaluate it before every +// test. + +// Check bailouts of the initial frame. + +eval(restartCode); +while (counter++ < 50) { + o = f2(); + assertEq(o.length, 0); +} + +eval(restartCode); +while (counter++ < 50) { + o = f2(21); + assertEq(o.length, 1); + assertEq(o[0], 21); +} + +eval(restartCode); +while (counter++ < 50) { + o = f2(21,42); + assertEq(o.length, 2); + assertEq(o[0], 21); + assertEq(o[1], 42); +} + +// 100 arguments. +eval(restartCode); +while (counter++ < 50) { + o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); + assertEq(o.length, 100); + for (var i in o) + assertEq(o[i], i % 10); +} + +// 200 arguments. +eval(restartCode); +while (counter++ < 50) { + o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); + assertEq(o.length, 200); + for (var i in o) + assertEq(o[i], i % 10); +} + +// 300 arguments. +eval(restartCode); +while (counter++ < 50) { + o = f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); + assertEq(o.length, 300); + for (var i in o) + assertEq(o[i], i % 10); +} + +// Check bailouts of one frame which is not the initial frame. + +eval(restartCode); +f1 = function() { + if (counter < 5) return 0; + return f2(); +}; +while (counter++ < 50) { + o = f1(); + if (counter < 5) continue; + assertEq(o.length, 0); +} + +eval(restartCode); +f1 = function() { + if (counter < 5) return 0; + return f2(21); +}; +while (counter++ < 50) { + o = f1(); + if (counter < 5) continue; + assertEq(o.length, 1); + assertEq(o[0], 21); +} + +eval(restartCode); +f1 = function() { + if (counter < 5) return 0; + return f2(21,42); +}; +while (counter++ < 50) { + o = f1(); + if (counter < 5) continue; + assertEq(o.length, 2); + assertEq(o[0], 21); + assertEq(o[1], 42); +} + +// 100 arguments. +eval(restartCode); +f1 = function() { + if (counter < 5) return 0; + return f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); +}; +while (counter++ < 50) { + o = f1(); + if (counter < 5) continue; + assertEq(o.length, 100); + for (var i in o) + assertEq(o[i], i % 10); +} + +// 200 arguments. +eval(restartCode); +f1 = function() { + if (counter < 5) return 0; + return f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); +}; +while (counter++ < 50) { + o = f1(); + if (counter < 5) continue; + assertEq(o.length, 200); + for (var i in o) + assertEq(o[i], i % 10); +} + +// 300 arguments. +eval(restartCode); +f1 = function() { + if (counter < 5) return 0; + return f2(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9); +}; +while (counter++ < 500) { + o = f1(); + if (counter < 5) continue; + assertEq(o.length, 300); + for (var i in o) + assertEq(o[i], i % 10); +} diff --git a/js/src/jit-test/tests/ion/eval-neg0.js b/js/src/jit-test/tests/ion/eval-neg0.js new file mode 100644 index 0000000000..14782614c2 --- /dev/null +++ b/js/src/jit-test/tests/ion/eval-neg0.js @@ -0,0 +1,6 @@ +function f() { + for (var i = 0; i < 100; i++) + assertEq(eval(-0), -0); +} + +f(); diff --git a/js/src/jit-test/tests/ion/evalCallingName.js b/js/src/jit-test/tests/ion/evalCallingName.js new file mode 100644 index 0000000000..c2ca3ccef7 --- /dev/null +++ b/js/src/jit-test/tests/ion/evalCallingName.js @@ -0,0 +1,43 @@ + +function a() { + return "a"; +} +function b() { + return "b"; +} +function c() { + return "c"; +} +var names = ["a","b","c"]; + +function foo(name) { + return eval(name + "()"); +} + +for (var i = 0; i < names.length; i++) + assertEq(foo(names[i]), names[i]); + +// Test bailout due to bad name passed to eval. +try { + foo("missing"); +} catch (e) { + assertEq(/missing/.test(e), true); +} + +function bar(name) { + return eval(name + "()"); +} + +for (var i = 0; i < names.length; i++) + assertEq(bar(names[i]), names[i]); + +function recursion() { + return bar({ valueOf: function() { return "gotcha"; }}); +} + +function gotcha() { + return "gotcha"; +} + +// Test invalidation within call made after name lookup. +assertEq(bar("recursion"), "gotcha"); diff --git a/js/src/jit-test/tests/ion/expando-realloc-slots.js b/js/src/jit-test/tests/ion/expando-realloc-slots.js new file mode 100644 index 0000000000..90438b5045 --- /dev/null +++ b/js/src/jit-test/tests/ion/expando-realloc-slots.js @@ -0,0 +1,28 @@ +function O() { + this.x0 = 1; + this.x1 = 1; + this.x2 = 1; + this.x3 = 1; + this.x4 = 1; + this.x5 = 1; +} +function f() { + var arr = []; + for (var i=0; i<1500; i++) + arr.push(new O); + for (var i=0; i<1500; i++) { + var o = arr[i]; + o.x10 = 1; + o.x11 = 1; + o.x12 = 1; + o.x13 = 1; + o.x14 = 1; + o.x15 = 1; + o.x16 = 1; + o.x17 = 1; + o.x18 = 1; + o.x19 = 1; + o.x20 = 1; + } +} +f(); diff --git a/js/src/jit-test/tests/ion/filtertypeset-float32.js b/js/src/jit-test/tests/ion/filtertypeset-float32.js new file mode 100644 index 0000000000..891c77aa40 --- /dev/null +++ b/js/src/jit-test/tests/ion/filtertypeset-float32.js @@ -0,0 +1,6 @@ +function f(x) { + return Math.fround((x ? 0 : x) | Math.max(x, x)); +} +for (var j = 0; j < 2; ++j) { + assertEq(f((function(){}) - 4294967297 ? 1 : 1 | 0 && 4294967297), 1); +} diff --git a/js/src/jit-test/tests/ion/fold-in.js b/js/src/jit-test/tests/ion/fold-in.js new file mode 100644 index 0000000000..4e0c54cd5d --- /dev/null +++ b/js/src/jit-test/tests/ion/fold-in.js @@ -0,0 +1,44 @@ +// Singleton +function f() { + var res = 0; + for (var i=0; i<500; i++) + res += ("abcd" in Math); + return res; +} +assertEq(f(), 0); +Math.abcd = 3; +assertEq(f(), 500); +delete Math.abcd; +assertEq(f(), 0); + +// Non-singleton +function O(x) { if (x) this.x = 1; } + +var arr = []; +for (var i=0; i<4; i++) + arr.push(new O(i % 2)); + +function g(arr) { + var res = 0; + for (var i=0; i<500; i++) { + var o = arr[i % arr.length]; + res += "x" in o; + res += "abcd" in o; + } + return res; +} +assertEq(g(arr), 250); +arr[0].abcd = 3; +assertEq(g(arr), 375); + +function testPrimitive() { + var x = 7; + var c = 0; + for (var i=0; i<5; i++) { + try { + "z" in x; + } catch(e) { c++; } + } + assertEq(c, 5); +} +testPrimitive(); diff --git a/js/src/jit-test/tests/ion/fold-linear-arith-bug1316830.js b/js/src/jit-test/tests/ion/fold-linear-arith-bug1316830.js new file mode 100644 index 0000000000..28ef5400ed --- /dev/null +++ b/js/src/jit-test/tests/ion/fold-linear-arith-bug1316830.js @@ -0,0 +1,9 @@ +function f(x) { + return (x | 0) - (-4294967295 | 0) + -2147483647 +} +x = [1, 4294967295] +for (var j = 0; j < 2; ++j) { + for (var k = 0; k < 3; ++k) { + assertEq(f(x[j]), -2147483647 - 2 * j); + } +} diff --git a/js/src/jit-test/tests/ion/fold-linear-arith-bug1319242.js b/js/src/jit-test/tests/ion/fold-linear-arith-bug1319242.js new file mode 100644 index 0000000000..8100180362 --- /dev/null +++ b/js/src/jit-test/tests/ion/fold-linear-arith-bug1319242.js @@ -0,0 +1,7 @@ +function f(x) { + // Check that we do not fold +1 and -2 across truncated/non-truncated operations. + return (((x | 0) + 1) | 0) + -2; +} +const int32_min = -Math.pow(2,31); +f(Infinity); +assertEq(f(int32_min - 1), int32_min - 2); diff --git a/js/src/jit-test/tests/ion/fold-linear-arith-bug1528829.js b/js/src/jit-test/tests/ion/fold-linear-arith-bug1528829.js new file mode 100644 index 0000000000..e4529c1bfb --- /dev/null +++ b/js/src/jit-test/tests/ion/fold-linear-arith-bug1528829.js @@ -0,0 +1,18 @@ +// |jit-test| --ion-warmup-threshold=0; --ion-check-range-analysis + +function f(o) { + // Int32 math does an overflow check. + o += 1; + // Int32 math does an underflow check. + o += -2147483647; + // If previous math operations are folded, we should keep the smallest + // overflow check and the highest underflow check to stay within the + // expected range deduced by Range Analysis. + for (let i = 0; i < 1; ++i) { + o -= 1; + } +} +f(0); +f(0); +f(2147483647); + diff --git a/js/src/jit-test/tests/ion/for-in-iterator-1.js b/js/src/jit-test/tests/ion/for-in-iterator-1.js new file mode 100644 index 0000000000..0257634459 --- /dev/null +++ b/js/src/jit-test/tests/ion/for-in-iterator-1.js @@ -0,0 +1,29 @@ +gczeal(0); + +var values = { + input1: null, + input2: undefined, + input3: {}, + input4: [], + input5: "" +}; + +var original = function (x) { + var res = { start: inIon(), end: false }; + for (var i in x.input) { + throw "Iterator is not empty"; + } + res.end = inIon(); + return res; +}; + +for (var i = 1; i < 6; i++) { + // Reset type inference. + var res = false; + var test = eval(`(${original})`.replace(".input", ".input" + i)); + + // Run until the end is running within Ion, or skip if we are unable to run + // in Ion. + while (!res.start || !res.end) + res = test(values); +} diff --git a/js/src/jit-test/tests/ion/gc-during-bailout.js b/js/src/jit-test/tests/ion/gc-during-bailout.js new file mode 100644 index 0000000000..b5cb91882a --- /dev/null +++ b/js/src/jit-test/tests/ion/gc-during-bailout.js @@ -0,0 +1,158 @@ +setJitCompilerOption("ion.warmup.trigger", 30); +gcPreserveCode(); +var o = {}; + +function f(i) { + var obj_1 = { a: 0 }; + var obj_2 = { a: 0 }; + var obj_3 = { a: 0 }; + var obj_4 = { a: 0 }; + var obj_5 = { a: 0 }; + var obj_6 = { a: 0 }; + var obj_7 = { a: 0 }; + var obj_8 = { a: 0 }; + var obj_9 = { a: 0 }; + var obj_10 = { a: 0 }; + var obj_11 = { a: 0 }; + var obj_12 = { a: 0 }; + var obj_13 = { a: 0 }; + var obj_14 = { a: 0 }; + var obj_15 = { a: 0 }; + var obj_16 = { a: 0 }; + var obj_17 = { a: 0 }; + var obj_18 = { a: 0 }; + var obj_19 = { a: 0 }; + var obj_20 = { a: 0 }; + var obj_21 = { a: 0 }; + var obj_22 = { a: 0 }; + var obj_23 = { a: 0 }; + var obj_24 = { a: 0 }; + var obj_25 = { a: 0 }; + var obj_26 = { a: 0 }; + var obj_27 = { a: 0 }; + var obj_28 = { a: 0 }; + var obj_29 = { a: 0 }; + var obj_30 = { a: 0 }; + + // Doing a bailout after the return of the function call implies that we + // cannot resume before the function call. Thus, we would have to recover + // the 30 objects allocations during the bailout. + schedulegc(i % 100); + bailout(); + + obj_1.a = 1; + obj_2.a = 1; + obj_3.a = 1; + obj_4.a = 1; + obj_5.a = 1; + obj_6.a = 1; + obj_7.a = 1; + obj_8.a = 1; + obj_9.a = 1; + obj_10.a = 1; + obj_11.a = 1; + obj_12.a = 1; + obj_13.a = 1; + obj_14.a = 1; + obj_15.a = 1; + obj_16.a = 1; + obj_17.a = 1; + obj_18.a = 1; + obj_19.a = 1; + obj_20.a = 1; + obj_21.a = 1; + obj_22.a = 1; + obj_23.a = 1; + obj_24.a = 1; + obj_25.a = 1; + obj_26.a = 1; + obj_27.a = 1; + obj_28.a = 1; + obj_29.a = 1; + obj_30.a = 1; +} + +for (var i = 0; i < 200; i++) { + // Do not inline 'f', to keep re-entering 'f' at every loop iteration. + with (o) { } + f(i); +} + +// This is the same test except that we do not preserve code under shrinking GC. +gczeal(14); + +function g(i) { + var obj_1 = { a: 0 }; + var obj_2 = { a: 0 }; + var obj_3 = { a: 0 }; + var obj_4 = { a: 0 }; + var obj_5 = { a: 0 }; + var obj_6 = { a: 0 }; + var obj_7 = { a: 0 }; + var obj_8 = { a: 0 }; + var obj_9 = { a: 0 }; + var obj_10 = { a: 0 }; + var obj_11 = { a: 0 }; + var obj_12 = { a: 0 }; + var obj_13 = { a: 0 }; + var obj_14 = { a: 0 }; + var obj_15 = { a: 0 }; + var obj_16 = { a: 0 }; + var obj_17 = { a: 0 }; + var obj_18 = { a: 0 }; + var obj_19 = { a: 0 }; + var obj_20 = { a: 0 }; + var obj_21 = { a: 0 }; + var obj_22 = { a: 0 }; + var obj_23 = { a: 0 }; + var obj_24 = { a: 0 }; + var obj_25 = { a: 0 }; + var obj_26 = { a: 0 }; + var obj_27 = { a: 0 }; + var obj_28 = { a: 0 }; + var obj_29 = { a: 0 }; + var obj_30 = { a: 0 }; + + // Doing a bailout after the return of the function call implies that we + // cannot resume before the function call. Thus, we would have to recover + // the 30 objects allocations during the bailout. + schedulegc(i % 100); + bailout(); + + obj_1.a = 1; + obj_2.a = 1; + obj_3.a = 1; + obj_4.a = 1; + obj_5.a = 1; + obj_6.a = 1; + obj_7.a = 1; + obj_8.a = 1; + obj_9.a = 1; + obj_10.a = 1; + obj_11.a = 1; + obj_12.a = 1; + obj_13.a = 1; + obj_14.a = 1; + obj_15.a = 1; + obj_16.a = 1; + obj_17.a = 1; + obj_18.a = 1; + obj_19.a = 1; + obj_20.a = 1; + obj_21.a = 1; + obj_22.a = 1; + obj_23.a = 1; + obj_24.a = 1; + obj_25.a = 1; + obj_26.a = 1; + obj_27.a = 1; + obj_28.a = 1; + obj_29.a = 1; + obj_30.a = 1; +} + +for (var i = 0; i < 200; i++) { + // Do not inline 'g', to keep re-entering 'g' at every loop iteration. + with (o) { } + g(i); +} diff --git a/js/src/jit-test/tests/ion/getPropertyCacheOverflow.js b/js/src/jit-test/tests/ion/getPropertyCacheOverflow.js new file mode 100644 index 0000000000..41a7fadedc --- /dev/null +++ b/js/src/jit-test/tests/ion/getPropertyCacheOverflow.js @@ -0,0 +1,37 @@ +// This test was made to be effective with --no-jm. + +var list = [ + { entry00: 0, length: 1 }, + { entry01: 0, length: 1 }, + { entry02: 0, length: 1 }, + { entry03: 0, length: 1 }, + { entry04: 0, length: 1 }, + { entry05: 0, length: 1 }, + { entry06: 0, length: 1 }, + { entry07: 0, length: 1 }, + { entry08: 0, length: 1 }, + { entry09: 0, length: 1 }, + { entry10: 0, length: 1 }, + { entry11: 0, length: 1 }, + { entry12: 0, length: 1 }, + { entry13: 0, length: 1 }, + { entry14: 0, length: 1 }, + { entry15: 0, length: 1 }, + { entry16: 0, length: 1 }, // cause an overflow. + { entry17: 0, length: 1 }, + [0], + (new Uint8Array(new ArrayBuffer(1))) +]; + +function f(obj) { + return obj.length; +} + +// Cook the f function on the top of the list to make sure we do not register +// our test cases. +for (var i = 0; i < 100; i++) + f(list[i % 10]); + +// Register & check stubs. +for (var i = 0; i < 40; i++) + assertEq(f(list[i % 20]), 1); diff --git a/js/src/jit-test/tests/ion/getelem-bounds-coalesce.js b/js/src/jit-test/tests/ion/getelem-bounds-coalesce.js new file mode 100644 index 0000000000..c5dda1784d --- /dev/null +++ b/js/src/jit-test/tests/ion/getelem-bounds-coalesce.js @@ -0,0 +1,49 @@ +var a = [1,2,3,4]; + +// Basic constants. +function foo(x) { + return x[0] + x[1] + x[2] + x[3]; +} +for (var i = 0; i < 100; i++) + assertEq(foo(a), 10); +assertEq(foo([1,2,3]), NaN); + +// Basic terms. +function foo2(x, n) { + return x[n] + x[n + 1] + x[n + 2]; +} +for (var i = 0; i < 100; i++) + assertEq(foo2(a, 1), 9); +assertEq(foo2(a, 2), NaN); + +// Term underflow. +function foo3(x, n) { + return x[n] + x[n + 1] + x[n + 2]; +} +for (var i = 0; i < 100; i++) + assertEq(foo3(a, 1), 9); +assertEq(foo3(a, -1), NaN); + +// Integer overflow computing bound. +function foo4(x, n) { + return x[n] + x[n + 1] + x[n + 2]; +} +for (var i = 0; i < 45; i++) + assertEq(foo4(a, 1), 9); +assertEq(foo4(a, 0x7fffffff), NaN); + +// Underflow at an offset. +function foo5(x, n) { + return x[n + 10] + x[n + 11] + x[n + 12]; +} +for (var i = 0; i < 45; i++) + assertEq(foo5(a, -9), 9); +assertEq(foo5(a, -11), NaN); + +// Overflow at offset. +function foo6(x, n) { + return x[n - 10] + x[n - 11] + x[n - 12]; +} +for (var i = 0; i < 45; i++) + assertEq(foo6(a, 13), 9); +assertEq(foo6(a, 14), NaN); diff --git a/js/src/jit-test/tests/ion/getelem-bounds-hoist.js b/js/src/jit-test/tests/ion/getelem-bounds-hoist.js new file mode 100644 index 0000000000..694da72d6a --- /dev/null +++ b/js/src/jit-test/tests/ion/getelem-bounds-hoist.js @@ -0,0 +1,83 @@ +var a = [1,2,3,4,5]; + +// Basic overflow in hoisted condition. +function foo(x, n) { + var v = 0; + for (var i = 0; i < n; i++) + v += x[i]; + return v; +} +for (var i = 0; i < 15; i++) + assertEq(foo(a, 5), 15); +assertEq(foo(a, 6), NaN); + +// Basic underflow in hoisted condition. +function foo2(x, m, n) { + var v = 0; + for (var i = m; i < n; i++) + v += x[i]; + return v; +} +for (var i = 0; i < 15; i++) + assertEq(foo2(a, 0, 5), 15); +assertEq(foo2(a, -1, 5), NaN); + +// Overflow when hoisting consolidated condition. +function foo3(x, m, n) { + var v = 0; + for (var i = m; i < n; i++) + v += x[i] + x[i + 1] + x[i + 2]; + return v; +} +for (var i = 0; i < 15; i++) + assertEq(foo3(a, 0, 3), 27); +assertEq(foo3(a, 0, 4), NaN); + +// Underflow when hoisting consolidated condition. +function foo4(x, m, n) { + var v = 0; + for (var i = m; i < n; i++) + v += x[i] + x[i - 1] + x[i - 2]; + return v; +} +for (var i = 0; i < 15; i++) + assertEq(foo4(a, 2, 5), 27); +assertEq(foo4(a, 0, 5), NaN); + +// Underflow due to decreasing index. +function foo5(x, n) { + var v = 0; + for (var i = 0; i < n; i++) { + v += x[i]; + if (n == 4) + i -= 2; + if (i == -5) + break; + } + return v; +} +for (var i = 0; i < 15; i++) + assertEq(foo5(a, 5), 15); +assertEq(foo5(a, 4), NaN); + +// Overflow after access at constant offset. +function foo6(x, m, n) { + var v = 0; + for (var i = m; i < n; i++) + v += x[i + 10]; + return v; +} +for (var i = 0; i < 15; i++) + assertEq(foo6(a, -10, -5), 15); +assertEq(foo6(a, -10, -4), NaN); + +// Underflow after access at constant offset. +function foo7(x, m, n) { + var v = 0; + for (var i = m; i < n; i++) + v += x[i + 10]; + return v; +} +for (var i = 0; i < 15; i++) + assertEq(foo7(a, -10, -5), 15); +assertEq(foo7(a, -11, -5), NaN); diff --git a/js/src/jit-test/tests/ion/getelem-hole.js b/js/src/jit-test/tests/ion/getelem-hole.js new file mode 100644 index 0000000000..de3517ecbb --- /dev/null +++ b/js/src/jit-test/tests/ion/getelem-hole.js @@ -0,0 +1,15 @@ +var a = [1, 2, 3]; +var b = [4, 5, 6]; + +function testFold() { + for (var i=0; i<10; i++) { + var x = a[i]; + var y = a[i]; + var z = b[i]; + assertEq(x, y); + if (i < 3) + assertEq(x !== z, true); + } +} +for (var i=0; i<10; i++) + testFold(); diff --git a/js/src/jit-test/tests/ion/getelem-proto.js b/js/src/jit-test/tests/ion/getelem-proto.js new file mode 100644 index 0000000000..5e9be37d12 --- /dev/null +++ b/js/src/jit-test/tests/ion/getelem-proto.js @@ -0,0 +1,18 @@ +var a = [1, , 2]; +Array.prototype[1] = 3; + +function f(arr) { + return arr[0] + arr[1] + arr[2]; +} +for (var i=0; i<70; i++) { + assertEq(f(a), 6); +} + +Object.defineProperty(Array.prototype, "1", { + get: function() { + return 1234; + } +}); + +assertEq(f(a), 1237); +assertEq(f(a), 1237); diff --git a/js/src/jit-test/tests/ion/getelem-string.js b/js/src/jit-test/tests/ion/getelem-string.js new file mode 100644 index 0000000000..b187e5b68b --- /dev/null +++ b/js/src/jit-test/tests/ion/getelem-string.js @@ -0,0 +1,11 @@ +function test1() { + function getchar(s, i) { + return s[i]; + } + for (var i=0; i<70; i++) { + assertEq(getchar("foo", 0), "f"); + assertEq(getchar("bar", 2), "r"); + } + assertEq(getchar("foo", 3), undefined); +} +test1(); diff --git a/js/src/jit-test/tests/ion/getelem.js b/js/src/jit-test/tests/ion/getelem.js new file mode 100644 index 0000000000..3fd11586a5 --- /dev/null +++ b/js/src/jit-test/tests/ion/getelem.js @@ -0,0 +1,77 @@ +function testValue() { + function f(arr, x) { + return arr[x]; + } + var a = [1, undefined, null, Math, 2.1, ""]; + for (var i=0; i<50; i++) { + assertEq(f(a, 0), 1); + assertEq(f(a, 1), undefined); + assertEq(f(a, 2), null); + assertEq(f(a, 3), Math); + assertEq(f(a, 4), 2.1); + assertEq(f(a, 5), ""); + assertEq(f(a, -1), undefined); + assertEq(f(a, 6), undefined); + } +} +testValue(); + +function testOutOfBounds() { + function f(arr, x) { + return arr[x]; + } + var a = [0, 1, 2, 3, 4]; + + for (var j=0; j<4; j++) { + for (var i=0; i<5; i++) { + assertEq(f(a, i), i); + } + for (var i=5; i<10; i++) { + assertEq(f(a, i), undefined); + } + for (var i=-1; i>-10; i--) { + assertEq(f(a, i), undefined); + } + } +} +testOutOfBounds(); + +function testHole() { + function f(arr, x) { + return arr[x]; + } + var a = [0, , 2, ]; + for (var i=0; i<70; i++) { + assertEq(f(a, 0), 0); + assertEq(f(a, 1), undefined); + assertEq(f(a, 2), 2); + assertEq(f(a, 3), undefined); + } +} +testHole(); + +function testClassGuard() { + function f(arr) { + return arr[2]; + } + var a = [1, 2, 3, 4]; + for (var i=0; i<90; i++) { + assertEq(f(a), 3); + } + var b = {2: 100}; + assertEq(f(b), 100); +} +testClassGuard(); + +function testGeneric1() { + function f(o, i) { + return o[i]; + } + for (var i=0; i<100; i++) { + assertEq(f("abc", 1), "b"); + assertEq(f("foo", "length"), 3); + assertEq(f([], -1), undefined); + assertEq(f({x: 1}, "x"), 1); + } +} +testGeneric1(); diff --git a/js/src/jit-test/tests/ion/getgname-getter.js b/js/src/jit-test/tests/ion/getgname-getter.js new file mode 100644 index 0000000000..47a0464f1c --- /dev/null +++ b/js/src/jit-test/tests/ion/getgname-getter.js @@ -0,0 +1,8 @@ +var accesses = 100000; + +for (var i = 0; i < accesses; i++) + assertEq(timesAccessed, i+1); + +gc(); + +assertEq(timesAccessed, accesses + 1); diff --git a/js/src/jit-test/tests/ion/getgname.js b/js/src/jit-test/tests/ion/getgname.js new file mode 100644 index 0000000000..507172524e --- /dev/null +++ b/js/src/jit-test/tests/ion/getgname.js @@ -0,0 +1,37 @@ +var x = 13; + +function ReturnArray() { + return Array; +} +function ReturnObject() { + return Object; +} +function ReturnX() { + return x; +} + +y = null; +function ReturnY() { + return y; +} +z = "3"; +z = null; +function ReturnZ() { + return z; +} + +for (var i = 0; i < 100; i++) + ReturnArray(); +for (var i = 0; i < 100; i++) + ReturnX(); +for (var i = 0; i < 100; i++) + ReturnZ(); + +gc(); + +assertEq(ReturnArray(), Array); +assertEq(ReturnObject(), Object); +assertEq(ReturnX(), 13); +assertEq(ReturnY(), null); +assertEq(ReturnZ(), null); + diff --git a/js/src/jit-test/tests/ion/getprop-cache.js b/js/src/jit-test/tests/ion/getprop-cache.js new file mode 100644 index 0000000000..68df630dd2 --- /dev/null +++ b/js/src/jit-test/tests/ion/getprop-cache.js @@ -0,0 +1,28 @@ +function test1() { + function h(node) { + var x = 0.1; + for (var i=0; i<100; i++) { + x += node.parent; + } + return x; + } + function build(depth) { + if (depth > 10) + return {parent: 3.3}; + return {__proto__: build(depth + 1)}; + } + var tree = build(0); + assertEq(h(tree)|0, 330); +} +test1(); + +function test2() { + function Foo() {}; + Foo.prototype.x = 3.3; + + var o = new Foo(); + for (var i=0; i<100; i++) { + assertEq(o.x, 3.3); + } +} +test2(); diff --git a/js/src/jit-test/tests/ion/getprop-constant.js b/js/src/jit-test/tests/ion/getprop-constant.js new file mode 100644 index 0000000000..c11e855281 --- /dev/null +++ b/js/src/jit-test/tests/ion/getprop-constant.js @@ -0,0 +1,20 @@ +// |jit-test| error: TypeError + +/* GETPROP of a known constant where the lvalue may not be an object. */ + +function foo(ox) { + var x = ox; + var n = 0; + for (var i = 0; i < 90; i++) { + n += x.f.g; + if (i >= 80) + x = undefined; + } + print(n); +} +var n = 1; +function f() {} +function g() {} +g.g = 1; +f.prototype = {f:g}; +foo(new f()); diff --git a/js/src/jit-test/tests/ion/getprop-idempotent-cache-1.js b/js/src/jit-test/tests/ion/getprop-idempotent-cache-1.js new file mode 100644 index 0000000000..bddde433f6 --- /dev/null +++ b/js/src/jit-test/tests/ion/getprop-idempotent-cache-1.js @@ -0,0 +1,17 @@ +function f(o) { + var res = 0; + for (var i=0; i<11000; i++) { + res += o.x; + } + return res; +} + +function O(x) { + if (x) + this.x = 10; +} + +f(new O(true)); + +// "o.x" is now missing so the idempotent cache should invalidate f. +f(new O(false)); diff --git a/js/src/jit-test/tests/ion/getprop-idempotent-cache-2.js b/js/src/jit-test/tests/ion/getprop-idempotent-cache-2.js new file mode 100644 index 0000000000..8da24537d9 --- /dev/null +++ b/js/src/jit-test/tests/ion/getprop-idempotent-cache-2.js @@ -0,0 +1,21 @@ +function f(o) { + var res = 0; + for (var i=0; i<110; i++) { + res += o.x; + } + return res; +} + +function O(x) { + if ([].length == 0) // Thwart definite slot analysis. + this.x = 10; +} + +var o = new O(true); +f(o); + +// Add a getter, this should invalidate the script containing the idempotent cache. +var res = 0; +o.__defineGetter__("x", function() { res++; }); +f(o); +assertEq(res, 110); diff --git a/js/src/jit-test/tests/ion/getprop-primitive.js b/js/src/jit-test/tests/ion/getprop-primitive.js new file mode 100644 index 0000000000..1935216ab0 --- /dev/null +++ b/js/src/jit-test/tests/ion/getprop-primitive.js @@ -0,0 +1,59 @@ +setJitCompilerOption("ion.warmup.trigger", 50); +setJitCompilerOption("offthread-compilation.enable", 0); +gcPreserveCode(); + +var testSet1 = [1, "", Symbol("a"), true]; +var testSet2 = [1, "", Symbol("a"), true, { bar: 5 }]; + +Number.prototype.bar = 1; +String.prototype.bar = 2; +Symbol.prototype.bar = 3; +Boolean.prototype.bar = 4; + +function assertEqIf(prev, curr, expected) { + // Branch pruning absolutely want to get rid of the next branch + // which causes bailouts, so we forbid inlining of this function. + with({}){} + if (prev) { + assertEq(curr, expected); + return false; + } + return true; +} + +var f; +var template = function (set) { + var lastX = 0, x = 0, i = 0, y = 0; + var cont = true; + while (cont) { // OSR here. + for (var i = 0; i < set.length; i++) { + x = x + (inIon() ? 1 : 0); + if (set[i].placeholder != set[(i + 1) % set.length].placeholder) + y += 1; + } + + // If we bailout in the inner loop, then x will have a smaller value + // than the number of iterations. + cont = assertEqIf(lastX > 0, x, set.length); + if (inIon()) + lastX = x; + x = 0; + } + return y; +} + +// Set 1, Non existing properties. +f = eval(`(${template})`.replace(".placeholder", ".foo")); +f(testSet1); + +// Set 2, Non existing properties. +f = eval(`(${template})`.replace(".placeholder", ".foo")); +f(testSet2); + +// Set 1, Existing properties. +f = eval(`(${template})`.replace(".placeholder", ".bar")); +f(testSet1); + +// Set 2, Existing properties. +f = eval(`(${template})`.replace(".placeholder", ".bar")); +f(testSet2); diff --git a/js/src/jit-test/tests/ion/gvn-unremovable-phi-bug1317675.js b/js/src/jit-test/tests/ion/gvn-unremovable-phi-bug1317675.js new file mode 100644 index 0000000000..99d74fc13e --- /dev/null +++ b/js/src/jit-test/tests/ion/gvn-unremovable-phi-bug1317675.js @@ -0,0 +1,18 @@ +// |jit-test| error: InternalError: too much recursion + +function f() { + var phi1 = 0; + var phi2 = 0; + while (true) { + if (!phi2) { + var add = phi1 + 1; + f(add); + if (!phi2) + return; + phi1 = 1; + phi2 = 0; + } + } +} + +f(0); diff --git a/js/src/jit-test/tests/ion/has-definite-folding.js b/js/src/jit-test/tests/ion/has-definite-folding.js new file mode 100644 index 0000000000..3e5dcfad45 --- /dev/null +++ b/js/src/jit-test/tests/ion/has-definite-folding.js @@ -0,0 +1,32 @@ +var max = 40; +setJitCompilerOption("ion.warmup.trigger", max - 10); + +function defineProperty() { + var abc = {}; + Object.defineProperty(abc, "x", {value: 1}) + assertEq(abc.x, 1); +} + +function simple() { + var o = {a: 1}; + assertEq("a" in o, true); + assertEq("b" in o, false); + assertEq(o.hasOwnProperty("a"), true); + assertEq(o.hasOwnProperty("b"), false); +} + +function proto() { + var o = {a: 1, __proto__: {b: 2}}; + assertEq("a" in o, true); + assertEq("b" in o, true); + assertEq("c" in o, false); + assertEq(o.hasOwnProperty("a"), true); + assertEq(o.hasOwnProperty("b"), false); + assertEq(o.hasOwnProperty("c"), false); +} + +for (var i = 0; i < max; i++) { + defineProperty(); + simple(); + proto(); +} diff --git a/js/src/jit-test/tests/ion/hole.js b/js/src/jit-test/tests/ion/hole.js new file mode 100644 index 0000000000..c990704cd7 --- /dev/null +++ b/js/src/jit-test/tests/ion/hole.js @@ -0,0 +1,11 @@ +function f() { + var a; + for (var i=0; i<50; i++) { + a = [i, , [,, i*3], ]; + } + return a; +} +Array.prototype[1] = 123; +var arr = f(); +assertEq(arr.length, 3); +assertEq(arr.toString(), "49,123,,123,147"); diff --git a/js/src/jit-test/tests/ion/ic-fuzz-0.js b/js/src/jit-test/tests/ion/ic-fuzz-0.js new file mode 100644 index 0000000000..9a14a1b148 --- /dev/null +++ b/js/src/jit-test/tests/ion/ic-fuzz-0.js @@ -0,0 +1,3 @@ +setJitCompilerOption("ion.warmup.trigger", 50); +for (var i = 0; i < 150; i++) + Infinity; diff --git a/js/src/jit-test/tests/ion/idempotentCache.js b/js/src/jit-test/tests/ion/idempotentCache.js new file mode 100644 index 0000000000..6a54bb72e5 --- /dev/null +++ b/js/src/jit-test/tests/ion/idempotentCache.js @@ -0,0 +1,34 @@ +// Test that we don't attach ICs to idempotent caches that are incompatible +// with the cache result type. + +var missingObjs = [{a:1},Object.create({a:2}),{}]; +function testMissing(limit) +{ + var res = 0; + for (var i = 0; i < 1000; i++) { + for (var j = 0; j < missingObjs.length; j++) { + var obj = missingObjs[j]; + if (j < limit) + res += obj.a; + } + } + return res; +} +assertEq(testMissing(2), 3000); +assertEq(testMissing(3), NaN); + +var lengthObjs = [{length:{a:1}},Object.create({length:{a:2}}),[0,1]]; +function testArrayLength(limit) +{ + var res = 0; + for (var i = 0; i < 1000; i++) { + for (var j = 0; j < lengthObjs.length; j++) { + var obj = lengthObjs[j]; + if (j < limit) + res += obj.length.a; + } + } + return res; +} +assertEq(testArrayLength(2), 3000); +assertEq(testArrayLength(3), NaN); diff --git a/js/src/jit-test/tests/ion/idiv-by-constant.js b/js/src/jit-test/tests/ion/idiv-by-constant.js new file mode 100644 index 0000000000..c1ebbea71f --- /dev/null +++ b/js/src/jit-test/tests/ion/idiv-by-constant.js @@ -0,0 +1,108 @@ +function int_seq(count) { + var arr = []; + var x = 0xfac83126; + while (count--) { + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + arr.push(x | 0); + } + return arr; +} + +function test(name, asm, ion, int) { + let count = 10000; + let seq = int_seq(count); + for (let x of seq) { + let rint = int(x); + let rasm = asm(x); + let rion = ion(x); + // console.log(name, x, rint, rasm, rion); + assertEq(rasm, rint); + assertEq(rion, rint); + } +} + +var asmdiv2 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x|0) / 2)|0; + return z|0; + } + return f; +})() + +var plaindiv2 = function(x) { + x = x|0; + var z = 0; + z = ((x|0) / 2)|0; + return z|0; +} + +var interpdiv2 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x|0) / 2)|0; + return z|0; +} + +test("div2", asmdiv2, plaindiv2, interpdiv2); + +var asmdiv3 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x|0) / 3)|0; + return z|0; + } + return f; +})() + +var plaindiv3 = function(x) { + x = x|0; + var z = 0; + z = ((x|0) / 3)|0; + return z|0; +} + +var interpdiv3 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x|0) / 3)|0; + return z|0; +} + +test("div3", asmdiv3, plaindiv3, interpdiv3); + +var asmdiv7 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x|0) / 7)|0; + return z|0; + } + return f; +})() + +var plaindiv7 = function(x) { + x = x|0; + var z = 0; + z = ((x|0) / 7)|0; + return z|0; +} + +var interpdiv7 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x|0) / 7)|0; + return z|0; +} + +test("div7", asmdiv7, plaindiv7, interpdiv7); diff --git a/js/src/jit-test/tests/ion/iloop.js b/js/src/jit-test/tests/ion/iloop.js new file mode 100644 index 0000000000..064432d4be --- /dev/null +++ b/js/src/jit-test/tests/ion/iloop.js @@ -0,0 +1,4 @@ +// |jit-test| exitstatus: 6; + +timeout(1); +for(;;); diff --git a/js/src/jit-test/tests/ion/inline-Math-random-before-called.js b/js/src/jit-test/tests/ion/inline-Math-random-before-called.js new file mode 100644 index 0000000000..25d801b62f --- /dev/null +++ b/js/src/jit-test/tests/ion/inline-Math-random-before-called.js @@ -0,0 +1,11 @@ +// |jit-test| --ion-eager + +function ionCompiledEagerly() { + Math.random; // establish Math.random's identity for inlining + return function() { + return +Math.random(); // call will be inlined + }; +} + +var alreadyIonCompiled = ionCompiledEagerly(); +assertEq(alreadyIonCompiled() < 1, true); diff --git a/js/src/jit-test/tests/ion/inline-doubles.js b/js/src/jit-test/tests/ion/inline-doubles.js new file mode 100644 index 0000000000..e59a5f1334 --- /dev/null +++ b/js/src/jit-test/tests/ion/inline-doubles.js @@ -0,0 +1,33 @@ +function add0_5 (n) { + return n + 0.5; +} + +function add1_0 (n) { + return n + 1; +} + +function add1_5 (n) { + return n + 1.5; +} + +function add2_0 (n) { + return n + 2; +} + +function sub2_0 (n) { + return n - 2; +} + + +var num = 1.5; + +function main () { + for (var i = 0; i < 1000; i++) { + assertEq(add0_5(num), 2); + assertEq(add1_0(num), 2.5); + assertEq(add1_5(num), 3); + assertEq(add2_0(num), 3.5); + assertEq(sub2_0(num), -0.5); + } +} +main(); diff --git a/js/src/jit-test/tests/ion/inlining/array-pop.js b/js/src/jit-test/tests/ion/inlining/array-pop.js new file mode 100644 index 0000000000..007b1dc8ec --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/array-pop.js @@ -0,0 +1,17 @@ +function f(arr) { + var x; + for (var i=0; i<100; i++) { + x = arr.pop(); + } + return x; +} + +var arr = []; +for (var i=0; i<130; i++) { + arr.push({i: i}); +} + +assertEq(f(arr).i, 30); +assertEq(arr.length, 30); +assertEq(f(arr), undefined); +assertEq(arr.length, 0); diff --git a/js/src/jit-test/tests/ion/inlining/array-push.js b/js/src/jit-test/tests/ion/inlining/array-push.js new file mode 100644 index 0000000000..3e7ac159e3 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/array-push.js @@ -0,0 +1,37 @@ +function test1() { + function push(arr, x) { + return arr.push(x); + } + var arr = []; + for (var i=0; i<100; i++) { + assertEq(push(arr, i), i + 1); + } +} +test1(); + +function test2() { + var arr; + for (var i=0; i<60; i++) { + arr = []; + assertEq(arr.push(3.3), 1); + assertEq(arr.push(undefined), 2); + assertEq(arr.push(true), 3); + assertEq(arr.push(Math), 4); + assertEq(arr.toString(), "3.3,,true,[object Math]"); + } +} +test2(); + +function test3() { + function push(arr, v) { + arr.push(v); + } + for (var i=0; i<60; i++) { + var arr = []; + push(arr, null); + push(arr, 3.14); + push(arr, {}); + assertEq(arr.toString(), ",3.14,[object Object]"); + } +} +test3(); diff --git a/js/src/jit-test/tests/ion/inlining/bug705251.js b/js/src/jit-test/tests/ion/inlining/bug705251.js new file mode 100644 index 0000000000..19f639d7aa --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/bug705251.js @@ -0,0 +1,10 @@ +function bitsinbyte() { + var c = 0; + while (false) c = c * 2; +} +function TimeFunc(func) { + for(var y=0; y<11000; y++) + func(); +} +for (var i=0; i<50; i++) + TimeFunc(bitsinbyte); diff --git a/js/src/jit-test/tests/ion/inlining/call-apply-non-singletons.js b/js/src/jit-test/tests/ion/inlining/call-apply-non-singletons.js new file mode 100644 index 0000000000..9b26ddf0ab --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/call-apply-non-singletons.js @@ -0,0 +1,22 @@ +var arr1 = []; +var arr2 = []; +for (let i = 0; i < 10; i++) { + arr1.push(function f(x) { + if (x === 350) + bailout(); + assertEq(f, arr1[i]); + return x + i; + }); + arr2.push(function() { + return arr1[i].apply(null, arguments); + }); +} + +function test() { + for (var i = 0; i < 400; i++) { + for (var j = 0; j < arr2.length; j++) { + assertEq(arr2[j].call(null, i), i + j); + } + } +} +test(); diff --git a/js/src/jit-test/tests/ion/inlining/exception-during-inlining-decision.js b/js/src/jit-test/tests/ion/inlining/exception-during-inlining-decision.js new file mode 100644 index 0000000000..17c11f8599 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/exception-during-inlining-decision.js @@ -0,0 +1,115 @@ +function runNearStackLimit(f) { + function t() { + try { + return t(); + } catch (e) { + return f(); + } + } + return t() +} +var helpers = function helpers() { + return { + get isCompatVersion9() { + } }; +}(); +var testRunner = function testRunner() { + var testRunner = { + asyncTestHasNoErr: function asyncTestHasNoErr() { + }, + runTests: function runTests(testsToRun) { + for (var i in testsToRun) { + this.runTest(i, testsToRun[i].name, testsToRun[i].body); + } + }, + runTest: function runTest(testIndex, testName, testBody) { + try { + testBody(); + } catch (ex) { + } + }, + asyncTestBegin: function asyncTestBegin() { + return explicitAsyncTestExit ? ` + ` : ` + `; + } }; + return testRunner; +}(); +var assert = function assert() { + var validate = function validate() { + }; + return { + areEqual: function areEqual() { + validate( message); + }, + areNotEqual: function areNotEqual() { + } }; +}(); +class __c_19 { + constructor() { + this.foo = 'SimpleParent'; + } +} +var __v_2735 = [{ + body: function () { + class __c_23 extends __c_19 { + constructor() { + super() + } + } + let __v_2738 = new __c_23(); + } +}, { + body: function () { + class __c_26 extends __c_19 { + constructor() { + super(); + } + } + let __v_2739 = new __c_26(); + } +}, { + body: function () { + class __c_29 extends __c_19 { + constructor() { + super() + } + } + let __v_2743 = new __c_29(); + class __c_30 extends __c_19 { + constructor() { + super() + super(); + } + } + let __v_2746 = new __c_30(); + } +}, { + body: function () { + class __c_34 extends __c_19 {} + let __v_2749 = new __c_34(); + } +}, { + body: function () { + class __c_87 extends __c_19 { + constructor() { + try { + assert.areEqual(); + } catch (e) {} + eval('super();') + } + } + function __f_683(__v_2812) { + __v_2812.foo + } + __f_683(new __c_87()) + runNearStackLimit(() => { + return __f_683(); + }) + } +}, { + body: function () { + } +}]; + testRunner.runTests(__v_2735, { + });
\ No newline at end of file diff --git a/js/src/jit-test/tests/ion/inlining/getelem-getter-bailout.js b/js/src/jit-test/tests/ion/inlining/getelem-getter-bailout.js new file mode 100644 index 0000000000..71fc680a8a --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/getelem-getter-bailout.js @@ -0,0 +1,48 @@ +// Test bailouts in inlined jsop_getelem accesses. + +// Defined outside of the test functions to ensure they're recognised as +// constants in Ion. +var atom = "prop"; +var symbol = Symbol(); + +function testAtom() { + var holder = { + get [atom]() { + bailout(); + return 1; + } + }; + + function f() { + for (var i = 0; i < 2000; ++i) { + var x = holder[atom]; + assertEq(x, 1); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testAtom(); + +function testSymbol() { + var holder = { + get [symbol]() { + bailout(); + return 1; + } + }; + + function f() { + for (var i = 0; i < 2000; ++i) { + var x = holder[symbol]; + assertEq(x, 1); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testSymbol(); diff --git a/js/src/jit-test/tests/ion/inlining/getelem-getter-frameiter.js b/js/src/jit-test/tests/ion/inlining/getelem-getter-frameiter.js new file mode 100644 index 0000000000..7a2e2f1405 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/getelem-getter-frameiter.js @@ -0,0 +1,48 @@ +// Test bailouts in inlined jsop_getelem accesses. + +// Defined outside of the test functions to ensure they're recognised as +// constants in Ion. +var atom = "prop"; +var symbol = Symbol(); + +function testAtom() { + var holder = { + get [atom]() { + new Error().stack; + return 1; + } + }; + + function f() { + for (var i = 0; i < 2000; ++i) { + var x = holder[atom]; + assertEq(x, 1); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testAtom(); + +function testSymbol() { + var holder = { + get [symbol]() { + new Error().stack; + return 1; + } + }; + + function f() { + for (var i = 0; i < 2000; ++i) { + var x = holder[symbol]; + assertEq(x, 1); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testSymbol(); diff --git a/js/src/jit-test/tests/ion/inlining/getelem-getter-id-mismatch.js b/js/src/jit-test/tests/ion/inlining/getelem-getter-id-mismatch.js new file mode 100644 index 0000000000..57a2c0ff68 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/getelem-getter-id-mismatch.js @@ -0,0 +1,113 @@ +// Ensure BaselineInspector properly handles mixed atom/symbols when determining +// whether or not a jsop_getelem access to a getter can be inlined. + +// Defined outside of the test functions to ensure they're recognised as +// constants in Ion. +var atom1 = "prop1"; +var atom2 = "prop2"; +var sym1 = Symbol(); +var sym2 = Symbol(); + +function testAtomAtom() { + var holder = { + get [atom1]() { return 1; }, + get [atom2]() { return 2; }, + }; + + function get(name) { + // Single access point called with different atoms. + return holder[name]; + } + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = get(atom1); + var y = get(atom2); + assertEq(x, 1); + assertEq(y, 2); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testAtomAtom(); + +function testAtomSymbol() { + var holder = { + get [atom1]() { return 1; }, + get [sym2]() { return 2; }, + }; + + function get(name) { + // Single access point called with atom and symbol. + return holder[name]; + } + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = get(atom1); + var y = get(sym2); + assertEq(x, 1); + assertEq(y, 2); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testAtomSymbol(); + +function testSymbolAtom() { + var holder = { + get [sym1]() { return 1; }, + get [atom2]() { return 2; }, + }; + + function get(name) { + // Single access point called with symbol and atom. + return holder[name]; + } + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = get(sym1); + var y = get(atom2); + assertEq(x, 1); + assertEq(y, 2); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testSymbolAtom(); + +function testSymbolSymbol() { + var holder = { + get [sym1]() { return 1; }, + get [sym2]() { return 2; }, + }; + + function get(name) { + // Single access point called with different symbols. + return holder[name]; + } + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = get(sym1); + var y = get(sym2); + assertEq(x, 1); + assertEq(y, 2); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testSymbolSymbol(); diff --git a/js/src/jit-test/tests/ion/inlining/getelem-getter-megamorphic.js b/js/src/jit-test/tests/ion/inlining/getelem-getter-megamorphic.js new file mode 100644 index 0000000000..2b8fdddcd0 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/getelem-getter-megamorphic.js @@ -0,0 +1,79 @@ +// Test for inlined getters for jsop_getelem accesses, where the getter is a +// property on the prototype and a megamorphic IC is attached. + +function makeObjects(name) { + class Base { + constructor(v) { + this._prop = v; + } + get [name]() { + return this._prop; + } + } + + // When we hit |TYPE_FLAG_OBJECT_COUNT_LIMIT|, the objects are marked as + // |TYPE_FLAG_ANYOBJECT|. That means less than |TYPE_FLAG_OBJECT_COUNT_LIMIT| + // objects need to be created to have no unknown objects in the type set. + const TYPE_FLAG_OBJECT_COUNT_LIMIT = 7; + + // |ICState::ICState::MaxOptimizedStubs| defines the maximum number of + // optimized stubs, so as soon as we hit the maximum number, the megamorphic + // state is entered. + const ICState_MaxOptimizedStubs = 6; + + // Create enough classes to enter megamorphic state, but not too much to + // have |TYPE_FLAG_ANYOBJECT| in the TypeSet. + const OBJECT_COUNT = Math.min(ICState_MaxOptimizedStubs, TYPE_FLAG_OBJECT_COUNT_LIMIT); + + var objects = []; + for (var i = 0; i < OBJECT_COUNT; ++i) { + objects.push(new class extends Base {}(1)); + } + + return objects; +} + +// Defined outside of the test functions to ensure they're recognised as +// constants in Ion. +var atom = "prop"; +var symbol = Symbol(); + +function testAtom() { + var objects = makeObjects(atom); + + function f() { + var actual = 0; + var expected = 0; + for (var i = 0; i < 1000; i++) { + var obj = objects[i % objects.length]; + actual += obj[atom]; + expected += obj._prop; + } + assertEq(actual, expected); + } + + for (var i = 0; i < 2; ++i) { + f(); + } +} +testAtom(); + +function testSymbol() { + var objects = makeObjects(symbol); + + function f() { + var actual = 0; + var expected = 0; + for (var i = 0; i < 1000; i++) { + var obj = objects[i % objects.length]; + actual += obj[symbol]; + expected += obj._prop; + } + assertEq(actual, expected); + } + + for (var i = 0; i < 2; ++i) { + f(); + } +} +testSymbol(); diff --git a/js/src/jit-test/tests/ion/inlining/getelem-getter-noninlined-call.js b/js/src/jit-test/tests/ion/inlining/getelem-getter-noninlined-call.js new file mode 100644 index 0000000000..e3b741e0ef --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/getelem-getter-noninlined-call.js @@ -0,0 +1,52 @@ +// With-Statements are not supported in Ion, therefore functions containing +// them can't be inlined in Ion. However it's still possible to inline the +// property access to the getter into a simple guard-shape instruction. + +// Defined outside of the test functions to ensure they're recognised as +// constants in Ion. +var atom = "prop"; +var symbol = Symbol(); + +function testAtom() { + var holder = { + get [atom]() { + with ({}) { + return 1; + } + } + }; + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = holder[atom]; + assertEq(x, 1); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testAtom(); + +function testSymbol() { + var holder = { + get [symbol]() { + with ({}) { + return 1; + } + } + }; + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = holder[symbol]; + assertEq(x, 1); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testSymbol(); diff --git a/js/src/jit-test/tests/ion/inlining/getelem-getter-own.js b/js/src/jit-test/tests/ion/inlining/getelem-getter-own.js new file mode 100644 index 0000000000..f2e5ce617b --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/getelem-getter-own.js @@ -0,0 +1,51 @@ +// Test for inlined getters for jsop_getelem accesses, where the getter is an +// own property. + +// Defined outside of the test functions to ensure they're recognised as +// constants in Ion. +var atom1 = "prop1"; +var atom2 = "prop2"; +var sym1 = Symbol(); +var sym2 = Symbol(); + +function testAtom() { + var holder = { + get [atom1]() { return 1; }, + get [atom2]() { return 2; }, + }; + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = holder[atom1]; + var y = holder[atom2]; + assertEq(x, 1); + assertEq(y, 2); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testAtom(); + +function testSymbol() { + var holder = { + get [sym1]() { return 1; }, + get [sym2]() { return 2; }, + }; + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = holder[sym1]; + var y = holder[sym2]; + assertEq(x, 1); + assertEq(y, 2); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testSymbol(); diff --git a/js/src/jit-test/tests/ion/inlining/getelem-getter-proto.js b/js/src/jit-test/tests/ion/inlining/getelem-getter-proto.js new file mode 100644 index 0000000000..8aab839f1e --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/getelem-getter-proto.js @@ -0,0 +1,55 @@ +// Test for inlined getters for jsop_getelem accesses, where the getter is a +// property on the prototype. + +// Defined outside of the test functions to ensure they're recognised as +// constants in Ion. +var atom1 = "prop1"; +var atom2 = "prop2"; +var sym1 = Symbol(); +var sym2 = Symbol(); + +function testAtom() { + var proto = { + get [atom1]() { return 1; }, + get [atom2]() { return 2; }, + }; + + var holder = Object.create(proto); + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = holder[atom1]; + var y = holder[atom2]; + assertEq(x, 1); + assertEq(y, 2); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testAtom(); + +function testSymbol() { + var proto = { + get [sym1]() { return 1; }, + get [sym2]() { return 2; }, + }; + + var holder = Object.create(proto); + + function f() { + for (var i = 0; i < 1000; ++i) { + var x = holder[sym1]; + var y = holder[sym2]; + assertEq(x, 1); + assertEq(y, 2); + } + } + + for (var i = 0; i < 2; i++) { + f(); + } +} +testSymbol(); diff --git a/js/src/jit-test/tests/ion/inlining/inline-callarg-bailout-phi.js b/js/src/jit-test/tests/ion/inlining/inline-callarg-bailout-phi.js new file mode 100644 index 0000000000..06bc1f6efe --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/inline-callarg-bailout-phi.js @@ -0,0 +1,29 @@ +function add(x, y) { + if (x & 0x1) + return x + y; + else + return y + x; +} + +function runBinop(binop, lhs, rhs) { + return binop(lhs, rhs); +} + +//dis(run_binop); + +// Get the add function to compile. +var accum = 0; +for (var i = 0; i < 1000; ++i) + accum += add(1, 1); +assertEq(accum, 2000); + +// Get the runBinop function to compile and inline the add function. +var accum = 0; +for (var i = 0; i < 11000; ++i) + accum = runBinop(add, i, i); +assertEq(accum, 21998); + +var t30 = 1 << 30; +var t31 = t30 + t30; +var result = runBinop(add, t31, t31); +assertEq(result, Math.pow(2, 32)); diff --git a/js/src/jit-test/tests/ion/inlining/inline-callarg-bailout.js b/js/src/jit-test/tests/ion/inlining/inline-callarg-bailout.js new file mode 100644 index 0000000000..fad2c1a3bb --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/inline-callarg-bailout.js @@ -0,0 +1,26 @@ +function add(x, y) { + return x + y; +} + +function runBinop(binop, lhs, rhs) { + return binop(lhs, rhs); +} + +//dis(run_binop); + +// Get the add function to compile. +var accum = 0; +for (var i = 0; i < 1000; ++i) + accum += add(1, 1); +assertEq(accum, 2000); + +// Get the runBinop function to compile and inline the add function. +var accum = 0; +for (var i = 0; i < 10100; ++i) + accum = runBinop(add, i, i); +assertEq(accum, 20198); + +var t30 = 1 << 30; +var t31 = t30 + t30; +var result = runBinop(add, t31, t31); +assertEq(result, Math.pow(2, 32)); diff --git a/js/src/jit-test/tests/ion/inlining/inline-callarg-ubench-no-double2.js b/js/src/jit-test/tests/ion/inlining/inline-callarg-ubench-no-double2.js new file mode 100644 index 0000000000..385ea1a026 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/inline-callarg-ubench-no-double2.js @@ -0,0 +1,27 @@ +function lameFunc(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +function runSomeTimes(func, iters) { + var result; + for (var i = 0; i < iters; ++i) { + result = func(42, 42); + result = func(42, 42); + } + return result; +} + +// First, run the inner function to get TI information. +for (var i = 0; i < 100; ++i) + lameFunc(42, 42); + +// Then, run the outer function with the inner function as a CALLARG to get it +// to Ion compile with inlining. +for (var i = 0; i < 11000; ++i) + runSomeTimes(lameFunc, 1); + +// Lastly, now that we're all inlined and compiled, perform the test! +var iterations = 100; +assertEq(84, runSomeTimes(lameFunc, iterations)); diff --git a/js/src/jit-test/tests/ion/inlining/inline-getelem-args.js b/js/src/jit-test/tests/ion/inlining/inline-getelem-args.js new file mode 100644 index 0000000000..41acaf6a04 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/inline-getelem-args.js @@ -0,0 +1,59 @@ +function cat() { + var res = ""; + for (var i = 0; i < arguments.length; i++) + res += arguments[i]; + return res; +} + +function cat_m1(ion) { + var res = ""; + for (var i = (ion ? -1 : 0); i < arguments.length; i++) + res += arguments[i]; + return res; +} + +function cat_p1(ion) { + var res = ""; + for (var i = 0; i < arguments.length + (ion ? 1 : 0); i++) + res += arguments[i]; + return res; +} + +function sum() { + var res = 0; + for (var i = 0; i < arguments.length; i++) + res += arguments[i]; + return res; +} + +function wrapper() { + var res; + var i6 = { valueOf: () => 6 }, + i8 = 8.5, + s2 = { toString: () => "2" }, + s4 = {}, + s6 = "6", + s7 = undefined, + s8 = null; + for (var b = true; b; b = !inIon()) { + res = sum(1,2,3,4,5,i6,7,i8,9,10); + assertEq(res, 55.5); + + res = cat(true,s2,3,s4,5,s6,s7,s8); + assertEq(res, "true23[object Object]56undefinednull"); + + ion = inIon(); + if (typeof ion !== "boolean") break; + res = cat_m1(ion,1,s2,3,s4,5,s6,s7,s8); + if (ion) assertEq(res, "undefinedtrue123[object Object]56undefinednull"); + else assertEq(res, "false123[object Object]56undefinednull"); + + ion = inIon(); + if (typeof ion !== "boolean") break; + res = cat_p1(ion,1,s2,3,s4,5,s6,s7,s8); + if (ion) assertEq(res, "true123[object Object]56undefinednullundefined"); + else assertEq(res, "false123[object Object]56undefinednull"); + } +} + +wrapper(); diff --git a/js/src/jit-test/tests/ion/inlining/inline-istypedarray-on-nontypedarray.js b/js/src/jit-test/tests/ion/inlining/inline-istypedarray-on-nontypedarray.js new file mode 100644 index 0000000000..e1c540d19d --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/inline-istypedarray-on-nontypedarray.js @@ -0,0 +1,6 @@ +(new Int8Array(3)).join(); +[Math.abs, Math.abs].forEach(x => { + try { + Int8Array.prototype.join.call(x); + } catch(e) {} +}); diff --git a/js/src/jit-test/tests/ion/inlining/isFiniteInline.js b/js/src/jit-test/tests/ion/inlining/isFiniteInline.js new file mode 100644 index 0000000000..6f0897009b --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/isFiniteInline.js @@ -0,0 +1,15 @@ +/* Test inlining of Number.isFinite() */ + +for (var i = 0; i < 10_000; i++) { + assertEq(Number.isFinite(NaN), false); + assertEq(Number.isFinite(-NaN), false); + assertEq(Number.isFinite(+Infinity), false); + assertEq(Number.isFinite(-Infinity), false); + assertEq(Number.isFinite(3), true); + assertEq(Number.isFinite(3.141592654), true); + assertEq(Number.isFinite(+0), true); + assertEq(Number.isFinite(-0), true); + assertEq(Number.isFinite(-3), true); + assertEq(Number.isFinite(-3.141592654), true); + assertEq(Number.isFinite({}), false); +} diff --git a/js/src/jit-test/tests/ion/inlining/isNaNInline.js b/js/src/jit-test/tests/ion/inlining/isNaNInline.js new file mode 100644 index 0000000000..23766f7b5d --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/isNaNInline.js @@ -0,0 +1,15 @@ +/* Test inlining of Number.isNaN() */ + +for (var i = 0; i < 10_000; i++) { + assertEq(Number.isNaN(NaN), true); + assertEq(Number.isNaN(-NaN), true); + assertEq(Number.isNaN(+Infinity), false); + assertEq(Number.isNaN(-Infinity), false); + assertEq(Number.isNaN(3.14159), false); + assertEq(Number.isNaN(-3.14159), false); + assertEq(Number.isNaN(3), false); + assertEq(Number.isNaN(-3), false); + assertEq(Number.isNaN(+0), false); + assertEq(Number.isNaN(-0), false); + assertEq(Number.isNaN({}), false); +} diff --git a/js/src/jit-test/tests/ion/inlining/object-is-stricteq.js b/js/src/jit-test/tests/ion/inlining/object-is-stricteq.js new file mode 100644 index 0000000000..059c3f210c --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/object-is-stricteq.js @@ -0,0 +1,143 @@ +// Test when Object.is() is inlined as JSOP_STRICTEQ + +function SameValue(x, y) { + if (x === y) { + return (x !== 0) || (1 / x === 1 / y); + } + return (x !== x && y !== y); +} + +var compareTemplate = function compare(name, xs, ys) { + // Compare each entry in xs with each entry in ys and ensure Object.is + // computes the same result as SameValue. + for (var i = 0; i < 1000; ++i) { + var xi = (i % xs.length) | 0; + var yi = ((i + ((i / ys.length) | 0)) % ys.length) | 0; + + assertEq(Object.is(xs[xi], ys[yi]), SameValue(xs[xi], ys[yi]), name); + } +} + +const objects = { + plain: {}, + function: function(){}, + proxy: new Proxy({}, {}), +}; + +const sym = Symbol(); + +const testCases = [ + { + name: "Homogenous-Int32", + xs: [-1, 0, 1, 2, 0x7fffffff], + ys: [2, 1, 0, -5, -0x80000000], + }, + { + name: "Homogenous-Boolean", + xs: [true, false], + ys: [true, false], + }, + { + name: "Homogenous-Object", + xs: [{}, [], objects.plain, objects.proxy], + ys: [{}, objects.function, objects.plain, objects.proxy], + }, + { + name: "Homogenous-String", + xs: ["", "abc", "αβγαβγ", "𝐀𝐁𝐂𝐀𝐁𝐂", "ABCabc"], + ys: ["abc", "ABC", "ABCABC", "αβγαβγ", "𝐀𝐁𝐂𝐀𝐁𝐂"], + }, + { + name: "Homogenous-Symbol", + xs: [Symbol.iterator, Symbol(), Symbol.for("object-is"), sym], + ys: [sym, Symbol.match, Symbol(), Symbol.for("object-is-two")], + }, + { + name: "Homogenous-Null", + xs: [null, null], + ys: [null, null], + }, + { + name: "Homogenous-Undefined", + xs: [undefined, undefined], + ys: [undefined, undefined], + }, + + // Note: Values must not include floating-point types! + { + name: "String-Value", + xs: ["", "abc", "αβγαβγ", "𝐀𝐁𝐂𝐀𝐁𝐂"], + ys: [null, undefined, sym, true, 0, "", {}], + }, + { + name: "Null-Value", + xs: [null, null], + ys: [null, undefined, sym, true, 0, "", {}], + }, + { + name: "Undefined-Value", + xs: [undefined, undefined], + ys: [null, undefined, sym, true, 0, "", {}], + }, + { + name: "Boolean-Value", + xs: [true, false], + ys: [null, undefined, sym, true, 0, "", {}], + }, + + // Note: Values must not include floating-point types! + { + name: "Value-String", + xs: [null, undefined, sym, true, 0, "", {}], + ys: ["", "abc", "αβγαβγ", "𝐀𝐁𝐂𝐀𝐁𝐂"], + }, + { + name: "Value-Null", + xs: [null, undefined, sym, true, 0, "", {}], + ys: [null, null], + }, + { + name: "Value-Undefined", + xs: [null, undefined, sym, true, 0, "", {}], + ys: [undefined, undefined], + }, + { + name: "Value-Boolean", + xs: [null, undefined, sym, true, 0, "", {}], + ys: [undefined, undefined], + }, + + // Strict-equal comparison can be optimized to bitwise comparison when + // string types are not possible. + // Note: Values must not include floating-point types! + { + name: "Value-Value", + xs: [null, undefined, sym, true, 0, {}], + ys: [null, undefined, sym, true, 0, {}], + }, + { + name: "ValueMaybeString-ValueMaybeString", + xs: [null, undefined, sym, true, 0, "", {}], + ys: [null, undefined, sym, true, 0, "", {}], + }, + { + name: "Value-ValueMaybeString", + xs: [null, undefined, sym, true, 0, {}], + ys: [null, undefined, sym, true, 0, "", {}], + }, + { + name: "ValueMaybeString-Value", + xs: [null, undefined, sym, true, 0, "", {}], + ys: [null, undefined, sym, true, 0, {}], + }, +]; + +for (let {name, xs, ys} of testCases) { + // Create a separate function for each test case. + // Use indirect eval to avoid possible direct eval deopts. + const compare = (0, eval)(`(${compareTemplate})`); + + for (let i = 0; i < 5; ++i) { + compare(name, xs, ys); + } +} diff --git a/js/src/jit-test/tests/ion/inlining/typedarray-data-inlining-neuter-samedata.js b/js/src/jit-test/tests/ion/inlining/typedarray-data-inlining-neuter-samedata.js new file mode 100644 index 0000000000..16478e0a06 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/typedarray-data-inlining-neuter-samedata.js @@ -0,0 +1,28 @@ +var NONINLINABLE_AMOUNT = 40; +var SIZEOF_INT32 = 4; + +var INLINABLE_INT8_AMOUNT = 4; + +// Large arrays with non-inline data + +var ab1 = new ArrayBuffer(NONINLINABLE_AMOUNT * SIZEOF_INT32); +var ta1 = new Int32Array(ab1); +for (var i = 0; i < ta1.length; i++) + ta1[i] = i + 43; +function q1() { return ta1[NONINLINABLE_AMOUNT - 1]; } +assertEq(q1(), NONINLINABLE_AMOUNT - 1 + 43); +assertEq(q1(), NONINLINABLE_AMOUNT - 1 + 43); +detachArrayBuffer(ab1); +assertEq(q1(), undefined); + +// Small arrays with inline data + +var ab2 = new ArrayBuffer(INLINABLE_INT8_AMOUNT); +var ta2 = new Int8Array(ab2); +for (var i = 0; i < ta2.length; i++) + ta2[i] = i + 13; +function q2() { return ta2[INLINABLE_INT8_AMOUNT - 1]; } +assertEq(q2(), INLINABLE_INT8_AMOUNT - 1 + 13); +assertEq(q2(), INLINABLE_INT8_AMOUNT - 1 + 13); +detachArrayBuffer(ab2); +assertEq(q2(), undefined); diff --git a/js/src/jit-test/tests/ion/inlining/typedarray-large-length.js b/js/src/jit-test/tests/ion/inlining/typedarray-large-length.js new file mode 100644 index 0000000000..9e6d67d3b3 --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/typedarray-large-length.js @@ -0,0 +1,10 @@ +var SINGLETON_BYTE_LENGTH = 1024 * 1024 * 10; + +for (var i = 0; i < 2000; i++) { + if (i == 1500) + len = SINGLETON_BYTE_LENGTH >> 3; + else + len = i % 64; + var arr = new Float64Array(len); + assertEq(arr[0], len ? 0 : undefined); +} diff --git a/js/src/jit-test/tests/ion/inlining/typedarray-length-inlining-neuter.js b/js/src/jit-test/tests/ion/inlining/typedarray-length-inlining-neuter.js new file mode 100644 index 0000000000..520dd1a38b --- /dev/null +++ b/js/src/jit-test/tests/ion/inlining/typedarray-length-inlining-neuter.js @@ -0,0 +1,22 @@ +var INLINE_INT8_AMOUNT = 4; +var OUT_OF_LINE_INT8_AMOUNT = 237; + +// Small and inline + +var ab1 = new ArrayBuffer(INLINE_INT8_AMOUNT); +var ta1 = new Int8Array(ab1); +function q1() { return ta1.length; } +q1(); +q1(); +detachArrayBuffer(ab1); +assertEq(q1(), 0); + +// Large and out-of-line + +var ab2 = new ArrayBuffer(OUT_OF_LINE_INT8_AMOUNT); +var ta2 = new Int8Array(ab2); +function q2() { return ta2.length; } +q2(); +q2(); +detachArrayBuffer(ab2); +assertEq(q2(), 0); diff --git a/js/src/jit-test/tests/ion/instanceof-mutate-proto.js b/js/src/jit-test/tests/ion/instanceof-mutate-proto.js new file mode 100644 index 0000000000..e3e057ec4f --- /dev/null +++ b/js/src/jit-test/tests/ion/instanceof-mutate-proto.js @@ -0,0 +1,13 @@ +function g(i) { + with(this) {}; // Don't inline. + if (i === 1500) + String.prototype.__proto__ = Array.prototype; +} +function f() { + var arr = new String("A"); + for (var i=0; i<2000; i++) { + g(i); + assertEq(arr instanceof Array, i >= 1500); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/invalidation/easy-invalidate.js b/js/src/jit-test/tests/ion/invalidation/easy-invalidate.js new file mode 100644 index 0000000000..ccade26dc6 --- /dev/null +++ b/js/src/jit-test/tests/ion/invalidation/easy-invalidate.js @@ -0,0 +1,5 @@ +// When run with eager, invalidation will be forced immediately. + +(function(o) { + o.s; +})({}); diff --git a/js/src/jit-test/tests/ion/invalidation/framedescriptors.js b/js/src/jit-test/tests/ion/invalidation/framedescriptors.js new file mode 100644 index 0000000000..562ddf9f66 --- /dev/null +++ b/js/src/jit-test/tests/ion/invalidation/framedescriptors.js @@ -0,0 +1,40 @@ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ +function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} +function core_md5(x, len) { + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + for(var i = 0; i < x.length; i += 16) + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); +} +function md5_cmn(q, a, b, x, s, t) { + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) { + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function safe_add(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} +function bit_rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); +} +function str2binl(str) { + var bin = Array(); + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); + return bin; +} +function binl2hex(binarray) {} +var plainText = "Rebellious subjects, enemies to peace,\n\ +Throw your mistemper'd weapons to the ground,\n\ +To know our further pleasure in this case,\n\ +To old Free-town, our common judgment-place.\n\ +Once more, on pain of death, all men depart." +for (var i = 0; i <4; i++) + plainText += plainText; +var md5Output = hex_md5(plainText); diff --git a/js/src/jit-test/tests/ion/invalidation/outofline.js b/js/src/jit-test/tests/ion/invalidation/outofline.js new file mode 100644 index 0000000000..17976d752b --- /dev/null +++ b/js/src/jit-test/tests/ion/invalidation/outofline.js @@ -0,0 +1,22 @@ +// Breaks with --ion -n. See bug 718122. + +function Foo() +{ } + +Foo.prototype.bar = function(){ + print("yes hello"); + return 5; +} + +var x = new Foo(); + +function f(x) { + // Enter Ion. + for (var i=0; i < 41; i++); + + // At this point we have no type information for the GetPropertyCache below. + // This causes the cache to be typed as Value. + x.bar(); +} + +f(x); diff --git a/js/src/jit-test/tests/ion/invalidation/recursive-invalidate.js b/js/src/jit-test/tests/ion/invalidation/recursive-invalidate.js new file mode 100644 index 0000000000..509a9992c4 --- /dev/null +++ b/js/src/jit-test/tests/ion/invalidation/recursive-invalidate.js @@ -0,0 +1,21 @@ +var causeOSI = true; + +function rec(x, self) { + if (x === 0 || x !== x) { + if (causeOSI) { + causeOSI = false; + self(NaN, self) + causeOSI = true; + } + return; + } + self(x - 1, self); +} + +// Use enough iterations to type infer the script. +causeOSI = false; +for (var i = 0; i < 20; ++i) + rec(1, rec); +causeOSI = true; + +rec(2, rec) diff --git a/js/src/jit-test/tests/ion/is-constructing.js b/js/src/jit-test/tests/ion/is-constructing.js new file mode 100644 index 0000000000..fc8abcbae4 --- /dev/null +++ b/js/src/jit-test/tests/ion/is-constructing.js @@ -0,0 +1,62 @@ +var isConstructing = getSelfHostedValue("_IsConstructing"); + +function testBasic() { + var f = function(expected) { + with(this) {}; // Don't inline. + assertEq(isConstructing(), expected); + }; + for (var i=0; i<40; i++) { + f(false); + new f(true); + } +} +testBasic(); + +function testGeneric() { + var f1 = function(expected) { + with(this) {}; + assertEq(isConstructing(), expected); + }; + var f2 = function(expected) { + assertEq(isConstructing(), expected); + } + var funs = [f1, f2]; + for (var i=0; i<40; i++) { + var f = funs[i % 2]; + f(false); + new f(true); + } +} +testGeneric(); + +function testArgsRectifier() { + var f = function(x) { + with(this) {}; + assertEq(isConstructing(), true); + }; + for (var i=0; i<40; i++) + new f(); +} +testArgsRectifier(); + +function testBailout() { + var f1 = function(x, expected) { + if (x > 20) { + bailout(); + assertEq(isConstructing(), expected); + } + }; + var f2 = function(x) { + return new f1(x, true); + }; + var f3 = function(x) { + return f1(x, false); + }; + for (var i=0; i<40; i++) { + f2(i); + f3(i); + } + for (var i=0; i<40; i++) + f1(i, false); +} +testBailout(); diff --git a/js/src/jit-test/tests/ion/isArray.js b/js/src/jit-test/tests/ion/isArray.js new file mode 100644 index 0000000000..db79122935 --- /dev/null +++ b/js/src/jit-test/tests/ion/isArray.js @@ -0,0 +1,47 @@ +function f() { + assertEq(Array.isArray(10), false); + assertEq(Array.isArray([]), true); + assertEq(Array.isArray(Math), false); + + var objs = [{}, []]; + for (var i=0; i<objs.length; i++) + assertEq(Array.isArray(objs[i]), i === 1); + var arr = [[], [], 1]; + for (var i=0; i<arr.length; i++) + assertEq(Array.isArray(arr[i]), i < 2); +} +f(); +f(); +f(); + +function testObjects() { + var arr = [{}, [1], Array.prototype, + new Proxy(this, {}), new Proxy([], {})]; + while (true) { + var arrays = 0; + for (var i = 0; i < arr.length; i++) { + if (Array.isArray(arr[i])) + arrays++; + } + assertEq(arrays, 3); + if (inIon()) + break; + } +} +testObjects(); + +function testValues() { + var arr = [1, {}, [1], Array.prototype, null, + new Proxy(this, {}), new Proxy([], {})]; + while (true) { + var arrays = 0; + for (var i = 0; i < arr.length; i++) { + if (Array.isArray(arr[i])) + arrays++; + } + assertEq(arrays, 3); + if (inIon()) + break; + } +} +testValues(); diff --git a/js/src/jit-test/tests/ion/known-class.js b/js/src/jit-test/tests/ion/known-class.js new file mode 100644 index 0000000000..61e6f2afe2 --- /dev/null +++ b/js/src/jit-test/tests/ion/known-class.js @@ -0,0 +1,121 @@ +var IsRegExpObject = getSelfHostedValue("IsRegExpObject"); +var IsCallable = getSelfHostedValue("IsCallable"); +var NewArrayIterator = getSelfHostedValue("NewArrayIterator"); +var GuardToArrayIterator = getSelfHostedValue("GuardToArrayIterator"); + +function array() { + var a = [0]; + assertEq(Array.isArray(a), true); + assertEq(typeof a, "object"); + assertEq(IsRegExpObject(a), false); + assertEq(IsCallable(a), false); +} + +function array2(x) { + var a; + if (x) { + a = [0]; + } else { + a = [1]; + } + assertEq(Array.isArray(a), true); + assertEq(typeof a, "object"); + assertEq(IsRegExpObject(a), false); + assertEq(IsCallable(a), false); +} + +function object() { + var o = {a: 1}; + assertEq(Array.isArray(o), false); + assertEq(typeof o, "object"); + assertEq(IsRegExpObject(o), false); + assertEq(IsCallable(o), false); +} + +function object2(x) { + var o; + if (x) { + o = {a: 1}; + } else { + o = {b: 1}; + } + assertEq(Array.isArray(o), false); + assertEq(typeof o, "object"); + assertEq(IsRegExpObject(o), false); + assertEq(IsCallable(o), false); +} + +function mixed(x) { + var o; + if (x) { + o = [1]; + } else { + o = {a: 1}; + } + assertEq(Array.isArray(o), x); + assertEq(typeof o, "object"); + assertEq(IsRegExpObject(o), false); + assertEq(IsCallable(o), false); +} + +function lambda() { + function f() {} + assertEq(Array.isArray(f), false); + assertEq(typeof f, "function"); + assertEq(IsRegExpObject(f), false); + assertEq(IsCallable(f), true); +} + +function arrow() { + var f = () => {}; + assertEq(Array.isArray(f), false); + assertEq(typeof f, "function"); + assertEq(IsRegExpObject(f), false); + assertEq(IsCallable(f), true); +} + +function regexp() { + var r = /a/; + assertEq(Array.isArray(r), false); + assertEq(typeof r, "object"); + assertEq(IsRegExpObject(r), true); + assertEq(IsCallable(r), false); +} + +function regexp2(x) { + var a; + if (x) { + a = /a/; + } else { + a = /b/; + } + assertEq(Array.isArray(a), false); + assertEq(typeof a, "object"); + assertEq(IsRegExpObject(a), true); + assertEq(IsCallable(a), false); +} + +function iterator() { + var i = NewArrayIterator(); + assertEq(Array.isArray(i), false); + assertEq(typeof i, "object"); + assertEq(IsRegExpObject(i), false); + assertEq(IsCallable(i), false); + assertEq(GuardToArrayIterator(i), i); +} + +var b = true; +for (var i = 0; i < 1e4; i++) { + array(); + array2(b); + object(); + object2(b); + mixed(b); + lambda(); + arrow(); + regexp() + regexp2(b); + iterator(); + + b = !b; +} diff --git a/js/src/jit-test/tests/ion/lambda.js b/js/src/jit-test/tests/ion/lambda.js new file mode 100644 index 0000000000..8960763e5a --- /dev/null +++ b/js/src/jit-test/tests/ion/lambda.js @@ -0,0 +1,25 @@ +function test1(i) { + var g1 = 20; + function g1() { + return 10; + } + assertEq(g1, 20); + + function g2(x) { + return x + 1; + } + return g2(i); +} +for (var i=0; i<100; i++) { + assertEq(test1(i), i + 1); +} + +var c = 0; +function test2(arr) { + for (var i=0; i<100; i++) { + arr.sort(function(a, b) { c += a + b; return 0; }); + } + return c; +} +test2([1, 2, 3]); +assertEq(c, 800); diff --git a/js/src/jit-test/tests/ion/lazyLink-bug1150783.js b/js/src/jit-test/tests/ion/lazyLink-bug1150783.js new file mode 100644 index 0000000000..518081a4fb --- /dev/null +++ b/js/src/jit-test/tests/ion/lazyLink-bug1150783.js @@ -0,0 +1,34 @@ +var path = ''; + +// trigger off-main-thread compilation +for (var i = 0; i < 11; i++) + path.substr(-1); + +// maybe link to the the result of the off-main-thread compilation. +function load(unsigned) { + if (unsigned) + path.substr(-1); +} + +(function(global, env) { + 'use asm'; + var load = env.load; + function _main() { + var $l1 = 0, $l2 = 0, $l3 = 0; + do { + load(); + $l1 = $l1 + 1 | 0; + } while (($l1 | 0) != 10); + load(1); + load(1); + do { + load(); + $l2 = $l2 + 1 | 0; + } while (($l2 | 0) != 1024); + while (($l3 | 0) < 10000) { + load(1); + $l3 = $l3 + 1 | 0; + } + } + return _main; +})({}, { 'load':load })(); diff --git a/js/src/jit-test/tests/ion/lexical-check-1.js b/js/src/jit-test/tests/ion/lexical-check-1.js new file mode 100644 index 0000000000..e1ba1baa17 --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-1.js @@ -0,0 +1,15 @@ +function f() { + const x = 42; + function g() { + var s = 0; + for (var i = 100; i--;) + s += x; + return s; + } + return g; +} + +var func = f(); +for (var i = 200; i--;) + assertEq(func(), 4200); + diff --git a/js/src/jit-test/tests/ion/lexical-check-2.js b/js/src/jit-test/tests/ion/lexical-check-2.js new file mode 100644 index 0000000000..30dbb67b97 --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-2.js @@ -0,0 +1,22 @@ +function f(i) { + if (i == 1500) + g(); + const x = 42; + function g() { + return x; + } + return g; +} + +var caught = false; +var i; +try { + for (i = 0; i < 2000; i++) + assertEq(f(i)(), 42); +} catch(e) { + assertEq(e instanceof ReferenceError, true); + assertEq(i, 1500); + caught = true; +} +assertEq(caught, true); + diff --git a/js/src/jit-test/tests/ion/lexical-check-3.js b/js/src/jit-test/tests/ion/lexical-check-3.js new file mode 100644 index 0000000000..5455202e80 --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-3.js @@ -0,0 +1,26 @@ +// |jit-test| skip-if: getBuildConfiguration()['arm64'] +// +// Test skipped on ARM64 due to bug 1546742. +function f() { + + function g(n) { + n = n|0; + var s = 0; + for (var i = 0; (i = i + 1 |0) < 1000;) { + s = s * i; + if (!n) { + s = x; + } + } + return s; + } + + return g; + let x; +} + +var func = f(); +var r; +for (var i = 0; i < 2000; i++) + r = func(i + 1); +assertEq(r, 0); diff --git a/js/src/jit-test/tests/ion/lexical-check-4.js b/js/src/jit-test/tests/ion/lexical-check-4.js new file mode 100644 index 0000000000..6812674e44 --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-4.js @@ -0,0 +1,15 @@ +var caught = false; +try { + (function() { + let x = (function f(y) { + if (y == 0) { + x + return + } + return f(y - 1) + })(3) + })() +} catch(e) { + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/ion/lexical-check-5.js b/js/src/jit-test/tests/ion/lexical-check-5.js new file mode 100644 index 0000000000..78b1ece661 --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-5.js @@ -0,0 +1,7 @@ +// |jit-test| error: ReferenceError + +{ + for (var i = 0; i < 100; i++) + a += i; + let a = 1; +} diff --git a/js/src/jit-test/tests/ion/lexical-check-6.js b/js/src/jit-test/tests/ion/lexical-check-6.js new file mode 100644 index 0000000000..5af7686aee --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-6.js @@ -0,0 +1,39 @@ +// This function uses UCE to test when the if branch is removed by +// IonMonkey. Some optimization such as Scalar Replacement are able to remove +// the scope chain, which can cause issues when the scope chain properties are +// not initialized properly. +var uceFault = function (i) { + if (i % 1500 == 0) { + uceFault = function (i) { return i % 1500 == 0; }; + } + return false; +}; + +function f(i) { + if (uceFault(i) || uceFault(i)) + g(); + const x = 42; + function g() { + return x; + } + return g; +} + +function loop() { + for (; i < 4000; i++) + assertEq(f(i)(), 42); +} + +var caught = 0; +var i = 1; +while (i < 4000) { + try { + loop(); + } catch(e) { + assertEq(e instanceof ReferenceError, true); + assertEq(i == 1500 || i == 3000, true); + caught += 1; + i++; + } +} +assertEq(caught, 2); diff --git a/js/src/jit-test/tests/ion/lookupswitch.js b/js/src/jit-test/tests/ion/lookupswitch.js new file mode 100644 index 0000000000..6e778d39ae --- /dev/null +++ b/js/src/jit-test/tests/ion/lookupswitch.js @@ -0,0 +1,3974 @@ +///////////////////////////////////////// +// This is a generated file! +// See jit-tests/etc/generate-lookupswitch-tests.js for the code +// that generated this code! +///////////////////////////////////////// + +///////////////////////////////////////// +// PRELUDE // +///////////////////////////////////////// + +// Avoid eager compilation of the global-scope. +try{} catch (x) {}; + +function ASSERT(cond, msg) { + assertEq(cond, true, msg); +} +function IsNull(x) { + return typeof x == "object" && x == null; +} +function IsNum(x) { + return typeof x == "number"; +} +function ArraysEqual(arr1, arr2) { + ASSERT(arr1.length == arr2.length, "Lengths not equal"); + for (var i = 0; i < arr1.length; i++) { + ASSERT(typeof arr1[i] == typeof arr2[i], "Types not equal for position " + i); + ASSERT(arr1[i] == arr2[i], "Values not equal for position " + i); + } +} +function InterpretSwitch(spec, input, outputArray) { + var foundMatch = undefined, foundDefault = undefined; + for (var i = 0; i < spec.length; i++) { + var caseSpec = spec[i], match = caseSpec.match; + if (IsNull(match)) { + foundDefault = i; + continue; + } else if (match === input) { + foundMatch = i; + break; + } + } + var matchI = IsNum(foundMatch) ? foundMatch : foundDefault; + if (IsNum(matchI)) { + for (var i = matchI; i < spec.length; i++) { + var caseSpec = spec[i], match = caseSpec.match, body = caseSpec.body, fallthrough = caseSpec.fallthrough; + if (!IsNull(body)) { + outputArray.push(body); + } + if (!fallthrough) { + break; + } + } + } +} +function RunTest(test) { + var inputs = test.INPUTS; + inputs.push("UNMATCHED_CASE"); + var spec = test.SPEC; + var results1 = []; + for (var i = 0; i < 80; i++) { + for (var j = 0; j < inputs.length; j++) { + test(inputs[j], results1); + } + } + var results2 = []; + for (var i = 0; i < 80; i++) { + for (var j = 0; j < inputs.length; j++) { + InterpretSwitch(spec, inputs[j], results2); + } + } + ArraysEqual(results1, results2); +} + +///////////////////////////////////////// +// TEST CASES // +///////////////////////////////////////// + +var TESTS = []; +function test_1(x, arr) { + switch(x) { + default: + case 'foo': + arr.push(777087170); + break; + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + } +} +test_1.INPUTS = ['foo', 'bar', 'zing']; +test_1.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":777087170,"fallthrough":false},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false}]; +TESTS.push(test_1); + +function test_2(x, arr) { + switch(x) { + case 'foo': + arr.push(777087170); + break; + default: + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + } +} +test_2.INPUTS = ['foo', 'bar', 'zing']; +test_2.SPEC = [{"match":"foo","body":777087170,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false}]; +TESTS.push(test_2); + +function test_3(x, arr) { + switch(x) { + case 'foo': + arr.push(777087170); + break; + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + default: + } +} +test_3.INPUTS = ['foo', 'bar', 'zing']; +test_3.SPEC = [{"match":"foo","body":777087170,"fallthrough":false},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_3); + +function test_4(x, arr) { + switch(x) { + default: + arr.push(633415567); + case 'foo': + arr.push(777087170); + break; + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + } +} +test_4.INPUTS = ['foo', 'bar', 'zing']; +test_4.SPEC = [{"match":null,"body":633415567,"fallthrough":true},{"match":"foo","body":777087170,"fallthrough":false},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false}]; +TESTS.push(test_4); + +function test_5(x, arr) { + switch(x) { + case 'foo': + arr.push(777087170); + break; + default: + arr.push(633415567); + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + } +} +test_5.INPUTS = ['foo', 'bar', 'zing']; +test_5.SPEC = [{"match":"foo","body":777087170,"fallthrough":false},{"match":null,"body":633415567,"fallthrough":true},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false}]; +TESTS.push(test_5); + +function test_6(x, arr) { + switch(x) { + case 'foo': + arr.push(777087170); + break; + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + default: + arr.push(633415567); + } +} +test_6.INPUTS = ['foo', 'bar', 'zing']; +test_6.SPEC = [{"match":"foo","body":777087170,"fallthrough":false},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false},{"match":null,"body":633415567,"fallthrough":true}]; +TESTS.push(test_6); + +function test_7(x, arr) { + switch(x) { + default: + arr.push('5zO^Qj'); + break; + case 'foo': + arr.push(777087170); + break; + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + } +} +test_7.INPUTS = ['foo', 'bar', 'zing']; +test_7.SPEC = [{"match":null,"body":"5zO^Qj","fallthrough":false},{"match":"foo","body":777087170,"fallthrough":false},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false}]; +TESTS.push(test_7); + +function test_8(x, arr) { + switch(x) { + case 'foo': + arr.push(777087170); + break; + default: + arr.push('5zO^Qj'); + break; + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + } +} +test_8.INPUTS = ['foo', 'bar', 'zing']; +test_8.SPEC = [{"match":"foo","body":777087170,"fallthrough":false},{"match":null,"body":"5zO^Qj","fallthrough":false},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false}]; +TESTS.push(test_8); + +function test_9(x, arr) { + switch(x) { + case 'foo': + arr.push(777087170); + break; + case 'bar': + arr.push(641037838); + break; + case 'zing': + arr.push(1652156613); + break; + default: + arr.push('5zO^Qj'); + break; + } +} +test_9.INPUTS = ['foo', 'bar', 'zing']; +test_9.SPEC = [{"match":"foo","body":777087170,"fallthrough":false},{"match":"bar","body":641037838,"fallthrough":false},{"match":"zing","body":1652156613,"fallthrough":false},{"match":null,"body":"5zO^Qj","fallthrough":false}]; +TESTS.push(test_9); + +function test_10(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + } +} +test_10.INPUTS = ['foo', 'bar', 'zing']; +test_10.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false}]; +TESTS.push(test_10); + +function test_11(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + } +} +test_11.INPUTS = ['foo', 'bar', 'zing']; +test_11.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false}]; +TESTS.push(test_11); + +function test_12(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + default: + } +} +test_12.INPUTS = ['foo', 'bar', 'zing']; +test_12.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_12); + +function test_13(x, arr) { + switch(x) { + default: + arr.push('M'); + case 'foo': + break; + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + } +} +test_13.INPUTS = ['foo', 'bar', 'zing']; +test_13.SPEC = [{"match":null,"body":"M","fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false}]; +TESTS.push(test_13); + +function test_14(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('M'); + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + } +} +test_14.INPUTS = ['foo', 'bar', 'zing']; +test_14.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"M","fallthrough":true},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false}]; +TESTS.push(test_14); + +function test_15(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + default: + arr.push('M'); + } +} +test_15.INPUTS = ['foo', 'bar', 'zing']; +test_15.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false},{"match":null,"body":"M","fallthrough":true}]; +TESTS.push(test_15); + +function test_16(x, arr) { + switch(x) { + default: + arr.push(1424069880); + break; + case 'foo': + break; + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + } +} +test_16.INPUTS = ['foo', 'bar', 'zing']; +test_16.SPEC = [{"match":null,"body":1424069880,"fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false}]; +TESTS.push(test_16); + +function test_17(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push(1424069880); + break; + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + } +} +test_17.INPUTS = ['foo', 'bar', 'zing']; +test_17.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":1424069880,"fallthrough":false},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false}]; +TESTS.push(test_17); + +function test_18(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push('c'); + break; + case 'zing': + arr.push(2008006064); + break; + default: + arr.push(1424069880); + break; + } +} +test_18.INPUTS = ['foo', 'bar', 'zing']; +test_18.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"c","fallthrough":false},{"match":"zing","body":2008006064,"fallthrough":false},{"match":null,"body":1424069880,"fallthrough":false}]; +TESTS.push(test_18); + +function test_19(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + } +} +test_19.INPUTS = ['foo', 'bar', 'zing']; +test_19.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false}]; +TESTS.push(test_19); + +function test_20(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + } +} +test_20.INPUTS = ['foo', 'bar', 'zing']; +test_20.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false}]; +TESTS.push(test_20); + +function test_21(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + default: + } +} +test_21.INPUTS = ['foo', 'bar', 'zing']; +test_21.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_21); + +function test_22(x, arr) { + switch(x) { + default: + arr.push(104770589); + case 'foo': + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + } +} +test_22.INPUTS = ['foo', 'bar', 'zing']; +test_22.SPEC = [{"match":null,"body":104770589,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false}]; +TESTS.push(test_22); + +function test_23(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(104770589); + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + } +} +test_23.INPUTS = ['foo', 'bar', 'zing']; +test_23.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":104770589,"fallthrough":true},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false}]; +TESTS.push(test_23); + +function test_24(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + default: + arr.push(104770589); + } +} +test_24.INPUTS = ['foo', 'bar', 'zing']; +test_24.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false},{"match":null,"body":104770589,"fallthrough":true}]; +TESTS.push(test_24); + +function test_25(x, arr) { + switch(x) { + default: + arr.push(304532507); + break; + case 'foo': + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + } +} +test_25.INPUTS = ['foo', 'bar', 'zing']; +test_25.SPEC = [{"match":null,"body":304532507,"fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false}]; +TESTS.push(test_25); + +function test_26(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(304532507); + break; + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + } +} +test_26.INPUTS = ['foo', 'bar', 'zing']; +test_26.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":304532507,"fallthrough":false},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false}]; +TESTS.push(test_26); + +function test_27(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push(1915689729); + break; + case 'zing': + arr.push(973913896); + break; + default: + arr.push(304532507); + break; + } +} +test_27.INPUTS = ['foo', 'bar', 'zing']; +test_27.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":1915689729,"fallthrough":false},{"match":"zing","body":973913896,"fallthrough":false},{"match":null,"body":304532507,"fallthrough":false}]; +TESTS.push(test_27); + +function test_28(x, arr) { + switch(x) { + default: + case 'foo': + arr.push(2116660419); + break; + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + } +} +test_28.INPUTS = ['foo', 'bar', 'zing']; +test_28.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":2116660419,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false}]; +TESTS.push(test_28); + +function test_29(x, arr) { + switch(x) { + case 'foo': + arr.push(2116660419); + break; + default: + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + } +} +test_29.INPUTS = ['foo', 'bar', 'zing']; +test_29.SPEC = [{"match":"foo","body":2116660419,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false}]; +TESTS.push(test_29); + +function test_30(x, arr) { + switch(x) { + case 'foo': + arr.push(2116660419); + break; + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + default: + } +} +test_30.INPUTS = ['foo', 'bar', 'zing']; +test_30.SPEC = [{"match":"foo","body":2116660419,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_30); + +function test_31(x, arr) { + switch(x) { + default: + arr.push(121730727); + case 'foo': + arr.push(2116660419); + break; + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + } +} +test_31.INPUTS = ['foo', 'bar', 'zing']; +test_31.SPEC = [{"match":null,"body":121730727,"fallthrough":true},{"match":"foo","body":2116660419,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false}]; +TESTS.push(test_31); + +function test_32(x, arr) { + switch(x) { + case 'foo': + arr.push(2116660419); + break; + default: + arr.push(121730727); + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + } +} +test_32.INPUTS = ['foo', 'bar', 'zing']; +test_32.SPEC = [{"match":"foo","body":2116660419,"fallthrough":false},{"match":null,"body":121730727,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false}]; +TESTS.push(test_32); + +function test_33(x, arr) { + switch(x) { + case 'foo': + arr.push(2116660419); + break; + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + default: + arr.push(121730727); + } +} +test_33.INPUTS = ['foo', 'bar', 'zing']; +test_33.SPEC = [{"match":"foo","body":2116660419,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false},{"match":null,"body":121730727,"fallthrough":true}]; +TESTS.push(test_33); + +function test_34(x, arr) { + switch(x) { + default: + arr.push(1614107154); + break; + case 'foo': + arr.push(2116660419); + break; + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + } +} +test_34.INPUTS = ['foo', 'bar', 'zing']; +test_34.SPEC = [{"match":null,"body":1614107154,"fallthrough":false},{"match":"foo","body":2116660419,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false}]; +TESTS.push(test_34); + +function test_35(x, arr) { + switch(x) { + case 'foo': + arr.push(2116660419); + break; + default: + arr.push(1614107154); + break; + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + } +} +test_35.INPUTS = ['foo', 'bar', 'zing']; +test_35.SPEC = [{"match":"foo","body":2116660419,"fallthrough":false},{"match":null,"body":1614107154,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false}]; +TESTS.push(test_35); + +function test_36(x, arr) { + switch(x) { + case 'foo': + arr.push(2116660419); + break; + case 'bar': + break; + case 'zing': + arr.push('FvxWZ'); + break; + default: + arr.push(1614107154); + break; + } +} +test_36.INPUTS = ['foo', 'bar', 'zing']; +test_36.SPEC = [{"match":"foo","body":2116660419,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"FvxWZ","fallthrough":false},{"match":null,"body":1614107154,"fallthrough":false}]; +TESTS.push(test_36); + +function test_37(x, arr) { + switch(x) { + default: + case 'foo': + arr.push('-=Z'); + break; + case 'bar': + case 'zing': + arr.push('R8f'); + break; + } +} +test_37.INPUTS = ['foo', 'bar', 'zing']; +test_37.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":"-=Z","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false}]; +TESTS.push(test_37); + +function test_38(x, arr) { + switch(x) { + case 'foo': + arr.push('-=Z'); + break; + default: + case 'bar': + case 'zing': + arr.push('R8f'); + break; + } +} +test_38.INPUTS = ['foo', 'bar', 'zing']; +test_38.SPEC = [{"match":"foo","body":"-=Z","fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false}]; +TESTS.push(test_38); + +function test_39(x, arr) { + switch(x) { + case 'foo': + arr.push('-=Z'); + break; + case 'bar': + case 'zing': + arr.push('R8f'); + break; + default: + } +} +test_39.INPUTS = ['foo', 'bar', 'zing']; +test_39.SPEC = [{"match":"foo","body":"-=Z","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_39); + +function test_40(x, arr) { + switch(x) { + default: + arr.push('XfrKO0'); + case 'foo': + arr.push('-=Z'); + break; + case 'bar': + case 'zing': + arr.push('R8f'); + break; + } +} +test_40.INPUTS = ['foo', 'bar', 'zing']; +test_40.SPEC = [{"match":null,"body":"XfrKO0","fallthrough":true},{"match":"foo","body":"-=Z","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false}]; +TESTS.push(test_40); + +function test_41(x, arr) { + switch(x) { + case 'foo': + arr.push('-=Z'); + break; + default: + arr.push('XfrKO0'); + case 'bar': + case 'zing': + arr.push('R8f'); + break; + } +} +test_41.INPUTS = ['foo', 'bar', 'zing']; +test_41.SPEC = [{"match":"foo","body":"-=Z","fallthrough":false},{"match":null,"body":"XfrKO0","fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false}]; +TESTS.push(test_41); + +function test_42(x, arr) { + switch(x) { + case 'foo': + arr.push('-=Z'); + break; + case 'bar': + case 'zing': + arr.push('R8f'); + break; + default: + arr.push('XfrKO0'); + } +} +test_42.INPUTS = ['foo', 'bar', 'zing']; +test_42.SPEC = [{"match":"foo","body":"-=Z","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false},{"match":null,"body":"XfrKO0","fallthrough":true}]; +TESTS.push(test_42); + +function test_43(x, arr) { + switch(x) { + default: + arr.push(465477587); + break; + case 'foo': + arr.push('-=Z'); + break; + case 'bar': + case 'zing': + arr.push('R8f'); + break; + } +} +test_43.INPUTS = ['foo', 'bar', 'zing']; +test_43.SPEC = [{"match":null,"body":465477587,"fallthrough":false},{"match":"foo","body":"-=Z","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false}]; +TESTS.push(test_43); + +function test_44(x, arr) { + switch(x) { + case 'foo': + arr.push('-=Z'); + break; + default: + arr.push(465477587); + break; + case 'bar': + case 'zing': + arr.push('R8f'); + break; + } +} +test_44.INPUTS = ['foo', 'bar', 'zing']; +test_44.SPEC = [{"match":"foo","body":"-=Z","fallthrough":false},{"match":null,"body":465477587,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false}]; +TESTS.push(test_44); + +function test_45(x, arr) { + switch(x) { + case 'foo': + arr.push('-=Z'); + break; + case 'bar': + case 'zing': + arr.push('R8f'); + break; + default: + arr.push(465477587); + break; + } +} +test_45.INPUTS = ['foo', 'bar', 'zing']; +test_45.SPEC = [{"match":"foo","body":"-=Z","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"R8f","fallthrough":false},{"match":null,"body":465477587,"fallthrough":false}]; +TESTS.push(test_45); + +function test_46(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + } +} +test_46.INPUTS = ['foo', 'bar', 'zing']; +test_46.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false}]; +TESTS.push(test_46); + +function test_47(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + } +} +test_47.INPUTS = ['foo', 'bar', 'zing']; +test_47.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false}]; +TESTS.push(test_47); + +function test_48(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + default: + } +} +test_48.INPUTS = ['foo', 'bar', 'zing']; +test_48.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_48); + +function test_49(x, arr) { + switch(x) { + default: + arr.push('{5J~&%)kV'); + case 'foo': + break; + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + } +} +test_49.INPUTS = ['foo', 'bar', 'zing']; +test_49.SPEC = [{"match":null,"body":"{5J~&%)kV","fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false}]; +TESTS.push(test_49); + +function test_50(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('{5J~&%)kV'); + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + } +} +test_50.INPUTS = ['foo', 'bar', 'zing']; +test_50.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"{5J~&%)kV","fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false}]; +TESTS.push(test_50); + +function test_51(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + default: + arr.push('{5J~&%)kV'); + } +} +test_51.INPUTS = ['foo', 'bar', 'zing']; +test_51.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false},{"match":null,"body":"{5J~&%)kV","fallthrough":true}]; +TESTS.push(test_51); + +function test_52(x, arr) { + switch(x) { + default: + arr.push('V^IbL'); + break; + case 'foo': + break; + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + } +} +test_52.INPUTS = ['foo', 'bar', 'zing']; +test_52.SPEC = [{"match":null,"body":"V^IbL","fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false}]; +TESTS.push(test_52); + +function test_53(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('V^IbL'); + break; + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + } +} +test_53.INPUTS = ['foo', 'bar', 'zing']; +test_53.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"V^IbL","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false}]; +TESTS.push(test_53); + +function test_54(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + arr.push('(0'); + break; + default: + arr.push('V^IbL'); + break; + } +} +test_54.INPUTS = ['foo', 'bar', 'zing']; +test_54.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"(0","fallthrough":false},{"match":null,"body":"V^IbL","fallthrough":false}]; +TESTS.push(test_54); + +function test_55(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + } +} +test_55.INPUTS = ['foo', 'bar', 'zing']; +test_55.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false}]; +TESTS.push(test_55); + +function test_56(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + } +} +test_56.INPUTS = ['foo', 'bar', 'zing']; +test_56.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false}]; +TESTS.push(test_56); + +function test_57(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + default: + } +} +test_57.INPUTS = ['foo', 'bar', 'zing']; +test_57.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_57); + +function test_58(x, arr) { + switch(x) { + default: + arr.push('K'); + case 'foo': + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + } +} +test_58.INPUTS = ['foo', 'bar', 'zing']; +test_58.SPEC = [{"match":null,"body":"K","fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false}]; +TESTS.push(test_58); + +function test_59(x, arr) { + switch(x) { + case 'foo': + default: + arr.push('K'); + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + } +} +test_59.INPUTS = ['foo', 'bar', 'zing']; +test_59.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":"K","fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false}]; +TESTS.push(test_59); + +function test_60(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + default: + arr.push('K'); + } +} +test_60.INPUTS = ['foo', 'bar', 'zing']; +test_60.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false},{"match":null,"body":"K","fallthrough":true}]; +TESTS.push(test_60); + +function test_61(x, arr) { + switch(x) { + default: + arr.push(129591787); + break; + case 'foo': + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + } +} +test_61.INPUTS = ['foo', 'bar', 'zing']; +test_61.SPEC = [{"match":null,"body":129591787,"fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false}]; +TESTS.push(test_61); + +function test_62(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(129591787); + break; + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + } +} +test_62.INPUTS = ['foo', 'bar', 'zing']; +test_62.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":129591787,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false}]; +TESTS.push(test_62); + +function test_63(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + arr.push('4'); + break; + default: + arr.push(129591787); + break; + } +} +test_63.INPUTS = ['foo', 'bar', 'zing']; +test_63.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":"4","fallthrough":false},{"match":null,"body":129591787,"fallthrough":false}]; +TESTS.push(test_63); + +function test_64(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + case 'zing': + arr.push(60518010); + break; + } +} +test_64.INPUTS = ['foo', 'bar', 'zing']; +test_64.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false}]; +TESTS.push(test_64); + +function test_65(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + case 'zing': + arr.push(60518010); + break; + } +} +test_65.INPUTS = ['foo', 'bar', 'zing']; +test_65.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false}]; +TESTS.push(test_65); + +function test_66(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + arr.push(60518010); + break; + default: + } +} +test_66.INPUTS = ['foo', 'bar', 'zing']; +test_66.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_66); + +function test_67(x, arr) { + switch(x) { + default: + arr.push('0]YO]}'); + case 'foo': + break; + case 'bar': + case 'zing': + arr.push(60518010); + break; + } +} +test_67.INPUTS = ['foo', 'bar', 'zing']; +test_67.SPEC = [{"match":null,"body":"0]YO]}","fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false}]; +TESTS.push(test_67); + +function test_68(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('0]YO]}'); + case 'bar': + case 'zing': + arr.push(60518010); + break; + } +} +test_68.INPUTS = ['foo', 'bar', 'zing']; +test_68.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"0]YO]}","fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false}]; +TESTS.push(test_68); + +function test_69(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + arr.push(60518010); + break; + default: + arr.push('0]YO]}'); + } +} +test_69.INPUTS = ['foo', 'bar', 'zing']; +test_69.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false},{"match":null,"body":"0]YO]}","fallthrough":true}]; +TESTS.push(test_69); + +function test_70(x, arr) { + switch(x) { + default: + arr.push(1222888797); + break; + case 'foo': + break; + case 'bar': + case 'zing': + arr.push(60518010); + break; + } +} +test_70.INPUTS = ['foo', 'bar', 'zing']; +test_70.SPEC = [{"match":null,"body":1222888797,"fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false}]; +TESTS.push(test_70); + +function test_71(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push(1222888797); + break; + case 'bar': + case 'zing': + arr.push(60518010); + break; + } +} +test_71.INPUTS = ['foo', 'bar', 'zing']; +test_71.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":1222888797,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false}]; +TESTS.push(test_71); + +function test_72(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + arr.push(60518010); + break; + default: + arr.push(1222888797); + break; + } +} +test_72.INPUTS = ['foo', 'bar', 'zing']; +test_72.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":60518010,"fallthrough":false},{"match":null,"body":1222888797,"fallthrough":false}]; +TESTS.push(test_72); + +function test_73(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + } +} +test_73.INPUTS = ['foo', 'bar', 'zing']; +test_73.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false}]; +TESTS.push(test_73); + +function test_74(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + } +} +test_74.INPUTS = ['foo', 'bar', 'zing']; +test_74.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false}]; +TESTS.push(test_74); + +function test_75(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + default: + } +} +test_75.INPUTS = ['foo', 'bar', 'zing']; +test_75.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_75); + +function test_76(x, arr) { + switch(x) { + default: + arr.push(1697959342); + case 'foo': + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + } +} +test_76.INPUTS = ['foo', 'bar', 'zing']; +test_76.SPEC = [{"match":null,"body":1697959342,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false}]; +TESTS.push(test_76); + +function test_77(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(1697959342); + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + } +} +test_77.INPUTS = ['foo', 'bar', 'zing']; +test_77.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":1697959342,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false}]; +TESTS.push(test_77); + +function test_78(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + default: + arr.push(1697959342); + } +} +test_78.INPUTS = ['foo', 'bar', 'zing']; +test_78.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false},{"match":null,"body":1697959342,"fallthrough":true}]; +TESTS.push(test_78); + +function test_79(x, arr) { + switch(x) { + default: + arr.push(2023306409); + break; + case 'foo': + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + } +} +test_79.INPUTS = ['foo', 'bar', 'zing']; +test_79.SPEC = [{"match":null,"body":2023306409,"fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false}]; +TESTS.push(test_79); + +function test_80(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(2023306409); + break; + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + } +} +test_80.INPUTS = ['foo', 'bar', 'zing']; +test_80.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":2023306409,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false}]; +TESTS.push(test_80); + +function test_81(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + arr.push('ku]^x'); + break; + default: + arr.push(2023306409); + break; + } +} +test_81.INPUTS = ['foo', 'bar', 'zing']; +test_81.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":"ku]^x","fallthrough":false},{"match":null,"body":2023306409,"fallthrough":false}]; +TESTS.push(test_81); + +function test_82(x, arr) { + switch(x) { + default: + case 'foo': + arr.push(588167318); + break; + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + } +} +test_82.INPUTS = ['foo', 'bar', 'zing']; +test_82.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":588167318,"fallthrough":false},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_82); + +function test_83(x, arr) { + switch(x) { + case 'foo': + arr.push(588167318); + break; + default: + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + } +} +test_83.INPUTS = ['foo', 'bar', 'zing']; +test_83.SPEC = [{"match":"foo","body":588167318,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_83); + +function test_84(x, arr) { + switch(x) { + case 'foo': + arr.push(588167318); + break; + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + default: + } +} +test_84.INPUTS = ['foo', 'bar', 'zing']; +test_84.SPEC = [{"match":"foo","body":588167318,"fallthrough":false},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_84); + +function test_85(x, arr) { + switch(x) { + default: + arr.push(1238869146); + case 'foo': + arr.push(588167318); + break; + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + } +} +test_85.INPUTS = ['foo', 'bar', 'zing']; +test_85.SPEC = [{"match":null,"body":1238869146,"fallthrough":true},{"match":"foo","body":588167318,"fallthrough":false},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_85); + +function test_86(x, arr) { + switch(x) { + case 'foo': + arr.push(588167318); + break; + default: + arr.push(1238869146); + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + } +} +test_86.INPUTS = ['foo', 'bar', 'zing']; +test_86.SPEC = [{"match":"foo","body":588167318,"fallthrough":false},{"match":null,"body":1238869146,"fallthrough":true},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_86); + +function test_87(x, arr) { + switch(x) { + case 'foo': + arr.push(588167318); + break; + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + default: + arr.push(1238869146); + } +} +test_87.INPUTS = ['foo', 'bar', 'zing']; +test_87.SPEC = [{"match":"foo","body":588167318,"fallthrough":false},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":1238869146,"fallthrough":true}]; +TESTS.push(test_87); + +function test_88(x, arr) { + switch(x) { + default: + arr.push('pOh#'); + break; + case 'foo': + arr.push(588167318); + break; + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + } +} +test_88.INPUTS = ['foo', 'bar', 'zing']; +test_88.SPEC = [{"match":null,"body":"pOh#","fallthrough":false},{"match":"foo","body":588167318,"fallthrough":false},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_88); + +function test_89(x, arr) { + switch(x) { + case 'foo': + arr.push(588167318); + break; + default: + arr.push('pOh#'); + break; + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + } +} +test_89.INPUTS = ['foo', 'bar', 'zing']; +test_89.SPEC = [{"match":"foo","body":588167318,"fallthrough":false},{"match":null,"body":"pOh#","fallthrough":false},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_89); + +function test_90(x, arr) { + switch(x) { + case 'foo': + arr.push(588167318); + break; + case 'bar': + arr.push(663884613); + break; + case 'zing': + break; + default: + arr.push('pOh#'); + break; + } +} +test_90.INPUTS = ['foo', 'bar', 'zing']; +test_90.SPEC = [{"match":"foo","body":588167318,"fallthrough":false},{"match":"bar","body":663884613,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"pOh#","fallthrough":false}]; +TESTS.push(test_90); + +function test_91(x, arr) { + switch(x) { + default: + case 'foo': + arr.push('Z!I#t'); + break; + case 'bar': + arr.push('D'); + break; + case 'zing': + } +} +test_91.INPUTS = ['foo', 'bar', 'zing']; +test_91.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_91); + +function test_92(x, arr) { + switch(x) { + case 'foo': + arr.push('Z!I#t'); + break; + default: + case 'bar': + arr.push('D'); + break; + case 'zing': + } +} +test_92.INPUTS = ['foo', 'bar', 'zing']; +test_92.SPEC = [{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_92); + +function test_93(x, arr) { + switch(x) { + case 'foo': + arr.push('Z!I#t'); + break; + case 'bar': + arr.push('D'); + break; + case 'zing': + default: + } +} +test_93.INPUTS = ['foo', 'bar', 'zing']; +test_93.SPEC = [{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_93); + +function test_94(x, arr) { + switch(x) { + default: + arr.push(63474909); + case 'foo': + arr.push('Z!I#t'); + break; + case 'bar': + arr.push('D'); + break; + case 'zing': + } +} +test_94.INPUTS = ['foo', 'bar', 'zing']; +test_94.SPEC = [{"match":null,"body":63474909,"fallthrough":true},{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_94); + +function test_95(x, arr) { + switch(x) { + case 'foo': + arr.push('Z!I#t'); + break; + default: + arr.push(63474909); + case 'bar': + arr.push('D'); + break; + case 'zing': + } +} +test_95.INPUTS = ['foo', 'bar', 'zing']; +test_95.SPEC = [{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":null,"body":63474909,"fallthrough":true},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_95); + +function test_96(x, arr) { + switch(x) { + case 'foo': + arr.push('Z!I#t'); + break; + case 'bar': + arr.push('D'); + break; + case 'zing': + default: + arr.push(63474909); + } +} +test_96.INPUTS = ['foo', 'bar', 'zing']; +test_96.SPEC = [{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":63474909,"fallthrough":true}]; +TESTS.push(test_96); + +function test_97(x, arr) { + switch(x) { + default: + arr.push(1165220694); + break; + case 'foo': + arr.push('Z!I#t'); + break; + case 'bar': + arr.push('D'); + break; + case 'zing': + } +} +test_97.INPUTS = ['foo', 'bar', 'zing']; +test_97.SPEC = [{"match":null,"body":1165220694,"fallthrough":false},{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_97); + +function test_98(x, arr) { + switch(x) { + case 'foo': + arr.push('Z!I#t'); + break; + default: + arr.push(1165220694); + break; + case 'bar': + arr.push('D'); + break; + case 'zing': + } +} +test_98.INPUTS = ['foo', 'bar', 'zing']; +test_98.SPEC = [{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":null,"body":1165220694,"fallthrough":false},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_98); + +function test_99(x, arr) { + switch(x) { + case 'foo': + arr.push('Z!I#t'); + break; + case 'bar': + arr.push('D'); + break; + case 'zing': + default: + arr.push(1165220694); + break; + } +} +test_99.INPUTS = ['foo', 'bar', 'zing']; +test_99.SPEC = [{"match":"foo","body":"Z!I#t","fallthrough":false},{"match":"bar","body":"D","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":1165220694,"fallthrough":false}]; +TESTS.push(test_99); + +function test_100(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + } +} +test_100.INPUTS = ['foo', 'bar', 'zing']; +test_100.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_100); + +function test_101(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + } +} +test_101.INPUTS = ['foo', 'bar', 'zing']; +test_101.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_101); + +function test_102(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + default: + } +} +test_102.INPUTS = ['foo', 'bar', 'zing']; +test_102.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_102); + +function test_103(x, arr) { + switch(x) { + default: + arr.push('*8ZYmVI($X'); + case 'foo': + break; + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + } +} +test_103.INPUTS = ['foo', 'bar', 'zing']; +test_103.SPEC = [{"match":null,"body":"*8ZYmVI($X","fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_103); + +function test_104(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('*8ZYmVI($X'); + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + } +} +test_104.INPUTS = ['foo', 'bar', 'zing']; +test_104.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"*8ZYmVI($X","fallthrough":true},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_104); + +function test_105(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + default: + arr.push('*8ZYmVI($X'); + } +} +test_105.INPUTS = ['foo', 'bar', 'zing']; +test_105.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"*8ZYmVI($X","fallthrough":true}]; +TESTS.push(test_105); + +function test_106(x, arr) { + switch(x) { + default: + arr.push(207183901); + break; + case 'foo': + break; + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + } +} +test_106.INPUTS = ['foo', 'bar', 'zing']; +test_106.SPEC = [{"match":null,"body":207183901,"fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_106); + +function test_107(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push(207183901); + break; + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + } +} +test_107.INPUTS = ['foo', 'bar', 'zing']; +test_107.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":207183901,"fallthrough":false},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_107); + +function test_108(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push(1994756408); + break; + case 'zing': + break; + default: + arr.push(207183901); + break; + } +} +test_108.INPUTS = ['foo', 'bar', 'zing']; +test_108.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":1994756408,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":207183901,"fallthrough":false}]; +TESTS.push(test_108); + +function test_109(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + } +} +test_109.INPUTS = ['foo', 'bar', 'zing']; +test_109.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_109); + +function test_110(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + } +} +test_110.INPUTS = ['foo', 'bar', 'zing']; +test_110.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_110); + +function test_111(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + default: + } +} +test_111.INPUTS = ['foo', 'bar', 'zing']; +test_111.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_111); + +function test_112(x, arr) { + switch(x) { + default: + arr.push('04mJy'); + case 'foo': + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + } +} +test_112.INPUTS = ['foo', 'bar', 'zing']; +test_112.SPEC = [{"match":null,"body":"04mJy","fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_112); + +function test_113(x, arr) { + switch(x) { + case 'foo': + default: + arr.push('04mJy'); + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + } +} +test_113.INPUTS = ['foo', 'bar', 'zing']; +test_113.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":"04mJy","fallthrough":true},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_113); + +function test_114(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + default: + arr.push('04mJy'); + } +} +test_114.INPUTS = ['foo', 'bar', 'zing']; +test_114.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"04mJy","fallthrough":true}]; +TESTS.push(test_114); + +function test_115(x, arr) { + switch(x) { + default: + arr.push('0NgLbYKr~c'); + break; + case 'foo': + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + } +} +test_115.INPUTS = ['foo', 'bar', 'zing']; +test_115.SPEC = [{"match":null,"body":"0NgLbYKr~c","fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_115); + +function test_116(x, arr) { + switch(x) { + case 'foo': + default: + arr.push('0NgLbYKr~c'); + break; + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + } +} +test_116.INPUTS = ['foo', 'bar', 'zing']; +test_116.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":"0NgLbYKr~c","fallthrough":false},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_116); + +function test_117(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push('YJQk'); + break; + case 'zing': + break; + default: + arr.push('0NgLbYKr~c'); + break; + } +} +test_117.INPUTS = ['foo', 'bar', 'zing']; +test_117.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"YJQk","fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"0NgLbYKr~c","fallthrough":false}]; +TESTS.push(test_117); + +function test_118(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + } +} +test_118.INPUTS = ['foo', 'bar', 'zing']; +test_118.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_118); + +function test_119(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + } +} +test_119.INPUTS = ['foo', 'bar', 'zing']; +test_119.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_119); + +function test_120(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + default: + } +} +test_120.INPUTS = ['foo', 'bar', 'zing']; +test_120.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_120); + +function test_121(x, arr) { + switch(x) { + default: + arr.push('Y'); + case 'foo': + break; + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + } +} +test_121.INPUTS = ['foo', 'bar', 'zing']; +test_121.SPEC = [{"match":null,"body":"Y","fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_121); + +function test_122(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('Y'); + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + } +} +test_122.INPUTS = ['foo', 'bar', 'zing']; +test_122.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"Y","fallthrough":true},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_122); + +function test_123(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + default: + arr.push('Y'); + } +} +test_123.INPUTS = ['foo', 'bar', 'zing']; +test_123.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"Y","fallthrough":true}]; +TESTS.push(test_123); + +function test_124(x, arr) { + switch(x) { + default: + arr.push(279382281); + break; + case 'foo': + break; + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + } +} +test_124.INPUTS = ['foo', 'bar', 'zing']; +test_124.SPEC = [{"match":null,"body":279382281,"fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_124); + +function test_125(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push(279382281); + break; + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + } +} +test_125.INPUTS = ['foo', 'bar', 'zing']; +test_125.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":279382281,"fallthrough":false},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_125); + +function test_126(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + arr.push('[^U}J^z'); + break; + case 'zing': + default: + arr.push(279382281); + break; + } +} +test_126.INPUTS = ['foo', 'bar', 'zing']; +test_126.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":"[^U}J^z","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":279382281,"fallthrough":false}]; +TESTS.push(test_126); + +function test_127(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + } +} +test_127.INPUTS = ['foo', 'bar', 'zing']; +test_127.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_127); + +function test_128(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + } +} +test_128.INPUTS = ['foo', 'bar', 'zing']; +test_128.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_128); + +function test_129(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + default: + } +} +test_129.INPUTS = ['foo', 'bar', 'zing']; +test_129.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_129); + +function test_130(x, arr) { + switch(x) { + default: + arr.push(282691036); + case 'foo': + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + } +} +test_130.INPUTS = ['foo', 'bar', 'zing']; +test_130.SPEC = [{"match":null,"body":282691036,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_130); + +function test_131(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(282691036); + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + } +} +test_131.INPUTS = ['foo', 'bar', 'zing']; +test_131.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":282691036,"fallthrough":true},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_131); + +function test_132(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + default: + arr.push(282691036); + } +} +test_132.INPUTS = ['foo', 'bar', 'zing']; +test_132.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":282691036,"fallthrough":true}]; +TESTS.push(test_132); + +function test_133(x, arr) { + switch(x) { + default: + arr.push('C^kPR'); + break; + case 'foo': + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + } +} +test_133.INPUTS = ['foo', 'bar', 'zing']; +test_133.SPEC = [{"match":null,"body":"C^kPR","fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_133); + +function test_134(x, arr) { + switch(x) { + case 'foo': + default: + arr.push('C^kPR'); + break; + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + } +} +test_134.INPUTS = ['foo', 'bar', 'zing']; +test_134.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":"C^kPR","fallthrough":false},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_134); + +function test_135(x, arr) { + switch(x) { + case 'foo': + case 'bar': + arr.push('7+leA1'); + break; + case 'zing': + default: + arr.push('C^kPR'); + break; + } +} +test_135.INPUTS = ['foo', 'bar', 'zing']; +test_135.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":"7+leA1","fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"C^kPR","fallthrough":false}]; +TESTS.push(test_135); + +function test_136(x, arr) { + switch(x) { + default: + case 'foo': + arr.push(1580091060); + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_136.INPUTS = ['foo', 'bar', 'zing']; +test_136.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":1580091060,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_136); + +function test_137(x, arr) { + switch(x) { + case 'foo': + arr.push(1580091060); + break; + default: + case 'bar': + break; + case 'zing': + break; + } +} +test_137.INPUTS = ['foo', 'bar', 'zing']; +test_137.SPEC = [{"match":"foo","body":1580091060,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_137); + +function test_138(x, arr) { + switch(x) { + case 'foo': + arr.push(1580091060); + break; + case 'bar': + break; + case 'zing': + break; + default: + } +} +test_138.INPUTS = ['foo', 'bar', 'zing']; +test_138.SPEC = [{"match":"foo","body":1580091060,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_138); + +function test_139(x, arr) { + switch(x) { + default: + arr.push(1822221944); + case 'foo': + arr.push(1580091060); + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_139.INPUTS = ['foo', 'bar', 'zing']; +test_139.SPEC = [{"match":null,"body":1822221944,"fallthrough":true},{"match":"foo","body":1580091060,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_139); + +function test_140(x, arr) { + switch(x) { + case 'foo': + arr.push(1580091060); + break; + default: + arr.push(1822221944); + case 'bar': + break; + case 'zing': + break; + } +} +test_140.INPUTS = ['foo', 'bar', 'zing']; +test_140.SPEC = [{"match":"foo","body":1580091060,"fallthrough":false},{"match":null,"body":1822221944,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_140); + +function test_141(x, arr) { + switch(x) { + case 'foo': + arr.push(1580091060); + break; + case 'bar': + break; + case 'zing': + break; + default: + arr.push(1822221944); + } +} +test_141.INPUTS = ['foo', 'bar', 'zing']; +test_141.SPEC = [{"match":"foo","body":1580091060,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":1822221944,"fallthrough":true}]; +TESTS.push(test_141); + +function test_142(x, arr) { + switch(x) { + default: + arr.push(1855786158); + break; + case 'foo': + arr.push(1580091060); + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_142.INPUTS = ['foo', 'bar', 'zing']; +test_142.SPEC = [{"match":null,"body":1855786158,"fallthrough":false},{"match":"foo","body":1580091060,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_142); + +function test_143(x, arr) { + switch(x) { + case 'foo': + arr.push(1580091060); + break; + default: + arr.push(1855786158); + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_143.INPUTS = ['foo', 'bar', 'zing']; +test_143.SPEC = [{"match":"foo","body":1580091060,"fallthrough":false},{"match":null,"body":1855786158,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_143); + +function test_144(x, arr) { + switch(x) { + case 'foo': + arr.push(1580091060); + break; + case 'bar': + break; + case 'zing': + break; + default: + arr.push(1855786158); + break; + } +} +test_144.INPUTS = ['foo', 'bar', 'zing']; +test_144.SPEC = [{"match":"foo","body":1580091060,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":1855786158,"fallthrough":false}]; +TESTS.push(test_144); + +function test_145(x, arr) { + switch(x) { + default: + case 'foo': + arr.push('XO'); + break; + case 'bar': + case 'zing': + break; + } +} +test_145.INPUTS = ['foo', 'bar', 'zing']; +test_145.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":"XO","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_145); + +function test_146(x, arr) { + switch(x) { + case 'foo': + arr.push('XO'); + break; + default: + case 'bar': + case 'zing': + break; + } +} +test_146.INPUTS = ['foo', 'bar', 'zing']; +test_146.SPEC = [{"match":"foo","body":"XO","fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_146); + +function test_147(x, arr) { + switch(x) { + case 'foo': + arr.push('XO'); + break; + case 'bar': + case 'zing': + break; + default: + } +} +test_147.INPUTS = ['foo', 'bar', 'zing']; +test_147.SPEC = [{"match":"foo","body":"XO","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_147); + +function test_148(x, arr) { + switch(x) { + default: + arr.push('L'); + case 'foo': + arr.push('XO'); + break; + case 'bar': + case 'zing': + break; + } +} +test_148.INPUTS = ['foo', 'bar', 'zing']; +test_148.SPEC = [{"match":null,"body":"L","fallthrough":true},{"match":"foo","body":"XO","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_148); + +function test_149(x, arr) { + switch(x) { + case 'foo': + arr.push('XO'); + break; + default: + arr.push('L'); + case 'bar': + case 'zing': + break; + } +} +test_149.INPUTS = ['foo', 'bar', 'zing']; +test_149.SPEC = [{"match":"foo","body":"XO","fallthrough":false},{"match":null,"body":"L","fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_149); + +function test_150(x, arr) { + switch(x) { + case 'foo': + arr.push('XO'); + break; + case 'bar': + case 'zing': + break; + default: + arr.push('L'); + } +} +test_150.INPUTS = ['foo', 'bar', 'zing']; +test_150.SPEC = [{"match":"foo","body":"XO","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"L","fallthrough":true}]; +TESTS.push(test_150); + +function test_151(x, arr) { + switch(x) { + default: + arr.push(1118900933); + break; + case 'foo': + arr.push('XO'); + break; + case 'bar': + case 'zing': + break; + } +} +test_151.INPUTS = ['foo', 'bar', 'zing']; +test_151.SPEC = [{"match":null,"body":1118900933,"fallthrough":false},{"match":"foo","body":"XO","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_151); + +function test_152(x, arr) { + switch(x) { + case 'foo': + arr.push('XO'); + break; + default: + arr.push(1118900933); + break; + case 'bar': + case 'zing': + break; + } +} +test_152.INPUTS = ['foo', 'bar', 'zing']; +test_152.SPEC = [{"match":"foo","body":"XO","fallthrough":false},{"match":null,"body":1118900933,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_152); + +function test_153(x, arr) { + switch(x) { + case 'foo': + arr.push('XO'); + break; + case 'bar': + case 'zing': + break; + default: + arr.push(1118900933); + break; + } +} +test_153.INPUTS = ['foo', 'bar', 'zing']; +test_153.SPEC = [{"match":"foo","body":"XO","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":1118900933,"fallthrough":false}]; +TESTS.push(test_153); + +function test_154(x, arr) { + switch(x) { + default: + case 'foo': + arr.push('H@'); + break; + case 'bar': + break; + case 'zing': + } +} +test_154.INPUTS = ['foo', 'bar', 'zing']; +test_154.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":"H@","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_154); + +function test_155(x, arr) { + switch(x) { + case 'foo': + arr.push('H@'); + break; + default: + case 'bar': + break; + case 'zing': + } +} +test_155.INPUTS = ['foo', 'bar', 'zing']; +test_155.SPEC = [{"match":"foo","body":"H@","fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_155); + +function test_156(x, arr) { + switch(x) { + case 'foo': + arr.push('H@'); + break; + case 'bar': + break; + case 'zing': + default: + } +} +test_156.INPUTS = ['foo', 'bar', 'zing']; +test_156.SPEC = [{"match":"foo","body":"H@","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_156); + +function test_157(x, arr) { + switch(x) { + default: + arr.push('f8n'); + case 'foo': + arr.push('H@'); + break; + case 'bar': + break; + case 'zing': + } +} +test_157.INPUTS = ['foo', 'bar', 'zing']; +test_157.SPEC = [{"match":null,"body":"f8n","fallthrough":true},{"match":"foo","body":"H@","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_157); + +function test_158(x, arr) { + switch(x) { + case 'foo': + arr.push('H@'); + break; + default: + arr.push('f8n'); + case 'bar': + break; + case 'zing': + } +} +test_158.INPUTS = ['foo', 'bar', 'zing']; +test_158.SPEC = [{"match":"foo","body":"H@","fallthrough":false},{"match":null,"body":"f8n","fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_158); + +function test_159(x, arr) { + switch(x) { + case 'foo': + arr.push('H@'); + break; + case 'bar': + break; + case 'zing': + default: + arr.push('f8n'); + } +} +test_159.INPUTS = ['foo', 'bar', 'zing']; +test_159.SPEC = [{"match":"foo","body":"H@","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"f8n","fallthrough":true}]; +TESTS.push(test_159); + +function test_160(x, arr) { + switch(x) { + default: + arr.push('4rg'); + break; + case 'foo': + arr.push('H@'); + break; + case 'bar': + break; + case 'zing': + } +} +test_160.INPUTS = ['foo', 'bar', 'zing']; +test_160.SPEC = [{"match":null,"body":"4rg","fallthrough":false},{"match":"foo","body":"H@","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_160); + +function test_161(x, arr) { + switch(x) { + case 'foo': + arr.push('H@'); + break; + default: + arr.push('4rg'); + break; + case 'bar': + break; + case 'zing': + } +} +test_161.INPUTS = ['foo', 'bar', 'zing']; +test_161.SPEC = [{"match":"foo","body":"H@","fallthrough":false},{"match":null,"body":"4rg","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_161); + +function test_162(x, arr) { + switch(x) { + case 'foo': + arr.push('H@'); + break; + case 'bar': + break; + case 'zing': + default: + arr.push('4rg'); + break; + } +} +test_162.INPUTS = ['foo', 'bar', 'zing']; +test_162.SPEC = [{"match":"foo","body":"H@","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"4rg","fallthrough":false}]; +TESTS.push(test_162); + +function test_163(x, arr) { + switch(x) { + default: + case 'foo': + arr.push(1921603085); + break; + case 'bar': + case 'zing': + } +} +test_163.INPUTS = ['foo', 'bar', 'zing']; +test_163.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":1921603085,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_163); + +function test_164(x, arr) { + switch(x) { + case 'foo': + arr.push(1921603085); + break; + default: + case 'bar': + case 'zing': + } +} +test_164.INPUTS = ['foo', 'bar', 'zing']; +test_164.SPEC = [{"match":"foo","body":1921603085,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_164); + +function test_165(x, arr) { + switch(x) { + case 'foo': + arr.push(1921603085); + break; + case 'bar': + case 'zing': + default: + } +} +test_165.INPUTS = ['foo', 'bar', 'zing']; +test_165.SPEC = [{"match":"foo","body":1921603085,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_165); + +function test_166(x, arr) { + switch(x) { + default: + arr.push(2201436); + case 'foo': + arr.push(1921603085); + break; + case 'bar': + case 'zing': + } +} +test_166.INPUTS = ['foo', 'bar', 'zing']; +test_166.SPEC = [{"match":null,"body":2201436,"fallthrough":true},{"match":"foo","body":1921603085,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_166); + +function test_167(x, arr) { + switch(x) { + case 'foo': + arr.push(1921603085); + break; + default: + arr.push(2201436); + case 'bar': + case 'zing': + } +} +test_167.INPUTS = ['foo', 'bar', 'zing']; +test_167.SPEC = [{"match":"foo","body":1921603085,"fallthrough":false},{"match":null,"body":2201436,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_167); + +function test_168(x, arr) { + switch(x) { + case 'foo': + arr.push(1921603085); + break; + case 'bar': + case 'zing': + default: + arr.push(2201436); + } +} +test_168.INPUTS = ['foo', 'bar', 'zing']; +test_168.SPEC = [{"match":"foo","body":1921603085,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":2201436,"fallthrough":true}]; +TESTS.push(test_168); + +function test_169(x, arr) { + switch(x) { + default: + arr.push('(vPssM{'); + break; + case 'foo': + arr.push(1921603085); + break; + case 'bar': + case 'zing': + } +} +test_169.INPUTS = ['foo', 'bar', 'zing']; +test_169.SPEC = [{"match":null,"body":"(vPssM{","fallthrough":false},{"match":"foo","body":1921603085,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_169); + +function test_170(x, arr) { + switch(x) { + case 'foo': + arr.push(1921603085); + break; + default: + arr.push('(vPssM{'); + break; + case 'bar': + case 'zing': + } +} +test_170.INPUTS = ['foo', 'bar', 'zing']; +test_170.SPEC = [{"match":"foo","body":1921603085,"fallthrough":false},{"match":null,"body":"(vPssM{","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_170); + +function test_171(x, arr) { + switch(x) { + case 'foo': + arr.push(1921603085); + break; + case 'bar': + case 'zing': + default: + arr.push('(vPssM{'); + break; + } +} +test_171.INPUTS = ['foo', 'bar', 'zing']; +test_171.SPEC = [{"match":"foo","body":1921603085,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"(vPssM{","fallthrough":false}]; +TESTS.push(test_171); + +function test_172(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_172.INPUTS = ['foo', 'bar', 'zing']; +test_172.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_172); + +function test_173(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + break; + case 'zing': + break; + } +} +test_173.INPUTS = ['foo', 'bar', 'zing']; +test_173.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_173); + +function test_174(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + break; + default: + } +} +test_174.INPUTS = ['foo', 'bar', 'zing']; +test_174.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_174); + +function test_175(x, arr) { + switch(x) { + default: + arr.push('y'); + case 'foo': + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_175.INPUTS = ['foo', 'bar', 'zing']; +test_175.SPEC = [{"match":null,"body":"y","fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_175); + +function test_176(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('y'); + case 'bar': + break; + case 'zing': + break; + } +} +test_176.INPUTS = ['foo', 'bar', 'zing']; +test_176.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"y","fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_176); + +function test_177(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + break; + default: + arr.push('y'); + } +} +test_177.INPUTS = ['foo', 'bar', 'zing']; +test_177.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"y","fallthrough":true}]; +TESTS.push(test_177); + +function test_178(x, arr) { + switch(x) { + default: + arr.push('H'); + break; + case 'foo': + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_178.INPUTS = ['foo', 'bar', 'zing']; +test_178.SPEC = [{"match":null,"body":"H","fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_178); + +function test_179(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('H'); + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_179.INPUTS = ['foo', 'bar', 'zing']; +test_179.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"H","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_179); + +function test_180(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + break; + default: + arr.push('H'); + break; + } +} +test_180.INPUTS = ['foo', 'bar', 'zing']; +test_180.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"H","fallthrough":false}]; +TESTS.push(test_180); + +function test_181(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + break; + case 'zing': + break; + } +} +test_181.INPUTS = ['foo', 'bar', 'zing']; +test_181.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_181); + +function test_182(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + break; + case 'zing': + break; + } +} +test_182.INPUTS = ['foo', 'bar', 'zing']; +test_182.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_182); + +function test_183(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + break; + default: + } +} +test_183.INPUTS = ['foo', 'bar', 'zing']; +test_183.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_183); + +function test_184(x, arr) { + switch(x) { + default: + arr.push('0vM}'); + case 'foo': + case 'bar': + break; + case 'zing': + break; + } +} +test_184.INPUTS = ['foo', 'bar', 'zing']; +test_184.SPEC = [{"match":null,"body":"0vM}","fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_184); + +function test_185(x, arr) { + switch(x) { + case 'foo': + default: + arr.push('0vM}'); + case 'bar': + break; + case 'zing': + break; + } +} +test_185.INPUTS = ['foo', 'bar', 'zing']; +test_185.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":"0vM}","fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_185); + +function test_186(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + break; + default: + arr.push('0vM}'); + } +} +test_186.INPUTS = ['foo', 'bar', 'zing']; +test_186.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"0vM}","fallthrough":true}]; +TESTS.push(test_186); + +function test_187(x, arr) { + switch(x) { + default: + arr.push('jn~d(x'); + break; + case 'foo': + case 'bar': + break; + case 'zing': + break; + } +} +test_187.INPUTS = ['foo', 'bar', 'zing']; +test_187.SPEC = [{"match":null,"body":"jn~d(x","fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_187); + +function test_188(x, arr) { + switch(x) { + case 'foo': + default: + arr.push('jn~d(x'); + break; + case 'bar': + break; + case 'zing': + break; + } +} +test_188.INPUTS = ['foo', 'bar', 'zing']; +test_188.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":"jn~d(x","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_188); + +function test_189(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + break; + default: + arr.push('jn~d(x'); + break; + } +} +test_189.INPUTS = ['foo', 'bar', 'zing']; +test_189.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"jn~d(x","fallthrough":false}]; +TESTS.push(test_189); + +function test_190(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + case 'zing': + break; + } +} +test_190.INPUTS = ['foo', 'bar', 'zing']; +test_190.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_190); + +function test_191(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + case 'zing': + break; + } +} +test_191.INPUTS = ['foo', 'bar', 'zing']; +test_191.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_191); + +function test_192(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + break; + default: + } +} +test_192.INPUTS = ['foo', 'bar', 'zing']; +test_192.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_192); + +function test_193(x, arr) { + switch(x) { + default: + arr.push('['); + case 'foo': + break; + case 'bar': + case 'zing': + break; + } +} +test_193.INPUTS = ['foo', 'bar', 'zing']; +test_193.SPEC = [{"match":null,"body":"[","fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_193); + +function test_194(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('['); + case 'bar': + case 'zing': + break; + } +} +test_194.INPUTS = ['foo', 'bar', 'zing']; +test_194.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"[","fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_194); + +function test_195(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + break; + default: + arr.push('['); + } +} +test_195.INPUTS = ['foo', 'bar', 'zing']; +test_195.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"[","fallthrough":true}]; +TESTS.push(test_195); + +function test_196(x, arr) { + switch(x) { + default: + arr.push('3DbGY'); + break; + case 'foo': + break; + case 'bar': + case 'zing': + break; + } +} +test_196.INPUTS = ['foo', 'bar', 'zing']; +test_196.SPEC = [{"match":null,"body":"3DbGY","fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_196); + +function test_197(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('3DbGY'); + break; + case 'bar': + case 'zing': + break; + } +} +test_197.INPUTS = ['foo', 'bar', 'zing']; +test_197.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"3DbGY","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_197); + +function test_198(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + break; + default: + arr.push('3DbGY'); + break; + } +} +test_198.INPUTS = ['foo', 'bar', 'zing']; +test_198.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":"3DbGY","fallthrough":false}]; +TESTS.push(test_198); + +function test_199(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + case 'zing': + break; + } +} +test_199.INPUTS = ['foo', 'bar', 'zing']; +test_199.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_199); + +function test_200(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + case 'zing': + break; + } +} +test_200.INPUTS = ['foo', 'bar', 'zing']; +test_200.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_200); + +function test_201(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + break; + default: + } +} +test_201.INPUTS = ['foo', 'bar', 'zing']; +test_201.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_201); + +function test_202(x, arr) { + switch(x) { + default: + arr.push(1320190826); + case 'foo': + case 'bar': + case 'zing': + break; + } +} +test_202.INPUTS = ['foo', 'bar', 'zing']; +test_202.SPEC = [{"match":null,"body":1320190826,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_202); + +function test_203(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(1320190826); + case 'bar': + case 'zing': + break; + } +} +test_203.INPUTS = ['foo', 'bar', 'zing']; +test_203.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":1320190826,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_203); + +function test_204(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + break; + default: + arr.push(1320190826); + } +} +test_204.INPUTS = ['foo', 'bar', 'zing']; +test_204.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":1320190826,"fallthrough":true}]; +TESTS.push(test_204); + +function test_205(x, arr) { + switch(x) { + default: + arr.push(1211439111); + break; + case 'foo': + case 'bar': + case 'zing': + break; + } +} +test_205.INPUTS = ['foo', 'bar', 'zing']; +test_205.SPEC = [{"match":null,"body":1211439111,"fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_205); + +function test_206(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(1211439111); + break; + case 'bar': + case 'zing': + break; + } +} +test_206.INPUTS = ['foo', 'bar', 'zing']; +test_206.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":1211439111,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false}]; +TESTS.push(test_206); + +function test_207(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + break; + default: + arr.push(1211439111); + break; + } +} +test_207.INPUTS = ['foo', 'bar', 'zing']; +test_207.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":false},{"match":null,"body":1211439111,"fallthrough":false}]; +TESTS.push(test_207); + +function test_208(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + break; + case 'zing': + } +} +test_208.INPUTS = ['foo', 'bar', 'zing']; +test_208.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_208); + +function test_209(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + break; + case 'zing': + } +} +test_209.INPUTS = ['foo', 'bar', 'zing']; +test_209.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_209); + +function test_210(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + default: + } +} +test_210.INPUTS = ['foo', 'bar', 'zing']; +test_210.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_210); + +function test_211(x, arr) { + switch(x) { + default: + arr.push(1547874695); + case 'foo': + break; + case 'bar': + break; + case 'zing': + } +} +test_211.INPUTS = ['foo', 'bar', 'zing']; +test_211.SPEC = [{"match":null,"body":1547874695,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_211); + +function test_212(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push(1547874695); + case 'bar': + break; + case 'zing': + } +} +test_212.INPUTS = ['foo', 'bar', 'zing']; +test_212.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":1547874695,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_212); + +function test_213(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + default: + arr.push(1547874695); + } +} +test_213.INPUTS = ['foo', 'bar', 'zing']; +test_213.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":1547874695,"fallthrough":true}]; +TESTS.push(test_213); + +function test_214(x, arr) { + switch(x) { + default: + arr.push('@_2GFlnK=t'); + break; + case 'foo': + break; + case 'bar': + break; + case 'zing': + } +} +test_214.INPUTS = ['foo', 'bar', 'zing']; +test_214.SPEC = [{"match":null,"body":"@_2GFlnK=t","fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_214); + +function test_215(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('@_2GFlnK=t'); + break; + case 'bar': + break; + case 'zing': + } +} +test_215.INPUTS = ['foo', 'bar', 'zing']; +test_215.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"@_2GFlnK=t","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_215); + +function test_216(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + break; + case 'zing': + default: + arr.push('@_2GFlnK=t'); + break; + } +} +test_216.INPUTS = ['foo', 'bar', 'zing']; +test_216.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"@_2GFlnK=t","fallthrough":false}]; +TESTS.push(test_216); + +function test_217(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + break; + case 'zing': + } +} +test_217.INPUTS = ['foo', 'bar', 'zing']; +test_217.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_217); + +function test_218(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + break; + case 'zing': + } +} +test_218.INPUTS = ['foo', 'bar', 'zing']; +test_218.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_218); + +function test_219(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + default: + } +} +test_219.INPUTS = ['foo', 'bar', 'zing']; +test_219.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_219); + +function test_220(x, arr) { + switch(x) { + default: + arr.push('~C$'); + case 'foo': + case 'bar': + break; + case 'zing': + } +} +test_220.INPUTS = ['foo', 'bar', 'zing']; +test_220.SPEC = [{"match":null,"body":"~C$","fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_220); + +function test_221(x, arr) { + switch(x) { + case 'foo': + default: + arr.push('~C$'); + case 'bar': + break; + case 'zing': + } +} +test_221.INPUTS = ['foo', 'bar', 'zing']; +test_221.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":"~C$","fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_221); + +function test_222(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + default: + arr.push('~C$'); + } +} +test_222.INPUTS = ['foo', 'bar', 'zing']; +test_222.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"~C$","fallthrough":true}]; +TESTS.push(test_222); + +function test_223(x, arr) { + switch(x) { + default: + arr.push('2sfo%'); + break; + case 'foo': + case 'bar': + break; + case 'zing': + } +} +test_223.INPUTS = ['foo', 'bar', 'zing']; +test_223.SPEC = [{"match":null,"body":"2sfo%","fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_223); + +function test_224(x, arr) { + switch(x) { + case 'foo': + default: + arr.push('2sfo%'); + break; + case 'bar': + break; + case 'zing': + } +} +test_224.INPUTS = ['foo', 'bar', 'zing']; +test_224.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":"2sfo%","fallthrough":false},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_224); + +function test_225(x, arr) { + switch(x) { + case 'foo': + case 'bar': + break; + case 'zing': + default: + arr.push('2sfo%'); + break; + } +} +test_225.INPUTS = ['foo', 'bar', 'zing']; +test_225.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":false},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"2sfo%","fallthrough":false}]; +TESTS.push(test_225); + +function test_226(x, arr) { + switch(x) { + default: + case 'foo': + break; + case 'bar': + case 'zing': + } +} +test_226.INPUTS = ['foo', 'bar', 'zing']; +test_226.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_226); + +function test_227(x, arr) { + switch(x) { + case 'foo': + break; + default: + case 'bar': + case 'zing': + } +} +test_227.INPUTS = ['foo', 'bar', 'zing']; +test_227.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_227); + +function test_228(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + default: + } +} +test_228.INPUTS = ['foo', 'bar', 'zing']; +test_228.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_228); + +function test_229(x, arr) { + switch(x) { + default: + arr.push(1637942279); + case 'foo': + break; + case 'bar': + case 'zing': + } +} +test_229.INPUTS = ['foo', 'bar', 'zing']; +test_229.SPEC = [{"match":null,"body":1637942279,"fallthrough":true},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_229); + +function test_230(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push(1637942279); + case 'bar': + case 'zing': + } +} +test_230.INPUTS = ['foo', 'bar', 'zing']; +test_230.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":1637942279,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_230); + +function test_231(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + default: + arr.push(1637942279); + } +} +test_231.INPUTS = ['foo', 'bar', 'zing']; +test_231.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":1637942279,"fallthrough":true}]; +TESTS.push(test_231); + +function test_232(x, arr) { + switch(x) { + default: + arr.push('4E!jR'); + break; + case 'foo': + break; + case 'bar': + case 'zing': + } +} +test_232.INPUTS = ['foo', 'bar', 'zing']; +test_232.SPEC = [{"match":null,"body":"4E!jR","fallthrough":false},{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_232); + +function test_233(x, arr) { + switch(x) { + case 'foo': + break; + default: + arr.push('4E!jR'); + break; + case 'bar': + case 'zing': + } +} +test_233.INPUTS = ['foo', 'bar', 'zing']; +test_233.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":null,"body":"4E!jR","fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_233); + +function test_234(x, arr) { + switch(x) { + case 'foo': + break; + case 'bar': + case 'zing': + default: + arr.push('4E!jR'); + break; + } +} +test_234.INPUTS = ['foo', 'bar', 'zing']; +test_234.SPEC = [{"match":"foo","body":null,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":"4E!jR","fallthrough":false}]; +TESTS.push(test_234); + +function test_235(x, arr) { + switch(x) { + default: + case 'foo': + case 'bar': + case 'zing': + } +} +test_235.INPUTS = ['foo', 'bar', 'zing']; +test_235.SPEC = [{"match":null,"body":null,"fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_235); + +function test_236(x, arr) { + switch(x) { + case 'foo': + default: + case 'bar': + case 'zing': + } +} +test_236.INPUTS = ['foo', 'bar', 'zing']; +test_236.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_236); + +function test_237(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + default: + } +} +test_237.INPUTS = ['foo', 'bar', 'zing']; +test_237.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":null,"fallthrough":true}]; +TESTS.push(test_237); + +function test_238(x, arr) { + switch(x) { + default: + arr.push(')fSNzp06'); + case 'foo': + case 'bar': + case 'zing': + } +} +test_238.INPUTS = ['foo', 'bar', 'zing']; +test_238.SPEC = [{"match":null,"body":")fSNzp06","fallthrough":true},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_238); + +function test_239(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(')fSNzp06'); + case 'bar': + case 'zing': + } +} +test_239.INPUTS = ['foo', 'bar', 'zing']; +test_239.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":")fSNzp06","fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_239); + +function test_240(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + default: + arr.push(')fSNzp06'); + } +} +test_240.INPUTS = ['foo', 'bar', 'zing']; +test_240.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":")fSNzp06","fallthrough":true}]; +TESTS.push(test_240); + +function test_241(x, arr) { + switch(x) { + default: + arr.push(974910083); + break; + case 'foo': + case 'bar': + case 'zing': + } +} +test_241.INPUTS = ['foo', 'bar', 'zing']; +test_241.SPEC = [{"match":null,"body":974910083,"fallthrough":false},{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_241); + +function test_242(x, arr) { + switch(x) { + case 'foo': + default: + arr.push(974910083); + break; + case 'bar': + case 'zing': + } +} +test_242.INPUTS = ['foo', 'bar', 'zing']; +test_242.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":null,"body":974910083,"fallthrough":false},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true}]; +TESTS.push(test_242); + +function test_243(x, arr) { + switch(x) { + case 'foo': + case 'bar': + case 'zing': + default: + arr.push(974910083); + break; + } +} +test_243.INPUTS = ['foo', 'bar', 'zing']; +test_243.SPEC = [{"match":"foo","body":null,"fallthrough":true},{"match":"bar","body":null,"fallthrough":true},{"match":"zing","body":null,"fallthrough":true},{"match":null,"body":974910083,"fallthrough":false}]; +TESTS.push(test_243); + + +///////////////////////////////////////// +// RUNNER // +///////////////////////////////////////// + +for(var i = 0; i < TESTS.length; i++) { + RunTest(TESTS[i]); +} diff --git a/js/src/jit-test/tests/ion/loop-test-fold.js b/js/src/jit-test/tests/ion/loop-test-fold.js new file mode 100644 index 0000000000..ff897c405b --- /dev/null +++ b/js/src/jit-test/tests/ion/loop-test-fold.js @@ -0,0 +1,7 @@ + +function f(a, b) { + do { + a--; + } while (a || b); +} +f(2000, 0); diff --git a/js/src/jit-test/tests/ion/lsra-bug1112164.js b/js/src/jit-test/tests/ion/lsra-bug1112164.js new file mode 100644 index 0000000000..92a7e08003 --- /dev/null +++ b/js/src/jit-test/tests/ion/lsra-bug1112164.js @@ -0,0 +1,36 @@ +setJitCompilerOption("baseline.warmup.trigger", 10); +setJitCompilerOption("ion.warmup.trigger", 30); + +var atan2 = Math.atan2; + +function reference(x, y, z, w) { + with({}) {}; /* prevent compilation */ + return [ atan2(x + 0.1, w), + atan2(y + 0.1, z), + atan2(z + 0.1, y), + atan2(w + 0.1, x) ]; +} + +function generator(x, y, z, w) { + return [ atan2(x + 0.1, w), + atan2(y + 0.1, z), + atan2(z + 0.1, y), + atan2(w + 0.1, x) ]; +} + +function test() { + var min = -0.99999, step = 0.1, max = 1; + for (var x = min; x < max; x += step) + for (var y = min; y < max; y += step) + for (var z = min; z < max; z += step) + for (var w = min; w < max; w += step) { + var ref = reference(x, y, z, w); + var gen = generator(x, y, z, w); + assertEq(gen[0], ref[0]); + assertEq(gen[1], ref[1]); + assertEq(gen[2], ref[2]); + assertEq(gen[3], ref[3]); + } +} + +test(); diff --git a/js/src/jit-test/tests/ion/math-imul-folding.js b/js/src/jit-test/tests/ion/math-imul-folding.js new file mode 100644 index 0000000000..4a187ad074 --- /dev/null +++ b/js/src/jit-test/tests/ion/math-imul-folding.js @@ -0,0 +1,7 @@ +function sprod(x, y) { + var iprod = Math.imul(x | 0, y | 0); + var fprod = (x | 0) * (y | 0); + return iprod + fprod; +} +assertEq(sprod(2, 2), 8); +assertEq(sprod(0x10000, 0x10000), 0x100000000); diff --git a/js/src/jit-test/tests/ion/math-max-arraylength.js b/js/src/jit-test/tests/ion/math-max-arraylength.js new file mode 100644 index 0000000000..dd8e915f84 --- /dev/null +++ b/js/src/jit-test/tests/ion/math-max-arraylength.js @@ -0,0 +1,25 @@ +var arrays = [ + [], + [1], + [1, 2], + [1, 2, 3], + [1, 2, 3, 4], +]; + +function test() { + for (var i = 0; i < arrays.length; i++) { + var array = arrays[i]; + + assertEq(Math.max(array.length, 0), i); + assertEq(Math.max(0, array.length), i); + + assertEq(Math.max(array.length, -1), i); + assertEq(Math.max(-1, array.length), i); + + assertEq(Math.max(array.length, -1.5), i); + assertEq(Math.max(-1.5, array.length), i); + } +} + +test(); +test(); diff --git a/js/src/jit-test/tests/ion/mathFloor.js b/js/src/jit-test/tests/ion/mathFloor.js new file mode 100644 index 0000000000..319ff17bff --- /dev/null +++ b/js/src/jit-test/tests/ion/mathFloor.js @@ -0,0 +1,50 @@ +// Test Math.floor() for IonMonkey. +// Requires --ion-eager to enter at the top of each loop. + +var floorDTests = [ + [-0, -0], + [0.49999999999999997, 0], + [0.5, 0], + [1.0, 1], + [1.5, 1], + [792.8, 792], + [-0.1, -1], + [-1.0001, -2], + [-3.14, -4], + [2137483649.5, 2137483649], + [2137483648.5, 2137483648], + [2137483647.1, 2137483647], + [900000000000, 900000000000], + [-0, -0], + [-Infinity, -Infinity], + [Infinity, Infinity], + [NaN, NaN], + [-2147483648.8, -2147483649], + [-2147483649.8, -2147483650] +]; + +var floorITests = [ + [0, 0], + [4, 4], + [-1, -1], + [-7, -7], + [2147483648, 2147483648], + [-2147483649, -2147483649] +]; + +// Typed functions to be compiled by Ion. +function floorD(x) { return Math.floor(x); } +function floorI(x) { return Math.floor(x); } + +function test() { + // Always run this function in the interpreter. + with ({}) {} + + for (var i = 0; i < floorDTests.length; i++) + assertEq(floorD(floorDTests[i][0]), floorDTests[i][1]); + for (var i = 0; i < floorITests.length; i++) + assertEq(floorI(floorITests[i][0]), floorITests[i][1]); +} + +for (var i = 0; i < 40; i++) + test(); diff --git a/js/src/jit-test/tests/ion/mathMinMax.js b/js/src/jit-test/tests/ion/mathMinMax.js new file mode 100644 index 0000000000..dc3e5df9e1 --- /dev/null +++ b/js/src/jit-test/tests/ion/mathMinMax.js @@ -0,0 +1,42 @@ +var nan = Number.NaN; +var negative_zero = -0; + +function max(a, b) { + return Math.max(a, b); +} +function min(a, b) { + return Math.min(a, b); +} + +function main() { + for (var i = 0; i < 100; i++) { + assertEq(max(negative_zero, 0), 0); + assertEq(max(0, negative_zero), 0); + assertEq(min(0, negative_zero), negative_zero); + assertEq(min(negative_zero, 0), negative_zero); + + assertEq(min(negative_zero, negative_zero), negative_zero); + assertEq(max(negative_zero, negative_zero), negative_zero); + + assertEq(max(nan, 0), nan); + assertEq(min(nan, 0), nan); + + assertEq(max(0, nan), nan); + assertEq(max(nan, 0), nan); + + assertEq(max(3, 5), 5); + assertEq(max(5, 3), 5); + + assertEq(min(3, 5), 3); + assertEq(min(5, 3), 3); + + assertEq(max(Infinity, -Infinity), Infinity); + assertEq(min(Infinity, -Infinity), -Infinity); + assertEq(max(Infinity, nan), nan); + + assertEq(max(negative_zero, -5), negative_zero); + assertEq(min(negative_zero, -5), -5); + } +} + +main();
\ No newline at end of file diff --git a/js/src/jit-test/tests/ion/mathRound.js b/js/src/jit-test/tests/ion/mathRound.js new file mode 100644 index 0000000000..9230e4fc10 --- /dev/null +++ b/js/src/jit-test/tests/ion/mathRound.js @@ -0,0 +1,48 @@ +// Test Math.round() for IonMonkey. +// Requires --ion-eager to enter at the top of each loop. + +var roundDTests = [ + [-0, -0], + [0.49999999999999997, 0], + [0.5, 1], + [1.0, 1], + [1.5, 2], + [792.8, 793], + [-0.1, -0], + [-1.0001, -1], + [-3.14, -3], + [2137483649.5, 2137483650], + [2137483648.5, 2137483649], + [2137483647.1, 2137483647], + [900000000000, 900000000000], + [-0, -0], + [-Infinity, -Infinity], + [Infinity, Infinity], + [NaN, NaN], + [-2147483648.8, -2147483649], + [-2147483649.8, -2147483650] +]; + +var roundITests = [ + [0, 0], + [4, 4], + [2147483648, 2147483648], + [-2147483649, -2147483649] +]; + +// Typed functions to be compiled by Ion. +function roundD(x) { return Math.round(x); } +function roundI(x) { return Math.round(x); } + +function test() { + // Always run this function in the interpreter. + with ({}) {} + + for (var i = 0; i < roundDTests.length; i++) + assertEq(roundD(roundDTests[i][0]), roundDTests[i][1]); + for (var i = 0; i < roundITests.length; i++) + assertEq(roundI(roundITests[i][0]), roundITests[i][1]); +} + +for (var i = 0; i < 40; i++) + test(); diff --git a/js/src/jit-test/tests/ion/mathSign.js b/js/src/jit-test/tests/ion/mathSign.js new file mode 100644 index 0000000000..892bcbe63b --- /dev/null +++ b/js/src/jit-test/tests/ion/mathSign.js @@ -0,0 +1,75 @@ +// Test Math.sign() for IonMonkey. +// Requires --ion-eager to enter at the top of each loop. + +var signDITests = [ + [0.49999999999999997, 1], + [0.5, 1], + [1.0, 1], + [1.5, 1], + [792.8, 1], + [-0.1, -1], + [-1.0001, -1], + [-3.14, -1], + [900000000000, 1], + [+0, +0], + [-Infinity, -1], + [Infinity, 1], +]; + +var signDITests_bailout = [ + // Add a few 'double -> int' tests before the bailout. + ...(function*(){ for (var i = 0; i < 50; ++i) yield* signDITests; })(), + + // Trigger bailout for negative zero. + [-0, -0], +]; + +var signDTests = [ + [-0, -0], + [0.49999999999999997, 1], + [0.5, 1], + [1.0, 1], + [1.5, 1], + [792.8, 1], + [-0.1, -1], + [-1.0001, -1], + [-3.14, -1], + [900000000000, 1], + [-0, -0], + [+0, +0], + [-Infinity, -1], + [Infinity, 1], + [NaN, NaN], +]; + +var signITests = [ + [0, 0], + [4, 1], + [-1, -1], + [-7, -1], + [2147483647, 1], + [-2147483648, -1], +]; + +// Typed functions to be compiled by Ion. +function signDI(x) { return Math.sign(x); } +function signDI_bailout(x) { return Math.sign(x); } +function signD(x) { return Math.sign(x); } +function signI(x) { return Math.sign(x); } + +function test() { + // Always run this function in the interpreter. + with ({}) {} + + for (var i = 0; i < signDITests.length; i++) + assertEq(signDI(signDITests[i][0]), signDITests[i][1]); + for (var i = 0; i < signDITests_bailout.length; i++) + assertEq(signDI_bailout(signDITests_bailout[i][0]), signDITests_bailout[i][1]); + for (var i = 0; i < signDTests.length; i++) + assertEq(signD(signDTests[i][0]), signDTests[i][1]); + for (var i = 0; i < signITests.length; i++) + assertEq(signI(signITests[i][0]), signITests[i][1]); +} + +for (var i = 0; i < 40; i++) + test(); diff --git a/js/src/jit-test/tests/ion/mathTrunc.js b/js/src/jit-test/tests/ion/mathTrunc.js new file mode 100644 index 0000000000..35c0369a00 --- /dev/null +++ b/js/src/jit-test/tests/ion/mathTrunc.js @@ -0,0 +1,76 @@ +// Test Math.trunc() for IonMonkey. +// Requires --ion-eager to enter at the top of each loop. + +var truncDITests = [ + [0.49999999999999997, 0], + [0.5, 0], + [1.0, 1], + [1.5, 1], + [792.8, 792], + [-1.0001, -1], + [-3.14, -3], + [2137483649.5, 2137483649], + [2137483648.5, 2137483648], + [2137483647.1, 2137483647], + [-2147483647.8, -2147483647], +]; + +var truncDITests_bailout = [ + ...truncDITests, + + // Bailout in bailoutCvttsd2si: https://bugzil.la/1379626#c1 + [-2147483648.8, -2147483648], +]; + +var truncDTests = [ + [-0, -0], + [0.49999999999999997, 0], + [0.5, 0], + [1.0, 1], + [1.5, 1], + [792.8, 792], + [-0.1, -0], + [-1.0001, -1], + [-3.14, -3], + [2137483649.5, 2137483649], + [2137483648.5, 2137483648], + [2137483647.1, 2137483647], + [900000000000, 900000000000], + [-0, -0], + [-Infinity, -Infinity], + [Infinity, Infinity], + [NaN, NaN], + [-2147483648.8, -2147483648], + [-2147483649.8, -2147483649], +]; + +var truncITests = [ + [0, 0], + [4, 4], + [-1, -1], + [-7, -7], + [2147483647, 2147483647], +]; + +// Typed functions to be compiled by Ion. +function truncDI(x) { return Math.trunc(x); } +function truncDI_bailout(x) { return Math.trunc(x); } +function truncD(x) { return Math.trunc(x); } +function truncI(x) { return Math.trunc(x); } + +function test() { + // Always run this function in the interpreter. + with ({}) {} + + for (var i = 0; i < truncDITests.length; i++) + assertEq(truncDI(truncDITests[i][0]), truncDITests[i][1]); + for (var i = 0; i < truncDITests_bailout.length; i++) + assertEq(truncDI_bailout(truncDITests_bailout[i][0]), truncDITests_bailout[i][1]); + for (var i = 0; i < truncDTests.length; i++) + assertEq(truncD(truncDTests[i][0]), truncDTests[i][1]); + for (var i = 0; i < truncITests.length; i++) + assertEq(truncI(truncITests[i][0]), truncITests[i][1]); +} + +for (var i = 0; i < 40; i++) + test(); diff --git a/js/src/jit-test/tests/ion/merge-phi-usage-analysis.js b/js/src/jit-test/tests/ion/merge-phi-usage-analysis.js new file mode 100644 index 0000000000..f239a8faf2 --- /dev/null +++ b/js/src/jit-test/tests/ion/merge-phi-usage-analysis.js @@ -0,0 +1,63 @@ + +function expensive() { + with({}) {} +} + +function phi_merge_0(i) { + // These computations can overflow, if the output is not truncated. + i = i | 0; + var a0 = i + i; + var a1 = i + i; + + if ((a1 | 0) - ((2 * i) | 0)) { + // Good candidate for branch pruning, which marks only a1 as having + // removed uses. + expensive(); + expensive(); + expensive(); + expensive(); + expensive(); + } + + // Simple branch made to let GVN merge the Phi instructions. + if (a1 % 3 == 1) { + a1 = 2 * i; + a0 = 2 * i; + } + + // a0 is never used, but a1 is truncated. + return a1 | 0; +} + +function phi_merge_1(i) { + // These computations can overflow, if the output is not truncated. + i = i | 0; + var a1 = i + i; + var a0 = i + i; + + if ((a1 | 0) - ((2 * i) | 0)) { + // Good candidate for branch pruning, which marks only a1 as having + // removed uses. + expensive(); + expensive(); + expensive(); + expensive(); + expensive(); + } + + // Simple branch made to let GVN merge the Phi instructions. + if (a1 % 3 == 1) { + a1 = 2 * i; + a0 = 2 * i; + } + + // a0 is never used, but a1 is truncated. + return a1 | 0; +} + +for (var j = 0; j < 300; j++) { + for (var i = 1; i == (i | 0); i = 2 * i + 1) { + assertEq(phi_merge_0(i) < 0x80000000, true); + assertEq(phi_merge_1(i) < 0x80000000, true); + } +} diff --git a/js/src/jit-test/tests/ion/mod-double.js b/js/src/jit-test/tests/ion/mod-double.js new file mode 100644 index 0000000000..7a6df7bd56 --- /dev/null +++ b/js/src/jit-test/tests/ion/mod-double.js @@ -0,0 +1,13 @@ +function test1() { + function mod(x, y) { + return x % y; + } + for (var i=0; i<60; i++) { + assertEq(mod(4, 2), 0); + assertEq(mod(5.5, 2.5), 0.5); + assertEq(mod(10.3, 0), NaN); + assertEq(mod(-0, -3), -0); + + } +} +test1(); diff --git a/js/src/jit-test/tests/ion/monomorphic-property-access.js b/js/src/jit-test/tests/ion/monomorphic-property-access.js new file mode 100644 index 0000000000..54066a8d89 --- /dev/null +++ b/js/src/jit-test/tests/ion/monomorphic-property-access.js @@ -0,0 +1,38 @@ +function Foo() { + for (var i=0; i<10; i++) { + this["p" + i] = i; + } +} + +function test1(foo) { + for (var i=0; i<10400; i++) { + foo.p1 = i; + foo.p9 = i; + var x = foo.p0 + foo.p1 + foo.p2 + foo.p8 + foo.p4 + + foo.p5 + foo.p6 + foo.p7 + foo.p3 + foo.p9; + assertEq(x, i + i + 35); + } +} + +test1(new Foo); + +function Bar(arg) { + if (arg) { // Thwart definite-property analysis. + this.x = 1; + this.y = 2; + this.z = 3; + } +} + +function test2(bar) { + for (var i=0; i<10400; i++) { + bar.x++; + bar.y++; + bar.z++; + } + assertEq(bar.x, 10401); + assertEq(bar.y, 10402); + assertEq(bar.z, 10403); +} + +test2(new Bar(true)); diff --git a/js/src/jit-test/tests/ion/muli-constant-1-bug1534810.js b/js/src/jit-test/tests/ion/muli-constant-1-bug1534810.js new file mode 100644 index 0000000000..3936d28697 --- /dev/null +++ b/js/src/jit-test/tests/ion/muli-constant-1-bug1534810.js @@ -0,0 +1,15 @@ +function f() {} +function g(x) { + var a = 0, b = NaN, c = 1, d = 0, e = 0; + a = (x >> 0); + b = f(); + b = +b; + c = Math.round(1); + d = Math.imul(b, c); + e = e + a; + e = e + d; + return e; +} +for (let i = 0; i < 2; ++i) { + assertEq(g(), 0); +} diff --git a/js/src/jit-test/tests/ion/nativeElementAccesses.js b/js/src/jit-test/tests/ion/nativeElementAccesses.js new file mode 100644 index 0000000000..c126750ac4 --- /dev/null +++ b/js/src/jit-test/tests/ion/nativeElementAccesses.js @@ -0,0 +1,44 @@ + +function testOverwritingSparseHole() +{ + var x = []; + for (var i = 0; i < 50; i++) + x[i] = i; + var hit = false; + Object.defineProperty(x, 40, {set: function() { hit = true; }}); + for (var i = 0; i < 50; i++) + x[i] = 10; + assertEq(hit, true); +} +testOverwritingSparseHole(); + +function testReadingSparseHole() +{ + var x = []; + for (var i = 5; i < 50; i++) + x[i] = i; + var hit = false; + Object.defineProperty(x, 40, {get: function() { hit = true; return 5.5; }}); + var res = 0; + for (var i = 0; i < 50; i++) { + res += x[i]; + if (i == 10) + res = 0; + } + assertEq(res, 1135.5); + assertEq(hit, true); +} +testReadingSparseHole(); + +function testInSparseHole() +{ + var x = []; + for (var i = 5; i < 50; i++) + x[i] = i; + Object.defineProperty(x, 40, {get: function() {}}); + var res = 0; + for (var i = 0; i < 50; i++) + res += (i in x) ? 1 : 0; + assertEq(res, 45); +} +testInSparseHole(); diff --git a/js/src/jit-test/tests/ion/new-0.js b/js/src/jit-test/tests/ion/new-0.js new file mode 100644 index 0000000000..851b59facd --- /dev/null +++ b/js/src/jit-test/tests/ion/new-0.js @@ -0,0 +1,16 @@ +// Some testing for JSOP_NEW. +function foo(prop) { + this.name = "Foo"; + this.prop = prop; + return this; +} + +// Construct an object with a unique assignation to a property. +function f(i) { + var x = new foo(i); + return x.prop; +} + +// Assert that a unique object really was created. +for (var i = 0; i < 100; i++) + assertEq(f(i), i); diff --git a/js/src/jit-test/tests/ion/new-1.js b/js/src/jit-test/tests/ion/new-1.js new file mode 100644 index 0000000000..81862b562f --- /dev/null +++ b/js/src/jit-test/tests/ion/new-1.js @@ -0,0 +1,15 @@ +// Some testing for JSOP_NEW. +function foo(prop) { + this.name = "Foo"; + this.prop = prop; +} + +// Construct an object with a unique assignation to a property. +function f(i) { + var x = new foo(i); + return x.prop; +} + +// Assert that a unique object really was created. +for (var i = 0; i < 100; i++) + assertEq(f(i), i); diff --git a/js/src/jit-test/tests/ion/new-10.js b/js/src/jit-test/tests/ion/new-10.js new file mode 100644 index 0000000000..7f8a202c76 --- /dev/null +++ b/js/src/jit-test/tests/ion/new-10.js @@ -0,0 +1,15 @@ +function O(a) { + this.x = 20; + var ret = a ? {x: 10} : 26; + return ret; +} +function test() { + for (var i=0; i<100; i++) { + var o = new O((i & 1) == 1); + if (i & 1) + assertEq(o.x, 10); + else + assertEq(o.x, 20); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/new-2.js b/js/src/jit-test/tests/ion/new-2.js new file mode 100644 index 0000000000..c8e7c2c273 --- /dev/null +++ b/js/src/jit-test/tests/ion/new-2.js @@ -0,0 +1,13 @@ +// Test JSOP_NEW using native constructors. +// Construct an object with a unique assignation to a property. +function f(i) { + var x = new Number(i); + return x; +} + +// Assert that a unique object really was created. +for (var i = 0; i < 100; i++) { + var o = f(i); + assertEq(typeof o, "object"); + assertEq(Number(o), i); +} diff --git a/js/src/jit-test/tests/ion/new-3.js b/js/src/jit-test/tests/ion/new-3.js new file mode 100644 index 0000000000..b7b2fa89fa --- /dev/null +++ b/js/src/jit-test/tests/ion/new-3.js @@ -0,0 +1,18 @@ +// Uncompiled, polymorphic callsite for |new|. + +function Foo(prop) { + this.name = "Foo"; + this.prop = prop; +} + +function f() { + // Enter OSR here. + for (var i = 0; i < 100; i++) + { } + + // No type information below this point. + var x = new Foo("cats"); + return x; +} + +assertEq(f().prop, "cats"); diff --git a/js/src/jit-test/tests/ion/new-4.js b/js/src/jit-test/tests/ion/new-4.js new file mode 100644 index 0000000000..d8df9ef3f7 --- /dev/null +++ b/js/src/jit-test/tests/ion/new-4.js @@ -0,0 +1,21 @@ +// Handle bailing from a constructor. + +var confuzzle = 0; + +function BailFromConstructor() { + this.x = "cats"; + this.y = confuzzle + 5; + return 4; +} + +function f() { + var x; + for (var i = 0; i < 100; i++) { + if (i == 99) + confuzzle = undefined; + x = new BailFromConstructor(); + assertEq(typeof(x), "object"); + } +} + +f(); diff --git a/js/src/jit-test/tests/ion/new-5.js b/js/src/jit-test/tests/ion/new-5.js new file mode 100644 index 0000000000..4c5a8485b5 --- /dev/null +++ b/js/src/jit-test/tests/ion/new-5.js @@ -0,0 +1,15 @@ +// Call an Ion constructor from the interpreter. + +// This gets compiled and called by the interpreter. +// Allocation and primitive check need to happen caller-side. +function Foo() { + this.x = 5; + return 4; +} + +eval("//nothing"); // Prevent compilation of global script. + +for (var i = 0; i < 100; i++) { + var x = new Foo(); + assertEq(typeof(x), "object"); +} diff --git a/js/src/jit-test/tests/ion/new-6.js b/js/src/jit-test/tests/ion/new-6.js new file mode 100644 index 0000000000..6212cd91d8 --- /dev/null +++ b/js/src/jit-test/tests/ion/new-6.js @@ -0,0 +1,18 @@ +// Enter an Ion constructor via on-stack replacement. + +// This gets compiled and called by the interpreter. +// Allocation and primitive check need to happen caller-side. +function Foo() { + var y = 0; + for (var i = 0; i < 100; i++) + { y++ } + this.x = 5; + return y; +} + +eval("//nothing"); // Prevent compilation of global script. + +for (var i = 0; i < 100; i++) { + var x = new Foo(); + assertEq(typeof(x), "object"); +} diff --git a/js/src/jit-test/tests/ion/new-7.js b/js/src/jit-test/tests/ion/new-7.js new file mode 100644 index 0000000000..73f059c24d --- /dev/null +++ b/js/src/jit-test/tests/ion/new-7.js @@ -0,0 +1,32 @@ +// Reduced from v8-raytrace. + +var Class = { + create : function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Bar = Class.create(); +Bar.prototype = { + // Compiled third. + initialize : function() { } +} + +var Foo = Class.create(); +Foo.prototype = { + // Compiled second. Crashes when setting "bar". Uses LCallConstructor. + initialize : function() { + this.bar = new Bar(); + } +} + +// Compiled first. +function f() { + for (var i = 0; i < 100; i++) { + var foo = new Foo(); + } +} + +f(); diff --git a/js/src/jit-test/tests/ion/new-8.js b/js/src/jit-test/tests/ion/new-8.js new file mode 100644 index 0000000000..bd2dfb9c7d --- /dev/null +++ b/js/src/jit-test/tests/ion/new-8.js @@ -0,0 +1,21 @@ +// Handle bailing from a constructor that's called from the interpreter. + +function yesokhellothankyou() { + return 5; +} + +function BailFromConstructor() { + this.x = "cats"; + this.y = 5; + var z = yesokhellothankyou(); + + // Causes a bailout for purposes of inlining at the LRecompileCheck. + // Yep, this is great. + for (var i = 0; i < 10500; i++) { + x = 4; + } + + return 4; +} + +var x = new BailFromConstructor(); diff --git a/js/src/jit-test/tests/ion/new-9.js b/js/src/jit-test/tests/ion/new-9.js new file mode 100644 index 0000000000..ef346ffc58 --- /dev/null +++ b/js/src/jit-test/tests/ion/new-9.js @@ -0,0 +1,27 @@ +// Test createThisScripted(), without a singleton. +function Foo(a) { + this.str = "foo"; +} + +function Bar(a) { + this.str = "bar"; +} + +function f() { + var x; + for (var i = 0; i < 400; i++) { + if (i % 2 == 0) + x = Foo; + else + x = Bar; + + var y = new x(5); + + if (i % 2 == 0) + assertEq(y.str, "foo"); + else + assertEq(y.str, "bar"); + } +} + +f(); diff --git a/js/src/jit-test/tests/ion/new-object-with-dynamic-slots.js b/js/src/jit-test/tests/ion/new-object-with-dynamic-slots.js new file mode 100644 index 0000000000..a6c7625234 --- /dev/null +++ b/js/src/jit-test/tests/ion/new-object-with-dynamic-slots.js @@ -0,0 +1,35 @@ + +function Foo() { + this.a = 1; + this.b = 1; + this.c = 1; + this.d = 1; + this.e = 1; + this.f = 1; + this.g = 1; + this.h = 1; + this.i = 1; + this.j = 1; + this.k = 1; + this.l = 1; + this.m = 1; + this.n = 1; + this.o = 1; + this.p = 1; + this.q = 1; + this.r = 1; + this.s = 1; +} + +function fn() { + var a = []; + for (var i = 0; i < 50; i++) + a.push(new Foo()); + var total = 0; + for (var i = 0; i < a.length; i++) { + var v = a[i]; + total += v.a + v.b + v.c + v.d + v.e + v.f + v.g + v.h + v.i + v.j + v.k + v.l + v.m + v.n + v.o + v.p + v.q + v.r + v.s; + } + assertEq(total, 950); +} +fn(); diff --git a/js/src/jit-test/tests/ion/notV.js b/js/src/jit-test/tests/ion/notV.js new file mode 100644 index 0000000000..f42a3893d1 --- /dev/null +++ b/js/src/jit-test/tests/ion/notV.js @@ -0,0 +1,32 @@ +function foo(x) { + return !x; +} + +assertEq(foo({}), false); +assertEq(foo({}), false); +assertEq(foo(1.1), false); +assertEq(foo(1.1), false); +assertEq(foo(0.0), true); +assertEq(foo(0.0), true); +assertEq(foo(null), true); +assertEq(foo(null), true); +assertEq(foo(undefined), true); +assertEq(foo(undefined), true); +assertEq(foo(Infinity), false); +assertEq(foo(Infinity), false); +assertEq(foo(NaN), true); +assertEq(foo(NaN), true); +assertEq(foo([]), false); +assertEq(foo([]), false); +assertEq(foo(''), true); +assertEq(foo(''), true); +assertEq(foo('x'), false); +assertEq(foo('x'), false); +assertEq(foo(true), false); +assertEq(foo(true), false); +assertEq(foo(false), true); +assertEq(foo(false), true); +assertEq(foo(-0.0), true); +assertEq(foo(-0.0), true); +assertEq(foo(createIsHTMLDDA()), true); +assertEq(foo(createIsHTMLDDA()), true); diff --git a/js/src/jit-test/tests/ion/nursery-getter-setter.js b/js/src/jit-test/tests/ion/nursery-getter-setter.js new file mode 100644 index 0000000000..c017b1d7bb --- /dev/null +++ b/js/src/jit-test/tests/ion/nursery-getter-setter.js @@ -0,0 +1,17 @@ +var threshold = getJitCompilerOptions()["ion.warmup.trigger"] + 101; +function bar(i) { + if (!i) + with (this) {}; // Don't inline. + if (i === threshold) + minorgc(); +} + +function f() { + var o2 = Object.create({get foo() { return this.x; }, set foo(x) { this.x = x + 1; }}); + for (var i=0; i<2000; i++) { + o2.foo = i; + assertEq(o2.foo, i + 1); + bar(i); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/nursery-getter-setter2.js b/js/src/jit-test/tests/ion/nursery-getter-setter2.js new file mode 100644 index 0000000000..3ad3b47e5b --- /dev/null +++ b/js/src/jit-test/tests/ion/nursery-getter-setter2.js @@ -0,0 +1,11 @@ +function g(o, i) { + o.foo = i; + assertEq(o.foo, i + 1); +} +function f() { + var o2 = Object.create({get foo() { return this.x; }, set foo(x) { this.x = x + 1; }}); + for (var i=0; i<1200; i++) { + g(o2, i); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/object-create-with-primitive-second-arg-in-ion.js b/js/src/jit-test/tests/ion/object-create-with-primitive-second-arg-in-ion.js new file mode 100644 index 0000000000..a4c6d40da9 --- /dev/null +++ b/js/src/jit-test/tests/ion/object-create-with-primitive-second-arg-in-ion.js @@ -0,0 +1,8 @@ +// |jit-test| --ion-eager +load(libdir + "asserts.js"); + +[1, "", true, Symbol(), undefined].forEach(props => { + assertEq(Object.getPrototypeOf(Object.create(null, props)), null); +}); + +assertThrowsInstanceOf(() => Object.create(null, null), TypeError); diff --git a/js/src/jit-test/tests/ion/object-create.js b/js/src/jit-test/tests/ion/object-create.js new file mode 100644 index 0000000000..dca277c3ed --- /dev/null +++ b/js/src/jit-test/tests/ion/object-create.js @@ -0,0 +1,25 @@ +// Ensure Ion inlining of Object.create(x) tests the type of x +// matches the template object. + +var P1 = {}; +var P2 = {}; +minorgc(); + +function f1() { + for (var i=0; i<100; i++) { + var P = (i & 1) ? P1 : P2; + var o = Object.create(P); + assertEq(Object.getPrototypeOf(o), P); + } +} +f1(); + +function f2() { + var arr = [null, Array]; + for (var i=0; i<99; i++) { + var p = arr[(i / 50)|0]; + var o = Object.create(p); + assertEq(Object.getPrototypeOf(o), p); + } +} +f2(); diff --git a/js/src/jit-test/tests/ion/object-prototype-tostring.js b/js/src/jit-test/tests/ion/object-prototype-tostring.js new file mode 100644 index 0000000000..ad06dbde89 --- /dev/null +++ b/js/src/jit-test/tests/ion/object-prototype-tostring.js @@ -0,0 +1,45 @@ +var toString = Object.prototype.toString; +var iter = 500; + +function testConstant() { + for (var i = 0; i < iter; i++) { + assertEq(({}).toString(), "[object Object]"); + assertEq(toString.call([]), "[object Array]"); + assertEq(toString.call(Math.abs), "[object Function]"); + } +} +testConstant(); + +function testOwnToStringTag() { + var stringify = o => toString.call(o); + var o = {}; + for (var i = 0; i < iter; i++) + assertEq(stringify(o), "[object Object]"); + o[Symbol.toStringTag] = "foo"; + for (var i = 0; i < iter; i++) + assertEq(stringify(o), "[object foo]"); +} +testOwnToStringTag(); + +function testDynamic() { + var arr = [{}, [], new Date, /a/]; + var expected = ["[object Object]", "[object Array]", "[object Date]", "[object RegExp]"]; + for (var i = 0; i < iter; i++) { + for (var j = 0; j < arr.length; j++) + assertEq(toString.call(arr[j]), expected[j]); + } +} +testDynamic(); + +function testToStringTagProto() { + var c = 0; + Object.defineProperty(Date.prototype, Symbol.toStringTag, {get() { c++; return "evil"; }}); + var arr = [{}, [], new Date, /a/]; + var expected = ["[object Object]", "[object Array]", "[object evil]", "[object RegExp]"]; + for (var i = 0; i < iter; i++) { + for (var j = 0; j < arr.length; j++) + assertEq(toString.call(arr[j]), expected[j]); + } + assertEq(c, iter); +} +testToStringTagProto(); diff --git a/js/src/jit-test/tests/ion/osr-with-optimized-out.js b/js/src/jit-test/tests/ion/osr-with-optimized-out.js new file mode 100644 index 0000000000..78e2685ff2 --- /dev/null +++ b/js/src/jit-test/tests/ion/osr-with-optimized-out.js @@ -0,0 +1,23 @@ +// |jit-test| --ion-offthread-compile=off; + +// We disable any off-main thread compilation, and set a definite trigger for +// Ion compilation, such that we can garantee that we would OSR into the inner +// loop before we reach the end of the loop. +setJitCompilerOption("ion.warmup.trigger", 30); +gcPreserveCode(); + +function f (n) { + while (!inIon()) { + var inner = 0; + let x = {}; + for (var i = 0; i < n; i++) { + inner += inIon() == true ? 1 : 0; + if (inner <= 1) + bailout(); + } + assertEq(inner != 1, true); + } +} + +// Iterate enough to ensure that we OSR in this inner loop. +f(300); diff --git a/js/src/jit-test/tests/ion/pgo-bug1252120.js b/js/src/jit-test/tests/ion/pgo-bug1252120.js new file mode 100644 index 0000000000..100fbfd34a --- /dev/null +++ b/js/src/jit-test/tests/ion/pgo-bug1252120.js @@ -0,0 +1,14 @@ +// |jit-test| --ion-pgo=on; + +target = handler = {} +for (p of[new Proxy(target, handler)]) + evaluate("foo()"); +function foo() { + symbols = [Symbol] + values = [NaN] + for (comparator of[""]) + for (b of values) assertEq; + for (comparator of[""]) + for (a of symbols) + for (b of values) assertEq; +} diff --git a/js/src/jit-test/tests/ion/pgo-bug1259476.js b/js/src/jit-test/tests/ion/pgo-bug1259476.js new file mode 100644 index 0000000000..2a6bc66d1c --- /dev/null +++ b/js/src/jit-test/tests/ion/pgo-bug1259476.js @@ -0,0 +1,16 @@ +// |jit-test| --ion-pgo=on; + +try { + x = evalcx(''); + x.__proto__ = 0; +} catch (e) {} +(function() { + for (var i = 0; i < 1; ++i) { + if (i % 5 == 0) { + for (let z of[0, 0, new Boolean(false), new Boolean(false), + new Boolean(false), new Boolean(false)]) { + this.x; + } + } + } +})() diff --git a/js/src/jit-test/tests/ion/popn.js b/js/src/jit-test/tests/ion/popn.js new file mode 100644 index 0000000000..06e2f5fb85 --- /dev/null +++ b/js/src/jit-test/tests/ion/popn.js @@ -0,0 +1,11 @@ +function f() { + var t = 0; + for (var j = 0; j < 10; j++) { + for (var i = 0; i < 9; ++i) { + var [r, g, b] = [1, i, -10]; + t += r + g + b; + } + } + return t; +} +assertEq(f(), -450); diff --git a/js/src/jit-test/tests/ion/pow-base-power-of-two-bailouts.js b/js/src/jit-test/tests/ion/pow-base-power-of-two-bailouts.js new file mode 100644 index 0000000000..34e7ed406f --- /dev/null +++ b/js/src/jit-test/tests/ion/pow-base-power-of-two-bailouts.js @@ -0,0 +1,85 @@ +// Lowering provides a specialisation when the base operand is a constant which +// is a power of two. +// +// Test bailout conditions for this optimisation. + +function test(x) { + function pow(x, y) { return `Math.pow(${x}, ${y})` }; + function exp(x, y) { return `((${x}) ** ${y})` }; + + function make(fn) { + return Function("y, z", ` + // Load from array to prevent constant-folding. + // (Ion is currently not smart enough to realise that both array + // values are the same.) + var ys = [y, y]; + var zs = [z, z]; + for (var i = 0; i < 1000; ++i) { + assertEq(${fn(x, "ys[i & 1]")}, zs[i & 1]); + } + `); + } + + function double(v) { + // NB: numberToDouble() always returns a double value. + return numberToDouble(v); + } + + // Find the first power which will exceed the Int32 range by computing ⌈log_x(2 ^ 31)⌉. + var limit = Math.ceil(Math.log2(2 ** 31) / Math.log2(x)); + assertEq(Math.pow(x, limit - 1) < 2 ** 31, true); + assertEq(Math.pow(x, limit) >= 2 ** 31, true); + + function* args(first, last) { + // Run the test function a few times without a bailout. + for (var i = 0; i < 3; ++i) { + yield first; + } + + // |last| should trigger a bailout. + yield last; + } + + // Test precision loss when the result exceeds 2**31. + for (var fn of [make(pow), make(exp)]) { + for (var y of args(limit - 1, limit)) { + // Ensure the callee always sees a double to avoid an early Bailout_ArgumentCheck. + var z = double(Math.pow(x, y)); + fn(y, z); + } + } + + // Test precision loss when the result is a fractional number. + for (var fn of [make(pow), make(exp)]) { + for (var y of args(0, -1)) { + // Ensure the callee always sees a double to avoid an early Bailout_ArgumentCheck. + var z = double(Math.pow(x, y)); + fn(y, z); + } + } + + // Find the first negative power which can be represented as a double + var negLimit = -Math.floor(1074 / Math.log2(x)); + + // Test precision loss when the result is a non-zero, fractional number. + for (var fn of [make(pow), make(exp)]) { + for (var y of args(limit - 1, limit)) { + // Ensure the callee always sees a double to avoid an early Bailout_ArgumentCheck. + var z = double(Math.pow(x, y)); + fn(y, z); + } + } +} + +function* range(a, b, fn) { + for (var i = a; i <= b; ++i) { + yield fn(i); + } +} + +// Only 2^i with |i| ∈ {1..8} currently triggers the optimisation, but also test +// the next power-of-two values. + +for (var x of range(1, 10, i => 2 ** i)) { + test(x); +} diff --git a/js/src/jit-test/tests/ion/pow-base-power-of-two.js b/js/src/jit-test/tests/ion/pow-base-power-of-two.js new file mode 100644 index 0000000000..35ae52a28d --- /dev/null +++ b/js/src/jit-test/tests/ion/pow-base-power-of-two.js @@ -0,0 +1,75 @@ +// Lowering provides a specialisation when the base operand is a constant which +// is a power of two. + +loadRelativeToScript("../../../tests/non262/Math/shell.js"); + +function test(x, y, z) { + function pow(x, y) { return `Math.pow(${x}, ${y})` }; + function exp(x, y) { return `((${x}) ** ${y})` }; + + function make(fn, x, y, z) { + return Function(` + // Load from array to prevent constant-folding. + // (Ion is currently not smart enough to realise that both array + // values are the same.) + var ys = [${y}, ${y}]; + var zs = [${z}, ${z}]; + for (var i = 0; i < 1000; ++i) { + assertNear(${fn(x, "ys[i & 1]")}, zs[i & 1]); + } + `); + } + + function double(v) { + // NB: numberToDouble() always returns a double value. + return `numberToDouble(${v})`; + } + + function addTests(fn) { + tests.push(make(fn, x, y, z)); + tests.push(make(fn, x, double(y), z)); + tests.push(make(fn, double(x), y, z)); + tests.push(make(fn, double(x), double(y), z)); + } + + var tests = []; + addTests(pow); + addTests(exp); + + for (var i = 0; i < tests.length; ++i) { + for (var j = 0; j < 2; ++j) { + tests[i](); + } + } +} + +function* range(a, b, fn) { + for (var i = a; i <= b; ++i) { + yield fn(i); + } +} + +// Only 2^i with |i| ∈ {1..8} currently triggers the optimisation, but also test +// the next power-of-two values, 1 and 0, and negative base-of-two values. +var values = [ + ...range(1, 10, i => 2 ** i), + 1, + 0, + ...range(1, 4, i => -(2 ** i)), +]; + +for (var x of values) { + test(x, 0, 1); + test(x, 1, x); + test(x, 2, x * x); + + // 0**(negative) is Infinity, 1**(negative) is 1. + if (Math.abs(x) > 1) { + test(x, -1076, 0); + } + + // (negative)**(odd-negative) is -0. + if (x > 1) { + test(x, -1075, 0); + } +} diff --git a/js/src/jit-test/tests/ion/pow-constant-power.js b/js/src/jit-test/tests/ion/pow-constant-power.js new file mode 100644 index 0000000000..9382348052 --- /dev/null +++ b/js/src/jit-test/tests/ion/pow-constant-power.js @@ -0,0 +1,68 @@ +// Ion provides specialisations when Math.pow() resp. the **-operator is used +// with a constant power of one of [-0.5, 0.5, 1, 2, 3, 4]. + +function test(x, y, z) { + function pow(x, y) { return `Math.pow(${x}, ${y})` }; + function exp(x, y) { return `((${x}) ** ${y})` }; + + function make(fn, x, y, z) { + return Function(` + // Load from array to prevent constant-folding. + // (Ion is currently not smart enough to realise that both array + // values are the same.) + var xs = [${x}, ${x}]; + var zs = [${z}, ${z}]; + for (var i = 0; i < 1000; ++i) { + assertEq(${fn("xs[i & 1]", y)}, zs[i & 1]); + } + `); + } + + function double(v) { + // NB: numberToDouble() always returns a double value. + return `numberToDouble(${v})`; + } + + function addTests(fn) { + tests.push(make(fn, x, y, z)); + tests.push(make(fn, x, double(y), z)); + tests.push(make(fn, double(x), y, z)); + tests.push(make(fn, double(x), double(y), z)); + } + + var tests = []; + addTests(pow); + addTests(exp); + + for (var i = 0; i < tests.length; ++i) { + for (var j = 0; j < 2; ++j) { + tests[i](); + } + } +} + +// Make sure the tests below test int32 and double return values. + +// Math.pow(x, -0.5) +test( 1, -0.5, 1); +test(16, -0.5, 0.25); + +// Math.pow(x, 0.5) +test(16, 0.5, 4); +test( 2, 0.5, Math.SQRT2); + +// Math.pow(x, 1) +test(5, 1, 5); +test(0.5, 1, 0.5); + +// Math.pow(x, 2) +test(5, 2, 25); +test(0.5, 2, 0.25); + +// Math.pow(x, 3) +test(5, 3, 125); +test(0.5, 3, 0.125); + +// Math.pow(x, 3) +test(5, 4, 625); +test(0.5, 4, 0.0625); diff --git a/js/src/jit-test/tests/ion/range-analysis-bug1122402.js b/js/src/jit-test/tests/ion/range-analysis-bug1122402.js new file mode 100644 index 0000000000..62e52e9e71 --- /dev/null +++ b/js/src/jit-test/tests/ion/range-analysis-bug1122402.js @@ -0,0 +1,11 @@ +// |jit-test| error:TypeError + +(function() { + let r + g = function(x) { + ((-0x80000000 + (x >>> 0)) != 0) ? 0 : x() + } +})() + +g(NaN) +g(0x80000000); diff --git a/js/src/jit-test/tests/ion/range-analysis-bug1124448.js b/js/src/jit-test/tests/ion/range-analysis-bug1124448.js new file mode 100644 index 0000000000..807f75432e --- /dev/null +++ b/js/src/jit-test/tests/ion/range-analysis-bug1124448.js @@ -0,0 +1,8 @@ + +function f(y) { + var x1 = Math.max(-2147483649 >> 0, y >>> 0); + var x2 = x1 | 0; + return (x2 >= 0) ? 1 : 0; +} +assertEq(f(0), 1); +assertEq(f(-1), 0); diff --git a/js/src/jit-test/tests/ion/range-analysis.js b/js/src/jit-test/tests/ion/range-analysis.js new file mode 100644 index 0000000000..86f4419135 --- /dev/null +++ b/js/src/jit-test/tests/ion/range-analysis.js @@ -0,0 +1,35 @@ +// |jit-test| + +// Only fails with Ion. +function add_xors_1() { + var res = 0; + var step = 4; + for (var i = 0x7fffffff | 0; i >= (1 << step); i -= (i >> step)) { + var x = i ^ (i << 1); + res += (((x + x) + res + res) | 0); + } + return res; +} + +var r1 = add_xors_1(); +for (var i = 0; i < 100; i++) { + var r2 = add_xors_1(); + assertEq(r2, r1); +} + +// Only fails with JM +function add_xors_2() { + var res = 0; + var step = 4; + for (var i = 0x7fffffff | 0; i >= (1 << step); i -= (i >> step)) { + var x = i ^ (i << 1); + res += ((x + x) + res + res) | 0; + } + return res; +} + +var r1 = add_xors_2(); +for (var i = 0; i < 100; i++) { + var r2 = add_xors_2(); + assertEq(r1, r2); +} diff --git a/js/src/jit-test/tests/ion/recover-arrays.js b/js/src/jit-test/tests/ion/recover-arrays.js new file mode 100644 index 0000000000..dd7c196edd --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-arrays.js @@ -0,0 +1,336 @@ +// |jit-test| --no-ion +// Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that +// bug has been fixed. + +// Ion eager fails the test below because we have not yet created any +// template object in baseline before running the content of the top-level +// function. +if (getJitCompilerOptions()["ion.warmup.trigger"] <= 100) + setJitCompilerOption("ion.warmup.trigger", 100); + +// This test checks that we are able to remove the getelem & setelem with scalar +// replacement, so we should not force inline caches, as this would skip the +// generation of getelem & setelem instructions. +if (getJitCompilerOptions()["ion.forceinlineCaches"]) + setJitCompilerOption("ion.forceinlineCaches", 0); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +// This function is used to force a bailout when it is inlined, and to recover +// the frame which is inlining this function. +var resumeHere = function (i) { if (i >= 99) bailout(); }; + +// This function is used to cause an invalidation after having removed a branch +// after DCE. This is made to check if we correctly recover an array +// allocation. +var uceFault = function (i) { + if (i > 98) + uceFault = function (i) { return true; }; + return false; +}; + +// This function is used to ensure that we do escape the array, and thus prevent +// any escape analysis. +var global_arr; +function escape(arr) { global_arr = arr; } + +// Check Array length defined by the literal. +function array0Length(i) { + var a = []; + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array0LengthBail(i) { + var a = []; + resumeHere(i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array1Length(i) { + var a = [ i ]; + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array1LengthBail(i) { + var a = [ i ]; + resumeHere(i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array2Length(i) { + var a = [ i, i ]; + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array2LengthBail(i) { + var a = [ i, i ]; + resumeHere(i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +// Check that we can correctly gc in the middle of an incomplete object +// intialization. +function arrayWithGCInit0(i) { + var a = [ (i == 99 ? (gc(), i) : i), i ]; + assertRecoveredOnBailout(a, true); + return a.length; +} + +function arrayWithGCInit1(i) { + var a = [ i, (i == 99 ? (gc(), i) : i) ]; + assertRecoveredOnBailout(a, true); + return a.length; +} + +function arrayWithGCInit2(i) { + var a = [ i, i ]; + if (i == 99) gc(); + assertRecoveredOnBailout(a, true); + return a.length; +} + +// Check Array content +function array1Content(i) { + var a = [ i ]; + assertEq(a[0], i); + assertRecoveredOnBailout(a, true); + return a.length; +} +function array1ContentBail0(i) { + var a = [ i ]; + resumeHere(i); + assertEq(a[0], i); + assertRecoveredOnBailout(a, true); + return a.length; +} +function array1ContentBail1(i) { + var a = [ i ]; + assertEq(a[0], i); + resumeHere(i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array2Content(i) { + var a = [ i, i ]; + assertEq(a[0], i); + assertEq(a[1], i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array2ContentBail0(i) { + var a = [ i, i ]; + resumeHere(i); + assertEq(a[0], i); + assertEq(a[1], i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array2ContentBail1(i) { + var a = [ i, i ]; + assertEq(a[0], i); + resumeHere(i); + assertEq(a[1], i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +function array2ContentBail2(i) { + var a = [ i, i ]; + assertEq(a[0], i); + assertEq(a[1], i); + resumeHere(i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +// Check bailouts during the initialization. +function arrayInitBail0(i) { + var a = [ resumeHere(i), i ]; + assertRecoveredOnBailout(a, true); + return a.length; +} + +function arrayInitBail1(i) { + var a = [ i, resumeHere(i) ]; + assertRecoveredOnBailout(a, true); + return a.length; +} + +// Check recovery of large arrays. +function arrayLarge0(i) { + var a = new Array(10000000); + resumeHere(); bailout(); // always resume here. + // IsArrayEscaped prevent us from escaping Arrays with too many elements. + assertRecoveredOnBailout(a, false); + return a.length; +} + +function arrayLarge1(i) { + var a = new Array(10000000); + a[0] = i; + assertEq(a[0], i); + // IsArrayEscaped prevent us from escaping Arrays with too many elements. + assertRecoveredOnBailout(a, false); + return a.length; +} + +function arrayLarge2(i) { + var a = new Array(10000000); + a[0] = i; + a[100] = i; + assertEq(a[0], i); + assertEq(a[100], i); + // IsArrayEscaped prevent us from escaping Arrays with too many elements. + assertRecoveredOnBailout(a, false); + return a.length; +} + +// Check escape analysis in case of branches. +function arrayCond(i) { + var a = [i,0,i]; + if (i % 2 == 1) + a[1] = i; + assertEq(a[0], i); + assertEq(a[1], (i % 2) * i); + assertEq(a[2], i); + assertRecoveredOnBailout(a, true); + return a.length; +} + +// Check escape analysis in case of holes. +function arrayHole0(i) { + var a = [i,,i]; + if (i != 99) + a[1] = i; + assertEq(a[0], i); + assertEq(a[1], i != 99 ? i : undefined); + assertEq(a[2], i); + // need to check for holes. + assertRecoveredOnBailout(a, false); + return a.length; +} + +// Same test as the previous one, but the Array.prototype is changed to reutn +// "100" when we request for the element "1". +function arrayHole1(i) { + var a = [i,,i]; + if (i != 99) + a[1] = i; + assertEq(a[0], i); + assertEq(a[1], i != 99 ? i : 100); + assertEq(a[2], i); + // need to check for holes. + assertRecoveredOnBailout(a, false); + return a.length; +} + +// Check that we correctly allocate the array after taking the recover path. +var uceFault_arrayAlloc0 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arrayAlloc0')); +function arrayAlloc0(i) { + var a = new Array(10); + if (uceFault_arrayAlloc0(i) || uceFault_arrayAlloc0(i)) { + return a.length; + } + assertRecoveredOnBailout(a, true); + return 0; +} + +var uceFault_arrayAlloc1 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arrayAlloc1')); +function arrayAlloc1(i) { + var a = new Array(10); + if (uceFault_arrayAlloc1(i) || uceFault_arrayAlloc1(i)) { + a[0] = i; + a[1] = i; + assertEq(a[0], i); + assertEq(a[1], i); + assertEq(a[2], undefined); + return a.length; + } + assertRecoveredOnBailout(a, true); + return 0; +} + +var uceFault_arrayAlloc2 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arrayAlloc2')); +function arrayAlloc2(i) { + var a = new Array(10); + if (uceFault_arrayAlloc2(i) || uceFault_arrayAlloc2(i)) { + a[4096] = i; + assertEq(a[0], undefined); + assertEq(a[4096], i); + return a.length; + } + assertRecoveredOnBailout(a, true); + return 0; +} + +function build(l) { var arr = []; for (var i = 0; i < l; i++) arr.push(i); return arr } +var uceFault_arrayAlloc3 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_arrayAlloc3')); +function arrayAlloc3(i) { + var a = [0,1,2,3,4,5,6,7,8]; + if (uceFault_arrayAlloc3(i) || uceFault_arrayAlloc3(i)) { + assertEq(a[0], 0); + assertEq(a[3], 3); + return a.length; + } + assertRecoveredOnBailout(a, true); + return 0; +}; + +// Prevent compilation of the top-level +eval(`(${resumeHere})`); + +for (var i = 0; i < 100; i++) { + array0Length(i); + array0LengthBail(i); + array1Length(i); + array1LengthBail(i); + array2Length(i); + array2LengthBail(i); + array1Content(i); + array1ContentBail0(i); + array1ContentBail1(i); + array2Content(i); + array2ContentBail0(i); + array2ContentBail1(i); + array2ContentBail2(i); + arrayInitBail0(i); + arrayInitBail1(i); + arrayLarge0(i); + arrayLarge1(i); + arrayLarge2(i); + arrayCond(i); + arrayHole0(i); + arrayAlloc0(i); + arrayAlloc1(i); + arrayAlloc2(i); + arrayAlloc3(i); +} + +for (var i = 0; i < 100; i++) { + arrayWithGCInit0(i); + arrayWithGCInit1(i); + arrayWithGCInit2(i); +} + +// If arr[1] is not defined, then we fallback on the prototype which instead of +// returning undefined, returns "0". +Object.defineProperty(Array.prototype, 1, { + value: 100, + configurable: true, + enumerable: true, + writable: true +}); + +for (var i = 0; i < 100; i++) { + arrayHole1(i); +} diff --git a/js/src/jit-test/tests/ion/recover-autounsafe.js b/js/src/jit-test/tests/ion/recover-autounsafe.js new file mode 100644 index 0000000000..e03b018ccc --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-autounsafe.js @@ -0,0 +1,36 @@ +// |jit-test| --ion-eager; --ion-offthread-compile=off + +// Some AutoUnsafeCallWithABI functions can be reached via recovery instructions. +// This testcase is designed to trigger all of the recovery paths that can reach +// AutoUnsafeCallWithABI functions, while an exception is being thrown. + +(function() { + inputs = []; + f = (function(x) { + var o = {a: x}; + 4294967297 ** (x >>> 0) * + 4294967297 / x >>> 0 * + 4294967297 % x >>> 0 * + Math.max(4294967297, x >>> 0) * + Math.min(4294967, x >>> 0) * + Math.atan2(4294967, x >>> 0) * + Math.sin(x >>> 0) * + Math.sqrt(x >>> 0) * + Math.hypot(4294967, x >>> 0) * + Math.ceil((x >>> 0) * 0.5) * + Math.floor((x >>> 0) * 0.5) * + Math.trunc((x >>> 0) * 0.5) * + Math.round((x >>> 0) * 0.5) * + Math.sign(x >>> 0) * + Math.log(x >>> 0) * + !o * + Math.fround(y); // Exception thrown here; y is not defined. + }); + if (f) { + for (var j = 0; j < 2; ++j) { + try { + f(inputs[0]); + } catch (e) {} + } + } +})(); diff --git a/js/src/jit-test/tests/ion/recover-bigint.js b/js/src/jit-test/tests/ion/recover-bigint.js new file mode 100644 index 0000000000..c3c6e9f644 --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-bigint.js @@ -0,0 +1,220 @@ +// |jit-test| --ion-limit-script-size=off + +setJitCompilerOption("baseline.warmup.trigger", 9); +setJitCompilerOption("ion.warmup.trigger", 20); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +// Keep in sync with BigInt::MaxBitLength. +const maxBitLength = 1024 * 1024; + +const maxBigInt = BigInt.asUintN(maxBitLength, -1n); +const minBigInt = -maxBigInt; + +function resumeHere() {} + +function bigIntAddBail(i) { + var x = [0n, maxBigInt][0 + (i >= 99)]; + + var a = x + 1n; + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +function bigIntSubBail(i) { + var x = [0n, minBigInt][0 + (i >= 99)]; + + var a = x - 1n; + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +function bigIntMulBail(i) { + var x = [0n, maxBigInt][0 + (i >= 99)]; + + var a = x * 2n; + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +function bigIntIncBail(i) { + var x = [0n, maxBigInt][0 + (i >= 99)]; + + var a = x++; + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +function bigIntDecBail(i) { + var x = [0n, minBigInt][0 + (i >= 99)]; + + var a = x--; + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +function bigIntBitNotBail(i) { + var x = [0n, maxBigInt][0 + (i >= 99)]; + + var a = ~x; + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +function bigIntLshBail(i) { + var shift = [0n, BigInt(maxBitLength)][0 + (i >= 99)]; + + var a = 1n << shift; + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +function bigIntRshBail(i) { + var shift = [0n, -BigInt(maxBitLength)][0 + (i >= 99)]; + + var a = 1n >> shift; + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +function bigIntAsUintBail(i) { + var x = [0, maxBitLength + 1][0 + (i >= 99)]; + + var a = BigInt.asUintN(x, -1n); + + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); + + if (i >= 99) bailout(); +} + +// Prevent compilation of the top-level +eval(`(${resumeHere})`); + +// The bigIntXBail() functions create a BigInt which exceeds the maximum +// representable BigInt. This results in either throwing a RangeError or an +// out-of-memory error when the operation is recovered during a bailout. + +try { + for (let i = 0; i < 100; i++) { + bigIntAddBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} + +try { + for (let i = 0; i < 100; i++) { + bigIntSubBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} + +try { + for (let i = 0; i < 100; i++) { + bigIntMulBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} + +try { + for (let i = 0; i < 100; i++) { + bigIntIncBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} + +try { + for (let i = 0; i < 100; i++) { + bigIntDecBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} + +try { + for (let i = 0; i < 100; i++) { + bigIntBitNotBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} + +try { + for (let i = 0; i < 100; i++) { + bigIntLshBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} + +try { + for (let i = 0; i < 100; i++) { + bigIntRshBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} + +try { + for (let i = 0; i < 100; i++) { + bigIntAsUintBail(i); + } + throw new Error("missing exception"); +} catch (e) { + assertEq(e instanceof RangeError || e === "out of memory", true, String(e)); +} diff --git a/js/src/jit-test/tests/ion/recover-bug1236114.js b/js/src/jit-test/tests/ion/recover-bug1236114.js new file mode 100644 index 0000000000..0956a3ee8a --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-bug1236114.js @@ -0,0 +1,5 @@ +function f(x) { + return (!(Math.round(Math.hypot(Number.MIN_VALUE, Math.fround(x))) | 0) | 0) !== (Math.atanh(x) ? false : Math.tan(0)) +} +f(Number.MIN_VALUE) +assertEq(f(4294967295), true) diff --git a/js/src/jit-test/tests/ion/recover-empty-new-object.js b/js/src/jit-test/tests/ion/recover-empty-new-object.js new file mode 100644 index 0000000000..2aee977ce2 --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-empty-new-object.js @@ -0,0 +1,35 @@ +// |jit-test| --no-ion +// Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that +// bug has been fixed. + +// Ion eager fails the test below because we have not yet created any +// template object in baseline before running the content of the top-level +// function. +if (getJitCompilerOptions()["ion.warmup.trigger"] <= 20) + setJitCompilerOption("ion.warmup.trigger", 20); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +// These arguments have to be computed by baseline, and thus captured in a +// resume point. The next function checks that we can remove the computation of +// these arguments. +function f(a, b, c, d) { } + +function topLevel() { + for (var i = 0; i < 30; i++) { + var unused = {}; + var a = {}; + var b = {}; + var c = {}; + var d = {}; + assertRecoveredOnBailout(unused, true); + assertRecoveredOnBailout(a, true); + assertRecoveredOnBailout(b, true); + assertRecoveredOnBailout(c, true); + assertRecoveredOnBailout(d, true); + f(a, b, c, d); + } +} + +topLevel(); diff --git a/js/src/jit-test/tests/ion/recover-lambdas-bug1113940.js b/js/src/jit-test/tests/ion/recover-lambdas-bug1113940.js new file mode 100644 index 0000000000..078e51ad2c --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-lambdas-bug1113940.js @@ -0,0 +1,37 @@ + +gczeal(14); + +// The object metadata callback can iterate over the stack. Thus during the +// allocation of the lambda we might inspect the stack which is still incomplete +// because the lambda is not yet reconstructed. +// +// enableShellAllocationMetadataBuilder ignores its argument, because we don't +// permit metadata callbacks to run JS any more, so this test may be +// unnecessary. We'll preserve its structure just in case. +enableShellAllocationMetadataBuilder(function() {}); +function f() { + (function() { + '' ^ Object + })(); +} +x = 0; +for (var j = 0; j < 99; ++j) { + x += f(); +} + +try { + x = true; + // Same comment as above. + enableShellAllocationMetadataBuilder(function([x, y, z], ... Debugger) {}); + for (var i = 0; i < 10; ++i) { + var f = function() { + function g() { + x++; + } + g(); + } + f(); + } +} catch (e) { + assertEq(e instanceof TypeError, true); +} diff --git a/js/src/jit-test/tests/ion/recover-lambdas-bug1114566.js b/js/src/jit-test/tests/ion/recover-lambdas-bug1114566.js new file mode 100644 index 0000000000..ada8e59f38 --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-lambdas-bug1114566.js @@ -0,0 +1,2 @@ + +(new Function("return (function o() {}).caller;"))(); diff --git a/js/src/jit-test/tests/ion/recover-lambdas-bug1118911.js b/js/src/jit-test/tests/ion/recover-lambdas-bug1118911.js new file mode 100644 index 0000000000..d1e43cb717 --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-lambdas-bug1118911.js @@ -0,0 +1,10 @@ + +function test() { + function f() { + return k.apply(this, arguments); + } + if (undefined >> undefined !== 0) {} + for (var [ v , c ] in this.tracemonkey) { } +} +try { test(); } catch(exc1) {} +try { test(); } catch(exc1) {} diff --git a/js/src/jit-test/tests/ion/recover-lambdas-bug1133389.js b/js/src/jit-test/tests/ion/recover-lambdas-bug1133389.js new file mode 100644 index 0000000000..a1fc813b63 --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-lambdas-bug1133389.js @@ -0,0 +1,17 @@ +var o = {} +Object.defineProperty(o, "p", { + get: function() { + return arguments.callee.caller.caller; + } +}); + +function f() { + function g() { + return o.p; + } + return g(); +} + +for (var k = 0; k < 2; k++) { + assertEq(f(), f); +} diff --git a/js/src/jit-test/tests/ion/recover-lambdas.js b/js/src/jit-test/tests/ion/recover-lambdas.js new file mode 100644 index 0000000000..bec1dad254 --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-lambdas.js @@ -0,0 +1,62 @@ +// |jit-test| --no-ion; --ion-osr=off +// Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that +// bug has been fixed. + +var max = 40; +setJitCompilerOption("ion.warmup.trigger", max - 10); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +// This function is used to escape "g" which is a non-escaped inner function. +// As it is not escaped within "f", the lambda for "g" would be computed on the +// bailout path. Resolving the first ".caller" implies that we have to recover +// the lambda. Resolving the second ".caller" is needed such as we can build the +// test case without explicitly escaping "g", which would prevent this +// optimization. + +function return_f(i) { + if (i != max - 1) + return f; + + // return_f.caller == g + // return_f.caller.caller == f + return return_f.caller.caller; +} + +function f(i) { + function g() { + return return_f(i); + } + + assertRecoveredOnBailout(g, true); + return g(); +} + +// This function is used to cause an invalidation after having removed a branch. +// These functions are used to check if we correctly recover the lambda +// and its environment during a bailout. +var uceFault = function (i) { + if (i == max - 1) + uceFault = function (i) { return true; }; + return false; +}; + +var uceFault_lambdaCall = eval(`(${uceFault})`.replace('uceFault', 'uceFault_lambdaCall')); +function lambdaCall(i) { + function g() { + return i; + } + + if (uceFault_lambdaCall(i) || uceFault_lambdaCall(i)) + assertEq(g(), i); + + assertRecoveredOnBailout(g, true); +}; + + + +for (var i = 0; i < max; i++) { + assertEq(f(i), f); + lambdaCall(i); +} diff --git a/js/src/jit-test/tests/ion/recover-newarrayiterator-close.js b/js/src/jit-test/tests/ion/recover-newarrayiterator-close.js new file mode 100644 index 0000000000..43d3b99b5f --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-newarrayiterator-close.js @@ -0,0 +1,15 @@ +// |jit-test| --no-threads +"use strict"; + +function test() { + for (var k = 0; k < 35; ++k) { + try { + (function (x) { + (x ? 0 : ([y] = [])); + })(); + } catch (e) {} + } +} + +for (var i = 0; i < 35; i++) + test(); diff --git a/js/src/jit-test/tests/ion/recover-newarrayiterator.js b/js/src/jit-test/tests/ion/recover-newarrayiterator.js new file mode 100644 index 0000000000..3d98640a2c --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-newarrayiterator.js @@ -0,0 +1,66 @@ +var max = 40; +setJitCompilerOption("ion.warmup.trigger", max - 10); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +function selfhosted() { + if (typeof getSelfHostedValue === "undefined") + return; + + var NewArrayIterator = getSelfHostedValue("NewArrayIterator"); + var iter = NewArrayIterator(); + bailout(); + // assertRecoveredOnBailout(iter, true); +} + +function iterator(i) { + var array = [1, i]; + var iter = array[Symbol.iterator](); + assertEq(iter.next().value, 1); + bailout(); + // This sometimes fails + // assertRecoveredOnBailout(iter, true); + var result = iter.next(); + assertEq(result.value, i); + assertEq(result.done, false); + assertEq(iter.next().done, true); +} + +function forof(i) { + var array = [1, i]; + var first = true; + + for (var x of array) { + if (first) { + assertEq(x, 1); + bailout(); + first = false; + } else { + assertEq(x, i); + } + } +} + +var data = { + a: 'foo', + b: {c: 'd'}, + arr: [1, 2, 3] +}; + +function fn() { + var {a, b:{c:b}, arr:[, c]} = data; + return c; +} + +function destructuring() { + for (var i = 0; i < max; i++) + assertEq(fn(), 2); +} + +for (var i = 0; i < max; i++) { + selfhosted(); + iterator(i); + forof(i); + destructuring(); +} diff --git a/js/src/jit-test/tests/ion/recover-newstringiterator.js b/js/src/jit-test/tests/ion/recover-newstringiterator.js new file mode 100644 index 0000000000..14a7d46b6e --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-newstringiterator.js @@ -0,0 +1,66 @@ +var max = 40; +setJitCompilerOption("ion.warmup.trigger", max - 10); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +function selfhosted() { + if (typeof getSelfHostedValue === "undefined") + return; + + var NewStringIterator = getSelfHostedValue("NewStringIterator"); + var iter = NewStringIterator(); + bailout(); + // assertRecoveredOnBailout(iter, true); +} + +function iterator(i) { + var string = String.fromCharCode(0x41, i); + var iter = string[Symbol.iterator](); + assertEq(iter.next().value, 'A'); + bailout(); + // This sometimes fails + // assertRecoveredOnBailout(iter, true); + var result = iter.next(); + assertEq(result.value, String.fromCharCode(i)); + assertEq(result.done, false); + assertEq(iter.next().done, true); +} + +function forof(i) { + var string = String.fromCharCode(0x41, i); + var first = true; + + for (var x of string) { + if (first) { + assertEq(x, 'A'); + bailout(); + first = false; + } else { + assertEq(x, String.fromCharCode(i)); + } + } +} + +var data = { + a: 'foo', + b: {c: 'd'}, + str: 'ABC' +}; + +function fn() { + var {a, b:{c:b}, str:[, c]} = data; + return c; +} + +function destructuring() { + for (var i = 0; i < max; i++) + assertEq(fn(), 'B'); +} + +for (var i = 0; i < max; i++) { + selfhosted(); + iterator(i); + forof(i); + destructuring(); +} diff --git a/js/src/jit-test/tests/ion/recover-object-bug1174322.js b/js/src/jit-test/tests/ion/recover-object-bug1174322.js new file mode 100644 index 0000000000..d5e1066b8e --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-object-bug1174322.js @@ -0,0 +1,13 @@ +function f(y) { + Math.min(NaN) ? a : y +} +function g(y) { + f({ + e: false + }) +} +x = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +for (var j = 0; j < 23; ++j) { + g(x[j]) +} diff --git a/js/src/jit-test/tests/ion/recover-object-bug1175233.js b/js/src/jit-test/tests/ion/recover-object-bug1175233.js new file mode 100644 index 0000000000..aaec613512 --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-object-bug1175233.js @@ -0,0 +1,51 @@ +// |jit-test| test-join=--no-unboxed-objects; --ion-pgo=on +// +// Unboxed object optimization might not trigger in all cases, thus we ensure +// that Scalar Replacement optimization is working well independently of the +// object representation. + +// Ion eager fails the test below because we have not yet created any +// template object in baseline before running the content of the top-level +// function. +if (getJitCompilerOptions()["ion.warmup.trigger"] <= 130) + setJitCompilerOption("ion.warmup.trigger", 130); + +// This test checks that we are able to remove the getelem & setelem with scalar +// replacement, so we should not force inline caches, as this would skip the +// generation of getelem & setelem instructions. +if (getJitCompilerOptions()["ion.forceinlineCaches"]) + setJitCompilerOption("ion.forceinlineCaches", 0); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +var uceFault = function (j) { + if (j >= max) + uceFault = function (j) { return true; }; + return false; +} + +function f(j) { + var i = Math.pow(2, j) | 0; + var obj = { + i: i, + v: i + i + }; + // These can only be recovered on bailout iff either we have type + // information for the property access in the branch, or the branch is + // removed before scalar replacement. + assertRecoveredOnBailout(obj, true); + assertRecoveredOnBailout(obj.v, true); + if (uceFault(j) || uceFault(j)) { + // MObjectState::recover should neither fail, + // nor coerce its result to an int32. + assertEq(obj.v, 2 * i); + } + return 2 * obj.i; +} + +var max = 150; +for (var j = 0; j <= max; ++j) { + with({}){}; + f(j); +} diff --git a/js/src/jit-test/tests/ion/recover-objects.js b/js/src/jit-test/tests/ion/recover-objects.js new file mode 100644 index 0000000000..63d1d8037e --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-objects.js @@ -0,0 +1,191 @@ +// |jit-test| --no-ion; --ion-pgo=on +// Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that +// bug has been fixed. + +var max = 200; + +// Ion eager fails the test below because we have not yet created any +// template object in baseline before running the content of the top-level +// function. +if (getJitCompilerOptions()["ion.warmup.trigger"] <= max - 10) + setJitCompilerOption("ion.warmup.trigger", max - 10); + +// Force Inlining heuristics to always inline the functions which have the same +// number of use count. +setJitCompilerOption("ion.warmup.trigger", getJitCompilerOptions()["ion.warmup.trigger"]); + +// This test checks that we are able to remove the getprop & setprop with scalar +// replacement, so we should not force inline caches, as this would skip the +// generation of getprop & setprop instructions. +if (getJitCompilerOptions()["ion.forceinlineCaches"]) + setJitCompilerOption("ion.forceinlineCaches", 0); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +function resumeHere() {} +var uceFault = function (i) { + if (i > max - 2) + uceFault = function (i) { return true; }; + return false; +}; + + +// Without "use script" in the inner function, the arguments might be +// observable. +function inline_notSoEmpty1(a, b, c, d) { + // This function is not strict, so we might be able to observe its + // arguments, if somebody ever called fun.arguments inside it. + return { v: (a.v + b.v + c.v + d.v - 10) / 4 }; +} +var uceFault_notSoEmpty1 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_notSoEmpty1')); +function notSoEmpty1() { + var a = { v: i }; + var b = { v: 1 + a.v }; + var c = { v: 2 + b.v }; + var d = { v: 3 + c.v }; + var unused = { v: 4 + d.v }; + var res = inline_notSoEmpty1(a, b, c, d); + if (uceFault_notSoEmpty1(i) || uceFault_notSoEmpty1(i)) + assertEq(i, res.v); + // Note, that even if the arguments are observable, we are capable of + // optimizing these cases by executing recover instruction before the + // execution of the bailout. This ensures that the observed objects are + // allocated once and used by the unexpected observation and the bailout. + assertRecoveredOnBailout(a, true); + assertRecoveredOnBailout(b, true); + assertRecoveredOnBailout(c, true); + assertRecoveredOnBailout(d, true); + assertRecoveredOnBailout(unused, true); + // This can only be recovered on bailout iff either we have type + // information for the property access in the branch, or the branch is + // removed before scalar replacement. + assertRecoveredOnBailout(res, true); +} + +// Check that we can recover objects with their content. +function inline_notSoEmpty2(a, b, c, d) { + "use strict"; + return { v: (a.v + b.v + c.v + d.v - 10) / 4 }; +} +var uceFault_notSoEmpty2 = eval(`(${uceFault})`.replace('uceFault', 'uceFault_notSoEmpty2')); +function notSoEmpty2(i) { + var a = { v: i }; + var b = { v: 1 + a.v }; + var c = { v: 2 + b.v }; + var d = { v: 3 + c.v }; + var unused = { v: 4 + d.v }; + var res = inline_notSoEmpty2(a, b, c, d); + if (uceFault_notSoEmpty2(i) || uceFault_notSoEmpty2(i)) + assertEq(i, res.v); + assertRecoveredOnBailout(a, true); + assertRecoveredOnBailout(b, true); + assertRecoveredOnBailout(c, true); + assertRecoveredOnBailout(d, true); + assertRecoveredOnBailout(unused, true); + // This can only be recovered on bailout iff either we have type + // information for the property access in the branch, or the branch is + // removed before scalar replacement. + assertRecoveredOnBailout(res, true); +} + +// Check that we can recover objects with their content. +var argFault_observeArg = function (i) { + if (i > max - 2) + return inline_observeArg.arguments[0]; + return { test : i }; +}; +function inline_observeArg(obj, i) { + return argFault_observeArg(i); +} +function observeArg(i) { + var obj = { test: i }; + var res = inline_observeArg(obj, i); + assertEq(res.test, i); + assertRecoveredOnBailout(obj, true); +} + +// Check case where one successor can have multiple times the same predecessor. +function complexPhi(i) { + var obj = { test: i }; + switch (i) { // TableSwitch + case 0: obj.test = 0; break; + case 1: obj.test = 1; break; + case 2: obj.test = 2; break; + case 3: case 4: case 5: case 6: + default: obj.test = i; break; + case 7: obj.test = 7; break; + case 8: obj.test = 8; break; + case 9: obj.test = 9; break; + } + assertEq(obj.test, i); + assertRecoveredOnBailout(obj, true); +} + +// Check case where one successor can have multiple times the same predecessor. +function withinIf(i) { + var x = undefined; + if (i % 2 == 0) { + let obj = { foo: i }; + x = obj.foo; + assertRecoveredOnBailout(obj, true); + obj = undefined; + } else { + let obj = { bar: i }; + x = obj.bar; + assertRecoveredOnBailout(obj, true); + obj = undefined; + } + assertEq(x, i); +} + +// Check case where one successor can have multiple times the same predecessor. +function unknownLoad(i) { + var obj = { foo: i }; + // Unknown properties are inlined as undefined. + assertEq(obj.bar, undefined); + assertRecoveredOnBailout(obj, true); +} + +// Check with dynamic slots. +function dynamicSlots(i) { + var obj = { + p0: i + 0, p1: i + 1, p2: i + 2, p3: i + 3, p4: i + 4, p5: i + 5, p6: i + 6, p7: i + 7, p8: i + 8, p9: i + 9, p10: i + 10, + p11: i + 11, p12: i + 12, p13: i + 13, p14: i + 14, p15: i + 15, p16: i + 16, p17: i + 17, p18: i + 18, p19: i + 19, p20: i + 20, + p21: i + 21, p22: i + 22, p23: i + 23, p24: i + 24, p25: i + 25, p26: i + 26, p27: i + 27, p28: i + 28, p29: i + 29, p30: i + 30, + p31: i + 31, p32: i + 32, p33: i + 33, p34: i + 34, p35: i + 35, p36: i + 36, p37: i + 37, p38: i + 38, p39: i + 39, p40: i + 40, + p41: i + 41, p42: i + 42, p43: i + 43, p44: i + 44, p45: i + 45, p46: i + 46, p47: i + 47, p48: i + 48, p49: i + 49, p50: i + 50 + }; + // Add a function call to capture a resumepoint at the end of the call or + // inside the inlined block, such as the bailout does not rewind to the + // beginning of the function. + resumeHere(); bailout(); + assertEq(obj.p0 + obj.p10 + obj.p20 + obj.p30 + obj.p40, 5 * i + 100); + assertRecoveredOnBailout(obj, true); +} + +// Check that we can correctly recover allocations of new objects. +function Point(x, y) +{ + this.x = x; + this.y = y; +} + +function createThisWithTemplate(i) +{ + var p = new Point(i - 1, i + 1); + bailout(); + assertEq(p.y - p.x, 2); + assertRecoveredOnBailout(p, true); +} + +for (var i = 0; i < max; i++) { + notSoEmpty1(i); + notSoEmpty2(i); + observeArg(i); + complexPhi(i); + withinIf(i); + unknownLoad(i); + dynamicSlots(i); + createThisWithTemplate(i); +} diff --git a/js/src/jit-test/tests/ion/recover-typed-array.js b/js/src/jit-test/tests/ion/recover-typed-array.js new file mode 100644 index 0000000000..9a48a2018a --- /dev/null +++ b/js/src/jit-test/tests/ion/recover-typed-array.js @@ -0,0 +1,13 @@ +function f () { + var x = new Uint8Array(4); + empty(); + assertRecoveredOnBailout(x, true); + var res = inIon(); + bailout(); + return res; +} + +function empty() { +} + +while(!f()); diff --git a/js/src/jit-test/tests/ion/regexp-clone.js b/js/src/jit-test/tests/ion/regexp-clone.js new file mode 100644 index 0000000000..2ed41967fb --- /dev/null +++ b/js/src/jit-test/tests/ion/regexp-clone.js @@ -0,0 +1,8 @@ +var i=0; +function f() { + assertEq(/^[a-z0-9\.]+$/gi.test("Foo.Bar"), true); + i++; + if (i < 100) + f(); +} +f(); diff --git a/js/src/jit-test/tests/ion/regexp-exec.js b/js/src/jit-test/tests/ion/regexp-exec.js new file mode 100644 index 0000000000..d9cec788ef --- /dev/null +++ b/js/src/jit-test/tests/ion/regexp-exec.js @@ -0,0 +1,20 @@ +// RegExp.exec -> RegExp.test optimization should use the builtin test method. +function f() { + var res = 0; + for (var i=0; i<100; i++) { + if (/a/.exec("a")) + res++; + } + assertEq(res, 100); +} +delete RegExp.prototype.test; +gc(); +f(); + +RegExp.prototype.test = function() { assertEq(0, 1); } +gc(); +f(); + +Object.defineProperty(RegExp.prototype, "test", {get: function() { assertEq(0, 1); }}); +gc(); +f(); diff --git a/js/src/jit-test/tests/ion/result-type-mutated.js b/js/src/jit-test/tests/ion/result-type-mutated.js new file mode 100644 index 0000000000..601a6d6176 --- /dev/null +++ b/js/src/jit-test/tests/ion/result-type-mutated.js @@ -0,0 +1,18 @@ +// jitcode which uses objects of one type might not be invalidated when that +// object changes type, if the object isn't accessed in any way. + +function foo(x) { + return x.f; +} + +function bar() { + with({}){} + + var a = {}; + var b = { f: a }; + foo(b); + a.__proto__ = null; + foo(b); +} + +bar(); diff --git a/js/src/jit-test/tests/ion/rinstructions-no-sse4.js b/js/src/jit-test/tests/ion/rinstructions-no-sse4.js new file mode 100644 index 0000000000..3fc764d7e2 --- /dev/null +++ b/js/src/jit-test/tests/ion/rinstructions-no-sse4.js @@ -0,0 +1,53 @@ +// |jit-test| --no-sse4; + +// This test is a fork of dce-with-rinstructions.js. It tests recover +// instructions which are only executed on pre-SSE4 processors. + +setJitCompilerOption("baseline.warmup.trigger", 10); +setJitCompilerOption("ion.warmup.trigger", 20); + +// Prevent the GC from cancelling Ion compilations, when we expect them to succeed +gczeal(0); + +const max = 200; + +// Check that we are able to remove the operation inside recover test +// functions (denoted by "rop..."), when we inline the first version +// of uceFault, and ensure that the bailout is correct when uceFault +// is replaced (which cause an invalidation bailout) +let uceFault = function (i) { + if (i > 98) + uceFault = function (i) { return true; }; + return false; +}; + +let uceFault_ceil_double = eval( + `(${uceFault})` + .replace('uceFault', 'uceFault_ceil_double') +); +function rceil_double(i) { + const x = Math.ceil(i + (-1 >>> 0)); + if (uceFault_ceil_double(i) || uceFault_ceil_double(i)) + assertEq(x, 99 + (-1 >>> 0)); /* = i + 2 ^ 32 - 1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +let uceFault_floor_double = eval( + `(${uceFault})` + .replace('uceFault', 'uceFault_floor_double') +); +function rfloor_double(i) { + const x = Math.floor(i + (-1 >>> 0)); + if (uceFault_floor_double(i) || uceFault_floor_double(i)) + assertEq(x, 99 + (-1 >>> 0)); /* = i + 2 ^ 32 - 1 */ + assertRecoveredOnBailout(x, true); + return i; +} + +for (let j = 100 - max; j < 100; j++) { + with({}){} // Do not Ion-compile this loop. + const i = j < 2 ? (Math.abs(j) % 50) + 2 : j; + rceil_double(i); + rfloor_double(i); +} diff --git a/js/src/jit-test/tests/ion/round-float32.js b/js/src/jit-test/tests/ion/round-float32.js new file mode 100644 index 0000000000..88bc7a842e --- /dev/null +++ b/js/src/jit-test/tests/ion/round-float32.js @@ -0,0 +1,103 @@ +// Bug 1073910 +(function() { + function roundf(y) { + return Math.round(Math.fround(y)); + } + + var x = -1; + assertEq(roundf(x), x); + assertEq(roundf(x), x); + + var x = -2; + assertEq(roundf(x), x); + assertEq(roundf(x), x); + + var x = -1024; + assertEq(roundf(x), x); + + var x = -14680050; + assertEq(roundf(x), Math.fround(x)); + + var x = -8388610; + assertEq(roundf(x), Math.fround(x)); +})(); + +// Bug 1000606 +(function() { + function f() { + var d = Math.fround(0.4999999701976776); + return Math.round(d); + } + assertEq(f(), f()); + + function g() { + var c = Math.fround(8886111); + return Math.round(c); + } + assertEq(g(), g()); +})(); + +// Bug 1124485 +(function() { + function h(x) { + var y = Math.fround(x); + assertEq(y, Math.pow(y, 1)); + } + h(0); + h(2147483647); +})(); + +// Bug 1122344 +(function() { + function f() { + return Math.round(Math.fround(-13527757)); + }; + assertEq(f(), f()); +})(); + +(function() { + // Test values around -0.5 and +0.5 + var f32 = new Float32Array(1); + var i32 = new Int32Array(f32.buffer); + + function round(x) { return Math.round(x); } + function roundf(x) { return Math.round(Math.fround(x)); } + + // Warm up + round(2.5); + round(3.5); + roundf(2.5); + roundf(3.5); + + f32[0] = 0.5; + i32[0] += 1; + print('0.5+e =', f32[0]); + + var x = f32[0]; + assertEq(round(x), 1); + assertEq(roundf(x), 1); + + f32[0] = 0.5; + i32[0] -= 1; + print('0.5-e =', f32[0]); + + var x = f32[0]; + assertEq(round(x), 0); + assertEq(roundf(x), 0); + + f32[0] = -0.5; + i32[0] += 1; + print('-0.5-e =', f32[0]); + + var x = f32[0]; + assertEq(round(x), -1); + assertEq(roundf(x), -1); + + f32[0] = -0.5; + i32[0] -= 1; + print('-0.5+e =', f32[0]); + + var x = f32[0]; + assertEq(round(x), -0); + assertEq(roundf(x), -0); +})(); diff --git a/js/src/jit-test/tests/ion/scalar-replacement-oom.js b/js/src/jit-test/tests/ion/scalar-replacement-oom.js new file mode 100644 index 0000000000..32a3a2e5d5 --- /dev/null +++ b/js/src/jit-test/tests/ion/scalar-replacement-oom.js @@ -0,0 +1,22 @@ +// |jit-test| skip-if: !('oomAtAllocation' in this) + +var lfcode = new Array(); +function k(a, f_arg, b, c) { + for (var i = 0; i < 5; ++i) { + f_arg(i + a); + } +} +function t() { + var x = 2; + k(50, function(i) { + x = i; + }, 100, 200); + oomAtAllocation(101); +} + +try { + t(); + t(); +} catch(e) { + // ignore the exception +} diff --git a/js/src/jit-test/tests/ion/scripted-getter-setter.js b/js/src/jit-test/tests/ion/scripted-getter-setter.js new file mode 100644 index 0000000000..4e8842cba5 --- /dev/null +++ b/js/src/jit-test/tests/ion/scripted-getter-setter.js @@ -0,0 +1,59 @@ +if (getJitCompilerOptions()["ion.warmup.trigger"] > 50) + setJitCompilerOption("ion.warmup.trigger", 50); + +function getObjects() { + var objs = []; + + // Own scripted getter/setter. + objs.push({x: 0, get prop() { + assertJitStackInvariants(); + return ++this.x; + }, set prop(v) { + assertJitStackInvariants(); + this.x += v; + }}); + + // Scripted getter/setter on prototype. Also verify extra formal args are + // handled correctly. + function getter(a, b, c) { + assertEq(arguments.length, 0); + assertEq(a, undefined); + assertEq(b, undefined); + assertEq(c, undefined); + assertJitStackInvariants(); + bailout(); + return ++this.y; + } + function setter1(a, b) { + assertEq(arguments.length, 1); + assertEq(b, undefined); + assertJitStackInvariants(); + this.y = a; + bailout(); + return "unused"; + } + var proto = {}; + Object.defineProperty(proto, "prop", {get: getter, set: setter1}); + objs.push(Object.create(proto)); + + function setter2() { + assertEq(arguments.length, 1); + assertJitStackInvariants(); + this.y = arguments[0]; + } + proto = {}; + Object.defineProperty(proto, "prop", {get: getter, set: setter2}); + objs.push(Object.create(proto)); + return objs; +} +function f() { + var objs = getObjects(); + var res = 0; + for (var i=0; i<200; i++) { + var o = objs[i % objs.length]; + o.prop = 2; + res += o.prop; + } + assertEq(res, 7233); +} +f(); diff --git a/js/src/jit-test/tests/ion/setelem-float32-typedarray-ic.js b/js/src/jit-test/tests/ion/setelem-float32-typedarray-ic.js new file mode 100644 index 0000000000..6ad44f4dce --- /dev/null +++ b/js/src/jit-test/tests/ion/setelem-float32-typedarray-ic.js @@ -0,0 +1,23 @@ +function testFloat32SetElemIC(a) { + for (var i = 0; i < a.length; i++) { + var r = Math.fround(Math.random()); + a[i] = r; + assertEq(a[i], r); + } +} + +function testCompoundClamping(a, b) { + for (var i = 0; i < a.length; i++) { + var r = Math.random(); + a[i] = b[i] = r; + assertEq(a[i], b[i]); + } +} + +testFloat32SetElemIC(new Array(2048)); +testFloat32SetElemIC(new Float64Array(2048)); +testFloat32SetElemIC(new Float32Array(2048)); + +testCompoundClamping(new Array(2048), new Array(2048)); +testCompoundClamping(new Uint8Array(2048), new Uint8Array(2048)); +testCompoundClamping(new Uint8ClampedArray(2048), new Uint8ClampedArray(2048)); diff --git a/js/src/jit-test/tests/ion/setelem-hole.js b/js/src/jit-test/tests/ion/setelem-hole.js new file mode 100644 index 0000000000..3f5333fb2e --- /dev/null +++ b/js/src/jit-test/tests/ion/setelem-hole.js @@ -0,0 +1,68 @@ +// Storing a typed value. +function test1() { + var a = []; + for (var i=0; i<130; i++) { + a[i] = i + 1; + } + return a; +} + +var arr = test1(); +assertEq(arr.length, 130); + +for (var i=0; i<130; i++) + assertEq(arr[i], i + 1); + +// Storing a Value. +function getValue(x) { + var y = x & 0x3; + if (y == 0) return null; + if (y == 1) return true; + if (y == 2) return 1.23; + if (y == 3) return Math; + assertEq(0, 1); +} +getValue(0); +getValue(1); + +function test2() { + var a = []; + for (var i=0; i<130; i++) { + a[i] = getValue(i); + } + return a; +} + +var arr = test2(); +assertEq(arr.length, 130); + +for (var i=0; i<130; i++) + assertEq(arr[i], getValue(i)); + +// Make sure the length-property is not updated if it's greater than +// the (new) initialized length. +function test3(arr, start, end) { + for (var i=start; i<end; i++) { + arr[i] = 10; + } +} +var a = new Array(200); +test3(a, 10, 130); +assertEq(a.length, 200); + +for (var i=10; i<130; i++) + assertEq(a[i], 10); + +test3(a, 130, 220); +assertEq(a.length, 220); + +// Test constant index. +function test4() { + var a = [0, 1, 2, 3, 4, 5]; + for (var i=0; i<150; i++) { + a[6] = i; + } + return a; +} +var arr = test4(); +assertEq(arr[6], 149); diff --git a/js/src/jit-test/tests/ion/setelem-proto.js b/js/src/jit-test/tests/ion/setelem-proto.js new file mode 100644 index 0000000000..d24e2e514b --- /dev/null +++ b/js/src/jit-test/tests/ion/setelem-proto.js @@ -0,0 +1,26 @@ +var a = [1, 2, 3, 4]; +var count = 0; + +function f(arr, i) { + arr[2] = i; +} + +for (var i=0; i<80; i++) { + f(a, i); + assertEq(a[2], i); +} + +delete a[2]; +f(a, 50); +assertEq(a[2], 50); + +Object.defineProperty(Object.prototype, "2", { + set: function() { count++; } +}); +delete a[2]; + +f(a, 100); +f(a, 100); + +assertEq(a[2], undefined); +assertEq(count, 2); diff --git a/js/src/jit-test/tests/ion/setelem.js b/js/src/jit-test/tests/ion/setelem.js new file mode 100644 index 0000000000..34b900d596 --- /dev/null +++ b/js/src/jit-test/tests/ion/setelem.js @@ -0,0 +1,109 @@ +function testInt32() { + function f(arr, i) { + arr[0] = 1; + arr[1] = arr[0] + 1; + arr[2] = arr[1] + arr[0]; + var x = arr[2]; // 3 + arr[x] = arr[x-1] + 1; + arr[x+1] = arr[x] + i; + return arr[4]; + } + var a = [1, 2, 3, 4, 5, 6, 7, 8]; + for (var i=0; i<70; i++) { + assertEq(f(a, i), i + 4); + } +} +testInt32(); + +function testDouble() { + function f(arr, d) { + arr[0] = d; + for (var i=1; i<8; i++) { + arr[i] = arr[i-1] + d; + } + return arr[7]; + } + var a = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]; + for (var i=0; i<50; i++) { + assertEq(f(a, Math.PI + i)|0, ((Math.PI + i) * 8)|0); + } +} +testDouble(); + +function testOutOfBounds() { + function f(arr, i, v) { + arr[i] = v; + } + var a = [1, 2]; + for (var i=0; i<90; i++) { + f(a, 1, i); + } + assertEq(a[1], 89); + + f(a, 2, 40); + f(a, 100, 50); + f(a, -1, 3); + + assertEq(a[2], 40); + assertEq(a[100], 50); + assertEq(a[-1], 3); +} +testOutOfBounds(); + +function testClassGuard() { + function f(arr, v) { + arr[1] = v; + } + var a = [1, 2, 3, 4]; + for (var i=0; i<90; i++) { + f(a, i); + } + assertEq(a[1], 89); + + var b = {}; + f(b, 100); + assertEq(b[1], 100); +} +testClassGuard(); + +function testMultipleTypes() { + function f(arr, v) { + arr[1] = v; + } + var a = [1, 2, 3, 4]; + var b = [1.1, -233.2, 3.3]; + + for (var i=0; i<90; i++) { + f(a, i); + } + assertEq(a[1], 89); + f(b, 20); + assertEq(b[1], 20); +} +testMultipleTypes(); + +function testNull() { + function f(arr) { + arr[0] = null; + } + + var arr = [undefined]; + for (var i=0; i<100; i++) { + f(arr); + } + assertEq(arr[0], null); +} +testNull(); + +// Bug 722245. +function testConstantGcThing() { + function f(arr, x) { + arr[x] = "abc"; + } + var arr = ["", ""]; + for (var i=0; i<100; i++) { + f(arr, 1); + } + assertEq(arr[1], "abc"); +} +testConstantGcThing(); diff --git a/js/src/jit-test/tests/ion/setgname-reconfigured.js b/js/src/jit-test/tests/ion/setgname-reconfigured.js new file mode 100644 index 0000000000..69a125b9c6 --- /dev/null +++ b/js/src/jit-test/tests/ion/setgname-reconfigured.js @@ -0,0 +1,6 @@ +for (p in this) { + delete p; +} +for (p in this) {} +evaluate("for(var i=0; i<50; i++) p = 1"); +assertEq(p, 1); diff --git a/js/src/jit-test/tests/ion/setgname.js b/js/src/jit-test/tests/ion/setgname.js new file mode 100644 index 0000000000..4d684e8136 --- /dev/null +++ b/js/src/jit-test/tests/ion/setgname.js @@ -0,0 +1,56 @@ + +// aaa is initially undefined. Make sure it's set to the +// correct value - we have to store the type tag, even though +// its known type is int32. +var aaa; +function f() { + function g(x) { + if (x) + aaa = 22; + } + g(10); + + function h() { + aaa = 22; + } + for (var i=0; i<70; i++) { + h(); + } + assertEq(aaa, 22); +} +f(); + +x = 0; +function setX(i) { + x = i; +} +for (var i=0; i<70; i++) + setX(i); +assertEq(x, 69); + +y = 3.14; +y = true; +y = []; +function setY(arg) { + y = arg; +} +for (var i=0; i<70; i++) + setY([1]); +setY([1, 2, 3]); +assertEq(y.length, 3); + +// z is non-configurable, but can be made non-writable. +var z = 10; + +function testNonWritable() { + function g() { + z = 11; + } + for (var i=0; i<70; i++) { + g(); + } + Object.defineProperty(this, "z", {value: 1234, writable: false}); + g(); + assertEq(z, 1234); +} +testNonWritable(); diff --git a/js/src/jit-test/tests/ion/setpropertypolymorphic-float32.js b/js/src/jit-test/tests/ion/setpropertypolymorphic-float32.js new file mode 100644 index 0000000000..38f8a7ac17 --- /dev/null +++ b/js/src/jit-test/tests/ion/setpropertypolymorphic-float32.js @@ -0,0 +1,24 @@ +function loop(f32, arr) { + for (var i = 0; i < 2000; i++) { + var j = i % 20; + arr[j].k = f32[j]; + } +} + +function f() { + var obj = {k: null, m: null}; + var obj2 = {m: null, k: 42, l: null}; + var f32 = new Float32Array(20); + var arr = []; + for (var i = 0; i < 10; i++) { + arr.push(obj); + arr.push(obj2); + + } + loop(f32, arr); + for(var i = 0; i < 20; i++) { + assertEq(arr[i].k, f32[i]); + } +} + +f(); diff --git a/js/src/jit-test/tests/ion/sincos-abi-args-bug1534492.js b/js/src/jit-test/tests/ion/sincos-abi-args-bug1534492.js new file mode 100644 index 0000000000..8bf112b379 --- /dev/null +++ b/js/src/jit-test/tests/ion/sincos-abi-args-bug1534492.js @@ -0,0 +1,6 @@ +x = [0]; +for (let i = 0; i < 1; ++i) { + try { + Math.cos(x[0])(Math.sin(x[0])); + } catch (e) {} +} diff --git a/js/src/jit-test/tests/ion/sink-in-recovered-object.js b/js/src/jit-test/tests/ion/sink-in-recovered-object.js new file mode 100644 index 0000000000..fd1b979175 --- /dev/null +++ b/js/src/jit-test/tests/ion/sink-in-recovered-object.js @@ -0,0 +1,19 @@ +setJitCompilerOption("ion.warmup.trigger", 30); + +var arr = []; +function f (cond, a) { + var obj = { a: 0 }; + var x = 2 * a + 1; + if (cond) { + obj.a = x; + arr.push(obj.a); + obj.a = 1; + } else { + obj.a = 1; + } + return obj.a; +} + +for (var i = 0; i < 100; i++) { + assertEq(f(i % 2, i), 1); +} diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-1.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-1.js new file mode 100644 index 0000000000..01b5745cc7 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-1.js @@ -0,0 +1,44 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// The rest argument is overwritten with a non-Array object. +function test() { + var badRest = { + *[Symbol.iterator]() { + yield 3; + yield 4; + } + }; + function maybeInvalidate(rest) { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i >= 1900) { + return badRest; + } + return rest; + } + function fn(...rest) { + rest = maybeInvalidate(rest); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), i < 1900 ? 3 : 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-2a.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-2a.js new file mode 100644 index 0000000000..8f5834b813 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-2a.js @@ -0,0 +1,37 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b, c = 0, d = 0) { + return a + b + c + d; +} + +// The rest argument contains holes. +function test() { + function maybeInvalidate(rest) { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i >= 1900) { + rest[3] = 4; + } + } + function fn(...rest) { + maybeInvalidate(rest); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), i < 1900 ? 3 : 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-2b.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-2b.js new file mode 100644 index 0000000000..e1d8c69496 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-2b.js @@ -0,0 +1,37 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b, c = 0, d = 0) { + return a + b + c + d; +} + +// The rest argument is a packed array. +function test() { + function maybeInvalidate(rest) { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i >= 1900) { + rest.length = 3; + } + } + function fn(...rest) { + maybeInvalidate(rest); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), 3); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-3.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-3.js new file mode 100644 index 0000000000..e7a136f41e --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-3.js @@ -0,0 +1,40 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// The rest argument has an own @@iterator property. +function test() { + function MyIter() { + return [3, 4][Symbol.iterator](); + } + function maybeInvalidate(rest) { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i >= 1900) { + rest[Symbol.iterator] = MyIter; + } + } + function fn(...rest) { + maybeInvalidate(rest); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), i < 1900 ? 3 : 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-4a.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-4a.js new file mode 100644 index 0000000000..22b64f9a81 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-4a.js @@ -0,0 +1,43 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// The rest arguments don't share a common prototype. +function test() { + class MyArray1 extends Array { } + class MyArray2 extends Array { } + function maybeInvalidate(rest) { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i >= 1900) { + if (i & 1) + rest = new MyArray1(3, 4); + else + rest = new MyArray2(5, 6); + } + return rest; + } + function fn(...rest) { + rest = maybeInvalidate(rest); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), i < 1900 ? 3 : (i & 1) ? 7 : 11); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-4b.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-4b.js new file mode 100644 index 0000000000..f533c39f3f --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-4b.js @@ -0,0 +1,39 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// The rest argument's prototype isn't Array.prototype. +function test() { + class MyArray extends Array { } + function maybeInvalidate(rest) { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i >= 1900) { + rest = new MyArray(3, 4); + } + return rest; + } + function fn(...rest) { + rest = maybeInvalidate(rest); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), i < 1900 ? 3 : 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-5a.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-5a.js new file mode 100644 index 0000000000..88c2683cab --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-5a.js @@ -0,0 +1,37 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// Array.prototype's [[Prototype]] was changed, as a result all properties are marked as unknown. +function test() { + function maybeInvalidate() { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i === 1900) { + Object.setPrototypeOf(Array.prototype, null); + } + } + function fn(...rest) { + maybeInvalidate(); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), 3); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-5b.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-5b.js new file mode 100644 index 0000000000..37ce077723 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-5b.js @@ -0,0 +1,40 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// Array.prototype[@@iterator] was modified. +function test() { + function maybeInvalidate() { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i === 1900) { + var ArrayPrototypeIterator = Array.prototype[Symbol.iterator]; + Array.prototype[Symbol.iterator] = function() { + return ArrayPrototypeIterator.call([3, 4]); + }; + } + } + function fn(...rest) { + maybeInvalidate(); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), i < 1900 ? 3 : 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-6a.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-6a.js new file mode 100644 index 0000000000..64d96b4de8 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-6a.js @@ -0,0 +1,38 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// %ArrayIteratorPrototype%'s [[Prototype]] was changed, as a result all properties are marked as unknown. +function test() { + function maybeInvalidate() { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i === 1900) { + var ArrayIteratorPrototype = Object.getPrototypeOf(Array.prototype[Symbol.iterator]()); + Object.setPrototypeOf(ArrayIteratorPrototype, null); + } + } + function fn(...rest) { + maybeInvalidate(); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), 3); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-6b.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-6b.js new file mode 100644 index 0000000000..a95e3f145c --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-dynamic-6b.js @@ -0,0 +1,45 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL no longer apply after the initial Ion +// compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// %ArrayIteratorPrototype%.next was modified. +function test() { + function maybeInvalidate() { + // Use a WithStatement to prevent Ion-inlining. This ensures any + // bailouts due to type changes don't occur in this function, but + // instead in the caller. + with ({}); + + if (i === 1900) { + var ArrayIteratorPrototype = Object.getPrototypeOf(Array.prototype[Symbol.iterator]()); + var ArrayIteratorPrototypeNext = ArrayIteratorPrototype.next; + ArrayIteratorPrototype.next = function() { + var res = ArrayIteratorPrototypeNext.call(this); + if (!res.done) { + res.value += 2; + } + return res; + }; + } + } + function fn(...rest) { + maybeInvalidate(); + return add(...rest); + } + for (var i = 0; i < 4000; ++i) { + assertEq(fn(1, 2), i < 1900 ? 3 : 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-1.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-1.js new file mode 100644 index 0000000000..bccd64c762 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-1.js @@ -0,0 +1,33 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// The rest argument is overwritten with a non-Array object. +function test() { + var badRest = { + *[Symbol.iterator]() { + yield 3; + yield 4; + } + }; + function fn(...rest) { + rest = badRest; + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-2a.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-2a.js new file mode 100644 index 0000000000..e9ec676c91 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-2a.js @@ -0,0 +1,27 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b, c = 0, d = 0) { + return a + b + c + d; +} + +// The rest argument contains holes. +function test() { + function fn(...rest) { + rest[3] = 4; + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-2b.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-2b.js new file mode 100644 index 0000000000..47e761d5a1 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-2b.js @@ -0,0 +1,27 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b, c = 0, d = 0) { + return a + b + c + d; +} + +// The rest argument is a packed array. +function test() { + function fn(...rest) { + rest.length = 3; + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 3); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-3.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-3.js new file mode 100644 index 0000000000..8bae3c19d2 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-3.js @@ -0,0 +1,30 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// The rest argument has an own @@iterator property. +function test() { + function MyIter() { + return [3, 4][Symbol.iterator](); + } + function fn(...rest) { + rest[Symbol.iterator] = MyIter; + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-4a.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-4a.js new file mode 100644 index 0000000000..d3bdb98869 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-4a.js @@ -0,0 +1,32 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// The rest arguments don't share a common prototype. +function test() { + class MyArray1 extends Array { } + class MyArray2 extends Array { } + function fn(...rest) { + if (i & 1) + rest = new MyArray1(3, 4); + else + rest = new MyArray2(5, 6); + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), (i & 1) ? 7 : 11); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-4b.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-4b.js new file mode 100644 index 0000000000..bdc2acbc8e --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-4b.js @@ -0,0 +1,28 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// The rest argument's prototype isn't Array.prototype. +function test() { + class MyArray extends Array { } + function fn(...rest) { + rest = new MyArray(3, 4); + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-5a.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-5a.js new file mode 100644 index 0000000000..4d5d8fec85 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-5a.js @@ -0,0 +1,27 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// Array.prototype's [[Prototype]] was changed, as a result all properties are marked as unknown. +function test() { + Object.setPrototypeOf(Array.prototype, null); + function fn(...rest) { + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 3); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-5b.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-5b.js new file mode 100644 index 0000000000..1302cfbedf --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-5b.js @@ -0,0 +1,30 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// Array.prototype[@@iterator] was modified. +function test() { + var ArrayPrototypeIterator = Array.prototype[Symbol.iterator]; + Array.prototype[Symbol.iterator] = function() { + return ArrayPrototypeIterator.call([3, 4]); + }; + function fn(...rest) { + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-6a.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-6a.js new file mode 100644 index 0000000000..c23a56bed0 --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-6a.js @@ -0,0 +1,28 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// %ArrayIteratorPrototype%'s [[Prototype]] was changed, as a result all properties are marked as unknown. +function test() { + var ArrayIteratorPrototype = Object.getPrototypeOf(Array.prototype[Symbol.iterator]()); + Object.setPrototypeOf(ArrayIteratorPrototype, null); + function fn(...rest) { + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 3); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-6b.js b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-6b.js new file mode 100644 index 0000000000..b666cadc3c --- /dev/null +++ b/js/src/jit-test/tests/ion/spreadcall-not-optimized-static-6b.js @@ -0,0 +1,35 @@ +// Tests when JSOP_OPTIMIZE_SPREADCALL can't be applied during the initial +// Ion compilation. + +// JSOP_OPTIMIZE_SPREADCALL can be optimised when the following conditions +// are fulfilled: +// (1) the argument is an array +// (2) the array has no hole +// (3) array[@@iterator] is not modified +// (4) the array's prototype is Array.prototype +// (5) Array.prototype[@@iterator] is not modified +// (6) %ArrayIteratorPrototype%.next is not modified + +function add(a, b) { + return a + b; +} + +// %ArrayIteratorPrototype%.next was modified. +function test() { + var ArrayIteratorPrototype = Object.getPrototypeOf(Array.prototype[Symbol.iterator]()); + var ArrayIteratorPrototypeNext = ArrayIteratorPrototype.next; + ArrayIteratorPrototype.next = function() { + var res = ArrayIteratorPrototypeNext.call(this); + if (!res.done) { + res.value += 2; + } + return res; + }; + function fn(...rest) { + return add(...rest); + } + for (var i = 0; i < 2000; ++i) { + assertEq(fn(1, 2), 7); + } +} +test(); diff --git a/js/src/jit-test/tests/ion/stack-alignment-bug1126375.js b/js/src/jit-test/tests/ion/stack-alignment-bug1126375.js new file mode 100644 index 0000000000..29c217aadc --- /dev/null +++ b/js/src/jit-test/tests/ion/stack-alignment-bug1126375.js @@ -0,0 +1,7 @@ +function entryFrame_1(d) { + assertJitStackInvariants(); +} +for (i = 0Xa; i < 40; i++) { + entryFrame_1(); +} + diff --git a/js/src/jit-test/tests/ion/stack-alignment.js b/js/src/jit-test/tests/ion/stack-alignment.js new file mode 100644 index 0000000000..0bd4ad5fba --- /dev/null +++ b/js/src/jit-test/tests/ion/stack-alignment.js @@ -0,0 +1,166 @@ +setJitCompilerOption("baseline.warmup.trigger", 10); +setJitCompilerOption("ion.warmup.trigger", 30); +var i; + +// Check that an entry frame is always aligned properly. +function entryFrame_1() { + assertJitStackInvariants(); +} + +// Check rectifier frames are keeping the same alignment. +function rectifierFrame_verify(a, b, c, d) { + assertJitStackInvariants(); +} + +function rectifierFrame_1(i) { + rectifierFrame_verify(); +} +function rectifierFrame_2(i) { + rectifierFrame_verify(i); +} +function rectifierFrame_3(i) { + rectifierFrame_verify(i, i); +} +function rectifierFrame_4(i) { + rectifierFrame_verify(i, i, i); +} + +// Check that an ion frame size is always aligned properly. +function gen_ionFrameSize(x, y, name) { + var locals = (new Array(x)).fill(0).map((v, i) => i); + var args = (new Array(y)).fill(0).map((v, i) => i); + + return new Function("i", + locals.map(i => "var l% = i + %;\n".replace(/%/g, i)).join("") + + name + "(" + args.map(i => "l%".replace("%", i)).join(", ") + ");\n" + + "return " + locals.map(i => "l%".replace("%", i)).join(" + ") + ";\n" + ); +} + +var ionFrameSize_0 = gen_ionFrameSize(30, 0, "assertJitStackInvariants"); +var ionFrameSize_1 = gen_ionFrameSize(31, 0, "assertJitStackInvariants"); +var ionFrameSize_2 = gen_ionFrameSize(32, 0, "assertJitStackInvariants"); +var ionFrameSize_3 = gen_ionFrameSize(33, 0, "assertJitStackInvariants"); + +function ionFrameSize_callee_verify(a, b, c, d) { + assertJitStackInvariants(); +} + +var ionFrameSize_args = []; +for (var l = 0; l < 4; l++) { + ionFrameSize_args[l] = []; + for (var a = 0; a < 4; a++) + ionFrameSize_args[l][a] = gen_ionFrameSize(30 + l, a, "ionFrameSize_callee_verify");; +} + +// Check ion frames during function apply calls with the argument vector. +function ionFrame_funApply_0() { + assertJitStackInvariants.apply(this, arguments); +} +function ionFrame_funApply_1() { + ionFrame_funApply_0.apply(this, arguments); +} + +// Check ion frames during function apply calls with an array of arguments. +function ionFrame_funApply_2() { + var arr = Array.apply(Array, arguments); + assertJitStackInvariants.apply(this, arr); +} +function ionFrame_funApply_3() { + var arr = Array.apply(Array, arguments); + ionFrame_funApply_2.apply(this, arr); +} + +// Check ion frames during function .call calls. +function ionFrame_funCall_0() { + assertJitStackInvariants.call(this); +} +function ionFrame_funCall_1(a) { + assertJitStackInvariants.call(this, a); +} +function ionFrame_funCall_2(a, b) { + assertJitStackInvariants.call(this, a, b); +} +function ionFrame_funCall_3(a, b, c) { + assertJitStackInvariants.call(this, a, b, c); +} + +function ionFrame_funCall_x0() { + ionFrame_funCall_0.call(this); +} +function ionFrame_funCall_x1(a) { + ionFrame_funCall_1.call(this, a); +} +function ionFrame_funCall_x2(a, b) { + ionFrame_funCall_2.call(this, a, b); +} +function ionFrame_funCall_x3(a, b, c) { + ionFrame_funCall_3.call(this, a, b, c); +} + +// Check ion frames during spread calls. +function ionFrame_spreadCall_0() { + var arr = Array.apply(Array, arguments); + assertJitStackInvariants(...arr); +} +function ionFrame_spreadCall_1() { + var arr = Array.apply(Array, arguments); + ionFrame_spreadCall_0(...arr); +} + + +for (i = 0; i < 40; i++) { + entryFrame_1(); + entryFrame_1(0); + entryFrame_1(0, 1); + + rectifierFrame_1(i); + rectifierFrame_2(i); + rectifierFrame_3(i); + rectifierFrame_4(i); + + ionFrameSize_0(i); + ionFrameSize_1(i); + ionFrameSize_2(i); + ionFrameSize_3(i); + + for (var l = 0; l < 4; l++) + for (var a = 0; a < 4; a++) + ionFrameSize_args[l][a](i); + + ionFrame_funApply_0(); + ionFrame_funApply_0(1); + ionFrame_funApply_0(1, 2); + ionFrame_funApply_0(1, 2, 3); + ionFrame_funApply_1(); + ionFrame_funApply_1(1); + ionFrame_funApply_1(1, 2); + ionFrame_funApply_1(1, 2, 3); + + ionFrame_funApply_2(); + ionFrame_funApply_2(1); + ionFrame_funApply_2(1, 2); + ionFrame_funApply_2(1, 2, 3); + ionFrame_funApply_3(); + ionFrame_funApply_3(1); + ionFrame_funApply_3(1, 2); + ionFrame_funApply_3(1, 2, 3); + + ionFrame_funCall_0(); + ionFrame_funCall_1(1); + ionFrame_funCall_2(1, 2); + ionFrame_funCall_3(1, 2, 3); + ionFrame_funCall_x0(); + ionFrame_funCall_x1(1); + ionFrame_funCall_x2(1, 2); + ionFrame_funCall_x3(1, 2, 3); + + ionFrame_spreadCall_0(); + ionFrame_spreadCall_0(1); + ionFrame_spreadCall_0(1, 2); + ionFrame_spreadCall_0(1, 2, 3); + ionFrame_spreadCall_1(); + ionFrame_spreadCall_1(1); + ionFrame_spreadCall_1(1, 2); + ionFrame_spreadCall_1(1, 2, 3); +} diff --git a/js/src/jit-test/tests/ion/string-compare.js b/js/src/jit-test/tests/ion/string-compare.js new file mode 100644 index 0000000000..001d0856e2 --- /dev/null +++ b/js/src/jit-test/tests/ion/string-compare.js @@ -0,0 +1,9 @@ +function f(a, b) { + return a == b; +} + +var X = "" + Math.random(); +var Y = "" + Math.random(); + +assertEq(f(X + Y, X + Y), true); + diff --git a/js/src/jit-test/tests/ion/string-concat-short.js b/js/src/jit-test/tests/ion/string-concat-short.js new file mode 100644 index 0000000000..a0108df044 --- /dev/null +++ b/js/src/jit-test/tests/ion/string-concat-short.js @@ -0,0 +1,13 @@ +function f() { + var res = 0; + for (var i=0; i<100; i++) { + var s = "test" + i; + res += s.length; + assertEq(s[0], "t"); + assertEq(s[3], "t"); + if (i > 90) + assertEq(s[4], "9"); + } + return res; +} +assertEq(f(), 590); diff --git a/js/src/jit-test/tests/ion/super-getelem-profiling.js b/js/src/jit-test/tests/ion/super-getelem-profiling.js new file mode 100644 index 0000000000..76aaf28707 --- /dev/null +++ b/js/src/jit-test/tests/ion/super-getelem-profiling.js @@ -0,0 +1,12 @@ +enableGeckoProfiling(); + +class base {} +class derived extends base { + testElem() { + super[ruin()]; + } +} +let instance = new derived(); +try { + instance.testElem(); +} catch { /* don't crash */ } diff --git a/js/src/jit-test/tests/ion/super-prop.js b/js/src/jit-test/tests/ion/super-prop.js new file mode 100644 index 0000000000..004284730f --- /dev/null +++ b/js/src/jit-test/tests/ion/super-prop.js @@ -0,0 +1,87 @@ +class Y { + a() { + assertEq(this.__proto__, X.prototype); + return 1; + } + b() { + assertEq(this.__proto__, X.prototype); + return 2; + } +} + +class X extends Y { + a() { throw "not invoked"; } + b() { + return super.a() + super.b(); + } + c(i) { + var a, b; + + if (i % 2) { + a = "a"; + b = "b" + } else { + a = "b"; + b = "a"; + } + + return super[a]() + super[b](); + } +} + +function simple() { + var x = new X(); + assertEq(x.b(), 3); + assertEq(x.c(), 3); +} + +class A { + b() { return 1;} +} +class B extends A { + a() { + assertEq(super.b(), 1); + } +} + +function nullHomeObjectSuperBase(i) { + var b = new B(); + if (i == 500) { + Object.setPrototypeOf(B.prototype, null); + // Don't crash + } + b.a(); +} + +class SArray extends Array { + constructor() { + super("a", "b"); + } + + a() { + assertEq(super.length, 0); + assertEq(this.length, 2); + + assertEq(this[0], "a"); + assertEq(this[1], "b"); + + assertEq(super[0], undefined); + assertEq(super[1], undefined); + } +} + +function array() { + var s = new SArray(); + s.a(); +} + +for (var i = 0; i < 1e4; i++) { + simple(); + array(); + + try { + nullHomeObjectSuperBase(i); + } catch (e) { + assertEq(i >= 500, true); + } +} diff --git a/js/src/jit-test/tests/ion/template-tag-callsiteobject.js b/js/src/jit-test/tests/ion/template-tag-callsiteobject.js new file mode 100644 index 0000000000..4d1cdcbf41 --- /dev/null +++ b/js/src/jit-test/tests/ion/template-tag-callsiteobject.js @@ -0,0 +1,26 @@ +function tagA(strings) { + assertEq(strings.length, 2); + assertEq(strings[0], "a"); + assertEq(strings[1], ""); +} + +function tagAB(strings) { + assertEq(strings.length, 2); + assertEq(strings[0], "a"); + assertEq(strings[1], "b"); +} + +var data = [1, 2, 3]; +function tag(strings, value1, value2) { + return strings[0] + value1 + strings[1] + value2 + strings[2]; +} + +function complex() { + return tag`${data[0]} ${data[1] + data[2]}`; +} + +for (var i = 0; i < 20; i++) { + tagA`a${0}`; + tagAB`a${0}b`; + assertEq(complex(), "1 5"); +} diff --git a/js/src/jit-test/tests/ion/test-scalar-replacement-float32.js b/js/src/jit-test/tests/ion/test-scalar-replacement-float32.js new file mode 100644 index 0000000000..3302381f14 --- /dev/null +++ b/js/src/jit-test/tests/ion/test-scalar-replacement-float32.js @@ -0,0 +1,98 @@ +setJitCompilerOption("ion.warmup.trigger", 30); +var max = 40; + +// This test case verify that even if we do some scalar replacement, we keep a +// correct computation of Float32 maths. In this case, when the object is not +// escaped, the "store" instruction are preventing any float32 optimization to +// kick-in. After Scalar Replacement, the store is removed, and the Float32 +// optimizations can avoid Double coercions. +function escape_object(o) { + if (o.e) { + print(o); + } +} + +var func = null; +var check_object_argument_func = function (i, res) { + with ({}) { /* trun off the jit for this function, do not inline */ }; + if (i == max - 1) + return funname.arguments[1].d; + return res; +}; + +var test_object_ref_check = eval(`(${check_object_argument_func})`.replace("funname", "test_object_ref")); +function test_object_ref(x, tmp) { + tmp = { + a: Math.fround(Math.pow(2 * x / max, 0)), + b: Math.fround(Math.pow(2 * x / max, 25)), + c: Math.fround(Math.pow(2 * x / max, 50)), + d: 0 + }; + + tmp.d = tmp.a + tmp.b; + assertFloat32(tmp.d, false); + escape_object(tmp); + return test_object_ref_check(x, Math.fround(tmp.c + Math.fround(tmp.d))); +} + +var test_object_check = eval(`(${check_object_argument_func})`.replace("funname", "test_object")); +function test_object(x, tmp) { + tmp = { + a: Math.fround(Math.pow(2 * x / max, 0)), + b: Math.fround(Math.pow(2 * x / max, 25)), + c: Math.fround(Math.pow(2 * x / max, 50)), + d: 0 + }; + + tmp.d = tmp.a + tmp.b; + assertFloat32(tmp.d, false); + return test_object_check(x, Math.fround(tmp.c + Math.fround(tmp.d))); +} + +// Same test with Arrays. +function escape_array(o) { + if (o.length == 0) { + print(o); + } +} + +var check_array_argument_func = function (i, res) { + with ({}) { /* trun off the jit for this function, do not inline */ }; + if (i == max - 1) { + return funname.arguments[1][3]; + } + return res; +}; + +var test_array_ref_check = eval(`(${check_array_argument_func})`.replace("funname", "test_array_ref")); +function test_array_ref(x, tmp) { + tmp = [ + Math.fround(Math.pow(2 * x / max, 0)), + Math.fround(Math.pow(2 * x / max, 25)), + Math.fround(Math.pow(2 * x / max, 50)), + 0 + ]; + tmp[3] = tmp[0] + tmp[1]; + assertFloat32(tmp[3], false); + escape_array(tmp); + return test_array_ref_check(x, Math.fround(tmp[2] + Math.fround(tmp[3]))); +} + +var test_array_check = eval(`(${check_array_argument_func})`.replace("funname", "test_array")); +function test_array(x, tmp) { + tmp = [ + Math.fround(Math.pow(2 * x / max, 0)), + Math.fround(Math.pow(2 * x / max, 25)), + Math.fround(Math.pow(2 * x / max, 50)), + 0 + ]; + tmp[3] = tmp[0] + tmp[1]; + assertFloat32(tmp[3], false); + return test_array_check(x, Math.fround(tmp[2] + Math.fround(tmp[3]))); +} + + +for (var i = 0; i < max; i++) { + assertEq(test_object_ref(i, undefined), test_object(i, undefined)); + assertEq(test_array_ref(i, undefined), test_array(i, undefined)); +} diff --git a/js/src/jit-test/tests/ion/testArrayBufferByteLength.js b/js/src/jit-test/tests/ion/testArrayBufferByteLength.js new file mode 100644 index 0000000000..0eb75b5dd5 --- /dev/null +++ b/js/src/jit-test/tests/ion/testArrayBufferByteLength.js @@ -0,0 +1,20 @@ +var ArrayBufferByteLength = getSelfHostedValue("ArrayBufferByteLength"); + +setJitCompilerOption("ion.warmup.trigger", 50); + +function testBasic() { + var arr = [1, 2, 3]; + var tarr = new Int32Array(arr); + var abuf = tarr.buffer; + + var arrLength = arr.length; + var bytesPerElement = Int32Array.BYTES_PER_ELEMENT; + + var f = function() { + assertEq(ArrayBufferByteLength(abuf), arrLength * bytesPerElement); + }; + do { + f(); + } while (!inIon()); +} +testBasic(); diff --git a/js/src/jit-test/tests/ion/testFloat32-correctness.js b/js/src/jit-test/tests/ion/testFloat32-correctness.js new file mode 100644 index 0000000000..8321e6bfab --- /dev/null +++ b/js/src/jit-test/tests/ion/testFloat32-correctness.js @@ -0,0 +1,340 @@ +setJitCompilerOption("ion.warmup.trigger", 50); + +var f32 = new Float32Array(10); + +function test(setup, f) { + if (f === undefined) { + f = setup; + setup = function(){}; + } + setup(); + for(var n = 200; n; --n) { + f(); + } +} + +// Basic arithmetic +function setupBasicArith() { + f32[0] = -Infinity; + f32[1] = -1; + f32[2] = -0; + f32[3] = 0; + f32[4] = 1.337; + f32[5] = 42; + f32[6] = Infinity; + f32[7] = NaN; +} +function basicArith() { + for (var i = 0; i < 7; ++i) { + var opf = Math.fround(f32[i] + f32[i+1]); + var opd = (1 / (1 / f32[i])) + f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] - f32[i+1]); + opd = (1 / (1 / f32[i])) - f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] * f32[i+1]); + opd = (1 / (1 / f32[i])) * f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] / f32[i+1]); + opd = (1 / (1 / f32[i])) / f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + } +} +test(setupBasicArith, basicArith); + +// MAbs +function setupAbs() { + f32[0] = -0; + f32[1] = 0; + f32[2] = -3.14159; + f32[3] = 3.14159; + f32[4] = -Infinity; + f32[5] = Infinity; + f32[6] = NaN; +} +function abs() { + for(var i = 0; i < 7; ++i) { + assertEq( Math.fround(Math.abs(f32[i])), Math.abs(f32[i]) ); + } +} +test(setupAbs, abs); + +// MSqrt +function setupSqrt() { + f32[0] = 0; + f32[1] = 1; + f32[2] = 4; + f32[3] = -1; + f32[4] = Infinity; + f32[5] = NaN; + f32[6] = 13.37; +} +function sqrt() { + for(var i = 0; i < 7; ++i) { + var sqrtf = Math.fround(Math.sqrt(f32[i])); + var sqrtd = 1 + Math.sqrt(f32[i]) - 1; // force no float32 by chaining arith ops + assertEq( sqrtf, Math.fround(sqrtd) ); + } +} +test(setupSqrt, sqrt); + +// MMinMax +function setupMinMax() { + f32[0] = -0; + f32[1] = 0; + f32[2] = 1; + f32[3] = 4; + f32[4] = -1; + f32[5] = Infinity; + f32[6] = NaN; + f32[7] = 13.37; + f32[8] = -Infinity; + f32[9] = Math.pow(2,31) - 1; +} +function minMax() { + for(var i = 0; i < 9; ++i) { + for(var j = 0; j < 9; j++) { + var minf = Math.fround(Math.min(f32[i], f32[j])); + var mind = 1 / (1 / Math.min(f32[i], f32[j])); // force no float32 by chaining arith ops + assertFloat32(minf, true); + assertFloat32(mind, false); + assertEq( minf, Math.fround(mind) ); + + var maxf = Math.fround(Math.max(f32[i], f32[j])); + var maxd = 1 / (1 / Math.max(f32[i], f32[j])); // force no float32 by chaining arith ops + assertFloat32(maxf, true); + assertFloat32(maxd, false); + assertEq( maxf, Math.fround(maxd) ); + } + } +} +test(setupMinMax, minMax); + +// MTruncateToInt32 +// The only way to get a MTruncateToInt32 with a Float32 input is to use Math.imul +function setupTruncateToInt32() { + f32[0] = -1; + f32[1] = 4; + f32[2] = 5.13; +} +function truncateToInt32() { + assertEq( Math.imul(f32[0], f32[1]), Math.imul(-1, 4) ); + assertEq( Math.imul(f32[1], f32[2]), Math.imul(4, 5) ); +} +test(setupTruncateToInt32, truncateToInt32); + +// MCompare +function comp() { + for(var i = 0; i < 9; ++i) { + assertEq( f32[i] < f32[i+1], true ); + } +} +function setupComp() { + f32[0] = -Infinity; + f32[1] = -1; + f32[2] = -0.01; + f32[3] = 0; + f32[4] = 0.01; + f32[5] = 1; + f32[6] = 10; + f32[7] = 13.37; + f32[8] = 42; + f32[9] = Infinity; +} +test(setupComp, comp); + +// MNot +function setupNot() { + f32[0] = -0; + f32[1] = 0; + f32[2] = 1; + f32[3] = NaN; + f32[4] = Infinity; + f32[5] = 42; + f32[6] = -23; +} +function not() { + assertEq( !f32[0], true ); + assertEq( !f32[1], true ); + assertEq( !f32[2], false ); + assertEq( !f32[3], true ); + assertEq( !f32[4], false ); + assertEq( !f32[5], false ); + assertEq( !f32[6], false ); +} +test(setupNot, not); + +// MToNumberInt32 +var str = "can haz cheezburger? okthxbye;"; +function setupToInt32() { + f32[0] = 0; + f32[1] = 1; + f32[2] = 2; + f32[3] = 4; + f32[4] = 5; +} +function testToInt32() { + assertEq(str[f32[0]], 'c'); + assertEq(str[f32[1]], 'a'); + assertEq(str[f32[2]], 'n'); + assertEq(str[f32[3]], 'h'); + assertEq(str[f32[4]], 'a'); +} +test(setupToInt32, testToInt32); + +function setupBailoutToInt32() { + f32[0] = .5; +} +function testBailoutToInt32() { + assertEq(typeof str[f32[0]], 'undefined'); +} +test(setupBailoutToInt32, testBailoutToInt32); + +// MMath (no trigo - see also testFloat32-trigo.js +function assertNear(a, b) { + var r = (a != a && b != b) || Math.abs(a-b) < 1e-1 || a === b; + if (!r) { + print('Precision error: '); + print(new Error().stack); + print('Got', a, ', expected near', b); + assertEq(false, true); + } +} + +function setupOtherMath() { + setupComp(); + f32[8] = 4.2; +} +function otherMath() { + for (var i = 0; i < 9; ++i) { + assertNear(Math.fround(Math.exp(f32[i])), Math.exp(f32[i])); + assertNear(Math.fround(Math.log(f32[i])), Math.log(f32[i])); + } +}; +test(setupOtherMath, otherMath); + +function setupFloor() { + f32[0] = -5.5; + f32[1] = -0.5; + f32[2] = 0; + f32[3] = 1.5; +} +function setupFloorDouble() { + f32[4] = NaN; + f32[5] = -0; + f32[6] = Infinity; + f32[7] = -Infinity; + f32[8] = Math.pow(2,31); // too big to fit into a int +} +function testFloor() { + for (var i = 0; i < 4; ++i) { + var f = Math.floor(f32[i]); + assertFloat32(f, false); // f is an int32 + + var g = Math.floor(-0 + f32[i]); + assertFloat32(g, false); + + assertEq(f, g); + } +} +function testFloorDouble() { + for (var i = 4; i < 9; ++i) { + var f = Math.fround(Math.floor(f32[i])); + assertFloat32(f, true); + + var g = Math.floor(-0 + f32[i]); + assertFloat32(g, false); + + assertEq(f, g); + } +} +test(setupFloor, testFloor); +test(setupFloorDouble, testFloorDouble); + +function setupRound() { + f32[0] = -5.5; + f32[1] = -0.6; + f32[2] = 1.5; + f32[3] = 1; +} +function setupRoundDouble() { + f32[4] = NaN; + f32[5] = -0.49; // rounded to -0 + f32[6] = Infinity; + f32[7] = -Infinity; + f32[8] = Math.pow(2,31); // too big to fit into a int + f32[9] = -0; +} +function testRound() { + for (var i = 0; i < 4; ++i) { + var r32 = Math.round(f32[i]); + assertFloat32(r32, false); // r32 is an int32 + + var r64 = Math.round(-0 + f32[i]); + assertFloat32(r64, false); + + assertEq(r32, r64); + } +} +function testRoundDouble() { + for (var i = 4; i < 10; ++i) { + var r32 = Math.fround(Math.round(f32[i])); + assertFloat32(r32, true); + + var r64 = Math.round(-0 + f32[i]); + assertFloat32(r64, false); + + assertEq(r32, r64); + } +} +test(setupRound, testRound); +test(setupRoundDouble, testRoundDouble); + +function setupCeil() { + f32[0] = -5.5; + f32[1] = -1.5; + f32[2] = 0; + f32[3] = 1.5; +} +function setupCeilDouble() { + f32[4] = NaN; + f32[5] = -0; + f32[6] = Infinity; + f32[7] = -Infinity; + f32[8] = Math.pow(2,31); // too big to fit into a int +} +function testCeil() { + for(var i = 0; i < 2; ++i) { + var f = Math.ceil(f32[i]); + assertFloat32(f, false); + + var g = Math.ceil(-0 + f32[i]); + assertFloat32(g, false); + + assertEq(f, g); + } +} +function testCeilDouble() { + for(var i = 4; i < 9; ++i) { + var f = Math.fround(Math.ceil(f32[i])); + assertFloat32(f, true); + + var g = Math.ceil(-0 + f32[i]); + assertFloat32(g, false); + + assertEq(f, g); + } +} +test(setupCeil, testCeil); +test(setupCeilDouble, testCeilDouble); diff --git a/js/src/jit-test/tests/ion/testFloat32.js b/js/src/jit-test/tests/ion/testFloat32.js new file mode 100644 index 0000000000..5d7d598bed --- /dev/null +++ b/js/src/jit-test/tests/ion/testFloat32.js @@ -0,0 +1,532 @@ +// |jit-test| --baseline-warmup-threshold=20 + +// This test checks that we are able to optimize float32 inputs. As +// GetElementIC (float32 array accesses) output is not specialized with Float32 +// output types, we should not force inline caches. +if (getJitCompilerOptions()["ion.forceinlineCaches"]) + setJitCompilerOption("ion.forceinlineCaches", 0); + +// Fuzz tests +(function(){ + // + (function(){ + var g = {}; + x = new Float32Array() + Function('g', "g.o = x[1]")(g); + })(); + // + (function() { + var g = new Float32Array(16); + var h = new Float64Array(16); + var farrays = [ g, h ]; + for (aridx = 0; aridx < farrays.length; ++aridx) { + ar = farrays[aridx]; + !(ar[ar.length-2] == (NaN / Infinity)[ar.length-2]) + } + })(); + // + (function () { + var v = new Float32Array(32); + for (var i = 0; i < v.length; ++i) + v[i] = i; + var t = (false ); + for (var i = 0; i < i .length; ++i) + t += v[i]; + })(); + // + (function() { + x = y = {}; + z = new Float32Array(6) + for (c in this) { + Array.prototype.unshift.call(x, new ArrayBuffer()) + } + Array.prototype.sort.call(x, (function (j) { + y.s = z[2] + })) + })(); + // + (function() { + // bug 1134298 + for (var k = 0; k < 1; k++) { + Math.fround(Math.ceil(Math.fround(Math.acos(3.0)))) + } + })(); +})(); +// +// ION TESTS +// +// The assertFloat32 function is deactivated in --ion-eager mode, as the first time, the function Math.fround +// would be guarded against modifications (typeguard on Math and then on fround). In this case, Math.fround is +// not inlined and the compiler will consider the return value to be a double, not a float32, making the +// assertions fail. Note that as assertFloat32 is declared unsafe for fuzzing, this can't happen in fuzzed code. +// +// To be able to test it, we still need ion compilation though. A nice solution +// is to manually lower the ion warm-up trigger. +setJitCompilerOption("ion.warmup.trigger", 50); + +function test(f) { + f32[0] = .5; + for(var n = 110; n; n--) + f(); +} + +var f32 = new Float32Array(4); +var f64 = new Float64Array(4); + +function acceptAdd() { + var use = f32[0] + 1; + assertFloat32(use, true); + f32[0] = use; +} +test(acceptAdd); + +function acceptAddSeveral() { + var sum1 = f32[0] + 0.5; + var sum2 = f32[0] + 0.5; + f32[0] = sum1; + f32[0] = sum2; + assertFloat32(sum1, true); + assertFloat32(sum2, true); +} +test(acceptAddSeveral); + +function acceptAddVar() { + var x = f32[0] + 1; + f32[0] = x; + f32[1] = x; + assertFloat32(x, true); +} +test(acceptAddVar); + +function refuseAddCst() { + var x = f32[0] + 1234567890; // this constant can't be precisely represented as a float32 + f32[0] = x; + assertFloat32(x, false); +} +test(refuseAddCst); + +function refuseAddVar() { + var x = f32[0] + 1; + f32[0] = x; + f32[1] = x; + f64[1] = x; // non consumer + assertFloat32(x, false); +} +test(refuseAddVar); + +function refuseAddStore64() { + var x = f32[0] + 1; + f64[0] = x; // non consumer + f32[0] = f64[0]; + assertFloat32(x, false); +} +test(refuseAddStore64); + +function refuseAddStoreObj() { + var o = {} + var x = f32[0] + 1; + o.x = x; // non consumer + f32[0] = o['x']; + assertFloat32(x, false); +} +test(refuseAddStoreObj); + +function refuseAddSeveral() { + var sum = (f32[0] + 2) - 1; // second addition is not a consumer + f32[0] = sum; + assertFloat32(sum, false); +} +test(refuseAddSeveral); + +function refuseAddFunctionCall() { + function plusOne(x) { return Math.cos(x+1)*13.37; } + var res = plusOne(f32[0]); // func call is not a consumer + f32[0] = res; + assertFloat32(res, false); +} +test(refuseAddFunctionCall); + +function acceptSqrt() { + var res = Math.sqrt(f32[0]); + assertFloat32(res, true); + f32[0] = res; +} +test(acceptSqrt); + +function refuseSqrt() { + var res = Math.sqrt(f32[0]); + assertFloat32(res, false); + f32[0] = res + 1; +} +test(refuseSqrt); + +function acceptMin() { + var res = Math.min(f32[0], f32[1]); + assertFloat32(res, true); + f64[0] = res; +} +test(acceptMin); + +// In theory, we could do it, as Math.min/max actually behave as a Phi (it's a +// float32 producer iff its inputs are producers, it's a consumer iff its uses +// are consumers). In practice, this would involve some overhead for big chains +// of min/max. +function refuseMinAdd() { + var res = Math.min(f32[0], f32[1]) + f32[2]; + assertFloat32(res, false); + f32[3] = res; +} +test(refuseMinAdd); + +function acceptSeveralMinMax() { + var x = Math.min(f32[0], f32[1]); + var y = Math.max(f32[2], f32[3]); + var res = Math.min(x, y); + assertFloat32(res, true); + f64[0] = res; +} +test(acceptSeveralMinMax); + +function acceptSeveralMinMax2() { + var res = Math.min(f32[0], f32[1], f32[2], f32[3]); + assertFloat32(res, true); + f64[0] = res; +} +test(acceptSeveralMinMax2); + +function partialMinMax() { + var x = Math.min(f32[0], f32[1]); + var y = Math.min(f64[0], f32[1]); + var res = Math.min(x, y); + assertFloat32(x, true); + assertFloat32(y, false); + assertFloat32(res, false); + f64[0] = res; +} +test(partialMinMax); + +function refuseSeveralMinMax() { + var res = Math.min(f32[0], f32[1] + f32[2], f32[2], f32[3]); + assertFloat32(res, false); + f64[0] = res; +} +test(refuseSeveralMinMax); + +function refuseMin() { + var res = Math.min(f32[0], 42.13 + f32[1]); + assertFloat32(res, false); + f64[0] = res; +} +test(refuseMin); + +function acceptMax() { + var res = Math.max(f32[0], f32[1]); + assertFloat32(res, true); + f64[0] = res; +} +test(acceptMax); + +function refuseMax() { + var res = Math.max(f32[0], 42.13 + f32[1]); + assertFloat32(res, false); + f64[0] = res; +} +test(refuseMax); + +function acceptAbs() { + var res = Math.abs(f32[0]); + assertFloat32(res, true); + f32[0] = res; +} +test(acceptAbs); + +function refuseAbs() { + var res = Math.abs(f32[0]); + assertFloat32(res, false); + f64[0] = res + 1; +} +test(refuseAbs); + +function acceptFilterTypeSet() { + var res = f32[0]; + if (!res) { + } else { + f32[0] = res; + assertFloat32(res, true); + } +} +test(acceptFilterTypeSet); + +function acceptFilterTypeSet2() { + var res = f32[0]; + if (!res) { + } else { + var res1 = Math.abs(res); + f32[0] = res1; + assertFloat32(res1, true); + } +} +test(acceptFilterTypeSet2); + +function refuseFilterTypeSet() { + var res = f32[0]; + if (!res) { + } else { + var res1 = Math.abs(res); + f64[0] = res1 + 1; + assertFloat32(res1, false); + } +} +test(refuseFilterTypeSet); + +function refuseTrigo() { + var res = Math.cos(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + var res = Math.sin(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + var res = Math.tan(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + var res = Math.acos(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + var res = Math.asin(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.atan(f32[0]); + f32[0] = res; + assertFloat32(res, false); +} +test(refuseTrigo); + +function acceptCeil() { + // Specialize for floating-point output. + f32[0] = NaN; + f32[1] = Infinity; + f32[2] = -0; + f32[3] = 0.5; + + var res = Math.ceil(f32[0]); + f32[0] = res; + assertFloat32(res, true); +} +test(acceptCeil); + +function acceptFloor() { + // Specialize for floating-point output. + f32[0] = NaN; + f32[1] = Infinity; + f32[2] = -0; + f32[3] = 0.5; + + var res = Math.floor(f32[0]); + f32[0] = res; + assertFloat32(res, true); +} +test(acceptFloor); + +function acceptRound() { + // Specialize for floating-point output. + f32[0] = NaN; + f32[1] = Infinity; + f32[2] = -0; + f32[3] = 0.5; + + var res = Math.round(f32[0]); + f32[0] = res; + assertFloat32(res, true); +} +test(acceptRound); + +function acceptTrunc() { + // Specialize for floating-point output. + f32[0] = NaN; + f32[1] = Infinity; + f32[2] = -0; + f32[3] = 0.5; + + var res = Math.trunc(f32[0]); + f32[0] = res; + assertFloat32(res, true); +} +test(acceptTrunc); + +function refuseMath() { + var res = Math.log(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + var res = Math.log10(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.log2(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.log1p(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.exp(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.expm1(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.cosh(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.sinh(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.tanh(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.acosh(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.asinh(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.atanh(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.cbrt(f32[0]); + f32[0] = res; + assertFloat32(res, false); + + res = Math.sign(f32[0]); + f32[0] = res; + assertFloat32(res, false); +} +test(refuseMath); + +function refuseLoop() { + var res = f32[0], + n = 10; + while (n--) { + res = res + 1; // this loop is equivalent to several additions => second addition is not a consumer + assertFloat32(res, false); + } + assertFloat32(res, false); + f32[0] = res; +} +test(refuseLoop); + +function acceptLoop() { + var res = f32[0], + n = 10; + while (n--) { + var sum = res + 1; + res = Math.fround(sum); + assertFloat32(sum, true); + } + assertFloat32(res, true); + f32[0] = res; +} +test(acceptLoop); + +function alternateCond(n) { + var x = f32[0]; + if (n > 0) { + var s1 = x + 1; + f32[0] = s1; + assertFloat32(s1, true); + } else { + var s2 = x + 1; + f64[0] = s2; // non consumer + assertFloat32(s2, false); + } +} +(function() { + f32[0] = 0; + for (var n = 110; n; n--) { + alternateCond(n % 2); + } +})(); + +function phiTest(n) { + var x = (f32[0]); + var y = n; + if (n > 0) { + x = x + 2; + assertFloat32(x, true); + } else { + if (n < -10) { + x = Math.fround(Math.sqrt(y)); + assertFloat32(x, true); + } else { + x = x - 1; + assertFloat32(x, true); + } + } + assertFloat32(x, true); + f32[0] = x; +} +(function() { + f32[0] = 0; + for (var n = 100; n; n--) { + phiTest( ((n % 3) - 1) * 15 ); + } +})(); + +function mixedPhiTest(n) { + var x = (f32[0]); + var y = n; + if (n > 0) { + x = x + 2; // non consumer because of (1) + assertFloat32(x, false); + } else { + if (n < -10) { + x = Math.fround(Math.sqrt(y)); // new producer + assertFloat32(x, true); + } else { + x = x - 1; // non consumer because of (1) + assertFloat32(x, false); + } + } + assertFloat32(x, false); + x = x + 1; // (1) non consumer + f32[0] = x; +} +(function() { + f32[0] = 0; + for (var n = 100; n; n--) { + mixedPhiTest( ((n % 3) - 1) * 15 ); + } +})(); + +function phiTest2(n) { + var x = f32[0]; + while (n >= 0) { + x = Math.fround(Math.fround(x) + 1); + assertFloat32(x, true); + if (n < 10) { + x = f32[0] + 1; + assertFloat32(x, true); + } + n = n - 1; + } +} +(function(){ + f32[0] = 0; + for (var n = 100; n > 10; n--) { + phiTest2(n); + } +})(); diff --git a/js/src/jit-test/tests/ion/testInArray.js b/js/src/jit-test/tests/ion/testInArray.js new file mode 100644 index 0000000000..8650d7d3d6 --- /dev/null +++ b/js/src/jit-test/tests/ion/testInArray.js @@ -0,0 +1,41 @@ +function test1() { + var dense = [1, 2, 3]; + var denseHoles = [1, , 3]; + var result = 0; + + for (var i = 0; i < 70; i++) { + if (i in dense) result += 1; + if (1 in dense) result += 2; + if (3 in dense) result += 3; + if (-1000 in dense) result += 4; + if (i in denseHoles) result += 5; + if (1 in denseHoles) result += 6; + } + + assertEq(result, 153); +} +test1(); + +function test2() { + var a = [1, 2, 3]; + + for (var i = 0; i < 70; i++) { + assertEq(-0 in a, true); + assertEq(Math.sqrt(4) in a, true); + assertEq(1.9 in a, false); + assertEq(NaN in a, false); + assertEq(Infinity in a, false); + } +} +test2(); + +function test3() { + var a = [1, , 3]; + + for (var i = 0; i < 70; i++) { + if (i == 60) + Object.prototype[1] = null; + assertEq(1 in a, i >= 60); + } +} +test3();
\ No newline at end of file diff --git a/js/src/jit-test/tests/ion/testIsCallable.js b/js/src/jit-test/tests/ion/testIsCallable.js new file mode 100644 index 0000000000..ad2c54c390 --- /dev/null +++ b/js/src/jit-test/tests/ion/testIsCallable.js @@ -0,0 +1,134 @@ +var IsCallable = getSelfHostedValue("IsCallable"); + +setJitCompilerOption("ion.warmup.trigger", 50); + +function testSinglePrimitive() { + var f1 = function() { assertEq(IsCallable(undefined), false); }; + do { f1(); } while (!inIon()); + + var f2 = function() { assertEq(IsCallable(null), false); }; + do { f2(); } while (!inIon()); + + var f3 = function() { assertEq(IsCallable(true), false); }; + do { f3(); } while (!inIon()); + + var f4 = function() { assertEq(IsCallable(1), false); }; + do { f4(); } while (!inIon()); + + var f5 = function() { assertEq(IsCallable(1.2), false); }; + do { f5(); } while (!inIon()); + + var f6 = function() { assertEq(IsCallable("foo"), false); }; + do { f6(); } while (!inIon()); + + var f7 = function() { assertEq(IsCallable(Symbol.iterator), false); }; + do { f7(); } while (!inIon()); +} +testSinglePrimitive(); + +function testMixedPrimitive() { + var list = [ + undefined, + null, + true, + 1, + 1.2, + "foo", + Symbol.iterator, + ]; + + var f1 = function() { + for (let x of list) { + assertEq(IsCallable(x), false); + } + }; + do { f1(); } while (!inIon()); +} +testMixedPrimitive(); + +function testSingleObject() { + var obj = []; + var arr = []; + + var f1 = function() { assertEq(IsCallable(obj), false); }; + do { f1(); } while (!inIon()); + + var f2 = function() { assertEq(IsCallable(arr), false); }; + do { f2(); } while (!inIon()); +} +testSingleObject(); + +function testMixedPrimitiveAndObject() { + var list = [ + undefined, + null, + true, + 1, + 1.2, + "foo", + Symbol.iterator, + + {}, + [], + ]; + + var f1 = function() { + for (let x of list) { + assertEq(IsCallable(x), false); + } + }; + do { f1(); } while (!inIon()); +} +testMixedPrimitiveAndObject(); + +function testFunction() { + var f1 = function() { assertEq(IsCallable(Function), true); }; + do { f1(); } while (!inIon()); + + var f2 = function() { assertEq(IsCallable(parseInt), true); }; + do { f2(); } while (!inIon()); +} +testFunction(); + +function testProxy() { + var p1 = new Proxy({}, {}); + var f1 = function() { assertEq(IsCallable(p1), false); }; + do { f1(); } while (!inIon()); + + var p2 = new Proxy(function() {}, {}); + var f2 = function() { assertEq(IsCallable(p2), true); }; + do { f2(); } while (!inIon()); +} +testProxy(); + +function testMixed() { + var p1 = new Proxy({}, {}); + var p2 = new Proxy(function() {}, {}); + + var list = [ + [undefined, false], + [null, false], + [true, false], + [1, false], + [1.2, false], + ["foo", false], + [Symbol.iterator, false], + + [{}, false], + [[], false], + + [Function, true], + [parseInt, true], + + [p1, false], + [p2, true], + ]; + + var f1 = function() { + for (let [x, expected] of list) { + assertEq(IsCallable(x), expected); + } + }; + do { f1(); } while (!inIon()); +} +testMixed(); diff --git a/js/src/jit-test/tests/ion/testObjectHasPrototype.js b/js/src/jit-test/tests/ion/testObjectHasPrototype.js new file mode 100644 index 0000000000..0fce075c5b --- /dev/null +++ b/js/src/jit-test/tests/ion/testObjectHasPrototype.js @@ -0,0 +1,63 @@ +setJitCompilerOption("ion.warmup.trigger", 4); + +var ObjectHasPrototype = getSelfHostedValue("ObjectHasPrototype"); + +var StringProto = String.prototype; +var ObjectProto = Object.prototype; + +function testBasic() { + var f = function() { + assertEq(ObjectHasPrototype(StringProto, ObjectProto), true); + }; + for (var i = 0; i < 40; i++) { + f(); + } +} +testBasic(); + +function testProtoChange(proto) { + var f = function(expected) { + assertEq(ObjectHasPrototype(StringProto, ObjectProto), expected); + }; + var expected = true; + for (var i = 0; i < 120; i++) { + f(expected); + if (i == 40) { + Object.setPrototypeOf(StringProto, proto); + expected = false; + } + if (i == 80) { + Object.setPrototypeOf(StringProto, ObjectProto); + expected = true; + } + } +} +testProtoChange(null); +// Different singleton +testProtoChange(Function.prototype); +// native non-singleton +testProtoChange(/a/); +// non-native non-singleton +testProtoChange({}); + +var Int32ArrayProto = Int32Array.prototype; +var TypedArrayProto = Object.getPrototypeOf(Int32ArrayProto); +function testProtoProtoChange(proto) { + var f = function() { + assertEq(ObjectHasPrototype(Int32ArrayProto, TypedArrayProto), true); + }; + for (var i = 0; i < 120; i++) { + f(); + if (i == 40) + Object.setPrototypeOf(TypedArrayProto, proto); + if (i == 80) + Object.setPrototypeOf(TypedArrayProto, Object); + } +} +testProtoProtoChange(null); +// Different singleton +testProtoProtoChange(Function.prototype); +// native non-singleton +testProtoProtoChange(/a/); +// non-native non-singleton +testProtoProtoChange({}); diff --git a/js/src/jit-test/tests/ion/testPos.js b/js/src/jit-test/tests/ion/testPos.js new file mode 100644 index 0000000000..197650e9b1 --- /dev/null +++ b/js/src/jit-test/tests/ion/testPos.js @@ -0,0 +1,32 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +function f_int(x) { + return +x; +} + +function f_double(x) { + return +x; +} + +for (var i = 0; i < 1000; i++) { + assertEq(f_int(0), 0); + assertEq(f_int(1), 1); + assertEq(f_int(-1), -1); + assertEq(f_int(-2147483648), -2147483648); + assertEq(f_int(2147483647), 2147483647); +} + +for (var i = 0; i < 1000; i++) { + assertEq(f_double(0.0), 0.0); + assertEq(f_double(1.0), 1.0); + assertEq(f_double(-1.0), -1.0); + assertEq(f_double(-2.147483648), -2.147483648); + assertEq(f_double(2.147483647), 2.147483647); +} + +for (var i = 0; i < 1000; i++) { + assertEq(f_double("0.0"), 0.0); + assertEq(f_double("1.0"), 1.0); + assertEq(f_double("-1.0"), -1.0); + assertEq(f_double("-2.147483648"), -2.147483648); + assertEq(f_double("2.147483647"), 2.147483647); +} diff --git a/js/src/jit-test/tests/ion/testPossiblyWrappedArrayBufferByteLength.js b/js/src/jit-test/tests/ion/testPossiblyWrappedArrayBufferByteLength.js new file mode 100644 index 0000000000..ef41f89c8b --- /dev/null +++ b/js/src/jit-test/tests/ion/testPossiblyWrappedArrayBufferByteLength.js @@ -0,0 +1,41 @@ +var PossiblyWrappedArrayBufferByteLength = getSelfHostedValue("PossiblyWrappedArrayBufferByteLength"); + +setJitCompilerOption("ion.warmup.trigger", 50); + +function testBasic() { + var arr = [1, 2, 3]; + var tarr = new Int32Array(arr); + var abuf = tarr.buffer; + + var arrLength = arr.length; + var bytesPerElement = Int32Array.BYTES_PER_ELEMENT; + + var f = function() { + assertEq(PossiblyWrappedArrayBufferByteLength(abuf), arrLength * bytesPerElement); + }; + do { + f(); + } while (!inIon()); +} +testBasic(); + +function testWrapped() { + var g = newGlobal(); +g.eval(` +var arr = [1, 2, 3]; +var tarr = new Int32Array(arr); +var abuf = tarr.buffer; +`); + + var abuf = g.abuf; + var arrLength = g.arr.length; + var bytesPerElement = g.Int32Array.BYTES_PER_ELEMENT; + + var f = function() { + assertEq(PossiblyWrappedArrayBufferByteLength(abuf), arrLength * bytesPerElement); + }; + do { + f(); + } while (!inIon()); +} +testWrapped(); diff --git a/js/src/jit-test/tests/ion/testStringFromCodePoint.js b/js/src/jit-test/tests/ion/testStringFromCodePoint.js new file mode 100644 index 0000000000..0e03f2f484 --- /dev/null +++ b/js/src/jit-test/tests/ion/testStringFromCodePoint.js @@ -0,0 +1,32 @@ +setJitCompilerOption("ion.warmup.trigger", 20); + +function testBailout() { + function f(v, r) { + for (var i = 0; i < 50; ++i) { + // Ensure DCE and LICM don't eliminate calls to fromCodePoint in + // case the input argument is not a valid code point. + if (i === 0) { + r(); + } + String.fromCodePoint(v); + String.fromCodePoint(v); + String.fromCodePoint(v); + } + } + + var result = []; + function r() { + result.push("ok"); + } + + do { + result.length = 0; + try { + f(0, r); + f(0, r); + f(0x10ffff + 1, r); + } catch (e) {} + assertEq(result.length, 3); + } while (!inIon()); +} +testBailout(); diff --git a/js/src/jit-test/tests/ion/testStringMatch.js b/js/src/jit-test/tests/ion/testStringMatch.js new file mode 100644 index 0000000000..dc5af2d80b --- /dev/null +++ b/js/src/jit-test/tests/ion/testStringMatch.js @@ -0,0 +1,71 @@ +setJitCompilerOption("ion.warmup.trigger", 4); + +function testBasic() { + var f = function() { + var result = "abc".match("b"); + assertEq(result.length, 1); + assertEq(result.index, 1); + assertEq(result[0], "b"); + }; + for (var i = 0; i < 40; i++) { + f(); + } +} +testBasic(); + +function testMod(apply, unapply) { + var f = function(applied) { + var result = "abc".match("b"); + assertEq(result.length, 1); + if (applied) { + assertEq(result[0], "mod"); + } else { + assertEq(result.index, 1); + assertEq(result[0], "b"); + } + }; + var applied = false; + for (var i = 0; i < 120; i++) { + f(applied); + if (i == 40) { + apply(); + applied = true; + } + if (i == 80) { + unapply(); + applied = false; + } + } +} +testMod(() => { + String.prototype[Symbol.match] = () => ["mod"]; +}, () => { + delete String.prototype[Symbol.match]; +}); +testMod(() => { + Object.prototype[Symbol.match] = () => ["mod"]; +}, () => { + delete Object.prototype[Symbol.match]; +}); + +testMod(() => { + Object.setPrototypeOf(String.prototype, { + [Symbol.match]: () => ["mod"] + }); +}, () => { + Object.setPrototypeOf(String.prototype, Object.prototype); +}); + +var orig_exec = RegExp.prototype.exec; +testMod(() => { + RegExp.prototype.exec = () => ["mod"]; +}, () => { + RegExp.prototype.exec = orig_exec; +}); + +var orig_match = RegExp.prototype[Symbol.match]; +testMod(() => { + RegExp.prototype[Symbol.match] = () => ["mod"]; +}, () => { + RegExp.prototype[Symbol.match] = orig_match; +}); diff --git a/js/src/jit-test/tests/ion/testSubtract.js b/js/src/jit-test/tests/ion/testSubtract.js new file mode 100644 index 0000000000..2b4389b2a8 --- /dev/null +++ b/js/src/jit-test/tests/ion/testSubtract.js @@ -0,0 +1,20 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +function f_int(x, y) { + return x - y; +} +function f_double(x, y) { + return x - y; +} + +for (var i = 0; i < 1000; i++) { + assertEq(f_int(5, 3), 2); + assertEq(f_int(3, 5), -2); + assertEq(f_int(-2147483648, 1), -2147483649); +} + + +for (var i = 0; i < 1000; i++) { + assertEq(f_double(5.5, 3.2), 2.3); + assertEq(f_double(2.5, 3.0), -0.5); +} + diff --git a/js/src/jit-test/tests/ion/testVAndBranch.js b/js/src/jit-test/tests/ion/testVAndBranch.js new file mode 100644 index 0000000000..c1fcc00e96 --- /dev/null +++ b/js/src/jit-test/tests/ion/testVAndBranch.js @@ -0,0 +1,20 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +function f(x) { + if (x) + return true; + return false; +} + +assertEq(f(NaN), false); +assertEq(f(-0), false); +assertEq(f(3.3), true); +assertEq(f(0), false); +assertEq(f(3), true); +assertEq(f("hi"), true); +assertEq(f(""), false); +assertEq(f(true), true); +assertEq(f(false), false); +assertEq(f(undefined), false); +assertEq(f({}), true); +assertEq(f(null), false); + diff --git a/js/src/jit-test/tests/ion/throw.js b/js/src/jit-test/tests/ion/throw.js new file mode 100644 index 0000000000..e81558194b --- /dev/null +++ b/js/src/jit-test/tests/ion/throw.js @@ -0,0 +1,112 @@ +function thrower1(x) { + throw x + 2; + + // Dead code, should be ignored. + throw ++x; + return x; +} +function test1() { + // If we ever inline functions containing JSOP_THROW, + // this shouldn't assert. + function f(x) { + thrower1(x + 1); + } + for (var i=0; i<11000; i++) { + try { + f(i); + assertEq(0, 1); + } catch(e) { + assertEq(e, i + 3); + } + } +} +test1(); + +// Test throwing from an uncompilable (interpreted) function. +function getException(f) { + try { + f(); + assertEq(0, 1); + } catch(e) { + return e; + } + assertEq(0, 1); +} + +function thrower2(x) { + if (x > 90) + throw x; + with ({}) {}; // Abort compilation...(?) +} +function test2() { + for (var i = 0; i < 100; i++) { + thrower2(i); + } +} +assertEq(getException(test2), 91); + +// Throwing |this| from a constructor. +function thrower3(x) { + this.x = x; + if (x > 90) + throw this; +} +function test3() { + for (var i=0; i < 100; i++) { + new thrower3(i); + } +} +assertEq(getException(test3).x, 91); + +// Throwing an exception in various loop blocks. +var count = 0; +function thrower4(x) { + throw count++; + count += 12345; // Shouldn't be executed. +} +function test4_1() { + var i = 0; + for (new thrower4(i); i < 100; i++) { + count += 2000; // Shouldn't be executed. + } +} +function test4_2() { + for (var i = 0; thrower4(i); i++) { + count += 3000; // Shouldn't be executed. + } +} +function test4_3() { + for (var i = 0; i < 100; thrower4(i)) { + count += 5; + } +} +function test4_4() { + for (var i = 0; i < 10; i++) { + if (i > 8) + thrower4(); + count += i; + } +} +for (var i = 0; i < 100; i++) { + assertEq(getException(test4_1), count-1); + assertEq(getException(test4_2), count-1); + assertEq(getException(test4_3), count-1); + assertEq(getException(test4_4), count-1); +} +assertEq(count, 4500); + +function test5() { + var res = 0; + for (var i=0; i<40; i++) { + try { + throw i; + } catch (e) { + if (e % 2) + res += e; + else + res += e * 3; + } + } + return res; +} +assertEq(test5(), 1540); diff --git a/js/src/jit-test/tests/ion/toid.js b/js/src/jit-test/tests/ion/toid.js new file mode 100644 index 0000000000..33341a5a6f --- /dev/null +++ b/js/src/jit-test/tests/ion/toid.js @@ -0,0 +1,10 @@ +function f(arr, index) { + for (var i=0; i<100; i++) { + arr[index]++; + ++arr[index]; + } +} +var arr = [1, 2, 3]; +f(arr, "1"); +f(arr, 1); +assertEq(arr[1], 402); diff --git a/js/src/jit-test/tests/ion/truncate.js b/js/src/jit-test/tests/ion/truncate.js new file mode 100644 index 0000000000..3f4d353ac0 --- /dev/null +++ b/js/src/jit-test/tests/ion/truncate.js @@ -0,0 +1,28 @@ +function f() { + var x = Math.pow(2, 31); // take it as argument if constant propagation comes in you way. + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 32 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 33 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 34 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 35 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 36 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 37 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 38 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 39 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 40 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 41 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 42 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 43 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 44 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 45 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 46 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 47 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 48 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 49 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 50 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 51 + x = x + x; assertEq((x + 1) | 0, 1); // 2 ** 52 + x = x + x; assertEq((x + 1) | 0, 0); // 2 ** 53 +} + +for (var i = 0; i <= 10_000; i++) + f(); diff --git a/js/src/jit-test/tests/ion/truncateToInt32-ool.js b/js/src/jit-test/tests/ion/truncateToInt32-ool.js new file mode 100644 index 0000000000..dd3d9c99ab --- /dev/null +++ b/js/src/jit-test/tests/ion/truncateToInt32-ool.js @@ -0,0 +1,28 @@ +function f (x) { + return x >> 0; +} + +var table = [ + [NaN, 0], + + [Infinity, 0], + [-Infinity, 0], + [0, 0], + [-0, 0], + + [15, 15], + [-15, -15], + + [0x80000000, -0x80000000], + [-0x80000000, -0x80000000], + + [0xffffffff, -1], + [-0xffffffff, 1], + + [0x7fffffff, 0x7fffffff], + [-0x7fffffff, -0x7fffffff] +] + +for (var i = 0; i < table.length; i++) { + assertEq(f(table[i][0]), table[i][1]); +} diff --git a/js/src/jit-test/tests/ion/truncateToInt32.js b/js/src/jit-test/tests/ion/truncateToInt32.js new file mode 100644 index 0000000000..462b411ad1 --- /dev/null +++ b/js/src/jit-test/tests/ion/truncateToInt32.js @@ -0,0 +1,46 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: + +function w(y) +{ + var x = 23.5; + return x & y; +} + +function f(x, y) { + // Confuse the type analysis to not know the type of x. + var t = 3.5 + x; + t + 3.5; + return x & y; +} + +function g_bool(x, y) { + var t; + if (x + 0) + t = true; + else + t = false; + return t & y; + +} + +function g_null(x) { + return null & x; +} + +var obj = { valueOf: function () { return 5; } } + +assertEq(w(93), 21); +assertEq(g_bool(1, 3), 1); +assertEq(g_bool(0, 3), 0); +assertEq(g_null(2), 0); + +assertEq(f(1, 7), 1); +assertEq(f(true, 7), 1); +assertEq(f(false, 7), 0); +assertEq(f("3", 7), 3); +assertEq(f(obj, 7), 5); +assertEq(f(3.5, 7), 3); +assertEq(f(undefined, 7), 0); +assertEq(f(null, 7), 0); +assertEq(f(Math.NaN, 7), 0); + diff --git a/js/src/jit-test/tests/ion/try-catch-1.js b/js/src/jit-test/tests/ion/try-catch-1.js new file mode 100644 index 0000000000..33041451aa --- /dev/null +++ b/js/src/jit-test/tests/ion/try-catch-1.js @@ -0,0 +1,12 @@ +function F() { + try { + var T = {}; + throw 12; + } catch (e) { + // Don't throw. + T.x = 5; + } +} +F(); +F(); +F(); diff --git a/js/src/jit-test/tests/ion/try-catch-2.js b/js/src/jit-test/tests/ion/try-catch-2.js new file mode 100644 index 0000000000..80ed6c9e9f --- /dev/null +++ b/js/src/jit-test/tests/ion/try-catch-2.js @@ -0,0 +1,14 @@ +// Control flow does not reach end of try block, code after try statement is +// reachable by catch block. +function f() { + try { + throw 3; + } catch(e) { + } + + var res = 0; + for (var i=0; i<40; i++) + res += 2; + return res; +} +assertEq(f(), 80); diff --git a/js/src/jit-test/tests/ion/try-catch-3.js b/js/src/jit-test/tests/ion/try-catch-3.js new file mode 100644 index 0000000000..53b6babe18 --- /dev/null +++ b/js/src/jit-test/tests/ion/try-catch-3.js @@ -0,0 +1,27 @@ +// Don't fail if code after try statement is unreachable. +function f() { + try { + throw 1; + } catch(e) { + throw 5; + } + + // Unreachable. + assertEq(0, 2); + var res = 0; + for (var i=0; i<10; i++) + res += 2; + return res; +} + +var c = 0; + +for (var i=0; i<5; i++) { + try { + f(); + assertEq(0, 1); + } catch(e) { + c += e; + } +} +assertEq(c, 25); diff --git a/js/src/jit-test/tests/ion/try-catch-4.js b/js/src/jit-test/tests/ion/try-catch-4.js new file mode 100644 index 0000000000..f87a5a44e5 --- /dev/null +++ b/js/src/jit-test/tests/ion/try-catch-4.js @@ -0,0 +1,15 @@ +// Entering catch blocks via OSR is not possible (because the catch block +// is not compiled by Ion). Don't crash. +function f() { + var res = 0; + try { + throw 1; + } catch(e) { + for (var i=0; i<10; i++) { + res += 3; + } + } + + assertEq(res, 30); +} +f(); diff --git a/js/src/jit-test/tests/ion/try-catch-5.js b/js/src/jit-test/tests/ion/try-catch-5.js new file mode 100644 index 0000000000..059ce6281e --- /dev/null +++ b/js/src/jit-test/tests/ion/try-catch-5.js @@ -0,0 +1,8 @@ +function x() { + try { + do { + var { q , gen } = t; + } while(false); + } catch (e) {} +} +x(); diff --git a/js/src/jit-test/tests/ion/try-catch-6.js b/js/src/jit-test/tests/ion/try-catch-6.js new file mode 100644 index 0000000000..f0c01048a0 --- /dev/null +++ b/js/src/jit-test/tests/ion/try-catch-6.js @@ -0,0 +1,14 @@ +var o = { + valueOf: function() {} +}; +var threw = false; +function test(t) { + try { + for (x[t++] in o) {} + } catch (err) { + assertEq(t, 3.14); + threw = true; + } +} +test(3.14); +assertEq(threw, true); diff --git a/js/src/jit-test/tests/ion/try-catch-7.js b/js/src/jit-test/tests/ion/try-catch-7.js new file mode 100644 index 0000000000..ed07cfe7e1 --- /dev/null +++ b/js/src/jit-test/tests/ion/try-catch-7.js @@ -0,0 +1,10 @@ +// The second for-loop is only reachable via the catch block, which Ion +// does not compile. +for (;;) { + try { + throw 3; + } catch(e) { + break; + } +} +for (var i = 0; i < 1500; i++) {} diff --git a/js/src/jit-test/tests/ion/typed-arrays-1.js b/js/src/jit-test/tests/ion/typed-arrays-1.js new file mode 100644 index 0000000000..0bfd1f4895 --- /dev/null +++ b/js/src/jit-test/tests/ion/typed-arrays-1.js @@ -0,0 +1,101 @@ +function testInt8() { + var arr1 = new Int8Array(50); + var arr2 = new Uint8Array(50); + var arr3 = new Uint8ClampedArray(50); + + for (var i=0; i<arr1.length; i++) { + arr1[i] = arr2[i] = arr3[i] = i * 8; + } + var res = 0; + for (var i=0; i<arr1.length; i++) { + res += arr1[i] + arr2[i] + arr3[i] + arr2[10]; + } + assertEq(res, 18334); +} +testInt8(); + +function testInt16() { + var arr1 = new Int16Array(70); + var arr2 = new Uint16Array(70); + + for (var i=0; i<arr1.length; i++) { + arr1[i] = arr2[i] = i * 1000; + } + var res = 0; + for (var i=0; i<arr1.length; i++) { + res += arr1[i] + arr2[i] + arr2[1] + arr1[3]; + } + assertEq(res, 2423024); +} +testInt16(); + +function testInt32() { + var arr = new Int32Array(60); + arr[0] = -50; + for (var i=1; i<arr.length; i++) { + arr[i] = arr[i-1] + arr[0]; + ++arr[0]; + } + assertEq(arr[arr.length-1], -1289); +} +testInt32(); + +function testUint32() { + function sum(arr) { + var res = 0; + for (var i=0; i<arr.length; i++) { + res += arr[i]; + } + return res; + } + var arr = new Uint32Array(100); + for (var i=0; i<arr.length; i++) { + arr[i] = i; + } + + // Compile sum() to read int32 values. + assertEq(sum(arr), 4950); + + // Add a large uint32 so that the sum no longer fits in an + // int32. sum() should be recompiled to return a double. + arr[50] = 0xffffeeee; + assertEq(sum(arr), 4294967826); +} +testUint32(); + +function testFloat() { + var arr1 = new Float32Array(75); + var arr2 = new Float64Array(75); + arr1[0] = arr2[0] = Math.PI * 1234567.8; + + for (var i=1; i<75; i++) { + arr1[i] = arr1[i-1] + arr1[0]; + arr2[i] = arr2[i-1] + arr2[0]; + } + assertEq(arr1[74] > 290888255, true); + assertEq(arr1[74] < 290888257, true); + + assertEq(arr2[74] > 290888184, true); + assertEq(arr2[74] < 290888185, true); +} +testFloat(); + +function testCanonicalNaN() { + // NaN values have to be canonicalized. Otherwise, malicious scripts could + // construct arbitrary Value's (due to our NaN boxing Value representation). + var buf = new ArrayBuffer(16); + var uint32 = new Uint32Array(buf); + var f64 = new Float64Array(buf); + var f32 = new Float32Array(buf); + + // Evil: write a JSVAL_TYPE_OBJECT type tag... + uint32[0] = 0xffffff87; + uint32[1] = 0xffffff87; + + // Make sure this value is interpreted as a double. + for (var i=0; i<100; i++) { + assertEq(isNaN(f64[0]), true); + assertEq(isNaN(f32[0]), true); + } +} +testCanonicalNaN(); diff --git a/js/src/jit-test/tests/ion/typed-arrays-2.js b/js/src/jit-test/tests/ion/typed-arrays-2.js new file mode 100644 index 0000000000..1f88cb65df --- /dev/null +++ b/js/src/jit-test/tests/ion/typed-arrays-2.js @@ -0,0 +1,18 @@ +function test1() { + var arr = new Uint32Array(100); + Object.prototype[105] = true; + arr[50] = 0xffffee00; + arr[84] = 444; + + var res = 0; + for (var i=0; i<200; i++) { + res = arr[i]; + if (i == 50) + assertEq(res, 0xffffee00); + else if (i == 84) + assertEq(res, 444); + else if (i >= 100) + assertEq(res, undefined); + } +} +test1(); diff --git a/js/src/jit-test/tests/ion/typed-arrays-3.js b/js/src/jit-test/tests/ion/typed-arrays-3.js new file mode 100644 index 0000000000..74deb1ed02 --- /dev/null +++ b/js/src/jit-test/tests/ion/typed-arrays-3.js @@ -0,0 +1,65 @@ +function testClampInt() { + var values = [-255, -254, -2, -1, 0, 1, 2, 128, 254, 255, 256, 300]; + var expected = [ 0, 0, 0, 0, 0, 1, 2, 128, 254, 255, 255, 255]; + + var arr = new Uint8ClampedArray(100); + + for (var i=0; i<10; i++) { + for (var j=0; j<values.length; j++) { + arr[1] = arr[j] = values[j]; + + assertEq(arr[1], arr[j]); + assertEq(arr[j], expected[j]); + } + } +} +testClampInt(); + +function testClampDouble() { + var values = [-255.1, -255.0, -2.1, -0, 0, 0.1, 123.4, 254.6, 255, 255.1, 255.9, 256, 1234.5, + NaN, -Infinity, Infinity]; + var expected = [ 0, 0, 0, 0, 0, 0, 123, 255, 255, 255, 255, 255, 255, + 0, 0, 255]; + + var arr = new Uint8ClampedArray(100); + + for (var i=0; i<10; i++) { + for (var j=0; j<values.length; j++) { + arr[1] = arr[j] = values[j]; + + assertEq(arr[1], arr[j]); + assertEq(arr[j], expected[j]); + } + } +} +testClampDouble(); + +function testClampValue() { + var values = [null, 123, 256, 267.9, -123.3, undefined, Math, true, NaN, false]; + var expected = [ 0, 123, 255, 255, 0, 0, 0, 1, 0, 0]; + + var arr = new Uint8ClampedArray(100); + + for (var i=0; i<10; i++) { + for (var j=0; j<values.length; j++) { + arr[1] = arr[j] = values[j]; + + assertEq(arr[1], arr[j]); + assertEq(arr[j], expected[j]); + } + } +} +testClampValue(); + +function testString() { + var arr = new Uint8ClampedArray(10); + for (var i=0; i<60; i++) { + arr[5] = ((i & 1) == 0) ? "123.5" : 33; + if (i % 2 == 0) + assertEq(arr[5], 124); + else + assertEq(arr[5], 33); + } +} +//FIXME: enable this test again (bug 741114) +//testString(); diff --git a/js/src/jit-test/tests/ion/typedarray-length.js b/js/src/jit-test/tests/ion/typedarray-length.js new file mode 100644 index 0000000000..6c2e1ceec3 --- /dev/null +++ b/js/src/jit-test/tests/ion/typedarray-length.js @@ -0,0 +1,24 @@ +function detachArrayBufferEventually(arr, i) +{ + with (arr) + { + // prevent inlining + } + + if (i === 2000) + detachArrayBuffer(arr.buffer); +} + +function test() +{ + var buf = new ArrayBuffer(1000); + var ta = new Int8Array(buf); + + for (var i = 0; i < 2500; i++) + { + detachArrayBufferEventually(ta, i); + assertEq(ta.length, i >= 2000 ? 0 : 1000); + } +} + +test(); diff --git a/js/src/jit-test/tests/ion/typedarray-static-load.js b/js/src/jit-test/tests/ion/typedarray-static-load.js new file mode 100644 index 0000000000..09a05ed2fd --- /dev/null +++ b/js/src/jit-test/tests/ion/typedarray-static-load.js @@ -0,0 +1,12 @@ +var buffer = new ArrayBuffer(512 * 1024); +var ta = new Uint8Array(buffer); + +function load() { return ta[0x1234]; } + +load(); +load(); +load(); + +detachArrayBuffer(buffer); + +load(); diff --git a/js/src/jit-test/tests/ion/typedarray-static-store.js b/js/src/jit-test/tests/ion/typedarray-static-store.js new file mode 100644 index 0000000000..98da228289 --- /dev/null +++ b/js/src/jit-test/tests/ion/typedarray-static-store.js @@ -0,0 +1,12 @@ +var buffer = new ArrayBuffer(512 * 1024); +var ta = new Uint8Array(buffer); + +function store() { ta[0x1234] = 42; } + +store(); +store(); +store(); + +detachArrayBuffer(buffer); + +store(); diff --git a/js/src/jit-test/tests/ion/typedarrayindex-const-double-representable-as-int32.js b/js/src/jit-test/tests/ion/typedarrayindex-const-double-representable-as-int32.js new file mode 100644 index 0000000000..9d1e0ca531 --- /dev/null +++ b/js/src/jit-test/tests/ion/typedarrayindex-const-double-representable-as-int32.js @@ -0,0 +1,20 @@ +function f(n) { + const ta = new Int32Array(n); + + // When the TypedArray has a zero length, accessing the element at index 0 + // should return undefined. That'll lead to including undefined in the + // typeset of |ta[k]|, which in turn triggers to use MTypedArrayIndexToInt32 + // for the TypedArray index conversion. + const r = n === 0 ? undefined : 0; + + // numberToDouble always returns a double number. + const k = numberToDouble(0); + + for (var i = 0; i < 10; ++i) { + assertEq(ta[k], r); + } +} + +for (var i = 0; i < 2; ++i) { + f(i); +} diff --git a/js/src/jit-test/tests/ion/typeof.js b/js/src/jit-test/tests/ion/typeof.js new file mode 100644 index 0000000000..355609dd58 --- /dev/null +++ b/js/src/jit-test/tests/ion/typeof.js @@ -0,0 +1,16 @@ +function getType(v) { + return typeof v; +} +function f() { + for (var i=0; i<100; i++) { + assertEq(getType({}), "object"); + assertEq(getType(Math.abs), "function"); + assertEq(getType(10), "number"); + assertEq(getType(Math.PI), "number"); + assertEq(getType(true), "boolean"); + assertEq(getType(""), "string"); + assertEq(getType(null), "object"); + assertEq(getType(undefined), "undefined"); + } +} +f(); diff --git a/js/src/jit-test/tests/ion/udiv-by-constant.js b/js/src/jit-test/tests/ion/udiv-by-constant.js new file mode 100644 index 0000000000..43549cd1e7 --- /dev/null +++ b/js/src/jit-test/tests/ion/udiv-by-constant.js @@ -0,0 +1,114 @@ +function uint_seq(count) { + with({}){} + var arr = []; + var x = 0xfac83126; + while (count--) { + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + // SpiderMonkey does not know how to represent UInt32, only Int32, and + // including any UInt32 will cause the following function to be + // de-optimized as double math. + if (x|0 > 0) + arr.push(x|0); + } + return arr; +} + +function test(name, asm, ion, int) { + with({}){} + let count = 10000; + let seq = uint_seq(count); + for (let x of seq) { + let rint = int(x); + let rasm = asm(x); + let rion = ion(x); + // console.log(name, x, rint, rasm, rion); + assertEq(rasm, rint); + assertEq(rion, rint); + } +} + +var asmdiv2 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 2)>>>0; + return z|0; + } + return f; +})() + +var plaindiv2 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 2)>>>0; + return z|0; +} + +var interpdiv2 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x>>>0) / 2)>>>0; + return z|0; +} + +test("div2", asmdiv2, plaindiv2, interpdiv2); + +var asmdiv5 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 5)>>>0; + return z|0; + } + return f; +})() + +var plaindiv5 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 5)>>>0; + return z|0; +} + +var interpdiv5 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x>>>0) / 5)>>>0; + return z|0; +} + +test("div5", asmdiv5, plaindiv5, interpdiv5); + +var asmdiv7 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 7)>>>0; + return z|0; + } + return f; +})() + +var plaindiv7 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 7)>>>0; + return z|0; +} + +var interpdiv7 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x>>>0) / 7)>>>0; + return z|0; +} + +test("div7", asmdiv7, plaindiv7, interpdiv7); diff --git a/js/src/jit-test/tests/ion/udiv-by-u32-constant.js b/js/src/jit-test/tests/ion/udiv-by-u32-constant.js new file mode 100644 index 0000000000..f73a6f6465 --- /dev/null +++ b/js/src/jit-test/tests/ion/udiv-by-u32-constant.js @@ -0,0 +1,110 @@ +function uint_seq(count) { + with({}){} + var arr = []; + var x = 0xfac83126; + while (count--) { + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + arr.push(x >>> 0); + } + return arr; +} + +function test(name, asm, ion, int) { + with({}){} + let count = 10000; + let seq = uint_seq(count); + for (let x of seq) { + let rint = int(x); + let rasm = asm(x); + let rion = ion(x); + // console.log(name, x, rint, rasm, rion); + assertEq(rasm, rint); + assertEq(rion, rint); + } +} + +var asmdiv2 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 2)>>>0; + return z|0; + } + return f; +})() + +var plaindiv2 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 2)>>>0; + return z|0; +} + +var interpdiv2 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x>>>0) / 2)>>>0; + return z|0; +} + +test("div2", asmdiv2, plaindiv2, interpdiv2); + +var asmdiv3 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 3)>>>0; + return z|0; + } + return f; +})() + +var plaindiv3 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 3)>>>0; + return z|0; +} + +var interpdiv3 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x>>>0) / 3)>>>0; + return z|0; +} + +test("div3", asmdiv3, plaindiv3, interpdiv3); + +var asmdiv7 = (function(m) { + "use asm" + function f(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 7)>>>0; + return z|0; + } + return f; +})() + +var plaindiv7 = function(x) { + x = x|0; + var z = 0; + z = ((x>>>0) / 7)>>>0; + return z|0; +} + +var interpdiv7 = function(x) { + with({}){}; + x = x|0; + var z = 0; + z = ((x>>>0) / 7)>>>0; + return z|0; +} + +test("div7", asmdiv7, plaindiv7, interpdiv7); diff --git a/js/src/jit-test/tests/ion/unboxed-objects-invalidate.js b/js/src/jit-test/tests/ion/unboxed-objects-invalidate.js new file mode 100644 index 0000000000..02e27614fe --- /dev/null +++ b/js/src/jit-test/tests/ion/unboxed-objects-invalidate.js @@ -0,0 +1,16 @@ + +var a = []; +for (var i = 0; i < 2000; i++) + a.push({f:i}); + +function f() { + var total = 0; + for (var i = 0; i < a.length; i++) + total += a[i].f; + return total; +} +assertEq(f(), 1999000); + +var sub = Object.create(a[0]); + +assertEq(f(), 1999000); diff --git a/js/src/jit-test/tests/ion/ursh-sign-bug1528597.js b/js/src/jit-test/tests/ion/ursh-sign-bug1528597.js new file mode 100644 index 0000000000..2c4f8eee38 --- /dev/null +++ b/js/src/jit-test/tests/ion/ursh-sign-bug1528597.js @@ -0,0 +1,8 @@ +setJitCompilerOption('ion.enable', 1); +function g(x) { + for (let i = 0; i < 2; ++i) { + var y = x[i]; + print(y >>> y); + } +} +g([2147483649, -2147483648]); diff --git a/js/src/jit-test/tests/ion/valueToInt32.js b/js/src/jit-test/tests/ion/valueToInt32.js new file mode 100644 index 0000000000..65ad561eca --- /dev/null +++ b/js/src/jit-test/tests/ion/valueToInt32.js @@ -0,0 +1,41 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: + +function f(x, y) { + // Confuse the type analysis to not know the type of x. + var u; + var a = x + u; + var b = x + 3; + return x + y; +} + +function g_bool(x, y) { + var t; + if (x + 0) + t = true; + else + t = false; + return t + y; + +} +function g_null(x) { + return null + x; +} + +assertEq(g_bool(1, 2), 3); +assertEq(g_bool(0, 2), 2); +assertEq(g_null(2), 2); + +// These will not bailout. +assertEq(f(Math.cos(Math.PI), 2), 1); +assertEq(f(null, 2), 2); +assertEq(f(false, 2), 2); +assertEq(f(true, 2), 3); +assertEq(f(17, 2), 19); + +// These will bailout. +assertEq(f(undefined, 2), Number.NaN); +assertEq(f("20", 2), "202"); +assertEq(f(16.3, 2), 18.3); +assertEq((1 / f(-0, -0)), -Infinity); + + diff --git a/js/src/jit-test/tests/ion/void.js b/js/src/jit-test/tests/ion/void.js new file mode 100644 index 0000000000..ce638b672f --- /dev/null +++ b/js/src/jit-test/tests/ion/void.js @@ -0,0 +1,6 @@ +function f() { + var b, c; + var a = void ( b = 5, c = 7 ); + return a; +} +assertEq(typeof f(), "undefined") |