diff options
Diffstat (limited to 'js/src/jit-test/tests/basic')
1353 files changed, 28181 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/basic/FPQuadCmp.js b/js/src/jit-test/tests/basic/FPQuadCmp.js new file mode 100644 index 000000000..010228d1f --- /dev/null +++ b/js/src/jit-test/tests/basic/FPQuadCmp.js @@ -0,0 +1,6 @@ +function FPQuadCmp() +{ + for (let j = 0; j < 3; ++j) { true == 0; } + return "ok"; +} +assertEq(FPQuadCmp(), "ok"); diff --git a/js/src/jit-test/tests/basic/__proto__-not-prototype-mutation-ion.js b/js/src/jit-test/tests/basic/__proto__-not-prototype-mutation-ion.js new file mode 100644 index 000000000..4a7b0bd37 --- /dev/null +++ b/js/src/jit-test/tests/basic/__proto__-not-prototype-mutation-ion.js @@ -0,0 +1,12 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function f() +{ + return { *__proto__() {}, __proto__: null }; +} + +for (var i = 0; i < 2e3; i++) + f(); diff --git a/js/src/jit-test/tests/basic/__proto__-not-prototype-mutation.js b/js/src/jit-test/tests/basic/__proto__-not-prototype-mutation.js new file mode 100644 index 000000000..b940a229b --- /dev/null +++ b/js/src/jit-test/tests/basic/__proto__-not-prototype-mutation.js @@ -0,0 +1,29 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var __proto__ = "string value"; + +var propdefs = + [{ c: "['__proto__']: null", t: "object" }, + { c: "__proto__() {}", t: "function" }, + { c: "['__proto__']() {}", t: "function" }, + { c: "*__proto__() {}", t: "function" }, + { c: "*['__proto__']() {}", t: "function" }, + { c: "__proto__", t: "string" }, + { c: "get __proto__() { return 42; }", t: "number" }, + { c: "get ['__proto__']() { return undefined; }", t: "undefined" }, + { c: "set __proto__(v) { }", t: "undefined" }, + { c: "set ['__proto__'](v) { }", t: "undefined" }]; + +for (var propdef of propdefs) +{ + var f = new Function("return { " + propdef.c + " };"); + for (var i = 0; i < 100; i++) + { + var inst = f(); + assertEq(typeof inst.__proto__, propdef.t); + assertEq(Object.getPrototypeOf(inst), Object.prototype); + } +} diff --git a/js/src/jit-test/tests/basic/adjacent-trycatch-second-nested.js b/js/src/jit-test/tests/basic/adjacent-trycatch-second-nested.js new file mode 100644 index 000000000..35767eb40 --- /dev/null +++ b/js/src/jit-test/tests/basic/adjacent-trycatch-second-nested.js @@ -0,0 +1,9 @@ +try { } +catch (e) { } + +try { throw 2; } +catch (e) +{ + try { throw 3; } + catch (e2) { } +} diff --git a/js/src/jit-test/tests/basic/argumentsPassedToBuiltin.js b/js/src/jit-test/tests/basic/argumentsPassedToBuiltin.js new file mode 100644 index 000000000..d8edfffff --- /dev/null +++ b/js/src/jit-test/tests/basic/argumentsPassedToBuiltin.js @@ -0,0 +1,14 @@ +// bug 504797 + +function f() { + g(arguments, 1); +} + +function g(a, b) { + var s = Array.prototype.slice.call(a, b); + assertEq(s[0] == undefined, false); +} + +for (var i = 0; i < 10; ++i) { + f(1, 2, 3, 4); +} diff --git a/js/src/jit-test/tests/basic/arityMismatchExtraArg.js b/js/src/jit-test/tests/basic/arityMismatchExtraArg.js new file mode 100644 index 000000000..6803368ac --- /dev/null +++ b/js/src/jit-test/tests/basic/arityMismatchExtraArg.js @@ -0,0 +1,13 @@ +function arityMismatchMissingArg(arg) +{ + for (var a = 0, i = 1; i < 10000; i *= 2) { + a += i; + } + return a; +} + +function arityMismatchExtraArg() +{ + return arityMismatchMissingArg(1, 2); +} +assertEq(arityMismatchExtraArg(), 16383); diff --git a/js/src/jit-test/tests/basic/arityMismatchMissingArg.js b/js/src/jit-test/tests/basic/arityMismatchMissingArg.js new file mode 100644 index 000000000..79284e948 --- /dev/null +++ b/js/src/jit-test/tests/basic/arityMismatchMissingArg.js @@ -0,0 +1,8 @@ +function arityMismatchMissingArg(arg) +{ + for (var a = 0, i = 1; i < 10000; i *= 2) { + a += i; + } + return a; +} +assertEq(arityMismatchMissingArg(), 16383); diff --git a/js/src/jit-test/tests/basic/array-copyWithin.js b/js/src/jit-test/tests/basic/array-copyWithin.js new file mode 100644 index 000000000..324a995a3 --- /dev/null +++ b/js/src/jit-test/tests/basic/array-copyWithin.js @@ -0,0 +1,187 @@ +// Tests for Array#copyWithin + +load(libdir + "asserts.js"); + +assertEq(Array.prototype.copyWithin.length, 2); + +// works with two arguments +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0, 3), [4, 5, 3, 4, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(1, 3), [1, 4, 5, 4, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(1, 2), [1, 3, 4, 5, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(2, 2), [1, 2, 3, 4, 5]); + +// works with three arguments +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0, 3, 4), [4, 2, 3, 4, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(1, 3, 4), [1, 4, 3, 4, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(1, 2, 4), [1, 3, 4, 4, 5]); + +// works with negative arguments +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0, -2), [4, 5, 3, 4, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0, -2, -1), [4, 2, 3, 4, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(-4, -3, -2), [1, 3, 3, 4, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(-4, -3, -1), [1, 3, 4, 4, 5]); +assertDeepEq([1, 2, 3, 4, 5].copyWithin(-4, -3), [1, 3, 4, 5, 5]); + +// works with array-like objects +var args = (function () { return Array.prototype.slice.call(arguments); }(1, 2, 3)); +var argsClass = Object.prototype.toString.call(args); +assertDeepEq(args, [1, 2, 3]); +Array.prototype.copyWithin.call(args, -2, 0); +assertDeepEq(args, [1, 1, 2]); +assertDeepEq(Object.prototype.toString.call(args), argsClass); + +// throws on null/undefined values +assertThrowsInstanceOf(function() { + Array.prototype.copyWithin.call(null, 0, 3); +}, TypeError, "Assert that copyWithin fails if this value is null"); + +assertThrowsInstanceOf(function() { + Array.prototype.copyWithin.call(undefined, 0, 3); +}, TypeError, "Assert that copyWithin fails if this value is undefined"); + +// test with this value as string +assertThrowsInstanceOf(function() { + Array.prototype.copyWithin.call("hello world", 0, 3); +}, TypeError, "Assert that copyWithin fails if this value is string"); + +// test with this value as number +assertDeepEq(Array.prototype.copyWithin.call(34, 0, 3), new Number(34)); + +// test with this value as TypedArray +var buffer = new ArrayBuffer(16); +var int32View = new Int32Array(buffer); +for (var i=0; i<int32View.length; i++) { + int32View[i] = i*2; +} +assertDeepEq(Array.prototype.copyWithin.call(int32View, 0, 1), new Int32Array([2, 4, 6, 6])); + +// if arguments object is sloppy, copyWithin must move the arguments around +function f(a, b, c, d, e) { + [].copyWithin.call(arguments, 1, 3); + return [a, b, c, d, e]; +} +assertDeepEq(f(1, 2, 3, 4, 5), [1, 4, 5, 4, 5]); + +// test with target > start on 2 arguments +assertDeepEq([1, 2, 3, 4, 5].copyWithin(3, 0), [1, 2, 3, 1, 2]); + +// test with target > start on 3 arguments +assertDeepEq([1, 2, 3, 4, 5].copyWithin(3, 0, 4), [1, 2, 3, 1, 2]); + +// test on array with holes +var arr = new Array(6); +for (var i = 0; i < arr.length; i += 2) { + arr[i] = i; +} +assertDeepEq(arr.copyWithin(0, 3), [, 4, , , 4, , ]); + +// test on fractional arguments +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0.2, 3.9), [4, 5, 3, 4, 5]); + +// test with -0 +assertDeepEq([1, 2, 3, 4, 5].copyWithin(-0, 3), [4, 5, 3, 4, 5]); + +// test with arguments more than this.length +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0, 7), [1, 2, 3, 4, 5]); + +// test with arguments less than -this.length +assertDeepEq([1, 2, 3, 4, 5].copyWithin(-7, 0), [1, 2, 3, 4, 5]); + +// test with arguments equal to -this.length +assertDeepEq([1, 2, 3, 4, 5].copyWithin(-5, 0), [1, 2, 3, 4, 5]); + +// test on empty array +assertDeepEq([].copyWithin(0, 3), []); + +// test with target range being shorter than end - start +assertDeepEq([1, 2, 3, 4, 5].copyWithin(2, 1, 4), [1, 2, 2, 3, 4]); + +// test overlapping ranges +arr = [1, 2, 3, 4, 5]; +arr.copyWithin(2, 1, 4); +assertDeepEq(arr.copyWithin(2, 1, 4), [1, 2, 2, 2, 3]); + +// check that delete is strict +arr = [1, , 3, , 4, 5]; +Object.freeze(arr); +assertThrowsInstanceOf(function() { + arr.copyWithin(2, 1, 4); +}, TypeError, "Assert that delete is strict in copyWithin"); + +// test with a proxy object +var proxyObj = { + get: function(recipient, name) { + return recipient[name] + 2; + } +}; + +var p = new Proxy([1, 2, 3, 4, 5], proxyObj); +Array.prototype.copyWithin.call(p, 0, 3); +for (name of Object.getOwnPropertyNames(p)) { + print(name + ": " + uneval(Object.getOwnPropertyDescriptor(p, name))); +} + +assertDeepEq(p, [6, 7, , , 5]); + +// test if we throw in between +arr = [1, 2, 3, 4, 5]; +Object.defineProperty(arr, 1, { + set: function () { + throw new Error("Boom!"); + } +}); + +assertThrowsInstanceOf(function() { + arr.copyWithin(1, 3); +}, Error, "Throwing in between."); +assertEq(arr[0], 1); +assertEq(arr[1], undefined); +assertEq(arr[2], 3); +assertEq(arr[3], 4); +assertEq(arr[4], 5); + +// undefined as third argument +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0, 3, undefined), [4, 5, 3, 4, 5]); + +// test that this.length is called only once +arr = {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}; +var count = 0; +Object.defineProperty(arr, "length", { + get: function () { + count++; + } +}); +Array.prototype.copyWithin.call(arr, 1, 3); +assertEq(count, 1); + +count = 0; +Array.prototype.copyWithin.call(arr, 1, 3, 4); +assertEq(count, 1); + +var large = 10000; + +// test on a large array +arr = new Array(large); +assertDeepEq(arr.copyWithin(45, 900), arr); + +// test on floating point numbers +for (var i = 0; i < large; i++) { + arr[i] = Math.random(); +} +arr.copyWithin(45, 900); + +// test on array of objects +for (var i = 0; i < large; i++) { + arr[i] = { num: Math.random() }; +} +arr.copyWithin(45, 900); + +// test array length remains same +assertEq(arr.length, large); + +// test null on third argument is handled correctly +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0, 3, null), [1, 2, 3, 4, 5]); + +// tamper the global Object prototype and test this works +Object.prototype[2] = 1; +assertDeepEq([1, 2, 3, 4, 5].copyWithin(0, 3), [4, 5, 3, 4, 5]); diff --git a/js/src/jit-test/tests/basic/array-length-double.js b/js/src/jit-test/tests/basic/array-length-double.js new file mode 100644 index 000000000..f4e0fd210 --- /dev/null +++ b/js/src/jit-test/tests/basic/array-length-double.js @@ -0,0 +1,13 @@ +function getLength(arr) { + return arr.length; +} +function f() { + var arr1 = new Array(10); + var arr2 = new Array(4294967295); + + for (var i=0; i<10; i++) { + assertEq(getLength(arr1), 10); + assertEq(getLength(arr2), 4294967295); + } +} +f(); diff --git a/js/src/jit-test/tests/basic/array-proto-outofrange.js b/js/src/jit-test/tests/basic/array-proto-outofrange.js new file mode 100644 index 000000000..795f41f72 --- /dev/null +++ b/js/src/jit-test/tests/basic/array-proto-outofrange.js @@ -0,0 +1,18 @@ +function f(obj) { + return typeof obj[15]; +} + +function test() { + var a = [1, 2]; + a.__proto__ = {15: 1337}; + var b = [1, 2, 3, 4]; + + for (var i = 0; i < 1000; i++) { + var r = f(i % 2 ? a : b); + assertEq(r, i % 2 ? "number" : "undefined"); + } +} + +test(); +test(); +test(); diff --git a/js/src/jit-test/tests/basic/array-slice.js b/js/src/jit-test/tests/basic/array-slice.js new file mode 100644 index 000000000..5aa87f391 --- /dev/null +++ b/js/src/jit-test/tests/basic/array-slice.js @@ -0,0 +1,32 @@ +function check_specified_range_zero_base_slice() { + var arr = new Array(32) + arr[0]=0, arr[1]=1, arr[7]=7; + var res = arr.slice(0,10); + assertEq(arr[0],res[0]); + assertEq(arr[1],res[1]); + assertEq(arr[7],res[7]); + assertEq(res.length,10); +} + +function check_specified_range_slice() { + var arr = new Array(32) + arr[0]=0, arr[6]=1, arr[8]=3; + var res = arr.slice(5,9); + assertEq(arr[6],res[1]); + assertEq(arr[8],res[3]); + assertEq(res.length,4); +} + +function check_all_range_slice() { + var arr = new Array(32) + arr[0]=0, arr[6]=1, arr[8]=3; + var res = arr.slice(); + assertEq(arr[0],res[0]); + assertEq(arr[6],res[6]); + assertEq(arr[8],res[8]); + assertEq(res.length,32); +} + +check_all_range_slice(); +check_specified_range_slice(); +check_specified_range_zero_base_slice();
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/array-tosource.js b/js/src/jit-test/tests/basic/array-tosource.js new file mode 100644 index 000000000..284f36940 --- /dev/null +++ b/js/src/jit-test/tests/basic/array-tosource.js @@ -0,0 +1,8 @@ +load(libdir + 'asserts.js'); + +assertEq(Array.prototype.toSource.call([1, 'hi']), '[1, "hi"]'); +assertEq(Array.prototype.toSource.call({1: 10, 0: 42, length: 2}), "[42, 10]"); +assertEq(Array.prototype.toSource.call({1: 10, 0: 42, length: 1}), "[42]"); +assertThrowsInstanceOf(() => Array.prototype.toSource.call("someString"), TypeError); +assertThrowsInstanceOf(() => Array.prototype.toSource.call(42), TypeError); +assertThrowsInstanceOf(() => Array.prototype.toSource.call(undefined), TypeError); diff --git a/js/src/jit-test/tests/basic/arrayConcat.js b/js/src/jit-test/tests/basic/arrayConcat.js new file mode 100644 index 000000000..17ad87711 --- /dev/null +++ b/js/src/jit-test/tests/basic/arrayConcat.js @@ -0,0 +1,18 @@ + +/* Test concat compiler paths. */ + +for (var i = 9; i < 10; i++) + assertEq([2].concat([3])[0], 2); + +function f(a, b) { + return a.concat(b)[0]; +} +function g() { + var x = []; + var y = [1]; + for (var i = 0; i < 50; i++) + assertEq(f(x, y), 1); + eval('y[0] = "three"'); + assertEq(f(x, y), "three"); +} +g(); diff --git a/js/src/jit-test/tests/basic/arrayNatives.js b/js/src/jit-test/tests/basic/arrayNatives.js new file mode 100644 index 000000000..5bb2099b2 --- /dev/null +++ b/js/src/jit-test/tests/basic/arrayNatives.js @@ -0,0 +1,18 @@ + +/* Array natives applied to non-arrays. */ + +var oa = {}; +Array.pop(oa); +assertEq(oa.length, 0); + +var ob = {}; +Array.push(ob, "twelve"); +assertEq(ob.length, 1); + +var oc = {}; +Array.shift(oc); +assertEq(oc.length, 0); + +var od = {}; +Array.unshift(od, "eight"); +assertEq(od.length, 1); diff --git a/js/src/jit-test/tests/basic/arrayPopShift.js b/js/src/jit-test/tests/basic/arrayPopShift.js new file mode 100644 index 000000000..9213f3c9a --- /dev/null +++ b/js/src/jit-test/tests/basic/arrayPopShift.js @@ -0,0 +1,30 @@ + +/* Test pop/shift compiler paths. */ + +function a() { + var x = []; + for (var i = 0; i < 50; i++) + x.push(i); + for (var j = 0; j < 100; j++) { + var z = x.shift(); + if (j < 50) + assertEq(z, j); + else + assertEq(z, undefined); + } +} +a(); + +function b() { + var x = []; + for (var i = 0; i < 50; i++) + x.push(i); + for (var j = 0; j < 100; j++) { + var z = x.pop(); + if (j < 50) + assertEq(z, 49 - j); + else + assertEq(z, undefined); + } +} +b(); diff --git a/js/src/jit-test/tests/basic/arrayProto.js b/js/src/jit-test/tests/basic/arrayProto.js new file mode 100644 index 000000000..0186d161e --- /dev/null +++ b/js/src/jit-test/tests/basic/arrayProto.js @@ -0,0 +1,12 @@ + +for (var i = 0; i < 15; i++) { + var x = Object.create([]); + assertEq(x.length, 0); +} + +for (var i = 0; i < 15; i++) { + function foo() {} + foo.prototype = []; + var x = new foo(); + assertEq(x.length, 0); +} diff --git a/js/src/jit-test/tests/basic/arraybuffer-slice-warn.js b/js/src/jit-test/tests/basic/arraybuffer-slice-warn.js new file mode 100644 index 000000000..291063e4a --- /dev/null +++ b/js/src/jit-test/tests/basic/arraybuffer-slice-warn.js @@ -0,0 +1,13 @@ +// ArrayBuffer.slice should be warned once and only once. + +enableLastWarning(); + +ArrayBuffer.slice(new ArrayBuffer(10), 1); +var warning = getLastWarning(); +assertEq(warning !== null, true, "warning should be generated"); +assertEq(warning.name, "Warning"); + +clearLastWarning(); +ArrayBuffer.slice(new ArrayBuffer(10), 1); +warning = getLastWarning(); +assertEq(warning, null, "warning should not generated for 2nd ocurrence"); diff --git a/js/src/jit-test/tests/basic/bigLoadStoreDisp.js b/js/src/jit-test/tests/basic/bigLoadStoreDisp.js new file mode 100644 index 000000000..4f0df8155 --- /dev/null +++ b/js/src/jit-test/tests/basic/bigLoadStoreDisp.js @@ -0,0 +1,25 @@ +// In Nanojit, loads and stores have a maximum displacement of 16-bits. Any +// displacements larger than that should be split off into a separate +// instruction that adds the displacement to the base pointer. This +// program tests if this is done correctly. +// +// x.y ends up having a dslot offset of 79988, because of the 20000 array +// elements before it. If Nanojit incorrectly stores this offset into a +// 16-bit value it will truncate to 14452 (because 79988 - 65536 == 14452). +// This means that the increments in the second loop will be done to one of +// the array elements instead of x.y. And so x.y's final value will be +// (99 + 8) instead of 1099. +// +// Note that setting x.y to 99 and checking its value at the end will +// access the correct location because those lines are interpreted. Phew. + +var x = {} +for (var i = 0; i < 20000; i++) + x[i] = 0; +x.y = 99; // not traced, correctly accessed + +for (var i = 0; i < 1000; ++i) { + x.y++; // traced, will access an array elem if disp was truncated +} +assertEq(x.y, 1099); // not traced, correctly accessed + diff --git a/js/src/jit-test/tests/basic/bindname-in-strict-eval.js b/js/src/jit-test/tests/basic/bindname-in-strict-eval.js new file mode 100644 index 000000000..e052a65dd --- /dev/null +++ b/js/src/jit-test/tests/basic/bindname-in-strict-eval.js @@ -0,0 +1,3 @@ +'use strict'; +eval("var i = 0; var end = 9; for(var j = 0; j < end; i++, j++) { i = 0; }"); +print("done"); diff --git a/js/src/jit-test/tests/basic/bitwiseAnd.js b/js/src/jit-test/tests/basic/bitwiseAnd.js new file mode 100644 index 000000000..dc9fafa4f --- /dev/null +++ b/js/src/jit-test/tests/basic/bitwiseAnd.js @@ -0,0 +1,10 @@ +function bitwiseAnd_inner(bitwiseAndValue) { + for (var i = 0; i < 60000; i++) + bitwiseAndValue = bitwiseAndValue & i; + return bitwiseAndValue; +} +function bitwiseAnd() +{ + return bitwiseAnd_inner(12341234); +} +assertEq(bitwiseAnd(), 0); diff --git a/js/src/jit-test/tests/basic/bitwiseGlobal.js b/js/src/jit-test/tests/basic/bitwiseGlobal.js new file mode 100644 index 000000000..e8967c12b --- /dev/null +++ b/js/src/jit-test/tests/basic/bitwiseGlobal.js @@ -0,0 +1,8 @@ +bitwiseAndValue = Math.pow(2,32); +for (var i = 0; i < 60000; i++) + bitwiseAndValue = bitwiseAndValue & i; + +assertEq(bitwiseAndValue, 0); + + + diff --git a/js/src/jit-test/tests/basic/bug-1133377.js b/js/src/jit-test/tests/basic/bug-1133377.js new file mode 100644 index 000000000..3883eb743 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug-1133377.js @@ -0,0 +1,11 @@ +var buffer = new ArrayBuffer(100); + +view = new DataView(buffer, undefined, undefined); +assertEq(view.buffer, buffer); +assertEq(view.byteOffset, 0); +assertEq(view.byteLength, 100); + +view = new DataView(buffer, 20, undefined); +assertEq(view.buffer, buffer); +assertEq(view.byteOffset, 20); +assertEq(view.byteLength, 80); diff --git a/js/src/jit-test/tests/basic/bug-1198090.js b/js/src/jit-test/tests/basic/bug-1198090.js new file mode 100644 index 000000000..143de6c70 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug-1198090.js @@ -0,0 +1,12 @@ +// |jit-test| allow-oom + +if (!('oomAtAllocation' in this)) + quit(); + +for (let a of [ + null, function() {}, function() {}, null, function() {}, function() {}, + function() {}, null, null, null, null, null, null, null, null, + function() {}, null, null, null, function() {} + ]) { + oomAtAllocation(5); +} diff --git a/js/src/jit-test/tests/basic/bug-1240532.js b/js/src/jit-test/tests/basic/bug-1240532.js new file mode 100644 index 000000000..6fd1ccd46 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug-1240532.js @@ -0,0 +1,3 @@ +if (helperThreadCount() > 0) { + evalInWorker("try { newGlobal({principal : 5}); } catch (e) {}"); +} diff --git a/js/src/jit-test/tests/basic/bug-1271507-2.js b/js/src/jit-test/tests/basic/bug-1271507-2.js new file mode 100644 index 000000000..78f5a2c12 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug-1271507-2.js @@ -0,0 +1,4 @@ +// |jit-test| allow-oom + +// Adapted from randomly chosen testcase: js/src/jit-test/tests/debug/bug-1238610.js +load(libdir + "../tests/basic/bug-1271507.js"); diff --git a/js/src/jit-test/tests/basic/bug-1271507.js b/js/src/jit-test/tests/basic/bug-1271507.js new file mode 100644 index 000000000..c9f16fd30 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug-1271507.js @@ -0,0 +1,13 @@ +// |jit-test| allow-oom +if (typeof oomAfterAllocations != "function") + quit(); + +lfcode = new Array(); +oomAfterAllocations(100); +loadFile(file); +lfGlobal = newGlobal() +for (lfLocal in this) + if (!(lfLocal in lfGlobal)) + lfGlobal[lfLocal] = this[lfLocal] +offThreadCompileScript(lfVarx) +lfGlobal.runOffThreadScript() diff --git a/js/src/jit-test/tests/basic/bug-508061.js b/js/src/jit-test/tests/basic/bug-508061.js new file mode 100644 index 000000000..8ee45e861 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug-508061.js @@ -0,0 +1,11 @@ +function loop() { + var x; + for (var i = 0; i < 9; i++) + x = {1.5: 1}; + return x; +} + +loop(); // record +Object.prototype.__defineSetter__('1.5', function () { return 'BAD'; }); +var x = loop(); // playback +assertEq(x["1.5"], 1);
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug-826124.js b/js/src/jit-test/tests/basic/bug-826124.js new file mode 100644 index 000000000..6efda93aa --- /dev/null +++ b/js/src/jit-test/tests/basic/bug-826124.js @@ -0,0 +1,14 @@ +var x = {}; +function f() { y.prop; } +x.toStr = function () { f(); }; +try { + f(); +} catch (e) { } +try { + x.toStr(); +} catch (e) { } +try { + function f() { which = 2; } + x.toStr(); +} catch (e) { which = 1; } +assertEq(which, 2); diff --git a/js/src/jit-test/tests/basic/bug1001090-1.js b/js/src/jit-test/tests/basic/bug1001090-1.js new file mode 100644 index 000000000..86970ffc4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1001090-1.js @@ -0,0 +1,2 @@ +(function() { let arguments })(); +(() => { let arguments; })() diff --git a/js/src/jit-test/tests/basic/bug1001090-2.js b/js/src/jit-test/tests/basic/bug1001090-2.js new file mode 100644 index 000000000..2a3be2722 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1001090-2.js @@ -0,0 +1,5 @@ +// |jit-test| error: ReferenceError +(function() { + with(x); + let x +})() diff --git a/js/src/jit-test/tests/basic/bug1001090-3.js b/js/src/jit-test/tests/basic/bug1001090-3.js new file mode 100644 index 000000000..ba3a88f1b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1001090-3.js @@ -0,0 +1,27 @@ +var output = []; +function g(s) { + L = s.length; + for (var i = 0; i < L; i++) { + a = s.charAt() + } +} +function h(f, inputs) { + results = []; + for (var j = 0; j < 99; ++j) { + for (var k = 0; k < 99; ++k) { + try { + results.push(f()) + } catch (e) {} + } + } + output.push(g(uneval(results))) +} +m = (function(x, y) {}); +h(m, []) +try { + output.push(x); + let x = s() +} catch (e) {} + +assertEq(output.length, 1); +assertEq(output[0], undefined); diff --git a/js/src/jit-test/tests/basic/bug1001090-4.js b/js/src/jit-test/tests/basic/bug1001090-4.js new file mode 100644 index 000000000..0511eea2a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1001090-4.js @@ -0,0 +1,30 @@ +var output = []; +function g(s) { + for (var i = 0; i < s.length; i++) { + s.charAt() + } +} +function h(f, inputs) { + results = [] + for (var j = 0; j < 99; ++j) { + for (var k = 0; k < 99; ++k) { + try { + results.push(f()) + } catch (e) {} + } + } + g(uneval(results)) +} +try { + x() +} catch (e) {} +m = function(y) { + return y; +}; +h(m, []); +try { + output.push(b); + let b = ""; +} catch (e) {} + +assertEq(output.length, 0); diff --git a/js/src/jit-test/tests/basic/bug1001090-5.js b/js/src/jit-test/tests/basic/bug1001090-5.js new file mode 100644 index 000000000..4636ca053 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1001090-5.js @@ -0,0 +1,6 @@ +// |jit-test| error: ReferenceError +evalcx("\ + for(x = 0; x < 9; x++) {\ + let y = y.s()\ + }\ +", newGlobal()) diff --git a/js/src/jit-test/tests/basic/bug1001090-6.js b/js/src/jit-test/tests/basic/bug1001090-6.js new file mode 100644 index 000000000..14d60e804 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1001090-6.js @@ -0,0 +1,7 @@ +// |jit-test| error: ReferenceError +(function() { + ((function() { + p(y) + })()); + let y +})() diff --git a/js/src/jit-test/tests/basic/bug1003161.js b/js/src/jit-test/tests/basic/bug1003161.js new file mode 100644 index 000000000..c2c602acb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1003161.js @@ -0,0 +1,8 @@ + +function foo(a, b) { + function bar() { + return b; + } + return arguments[0] + arguments[1] + bar(); +} +foo(1, 2); diff --git a/js/src/jit-test/tests/basic/bug1008339.js b/js/src/jit-test/tests/basic/bug1008339.js new file mode 100644 index 000000000..f253d6024 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1008339.js @@ -0,0 +1,64 @@ + +var count = 0; + +function Parent() { + // Scanning "this" properties here with Object.keys() solved the bug in my case + //Object.keys(this); + + this.log('Parent ctor'); + this.meth1(); + this.log('data3 before : ' + this.data3); + this.meth2(); + // Added properties lost in ChildA + this.log('data3 after : ' + this.data3); + this.log(''); + + if (count++) + assertEq(this.data3, 'z'); +} +Parent.prototype.meth1 = function () { + this.log('Parent.meth1()'); +}; +Parent.prototype.meth2 = function () { + this.log('Parent.meth2()'); + // Requirement for the bug : Parent.meth2() needs to add data + this.data4 = 'x'; +}; +Parent.prototype.log = function (data) { + print(data); +} + +// Intermediate constructor to instantiate children prototype without executing Parent constructor code +function ParentEmptyCtor() { } +ParentEmptyCtor.prototype = Parent.prototype; + +function ChildA() { + this.log('ChildA ctor'); + Parent.call(this); +} +ChildA.prototype = new ParentEmptyCtor(); +// Using Object.create() instead solves the bug +//ChildA.prototype = Object.create(ParentEmptyCtor.prototype); +ChildA.prototype.constructor = ChildA; +ChildA.prototype.meth1 = function () { + this.log('ChildA.meth1()'); + this.data3 = 'z'; +}; +ChildA.prototype.meth2 = function () { + this.log('ChildA.meth2()'); +}; + +function ChildB() { + this.log('ChildB ctor'); + Parent.call(this); +} +ChildB.prototype = new ParentEmptyCtor(); +//ChildB.prototype = Object.create(ParentEmptyCtor.prototype); +ChildB.prototype.constructor = ChildB; + +function demo() { + // Requirement for the bug : ChildB needs to be instantiated before ChildA + new ChildB(); + new ChildA(); +} +demo(); diff --git a/js/src/jit-test/tests/basic/bug1013922.js b/js/src/jit-test/tests/basic/bug1013922.js new file mode 100644 index 000000000..febe32ea5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1013922.js @@ -0,0 +1,67 @@ +String.prototype.repeat = function(num) { + return new Array(num + 1).join(this); +} + +function set_to_length(length, frag_size) +{ + var fragment = "'" + "x".repeat(frag_size) + "' + "; + var frags = Math.floor((length - 1)/frag_size); + var code = "var x = " + fragment.repeat(frags) + "'" + + "x".repeat(length - frags * frag_size) + "';"; + + try { + eval(code); + } + catch(err) { + if (err.message && err.message == "Out of memory") + return -1; + if (err == "out of memory") + return -1; + throw(err); /* Oops, broke something. */ + } + + return code.length; +} + +var first_fail; +var first_pass; +var frag_size; +var pass_code_length; + +function search_up() +{ + if (set_to_length(first_fail, frag_size) < 0) { + setTimeout(binary_search, 0); + return; + } + + first_fail *= 2; +} + +function binary_search() +{ + if (first_fail - first_pass > 1) { + var length = (first_pass + first_fail) / 2; + var code_len = set_to_length(length, frag_size); + if (code_len > 0) { + first_pass = length; + pass_code_length = code_len; + } else + first_fail = length; + setTimeout(binary_search, 0); + return; + } +} + +function run_find_limit() +{ + frag_size = 64; + first_fail = 65536; /* A guess */ + first_pass = 0; + pass_code_length = 0; + + for (var i=0; i<5; i++) + search_up(0); +} + +run_find_limit(); diff --git a/js/src/jit-test/tests/basic/bug1015339.js b/js/src/jit-test/tests/basic/bug1015339.js new file mode 100644 index 000000000..2441811d4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1015339.js @@ -0,0 +1,8 @@ +function f(x, y) { + for (var i=0; i<40; i++) { + var stack = getBacktrace({args: true, locals: true, thisprops: true}); + assertEq(stack.includes("f(x = "), true); + backtrace(); + } +} +f(1, 2); diff --git a/js/src/jit-test/tests/basic/bug1015766.js b/js/src/jit-test/tests/basic/bug1015766.js new file mode 100644 index 000000000..e76aff7c7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1015766.js @@ -0,0 +1,10 @@ +gczeal(8, 2) +try { + [new String, y] +} catch (e) {} +r = /()/ +try { + "".replace(r, () => { + []() + }); +} catch(e) {} diff --git a/js/src/jit-test/tests/basic/bug1018620.js b/js/src/jit-test/tests/basic/bug1018620.js new file mode 100644 index 000000000..64463d23c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1018620.js @@ -0,0 +1,5 @@ + +String.prototype.search = evalcx('').String.prototype.search; +''.search(/()/); +gcPreserveCode(); +gc(this); diff --git a/js/src/jit-test/tests/basic/bug1024786.js b/js/src/jit-test/tests/basic/bug1024786.js new file mode 100644 index 000000000..6811513cb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1024786.js @@ -0,0 +1,65 @@ +//|jit-test| error: SyntaxError + +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +(function(){}); +evaluate("function f(){\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",({ + fileName: null, + lineNumber: 42, + isRunOnce: 9, +})) diff --git a/js/src/jit-test/tests/basic/bug1033946.js b/js/src/jit-test/tests/basic/bug1033946.js new file mode 100644 index 000000000..a9dda468c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1033946.js @@ -0,0 +1,3 @@ + +assertEq((/(?!(?!(?!6)[\Wc]))/i).test(), false); +assertEq("foobar\xff5baz\u1200".search(/bar\u0178\d/i), 3); diff --git a/js/src/jit-test/tests/basic/bug1035287-track-allocation-sites-recursion.js b/js/src/jit-test/tests/basic/bug1035287-track-allocation-sites-recursion.js new file mode 100644 index 000000000..79394c31c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1035287-track-allocation-sites-recursion.js @@ -0,0 +1,7 @@ +// |jit-test| exitstatus: 3 + +enableTrackAllocations(); +function f() { + eval('f();'); +} +f(); diff --git a/js/src/jit-test/tests/basic/bug1035325.js b/js/src/jit-test/tests/basic/bug1035325.js new file mode 100644 index 000000000..48e6ff33a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1035325.js @@ -0,0 +1 @@ +print("\uDBFF\uDFFF"); // don't crash/assert diff --git a/js/src/jit-test/tests/basic/bug1054243.js b/js/src/jit-test/tests/basic/bug1054243.js new file mode 100644 index 000000000..66d167ad7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1054243.js @@ -0,0 +1,3 @@ +// |jit-test| error: uncaught exception +var prox = new Proxy({}, {getOwnPropertyDescriptor: function() { throw prox; }}); +Object.prototype.__lookupGetter__.call(prox, 'q'); diff --git a/js/src/jit-test/tests/basic/bug1057571.js b/js/src/jit-test/tests/basic/bug1057571.js new file mode 100644 index 000000000..42a07f99b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1057571.js @@ -0,0 +1,15 @@ + +test = (function () { + function f() { + [1,2,3,4,5]; + }; + return "var obj = { x : 2 };" + f.toSource() + "; f()"; +})(); +evalWithCache(test, {}); +function evalWithCache(code, ctx) { + code = cacheEntry(code); + ctx.global = newGlobal({ cloneSingletons: true }); + ctx.isRunOnce = true; + var res1 = evaluate(code, Object.create(ctx, {saveBytecode: { value: true } })); + var res2 = evaluate(code, Object.create(ctx, {loadBytecode: { value: true }, saveBytecode: { value: true } })); +} diff --git a/js/src/jit-test/tests/basic/bug1059459.js b/js/src/jit-test/tests/basic/bug1059459.js new file mode 100644 index 000000000..47f0246c7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1059459.js @@ -0,0 +1 @@ +evalcx(" s = 3; s; for(let x = 0; x < 1; ++x) { null }", newGlobal()) diff --git a/js/src/jit-test/tests/basic/bug1061534.js b/js/src/jit-test/tests/basic/bug1061534.js new file mode 100644 index 000000000..acfd1fb40 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1061534.js @@ -0,0 +1,15 @@ + +test = (function () { + function f() {}; + return "var obj = { x : 2 };" + f.toSource() + (4); +})(); +evalWithCache(test, {}); +function evalWithCache(code, ctx) { + code = cacheEntry(code); + ctx.global = newGlobal({ cloneSingletons: true }); + var res1 = evaluate(code, Object.create(ctx, {saveBytecode: { value: true } })); +} +if (typeof assertThrowsInstanceOf === 'undefined') { + var assertThrowsInstanceOf = function assertThrowsInstanceOf(f, ctor, msg) {}; +} +evaluate('evaluate(\'assertThrowsInstanceOf(function () {}, ["jak", "ms"]);\', { noScriptRval : true, isRunOnce: true })'); diff --git a/js/src/jit-test/tests/basic/bug1066414.js b/js/src/jit-test/tests/basic/bug1066414.js new file mode 100644 index 000000000..be7ab3346 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1066414.js @@ -0,0 +1 @@ +for (var [...y] in Object) {} // dont assert diff --git a/js/src/jit-test/tests/basic/bug1078871.js b/js/src/jit-test/tests/basic/bug1078871.js new file mode 100644 index 000000000..b055fa365 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1078871.js @@ -0,0 +1,44 @@ + +// Robert Jenkins' 32 bit integer hash function +var seed = 100; +Math.random = function() { + seed = (seed + 0x7ed55d16) + (seed<<12); + seed = (seed ^ 0xc761c23c) ^ (seed>>19); + seed = (seed + 0x165667b1) + (seed<<5); + seed = (seed + 0xd3a2646c) ^ (seed<<9); + seed = (seed + 0xfd7046c5) + (seed<<3); + seed = (seed ^ 0xb55a4f09) ^ (seed>>16); + seed = Math.abs(seed | 0); + return seed / 0xffffffff * 2; +} + +function tangle(n, m) { + function rand(n) { + return Math.floor(Math.random() * n); + } + + var arr = []; + for (var i = 0; i < n; i++) + arr[i] = String.fromCharCode(65 + rand(26)); + for (var i = 0; i < m; i++) { + var j = rand(n); + switch (rand(2)) { + case 0: { + var s = arr[rand(n)]; + var b = rand(s.length); + var e = b + rand(s.length - b); + if (e - b > 1) + arr[j] = s.substring(b, e); + } + break; + case 1: { + arr[j] = arr[rand(n)] + arr[rand(n)]; + } + } + uneval(arr[j]); + } + + return arr; +} + +tangle(10, 500); diff --git a/js/src/jit-test/tests/basic/bug1081175.js b/js/src/jit-test/tests/basic/bug1081175.js new file mode 100644 index 000000000..32766d768 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1081175.js @@ -0,0 +1,20 @@ +var input = "webkit-search-cancel-button-aaaaaaa-bbbbb-ccccccc-dddddddd," +var bad_regex = '([a-u-]|\\u0080|\\u0100)*[d]'; + +function forceUnicode(s) { + return ('\uffff' + s).replace(/^\uffff/, ''); +} +function testRegex(input) { + for (var i = 0; i < input.length; i++) { + var sub = input.substring(0, i + 1); + var res = sub.match(bad_regex); + if (i >= 50) { + assertEq(res.length, 2); + assertEq(res[1], sub.substr(-2, 1)); + } else { + assertEq(res, null); + } + } +} +testRegex(input); +testRegex(forceUnicode(input)); diff --git a/js/src/jit-test/tests/basic/bug1085464.js b/js/src/jit-test/tests/basic/bug1085464.js new file mode 100644 index 000000000..1c09eb8af --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1085464.js @@ -0,0 +1,20 @@ +function *f() { + var o = new Proxy({}, { + get: function() { assertEq(0, 1); }, + has: function() { assertEq(0, 2); } + }); + + with (o) { + yield 1; + with ({}) { + yield 2; + } + } + with ({".generator": 100}) { + yield eval("3"); + } +} +var s = ""; +for (var i of f()) + s += i; +assertEq(s, "123"); diff --git a/js/src/jit-test/tests/basic/bug1091757.js b/js/src/jit-test/tests/basic/bug1091757.js new file mode 100644 index 000000000..e3c437b6a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1091757.js @@ -0,0 +1,11 @@ +try { + (function() { + let a = 3; + let XY = XY; + return function() { return a; }; + })(); + assertEq(0, 1); +} catch(e) { + assertEq(e instanceof ReferenceError, true); + assertEq(e.message.includes("XY"), true); +} diff --git a/js/src/jit-test/tests/basic/bug1100623.js b/js/src/jit-test/tests/basic/bug1100623.js new file mode 100644 index 000000000..7de07d274 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1100623.js @@ -0,0 +1,12 @@ +// |jit-test| error: baz is null +var document = {getElementById: () => null}; + +(function() { + const one = 1; + + function foo() { return one; } + function bar() { return foo(); } + + var baz = document.getElementById("baz"); + baz.value; +})(); diff --git a/js/src/jit-test/tests/basic/bug1106982-2.js b/js/src/jit-test/tests/basic/bug1106982-2.js new file mode 100644 index 000000000..378d10f51 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1106982-2.js @@ -0,0 +1,20 @@ +var x = "wrong"; +var t = {x: "x"}; +var hits = 0; +var p = new Proxy(t, { + has(t, id) { + var found = id in t; + if (++hits == 2) + delete t[id]; + return found; + }, + get(t, id) { return t[id]; } +}); +evaluate(`function testFunc() { + x += " x"; +}`); + +var cloneFunc = clone(testFunc, p); +cloneFunc(); +assertEq(hits, 2); +assertEq(t.x, "undefined x"); diff --git a/js/src/jit-test/tests/basic/bug1106982.js b/js/src/jit-test/tests/basic/bug1106982.js new file mode 100644 index 000000000..ededf3b93 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1106982.js @@ -0,0 +1,19 @@ +var x = "wrong"; +var t = {x: "x"}; +var hits = 0; +var p = new Proxy(t, { + has(t, id) { + var found = id in t; + if (++hits == 2) + delete t[id]; + return found; + }, + get(t, id) { return t[id]; } +}); +with (p) + x += " x"; +// If you change this testcase (e.g. because we fix the number of +// has() calls we end up making to match spec better), don't forget to +// update bug1106982-2.js too. See also bug 1145641. +assertEq(hits, 2); +assertEq(t.x, "undefined x"); diff --git a/js/src/jit-test/tests/basic/bug1113980.js b/js/src/jit-test/tests/basic/bug1113980.js new file mode 100644 index 000000000..d975c5d8d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1113980.js @@ -0,0 +1,10 @@ +var p = new Proxy({}, { + getOwnPropertyDescriptor: function() { + return {value: 1, configurable: true, writable: true}; + }, + defineProperty: function() { + } +}, null); + +var o = Object.create(p); +o.a = 1; diff --git a/js/src/jit-test/tests/basic/bug1118996.js b/js/src/jit-test/tests/basic/bug1118996.js new file mode 100644 index 000000000..b5c8a4805 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1118996.js @@ -0,0 +1,13 @@ +// |jit-test| allow-oom; --fuzzing-safe; --no-threads; --no-ion +g = newGlobal(); +gcparam('maxBytes', gcparam('gcBytes')); +try { + evaluate("return 0", ({ + global: g, + newContext: true + })); +} catch (error) { + // We expect evaluate() above to fail with OOM, but due to GC zeal settings + // it may execute correctly and throw "SyntaxError: return not in function". + // This catch block is to ignore that error. +} diff --git a/js/src/jit-test/tests/basic/bug1122534.js b/js/src/jit-test/tests/basic/bug1122534.js new file mode 100644 index 000000000..bdf1a0b57 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1122534.js @@ -0,0 +1,16 @@ +// |jit-test| error: TypeError + +function newFunc(x) { new Function(x)(); }; +newFunc("\ +function GetUnicodeValues(c) {\ + u = new Array();\ + if ((c >= 0x0100 && c < 0x0138) || (c > 0x1Bedb && c < 0x0178))\ + return;\ + return u;\ +}\ +function Unicode(c) {\ + u = GetUnicodeValues(c);\ + this.upper = u[0];\ +}\ +for (var i = 0; i <= 0x017f; i++) { var U = new Unicode(i); }\ +"); diff --git a/js/src/jit-test/tests/basic/bug1122581.js b/js/src/jit-test/tests/basic/bug1122581.js new file mode 100644 index 000000000..7c9992427 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1122581.js @@ -0,0 +1,10 @@ +function f(x, y) { + for (var i=0; i<50; i++) { + if (i % 10 === 0) { + var stack = getBacktrace({args: true, locals: true, thisprops: true}); + assertEq(stack.includes("f(x = "), true); + foo = arguments; + } + } +} +f(1, 2); diff --git a/js/src/jit-test/tests/basic/bug1127303.js b/js/src/jit-test/tests/basic/bug1127303.js new file mode 100644 index 000000000..078b4477c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1127303.js @@ -0,0 +1,9 @@ + +function test1() {} +function test() { test1.call(this); } +var length = 30 * 1024 - 1; +var obj = new test(); +for(var i = 0 ; i < length ; i++) { + obj.next = new (function ( ) { } ) (); + obj = obj.next; +} diff --git a/js/src/jit-test/tests/basic/bug1131035.js b/js/src/jit-test/tests/basic/bug1131035.js new file mode 100644 index 000000000..6ff80f374 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1131035.js @@ -0,0 +1,9 @@ + +function TestCase() { + this.passed = 'x'; +} +result = "pass"; +for (var i = 0; i < 100; i++) + new TestCase(result); +function Gen2(value) {} +Gen2.prototype = new TestCase(); diff --git a/js/src/jit-test/tests/basic/bug1134146.js b/js/src/jit-test/tests/basic/bug1134146.js new file mode 100644 index 000000000..5d2a47895 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1134146.js @@ -0,0 +1,10 @@ + +function Foo(a, b) { + b = {}; + this.b = b; +}; +var a = []; +for (var i = 0; i < 50; i++) + a.push(new Foo(i, i + 1)); +i = 0; +a[i].c = i; diff --git a/js/src/jit-test/tests/basic/bug1135718.js b/js/src/jit-test/tests/basic/bug1135718.js new file mode 100644 index 000000000..312c2ce35 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1135718.js @@ -0,0 +1,13 @@ + +setJitCompilerOption("ion.warmup.trigger", 30); +function ArrayCallback(state) + this.state = state; +ArrayCallback.prototype.isUpperCase = function(v, index, array) { + return this.state ? true : (v == v.toUpperCase()); +}; +strings = ['hello', 'Array', 'WORLD']; +obj = new ArrayCallback(false); +strings.filter(obj.isUpperCase, obj) +obj = new ArrayCallback(true); +strings.filter(obj.isUpperCase, obj) +obj.__proto__ = {}; diff --git a/js/src/jit-test/tests/basic/bug1137616.js b/js/src/jit-test/tests/basic/bug1137616.js new file mode 100644 index 000000000..ca093c1ba --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1137616.js @@ -0,0 +1,9 @@ +// Accessing a name that isn't a global property is a ReferenceError, +// even if a proxy is on the global's prototype chain. +load(libdir + "asserts.js"); +load(libdir + "immutable-prototype.js"); + +var g = newGlobal(); +if (globalPrototypeChainIsMutable()) + g.__proto__ = {}; +assertThrowsInstanceOf(() => g.eval("s += ''"), g.ReferenceError); diff --git a/js/src/jit-test/tests/basic/bug1141154.js b/js/src/jit-test/tests/basic/bug1141154.js new file mode 100644 index 000000000..3640c4c17 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1141154.js @@ -0,0 +1,19 @@ +function foo() { + (function() { + Object.preventExtensions(this); + setJitCompilerOption("ion.warmup.trigger", 4); + var g = newGlobal(); + g.debuggeeGlobal = this; + g.eval("(" + function () { + dbg = new Debugger(debuggeeGlobal); + dbg.onExceptionUnwind = function (frame, exc) { + var s = '!'; + for (var f = frame; f; f = f.older) + debuggeeGlobal.log += s; + }; + } + ")();"); + try { + j('Number.prototype.toSource.call([])'); + } catch (exc) {} + })(); +} foo(); diff --git a/js/src/jit-test/tests/basic/bug1141329.js b/js/src/jit-test/tests/basic/bug1141329.js new file mode 100644 index 000000000..ee41a61bb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1141329.js @@ -0,0 +1,15 @@ +x = [] +Object.defineProperty(x, 7, {}) +function f() { + "use strict" + x.length = { + valueOf: function() { + return 7 + } + } +} +for (var m = 0; m < 9; m++) { + try { + f() + } catch (e) {} +} diff --git a/js/src/jit-test/tests/basic/bug1141338.js b/js/src/jit-test/tests/basic/bug1141338.js new file mode 100644 index 000000000..8c04316f7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1141338.js @@ -0,0 +1,6 @@ +z = []; +m = evalcx(""); +Object.freeze(m); +for each(l in [{}, {}]) { + m.s = ""; +} diff --git a/js/src/jit-test/tests/basic/bug1143106.js b/js/src/jit-test/tests/basic/bug1143106.js new file mode 100644 index 000000000..6bf81bb65 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1143106.js @@ -0,0 +1,8 @@ +({x:3}), ({x:3}), ({x:3}), ({x:3}), ({x:3}), ({x:3}), +({x:3}), ({x:3}), ({x:3}), ({x:3}), ({x:3}), ({x:3}), +({x:3}), ({x:3}), ({x:3}), ({x:3}), ({x:3}), ({x:3}), +({x:3}), ({x:3}), ({x:3}) + +[{x:3},{x:3},{x:3},{x:3},{x:3},{x:3},{x:3}, + {x:3},{x:3},{x:3},{x:3},{x:3},{x:3},{x:3}, + {x:3},{x:3},{x:3},{x:3},{x:3},{x:3},{x:3}] diff --git a/js/src/jit-test/tests/basic/bug1146836.js b/js/src/jit-test/tests/basic/bug1146836.js new file mode 100644 index 000000000..2b4f4acec --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1146836.js @@ -0,0 +1,11 @@ +function f() { + var s = "switch (x) {"; + for (var i=8000; i<16400; i++) { + s += "case " + i + ": return " + i + "; break;"; + } + s += "case 8005: return -1; break;"; + s += "}"; + var g = Function("x", s); + assertEq(g(8005), 8005); +} +f(); diff --git a/js/src/jit-test/tests/basic/bug1147216.js b/js/src/jit-test/tests/basic/bug1147216.js new file mode 100644 index 000000000..d683d713f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1147216.js @@ -0,0 +1,25 @@ +// Ensure JSOP_LINENO (emitted after JSOP_EVAL) handles big line +// numbers correctly. +function getsource() { + var s = ""; + for (var i=0; i<66002; i++) { + s += "\n"; + if (i === 66000) + s += "eval('stack = Error().stack');"; + } + return s; +} +function test() { + var stack; + eval(getsource()); + assertEq(stack.indexOf("line 66002") > 0, true); +} +test(); + +function testStrict() { + "use strict"; + var stack; + eval(getsource()); + assertEq(stack.indexOf("line 66002") > 0, true); +} +testStrict(); diff --git a/js/src/jit-test/tests/basic/bug1153057.js b/js/src/jit-test/tests/basic/bug1153057.js new file mode 100644 index 000000000..7f4ab1b11 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1153057.js @@ -0,0 +1 @@ +({ "0"() { eval(); } }); diff --git a/js/src/jit-test/tests/basic/bug1161762.js b/js/src/jit-test/tests/basic/bug1161762.js new file mode 100644 index 000000000..ba072c507 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1161762.js @@ -0,0 +1,24 @@ + +for (var actual = .5; actual < 100; actual++) { + var test2 = { + test4: actual + 6, + test2: actual + 9, + printStatus: actual + 10, + isPrototypeOf: actual + 12, + expect: actual + 14, + printErr: actual + 17, + ret2: actual + 19, + printBugNumber: actual + 32, + test3: actual + 33, + String: actual + 34, + summary: actual + 40, + test1: actual + 42, + Array: actual + 43, + BUGNUMBER: actual + 44, + assertEq: actual + 45, + __call__: actual + 47, + x: actual + 48, + test0: actual + 49, + res: actual + 50 + }; +} diff --git a/js/src/jit-test/tests/basic/bug1168667.js b/js/src/jit-test/tests/basic/bug1168667.js new file mode 100644 index 000000000..ce3a7fc4d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1168667.js @@ -0,0 +1,6 @@ +for each(var x in [{n: 1}, {n: 1}, {n: 1}, {n: 1}, {n: 1}, {n: 1}, {n: 1}, + {n: 1}, {n: 1}, {n: 1}, {n: 1}, {n: 1}, {n: 1}, {n: 1}, + {n: 1}, {n: 1}, {n: 1}, {n: 1}, {n: 1}, {n: 1}]) { + x[0] = 0; + Object.freeze(x); +} diff --git a/js/src/jit-test/tests/basic/bug1170355.js b/js/src/jit-test/tests/basic/bug1170355.js new file mode 100644 index 000000000..cddb3c547 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1170355.js @@ -0,0 +1,3 @@ +x = Array(4294967295); +x[1] = 0; +Array.prototype.shift.call(x); diff --git a/js/src/jit-test/tests/basic/bug1172503-2.js b/js/src/jit-test/tests/basic/bug1172503-2.js new file mode 100644 index 000000000..2c65b7161 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1172503-2.js @@ -0,0 +1,14 @@ +load(libdir + "immutable-prototype.js"); + +var n = 0; +if (globalPrototypeChainIsMutable()) { + this.__proto__ = new Proxy({}, { + has: function () { + if (++n === 2) + return false; + a = 0; + } + }); + } +a = 0; +assertEq(a, 0); diff --git a/js/src/jit-test/tests/basic/bug1177907.js b/js/src/jit-test/tests/basic/bug1177907.js new file mode 100644 index 000000000..0967b8ace --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1177907.js @@ -0,0 +1,4 @@ +// |jit-test| error: InternalError + +var Date_toString = newGlobal().Date.prototype.toString; +(function f(){ f(Date_toString.call({})); })(); diff --git a/js/src/jit-test/tests/basic/bug1180054.js b/js/src/jit-test/tests/basic/bug1180054.js new file mode 100644 index 000000000..ae23ad3d6 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1180054.js @@ -0,0 +1,6 @@ +function entryFrame_1(d) { + assertJitStackInvariants(); +} +for (i = 0Xa; i < 40; i++) { + new entryFrame_1(); +} diff --git a/js/src/jit-test/tests/basic/bug1182865.js b/js/src/jit-test/tests/basic/bug1182865.js new file mode 100644 index 000000000..f221b4328 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1182865.js @@ -0,0 +1,8 @@ + +for (var j = 0; j < 99; j++) { + Array[{ + f() { + eval() + } + }]; +} diff --git a/js/src/jit-test/tests/basic/bug1185653.js b/js/src/jit-test/tests/basic/bug1185653.js new file mode 100644 index 000000000..b29fd6e0c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1185653.js @@ -0,0 +1,28 @@ +function f() { + var arr = []; + for (var i=0; i<80; i++) { + var o3 = {foo: i}; + var o2 = {owner: o3}; + arr.push(o2); + } + for (var i=0; i<80; i++) { + var o2 = arr[i]; + var o3 = o2.owner; + Object.defineProperty(o3, "bar", {value: arr, enumerable: false}); + } + assertEq(JSON.stringify(arr).length, 1671); +} +f(); + +function g() { + var arr = []; + for (var i=0; i<100; i++) { + arr.push([1, i]); + } + for (var i=0; i<100; i++) { + for (var p in arr[i]) { + assertEq(p === "0" || p === "1", true); + } + } +} +g(); diff --git a/js/src/jit-test/tests/basic/bug1189744.js b/js/src/jit-test/tests/basic/bug1189744.js new file mode 100644 index 000000000..6d202e702 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1189744.js @@ -0,0 +1,11 @@ +var obj; +for (var i = 0; i < 100; i++) + obj = {a: 7, b: 13, c: 42, d: 0}; + +Object.defineProperty(obj, "x", { + get: function () { return 3; } +}); +obj.__ob__ = 17; + +Object.defineProperty(obj, "c", {value: 8, writable: true}); +assertEq(obj.__ob__, 17); diff --git a/js/src/jit-test/tests/basic/bug1190733.js b/js/src/jit-test/tests/basic/bug1190733.js new file mode 100644 index 000000000..2b3f4a419 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1190733.js @@ -0,0 +1,7 @@ + +x = []; +Array.prototype.push.call(x, Uint8ClampedArray); +(function() { + x.length = 9; +})(); +Array.prototype.reverse.call(x); diff --git a/js/src/jit-test/tests/basic/bug1195452.js b/js/src/jit-test/tests/basic/bug1195452.js new file mode 100644 index 000000000..92d856857 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1195452.js @@ -0,0 +1,42 @@ +// |jit-test| allow-oom; allow-unhandlable-oom + +var lfcode = new Array(); +lfcode.push(` +function TestCase(e) { + this.expect = e; +} +function writeHeaderToLog() {} +var SECTION = "15.5.4.7-1"; +var TITLE = "String.protoype.lastIndexOf"; +writeHeaderToLog(); +var j = 0; +for (k = 0, i = 0x0021; i < 0x007e; i++, j++, k++) + new TestCase("x" - 1); +LastIndexOf(); +function LastIndexOf() { + if (isNaN(n)) {} +} +`); +lfcode.push(` +oomAfterAllocations(50); +writeHeaderToLog(SECTION + " " + TITLE); +var expect = "Passed"; +try { + eval("this = true"); +} catch (e) { + result = expect; + exception = e.toString(0, 0); +} +new TestCase(); +`); +while (lfcode.length > 0) { + var file = lfcode.shift(); + loadFile(file) +} +function loadFile(lfVarx) { + try { + if (lfVarx.substr(-3) != ".js" && lfVarx.length != 1) { + evaluate(lfVarx); + } + } catch (lfVare) {} +} diff --git a/js/src/jit-test/tests/basic/bug1196579.js b/js/src/jit-test/tests/basic/bug1196579.js new file mode 100644 index 000000000..1f8f3760e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1196579.js @@ -0,0 +1,14 @@ + +setJitCompilerOption("ion.warmup.trigger", 30); +var spaces = [ +"\u0009", "\u000b", "\u000c", "\u0020", "\u00a0", "\u1680", +"\u180e", "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", +"\u2005", "\u2006", "\u2007", "\u2008", "\u2009", "\u200a", +]; +var line_terminators = [ "\u2028", "\u2029", "\u000a", "\u000d" ]; +var space_chars = [].concat(spaces, line_terminators); +var non_space_chars = [ "\u200b", "\u200c", "\u200d" ]; +var chars = [].concat(space_chars, non_space_chars); +var is_space = [].concat(space_chars.map(function(ch) { return true; }), +non_space_chars.map(function() { return false; })); +chars.map(function(ch) {}).join(','); diff --git a/js/src/jit-test/tests/basic/bug1203790.js b/js/src/jit-test/tests/basic/bug1203790.js new file mode 100644 index 000000000..9fee5117f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1203790.js @@ -0,0 +1,10 @@ +gczeal(14); +verifyprebarriers(); +x = []; +Array.prototype.push.call(x, new Uint8Array()); +Array.prototype.some.call(x, function() { + try { + y.toString(); + } catch (e) {} +}); +Array.prototype.shift.call(x); diff --git a/js/src/jit-test/tests/basic/bug1204722.js b/js/src/jit-test/tests/basic/bug1204722.js new file mode 100644 index 000000000..5102b57c9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1204722.js @@ -0,0 +1,7 @@ + +x = [1e81]; +x.map(function() {}); +x.pop(); +x.push([]); +[].map(function() {}); +eval("[1/0]"); diff --git a/js/src/jit-test/tests/basic/bug1205870.js b/js/src/jit-test/tests/basic/bug1205870.js new file mode 100644 index 000000000..8340a797c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1205870.js @@ -0,0 +1,16 @@ + +// Make sure that unboxed arrays can be created with all possible inline +// capacities for the different sizes. +var bools = []; +var ints = []; +var doubles = []; +for (var i = 0; i < 150; i++) { + bools.push(false); + ints.push(0); + doubles.push(0.5); +} +for (var i = 0; i < 150; i++) { + bools = bools.slice(1); + ints = ints.slice(1); + doubles = doubles.slice(1); +} diff --git a/js/src/jit-test/tests/basic/bug1206265.js b/js/src/jit-test/tests/basic/bug1206265.js new file mode 100644 index 000000000..cd35cdbea --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1206265.js @@ -0,0 +1,8 @@ +x = [ + objectEmulatingUndefined(), + function() {} +]; +x.forEach(function() {}); +this.x.sort(function() {}); +assertEq(x[0] instanceof Function, false); +assertEq(x[1] instanceof Function, true); diff --git a/js/src/jit-test/tests/basic/bug1207863.js b/js/src/jit-test/tests/basic/bug1207863.js new file mode 100644 index 000000000..a75beba34 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1207863.js @@ -0,0 +1,24 @@ +// |jit-test| allow-oom; allow-unhandlable-oom + +if (!("oomAtAllocation" in this && "resetOOMFailure" in this)) + quit(); + +function oomTest(f) { + var i = 1; + do { + try { + oomAtAllocation(i); + f(); + } catch (e) { + more = resetOOMFailure(); + } + i++; + } while(more); +} +oomTest( + () => 3 + | (function () { + "use strict"; + return eval("f();"); + })() +); diff --git a/js/src/jit-test/tests/basic/bug1208403.js b/js/src/jit-test/tests/basic/bug1208403.js new file mode 100644 index 000000000..5077fcef0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1208403.js @@ -0,0 +1,2 @@ +// |jit-test| error: scripted function +byteSizeOfScript(Array); diff --git a/js/src/jit-test/tests/basic/bug1210596.js b/js/src/jit-test/tests/basic/bug1210596.js new file mode 100644 index 000000000..5efea9fcc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1210596.js @@ -0,0 +1,4 @@ +var count = 0; +var a = Array.prototype.concat.call([], [, []], []); +a.forEach(function() { count++; }); +assertEq(count, 1); diff --git a/js/src/jit-test/tests/basic/bug1219363.js b/js/src/jit-test/tests/basic/bug1219363.js new file mode 100644 index 000000000..03e4008ab --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1219363.js @@ -0,0 +1,9 @@ +var x = [1, 2, , 4] +x[100000] = 1; +var y = Object.create(x); +y.a = 1; +y.b = 1; +var arr = []; +for (var z in y) + arr.push(z); +assertEq(arr.join(), "a,b,0,1,3,100000"); diff --git a/js/src/jit-test/tests/basic/bug1220766.js b/js/src/jit-test/tests/basic/bug1220766.js new file mode 100644 index 000000000..fca11eafe --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1220766.js @@ -0,0 +1,3 @@ +iter = getSelfHostedValue("CreateListIterator")([]); +iter.next(); +iter.next(); diff --git a/js/src/jit-test/tests/basic/bug1232269.js b/js/src/jit-test/tests/basic/bug1232269.js new file mode 100644 index 000000000..c979d3b40 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1232269.js @@ -0,0 +1,30 @@ + +function f() { + for (var i=0; i<100; i++) { + var obj = {data: {id:1}}; + } + Object.defineProperty(obj, "id", { + configurable: true, + enumerable: false, + get: function() { + return this.data.id; + } + }); + return obj.id; +} +assertEq(f(), 1); + +function f2() { + for (var i=0; i<100; i++) { + var obj = {data: {id:1}}; + } + Object.defineProperty(obj, "id", { + configurable: true, + enumerable: false, + get: function() { return this.data.id; }, + set: function(v) { this.data.id = v; } + }); + obj.id = 3; + return obj.id; +} +assertEq(f2(), 3); diff --git a/js/src/jit-test/tests/basic/bug1234414.js b/js/src/jit-test/tests/basic/bug1234414.js new file mode 100644 index 000000000..973aacab4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1234414.js @@ -0,0 +1,12 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(() => { + var max = 400; + function f(b) { + if (b) { + f(b - 1); + } else eval('"use strict"; const z = w; z = 1 + w; c = 5'); + } + f(max - 1); +}); diff --git a/js/src/jit-test/tests/basic/bug1236476.js b/js/src/jit-test/tests/basic/bug1236476.js new file mode 100644 index 000000000..f9f2b3d5c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1236476.js @@ -0,0 +1,16 @@ +// |jit-test| allow-oom; allow-unhandlable-oom +// 1236476 + +if (typeof oomTest !== 'function' || + typeof offThreadCompileScript !== 'function' || + typeof runOffThreadScript !== 'function') + quit(); + +oomTest(() => { + offThreadCompileScript(` + "use asm"; + return assertEq; + `); + runOffThreadScript(); +}); + diff --git a/js/src/jit-test/tests/basic/bug1237564.js b/js/src/jit-test/tests/basic/bug1237564.js new file mode 100644 index 000000000..a67174c75 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1237564.js @@ -0,0 +1,8 @@ +// |jit-test| error:ReferenceError: can't access lexical +try { + evaluate("let x = (() => { throw 3 })();"); +} catch(e) { + assertEq(e, 3); +} +Object.defineProperty(this, "x", {}); +(function() { x = 3; })(); diff --git a/js/src/jit-test/tests/basic/bug1238003.js b/js/src/jit-test/tests/basic/bug1238003.js new file mode 100644 index 000000000..64c89cb27 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1238003.js @@ -0,0 +1,15 @@ +function f(str) { + if (typeof str === 'string') + str = new RegExp(str); + for (var i = 0; i < 2000; i++) + str.test('foo'); +} +f("abc"); + +function g(str) { + if (typeof str === 'string') + str = new RegExp(str); + for (var i = 0; i < 2000; i++) + str.exec('foo'); +} +g("abc"); diff --git a/js/src/jit-test/tests/basic/bug1238630.js b/js/src/jit-test/tests/basic/bug1238630.js new file mode 100644 index 000000000..021b66af5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1238630.js @@ -0,0 +1,7 @@ +var g = /1/g; +g.exec('1234561'); +g.exec(); +var r = /uDC38/ug; +r.lastIndex = 1; +var str = "\uD83D\uDC38"; +r.exec(str); diff --git a/js/src/jit-test/tests/basic/bug1240502.js b/js/src/jit-test/tests/basic/bug1240502.js new file mode 100644 index 000000000..854c7a26d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1240502.js @@ -0,0 +1,3 @@ +if (!('oomTest' in this)) + quit(); +oomTest(() => eval(`Array(..."ABC")`)); diff --git a/js/src/jit-test/tests/basic/bug1247926.js b/js/src/jit-test/tests/basic/bug1247926.js new file mode 100644 index 000000000..e93198db3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1247926.js @@ -0,0 +1,6 @@ + +JSON.parse('[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0]', function(k, v) { return ""; }); +str = "["; +for (i = 0; i < 2048; i++) str += "1," +str += "1]"; +JSON.parse(str); diff --git a/js/src/jit-test/tests/basic/bug1263868.js b/js/src/jit-test/tests/basic/bug1263868.js new file mode 100644 index 000000000..c73a4b796 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1263868.js @@ -0,0 +1,12 @@ +if (!('oomTest' in this)) + quit(); +function g(f, params) { + entryPoints(params); +} +function entry1() {}; +s = "g(entry1, {function: entry1});"; +f(s); +f(s); +function f(x) { + oomTest(() => eval(x)); +} diff --git a/js/src/jit-test/tests/basic/bug1264954.js b/js/src/jit-test/tests/basic/bug1264954.js new file mode 100644 index 000000000..d67ac2b63 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1264954.js @@ -0,0 +1,8 @@ +if (!('oomTest' in this)) + quit(); +function f(x) { + oomTest(() => eval(x)); +} +f(""); +f(""); +f(`eval([ "x = \`\${new Error.lineNumber}" ].join())`); diff --git a/js/src/jit-test/tests/basic/bug1265693.js b/js/src/jit-test/tests/basic/bug1265693.js new file mode 100644 index 000000000..93c9a0e3e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1265693.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); + +oomTest(Function("Function.hasOwnProperty(1.1)")); diff --git a/js/src/jit-test/tests/basic/bug1276882.js b/js/src/jit-test/tests/basic/bug1276882.js new file mode 100644 index 000000000..4e88122be --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1276882.js @@ -0,0 +1,5 @@ +// |jit-test| error: sleep interval is not a number +sleep(0.001); +1; +sleep(0.1); +sleep(this); diff --git a/js/src/jit-test/tests/basic/bug1278839.js b/js/src/jit-test/tests/basic/bug1278839.js new file mode 100644 index 000000000..079aac4b3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1278839.js @@ -0,0 +1,4 @@ +if (!('oomTest' in this)) + quit(); +for (var i=0; i<2; i++) + oomTest(() => eval("setJitCompilerOption(eval + Function, 0);")); diff --git a/js/src/jit-test/tests/basic/bug1280252.js b/js/src/jit-test/tests/basic/bug1280252.js new file mode 100644 index 000000000..486d2d2a5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1280252.js @@ -0,0 +1,9 @@ +function f() { + x = arguments; + delete x[1]; +} +f(0, 1); +gc(); +assertEq(x.length, 2); +assertEq(0 in x, true); +assertEq(1 in x, false); diff --git a/js/src/jit-test/tests/basic/bug1285227.js b/js/src/jit-test/tests/basic/bug1285227.js new file mode 100644 index 000000000..f68a4fbde --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1285227.js @@ -0,0 +1,5 @@ +if (helperThreadCount() === 0) + quit(); +evalInWorker(` + (new WeakMap).set(FakeDOMObject.prototype, this) +`); diff --git a/js/src/jit-test/tests/basic/bug1292858.js b/js/src/jit-test/tests/basic/bug1292858.js new file mode 100644 index 000000000..788eb9652 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1292858.js @@ -0,0 +1,47 @@ +var caughtInvalidArguments = false; +var a = -1 +try { + var buf = new Uint8ClampedArray(a); + throw new Error("didn't throw"); +} catch (e) { + assertEq(e instanceof TypeError, true, + "expected TypeError, instead threw: " + e); + caughtInvalidArguments = true; +} +assertEq(caughtInvalidArguments, true); + +var caughtInvalidArguments = false; +var i = 0; +while (true) { + i = (i + 1) | 0; + var a = inIon() ? -1 : 300; + try { + var buf = new Uint8ClampedArray(a); + assertEq(buf.length, 300); + } catch (e) { + assertEq(a, -1); + assertEq(e instanceof TypeError, true, + "expected TypeError, instead threw: " + e); + caughtInvalidArguments = true; + break; + } +} +assertEq(caughtInvalidArguments, true); + +var caughtInvalidArguments = false; +var i = 0; +while (true) { + i = (i + 1) | 0; + var a = inIon() ? -1 : 0; + try { + var buf = new Uint8ClampedArray(a); + assertEq(buf.length, 0); + } catch (e) { + assertEq(a, -1); + assertEq(e instanceof TypeError, true, + "expected TypeError, instead threw: " + e); + caughtInvalidArguments = true; + break; + } +} +assertEq(caughtInvalidArguments, true); diff --git a/js/src/jit-test/tests/basic/bug1293258.js b/js/src/jit-test/tests/basic/bug1293258.js new file mode 100644 index 000000000..79d4dcbd5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1293258.js @@ -0,0 +1,10 @@ +try { + function test() { + var arr = new Int8Array(400); + var o = new test(true); + arr[idx] = 9; + } + test(); +} catch(e) { + assertEq(""+e, "InternalError: too much recursion"); +} diff --git a/js/src/jit-test/tests/basic/bug1295031.js b/js/src/jit-test/tests/basic/bug1295031.js new file mode 100644 index 000000000..386ffc93a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1295031.js @@ -0,0 +1,20 @@ +try { + while (true) { + a = inIon() ? 0 : 300; + try { + buf = new Uint8ClampedArray(a); + assertEq(buf.length, 300); + } catch (e) { + assertEqa; + } + } +} catch(exc1) {} +loadFile() +function loadFile() { + try { + switch (lfRunTypeId) { + case 1: + eval(); + } + } catch (lfVare) {} +} diff --git a/js/src/jit-test/tests/basic/bug1296015.js b/js/src/jit-test/tests/basic/bug1296015.js new file mode 100644 index 000000000..ce1b270d2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1296015.js @@ -0,0 +1,9 @@ +function f() { + for (var i=0; i<30000; i++) { + var a = inIon() ? 0 : 300; + var buf = new Uint8ClampedArray(a); + (function() {}) * this; + } + try {} catch(e) {} +} +f(); diff --git a/js/src/jit-test/tests/basic/bug1296016.js b/js/src/jit-test/tests/basic/bug1296016.js new file mode 100644 index 000000000..6637cc819 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1296016.js @@ -0,0 +1,4 @@ +if (helperThreadCount() === 0) + quit(0); +offThreadCompileScript(``); +evalInWorker(`runOffThreadScript()`); diff --git a/js/src/jit-test/tests/basic/bug1296249.js b/js/src/jit-test/tests/basic/bug1296249.js new file mode 100644 index 000000000..b9994fd42 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1296249.js @@ -0,0 +1,10 @@ +// |jit-test| slow +if (!('oomTest' in this)) + quit(); + +function f(x) { + new Int32Array(x); +} + +f(0); +oomTest(() => f(2147483647)); diff --git a/js/src/jit-test/tests/basic/bug1300548.js b/js/src/jit-test/tests/basic/bug1300548.js new file mode 100644 index 000000000..f70f560bf --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1300548.js @@ -0,0 +1,13 @@ +var g1 = newGlobal(); +var g2 = newGlobal({sameZoneAs: g1}); +function f() { + var o = Object.create(null); + for (var p in o) {}; +} +g1.eval(f.toSource()); +g2.eval(f.toSource()); + +for (var i=0; i<10; i++) { + g1.eval("f()"); + g2.eval("f()"); +} diff --git a/js/src/jit-test/tests/basic/bug1300904.js b/js/src/jit-test/tests/basic/bug1300904.js new file mode 100644 index 000000000..fb02778d0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1300904.js @@ -0,0 +1,7 @@ +if (!('oomTest' in this)) + quit(); +Object.getOwnPropertyNames(this); +oomTest(function() { + this[0] = null; + Object.freeze(this); +}); diff --git a/js/src/jit-test/tests/basic/bug1301797.js b/js/src/jit-test/tests/basic/bug1301797.js new file mode 100644 index 000000000..0822943e3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1301797.js @@ -0,0 +1,4 @@ +var arr = new Uint8ClampedArray(10*1024*1024); +var sum = 0; +for (var i = 0; i < 10000; i++) + sum += arr[i]; diff --git a/js/src/jit-test/tests/basic/bug1302682.js b/js/src/jit-test/tests/basic/bug1302682.js new file mode 100644 index 000000000..1fdb7fe16 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1302682.js @@ -0,0 +1,6 @@ +for (var i = 0; i < 30000; i++) { + var a = inIon() ? 7 : 300; + var buf = new Uint8ClampedArray(a); + (function() {}) * this; + try {} catch (e) {} +} diff --git a/js/src/jit-test/tests/basic/bug1310418.js b/js/src/jit-test/tests/basic/bug1310418.js new file mode 100644 index 000000000..abbfa6127 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1310418.js @@ -0,0 +1,9 @@ +(function(stdlib, n, heap) { + "use asm"; + var Uint8ArrayView = new stdlib.Uint8Array(heap); + function f(d1) { + d1 = +d1; + var d2 = .0; + Uint8ArrayView[d1 < d2] = 0 + 3 + (d2 > -0); + } +})(this, 0>>0, new Int32Array(0)) diff --git a/js/src/jit-test/tests/basic/bug1317402.js b/js/src/jit-test/tests/basic/bug1317402.js new file mode 100644 index 000000000..127af2e62 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1317402.js @@ -0,0 +1,8 @@ +gczeal(9); +let o = {p1:0, p2:0, set p3({}) {}, p4:1, p5:1, + p6:1, p7:1, p8:1, p9:1, p10:1, p11:1}; +for (let p in o) + x = o[p]; +delete o.p3; +for (let i = 0; i < 100; i++) + x = -o; diff --git a/js/src/jit-test/tests/basic/bug1344265.js b/js/src/jit-test/tests/basic/bug1344265.js new file mode 100644 index 000000000..a4e5b1dc4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1344265.js @@ -0,0 +1,5 @@ +// |jit-test| allow-unhandlable-oom; allow-oom +if (!('oomAfterAllocations' in this)) + quit(); +oomAfterAllocations(1); +newExternalString("a"); diff --git a/js/src/jit-test/tests/basic/bug464403.js b/js/src/jit-test/tests/basic/bug464403.js new file mode 100644 index 000000000..a0d4b4ca9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug464403.js @@ -0,0 +1,7 @@ +function bug464403() { + print(8); + var u = [print, print, function(){}] + for each (x in u) for (u.e in [1,1,1,1]); + return "ok"; +} +assertEq(bug464403(), "ok"); diff --git a/js/src/jit-test/tests/basic/bug465902.js b/js/src/jit-test/tests/basic/bug465902.js new file mode 100644 index 000000000..c490d4593 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug465902.js @@ -0,0 +1,13 @@ +var a = []; +for (let j = 0; j < 6; ++j) { + e = 3; + for each (let c in [10, 20, 30]) { + a.push(e); + e = c; + } +} +for (let j = 0; j < 6; ++j) { + assertEq(a[j*3 + 0], 3); + assertEq(a[j*3 + 1], 10); + assertEq(a[j*3 + 2], 20); +} diff --git a/js/src/jit-test/tests/basic/bug504587-1.js b/js/src/jit-test/tests/basic/bug504587-1.js new file mode 100644 index 000000000..a489f99ca --- /dev/null +++ b/js/src/jit-test/tests/basic/bug504587-1.js @@ -0,0 +1,13 @@ +// This test case failed a WIP patch. See https://bugzilla.mozilla.org/show_bug.cgi?id=504587#c68 + +function B() {} +B.prototype.x = 1; +var d = new B; + +var names = ['z', 'z', 'z', 'z', 'z', 'z', 'z', 'x']; +for (var i = 0; i < names.length; i++) { + x = d.x; // guard on shapeOf(d) + d[names[i]] = 2; // unpredicted shape change + y = d.x; // guard here is elided +} +assertEq(y, 2); // Assertion failed: got 1, expected 2 diff --git a/js/src/jit-test/tests/basic/bug507180.js b/js/src/jit-test/tests/basic/bug507180.js new file mode 100644 index 000000000..9d8fb1958 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug507180.js @@ -0,0 +1,69 @@ +var o = { + valueOf : function() { + return { + toString : function() { return "fail" } + } + }, + toString : function() { return "good" } +}; + +var p = { + valueOf : function() { + return { + toString : function() { return "0" } + } + }, + toString : function() { return "7" } +}; + +var q = { + toString : function() { + return { + valueOf : function() { return "0" } + } + }, + valueOf : function() { return "7" } +}; + +function assert(b, s) { + if (b) + return; + assertEq("imacro produces incorrect result for " + s, "fail"); +} + +function run() { + for (var i = 0; i < 5; ++i) { + // equality / inequality + assert(!(o == "fail"), "obj == any"); + assert(!("fail" == o), "any == obj"); + assert(!(o != "good"), "obj != any"); + assert(!("good" != o), "any != obj"); + + // binary + assert(!((p | 3) != 7), "obj | any"); + assert(!((3 | p) != 7), "any | obj"); + assert(!((p | p) != 7), "obj | obj"); + assert(!((p & 3) != 3), "obj & any"); + assert(!((3 & p) != 3), "any & obj"); + assert(!((p & p) != 7), "obj & obj"); + assert(!((p * 3) != 21), "obj * any"); + assert(!((3 * p) != 21), "any * obj"); + assert(!((p * p) != 49), "obj * obj"); + + // addition + assert(!(o + "" != "good"), "obj + any"); + assert(!("" + o != "good"), "any + obj"); + assert(!(o + o != "goodgood"), "any + any"); + + // sign + assert(!(-p != -7), "-obj"); + assert(!(+p != 7), "+obj"); + + // String + assert(!(String(q) != "7"), "String(obj)"); + assert(!(new String(q) != "7"), "new String(obj)"); + } + return true; +} + +run(); diff --git a/js/src/jit-test/tests/basic/bug509639.js b/js/src/jit-test/tests/basic/bug509639.js new file mode 100644 index 000000000..7c5b0c791 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug509639.js @@ -0,0 +1,3 @@ +// don't crash + +(function(){ var c; eval("for(c in [1,2,3,4]) {}") })(); diff --git a/js/src/jit-test/tests/basic/bug509982.js b/js/src/jit-test/tests/basic/bug509982.js new file mode 100644 index 000000000..36b9364a1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug509982.js @@ -0,0 +1,15 @@ +function g() { + const e = 0; + return function () { + switch (7) { + case e: + } + }; +} + +for (var i = 0; i < 2; i++) { + let f = g; + f(); +} + +// Just test that we don't crash. diff --git a/js/src/jit-test/tests/basic/bug510434.js b/js/src/jit-test/tests/basic/bug510434.js new file mode 100644 index 000000000..253352e29 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug510434.js @@ -0,0 +1,2 @@ +var f = function(){ var arguments = 3; for (var j=0;j<4;++j) print(arguments); }; +f(); diff --git a/js/src/jit-test/tests/basic/bug510437-2.js b/js/src/jit-test/tests/basic/bug510437-2.js new file mode 100644 index 000000000..1fca2067f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug510437-2.js @@ -0,0 +1,13 @@ +function f() { + eval("g=function() { \ + for (let x=0; x < 2; ++x) { \ + d=x \ + } \ + }") + g(); + eval("var d") + g(); +} + +f(); +assertEq(d, 1); diff --git a/js/src/jit-test/tests/basic/bug510437.js b/js/src/jit-test/tests/basic/bug510437.js new file mode 100644 index 000000000..2418b9b11 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug510437.js @@ -0,0 +1,13 @@ +// Don't crash or assert. + +var d; +this.watch("d", eval); +(function () { + (eval("\ + (function () {\ + for (let x = 0; x < 2; ++x) {\ + d = x\ + }\ + })\ +"))() +})() diff --git a/js/src/jit-test/tests/basic/bug511214.js b/js/src/jit-test/tests/basic/bug511214.js new file mode 100644 index 000000000..611d86e45 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug511214.js @@ -0,0 +1,18 @@ +eval(1); // avoid global shape change when we call eval below +function q() { + var x = 1; + function f() { + function g() { + var t=0; + for (var i=0; i<3; i++) + x = i; + }; + g(); + eval("var x = 3"); + g(); + assertEq(x, 2); + } + f(); + assertEq(x, 2); +} +q(); diff --git a/js/src/jit-test/tests/basic/bug511241.js b/js/src/jit-test/tests/basic/bug511241.js new file mode 100644 index 000000000..fe28febb9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug511241.js @@ -0,0 +1,15 @@ +var d = 1; +function heavy(x) { + eval(x); + return function lite() { + var s = 0; + for (var i = 0; i < 9; i++) + s += d; + return s; + }; +} + +var f1 = heavy("1"); +var f2 = heavy("var d = 100;"); +assertEq(f1(), 9); +assertEq(f2(), 900); diff --git a/js/src/jit-test/tests/basic/bug513038.js b/js/src/jit-test/tests/basic/bug513038.js new file mode 100644 index 000000000..21cf1c326 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug513038.js @@ -0,0 +1,16 @@ +// Just don't assert or crash. + +function f() { + let c + try { + (eval("\ + (function(){\ + with(\ + this.__defineGetter__(\"x\", function(){for(a = 0; a < 3; a++){c=a}})\ + ){}\ + })\ + "))() + } catch(e) {} +} +f() +print(x) diff --git a/js/src/jit-test/tests/basic/bug513898-regexp.js b/js/src/jit-test/tests/basic/bug513898-regexp.js new file mode 100644 index 000000000..48a5d9fd4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug513898-regexp.js @@ -0,0 +1,51 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: haytjes <hv1989@gmail.com> + */ + +/* Check the undefined pattern is equivalent to empty string. */ + +assertEq(RegExp(undefined).source, '(?:)'); +assertEq(RegExp(undefined).global, false); +assertEq("test".replace(RegExp(undefined), "*"), '*test'); +assertEq(new RegExp(undefined).source, '(?:)'); +assertEq(new RegExp(undefined).global, false); +assertEq('test'.replace(new RegExp(undefined), "*"), '*test'); + +/* Global flags. */ + +assertEq(new RegExp(undefined, "g").global, true); +assertEq("test".replace(new RegExp(undefined, "g"), "*"), "*t*e*s*t*"); +assertEq(RegExp(undefined, "g").global, true); +assertEq("test".replace(RegExp(undefined, "g"), "*"), "*t*e*s*t*"); + +/* Undefined flags. */ + +var re = new RegExp(undefined, undefined); +assertEq(re.multiline, false); +assertEq(re.global, false); +assertEq(re.ignoreCase, false); + +var re = new RegExp("test", undefined); +assertEq(re.multiline, false); +assertEq(re.global, false); +assertEq(re.ignoreCase, false); + +/* Flags argument that requires toString. */ + +function Flags() {}; + +Flags.prototype.toString = function dogToString() { return ""; } + +var re = new RegExp(undefined, new Flags()); +assertEq(re.multiline, false); +assertEq(re.global, false); +assertEq(re.ignoreCase, false); + +Flags.prototype.toString = function dogToString() { return "gim"; } + +var re = new RegExp(undefined, new Flags()); +assertEq(re.multiline, true); +assertEq(re.global, true); +assertEq(re.ignoreCase, true); diff --git a/js/src/jit-test/tests/basic/bug516009.js b/js/src/jit-test/tests/basic/bug516009.js new file mode 100644 index 000000000..db3a35942 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug516009.js @@ -0,0 +1,20 @@ +var gFutureCalls = []; + +function add_future_call(index, func) +{ + if (!(index in gFutureCalls)) { + gFutureCalls[index] = []; + } +} + +function check_reset_test(time) +{ +} + +check_reset_test(0); + +for (var i = 1; i <= 8; ++i) { + (function(j) { + add_future_call(j, function() { check_reset_test(j); }); + })(i); +} diff --git a/js/src/jit-test/tests/basic/bug517721.js b/js/src/jit-test/tests/basic/bug517721.js new file mode 100644 index 000000000..77a2c944e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug517721.js @@ -0,0 +1,8 @@ +try { + for (var j = 0; j < 2; ++j) { + if (j == 1) { + ++(null[2]); + } + } +} catch(e) { +} diff --git a/js/src/jit-test/tests/basic/bug519129.js b/js/src/jit-test/tests/basic/bug519129.js new file mode 100644 index 000000000..89ba1f9da --- /dev/null +++ b/js/src/jit-test/tests/basic/bug519129.js @@ -0,0 +1 @@ +(function(){eval("for(l in[0,0,0]){}",0)})() diff --git a/js/src/jit-test/tests/basic/bug520498.js b/js/src/jit-test/tests/basic/bug520498.js new file mode 100644 index 000000000..55324f6f3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug520498.js @@ -0,0 +1,9 @@ +var Q = 0; +try { + (function f(i) { Q = i; if (i == 100000) return; f(i+1); })(1) +} catch (e) { +} + +if (Q == 100000) + assertEq(Q, "fail"); + diff --git a/js/src/jit-test/tests/basic/bug522136.js b/js/src/jit-test/tests/basic/bug522136.js new file mode 100644 index 000000000..751396dbd --- /dev/null +++ b/js/src/jit-test/tests/basic/bug522136.js @@ -0,0 +1,10 @@ +var Q = 0; +var thrown = false; +try { + (function f(i) { Q = i; if (i == 200000) return; f(i+1); })(1) +} catch (e) { + thrown = true; +} + +// Exact behavior of recursion check depends on which JIT we use. +assertEq(thrown && Q > 3500, true); diff --git a/js/src/jit-test/tests/basic/bug522817.js b/js/src/jit-test/tests/basic/bug522817.js new file mode 100644 index 000000000..25b5b99f3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug522817.js @@ -0,0 +1,17 @@ +// This test should not assert in a debug build. + +var q1={}; +var $native = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + arguments[i].extend = function (props) {}; + } +}; +$native(q1, Array, String, Number); +Array.extend({}); +Number.extend({}); +Object.Native = function () { + for (var i = 0; i < arguments.length; i++) { + arguments[i].eeeeee = (function(){}); + } +}; +new Object.Native(q1, Array, String, Number); diff --git a/js/src/jit-test/tests/basic/bug524826-2.js b/js/src/jit-test/tests/basic/bug524826-2.js new file mode 100644 index 000000000..38e3c2728 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug524826-2.js @@ -0,0 +1,11 @@ +var x = 42; + +function f() { + var a = [{}, {}, {}, {}, {}]; + for (var i = 0; i < 5; i++) + a[i].m = function () {return x}; + for (i = 0; i < 4; i++) + if (a[i].m == a[i+1].m) + throw "FAIL!"; +} +f(); diff --git a/js/src/jit-test/tests/basic/bug524826.js b/js/src/jit-test/tests/basic/bug524826.js new file mode 100644 index 000000000..225c3591f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug524826.js @@ -0,0 +1,10 @@ +var x = 42; +function f() { + var a = [new Date, new Date, new Date, new Date, new Date]; + for (var i = 0; i < 5; i++) + a[i].m = function () {return x}; + for (i = 0; i < 4; i++) + if (a[i].m == a[i+1].m) + throw "FAIL!"; +} +f(); diff --git a/js/src/jit-test/tests/basic/bug525028.js b/js/src/jit-test/tests/basic/bug525028.js new file mode 100644 index 000000000..90200b6bc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug525028.js @@ -0,0 +1,16 @@ +// don't crash + +function f() { + var _L1 = arguments; + for (var i = 0; i < _L1.length; i++) { + if (typeof _L1[i] == "string") + _L1[i] = new Object(); + } + print(arguments[2]); +} + +f(1, 2, "3", 4, 5); +f(1, 2, "3", 4, 5); +f(1, 2, "3", 4, 5); +f(1, 2, "3", 4, 5); + diff --git a/js/src/jit-test/tests/basic/bug527288.js b/js/src/jit-test/tests/basic/bug527288.js new file mode 100644 index 000000000..de227a7c9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug527288.js @@ -0,0 +1,7 @@ +(function () { + for (a = 0; a < 3; a++) { + for each(b in [0, -0]) {} + } +})() + +// Just test we don't assert. diff --git a/js/src/jit-test/tests/basic/bug528116.js b/js/src/jit-test/tests/basic/bug528116.js new file mode 100644 index 000000000..8a47778f7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug528116.js @@ -0,0 +1,8 @@ +(function() { + var x = [null, [], null]; + for (var i = 0; i != x.length; ++i) { + eval("for (var b = 0; b < 2; ++b);", x[i]); + } +})(); + +// Just test that we don't crash. diff --git a/js/src/jit-test/tests/basic/bug528644.js b/js/src/jit-test/tests/basic/bug528644.js new file mode 100644 index 000000000..260e0d995 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug528644.js @@ -0,0 +1,16 @@ +// Don't crash + +function g(foo) { + for (a in foo) { + } +} + +var makegen = eval("\n\ + (function(b) {\n\ + var h = \n\ + eval(\"new function() { yield print(b) }\" ); \n\ + return h\n\ + })\n\ +"); + +g(makegen()); diff --git a/js/src/jit-test/tests/basic/bug532568-2.js b/js/src/jit-test/tests/basic/bug532568-2.js new file mode 100644 index 000000000..47f705810 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug532568-2.js @@ -0,0 +1,20 @@ +var before = ''; +var after = ''; + +function g(b) { + for (var i = 0; i < 10; ++i) { + } +} + +function f(xa_arg) { + var xa = xa_arg; + for (var i = 0; i < 5; ++i) { + var j = i + xa[i]; + before += j + ','; + g(); + after += j + ','; + } +} + +f([ 0, 1, 2, 3, 4 ]); +assertEq(before, after); diff --git a/js/src/jit-test/tests/basic/bug532568.js b/js/src/jit-test/tests/basic/bug532568.js new file mode 100644 index 000000000..b1cf86c15 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug532568.js @@ -0,0 +1,19 @@ +var actual = ""; + +function f() { + var x = 10; + + var g = function(p) { + for (var i = 0; i < 10; ++i) + x = p + i; + } + + for (var i = 0; i < 10; ++i) { + g(100 * i + x); + actual += x + ','; + } +} + +f(); + +assertEq(actual, "19,128,337,646,1055,1564,2173,2882,3691,4600,"); diff --git a/js/src/jit-test/tests/basic/bug532823.js b/js/src/jit-test/tests/basic/bug532823.js new file mode 100644 index 000000000..c2b2dc6d5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug532823.js @@ -0,0 +1,23 @@ +function loop(f) { + var p; + for (var i = 0; i < 10; ++i) { + p = f(); + } + return p; +} + +function f(j, k) { + var g = function() { return k; } + + var ans = ''; + + for (k = 0; k < 5; ++k) { + ans += loop(g); + } + return ans; +} + +var t0 = new Date; +var actual = f(1); + +assertEq(actual, '01234'); diff --git a/js/src/jit-test/tests/basic/bug535474.js b/js/src/jit-test/tests/basic/bug535474.js new file mode 100644 index 000000000..6e34298a2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug535474.js @@ -0,0 +1,27 @@ +function f() { + var _76 = {}; + for (var i = 0; i < arguments.length; i++) { + var typ = arguments[i]; + _76[typ] = typ; + } + return function () { + for (var i = 0; i < arguments.length; i++) { + if (!(typeof (arguments[i]) in _76)) { + return false; + } + } + return true; + } +} + +g = f("number", "boolean", "object"); + +g("a", "b", "c", "d", "e", "f", 2); +g(2, "a", "b", "c", "d", "e", "f", 2); + +/* + * Don't assert -- + * Assertion failed: frame entry -4 wasn't freed + * : _activation.entry[i] == 0 (../nanojit/Assembler.cpp:786) + */ + diff --git a/js/src/jit-test/tests/basic/bug535760.js b/js/src/jit-test/tests/basic/bug535760.js new file mode 100644 index 000000000..dd00b9615 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug535760.js @@ -0,0 +1,13 @@ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ +function foundit(items, n) { + for (var i = 0; i < 10; i++) + arguments[2](items, this); +} + +function dostuff() { + print(this); +} +foundit('crab', 'crab', dostuff); + +/* Don't crash or assert */ + diff --git a/js/src/jit-test/tests/basic/bug535930.js b/js/src/jit-test/tests/basic/bug535930.js new file mode 100644 index 000000000..ac985d18e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug535930.js @@ -0,0 +1,19 @@ +(function () { + p = function () { + Set() + }; + var Set = function () {}; + for (var x = 0; x < 5; x++) { + Set = function (z) { + return function () { + [z] + } + } (x) + } +})() + +/* + * bug 535930, mistakenly generated code to GetUpvar and crashed inside the call. + * so don't crash. + */ + diff --git a/js/src/jit-test/tests/basic/bug536445.js b/js/src/jit-test/tests/basic/bug536445.js new file mode 100644 index 000000000..16808bb30 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug536445.js @@ -0,0 +1,10 @@ +var x; +var str = "a"; +assertEq(str.charCodeAt(Infinity) | 0, 0); +for (var i = 0; i < 10; ++i) + x = str.charCodeAt(Infinity) | 0; +assertEq(x, 0); +for (var i = 0; i < 10; ++i) + x = str.charCodeAt(Infinity); +assertEq(x | 0, 0); + diff --git a/js/src/jit-test/tests/basic/bug536748.js b/js/src/jit-test/tests/basic/bug536748.js new file mode 100644 index 000000000..42d820089 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug536748.js @@ -0,0 +1,8 @@ +// Do not assert. + +var s = "a"; +var b = 32767; + +for (var i = 0; i < 10; ++i) { + b = b & s.charCodeAt(); +} diff --git a/js/src/jit-test/tests/basic/bug539379.js b/js/src/jit-test/tests/basic/bug539379.js new file mode 100644 index 000000000..dab57f507 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug539379.js @@ -0,0 +1,9 @@ +try { + // On X64 this was crashing rather than causing a "too much recursion" exception. + x = /x/; + (function f() { + x.r = x; + return f() + })(); +} catch (e) {} + diff --git a/js/src/jit-test/tests/basic/bug539553-2.js b/js/src/jit-test/tests/basic/bug539553-2.js new file mode 100644 index 000000000..b8fbeb1ea --- /dev/null +++ b/js/src/jit-test/tests/basic/bug539553-2.js @@ -0,0 +1,7 @@ +function f() { + var x = arguments; + arguments.length = {}; + for (var i = 0; i < 9; i++) + x.length.toSource(); +} +f(); diff --git a/js/src/jit-test/tests/basic/bug539553-3.js b/js/src/jit-test/tests/basic/bug539553-3.js new file mode 100644 index 000000000..44b7d41f5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug539553-3.js @@ -0,0 +1,11 @@ +function g(x) { + assertEq(arguments.length, 1); + assertEq(x.length, 4); +} + +function f() { + for (var i = 0; i < 9; i++) + g(arguments); +} + +f(1, 2, 3, 4); diff --git a/js/src/jit-test/tests/basic/bug539553.js b/js/src/jit-test/tests/basic/bug539553.js new file mode 100644 index 000000000..41f12c794 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug539553.js @@ -0,0 +1,11 @@ +function g(x) { + assertEq(x.length, 1); +} + +function f() { + arguments.length = 1; + for (var i = 0; i < 9; i++) + g(arguments); +} + +f(); diff --git a/js/src/jit-test/tests/basic/bug541191-1.js b/js/src/jit-test/tests/basic/bug541191-1.js new file mode 100644 index 000000000..74ccae829 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug541191-1.js @@ -0,0 +1,23 @@ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ + +function g(a, b, c, d) { + return "" + a + b + c + d; +} + +var x = 1; +function f(a, b, c) { + arguments[1] = 2; + arguments[2] = 3; + arguments[3] = 4; + if (!x) + arguments.length = 4; + var k; + for (var i = 0; i < 10; i++) + k = g.apply(this, arguments); + return k; +} + +assertEq(f(1), "1undefinedundefinedundefined"); +x = 0; +assertEq(f(1), "1234"); + diff --git a/js/src/jit-test/tests/basic/bug541191-2.js b/js/src/jit-test/tests/basic/bug541191-2.js new file mode 100644 index 000000000..d270b7de1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug541191-2.js @@ -0,0 +1,23 @@ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ + +function g(a, b, c, d) { + return "" + a + b + c + d; +} + +var x = 1; +function f(a, b, c) { + arguments[1] = 2; + arguments[2] = 3; + arguments[3] = 4; + if (x) + arguments.length = 4; + var k; + for (var i = 0; i < 9; i++) + k = g.apply(this, arguments); + return k; +} + +assertEq(f(1), "1234"); +x = 0; +assertEq(f(1), "1undefinedundefinedundefined"); + diff --git a/js/src/jit-test/tests/basic/bug541191-3.js b/js/src/jit-test/tests/basic/bug541191-3.js new file mode 100644 index 000000000..f447d49d1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug541191-3.js @@ -0,0 +1,23 @@ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ + +function g(a, b, c, d) { + return "" + a + b + c + d; +} + +var x = 1; +function f(a, b, c) { + arguments[1] = 2; + arguments[2] = 3; + arguments[3] = 4; + if (x) + arguments.length = 1; + var k; + for (var i = 0; i < 10; i++) + k = g.apply(this, arguments); + return k; +} + +assertEq(f(1), "1undefinedundefinedundefined"); +x = 0; +assertEq(f(1), "1undefinedundefinedundefined"); + diff --git a/js/src/jit-test/tests/basic/bug541191-4.js b/js/src/jit-test/tests/basic/bug541191-4.js new file mode 100644 index 000000000..5d15bedb5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug541191-4.js @@ -0,0 +1,27 @@ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ + +function g(a, b, c, d) { + return "" + a + b + c + d; +} + +var x = 1; +function f(a, b, c) { + arguments[1] = 2; + arguments[2] = 3; + arguments[3] = 4; + if (x) { + arguments.length = 1; + delete arguments.length; + arguments.__defineGetter__('length', function () { return eval('1'); }); + } + var k; + for (var i = 0; i < 10; i++) + k = g.apply(this, arguments); + return k; +} + +assertEq(f(1), "1undefinedundefinedundefined"); +x = 0; +assertEq(f(1), "1undefinedundefinedundefined"); + + diff --git a/js/src/jit-test/tests/basic/bug541191-5.js b/js/src/jit-test/tests/basic/bug541191-5.js new file mode 100644 index 000000000..f87217b2c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug541191-5.js @@ -0,0 +1,24 @@ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ + +function g(a, b, c, d) { + return "" + a + b + c + d; +} + +var x = 1; +function f(a, b, c) { + arguments[1] = 2; + arguments[2] = 3; + arguments[3] = 4; + if (x) + arguments.length = 1; + var k; + for (var i = 0; i < 10; i++) + k = g.apply(this, arguments); + return k; +} + +assertEq(f(1), "1undefinedundefinedundefined"); +x = 0; +assertEq(f(1), "1undefinedundefinedundefined"); + + diff --git a/js/src/jit-test/tests/basic/bug547911-1.js b/js/src/jit-test/tests/basic/bug547911-1.js new file mode 100644 index 000000000..e15c3356c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug547911-1.js @@ -0,0 +1,7 @@ +a = b = c = d = 0; +this.__defineGetter__("e", function () { throw StopIteration; }) +try { + for each(f in this) {} +} catch (exc) { + assertEq(exc, StopIteration); +} diff --git a/js/src/jit-test/tests/basic/bug547911-2.js b/js/src/jit-test/tests/basic/bug547911-2.js new file mode 100644 index 000000000..d29d3303d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug547911-2.js @@ -0,0 +1,7 @@ +var obj = {a: 0, b: 0, c: 0, d: 0, get e() { throw StopIteration; }}; +try { + for each (x in obj) {} + FAIL; +} catch (exc) { + assertEq(exc, StopIteration); +} diff --git a/js/src/jit-test/tests/basic/bug551705.js b/js/src/jit-test/tests/basic/bug551705.js new file mode 100644 index 000000000..a97d98868 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug551705.js @@ -0,0 +1,39 @@ +(Function("\ + for each(let x in [\n\ + true,\n\ + (1),\n\ + (1),\n\ + (1),\n\ + (1),\n\ + true,\n\ + true,\n\ + true,\n\ + (1),\n\ + true,\n\ + true,\n\ + (1),\n\ + true,\n\ + true,\n\ + (1),\n\ + (1),\n\ + true,\n\ + true,\n\ + true,\n\ + true\n\ + ]) { \n\ + ((function f(aaaaaa) {\n\ + return aaaaaa.length == 0 ? 0 : aaaaaa[0] + f(aaaaaa.slice(1))\n\ + })([\n\ + x,\n\ + Math.I,\n\ + '',\n\ + null,\n\ + Math.I,\n\ + null,\n\ + new String(),\n\ + new String()\n\ + ]))\n\ +}"))() + +/* Don't assert/crash. */ + diff --git a/js/src/jit-test/tests/basic/bug552196.js b/js/src/jit-test/tests/basic/bug552196.js new file mode 100644 index 000000000..d52623485 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug552196.js @@ -0,0 +1,12 @@ +(Function("\ + for (a = 0; a < 5; a++)\n\ + (function f(b) {\n\ + if (b > 0) {\n\ + f(b - 1)\n\ + }\n\ + })\n\ + (3)\n\ +"))() + +/* Don't assert. */ + diff --git a/js/src/jit-test/tests/basic/bug557841.js b/js/src/jit-test/tests/basic/bug557841.js new file mode 100644 index 000000000..903490e6e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug557841.js @@ -0,0 +1 @@ +eval("for(a = 0; a < 4; a++) x = 1;", []); diff --git a/js/src/jit-test/tests/basic/bug558530.js b/js/src/jit-test/tests/basic/bug558530.js new file mode 100644 index 000000000..31fa78ead --- /dev/null +++ b/js/src/jit-test/tests/basic/bug558530.js @@ -0,0 +1,14 @@ +// There's no assertEq() here; the test is just that it doesn't crash. +(function () { + new function () {} +}()); +[function () {}] +gc() +for (z = 0; z < 6; ++z) { + x = [] +} +for (w in [0]) { + x._ = w +} +gc() + diff --git a/js/src/jit-test/tests/basic/bug558531.js b/js/src/jit-test/tests/basic/bug558531.js new file mode 100644 index 000000000..ddabce879 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug558531.js @@ -0,0 +1,46 @@ +function f2(c) { + return { + g: c.match(/:/) & c.match(/:/) & c.match(/f/) & c.m & c.a & c.match(/f/) & + c.match(/c/) & c.match(/a/) & (/s/) & c.match(/e/) & c.match(/s/) & + (c.match(/./) & c.i) & (c.match(/\*/)) & (c.match(/n/)), + y: c.a & c.a & c.match(/\)/) & c.match(/\)/) & c.match(/\)/) + & c.match(/\\/), + c: c.match(/f/) + } +} +function f1(c) { + t = f2(c.replace(/s/)) + try { + eval(c) + } catch(e) {} + f4(); + if (c.indexOf("<") == -1 || c.indexOf()) + try {} catch(e) {} + try { + try { + l + } catch(e) {} + if ("unwatch" in this) {} + g + } catch(e) {} + try {} catch(p) {} +} +function f4() { + try {} catch(e) {} { + try { + eval(s + "") + } catch(e) {} + } +} [{}] +s = [{},{}]; +(function(){}()) +s[{},{},{}] = [function(){}] +a = [{},{},{}].concat([{},{}]) +f1("") +f1("") +f1("n") +f1("") +f1("(__proto__=null)") +f1("for(var z=0;z<1;z++){gc()(*::*)}") +f1("gc()") +f1("<") diff --git a/js/src/jit-test/tests/basic/bug558814.js b/js/src/jit-test/tests/basic/bug558814.js new file mode 100644 index 000000000..63a9f877b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug558814.js @@ -0,0 +1,10 @@ +function f() +{ + var a = []; + a.length = 10; + for (var i = 0; i < 100; i++) { + var y = a[a.length]; + } +} +f(); +// No assertEq() call, the test is just that it shouldn't assert or crash. diff --git a/js/src/jit-test/tests/basic/bug559912.js b/js/src/jit-test/tests/basic/bug559912.js new file mode 100644 index 000000000..8f05ff5a3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug559912.js @@ -0,0 +1,12 @@ + +function s(f) { this._m = f; } +function C() { + Object.defineProperty(this, "m", {set: s}); + this.m = function () {}; +} +var last = {}; +for (var i = 0; i < 20; i++) { + var a = new C; + assertEq(a._m === last._m, false); + last = a; +} diff --git a/js/src/jit-test/tests/basic/bug560234.js b/js/src/jit-test/tests/basic/bug560234.js new file mode 100644 index 000000000..dc2956a76 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug560234.js @@ -0,0 +1,10 @@ +function test() { + var a = ['x', '', '', '', '', '', '', 'x']; + var b = ''; + for (var i = 0; i < a.length; i++) { + (function() { + a[i].replace(/x/, function() { return b; }); + }()); + } +} +test(); // should NOT get a ReferenceError for b on trace diff --git a/js/src/jit-test/tests/basic/bug560234b.js b/js/src/jit-test/tests/basic/bug560234b.js new file mode 100644 index 000000000..b130d7500 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug560234b.js @@ -0,0 +1,12 @@ +function f(a) { + function g() { + yield function () a; + } + if (a == 8) + return g(); + a = 3; +} +var x; +for (var i = 0; i < 9; i++) + x = f(i); +x.next()(); // ReferenceError: a is not defined. diff --git a/js/src/jit-test/tests/basic/bug561279.js b/js/src/jit-test/tests/basic/bug561279.js new file mode 100644 index 000000000..2160be51b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug561279.js @@ -0,0 +1,4 @@ +{ + let y; + eval('eval("for (z = 0; z < 6; z++) a = z;")'); +} diff --git a/js/src/jit-test/tests/basic/bug561359-1.js b/js/src/jit-test/tests/basic/bug561359-1.js new file mode 100644 index 000000000..4439174e0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug561359-1.js @@ -0,0 +1,4 @@ +for (let z = 0; z < 2; z++) { + with ({x: function () {}}) + f = x; +} diff --git a/js/src/jit-test/tests/basic/bug561359-2.js b/js/src/jit-test/tests/basic/bug561359-2.js new file mode 100644 index 000000000..017b9bf33 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug561359-2.js @@ -0,0 +1,8 @@ +function f(s) { + var obj = {m: function () { return a; }}; + eval(s); + return obj; +} +var obj = f("var a = 'right';"); +var a = 'wrong'; +assertEq(obj.m(), 'right'); diff --git a/js/src/jit-test/tests/basic/bug563125.js b/js/src/jit-test/tests/basic/bug563125.js new file mode 100644 index 000000000..79e43eae4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug563125.js @@ -0,0 +1,5 @@ +var array = new Array(4294967295); +for (var j = 0; j < 9; ++j) { '' + array.length; } + +// Don't assert. + diff --git a/js/src/jit-test/tests/basic/bug563243.js b/js/src/jit-test/tests/basic/bug563243.js new file mode 100644 index 000000000..64dc830e8 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug563243.js @@ -0,0 +1,7 @@ +// |jit-test| error:SyntaxError + +(function () { + for (a in (function () { + yield Array.reduce() + })()) function () {} +})() diff --git a/js/src/jit-test/tests/basic/bug566136.js b/js/src/jit-test/tests/basic/bug566136.js new file mode 100644 index 000000000..2d5f7ffb0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug566136.js @@ -0,0 +1,11 @@ +load(libdir + "immutable-prototype.js"); + +Object.prototype.length = 0; +if (globalPrototypeChainIsMutable()) + this.__proto__ = []; + +function f() { + eval('Math'); + length = 2; +} +f(); diff --git a/js/src/jit-test/tests/basic/bug566637.js b/js/src/jit-test/tests/basic/bug566637.js new file mode 100644 index 000000000..6623dbabf --- /dev/null +++ b/js/src/jit-test/tests/basic/bug566637.js @@ -0,0 +1,5 @@ +for (var j = 0; j < 9; j++) {
+ var a = j;
+ var b = this.a;
+}
+assertEq(b, 8);
diff --git a/js/src/jit-test/tests/basic/bug568276.js b/js/src/jit-test/tests/basic/bug568276.js new file mode 100644 index 000000000..4f3f6e7e5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug568276.js @@ -0,0 +1 @@ +function outer(a) { var b, c, d, e, f, g, h, i; function a() {} } diff --git a/js/src/jit-test/tests/basic/bug569651.js b/js/src/jit-test/tests/basic/bug569651.js new file mode 100644 index 000000000..58f9c1362 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug569651.js @@ -0,0 +1,3 @@ +// don't crash or assert
+
++Function("switch(\"\"){case 1:case 8:}");
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug569849.js b/js/src/jit-test/tests/basic/bug569849.js new file mode 100644 index 000000000..18598ba3b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug569849.js @@ -0,0 +1,9 @@ +function g() { + function f(a) { + delete a.x; + } + for each(let w in [Infinity, String()]) { + let i = f(w); + } +} +g(); diff --git a/js/src/jit-test/tests/basic/bug570385-1.js b/js/src/jit-test/tests/basic/bug570385-1.js new file mode 100644 index 000000000..ec9007c01 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug570385-1.js @@ -0,0 +1,9 @@ +var actual = '';
+
+var a = [0, 1];
+for (var i in a) {
+ appendToActual(i);
+ a.pop();
+}
+
+assertEq(actual, "0,");
diff --git a/js/src/jit-test/tests/basic/bug570385-2.js b/js/src/jit-test/tests/basic/bug570385-2.js new file mode 100644 index 000000000..dc189dd5c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug570385-2.js @@ -0,0 +1,9 @@ +var actual = '';
+
+var a = [0, 1];
+for (var i in a) {
+ appendToActual(i);
+ delete a[1];
+}
+
+assertEq(actual, "0,");
diff --git a/js/src/jit-test/tests/basic/bug570385-3.js b/js/src/jit-test/tests/basic/bug570385-3.js new file mode 100644 index 000000000..f65fabccd --- /dev/null +++ b/js/src/jit-test/tests/basic/bug570385-3.js @@ -0,0 +1,11 @@ +var actual = '';
+
+var a = [0, 1];
+a.x = 10;
+delete a.x;
+for (var i in a) {
+ appendToActual(i);
+ a.pop();
+}
+
+assertEq(actual, "0,");
diff --git a/js/src/jit-test/tests/basic/bug570663-1.js b/js/src/jit-test/tests/basic/bug570663-1.js new file mode 100644 index 000000000..08f14ecf7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug570663-1.js @@ -0,0 +1,4 @@ +// don't crash +for (var a = 0; a < 4; a++) { + switch (NaN) {} +} diff --git a/js/src/jit-test/tests/basic/bug570663-2.js b/js/src/jit-test/tests/basic/bug570663-2.js new file mode 100644 index 000000000..bc4b08869 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug570663-2.js @@ -0,0 +1,12 @@ +function f() { + var x; + for (var a = 0; a < 4; a++) { + switch (NaN) { + default: + x = a; + } + } + assertEq(x, 3); +} + +f(); diff --git a/js/src/jit-test/tests/basic/bug572229.js b/js/src/jit-test/tests/basic/bug572229.js new file mode 100644 index 000000000..c45cea0b6 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug572229.js @@ -0,0 +1,12 @@ +// Don't crash
+
+function f(o, s) {
+ var k = s.substr(0, 1);
+ var c;
+ for (var i = 0; i < 10; ++i) {
+ c = k in o;
+ }
+ return c;
+}
+
+assertEq(f({ a: 66 }, 'abc'), true);
diff --git a/js/src/jit-test/tests/basic/bug572232.js b/js/src/jit-test/tests/basic/bug572232.js new file mode 100644 index 000000000..f651ca986 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug572232.js @@ -0,0 +1,4 @@ +// |jit-test| error: TypeError +gczeal(11); +var o = { valueOf: function() { new Object(); gc(); return 17; } }; +(new String.prototype.substring(o)).toString; diff --git a/js/src/jit-test/tests/basic/bug576823-regexp.js b/js/src/jit-test/tests/basic/bug576823-regexp.js new file mode 100644 index 000000000..175ecb2bc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug576823-regexp.js @@ -0,0 +1,3 @@ +// Sticky should work across disjunctions. + +assertEq(/A|B/y.exec("CB"), null); diff --git a/js/src/jit-test/tests/basic/bug576837-regexp.js b/js/src/jit-test/tests/basic/bug576837-regexp.js new file mode 100644 index 000000000..956b3eae9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug576837-regexp.js @@ -0,0 +1,41 @@ +/* + * Check that builtin character classes within ranges produce syntax + * errors. + * + * Note: /\b/ is the backspace escape, which is a single pattern character, + * though it looks deceptively like a character class. + */ + +function isRegExpSyntaxError(pattern) { + try { + var re = new RegExp(pattern); + } catch (e) { + if (e instanceof SyntaxError) + return true; + } + return false; +} + +//assertEq(isRegExpSyntaxError('[C-\\s]'), false); +//assertEq(isRegExpSyntaxError('[C-\\d]'), false); +//assertEq(isRegExpSyntaxError('[C-\\W]'), false); +assertEq(isRegExpSyntaxError('[C-]'), false); +assertEq(isRegExpSyntaxError('[-C]'), false); +assertEq(isRegExpSyntaxError('[C-C]'), false); +assertEq(isRegExpSyntaxError('[C-C]'), false); +assertEq(isRegExpSyntaxError('[\\b-\\b]'), false); +assertEq(isRegExpSyntaxError('[\\B-\\B]'), false); +assertEq(isRegExpSyntaxError('[\\b-\\B]'), false); +assertEq(isRegExpSyntaxError('[\\B-\\b]'), true); +//assertEq(isRegExpSyntaxError('[\\b-\\w]'), false); +//assertEq(isRegExpSyntaxError('[\\B-\\w]'), false); + +/* Extension. */ +assertEq(isRegExpSyntaxError('[\\s-\\s]'), false); +assertEq(isRegExpSyntaxError('[\\W-\\s]'), false); +assertEq(isRegExpSyntaxError('[\\s-\\W]'), false); +assertEq(isRegExpSyntaxError('[\\W-C]'), false); +assertEq(isRegExpSyntaxError('[\\d-C]'), false); +assertEq(isRegExpSyntaxError('[\\s-C]'), false); +assertEq(isRegExpSyntaxError('[\\w-\\b]'), false); +assertEq(isRegExpSyntaxError('[\\w-\\B]'), false); diff --git a/js/src/jit-test/tests/basic/bug576891.js b/js/src/jit-test/tests/basic/bug576891.js new file mode 100644 index 000000000..5abae94ce --- /dev/null +++ b/js/src/jit-test/tests/basic/bug576891.js @@ -0,0 +1 @@ +/[&@!)OZ%3,#]/; diff --git a/js/src/jit-test/tests/basic/bug578041.js b/js/src/jit-test/tests/basic/bug578041.js new file mode 100644 index 000000000..59a1f2910 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug578041.js @@ -0,0 +1,3 @@ +this.__defineGetter__('x', () => new Float32Array()); +with(this) + x; diff --git a/js/src/jit-test/tests/basic/bug579740.js b/js/src/jit-test/tests/basic/bug579740.js new file mode 100644 index 000000000..26fa1ce22 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug579740.js @@ -0,0 +1,7 @@ +try { + for (a = 0; a < 4; a++) { + new Math.round(0).t + } +} +catch (e) {} +/* Don't assert. */ diff --git a/js/src/jit-test/tests/basic/bug582161.js b/js/src/jit-test/tests/basic/bug582161.js new file mode 100644 index 000000000..09f9a8919 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug582161.js @@ -0,0 +1,3 @@ +// |jit-test| error: RangeError; +var vs = [1, 1, 1, 1, 3.5, 1]; +for (var i = 0, sz = vs.length; i < sz; i++) new Array(vs[i]); diff --git a/js/src/jit-test/tests/basic/bug582479.js b/js/src/jit-test/tests/basic/bug582479.js new file mode 100644 index 000000000..246c66780 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug582479.js @@ -0,0 +1,4 @@ +for (b = 0; b < 2; b++) { + / /.exec(function(){}) +} + diff --git a/js/src/jit-test/tests/basic/bug583757.js b/js/src/jit-test/tests/basic/bug583757.js new file mode 100644 index 000000000..3a7f910ba --- /dev/null +++ b/js/src/jit-test/tests/basic/bug583757.js @@ -0,0 +1,24 @@ +var arr = []; + +function f() {} + +function g(n, h) { + var a = f; + if (n <= 0) + return f; + + var t = g(n - 1, h); + var r = function(x) { + if (x) + return a; + return a(h(function() { return t(); })); + }; + arr.push(r); + return r; +} + +g(80, f); +g(80, f); +g(80, f); +for (var i = 0; i < arr.length; i++) + assertEq(arr[i](1), f); diff --git a/js/src/jit-test/tests/basic/bug584499-1.js b/js/src/jit-test/tests/basic/bug584499-1.js new file mode 100644 index 000000000..bc9895379 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug584499-1.js @@ -0,0 +1,6 @@ +// |jit-test| error: TypeError +var s = "12345"; +for(var i=0; i<7; i++) { + print(s[i].length); +} + diff --git a/js/src/jit-test/tests/basic/bug584499-2.js b/js/src/jit-test/tests/basic/bug584499-2.js new file mode 100644 index 000000000..bb31a731e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug584499-2.js @@ -0,0 +1,12 @@ +function f(x) { + var s = "a"; + var last = ""; + for (var i = 0; i < 10; i++) { + last = s[x]; + } + return last; +} + +f(0); + +assertEq(f(1), undefined); diff --git a/js/src/jit-test/tests/basic/bug584565.js b/js/src/jit-test/tests/basic/bug584565.js new file mode 100644 index 000000000..ad7d4b475 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug584565.js @@ -0,0 +1,10 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Luke Wagner <lw@mozilla.com> + +var x, f; +for (var i = 0; i < 100; i++) { + f = function() {}; + f.foo; + x = f.length; +} diff --git a/js/src/jit-test/tests/basic/bug584603.js b/js/src/jit-test/tests/basic/bug584603.js new file mode 100644 index 000000000..4e7607939 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug584603.js @@ -0,0 +1,13 @@ +var f = 99;
+
+function g(a) {
+ if (a) {
+ var e = 55;
+ function f() {
+ print("f");
+ }
+ assertEq(f == 99, false);
+ }
+}
+
+g(true);
diff --git a/js/src/jit-test/tests/basic/bug585542.js b/js/src/jit-test/tests/basic/bug585542.js new file mode 100644 index 000000000..9ea3de6be --- /dev/null +++ b/js/src/jit-test/tests/basic/bug585542.js @@ -0,0 +1,11 @@ +function f() { return 2; } +function g(o) { + with (o) { + var f = function() { return 4; } + } + return f(); +} + +assertEq(g({}), 4); + + diff --git a/js/src/jit-test/tests/basic/bug586499-regexp.js b/js/src/jit-test/tests/basic/bug586499-regexp.js new file mode 100644 index 000000000..3f7f451cf --- /dev/null +++ b/js/src/jit-test/tests/basic/bug586499-regexp.js @@ -0,0 +1,2 @@ +// Don't crash. +var re = /^(?:\s*.){0,16}/; diff --git a/js/src/jit-test/tests/basic/bug586917.js b/js/src/jit-test/tests/basic/bug586917.js new file mode 100644 index 000000000..7b8b5072a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug586917.js @@ -0,0 +1,1834 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ + +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +/* The tracer should properly parse JSOP_TABLESWITCHX instructions. */ +var x = 1; +for (i = 0; i < 8; i++) { + switch (x) { + case 2: + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + try {} catch (e) {} + } +} diff --git a/js/src/jit-test/tests/basic/bug587346-regexp-01.js b/js/src/jit-test/tests/basic/bug587346-regexp-01.js new file mode 100644 index 000000000..cf341a4f6 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug587346-regexp-01.js @@ -0,0 +1 @@ +var re = /(?:){1,60}/ diff --git a/js/src/jit-test/tests/basic/bug587366.js b/js/src/jit-test/tests/basic/bug587366.js new file mode 100644 index 000000000..9934d987a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug587366.js @@ -0,0 +1,3 @@ +// Test flat string replacement, per ECMAScriptv5 15.5.4.11. +assertEq("1+2".replace("1+2", "$&+3"), "1+2+3"); +assertEq(")".replace(")","*$&*"), "*)*"); diff --git a/js/src/jit-test/tests/basic/bug589318.js b/js/src/jit-test/tests/basic/bug589318.js new file mode 100644 index 000000000..98902b0b9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug589318.js @@ -0,0 +1,10 @@ +// Use arguments in an eval. +code = " \ +function f(a) { var x = a; } \ +for (var i = 0; i < 10; i++) { f(5); } \ +"; + +eval(code); + + +// Test it doesn't assert. diff --git a/js/src/jit-test/tests/basic/bug590006.js b/js/src/jit-test/tests/basic/bug590006.js new file mode 100644 index 000000000..233aeb292 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug590006.js @@ -0,0 +1,12 @@ +function f() { + var ret; + for (var i = 0; i < 10; ++i) { + { + let local = 3; + ret = function() { print(local++); } + } + } + return ret; +} +f()(); // test.js:5: ReferenceError: local is not defined + diff --git a/js/src/jit-test/tests/basic/bug590036.js b/js/src/jit-test/tests/basic/bug590036.js new file mode 100644 index 000000000..25add41ff --- /dev/null +++ b/js/src/jit-test/tests/basic/bug590036.js @@ -0,0 +1,13 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +load(libdir + 'eqArrayHelper.js'); + +assertEqArray(eval('[]'), []); +assertEqArray(eval('[,]'), [,]); +assertEqArray(eval('[,,]'), [,,]); +assertEqArray(eval('[1, 1, ]'), [1,1, ]); +assertEqArray(eval('[1, 1, true]'), [1, 1, true]); +assertEqArray(eval('[1, false, true]'), [1, false, true]); diff --git a/js/src/jit-test/tests/basic/bug592927.js b/js/src/jit-test/tests/basic/bug592927.js new file mode 100644 index 000000000..69f0bd237 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug592927.js @@ -0,0 +1,27 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +function f(x, y) { + x(f); + assertEq(y, "hello"); +} + +function g(x) { + assertEq(x.arguments[1], "hello"); + x.arguments[1] = "bye"; + assertEq(x.arguments[1], "hello"); +} + +function f2(x, y) { + arguments; + x(f2); + assertEq(y, "hello"); +} + +function g2(x) { + assertEq(x.arguments[1], "hello"); + x.arguments[1] = "bye"; + assertEq(x.arguments[1], "hello"); +} + +f(g, "hello"); +f2(g2, "hello"); + diff --git a/js/src/jit-test/tests/basic/bug593611.js b/js/src/jit-test/tests/basic/bug593611.js new file mode 100644 index 000000000..6106c0f5c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug593611.js @@ -0,0 +1,11 @@ +var global = this; +(function() { + global.__defineGetter__("x", /x/.constructor) +})() +for (var a = 0; a < 4; ++a) { + if (a % 4 == 1) { + gc() + } else { + print(x); + } +} diff --git a/js/src/jit-test/tests/basic/bug593663-regexp.js b/js/src/jit-test/tests/basic/bug593663-regexp.js new file mode 100644 index 000000000..10133c300 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug593663-regexp.js @@ -0,0 +1,109 @@ +/* + * Ensure that flat matches with metachars in them don't have their metachars + * interpreted as special. + */ + +function isPatternSyntaxError(pattern) { + try { + new RegExp(pattern); + return false; + } catch (e if e instanceof SyntaxError) { + return true; + } +} + +// Bug example. +assertEq("1+2".replace("1+2", "$&+3"), "1+2+3"); +assertEq("1112".replace("1+2", ""), "1112"); + +// ^ +assertEq("leading text^my hat".replace("^my hat", ""), "leading text"); +assertEq("my hat".replace("^my hat", ""), "my hat"); + +// $ +assertEq("leading text$my money".replace("leading text$", ""), "my money"); +assertEq("leading text".replace("leading text$", ""), "leading text"); + +// \ +var BSL = '\\'; +assertEq(("dir C:" + BSL + "Windoze").replace("C:" + BSL, ""), + "dir Windoze"); +assertEq(isPatternSyntaxError("C:" + BSL), true); + +// . +assertEq("This is a sentence. It has words.".replace(".", "!"), + "This is a sentence! It has words."); +assertEq("This is an unterminated sentence".replace(".", ""), + "This is an unterminated sentence"); + +// * +assertEq("Video killed the radio *".replace(" *", ""), "Video killed the radio"); +assertEq("aaa".replace("a*", ""), "aaa"); + +// + +assertEq("On the + side".replace(" +", ""), "On the side"); +assertEq("1111111111111".replace("1+", ""), "1111111111111"); + +// \+ +assertEq(("Inverse cone head: " + BSL + "++/").replace(BSL + "+", ""), + "Inverse cone head: +/"); +assertEq((BSL + BSL + BSL).replace(BSL + "+", ""), + BSL + BSL + BSL); + +// \\+ +assertEq((BSL + BSL + "+").replace(BSL + BSL + "+", ""), ""); +assertEq((BSL + BSL + BSL).replace(BSL + BSL + "+", ""), (BSL + BSL + BSL)); + +// \\\ +assertEq((BSL + BSL + BSL + BSL).replace(BSL + BSL + BSL, ""), BSL); +assertEq(isPatternSyntaxError(BSL + BSL + BSL), true); + +// \\\\ +assertEq((BSL + BSL + BSL + BSL).replace(BSL + BSL + BSL + BSL, "", "i"), ""); +assertEq((BSL + BSL).replace(BSL + BSL + BSL + BSL, ""), BSL + BSL); + + +// ? +assertEq("Pressing question?".replace("?", "."), "Pressing question."); +assertEq("a".replace("a?", ""), "a"); + +// ( +assertEq("(a".replace("(", ""), "a"); + +// ) +assertEq("a)".replace(")", ""), "a"); + +// ( and ) +assertEq("(foo)".replace("(foo)", ""), ""); +assertEq("a".replace("(a)", ""), "a"); + +// [ +assertEq("[a".replace("[", ""), "a"); + +// ] +assertEq("a]".replace("]", ""), "a"); + +// [ and ] +assertEq("a".replace("[a-z]", ""), "a"); +assertEq("You would write your regexp as [a-z]".replace("[a-z]", ""), + "You would write your regexp as "); + +// { +assertEq("Numbers may be specified in the interval {1,100}".replace("{1,", ""), + "Numbers may be specified in the interval 100}"); + +// } +assertEq("Numbers may be specified in the interval {1,100}".replace(",100}", ""), + "Numbers may be specified in the interval {1"); + +// { and } +assertEq("Numbers may be specified in the interval {1,100}".replace(" {1,100}", ""), + "Numbers may be specified in the interval"); +assertEq("aaa".replace("a{1,10}", ""), "aaa"); + +// | +assertEq("Mr. Gorbachev|Tear down this wall!".replace("|Tear down this wall!", ""), + "Mr. Gorbachev"); +assertEq("foobar".replace("foo|bar", ""), "foobar"); + +print("PASS"); diff --git a/js/src/jit-test/tests/basic/bug594108.js b/js/src/jit-test/tests/basic/bug594108.js new file mode 100644 index 000000000..3a250db9f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug594108.js @@ -0,0 +1,8 @@ +var res; +for (var i = 0; i < 10; i++) { + var re = /a(b)c/; + var b = (re.exec(""), v = re.exec("abc")) !== null; + assertEq(v[0], "abc"); + assertEq(v[1], "b"); +} + diff --git a/js/src/jit-test/tests/basic/bug594205.js b/js/src/jit-test/tests/basic/bug594205.js new file mode 100644 index 000000000..beaeaa164 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug594205.js @@ -0,0 +1,16 @@ +var re = /a(b)c/; + +for (var i = 0; i < 10; i++) { + // These two are of a form where we can convert exec() to test(). + if (!re.exec("abc")) print("huh?"); + re.exec("abc"); +} + +RegExp.prototype.test = 1; + +for (var i = 0; i < 10; i++) { + // These two are the same form, but we've replaced test(), so we must + // not convert. + if (!re.exec("abc")) print("huh?"); // don't crash/assert + re.exec("abc"); // don't crash/assert +} diff --git a/js/src/jit-test/tests/basic/bug595963-1.js b/js/src/jit-test/tests/basic/bug595963-1.js new file mode 100644 index 000000000..2cccfac40 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug595963-1.js @@ -0,0 +1,19 @@ +function remove(k, L) { + for (var i in k) { + if (i == L) + k.splice(L, 1); + } +} +function f(k) { + var L = 0; + for (var i in k) { + if (L == 1) + remove(k, L); + L++; + assertEq(k[i], 3); + } + assertEq(L, 6); +} + +var a = [3, 3, 3, 3, 3, 3, 3]; +f(a); diff --git a/js/src/jit-test/tests/basic/bug595963-2.js b/js/src/jit-test/tests/basic/bug595963-2.js new file mode 100644 index 000000000..651a38064 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug595963-2.js @@ -0,0 +1,19 @@ +function remove(k, L) { + for (var i in k) { + if (i == L) + k.splice(L, 3); + } +} +function f(k) { + var L = 0; + for (var i in k) { + if (L == 1) + remove(k, L); + L++; + assertEq(k[i], 3); + } + assertEq(L, 4); +} + +var a = [3, 3, 3, 3, 3, 3, 3]; +f(a); diff --git a/js/src/jit-test/tests/basic/bug596351-1.js b/js/src/jit-test/tests/basic/bug596351-1.js new file mode 100644 index 000000000..f4d764a6d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug596351-1.js @@ -0,0 +1,5 @@ +// |jit-test| error: TypeError +"use strict" +var g = newGlobal(); +g.eval("foo = {}; Object.defineProperty(foo, 'a', {value: 2, writable: false});"); +g.foo.a = 3; diff --git a/js/src/jit-test/tests/basic/bug596351-2.js b/js/src/jit-test/tests/basic/bug596351-2.js new file mode 100644 index 000000000..2a014ad15 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug596351-2.js @@ -0,0 +1,7 @@ +// |jit-test| error: TypeError + +"use strict" +var g = newGlobal(); + +g.eval("bar = {}; Object.freeze(bar);"); +g.bar.a = 4; diff --git a/js/src/jit-test/tests/basic/bug599854.js b/js/src/jit-test/tests/basic/bug599854.js new file mode 100644 index 000000000..19e3f7c72 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug599854.js @@ -0,0 +1,4 @@ +load(libdir + 'eqArrayHelper.js'); +assertEqArray(/(?:(?:(")(c)")?)*/.exec('"c"'), [ '"c"', '"', "c" ]); +assertEqArray(/(?:(?:a*?(")(c)")?)*/.exec('"c"'), [ '"c"', '"', "c" ]); +assertEqArray(/<script\s*(?![^>]*type=['"]?(?:dojo\/|text\/html\b))(?:[^>]*?(?:src=(['"]?)([^>]*?)\1[^>]*)?)*>([\s\S]*?)<\/script>/gi.exec('<script type="text/javascript" src="..."></script>'), ['<script type="text/javascript" src="..."></script>', '"', "...", ""]); diff --git a/js/src/jit-test/tests/basic/bug601046.js b/js/src/jit-test/tests/basic/bug601046.js new file mode 100644 index 000000000..45f3bf82e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug601046.js @@ -0,0 +1,8 @@ +// don't assert
+var f = function(){};
+for (var p in f);
+Object.defineProperty(f, "j", ({configurable: true, value: "a"}));
+Object.defineProperty(f, "k", ({configurable: true, value: "b"}));
+Object.defineProperty(f, "j", ({configurable: true, get: function() {}}));
+delete f.k;
+Object.defineProperty(f, "j", ({configurable: false}));
diff --git a/js/src/jit-test/tests/basic/bug601398.js b/js/src/jit-test/tests/basic/bug601398.js new file mode 100644 index 000000000..f3eaddccb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug601398.js @@ -0,0 +1,8 @@ +(function () { + try {} finally { + { + let z; + return; + } + } +})() diff --git a/js/src/jit-test/tests/basic/bug601401.js b/js/src/jit-test/tests/basic/bug601401.js new file mode 100644 index 000000000..5c4a4f36c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug601401.js @@ -0,0 +1,6 @@ +{ + let e; + with({}) try {} catch (x) {} finally { + { let y; } + } +} diff --git a/js/src/jit-test/tests/basic/bug601428.js b/js/src/jit-test/tests/basic/bug601428.js new file mode 100644 index 000000000..b9419f822 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug601428.js @@ -0,0 +1,2 @@ +// |jit-test| error: SyntaxError; +let({}=[c for(x in[])]){let diff --git a/js/src/jit-test/tests/basic/bug605015.js b/js/src/jit-test/tests/basic/bug605015.js new file mode 100644 index 000000000..a35f7b6c7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug605015.js @@ -0,0 +1,9 @@ +// |jit-test| error: TypeError
+// don't assert
+
+print(this.watch("x",
+function() {
+ Object.defineProperty(this, "x", ({
+ get: (Int8Array)
+ }))
+}))(x = /x/)
diff --git a/js/src/jit-test/tests/basic/bug605754-regexp.js b/js/src/jit-test/tests/basic/bug605754-regexp.js new file mode 100644 index 000000000..9acd31437 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug605754-regexp.js @@ -0,0 +1,2 @@ +var result = "foobarbaz".replace(/foo(bar)?bar/, "$1"); +assertEq(result, "baz"); diff --git a/js/src/jit-test/tests/basic/bug606083.js b/js/src/jit-test/tests/basic/bug606083.js new file mode 100644 index 000000000..d8049b94f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug606083.js @@ -0,0 +1,32 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +function f(L) { + do { + L: for (var i = 0; i < L; i++) { + break L; + } + } while (0); +} +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); +f(1); diff --git a/js/src/jit-test/tests/basic/bug606882-1.js b/js/src/jit-test/tests/basic/bug606882-1.js new file mode 100644 index 000000000..3d8bdf4a2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug606882-1.js @@ -0,0 +1,3 @@ +// don't crash + +"ABC".match("A+(?:X?(?:|(?:))(?:(?:B)?C+w?w?)?)*"); diff --git a/js/src/jit-test/tests/basic/bug606882-2.js b/js/src/jit-test/tests/basic/bug606882-2.js new file mode 100644 index 000000000..b7542170f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug606882-2.js @@ -0,0 +1,16 @@ +// don't crash +var book = 'Ps'; +var pattern = "(?:" ++ "(?:" ++ "(?:" ++ "(?:-|)" ++ "\\s?" ++ ")" ++ "|" ++ ")" ++ " ?" ++ "\\d+" ++ "\\w?" ++ ")*"; +var re = new RegExp(pattern); +'8:5-8'.match(re); diff --git a/js/src/jit-test/tests/basic/bug608313.js b/js/src/jit-test/tests/basic/bug608313.js new file mode 100644 index 000000000..1bd20df4a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug608313.js @@ -0,0 +1,11 @@ + +function testInt8Array(L) { + var f = new Int8Array(8); + f[0] = 0; // Don't assert. +} + +for (var i = 0; i < 10; i++) { + testInt8Array(0); +} + + diff --git a/js/src/jit-test/tests/basic/bug608980.js b/js/src/jit-test/tests/basic/bug608980.js new file mode 100644 index 000000000..53ad2cbad --- /dev/null +++ b/js/src/jit-test/tests/basic/bug608980.js @@ -0,0 +1,11 @@ + +/* Don't trip bogus assert. */ + +function foo() +{ + var x; + while (x = 0) { + x = 1; + } +} +foo(); diff --git a/js/src/jit-test/tests/basic/bug609502-1.js b/js/src/jit-test/tests/basic/bug609502-1.js new file mode 100644 index 000000000..a62316d60 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug609502-1.js @@ -0,0 +1,9 @@ +for(var i = 0; i < 9; i++) { + x = ''.charCodeAt(NaN); +} + +for(var i = 0; i < 9; i++) { + x = ''.charAt(NaN); +} + +// Don't assert diff --git a/js/src/jit-test/tests/basic/bug609502-2.js b/js/src/jit-test/tests/basic/bug609502-2.js new file mode 100644 index 000000000..4c1469dce --- /dev/null +++ b/js/src/jit-test/tests/basic/bug609502-2.js @@ -0,0 +1,5 @@ +for (var i = 0; i < 9; i++) { + Math.abs(-2147483648) +} + +// Don't assert diff --git a/js/src/jit-test/tests/basic/bug609502-3.js b/js/src/jit-test/tests/basic/bug609502-3.js new file mode 100644 index 000000000..7c9436dff --- /dev/null +++ b/js/src/jit-test/tests/basic/bug609502-3.js @@ -0,0 +1,11 @@ +{ + function a() {} +} +Math.floor(Math.d) + function c() {} + c() + for each(let b in [0, 0, 0, 0, 0, 0, 0, -2147483648]) { + print(Math.abs(b)) + } + +// Don't assert diff --git a/js/src/jit-test/tests/basic/bug610592.js b/js/src/jit-test/tests/basic/bug610592.js new file mode 100644 index 000000000..da825d284 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug610592.js @@ -0,0 +1,29 @@ + +/* Don't confuse JIT code by making slow arrays that use inline slots inconsistently. */ + +function foo(a) +{ + assertEq(a.x, 5); +} + +function bar() +{ + for (var i = 0; i < 50; i++) { + var a = []; + a[i] = 0; + delete a[i]; + a.x = 5; + foo(a); + } + + var b = [1,,2,,3,,4,,5]; + assertEq(b.toString(), "1,,2,,3,,4,,5"); + b.x = 0; + assertEq(b.toString(), "1,,2,,3,,4,,5"); + delete b.x; + delete b[8]; + delete b[6]; + delete b[4]; + assertEq(b.toString(), "1,,2,,,,,,"); +} +bar(); diff --git a/js/src/jit-test/tests/basic/bug613122.js b/js/src/jit-test/tests/basic/bug613122.js new file mode 100644 index 000000000..64c6b0688 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug613122.js @@ -0,0 +1,4 @@ +var a = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; +a.push(1); +a.splice(0, a.length); +a.d = ""; diff --git a/js/src/jit-test/tests/basic/bug613151.js b/js/src/jit-test/tests/basic/bug613151.js new file mode 100644 index 000000000..6a3a24ae3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug613151.js @@ -0,0 +1,18 @@ +// Iterating over a property with an Array id. +function n() {} +function g() {} +eval("\ + function a() {}\ + function b() {\ + for (w in this) {}\ + Object.defineProperty(\ + this, \ + new Array, \ + ({enumerable: true})\ + )\ + }\ + for (z in [0, 0, 0]) b()\ +") + +// Test it doesn't assert. + diff --git a/js/src/jit-test/tests/basic/bug613399.js b/js/src/jit-test/tests/basic/bug613399.js new file mode 100644 index 000000000..b2431c9f9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug613399.js @@ -0,0 +1,3 @@ +// don't assert
+/((?=()+))?/.exec("");
+
diff --git a/js/src/jit-test/tests/basic/bug614688.js b/js/src/jit-test/tests/basic/bug614688.js new file mode 100644 index 000000000..c075cadab --- /dev/null +++ b/js/src/jit-test/tests/basic/bug614688.js @@ -0,0 +1,7 @@ +function Foo() { + u = 0; +} + +var x = new Foo(); +assertEq(Object.getPrototypeOf(x) === Foo.prototype, true); +assertEq(Object.getPrototypeOf(x) === Object.prototype, false); diff --git a/js/src/jit-test/tests/basic/bug614915.js b/js/src/jit-test/tests/basic/bug614915.js new file mode 100644 index 000000000..b4ab9491a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug614915.js @@ -0,0 +1,2 @@ +var s = [undefined, undefined].sort();
+assertEq(s.length, 2);
diff --git a/js/src/jit-test/tests/basic/bug616009.js b/js/src/jit-test/tests/basic/bug616009.js new file mode 100644 index 000000000..ecfbc6506 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug616009.js @@ -0,0 +1,35 @@ +function run() { + var obj = { + toJSON: function() { + return { + key: { + toJSON: function() { + for (i=0; i!=1<<10; ++i) + new Object(); + var big = unescape("%udddd"); + while (big.length != 0x100000) + big += big; + for (i=0; i!=32; ++i) + new String(big+i); + return "whatever"; + } + }, + __iterator__: function() { + return { + next: function() { + return "key"; + } + } + } + } + } + }; + + var repl = function(id, val) { + this[0]++; + return val; + }; + + JSON.stringify(obj, repl); +} +run(); diff --git a/js/src/jit-test/tests/basic/bug616170.js b/js/src/jit-test/tests/basic/bug616170.js new file mode 100644 index 000000000..efcd468ba --- /dev/null +++ b/js/src/jit-test/tests/basic/bug616170.js @@ -0,0 +1,17 @@ +/* Don't trip bogus assert. */ + +function e() +{ + try + { + var t = undefined; + } + catch (e) + { + var t = null; + } + while (t && (t.tagName.toUpperCase() != "BODY")) + continue; +} +for (var i = 0; i < 20; i++) + e(); diff --git a/js/src/jit-test/tests/basic/bug616762.js b/js/src/jit-test/tests/basic/bug616762.js new file mode 100644 index 000000000..02f5c953c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug616762.js @@ -0,0 +1,26 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +document = { + ready: function (x) { + this.exec = x; + } +}; + +var $ = function (x) { + return document; +}; + +(function ($) { + eval("(function(){\n" + + " var Private={};\n" + + " $(document).ready(function(){\n" + + " init()\n" + + " });\n" + + " function init(){\n" + + " $(Private)\n" + + " };\n" + + "})();"); +})($); +document.exec(); + +// Don't crash or assert. + diff --git a/js/src/jit-test/tests/basic/bug617139.js b/js/src/jit-test/tests/basic/bug617139.js new file mode 100644 index 000000000..d53456e65 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug617139.js @@ -0,0 +1,9 @@ +// |jit-test| error: InternalError +// don't assert + +gczeal(2) +function x() { + [null].some(x) +} +x(); + diff --git a/js/src/jit-test/tests/basic/bug617171.js b/js/src/jit-test/tests/basic/bug617171.js new file mode 100644 index 000000000..c4305f957 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug617171.js @@ -0,0 +1,4 @@ +var a = 6;
+Object.defineProperty(this, "a", {writable: false});
+a = 7;
+assertEq(a, 6);
diff --git a/js/src/jit-test/tests/basic/bug617745.js b/js/src/jit-test/tests/basic/bug617745.js new file mode 100644 index 000000000..f7f60e20e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug617745.js @@ -0,0 +1,4 @@ + +var array1 = ['0']; +var array2 = (new Array(1)).splice(0,0, array1); +assertEq("" + array2, ""); diff --git a/js/src/jit-test/tests/basic/bug618350.js b/js/src/jit-test/tests/basic/bug618350.js new file mode 100644 index 000000000..61e72d0a0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug618350.js @@ -0,0 +1,24 @@ + +var global = 0; + +Object.defineProperty(Object.prototype, 0, {set: function() { global++; }}); + +for (var x = 0; x < 20; ++x) + [1,2]; +assertEq(global, 0); + +Object.defineProperty(Object.prototype, 1, {set: function() { global++; }}); + +for (var x = 0; x < 20; ++x) + [1,2]; +assertEq(global, 0); + +Object.defineProperty(Object.prototype, "b", {set: function() { global++; }}); + +for (var x = 0; x < 20; ++x) { + var s = { a:0, b:1, 0: 2, 1: 3 }; +} +assertEq(global, 0); + +assertEq([42][0], 42); +assertEq([42].length, 1); diff --git a/js/src/jit-test/tests/basic/bug618577.js b/js/src/jit-test/tests/basic/bug618577.js new file mode 100644 index 000000000..a41f820cb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug618577.js @@ -0,0 +1,5 @@ +var x = new Uint32Array(); +for (var i = 0; i < 100; i++) + x[77] = x[77]; + +// Don't assert. diff --git a/js/src/jit-test/tests/basic/bug618853.js b/js/src/jit-test/tests/basic/bug618853.js new file mode 100644 index 000000000..9c80b7fee --- /dev/null +++ b/js/src/jit-test/tests/basic/bug618853.js @@ -0,0 +1,12 @@ + +try { new isNaN; } catch (e) {} +new Array; +new Boolean; +new Date; +new Number; +new Object; +new String; +try { new [].push(4); } catch (e) {} +try { new [1,2,3].pop(); } catch (e) {} +try { new "a,b,c".split(","); } catch (e) {} +try { new Array.concat(3); } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug619004.js b/js/src/jit-test/tests/basic/bug619004.js new file mode 100644 index 000000000..90d3bca99 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug619004.js @@ -0,0 +1,3 @@ +// don't crash +gczeal(2); +evalcx('lazy'); diff --git a/js/src/jit-test/tests/basic/bug619338.js b/js/src/jit-test/tests/basic/bug619338.js new file mode 100644 index 000000000..2548c0c71 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug619338.js @@ -0,0 +1 @@ +try { new Function.prototype } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug620532.js b/js/src/jit-test/tests/basic/bug620532.js new file mode 100644 index 000000000..4a2f6f664 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug620532.js @@ -0,0 +1,15 @@ +for (var i = 0; i < 20; i++) { + m = Math.min(0xffffffff, 0); +} +assertEq(m == 0, true); + +var buffer = new ArrayBuffer(4); +var int32View = new Int32Array(buffer); +var uint32View = new Uint32Array(buffer); +int32View[0] = -1; +var m; +for (var i = 0; i < 20; i++) { + m = Math.min(uint32View[0], 0); // uint32View[0] == 0xffffffff +} +assertEq(m == 0, true); + diff --git a/js/src/jit-test/tests/basic/bug620838.js b/js/src/jit-test/tests/basic/bug620838.js new file mode 100644 index 000000000..c82933ae8 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug620838.js @@ -0,0 +1,22 @@ +function g() { + return "global"; +} + +function q(fun) { + return fun(); +} + +function f(x) { + if (x) { + function g() { + return "local"; + } + var ans = q(function() { + return g(); + }); + } + g = null; + return ans; +} + +assertEq(f(true), "local"); diff --git a/js/src/jit-test/tests/basic/bug621022-1.js b/js/src/jit-test/tests/basic/bug621022-1.js new file mode 100644 index 000000000..aab5bf90f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug621022-1.js @@ -0,0 +1,14 @@ +function f(x) { + delete arguments[0]; + undefined != arguments[0]; + undefined == arguments[0]; + undefined != arguments[0]; + undefined === arguments[0]; +} + +for(var i=0; i<20; i++) { + f(1); +} + +// Don't assert. + diff --git a/js/src/jit-test/tests/basic/bug621022-2.js b/js/src/jit-test/tests/basic/bug621022-2.js new file mode 100644 index 000000000..0f3549c02 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug621022-2.js @@ -0,0 +1,13 @@ +function f(j) { + var a = [[1],[1],[1],[1],[1],[1],[1],[1],[1],arguments]; + var b; + for (var i = 0; i < a.length; i++) { + delete a[i][0]; + b = arguments[0]; + } + assertEq(b === undefined, true); +} + +f(1); + + diff --git a/js/src/jit-test/tests/basic/bug621487.js b/js/src/jit-test/tests/basic/bug621487.js new file mode 100644 index 000000000..ebe92e3d5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug621487.js @@ -0,0 +1,4 @@ + +(function() { while (0) { var a, a = b; } })(); + +(function(b) { do { var a, a = b; } while (0); assertEq(a, 10); })(10); diff --git a/js/src/jit-test/tests/basic/bug623859.js b/js/src/jit-test/tests/basic/bug623859.js new file mode 100644 index 000000000..06f04537c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug623859.js @@ -0,0 +1,10 @@ +// |jit-test| allow-oom +var size = 1000000; +var a = []; +for (var i = 0; i < size; ++i) { + a[i] = null; +} +gcparam("maxBytes", gcparam("gcBytes") + 4*1024); +for (var i = 0; i < size; ++i) { + a[i] = []; +} diff --git a/js/src/jit-test/tests/basic/bug623863.js b/js/src/jit-test/tests/basic/bug623863.js new file mode 100644 index 000000000..d9ba4f79e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug623863.js @@ -0,0 +1,5 @@ +// Contributor: Christian Holler <decoder@own-hero.net> +if (typeof gczeal === 'function') gczeal(2); +Function.prototype.prototype = function() { return 42; }; +try { foo(Function); } catch (e) { } +Function.prototype.prototype = function() { return 42; }; diff --git a/js/src/jit-test/tests/basic/bug624041-1.js b/js/src/jit-test/tests/basic/bug624041-1.js new file mode 100644 index 000000000..4eef9e9a9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug624041-1.js @@ -0,0 +1,8 @@ +var count = 0; + +var a = [0, 1]; +for (var i in a) { + assertEq(++count <= 1, true); + a.shift(); +} + diff --git a/js/src/jit-test/tests/basic/bug624041-2.js b/js/src/jit-test/tests/basic/bug624041-2.js new file mode 100644 index 000000000..6eb1b78f9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug624041-2.js @@ -0,0 +1,11 @@ +var s = ''; + +var a = [, 0, 1]; +for (var i in a) { + a.reverse(); + s += i + ','; +} + +// Index of the element with value '0'. +assertEq(s, '1,'); + diff --git a/js/src/jit-test/tests/basic/bug625141-1.js b/js/src/jit-test/tests/basic/bug625141-1.js new file mode 100644 index 000000000..9f79cf7b2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug625141-1.js @@ -0,0 +1,13 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +function f() { + var arr = new Int32Array(10); + x = function () { return arr.length; } + for (var i = 0; i < arr.length; i++) { + arr[i] = i; + } + assertEq(arr[5], 5); +} +f(); diff --git a/js/src/jit-test/tests/basic/bug625141-2.js b/js/src/jit-test/tests/basic/bug625141-2.js new file mode 100644 index 000000000..d97cdf4df --- /dev/null +++ b/js/src/jit-test/tests/basic/bug625141-2.js @@ -0,0 +1,13 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +function f() { + var arr = new Int8Array(10); + x = function () { return arr.length; } + for (var i = 0; i < arr.length; i++) { + arr[i] = i; + } + assertEq(arr[5], 5); +} +f(); diff --git a/js/src/jit-test/tests/basic/bug625399.js b/js/src/jit-test/tests/basic/bug625399.js new file mode 100644 index 000000000..01b616df4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug625399.js @@ -0,0 +1,7 @@ +function a(bb) { + "use strict"; + return; + this.d = function() { bb; }; +} +for (var i = 0; i <= 9; i++) + a(); diff --git a/js/src/jit-test/tests/basic/bug626398.js b/js/src/jit-test/tests/basic/bug626398.js new file mode 100644 index 000000000..f9571e933 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug626398.js @@ -0,0 +1,30 @@ + +function g(n) { + var s; + switch (n) { + case 0: + s = "c"+n; + break; + + default: + s = "d"+n; + break; + } + return s; +} + +// Do it twice with different initial values for 'i' to allow for 8 +// being even or odd. + +var s = ""; +for (let i = 0; i != 30; i+=2) { + s += g(i%4/2); +} +assertEq(s, "c0d1c0d1c0d1c0d1c0d1c0d1c0d1c0"); + +var s = ""; +for (let i = 2; i != 30; i+=2) { + s += g(i%4/2); +} +assertEq(s, "d1c0d1c0d1c0d1c0d1c0d1c0d1c0"); + diff --git a/js/src/jit-test/tests/basic/bug627609.js b/js/src/jit-test/tests/basic/bug627609.js new file mode 100644 index 000000000..c36a99556 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug627609.js @@ -0,0 +1,2 @@ +load(libdir + 'eqArrayHelper.js'); +assertEqArray(/((a|)+b)+/.exec('bb'), [ "bb", "b", "" ]); diff --git a/js/src/jit-test/tests/basic/bug627692-1.js b/js/src/jit-test/tests/basic/bug627692-1.js new file mode 100644 index 000000000..9e41eb4ef --- /dev/null +++ b/js/src/jit-test/tests/basic/bug627692-1.js @@ -0,0 +1,19 @@ +var loop1 = '', loop2 = '', actual = '';
+
+var obj = {};
+for (var i = 0; i < 10; i++) {
+ obj['a' + i] = i;
+ loop1 += i;
+ loop2 += 'a' + i;
+}
+
+Object.defineProperty(obj, 'z', {enumerable: true, get: function () {
+ for (var y in obj)
+ actual += y;
+ }});
+(function() {
+ for each (var e in obj)
+ actual += e;
+ })();
+
+assertEq(actual, loop1 + loop2 + "z" + "undefined");
diff --git a/js/src/jit-test/tests/basic/bug627692-2.js b/js/src/jit-test/tests/basic/bug627692-2.js new file mode 100644 index 000000000..3c603318e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug627692-2.js @@ -0,0 +1,28 @@ +N = 0;
+function n() {}
+s = n;
+function f(foo) {
+ gc();
+ try {
+ (Function(foo))();
+ } catch(r) {}
+ delete this.Math;
+}
+function g() {}
+var c;
+function y() {}
+t = b = eval;
+f("\
+ __defineGetter__(\"\",\
+ function(p){\
+ for(var s in this) {}\
+ }\
+ )[\"\"]\
+");
+f("\
+ do;\
+ while(([\
+ \"\" for each(z in this)\
+ ])&0)\
+");
+f();
diff --git a/js/src/jit-test/tests/basic/bug629858.js b/js/src/jit-test/tests/basic/bug629858.js new file mode 100644 index 000000000..a931e4faf --- /dev/null +++ b/js/src/jit-test/tests/basic/bug629858.js @@ -0,0 +1,9 @@ +// |jit-test| error: strict +options("strict"); +options("warn"); // Exit with error code on lint failures. +eval("\n\ +function f(a) {\n\ + if (a > 3)\n\ + return 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';\n\ +}"); + diff --git a/js/src/jit-test/tests/basic/bug630865-5.js b/js/src/jit-test/tests/basic/bug630865-5.js new file mode 100644 index 000000000..67fdb7e5b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug630865-5.js @@ -0,0 +1,13 @@ +function C(a, b) { + this.a = a; + this.b = b; +} +var f = C.bind(null, 2); +Object.defineProperty(f, "prototype", {get: function () { throw "FAIL"; }}); +var x; +for (var i = 0; i < 10; i++) + x = new f(i); +assertEq(toString.call(x), "[object Object]"); +assertEq(Object.getPrototypeOf(x), C.prototype); +assertEq(x.a, 2); +assertEq(x.b, 9); diff --git a/js/src/jit-test/tests/basic/bug630865-6.js b/js/src/jit-test/tests/basic/bug630865-6.js new file mode 100644 index 000000000..0532101bd --- /dev/null +++ b/js/src/jit-test/tests/basic/bug630865-6.js @@ -0,0 +1,11 @@ +var a = []; +var x, i; +for (i = 0; i < 18; i++) { + a[i] = function (b) { this.b = b; }; + if (i != 17) + x = a[i].prototype; +} +for (i = 0; i < 18; i++) + x = new a[i]; +assertEq(toString.call(x), "[object Object]"); +assertEq(Object.getPrototypeOf(x), a[17].prototype); diff --git a/js/src/jit-test/tests/basic/bug631082.js b/js/src/jit-test/tests/basic/bug631082.js new file mode 100644 index 000000000..61db35a57 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug631082.js @@ -0,0 +1,13 @@ +var t;
+(function () {
+ t = (function() {
+ yield k();
+ })();
+ function h() {
+ }
+ function k() {
+ return function() { h(); };
+ }
+})();
+t.next();
+
diff --git a/js/src/jit-test/tests/basic/bug631219.js b/js/src/jit-test/tests/basic/bug631219.js new file mode 100644 index 000000000..5b33919bd --- /dev/null +++ b/js/src/jit-test/tests/basic/bug631219.js @@ -0,0 +1,10 @@ +// don't assert or crash
+function g(o) {
+ o.__proto__ = arguments;
+ o.length = 123;
+}
+function f() {
+ g(arguments);
+}
+f();
+
diff --git a/js/src/jit-test/tests/basic/bug631305.js b/js/src/jit-test/tests/basic/bug631305.js new file mode 100644 index 000000000..b0cbbbb24 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug631305.js @@ -0,0 +1,9 @@ +var n = 0; +var a = []; +for (var i = 0; i < 20; i++) + a[i] = {}; +a[18].watch("p", function () { n++; }); +delete a[18].p; +for (var i = 0; i < 20; i++) + a[i].p = 0; +assertEq(n, 1); diff --git a/js/src/jit-test/tests/basic/bug631788.js b/js/src/jit-test/tests/basic/bug631788.js new file mode 100644 index 000000000..503d32f04 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug631788.js @@ -0,0 +1 @@ +for (var j = 1; j < 10; ++j) { switch(0/j) { } } // don't assert diff --git a/js/src/jit-test/tests/basic/bug632778-1.js b/js/src/jit-test/tests/basic/bug632778-1.js new file mode 100644 index 000000000..b982727a6 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug632778-1.js @@ -0,0 +1,5 @@ +function f() { + "use strict"; +} +g = new Proxy(f, {}); +Object.defineProperty(g, "arguments", {set: function(){}}); diff --git a/js/src/jit-test/tests/basic/bug632778-2.js b/js/src/jit-test/tests/basic/bug632778-2.js new file mode 100644 index 000000000..b135b560f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug632778-2.js @@ -0,0 +1,2 @@ +obj = new Proxy(Number.bind(), {}); +Object.defineProperty(obj, "caller", {set: function () {}}); diff --git a/js/src/jit-test/tests/basic/bug632901.js b/js/src/jit-test/tests/basic/bug632901.js new file mode 100644 index 000000000..3039318c2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug632901.js @@ -0,0 +1,9 @@ +// don't crash when tracing +function f(o) { + var prop = "arguments"; + f[prop] = f[prop]; +} +for(var i = 0; i < 50; i++) { + f(); +} + diff --git a/js/src/jit-test/tests/basic/bug632964-regexp.js b/js/src/jit-test/tests/basic/bug632964-regexp.js new file mode 100644 index 000000000..75612dbc7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug632964-regexp.js @@ -0,0 +1,14 @@ +var sText = "s"; + +for (var i = 0; i < 250000; ++i) + sText += 'a\n'; + +sText += 'e'; + +var start = new Date(); +var match = sText.match(/s(\s|.)*?e/gi); +//var match = sText.match(/s([\s\S]*?)e/gi); +//var match = sText.match(/s(?:[\s\S]*?)e/gi); +var end = new Date(); + +assertEq(match.length, 1); diff --git a/js/src/jit-test/tests/basic/bug633409-1.js b/js/src/jit-test/tests/basic/bug633409-1.js new file mode 100644 index 000000000..20eaa6cda --- /dev/null +++ b/js/src/jit-test/tests/basic/bug633409-1.js @@ -0,0 +1,13 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: +x = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }; + +for (i in x) + delete x.d; + +x = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }; +y = []; +for (i in x) + y.push(i) + +assertEq(y[3], "d"); + diff --git a/js/src/jit-test/tests/basic/bug633409-2.js b/js/src/jit-test/tests/basic/bug633409-2.js new file mode 100644 index 000000000..d3c498d6d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug633409-2.js @@ -0,0 +1,13 @@ +// vim: set ts=8 sts=4 et sw=4 tw=99: + +var o1 = {p1: 1}; +var o2 = {p1: 1, p2: 2}; + +for(var x in o1) { + for(var y in o2) { + delete o2.p2; + } +} + +/* Don't fail cx->enumerators == obj assert, see bug comment #31 */ + diff --git a/js/src/jit-test/tests/basic/bug633752.js b/js/src/jit-test/tests/basic/bug633752.js new file mode 100644 index 000000000..522f64277 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug633752.js @@ -0,0 +1,11 @@ +function f(o) { + var p = "arguments"; + for(var i=0; i<10; i++) { + f[p]; + } +} +f({}); +f({}); +f({}); +f({}); + diff --git a/js/src/jit-test/tests/basic/bug633828.js b/js/src/jit-test/tests/basic/bug633828.js new file mode 100644 index 000000000..6b71d095b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug633828.js @@ -0,0 +1,6 @@ +// |jit-test| error: SyntaxError; +(function() { + function a() {} + function a() {} +} +for diff --git a/js/src/jit-test/tests/basic/bug634593.js b/js/src/jit-test/tests/basic/bug634593.js new file mode 100644 index 000000000..b4241a8a4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug634593.js @@ -0,0 +1,4 @@ +this.__defineGetter__("x3", Function); +parseInt = x3; +parseInt.prototype = []; +for (var z = 0; z < 10; ++z) { new parseInt() }
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug635417.js b/js/src/jit-test/tests/basic/bug635417.js new file mode 100644 index 000000000..94dd10163 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug635417.js @@ -0,0 +1,2 @@ +assertEq(/^@(A*)x(B)*/.test("@xB"), true); + diff --git a/js/src/jit-test/tests/basic/bug638981.js b/js/src/jit-test/tests/basic/bug638981.js new file mode 100644 index 000000000..944daa76e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug638981.js @@ -0,0 +1,4 @@ +/* Don't crash. */ + +delete Function; +Object.getOwnPropertyNames(this); diff --git a/js/src/jit-test/tests/basic/bug639126.js b/js/src/jit-test/tests/basic/bug639126.js new file mode 100644 index 000000000..7283fe6ca --- /dev/null +++ b/js/src/jit-test/tests/basic/bug639126.js @@ -0,0 +1,4 @@ +Array.__proto__ = Array.__proto__; +gc(); +Array["name" + ""]; +Array(); diff --git a/js/src/jit-test/tests/basic/bug639128.js b/js/src/jit-test/tests/basic/bug639128.js new file mode 100644 index 000000000..fadd559aa --- /dev/null +++ b/js/src/jit-test/tests/basic/bug639128.js @@ -0,0 +1,10 @@ +function f(o) { + Object.seal(o); +} +gc(); +if(2 != 2) { + g = new f(g); +} +with({}) { + f({}); +} diff --git a/js/src/jit-test/tests/basic/bug639311.js b/js/src/jit-test/tests/basic/bug639311.js new file mode 100644 index 000000000..277d0c3d1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug639311.js @@ -0,0 +1,18 @@ +/* Avoid use-after-free while sweeping type objects. */ + +try { + Reflparse("") +} catch(e) {} +Reflect.parse("for(var a;a;j){if(a%2==0){c()}}") +try { + (function() { + for (a = 0;; j) { + gc() + } + })() +} catch(e) { + delete this.Math +} +gc() +Reflect.parse("{ let x; }") +gc() diff --git a/js/src/jit-test/tests/basic/bug639591.js b/js/src/jit-test/tests/basic/bug639591.js new file mode 100644 index 000000000..435cc31fc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug639591.js @@ -0,0 +1,4 @@ +gczeal(2); +var x; +[eval("x")] ? eval("x") : 3; +eval("Object()"); diff --git a/js/src/jit-test/tests/basic/bug639759.js b/js/src/jit-test/tests/basic/bug639759.js new file mode 100644 index 000000000..ede971374 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug639759.js @@ -0,0 +1,9 @@ +gczeal(2); +function f() { + for(var i=0; i<10; i++) { + [1, [1, 2, 3]]; + eval(""); + } +} +eval("Array(f() ? 0 : 1)"); +eval("Array((eval(\"f()\")) ? true : eval(''))"); diff --git a/js/src/jit-test/tests/basic/bug639797.js b/js/src/jit-test/tests/basic/bug639797.js new file mode 100644 index 000000000..f061fac46 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug639797.js @@ -0,0 +1 @@ +Function("with([]){const x=0}")() diff --git a/js/src/jit-test/tests/basic/bug639807.js b/js/src/jit-test/tests/basic/bug639807.js new file mode 100644 index 000000000..42702b46b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug639807.js @@ -0,0 +1,4 @@ + +try { + eval("const[]=*,[x]=r") +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug640078.js b/js/src/jit-test/tests/basic/bug640078.js new file mode 100644 index 000000000..27e547081 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug640078.js @@ -0,0 +1,4 @@ +eval("\ + try{}\ + catch(w if(function(){})){4067286856}\ +") diff --git a/js/src/jit-test/tests/basic/bug640203.js b/js/src/jit-test/tests/basic/bug640203.js new file mode 100644 index 000000000..aa066bfb2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug640203.js @@ -0,0 +1,2 @@ +var x = [,].splice(0); +assertEq(x[0], undefined); diff --git a/js/src/jit-test/tests/basic/bug640993.js b/js/src/jit-test/tests/basic/bug640993.js new file mode 100644 index 000000000..45ce0856a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug640993.js @@ -0,0 +1,7 @@ +function f() { + return f; +} +f.__proto__ = null; +gc(); +f(); +new f(); diff --git a/js/src/jit-test/tests/basic/bug641224.js b/js/src/jit-test/tests/basic/bug641224.js new file mode 100644 index 000000000..9c976f047 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug641224.js @@ -0,0 +1,5 @@ +try { +x = evalcx('lazy'); +x.__iterator__ = Object.isFrozen +for each(x in x) {} +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug641229.js b/js/src/jit-test/tests/basic/bug641229.js new file mode 100644 index 000000000..4ae5427b2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug641229.js @@ -0,0 +1,2 @@ +this.__defineSetter__("x",Math.max) +Function("({x}=[])")() diff --git a/js/src/jit-test/tests/basic/bug641231.js b/js/src/jit-test/tests/basic/bug641231.js new file mode 100644 index 000000000..0e778a024 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug641231.js @@ -0,0 +1 @@ +try { Function("function a(){this(*)}new a")() } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug641235.js b/js/src/jit-test/tests/basic/bug641235.js new file mode 100644 index 000000000..8534b53c0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug641235.js @@ -0,0 +1,21 @@ +try { +function g(code) { + code = code.replace(/\/\*DUPTRY\d+\*\//, function(k) { + var n = parseInt(k.substr(8), 10); + return aa("try{}catch(e){}", n); + }); + var f = new Function(code); + f() +} +function aa(s, n) { + if (n == 1) { + return s; + } + var s2 = s + s; + var r = n % 2; + var d = (n - r) / 2; + var m = aa(s2, d); + return r ? m + s : m; +} +g("switch(x){default:case l:/*DUPTRY5338*/case 0:x}"); +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug641491.js b/js/src/jit-test/tests/basic/bug641491.js new file mode 100644 index 000000000..653e47a6a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug641491.js @@ -0,0 +1,19 @@ +function f1() { +} +function f2() { +} +function f3(o) { + f2 = Date.prototype; +} +var key = Object.getOwnPropertyNames(f1)[30]; +if(key) { + f3 = f1[key]; +} +gc(); +gc(); +try { +for(var i=0; i<10; i++) { + delete f2[1]; + f3(function() {}); +} +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug641525.js b/js/src/jit-test/tests/basic/bug641525.js new file mode 100644 index 000000000..4c7c8b85c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug641525.js @@ -0,0 +1,34 @@ + +var o2 = new Proxy({}, {}); +function f1() {} +function f2() {} +function f4(o) { + var key = Object.getOwnPropertyNames(o)[18]; + o4 = o[key]; + o.prototype = {}; +} +f4(f1); +f4(f1); +f4(f2); +new f2(o2); + +// these will hold only if type inference is enabled. +//assertEq(shapeOf(f1) == shapeOf(f2), false); +//assertEq(shapeOf(f1) == shapeOf(f4), false); + +function factory() { + function foo() {} + foo.x = 0; + return foo; +} + +var fobjs = []; +for (var i = 0; i < 10; i++) { + var of = fobjs[i] = factory(); + if (i > 0) { + assertEq(fobjs[i - 1] === of, false); + assertEq(shapeOf(fobjs[i - 1]), shapeOf(of)); + } +} + +assertEq(shapeOf(fobjs[0]) == shapeOf(f1), false); diff --git a/js/src/jit-test/tests/basic/bug641563.js b/js/src/jit-test/tests/basic/bug641563.js new file mode 100644 index 000000000..e3d60afef --- /dev/null +++ b/js/src/jit-test/tests/basic/bug641563.js @@ -0,0 +1,3 @@ +// |jit-test| error: SyntaxError; +Function("(x)\nfor(var b,x in") + diff --git a/js/src/jit-test/tests/basic/bug641741.js b/js/src/jit-test/tests/basic/bug641741.js new file mode 100644 index 000000000..760f7ec51 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug641741.js @@ -0,0 +1 @@ +try { eval("var[]=(++false[x])()=[],x") } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug642154.js b/js/src/jit-test/tests/basic/bug642154.js new file mode 100644 index 000000000..8518e2f87 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642154.js @@ -0,0 +1,16 @@ +assertEq(Math.pow(1, undefined), NaN); +assertEq(Math.pow(1, null), 1); +assertEq(Math.pow(1, true), 1); +assertEq(Math.pow(1, false), 1); +assertEq(Math.pow(1, 0), 1); +assertEq(Math.pow(1, -0), 1); +assertEq(Math.pow(1, NaN), NaN); +assertEq(Math.pow(1, {}), NaN); +assertEq(Math.pow(1, {valueOf: function() { return undefined; }}), NaN); + +x = 2.2; +assertEq(Math.pow(x - 1.2, undefined), NaN); + +var y; +assertEq(Math.pow(1, y), NaN); + diff --git a/js/src/jit-test/tests/basic/bug642161.js b/js/src/jit-test/tests/basic/bug642161.js new file mode 100644 index 000000000..18679dd9e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642161.js @@ -0,0 +1 @@ +assertEq(JSON.stringify(0 | "prefix" || Boolean), undefined); diff --git a/js/src/jit-test/tests/basic/bug642164.js b/js/src/jit-test/tests/basic/bug642164.js new file mode 100644 index 000000000..6b97e82ea --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642164.js @@ -0,0 +1,14 @@ +function raisesException(exception) { + return function (code) { + eval(code); + }; +}; +function obj() { + var o = { assertEq: true, y: 1 }; + Object.defineProperty(o, 'x', { writable: false }); + return o; +} +function in_strict_with(expr) { + return "with(obj()) { (function () { 'use strict'; " + expr + " })(); }"; +} +try { assertEq(raisesException(TypeError)(in_strict_with('x++;')), true); } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug642206.js b/js/src/jit-test/tests/basic/bug642206.js new file mode 100644 index 000000000..775e4c6e1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642206.js @@ -0,0 +1,30 @@ +Function.prototype.__proto__ = null; + +function testLenientAndStrict(code, lenient_pred, strict_pred) { + return (strict_pred("'use strict'; " + code) && + lenient_pred(code)); +} +function raisesException(exception) { + return function (code) { + try { + eval(code); + } catch (actual) { + } + }; +}; +try { +function arr() { + return Object.defineProperty(Object()* delete Object, 0, {writable: false}); +} +assertEq(testLenientAndStrict('var a = arr(); [a.splice(0, 1), a]', + raisesException(TypeError), + raisesException(TypeError)), + true); +} catch (e) {} +ForIn_2(this); +function ForIn_2(object) { + for ( property in object ) { + with ( object ) { + } + } +} diff --git a/js/src/jit-test/tests/basic/bug642248.js b/js/src/jit-test/tests/basic/bug642248.js new file mode 100644 index 000000000..8c37b7675 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642248.js @@ -0,0 +1,10 @@ +function test(makeNonArray) { + function C() {} + C.prototype = [] + c = new C(); + c.push("foo"); + return c.length +} +assertEq(test(true), 1); +var a = []; +var b = Object.create(a); diff --git a/js/src/jit-test/tests/basic/bug642254.js b/js/src/jit-test/tests/basic/bug642254.js new file mode 100644 index 000000000..a603920fe --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642254.js @@ -0,0 +1,4 @@ +function f(i) { + for (var n = 0; n < 0; n = i) { } +} +actual = f(.5); diff --git a/js/src/jit-test/tests/basic/bug642319.js b/js/src/jit-test/tests/basic/bug642319.js new file mode 100644 index 000000000..6be3a4c59 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642319.js @@ -0,0 +1,10 @@ + +test(); +function test() { + function f() { + function test( ) { summary( summary, test, false ); } + } + f.__proto__ = this; +} +gc(); +test(); diff --git a/js/src/jit-test/tests/basic/bug642326.js b/js/src/jit-test/tests/basic/bug642326.js new file mode 100644 index 000000000..8b91ecacf --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642326.js @@ -0,0 +1,8 @@ +load(libdir + "immutable-prototype.js"); + +if (globalPrototypeChainIsMutable()) + this.__proto__ = null; + +gczeal(2); +gc(); +var box = evalcx('lazy'); diff --git a/js/src/jit-test/tests/basic/bug642422.js b/js/src/jit-test/tests/basic/bug642422.js new file mode 100644 index 000000000..bb9cfea83 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642422.js @@ -0,0 +1,4 @@ +gczeal(2); +var x; +var foo = "for (var z = 0; z < 2; ++z) { new Object(new String(this), x)}"; +eval(foo); diff --git a/js/src/jit-test/tests/basic/bug642569.js b/js/src/jit-test/tests/basic/bug642569.js new file mode 100644 index 000000000..6f84492d8 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642569.js @@ -0,0 +1,13 @@ +function main() { + var v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, + v43, v44, v45, v46, v47; + var v48 = 0, v49 = 0; + if (true) { + var v50 = v48 - 1; + var v51 = v49 + 1; + return v51; + } +} +assertEq(main(), 1); diff --git a/js/src/jit-test/tests/basic/bug642592.js b/js/src/jit-test/tests/basic/bug642592.js new file mode 100644 index 000000000..57e40faca --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642592.js @@ -0,0 +1,2 @@ +var strings = new Array(); +strings[0x7fffffff] = 0; diff --git a/js/src/jit-test/tests/basic/bug642758.js b/js/src/jit-test/tests/basic/bug642758.js new file mode 100644 index 000000000..e92e65730 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642758.js @@ -0,0 +1,4 @@ +function Integer( value, exception ) { } +try { +new Integer( Math.LN2, ++INVALID_INTEGER_VALUE? exception+1.1: 1900 ); +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug642772-1.js b/js/src/jit-test/tests/basic/bug642772-1.js new file mode 100644 index 000000000..b7dc483fc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642772-1.js @@ -0,0 +1,19 @@ +var n1 = Number.prototype.toFixed; +var s1 = String.prototype.split; +delete Number; +delete String; + +var n2 = (5).toFixed; +var s2 = ("foo").split; + +// Check enumeration doesn't resurrect deleted standard classes +for (x in this) {} + +// Ensure the prototypes are shared. +var n3 = (5).toFixed; +var s3 = ("foo").split; + +assertEq(s1, s2); +assertEq(s1, s3); +assertEq(n1, n2); +assertEq(n1, n3); diff --git a/js/src/jit-test/tests/basic/bug642772-2.js b/js/src/jit-test/tests/basic/bug642772-2.js new file mode 100644 index 000000000..d797664bf --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642772-2.js @@ -0,0 +1,101 @@ +function failWrapper(callback) { + try { + callback(); // this should fail + throw "test-error"; // and if it didn't we have a problem` + } catch (e) { + if (e == "test-error") + throw ("Testing error when running " + callback.toString()); + } +} + + +print ("Deleting standard classes"); +delete Function; +delete Object; +delete Array; +delete Boolean; +delete JSON; +delete Date; +delete Math; +delete Number; +delete String; +delete Regexp; +delete Reflect; +delete Proxy; +delete Error; +delete Iterator; +delete Generator; +delete StopIteration; +delete Float32Array; +delete Float64Array; +delete Int16Array; +delete Int32Array; +delete Int32Array; +delete Uint16Array; +delete Uint32Array; +delete Uint8Array; +delete Uint8ClampedArray; +delete Weakmap; + + +print ("Accessing standard classes shouldn't recreate them"); +failWrapper(function () { Function; }); +failWrapper(function () { Object; }); +failWrapper(function () { Array; }); +failWrapper(function () { Boolean; }); +failWrapper(function () { JSON; }); +failWrapper(function () { Date; }); +failWrapper(function () { Math; }); +failWrapper(function () { Number; }); +failWrapper(function () { String; }); +failWrapper(function () { Regexp; }); +failWrapper(function () { Reflect; }); +failWrapper(function () { Proxy; }); +failWrapper(function () { Error; }); +failWrapper(function () { Iterator; }); +failWrapper(function () { Generator; }); +failWrapper(function () { StopIteration; }); +failWrapper(function () { Float32Array; }); +failWrapper(function () { Float64Array; }); +failWrapper(function () { Int16Array; }); +failWrapper(function () { Int32Array; }); +failWrapper(function () { Int32Array; }); +failWrapper(function () { Uint16Array; }); +failWrapper(function () { Uint32Array; }); +failWrapper(function () { Uint8Array; }); +failWrapper(function () { Uint8ClampedArray; }); +failWrapper(function () { Weakmap; }); + + +print ("Enumerate over the global object"); +for (c in this) {} + +print ("That shouldn't have recreated the standard classes either"); +failWrapper(function () { Function; }); +failWrapper(function () { Object; }); +failWrapper(function () { Array; }); +failWrapper(function () { Boolean; }); +failWrapper(function () { JSON; }); +failWrapper(function () { Date; }); +failWrapper(function () { Math; }); +failWrapper(function () { Number; }); +failWrapper(function () { String; }); +failWrapper(function () { Regexp; }); +failWrapper(function () { Reflect; }); +failWrapper(function () { Proxy; }); +failWrapper(function () { Error; }); +failWrapper(function () { Iterator; }); +failWrapper(function () { Generator; }); +failWrapper(function () { StopIteration; }); +failWrapper(function () { Float32Array; }); +failWrapper(function () { Float64Array; }); +failWrapper(function () { Int16Array; }); +failWrapper(function () { Int32Array; }); +failWrapper(function () { Int32Array; }); +failWrapper(function () { Uint16Array; }); +failWrapper(function () { Uint32Array; }); +failWrapper(function () { Uint8Array; }); +failWrapper(function () { Uint8ClampedArray; }); +failWrapper(function () { Weakmap; }); + +print ("success"); diff --git a/js/src/jit-test/tests/basic/bug642772-3.js b/js/src/jit-test/tests/basic/bug642772-3.js new file mode 100644 index 000000000..a722569b4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642772-3.js @@ -0,0 +1,5 @@ +// Catch memory leaks when enumerating over the global object. + +for (let z = 1; z <= 16000; ++z) { + for each (y in this); +} diff --git a/js/src/jit-test/tests/basic/bug642894.js b/js/src/jit-test/tests/basic/bug642894.js new file mode 100644 index 000000000..5de6f3597 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642894.js @@ -0,0 +1,9 @@ + +function foo() { + var x = {}; + x.__proto__ = function() { return 0 } + return x; +} +var a = foo(); +var b = foo(); +assertEq(a.__proto__ === b.__proto__, false); diff --git a/js/src/jit-test/tests/basic/bug642985-1.js b/js/src/jit-test/tests/basic/bug642985-1.js new file mode 100644 index 000000000..fb90691a9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642985-1.js @@ -0,0 +1,23 @@ +gczeal(2); +function complex(aReal, aImag) {} +function mandelbrotValueOO (aC, aIterMax) { + for (var iter = 0; iter < aIterMax; iter++) { } +} +function f(trace) { + const width = 5; + const height = 5; + const max_iters = 5; + var output = []; + for (let img_x = 0; img_x < width; img_x++) { + 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 res = mandelbrotValueOO(C, max_iters); + if (output.length > 0 && complex(5)) { + } else { + output.push([res, 1]); + } + } + } +} +var timenonjit = f(false); diff --git a/js/src/jit-test/tests/basic/bug642985-2.js b/js/src/jit-test/tests/basic/bug642985-2.js new file mode 100644 index 000000000..478b58559 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug642985-2.js @@ -0,0 +1,23 @@ +function f(N) +{ + for (var i = 0; i != N; ++i) { + var obj1 = {}, obj2 = {}; + obj1['a'+i] = 0; + obj2['b'+i] = 0; + for (var repeat = 0;repeat != 2; ++repeat) { + for (var j in obj1) { + for (var k in obj2) { + gc(); + } + } + } + } +} +var array = [function() { f(10); }, + function(array) { f(50); }, + function() { propertyIsEnumerable.call(undefined, {}); }, + ]; +try { + for (var i = 0; i != array.length; ++i) + array[i](); +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug643113.js b/js/src/jit-test/tests/basic/bug643113.js new file mode 100644 index 000000000..54ade9891 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug643113.js @@ -0,0 +1,11 @@ +function printBugNumber (num) +{ + print ('BUGNUMBER: ' + num); +} +try { test(); } catch (e) {} +function test() +{ + printBugNumber(typeof BUGNUMBER == 'undefined'); + 1|| q + 48? new q( printBugNumber, + eval("var EXP_1 = new MyValuelessObject('string'); var EXP_2 = new MyValuelessObject(false); EXP_1 + EXP_2") ): 1; +} diff --git a/js/src/jit-test/tests/basic/bug643169.js b/js/src/jit-test/tests/basic/bug643169.js new file mode 100644 index 000000000..28f3ac025 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug643169.js @@ -0,0 +1,7 @@ +for(var i=0; i<3; i++) { + var x; + function ff() {} + with(this) {} + x; + x = true; +} diff --git a/js/src/jit-test/tests/basic/bug643243.js b/js/src/jit-test/tests/basic/bug643243.js new file mode 100644 index 000000000..71530c56a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug643243.js @@ -0,0 +1,11 @@ +{ + function newSandbox(n) {} +} +var o12 = Float32Array.prototype; +function f12(o) { + eval('o')['__proto_' + '_'] = null; +} +for (var i = 0; i < 14; i++) { + gc() + new f12(o12); +} diff --git a/js/src/jit-test/tests/basic/bug643244.js b/js/src/jit-test/tests/basic/bug643244.js new file mode 100644 index 000000000..90e2d510e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug643244.js @@ -0,0 +1,2 @@ +delete(0).__proto__.valueOf +eval("(function(){(0).valueOf();})")() diff --git a/js/src/jit-test/tests/basic/bug643249.js b/js/src/jit-test/tests/basic/bug643249.js new file mode 100644 index 000000000..86a000228 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug643249.js @@ -0,0 +1,13 @@ +{ + function x() {} +} +for (i = 0; i < 10; i++) { + _someglobal_ = /a/; + (function() { + return function() { + return _someglobal_ + } () + } () == /a/); + gc(); + try { _someglobal_ = new Function.__lookupSetter__ } catch (e) {} +} diff --git a/js/src/jit-test/tests/basic/bug643285.js b/js/src/jit-test/tests/basic/bug643285.js new file mode 100644 index 000000000..0f8d75592 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug643285.js @@ -0,0 +1,4 @@ +function fun() { + (new Function ("function ff () { actual = '' + ff. caller; } function f () { ff (); } f ();")) ('function pf' + fun + '() {}'); +} +fun(); diff --git a/js/src/jit-test/tests/basic/bug643733.js b/js/src/jit-test/tests/basic/bug643733.js new file mode 100644 index 000000000..89a6695b3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug643733.js @@ -0,0 +1,4 @@ +var x; +assertEq(-(typeof (x+x)), NaN); +assertEq(-(typeof Math.abs()), NaN); + diff --git a/js/src/jit-test/tests/basic/bug645293.js b/js/src/jit-test/tests/basic/bug645293.js new file mode 100644 index 000000000..366c498fa --- /dev/null +++ b/js/src/jit-test/tests/basic/bug645293.js @@ -0,0 +1,12 @@ +/* Don't assert. */ +function f() { + NaN++; + --NaN; + Infinity--; + ++Infinity; + undefined++; + --undefined; + ++Math; + Math--; +} +f();
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug645632.js b/js/src/jit-test/tests/basic/bug645632.js new file mode 100644 index 000000000..dbb5b8fd7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug645632.js @@ -0,0 +1,6 @@ + +function f(o) { + o[{}] = 1; + with(Object) {} +} +f(Object.prototype); diff --git a/js/src/jit-test/tests/basic/bug646393.js b/js/src/jit-test/tests/basic/bug646393.js new file mode 100644 index 000000000..5d98e1541 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug646393.js @@ -0,0 +1,4 @@ +try { + x.y; +} catch(ex) {} +x = Number(1); diff --git a/js/src/jit-test/tests/basic/bug646968-3.js b/js/src/jit-test/tests/basic/bug646968-3.js new file mode 100644 index 000000000..a02cb3f68 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug646968-3.js @@ -0,0 +1,16 @@ +var s, v = "NOPE"; + +s = ''; +for (let v = 0, x = v; x < 3; x++) + s += x; +assertEq(s, '012'); + +s = ''; +for (let v = 0, x = eval('v'); x < 3; x++) + s += x; +assertEq(s, '012'); + +s = '' +for (let v = 0, x = function () { with ({}) return v; }(); x < 3; x++) + s += x; +assertEq(s, '012'); diff --git a/js/src/jit-test/tests/basic/bug646968-4.js b/js/src/jit-test/tests/basic/bug646968-4.js new file mode 100644 index 000000000..fdcafbb2b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug646968-4.js @@ -0,0 +1,10 @@ +load(libdir + "asserts.js"); + +// Scoping: `x` in the head of a `for (let x...)` loop refers to the loop variable. + +assertThrowsInstanceOf(function () { +var s = "", x = {a: 1, b: 2, c: 3}; +for (let x in eval('x')) + s += x; +assertEq(s, ""); +}, ReferenceError); diff --git a/js/src/jit-test/tests/basic/bug646968-5.js b/js/src/jit-test/tests/basic/bug646968-5.js new file mode 100644 index 000000000..abc372a85 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug646968-5.js @@ -0,0 +1,9 @@ +var y = 7; + +switch (function () { with ({}) return y; }()) { +case 7: + let y; + break; +default: + throw 'FAIL'; +} diff --git a/js/src/jit-test/tests/basic/bug646968-6.js b/js/src/jit-test/tests/basic/bug646968-6.js new file mode 100644 index 000000000..11b1fa1c1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug646968-6.js @@ -0,0 +1,16 @@ +// In `for (let x = EXPR; ;)`, if `x` appears within EXPR, it refers to the +// loop variable. Actually doing this is typically a TDZ error. + +load(libdir + "asserts.js"); + +assertThrowsInstanceOf(() => { + for (let x = x; null.foo; null.foo++) {} +}, ReferenceError); + +assertThrowsInstanceOf(() => { + for (let x = eval('x'); null.foo; null.foo++) {} +}, ReferenceError); + +assertThrowsInstanceOf(() => { + for (let x = function () { with ({}) return x; }(); null.foo; null.foo++) {} +}, ReferenceError); diff --git a/js/src/jit-test/tests/basic/bug646968-7.js b/js/src/jit-test/tests/basic/bug646968-7.js new file mode 100644 index 000000000..7fac119f5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug646968-7.js @@ -0,0 +1,10 @@ +load(libdir + "evalInFrame.js"); + +function test(s) { + eval(s); + { + let y = evalInFrame(0, '3'), x = x0; + assertEq(x, 5); + } +} +test('var x0= 5;'); diff --git a/js/src/jit-test/tests/basic/bug646968-8.js b/js/src/jit-test/tests/basic/bug646968-8.js new file mode 100644 index 000000000..9214f0798 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug646968-8.js @@ -0,0 +1,8 @@ +load(libdir + "evalInFrame.js"); + +var x = 5; +{ + let x = eval("this.x++"); + assertEq(evalInFrame(0, "x"), 5); +} +assertEq(x, 6); diff --git a/js/src/jit-test/tests/basic/bug647463.js b/js/src/jit-test/tests/basic/bug647463.js new file mode 100644 index 000000000..0f3d5cd57 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug647463.js @@ -0,0 +1,6 @@ + +try { + eval("\ + [0].sort()\ + ") +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug648357.js b/js/src/jit-test/tests/basic/bug648357.js new file mode 100644 index 000000000..9c2c939e0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug648357.js @@ -0,0 +1,3 @@ +var x = [1, 2, 3, 4, 5, 6, 7, 8]; +x.pop(); +x.push(9); diff --git a/js/src/jit-test/tests/basic/bug648773.js b/js/src/jit-test/tests/basic/bug648773.js new file mode 100644 index 000000000..2ab57ed24 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug648773.js @@ -0,0 +1,4 @@ +gczeal(2); +for (var loopa2 = 0; loopa2 < 13; loopa2++) { + [, , , , , , ][new Float64Array()] = 72413.8139177333; +} diff --git a/js/src/jit-test/tests/basic/bug649439.js b/js/src/jit-test/tests/basic/bug649439.js new file mode 100644 index 000000000..0f19afca8 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug649439.js @@ -0,0 +1,3 @@ +var o1 = new String("abc"); +var o2 = o1[1]; +o2[1]; diff --git a/js/src/jit-test/tests/basic/bug649771.js b/js/src/jit-test/tests/basic/bug649771.js new file mode 100644 index 000000000..6ecc2d83e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug649771.js @@ -0,0 +1,7 @@ +function f(o) { + f = o.constructor; + eval('delete o.x'); +} +for(var i=0; i<3; i++) { + f(RegExp.prototype); +} diff --git a/js/src/jit-test/tests/basic/bug649939.js b/js/src/jit-test/tests/basic/bug649939.js new file mode 100644 index 000000000..2f1b05473 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug649939.js @@ -0,0 +1,27 @@ +// This was the actual bug +assertRaises(StopIteration, function() { + Iterator.prototype.next(); + Iterator.prototype.next(); +}); + +// The error should have triggered here, but was masked by a latent bug +assertRaises(StopIteration, function() { + Iterator.prototype.next(); +}); + +// Found by fuzzing +assertRaises(StopIteration, function() { + (new Iterator({})).__proto__.next(); +}); + + +function assertRaises(exc, callback) { + var caught = false; + try { + callback(); + } catch (e) { + assertEq(e instanceof StopIteration, true); + caught = true; + } + assertEq(caught, true); +} diff --git a/js/src/jit-test/tests/basic/bug650148.js b/js/src/jit-test/tests/basic/bug650148.js new file mode 100644 index 000000000..9f6b45548 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug650148.js @@ -0,0 +1,11 @@ +summary=/(?!AB+D)AB/.exec("AB") + ''; +try { + var s = "throw 42"; +} catch (e) {} +test(); +function test() { + [ {0xBe: /l/|| 'Error' ? s++ : summary } ] +} +function foo(code) + Function(code)(); +foo("for each (y in this);"); diff --git a/js/src/jit-test/tests/basic/bug651451-2.js b/js/src/jit-test/tests/basic/bug651451-2.js new file mode 100644 index 000000000..d5594b892 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug651451-2.js @@ -0,0 +1,6 @@ +var arr = [1, 2, 3, 4, 5]; +arr.length = 100; +arr.pop(); +assertEq(arr.length, 99); +arr.pop(); +assertEq(arr.length, 98);
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug651451.js b/js/src/jit-test/tests/basic/bug651451.js new file mode 100644 index 000000000..e547fa4d7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug651451.js @@ -0,0 +1,4 @@ +var arr = [2]; +arr.pop(); +arr[0] = 2; +assertEq(arr.length, 1); diff --git a/js/src/jit-test/tests/basic/bug651966.js b/js/src/jit-test/tests/basic/bug651966.js new file mode 100644 index 000000000..d2f9a522d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug651966.js @@ -0,0 +1,38 @@ + +function f(code) { + g = eval("(function(){" + code + "})"); + g() +} +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +f(); +try { f("function x(){}(x())"); } catch (e) {} + +function f2() { + a = { + x + } = x, (x._) + function + x()({}) +} +try { f2(); } catch (e) {} + +function f3() { + var x = 0; + with ({}) { x = 'three'; } + return x; +} +f3(); diff --git a/js/src/jit-test/tests/basic/bug652054.js b/js/src/jit-test/tests/basic/bug652054.js new file mode 100644 index 000000000..3e43d3673 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug652054.js @@ -0,0 +1,55 @@ +var M4x4 = {};
+M4x4.mul = function M4x4_mul(a, b, r) {
+ a11 = a[0]
+ a21 = a[1]
+ a31 = a[2]
+ a12 = a[4]
+ a22 = a[5]
+ a32 = a[6]
+ a13 = a[8]
+ a23 = a[9]
+ a33 = a[10]
+ a14 = a[12]
+ a24 = a[13]
+ a34 = a[14]
+ b[3]
+ b[4]
+ b13 = b[8]
+ b23 = b[9]
+ b33 = b[10]
+ b43 = b[11]
+ r[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43
+ r[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43
+ r[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43
+ return r;
+};
+M4x4.scale3 = function M4x4_scale3(x, y, z, m) {
+ m[0] *= x;
+ m[3] *= x;
+ m[4] *= y;
+ m[11] *= z;
+};
+M4x4.makeLookAt = function M4x4_makeLookAt() {
+ tm1 = new Float32Array(16);
+ tm2 = new Float32Array(16);
+ r = new Float32Array(16)
+ return M4x4.mul(tm1, tm2, r);
+};
+var jellyfish = {};
+jellyfish.order = [];
+function jellyfishInstance() {}
+jellyfishInstance.prototype.drawShadow = function () {
+ pMatrix = M4x4.makeLookAt();
+ M4x4.mul(M4x4.makeLookAt(), pMatrix, pMatrix);
+ M4x4.scale3(6, 180, 0, pMatrix);
+}
+function drawScene() {
+ jellyfish.order.push([0, 0])
+ jellyfish[0] = new jellyfishInstance()
+ for (var i = 0, j = 0; i < jellyfish.count, j < 30; ++j) {
+ jellyfish.order[i][0]
+ jellyfish[0].drawShadow();
+ }
+}
+drawScene();
+
diff --git a/js/src/jit-test/tests/basic/bug652060.js b/js/src/jit-test/tests/basic/bug652060.js new file mode 100644 index 000000000..d7d5609a0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug652060.js @@ -0,0 +1,9 @@ +var x = -false; +var y = -0; +assertEq(-x === x, true); +assertEq(-x === y, true); +assertEq(-y !== y, false); + +assertEq(-x == x, true); +assertEq(-x == y, true); +assertEq(-y != y, false); diff --git a/js/src/jit-test/tests/basic/bug652422.js b/js/src/jit-test/tests/basic/bug652422.js new file mode 100644 index 000000000..64525ee36 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug652422.js @@ -0,0 +1,6 @@ +try { (function() { + var o = {}; + with (o) o='recorder not started, '; + ('arguments' in o, false, + "property deletion observable") +})() } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug652646.js b/js/src/jit-test/tests/basic/bug652646.js new file mode 100644 index 000000000..5f54c32de --- /dev/null +++ b/js/src/jit-test/tests/basic/bug652646.js @@ -0,0 +1,11 @@ +function foo() { + try { + return 0; + } catch (e) { + try { + return 1; + } catch (e) { + } + } +} +foo(); diff --git a/js/src/jit-test/tests/basic/bug653153.js b/js/src/jit-test/tests/basic/bug653153.js new file mode 100644 index 000000000..c06e3b82b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug653153.js @@ -0,0 +1,76 @@ +// ES5 15.1.2.2 step 1 + +/* + * Boundary testing for super-large positive numbers between non-exponential + * and in-exponential-form. + * + * NB: While 1e21 is exactly representable as an IEEE754 double-precision + * number, its nearest neighboring representable values are a good distance + * away, 65536 to be precise. + */ + +// This is the boundary in theory. +assertEq(parseInt(1e21), 1); + +// This is the boundary in practice. +assertEq(parseInt(1e21 - 65537) > 1e20, true); +assertEq(parseInt(1e21 - 65536), 1); +assertEq(parseInt(1e21 + 65536), 1); + +// Check that we understand floating point accuracy near the boundary +assertEq(1e21 - 65537 !== 1e21 - 65536, true); +assertEq(1e21 - 65536, 1e21); +assertEq(1e21 + 65535, 1e21); +assertEq(1e21 + 65536, 1e21); + +// ES5 leaves exact precision in ToString(bigMagNum) undefined, which +// might make this value inconsistent across implementations (maybe, +// nobody's done the math here). Regardless, it's definitely a number +// very close to 1, and not a large-magnitude positive number. +assertEq(1e21 + 65537 !== 1e21, true); +assertEq(parseInt(1e21 + 65537) < 1.001, true); + + +/* + * Now do the same tests for super-large negative numbers crossing the + * opposite boundary. + */ + +// This is the boundary in theory. +assertEq(parseInt(-1e21), -1); + +// This is the boundary in practice. +assertEq(parseInt(-1e21 + 65537) < -1e20, true); +assertEq(parseInt(-1e21 + 65536), -1); +assertEq(parseInt(-1e21 - 65536), -1); + +// Check that we understand floating point accuracy near the boundary +assertEq(-1e21 + 65537 !== -1e21 + 65536, true); +assertEq(-1e21 + 65536, -1e21); +assertEq(-1e21 - 65535, -1e21); +assertEq(-1e21 - 65536, -1e21); + +// ES5 leaves exact precision in ToString(bigMagNum) undefined, which +// might make this value inconsistent across implementations (maybe, +// nobody's done the math here). Regardless, it's definitely a number +// very close to -1, and not a large-magnitude negative number. +assertEq(-1e21 - 65537 !== 1e21, true); +assertEq(parseInt(-1e21 - 65537) > -1.001, true); + + +/* Check values around the boundary. */ +arr = [1e0, 5e1, 9e19, 0.1e20, 1.3e20, 1e20, 9e20, 9.99e20, 0.1e21, + 1e21, 1.0e21, 2e21, 2e20, 2.1e22, 9e21, 0.1e22, 1e22, 3e46, 3e23, 3e100, 3.4e200, 7e1000, + 1e21, 1e21+65537, 1e21+65536, 1e21-65536, 1e21-65537]; + +/* Check across a range of values in case we missed anything. */ +for (var i = 0; i < 4000; i++) { + arr.push(1e19 + i*1e19); +} + +for (var i in arr) { + assertEq(parseInt( arr[i]), parseInt(String( arr[i]))); + assertEq(parseInt(-arr[i]), parseInt(String(-arr[i]))); +} + + diff --git a/js/src/jit-test/tests/basic/bug653262.js b/js/src/jit-test/tests/basic/bug653262.js new file mode 100644 index 000000000..9a488bbaa --- /dev/null +++ b/js/src/jit-test/tests/basic/bug653262.js @@ -0,0 +1,4 @@ +with(evalcx(''))(function eval() {}, this.__defineGetter__("x", Function)); +var i = 0; +var o; +new(x); diff --git a/js/src/jit-test/tests/basic/bug653438.js b/js/src/jit-test/tests/basic/bug653438.js new file mode 100644 index 000000000..23cd086ba --- /dev/null +++ b/js/src/jit-test/tests/basic/bug653438.js @@ -0,0 +1,2 @@ +assertEq((123456789).toExponential(), "1.23456789e+8"); +assertEq((123456789).toExponential(undefined), "1.23456789e+8"); diff --git a/js/src/jit-test/tests/basic/bug653672.js b/js/src/jit-test/tests/basic/bug653672.js new file mode 100644 index 000000000..c9d5e202b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug653672.js @@ -0,0 +1,5 @@ +// don't crash + +var regexp1 = /(?:(?=g))|(?:m).{2147483648,}/; +var regexp2 = /(?:(?=g)).{2147483648,}/; + diff --git a/js/src/jit-test/tests/basic/bug654073.js b/js/src/jit-test/tests/basic/bug654073.js new file mode 100644 index 000000000..7659d534b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug654073.js @@ -0,0 +1,11 @@ +load(libdir + "immutable-prototype.js"); + +if (globalPrototypeChainIsMutable()) { + this.__proto__ = null; + Object.prototype.__proto__ = this; +} + +for (var y in Object.prototype) + continue; +for (var x in this) + continue; diff --git a/js/src/jit-test/tests/basic/bug654668.js b/js/src/jit-test/tests/basic/bug654668.js new file mode 100644 index 000000000..8706c154a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug654668.js @@ -0,0 +1,10 @@ +var summary = 'foo'; +function X(n) { + var y = []; + while (summary + y[0]) { + break; + } +} +X(); + +// Don't crash wthi -m -n -a diff --git a/js/src/jit-test/tests/basic/bug656261.js b/js/src/jit-test/tests/basic/bug656261.js new file mode 100644 index 000000000..7a3b61d21 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug656261.js @@ -0,0 +1,31 @@ +function build_getter(i) { + var x = [i]; + return function f() { return x; } +} + +function test() +{ + var N = internalConst("INCREMENTAL_MARK_STACK_BASE_CAPACITY") + 2; + var o = {}; + var descriptor = { enumerable: true}; + for (var i = 0; i != N; ++i) { + descriptor.get = build_getter(i); + Object.defineProperty(o, i, descriptor); + } + + // At this point we have an object o with N getters. Each getter in turn + // is a closure storing an array. During the GC we push to the object + // marking stack all the getters found in an object after we mark it. As N + // exceeds the size of the object marking stack, this requires to run the + // dealyed scanning for some closures to mark the array objects stored in + // them. + // + // We run the GC twice to make sure that the background finalization + // finishes before we access the objects. + gc(); + gc(); + for (var i = 0; i != N; ++i) + assertEq(o[i][0], i); +} + +test(); diff --git a/js/src/jit-test/tests/basic/bug657197.js b/js/src/jit-test/tests/basic/bug657197.js new file mode 100644 index 000000000..fde956abe --- /dev/null +++ b/js/src/jit-test/tests/basic/bug657197.js @@ -0,0 +1,5 @@ +try { (function() { + new function() { + throw []; + } +})() } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug657225.js b/js/src/jit-test/tests/basic/bug657225.js new file mode 100644 index 000000000..40f0dbf96 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug657225.js @@ -0,0 +1,9 @@ + +function reportCompare(expected, actual, description) + ++actual + "'"; +var summary = 'Object.prototype.toLocaleString() should track Object.prototype.toString() '; +var o = { + toString: function () {} +}; +expect = o; +actual = o.toLocaleString(); +reportCompare(expect, actual, summary); diff --git a/js/src/jit-test/tests/basic/bug657245.js b/js/src/jit-test/tests/basic/bug657245.js new file mode 100644 index 000000000..15bea1c94 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug657245.js @@ -0,0 +1,4 @@ + +var length = 4294967295; +var array1 = Array(length); +array1.pop(); diff --git a/js/src/jit-test/tests/basic/bug657901.js b/js/src/jit-test/tests/basic/bug657901.js new file mode 100644 index 000000000..a0531ae75 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug657901.js @@ -0,0 +1,8 @@ +function f() {}; +function g(o) { + f = new Function(""); + eval(""); +} +g({}); +g({}); +f++; diff --git a/js/src/jit-test/tests/basic/bug658539.js b/js/src/jit-test/tests/basic/bug658539.js new file mode 100644 index 000000000..045439411 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug658539.js @@ -0,0 +1,2 @@ +with(newGlobal('same-compartment')) +new Number() diff --git a/js/src/jit-test/tests/basic/bug660081.js b/js/src/jit-test/tests/basic/bug660081.js new file mode 100644 index 000000000..1c62a654c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug660081.js @@ -0,0 +1 @@ +(function() { "length" in (true && arguments); })() diff --git a/js/src/jit-test/tests/basic/bug660173.js b/js/src/jit-test/tests/basic/bug660173.js new file mode 100644 index 000000000..99d0f8ed8 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug660173.js @@ -0,0 +1,4 @@ +(function() {}).apply(null, (function() { + var x; + return (x = arguments); +})()); diff --git a/js/src/jit-test/tests/basic/bug660203.js b/js/src/jit-test/tests/basic/bug660203.js new file mode 100644 index 000000000..faed7b686 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug660203.js @@ -0,0 +1,9 @@ + +function throwsRangeError(t) { + try { + var date = arguments; + date.setTime + } catch (err) { + } +} +throwsRangeError(); diff --git a/js/src/jit-test/tests/basic/bug660204.js b/js/src/jit-test/tests/basic/bug660204.js new file mode 100644 index 000000000..eddd4ba83 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug660204.js @@ -0,0 +1,12 @@ + +eval("try { name(); } catch(e) {}"); +function Employee ( name, dept ) { + this.name=name || "" + this.dept +} +function WorkerBee ( name, dept, projs ) { + this.base=Employee + this.base( name, print("WHAT")) +} +new WorkerBee; +WorkerBee(); diff --git a/js/src/jit-test/tests/basic/bug660597.js b/js/src/jit-test/tests/basic/bug660597.js new file mode 100644 index 000000000..207a828e7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug660597.js @@ -0,0 +1,5 @@ + +function foo() { + with(foo) this["00"]=function(){} +} +new foo; diff --git a/js/src/jit-test/tests/basic/bug662044.js b/js/src/jit-test/tests/basic/bug662044.js new file mode 100644 index 000000000..bebabef84 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug662044.js @@ -0,0 +1,12 @@ +eval("var OBJ = new MyObject(true); OBJ.valueOf()") +function MyObject( value ) { + this.valueOf = new Function( "return this.value" ); +} +eval("\ +var VERSION = \"ECMA_1\";\ +var DATE1 = new Date();\ +var MYOB1 = new MyObject( DATE1 );\ +function MyProtoValuelessObject() {}\ +function Function() {\ + __proto__[MyProtoValuelessObject] = VERSION;\ +}"); diff --git a/js/src/jit-test/tests/basic/bug662562.js b/js/src/jit-test/tests/basic/bug662562.js new file mode 100644 index 000000000..45b48589a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug662562.js @@ -0,0 +1,6 @@ +// |jit-test| error: TypeError +function f(o) { + o.watch("x", this); +} +var c = evalcx(""); +f(c); diff --git a/js/src/jit-test/tests/basic/bug662841.js b/js/src/jit-test/tests/basic/bug662841.js new file mode 100644 index 000000000..351bb97a9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug662841.js @@ -0,0 +1,4 @@ +var e = newGlobal(); +for (let w in [0, 0, 0, 0, 0, 0, 0, 0]) { + -e; +} diff --git a/js/src/jit-test/tests/basic/bug663338.js b/js/src/jit-test/tests/basic/bug663338.js new file mode 100644 index 000000000..7f511b314 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug663338.js @@ -0,0 +1,26 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + + +assertEq(parseInt(1.0e-7, 10), 1); +assertEq(parseInt(-1.0e-7, 10), -1); + +assertEq(parseInt(9e-8, 10), 9); +assertEq(parseInt(-9e-8, 10), -9); + +assertEq(parseInt(1.5e-8, 10), 1); +assertEq(parseInt(-1.5e-8, 10), -1); + +assertEq(parseInt(1.0e-6, 10), 0); + +assertEq(parseInt(0, 10), 0); +assertEq(parseInt(-0, 10), 0); + +assertEq(parseInt('0', 10), 0); +assertEq(parseInt('-0', 10), -0); + +/* this is not very hacky, but we try to get a double value of 0, instead of int */ +assertEq(parseInt(Math.asin(0), 10), 0); +assertEq(parseInt(Math.asin(-0), 10), 0); diff --git a/js/src/jit-test/tests/basic/bug665289.js b/js/src/jit-test/tests/basic/bug665289.js new file mode 100644 index 000000000..a5e9d7e54 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug665289.js @@ -0,0 +1,4 @@ +delete this.Function; +a = evalcx("lazy"); +a["Object"] = this; +if (typeof a.isPrototypeOf == "") {} diff --git a/js/src/jit-test/tests/basic/bug666448.js b/js/src/jit-test/tests/basic/bug666448.js new file mode 100644 index 000000000..aef626265 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug666448.js @@ -0,0 +1 @@ +assertEq(["a"].map(escape)[0], ["a"].map(function(s) {return escape(s);})[0]); diff --git a/js/src/jit-test/tests/basic/bug667504-syntax.js b/js/src/jit-test/tests/basic/bug667504-syntax.js new file mode 100644 index 000000000..606922020 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug667504-syntax.js @@ -0,0 +1,3 @@ +for (var x in x) { +function x() {} +} diff --git a/js/src/jit-test/tests/basic/bug667507.js b/js/src/jit-test/tests/basic/bug667507.js new file mode 100644 index 000000000..883857a1e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug667507.js @@ -0,0 +1,6 @@ +for (i = 0; i < 10; i++) { + Object.defineProperty({}, "", { + get: function() {} + }) + gc() +} diff --git a/js/src/jit-test/tests/basic/bug673468.js b/js/src/jit-test/tests/basic/bug673468.js new file mode 100644 index 000000000..90749115b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673468.js @@ -0,0 +1,8 @@ +var g = newGlobal(); +var k = g.eval('var u = new Object(); u'); +var m = new WeakMap(); +m.set(k, {}); +k = null; +gc(); +k = g.eval('u'); +assertEq(m.has(k), true); diff --git a/js/src/jit-test/tests/basic/bug673469.js b/js/src/jit-test/tests/basic/bug673469.js new file mode 100644 index 000000000..21dbf43fe --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673469.js @@ -0,0 +1,9 @@ +var a = Boolean(); +false.__proto__; +var c = ({}).__proto__; +var d = {}; +gc() +c[0] = d; +for (var x in a) { + a[x]; +} diff --git a/js/src/jit-test/tests/basic/bug673569.js b/js/src/jit-test/tests/basic/bug673569.js new file mode 100644 index 000000000..acc54277a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673569.js @@ -0,0 +1,18 @@ +function qualified_tests(prefix) { + let scopes = evalReturningScope(prefix + "var x = 1"); + assertEq(scopes.vars.x, 1); +} + +qualified_tests(""); +qualified_tests("'use strict'; "); + +let scopes = evalReturningScope("x = 1"); +assertEq(scopes.vars.x, 1); + +let fail = true; +try { + evalReturningScope("'use strict'; x = 1"); +} catch (e) { + fail = false; +} +assertEq(fail, false); diff --git a/js/src/jit-test/tests/basic/bug673705-1.js b/js/src/jit-test/tests/basic/bug673705-1.js new file mode 100644 index 000000000..42fc30591 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673705-1.js @@ -0,0 +1,10 @@ +function bug673705() { + var x; + try { + } catch (e) { + } finally { + print(x); + } + return x; +} +assertEq(bug673705(), undefined); diff --git a/js/src/jit-test/tests/basic/bug673705-2.js b/js/src/jit-test/tests/basic/bug673705-2.js new file mode 100644 index 000000000..28076f9c4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673705-2.js @@ -0,0 +1,12 @@ +function bug673705() { + var x; + try { + try { + } catch (e) { + } + } finally { + } + print(x); + return x; +} +assertEq(bug673705(), undefined); diff --git a/js/src/jit-test/tests/basic/bug673715.js b/js/src/jit-test/tests/basic/bug673715.js new file mode 100644 index 000000000..b20406906 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673715.js @@ -0,0 +1,10 @@ +function g() { + "use strict"; + for (var i = 0; i < 50; i++) + arguments[0]; + eval(""); +} +function f() { + g.call(arguments); +} +f(); diff --git a/js/src/jit-test/tests/basic/bug673731.js b/js/src/jit-test/tests/basic/bug673731.js new file mode 100644 index 000000000..ca249828e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673731.js @@ -0,0 +1,3 @@ +// |jit-test| error: ReferenceError + +const IS_TOKEN_ARRAY = [ printBugNumber && this() ? this() : this() ]; diff --git a/js/src/jit-test/tests/basic/bug673766.js b/js/src/jit-test/tests/basic/bug673766.js new file mode 100644 index 000000000..0d1d36f5d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673766.js @@ -0,0 +1,20 @@ +function TestCase(n, d, e, a) { + this.name = n + this.description = d +} +function reportCompare(expected, actual, description) { + new TestCase +} +var actual = ''; +var expect = ''; +for (var i = 0; i < 2; ++i) reportCompare(expect, actual, ': 2'); +try { + ({ + valueOf: gc + } - []) +} catch (prop) {} +function addThis() reportCompare(expect, actual, 'ok'); +Object.defineProperty(Object.prototype, "name", { + set: function (newValue) {} +}); +addThis() diff --git a/js/src/jit-test/tests/basic/bug673767.js b/js/src/jit-test/tests/basic/bug673767.js new file mode 100644 index 000000000..5a7fb07b7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug673767.js @@ -0,0 +1,2 @@ +var stack = {}; +stack.length += 3; diff --git a/js/src/jit-test/tests/basic/bug674085.js b/js/src/jit-test/tests/basic/bug674085.js new file mode 100644 index 000000000..0147621e7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug674085.js @@ -0,0 +1,6 @@ +function f(x) { + for (var i = 0; i < 50; i++) {}; + [1][arguments[0]]++; + x = 1.2; +} +f(0); diff --git a/js/src/jit-test/tests/basic/bug674776.js b/js/src/jit-test/tests/basic/bug674776.js new file mode 100644 index 000000000..816cfc534 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug674776.js @@ -0,0 +1,18 @@ +// |jit-test| slow + +/* Make a lot of functions of the form: +function x1(){x1();} +function x2(){x2();} +function x3(){x3();} +... +*/ + +var g = newGlobal(); +var dbg = new g.Debugger(this); + +var s = ''; +for (var i = 0; i < 70000; i++) { + s += 'function x' + i + '() { x' + i + '(); }\n'; +} +s += 'pc2line(1);\n' +evaluate(s); diff --git a/js/src/jit-test/tests/basic/bug675889.js b/js/src/jit-test/tests/basic/bug675889.js new file mode 100644 index 000000000..906bbb431 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug675889.js @@ -0,0 +1,8 @@ +function checkMethods(proto) { + var names = Object.getOwnPropertyNames(proto); + for (var i = 0; i < names.length; i++) { + var name = names[i]; + var prop = proto[name]; + } +} +checkMethods(Function.prototype); diff --git a/js/src/jit-test/tests/basic/bug677635.js b/js/src/jit-test/tests/basic/bug677635.js new file mode 100644 index 000000000..fffc67cc5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug677635.js @@ -0,0 +1,7 @@ + +index = 0; +test(); +function test() { + var [message,prettyPrinting]=[arguments,__lookupGetter__]; + message<index; +} diff --git a/js/src/jit-test/tests/basic/bug677957-1.js b/js/src/jit-test/tests/basic/bug677957-1.js new file mode 100644 index 000000000..5e90b2a76 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug677957-1.js @@ -0,0 +1,4 @@ +function test() { + for each (var i in []) {} +} +for each (new test().p in [0]) {} diff --git a/js/src/jit-test/tests/basic/bug677957-2.js b/js/src/jit-test/tests/basic/bug677957-2.js new file mode 100644 index 000000000..7778dd02a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug677957-2.js @@ -0,0 +1,13 @@ +var x = {f: 1, g: 0}; +function f() { + for each (new f().nosuch.prop in x) + throw 'FAIL'; +} + +var e; +try { + f(); +} catch (exc) { + e = exc; +} +assertEq(e instanceof InternalError, true); diff --git a/js/src/jit-test/tests/basic/bug678087.js b/js/src/jit-test/tests/basic/bug678087.js new file mode 100644 index 000000000..05a2ad4a3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug678087.js @@ -0,0 +1,11 @@ +load(libdir + "asserts.js"); + +assertThrowsInstanceOf(function () { +i = 0; +do { +with({ + TestCase: Float64Array +}) for each(let TestCase in [TestCase]) {} + } while (i++ < 10); +function TestCase(n, d, e, a) {} +}, ReferenceError); diff --git a/js/src/jit-test/tests/basic/bug678211.js b/js/src/jit-test/tests/basic/bug678211.js new file mode 100644 index 000000000..6918be3fc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug678211.js @@ -0,0 +1,3 @@ +var g = newGlobal(); +g.eval("function f(n) { for (var i = 0; i < n; i++) f(0); }"); +g.f(10); diff --git a/js/src/jit-test/tests/basic/bug679977.js b/js/src/jit-test/tests/basic/bug679977.js new file mode 100644 index 000000000..f11311945 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug679977.js @@ -0,0 +1,26 @@ +var Test = function (foo) { + var a = []; + + this.fillArray = function() { + a = []; + for (var i = 0; i < 10; i++) + a.push(0); + assertEq(a.length, 10); + } + + foo.go(this); +}; + +// Import assertEq now to prevent global object shape from changing. +assertEq(true, true); + +(new Test({ go: function(p) { + p.fill = function() { + p.fillArray(); + } +}})).fill(); + +new Test({ go: function(p) { + for (var k = 0; k < 10; k++) + p.fillArray(); +}}); diff --git a/js/src/jit-test/tests/basic/bug679986-1.js b/js/src/jit-test/tests/basic/bug679986-1.js new file mode 100644 index 000000000..e1e512810 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug679986-1.js @@ -0,0 +1,2 @@ +// don't assert +var m = "aaaa".match(/(?:|a)*/); diff --git a/js/src/jit-test/tests/basic/bug679986-2.js b/js/src/jit-test/tests/basic/bug679986-2.js new file mode 100644 index 000000000..95e84901b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug679986-2.js @@ -0,0 +1,2 @@ +// don't hang +var m = "aaaa".match(/(?:a?)*/); diff --git a/js/src/jit-test/tests/basic/bug680217.js b/js/src/jit-test/tests/basic/bug680217.js new file mode 100644 index 000000000..90f6b38fb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug680217.js @@ -0,0 +1,13 @@ +try { + for (var BUGNUMBER = 0, sz = Math.pow(2, 12); i < sz; i++) + str += '0,'; +} catch (exc1) {} +var str = '['; +for (var i = 0, BUGNUMBER; i < sz; i++) + str += '0,'; +var obj = { + p: { __proto__: null }, +}; +for (var i = 0; i < sz; i++) + str += '0,'; +gc(); diff --git a/js/src/jit-test/tests/basic/bug683140.js b/js/src/jit-test/tests/basic/bug683140.js new file mode 100644 index 000000000..23b998214 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug683140.js @@ -0,0 +1,13 @@ + +var g = newGlobal("same-compartment"); +g.eval("this.f = function(a) {" + + "assertEq(a instanceof Array, false);" + + "a = Array.prototype.slice.call(a);" + + "assertEq(a instanceof Array, true); }"); +g.f([1, 2, 3]); + +var g2 = newGlobal(); +g2.a = g2.Array(10); +assertEq(g2.a instanceof Array, false); +g2.a = Array.prototype.slice(g2.a); +assertEq(g2.a instanceof Array, true); diff --git a/js/src/jit-test/tests/basic/bug683838.js b/js/src/jit-test/tests/basic/bug683838.js new file mode 100644 index 000000000..841376c03 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug683838.js @@ -0,0 +1,3 @@ +var rg = /(X(?:.(?!X))*?Y)|(Y(?:.(?!Y))*?Z)/g;
+var str = "Y aaa X Match1 Y aaa Y Match2 Z";
+assertEq(str.match(rg) + "", "X Match1 Y,Y Match2 Z");
diff --git a/js/src/jit-test/tests/basic/bug684922.js b/js/src/jit-test/tests/basic/bug684922.js new file mode 100644 index 000000000..39421584b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug684922.js @@ -0,0 +1,6 @@ +// |jit-test| error: InternalError +var op = Object.prototype; +op.b = op; +op.__iterator__ = Iterator; +for (var c in {}) {} + diff --git a/js/src/jit-test/tests/basic/bug685313.js b/js/src/jit-test/tests/basic/bug685313.js new file mode 100644 index 000000000..f791e5e66 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug685313.js @@ -0,0 +1,11 @@ + +function foo() { + function D(){} + arr = [ + new (function D ( ) { + D += '' + foo; + }), + new D + ]; +} +foo(); diff --git a/js/src/jit-test/tests/basic/bug685321-1.js b/js/src/jit-test/tests/basic/bug685321-1.js new file mode 100644 index 000000000..789651fc9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug685321-1.js @@ -0,0 +1,11 @@ +function f() { + function g() { + for (var i = 0; i < 3; i++) + x = i; + }; + var [x] = []; + g(); + assertEq(x, 2); + print(x); +} +f(); diff --git a/js/src/jit-test/tests/basic/bug685321-2.js b/js/src/jit-test/tests/basic/bug685321-2.js new file mode 100644 index 000000000..3cc6718cc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug685321-2.js @@ -0,0 +1,13 @@ +var o = {};
+function f() {
+ function g() {
+ x = 80;
+ return x;
+ };
+ Object.defineProperty(o, "f", {get:g});
+ var [x] = [];
+ x = {};
+ 2 + o.f;
+ print(x);
+}
+f();
diff --git a/js/src/jit-test/tests/basic/bug686296.js b/js/src/jit-test/tests/basic/bug686296.js new file mode 100644 index 000000000..f83917d77 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug686296.js @@ -0,0 +1,3 @@ +load(libdir + "asserts.js"); +var o = Object.preventExtensions(new ArrayBuffer); +assertThrowsInstanceOf(function () { o.__proto__ = {}; }, TypeError); diff --git a/js/src/jit-test/tests/basic/bug686396.js b/js/src/jit-test/tests/basic/bug686396.js new file mode 100644 index 000000000..8123fc99c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug686396.js @@ -0,0 +1,16 @@ + +(function () { + assertEquals = function assertEquals(expected, found, name_opt) { }; +})(); +function testOne(receiver, key, result) { + for(var i = 0; i != 10; i++ ) { + assertEquals(result, receiver[key]()); + } +} +function TypeOfThis() { return typeof this; } +Number.prototype.type = TypeOfThis; +String.prototype.type = TypeOfThis; +Boolean.prototype.type = TypeOfThis; +testOne(2.3, 'type', 'object'); +testOne('x', 'type', 'object'); +testOne(true, 'type', 'object'); diff --git a/js/src/jit-test/tests/basic/bug688939.js b/js/src/jit-test/tests/basic/bug688939.js new file mode 100644 index 000000000..c2bf473a7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug688939.js @@ -0,0 +1,4 @@ +gczeal(2); +string="" +for (var i = 0; i < 100; i++ ) + hex=newGlobal('same-compartment'); diff --git a/js/src/jit-test/tests/basic/bug689916-regexp.js b/js/src/jit-test/tests/basic/bug689916-regexp.js new file mode 100644 index 000000000..620b302eb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug689916-regexp.js @@ -0,0 +1,4 @@ +/* should not crash on SPARC */ +var http_string = 'https://easylist-downloads.adblockplus.org/easylist.txt'; +var regexp = /^[\w\-]+:\/+(?!\/)(?:[^.\/]+\.)*?reports\.adblockplus\.org(?:[\x00-\x24\x26-\x2C\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x80]|$)/i; +assertEq(http_string.match(regexp), null); diff --git a/js/src/jit-test/tests/basic/bug690292.js b/js/src/jit-test/tests/basic/bug690292.js new file mode 100644 index 000000000..43ab56dd7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug690292.js @@ -0,0 +1,12 @@ + +done = false; +try { + function x() {} + print(this.watch("d", Object.create)) + var d = {} +} catch (e) {} +try { + eval("d = ''") + done = true; +} catch (e) {} +assertEq(done, false); diff --git a/js/src/jit-test/tests/basic/bug690732.js b/js/src/jit-test/tests/basic/bug690732.js new file mode 100644 index 000000000..bfcb72891 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug690732.js @@ -0,0 +1,4 @@ + +var o4 = Object.freeze({ + set: function(summary) {} +}); diff --git a/js/src/jit-test/tests/basic/bug691797-regexp-1.js b/js/src/jit-test/tests/basic/bug691797-regexp-1.js new file mode 100644 index 000000000..b78c0cb06 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug691797-regexp-1.js @@ -0,0 +1,4 @@ +var re = /.*star.*/i; +var str = "The Shawshank Redemption (1994)"; +for (var k = 0; k < 100; k++) + assertEq(false, re.test(str)); diff --git a/js/src/jit-test/tests/basic/bug691797-regexp-2.js b/js/src/jit-test/tests/basic/bug691797-regexp-2.js new file mode 100644 index 000000000..a8c0c4486 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug691797-regexp-2.js @@ -0,0 +1,6 @@ +var re = /.*(a\w).*/i; +var str = "abccccccad"; +for (var k = 0; k < 100; k++) { + re.test(str); + assertEq('ad', RegExp['$1']); +} diff --git a/js/src/jit-test/tests/basic/bug695922-syntax.js b/js/src/jit-test/tests/basic/bug695922-syntax.js new file mode 100644 index 000000000..599888080 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug695922-syntax.js @@ -0,0 +1,2 @@ +load(libdir + "asserts.js"); +assertThrowsInstanceOf(function () { eval("({p:"); }, SyntaxError); // don't crash diff --git a/js/src/jit-test/tests/basic/bug696748.js b/js/src/jit-test/tests/basic/bug696748.js new file mode 100644 index 000000000..fe171f976 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug696748.js @@ -0,0 +1,16 @@ +try { +this.watch("b", "".substring); +} catch(exc1) {} +eval("\ +var URI = '';\ +test();\ +function test() {\ + URI += '<zcti application=\"xxxx_demo\">';\ + URI += '<pstn_data>';\ + URI += '<dnis>877-485-xxxx</dnis>';\ + URI += '</pstn_data>';\ + URI >>= '<keyvalue key=\"name\" value=\"xxx\"/>';\ + URI += '<keyvalue key=\"phone\" value=\"6509309000\"/>';\ +}\ +test();\ +"); diff --git a/js/src/jit-test/tests/basic/bug699166.js b/js/src/jit-test/tests/basic/bug699166.js new file mode 100644 index 000000000..ac4c89eb0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug699166.js @@ -0,0 +1,7 @@ +a = "".__proto__ +b = uneval().__proto__ +for (var i = 0; i < 2; i++) { + a.__defineSetter__("valueOf", function() {}) + a + "" + delete b.valueOf +} diff --git a/js/src/jit-test/tests/basic/bug700300.js b/js/src/jit-test/tests/basic/bug700300.js new file mode 100644 index 000000000..ccee3ecfd --- /dev/null +++ b/js/src/jit-test/tests/basic/bug700300.js @@ -0,0 +1,4 @@ +for (let j = 0; j < (20); ++(__lookupSetter__)) { + function g() { j; } + j++; +} diff --git a/js/src/jit-test/tests/basic/bug700501.js b/js/src/jit-test/tests/basic/bug700501.js new file mode 100644 index 000000000..1f4426cb6 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug700501.js @@ -0,0 +1,12 @@ +Function.prototype.__proto__["p"] = 3 +c = [].__proto__ +c[5] = 3 +gc() +Function("\ + {\ + function f(d) {}\ + for each(let z in[0]) {\ + f(z)\ + }\ + }\ +")() diff --git a/js/src/jit-test/tests/basic/bug702426-regexp-gc.js b/js/src/jit-test/tests/basic/bug702426-regexp-gc.js new file mode 100644 index 000000000..206e2fd95 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug702426-regexp-gc.js @@ -0,0 +1,5 @@ +function g(code) { + eval("(function(){" + code + "})")() +} +g("evalcx(\"(/a/g,function(){})\")"); +g("'a'.replace(/a/g,gc)") diff --git a/js/src/jit-test/tests/basic/bug702572.js b/js/src/jit-test/tests/basic/bug702572.js new file mode 100644 index 000000000..50595d09e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug702572.js @@ -0,0 +1,10 @@ +eval("function f() { function g() {} return g; }"); +assertEq(f().prototype !== f().prototype, true); + +function f1() { + function g1() { + function h1() { return h1; } + } + return g1; +} +assertEq(f1().prototype !== f1().prototype, true); diff --git a/js/src/jit-test/tests/basic/bug703157.js b/js/src/jit-test/tests/basic/bug703157.js new file mode 100644 index 000000000..2acdd92eb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug703157.js @@ -0,0 +1,36 @@ +// Define a test object +var test = {x:1,y:2}; + +// Put the object into dictionary mode by deleting +// a property that was not the last one added. +delete test.x; + +// Define a an accessor property with a setter that +// itself calls Object.defineProperty +Object.defineProperty(test, "foo", { + get: function() { return 1; }, + set: function(v) { + Object.defineProperty(this, "foo", { value: v }); + // Prints the correct object descriptor + assertEq(this.foo, 33); + }, + configurable: true +}); + +// Add another property, so generateOwnShape does not replace the foo property. +test.other = 0; + +// This line prints 1, as expected +assertEq(test.foo, 1); + +// Now set the property. This calls the setter method above. +// And the setter method prints the expected value and property descriptor. +test.foo = 33; + +// Finally read the newly set value. +assertEq(test.foo, 33); + +// Check that enumeration order is correct. +var arr = []; +for (var x in test) arr.push(x); +assertEq("" + arr, "y,other"); diff --git a/js/src/jit-test/tests/basic/bug703544.js b/js/src/jit-test/tests/basic/bug703544.js new file mode 100644 index 000000000..87d1a1b0d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug703544.js @@ -0,0 +1,7 @@ +gczeal(4); +function testInterpreterReentry7() { + var arr = [0, 1, 2, 3, 4]; + for (var i = (1); i < 5; i++) + arr[i] = "grue"; +} +testInterpreterReentry7(); diff --git a/js/src/jit-test/tests/basic/bug703818.js b/js/src/jit-test/tests/basic/bug703818.js new file mode 100644 index 000000000..9d844986a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug703818.js @@ -0,0 +1,3 @@ +Object.defineProperty(Array.prototype, "toString", { + enumerable: true +}) diff --git a/js/src/jit-test/tests/basic/bug704134.js b/js/src/jit-test/tests/basic/bug704134.js new file mode 100644 index 000000000..947a0b13b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug704134.js @@ -0,0 +1,12 @@ +function f(s) { + eval(s); + return function() { + with({}) {}; + return b; + }; +} +var b = 1; +var g1 = f(""); +var g2 = f("var b = 2;"); +g1(''); +assertEq(g2(''), 2); diff --git a/js/src/jit-test/tests/basic/bug704795.js b/js/src/jit-test/tests/basic/bug704795.js new file mode 100644 index 000000000..d39b6915c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug704795.js @@ -0,0 +1,13 @@ +Function("\ + gczeal(4,false);\ + function f(){\ + \"use strict\";\ + this.x = Object\ + }\ + for each(y in[0,0]){\ + try{\ + new f\ + }\ + catch(e){}\ + }\ +")()
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug705895-1.js b/js/src/jit-test/tests/basic/bug705895-1.js new file mode 100644 index 000000000..c2beca9f6 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug705895-1.js @@ -0,0 +1,16 @@ +load(libdir + "immutable-prototype.js"); + +c = Number.prototype; +function f(o) { + if (globalPrototypeChainIsMutable() || o !== Object.prototype) + o.__proto__ = null + for (x in o) {} +} +for (i = 0; i < 9; i++) { + f(c) + if (globalPrototypeChainIsMutable()) + Object.prototype.__proto__ = c; + for (x in Object.prototype) + continue; + f(Math.__proto__); +} diff --git a/js/src/jit-test/tests/basic/bug705895-2.js b/js/src/jit-test/tests/basic/bug705895-2.js new file mode 100644 index 000000000..445efb56a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug705895-2.js @@ -0,0 +1,13 @@ +// |jit-test| error: TypeError +function f(o) { + for (j = 0; j < 9; j++) { + if (j) { + o.__proto__ = null + } + for (v in o) {} + } +} +for (i = 0; i < 9; i++) { + (new Boolean).__proto__.__defineGetter__("toString", function() {}) + f(Boolean.prototype) +} diff --git a/js/src/jit-test/tests/basic/bug706316.js b/js/src/jit-test/tests/basic/bug706316.js new file mode 100644 index 000000000..d34aa79f7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug706316.js @@ -0,0 +1,11 @@ +// |jit-test| error: ReferenceError
+gczeal(4);
+function setprop() {
+ var obj = { a:({ } ) };
+ var obj2 = { b:-1, a:-1 };
+ for (var i = 0; i < 20; (length(resultsY.global0, 42))) {
+ obj2.b = obj.a = i;
+ }
+}
+assertEq(setprop(), "19,-1,19");
+
diff --git a/js/src/jit-test/tests/basic/bug706795.js b/js/src/jit-test/tests/basic/bug706795.js new file mode 100644 index 000000000..57d1a41a4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug706795.js @@ -0,0 +1,7 @@ +executed = false; +Object.defineProperty(Object.prototype, 'x', { set: function() { executed = true; } }); +function A() { + this.x = 12; +} +new A(); +assertEq(executed, true); diff --git a/js/src/jit-test/tests/basic/bug706808.js b/js/src/jit-test/tests/basic/bug706808.js new file mode 100644 index 000000000..8bbba9d98 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug706808.js @@ -0,0 +1,5 @@ + +Object.defineProperty(Object.prototype, "a", {}); +function t2(b) { this.a = b; } +var x = new t2(3); +assertEq(x.a, undefined); diff --git a/js/src/jit-test/tests/basic/bug707750.js b/js/src/jit-test/tests/basic/bug707750.js new file mode 100644 index 000000000..56df1043c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug707750.js @@ -0,0 +1,9 @@ +// |jit-test| error: ReferenceError +var lfcode = new Array(); +lfcode.push("gczeal(4);"); +lfcode.push('print(BUGNUMBER + ": " + (W -- ));'); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + eval(file); +} + diff --git a/js/src/jit-test/tests/basic/bug708228.js b/js/src/jit-test/tests/basic/bug708228.js new file mode 100644 index 000000000..4a627fd1f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug708228.js @@ -0,0 +1,5 @@ +// |jit-test| error: TypeError +gczeal(4); +var g_rx = /(?:)/; +(3).replace(g_rx.compile("test", "g"), {}); + diff --git a/js/src/jit-test/tests/basic/bug708819.js b/js/src/jit-test/tests/basic/bug708819.js new file mode 100644 index 000000000..8f3f0a552 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug708819.js @@ -0,0 +1,12 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +try { + var e = new Error(); + e.name = e; + "" + e; +} catch (e) { + assertEq(e.message, 'too much recursion'); +} diff --git a/js/src/jit-test/tests/basic/bug709634.js b/js/src/jit-test/tests/basic/bug709634.js new file mode 100644 index 000000000..57de9720a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug709634.js @@ -0,0 +1,6 @@ + +Function.prototype.toString = function () f(this, true); +function f(obj) { + f.caller.p +} +decodeURI + 3; diff --git a/js/src/jit-test/tests/basic/bug710947.js b/js/src/jit-test/tests/basic/bug710947.js new file mode 100644 index 000000000..278288020 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug710947.js @@ -0,0 +1,8 @@ +// |jit-test| allow-oom; +function startTest() { + if (typeof document != "object" + || !document.location.href.match(/jsreftest.html/)) {} +}; +gczeal(4); +startTest(); +new ArrayBuffer( 8192 ); diff --git a/js/src/jit-test/tests/basic/bug713226.js b/js/src/jit-test/tests/basic/bug713226.js new file mode 100644 index 000000000..3ae991f43 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug713226.js @@ -0,0 +1,20 @@ +// |jit-test| +gczeal(4); +var optionNames = options().split(','); + for (var i = 0; i < optionNames.length; i++) + var optionName = optionNames[i]; +evaluate("\ +function addDebug(g, id) {\ + var debuggerGlobal = newGlobal();\ + debuggerGlobal.debuggee = g;\ + debuggerGlobal.id = id;\ + debuggerGlobal.print = function (s) { (g) += s; };\ + debuggerGlobal.eval('var dbg = new Debugger(debuggee);dbg.onDebuggerStatement = function () { print(id); debugger; };');\ + return debuggerGlobal;\ +}\ +var base = newGlobal();\ +var top = base;\ +for (var i = 0; i < 8; i++ )\ + top = addDebug(top, i);\ +base.eval('debugger;');\ +"); diff --git a/js/src/jit-test/tests/basic/bug714614.js b/js/src/jit-test/tests/basic/bug714614.js new file mode 100644 index 000000000..fd01dce56 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug714614.js @@ -0,0 +1,5 @@ +function testForVarInWith(foo, foo) { + return eval("with ({}) { for (var x = 0; x < 5; x++); } (function() { return delete x; })"); +} +f = testForVarInWith()(); + diff --git a/js/src/jit-test/tests/basic/bug714616.js b/js/src/jit-test/tests/basic/bug714616.js new file mode 100644 index 000000000..706594d05 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug714616.js @@ -0,0 +1,8 @@ +array1 = new Array(); +size = 10; +for (i = 0; i < size; (array1.length)++) +{ + array1.push(array1.shift()); + ++i +} + diff --git a/js/src/jit-test/tests/basic/bug716013.js b/js/src/jit-test/tests/basic/bug716013.js new file mode 100644 index 000000000..b6ff2f991 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug716013.js @@ -0,0 +1,4 @@ +f = (function() { + for (x in [arguments, arguments]) yield(gczeal(4, function(){})) +}) +for (i in f()) {} diff --git a/js/src/jit-test/tests/basic/bug718852.js b/js/src/jit-test/tests/basic/bug718852.js new file mode 100644 index 000000000..845b84cf3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug718852.js @@ -0,0 +1,15 @@ +// |jit-test| error:ReferenceError + +function fannkuch(n) { + var perm1 = Array(n); + while (true) { + if (check < 30){ + for(var i=0; i<n; i++) s += (perm1[i]+1).toString(); + while (i < r) { + var j = this.abstract + 1; + perm1[i] = perm1[j]; + } + } + } +} +fannkuch(8); diff --git a/js/src/jit-test/tests/basic/bug719750.js b/js/src/jit-test/tests/basic/bug719750.js new file mode 100644 index 000000000..a90535371 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug719750.js @@ -0,0 +1,12 @@ +function f( ) { + var [ [x], e ] = ["*", "/", "%"]; + function h() { + for (var i = 0; i < 5; ++i) { + x = i * 2; + } + } + h(); + assertEq(x, 8); +} +f(); + diff --git a/js/src/jit-test/tests/basic/bug720070.js b/js/src/jit-test/tests/basic/bug720070.js new file mode 100644 index 000000000..859b0b8af --- /dev/null +++ b/js/src/jit-test/tests/basic/bug720070.js @@ -0,0 +1,6 @@ +var bytes = [0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; // big-endian +bytes.reverse(); // if testing on little-endian +var result = new Float64Array(new Uint8Array(bytes).buffer)[0]; + +// Check that this doesn't crash +isNaN(result + 0); diff --git a/js/src/jit-test/tests/basic/bug720675.js b/js/src/jit-test/tests/basic/bug720675.js new file mode 100644 index 000000000..dd664d508 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug720675.js @@ -0,0 +1,9 @@ +// |jit-test| allow-oom; + +gcparam("maxBytes", gcparam("gcBytes") + 4*1024); +arr = [1e0, 5e1, 9e19, 0.1e20, 1.3e20, 1e20, 9e20, 9.99e20, + 0.1e21, 1e21, 1e21+65537, 1e21+65536, 1e21-65536, 1]; +for (var i = 0; i < 4000; i++) { + arr.push(1e19 + i*1e19); +} +for (var i in arr) {} diff --git a/js/src/jit-test/tests/basic/bug722028.js b/js/src/jit-test/tests/basic/bug722028.js new file mode 100644 index 000000000..837e34460 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug722028.js @@ -0,0 +1,13 @@ + +gczeal(4); +var BUGNUMBER = 668024; +var summary = +print(BUGNUMBER + ": " + summary); +var arr = [0, 1, 2, 3, 4, 5, , 7]; +var seen = []; +for (var p in arr) { + if (seen.indexOf(unescape) >= 0) {} + arr.splice(2, 3); + seen.push(p); +} + diff --git a/js/src/jit-test/tests/basic/bug727223.js b/js/src/jit-test/tests/basic/bug727223.js new file mode 100644 index 000000000..5011c134d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug727223.js @@ -0,0 +1,15 @@ +try { + mjitChunkLimit(1) + function x() {} +} catch (e) {} +(function() { + for (let c in [0, 0, 0]) { + let c + for (y in decodeURI()) { + (function() { + c + }()) + } + } +}()) + diff --git a/js/src/jit-test/tests/basic/bug727921.js b/js/src/jit-test/tests/basic/bug727921.js new file mode 100644 index 000000000..14a4b689f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug727921.js @@ -0,0 +1,11 @@ +(function() { + { + let d; + yield + } +})() +eval("\ + (function(){\ + schedulegc(5), 'a'.replace(/a/,function(){yield})\ + })\ +")() diff --git a/js/src/jit-test/tests/basic/bug728086.js b/js/src/jit-test/tests/basic/bug728086.js new file mode 100644 index 000000000..39692c670 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug728086.js @@ -0,0 +1,65 @@ +var expected = ''; +function TestCase(n, d, e, a) {} +function reportFailure (msg) {} +function toPrinted(value) { + value = value.replace(/\\\n/g, 'NL') + .replace(/[^\x20-\x7E]+/g, escapeString); +} +function escapeString (str) {} +function reportCompare (expected, actual, description) { + var expected_t = typeof expected; + var actual_t = typeof actual; + var output = ""; + var testcase = new TestCase("unknown-test-name", description, expected, actual); + reportFailure (description + " : " + output); +} +function enterFunc (funcName) + callStack.push(funcName); + try { + reportCompare(expectCompile, actualCompile, + summary + ': compile actual'); + } catch(ex) { } +var lfcode = new Array(); +lfcode.push("gczeal(2);\ +enterFunc ('test');\ +"); +lfcode.push("{}"); +lfcode.push("noexist.js"); +lfcode.push("var BUGNUMBER = 305064;\ +var summary = 'Tests the trim, trimRight and trimLeft methods';\ +var trimMethods = ['trim', 'trimLeft', 'trimRight'];\ +var whitespace = [\ + {s : '\\u0009', t : 'HORIZONTAL TAB'},\ + {s : '\\u200A', t : 'HAIR SPACE'},\ + ];\ +for (var j = 0; j < trimMethods.length; ++j)\ + var method = trimMethods[j];\ + reportCompare(true, true, 'Test skipped. String.prototype.' + method + ' is not supported');\ + str = '';\ + for (var i = 0; i < whitespace.length; ++i) {\ + var v = whitespace[i].s;\ + var t = (summary)[i].t;\ + v = v + v + v;\ + print('Test ' + method + ' with with leading whitespace. : ' + t);\ + actual = str[method]();\ + reportCompare(expected, actual, t + ':' + '\"' + toPrinted(str) + '\".' + method + '()');\ + str = v + 'a' + v;\ +}\ +"); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + if (file == "evaluate") { + } else { + loadFile(file); + } +} +function loadFile(lfVarx) { + try { + if (lfVarx.substr(-3) == ".js") { + switch (lfRunTypeId) { + } + } else { + eval(lfVarx); + } + } catch (lfVare) { } +} diff --git a/js/src/jit-test/tests/basic/bug728190.js b/js/src/jit-test/tests/basic/bug728190.js new file mode 100644 index 000000000..0e2f29726 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug728190.js @@ -0,0 +1,24 @@ +// |jit-test| slow; + +function TestCase(n, d, e, a) {} +var lfcode = new Array(); +lfcode.push(""); +lfcode.push("\ + var summary = 'foo';\ + test();\ + function test() {\ + test(\"TEST-UNEXPECTED-FAIL | TestPerf | \" + summary);\ + }\ +"); +lfcode.push("gczeal(2);"); +lfcode.push("\ + new TestCase(TestFunction_3( \"P\", \"A\", \"S\", \"S\" ) +\"\");\ + new TestCase(TestFunction_4( \"F\", \"A\", (\"length\"), \"L\" ) +\"\");\ + function TestFunction_3( a, b, c, d, e ) {\ + TestFunction_3(arguments);\ + }\ +"); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + try { evaluate(file); } catch (lfVare) {} +} diff --git a/js/src/jit-test/tests/basic/bug728609.js b/js/src/jit-test/tests/basic/bug728609.js new file mode 100644 index 000000000..0d84c2537 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug728609.js @@ -0,0 +1,23 @@ +var lfcode = new Array(); +lfcode.push("\ +test();\ +function test() {\ + function removeAllProperties(o) {\ + bar() = thaw, patterns;\ + }\ + var o = {};\ + o.first = { toSource: function() { removeAllProperties(o); } };\ + return o.toSource();\ +}\ +"); +lfcode.push("test();"); +gczeal(4); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file); +} +function loadFile(lfVarx) { + try { + evaluate(lfVarx); + } catch (lfVare) { } +} diff --git a/js/src/jit-test/tests/basic/bug730085.js b/js/src/jit-test/tests/basic/bug730085.js new file mode 100644 index 000000000..f2f6cb699 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug730085.js @@ -0,0 +1,6 @@ +load(libdir + "asserts.js"); +var calledToString = false; +assertThrowsInstanceOf(function () { Object.prototype.hasOwnProperty.call(null, + {toString: function () { calledToString = true; }}); }, + TypeError); +assertEq(calledToString, true); diff --git a/js/src/jit-test/tests/basic/bug730888.js b/js/src/jit-test/tests/basic/bug730888.js new file mode 100644 index 000000000..5d328d6aa --- /dev/null +++ b/js/src/jit-test/tests/basic/bug730888.js @@ -0,0 +1,14 @@ + +(function() { + for (var i = 0; i < 64; ++i) { + var name; + switch (this) { + case 0: name = 'firstAttr'; break; + case 1: name = 'secondAttr'; + case 2: name = 'thirdAttr'; break; + } + switch (name) { + case 'firstAttr': assertEq(result, 'value'); break; + } + } +})(); diff --git a/js/src/jit-test/tests/basic/bug731642.js b/js/src/jit-test/tests/basic/bug731642.js new file mode 100644 index 000000000..5459dfa65 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug731642.js @@ -0,0 +1,2 @@ +Object.defineProperty(Object.prototype, 1, {get: function() { this.foo++; return 23 }}); +assertEq([1,,].pop(), 23); diff --git a/js/src/jit-test/tests/basic/bug732693.js b/js/src/jit-test/tests/basic/bug732693.js new file mode 100644 index 000000000..d82da1e24 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug732693.js @@ -0,0 +1,10 @@ +var res = 0; +var o = {__proto__: function() { res++; }}; + +function f() { + for (var i=0; i<70; i++) { + o.__proto__(); + } +} +f(); +assertEq(res, 70); diff --git a/js/src/jit-test/tests/basic/bug737384.js b/js/src/jit-test/tests/basic/bug737384.js new file mode 100644 index 000000000..6ec87ec78 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug737384.js @@ -0,0 +1,10 @@ +a = evalcx(''); +for (var i = 0; i < 1000; i++) { + a[i] = i; +} +function foo(x) { + for (var i in x) + var summary = "Basic support for iterable objects and for-in"; +} +schedulegc(1234); +foo(a); diff --git a/js/src/jit-test/tests/basic/bug738841.js b/js/src/jit-test/tests/basic/bug738841.js new file mode 100644 index 000000000..9a81341aa --- /dev/null +++ b/js/src/jit-test/tests/basic/bug738841.js @@ -0,0 +1,49 @@ +try { + for (let z = 0; z < 1; ++evalcx("[]", newGlobal())) {} +} catch (e) {} +try { + for (y in [schedulegc(58)]) { + b + } +} catch (e) {} +try { + e +} catch (e) {} +try { + (function() { + h + }()) +} catch (e) {} +try { + (function() { + this.m.f = function() {} + }()) +} catch (e) {} +try { + t() +} catch (e) {} +try { + p +} catch (e) {} +try { + gc() + p +} catch (e) {} +try { + (function() { + for (var v of m) {} + }()) +} catch (e) {} +try { + m +} catch (e) {} +try { + var f = function() { + { + print(new function(q)("", s)) + let u + } + }; + dis(f); + f(); +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug738846.js b/js/src/jit-test/tests/basic/bug738846.js new file mode 100644 index 000000000..32f973bdc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug738846.js @@ -0,0 +1,49 @@ +try { + (function() { + var m + new ArrayBuffer() + var _ = t + var _2 = [] + }()) +} catch (e) {} +try { + for (y in [schedulegc(58)]) { + m + } +} catch (e) {} +try { + (function() { + true + }()) +} catch (e) {} +try { + (function() { + s + }()) +} catch (e) {} +try { + e +} catch (e) {} +try { + "" () +} catch (e) {} +try { + gc() + s +} catch (e) {} +try { + (function() { + for (v of m) {} + }()) +} catch (e) {} +try { + t +} catch (e) {} +try { + (function() { + "use strict"; + print(new function() { + r + }(this)) + }()) +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug739694-1.js b/js/src/jit-test/tests/basic/bug739694-1.js new file mode 100644 index 000000000..bac7e49c9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug739694-1.js @@ -0,0 +1,12 @@ +function newFunc(x) { new Function(x)(); }; try { newFunc("\ +var g = newGlobal();\ +g.h = function () {\ + names = foo.blaaaaaaaaaaaaah().environment.names();\ +};\ +g.eval('var obj = {a: 1};' + \"with ({a: 1, '0xcafe': 2, ' ': 3, '': 4, '0': 5}) h();\");\ +"); +} catch(exc1) {} +function newFunc(x) { new Function(x)(); }; newFunc("\ +gczeal(2);\ + a=b=c=d=0; this.__defineGetter__('g', gc); for each (y in this);\ +"); diff --git a/js/src/jit-test/tests/basic/bug739694-2.js b/js/src/jit-test/tests/basic/bug739694-2.js new file mode 100644 index 000000000..41cc4b6e4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug739694-2.js @@ -0,0 +1,8 @@ +try { + ({ + f: evalcx("evalcx(\"e\",newGlobal())", + newGlobal()) + }) +} catch (e) {} +gc() +gc() diff --git a/js/src/jit-test/tests/basic/bug743961.js b/js/src/jit-test/tests/basic/bug743961.js new file mode 100644 index 000000000..6c1f253d4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug743961.js @@ -0,0 +1,2 @@ +var n = (evalcx('lazy')); +try { var nbuf = serialize(n); } catch(e) {} // Don't crash diff --git a/js/src/jit-test/tests/basic/bug744285.js b/js/src/jit-test/tests/basic/bug744285.js new file mode 100644 index 000000000..f5a9e4f36 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug744285.js @@ -0,0 +1,71 @@ +// |jit-test| error: TypeError; +var TZ_DIFF = getTimeZoneDiff(); +var now = new Date; +var TZ_DIFF = getTimeZoneDiff(); +var now = new Date; +var MAX_UNIX_TIMET = 2145859200; +var RANGE_EXPANSION_AMOUNT = 60; +function tzOffsetFromUnixTimestamp(timestamp) { + new Date + } +function clearDSTOffsetCache(undesiredTimestamp) { + tzOffsetFromUnixTimestamp() + tzOffsetFromUnixTimestamp() + tzOffsetFromUnixTimestamp() + tzOffsetFromUnixTimestamp() + tzOffsetFromUnixTimestamp() + } +function computeCanonicalTZOffset(timestamp) { + clearDSTOffsetCache() + tzOffsetFromUnixTimestamp() + } +var TEST_TIMESTAMPS_SECONDS = [ + 0, + RANGE_EXPANSION_AMOUNT, + MAX_UNIX_TIMET, + ]; +var TEST_TIMESTAMPS = TEST_TIMESTAMPS_SECONDS.map(function(v) { }); +var CORRECT_TZOFFSETS = TEST_TIMESTAMPS.map(computeCanonicalTZOffset); +var TZ_DIFF = getTimeZoneDiff(); +var now = new Date; +var TZ_DIFF = getTimeZoneDiff(); +var now = new Date;function getTimeZoneDiff() { + new Date/60 +} +function check(b, desc) { + function classOf(obj) { + return Object.prototype.toString.call(obj); + } + function ownProperties(obj) { + return Object.getOwnPropertyNames(obj). + map(function (p) { return [p, Object.getOwnPropertyDescriptor(obj, p)]; }); + } + function isCloneable(pair) { } + function assertIsCloneOf(a, b, path) { + ca = classOf(a) + assertEq(ca, classOf(b), path) + assertEq(Object.getPrototypeOf(a), ca == "[object Object]" ? Object.prototype : Array.prototype, path) + pb = ownProperties(b).filter(isCloneable) + pa = ownProperties(a) + function byName(a, b) 0 + byName + (pa.length, pb.length, "should see the same number of properties " + path) + for (var i = 0; i < pa.length; i++) { + gczeal(4) + } + } + banner = desc || uneval() + a = deserialize(serialize(b)) + var queue = [[a, b, banner]]; + while (queue.length) { + var triple = queue.shift(); + assertIsCloneOf(triple[0], triple[1], triple[2]) + } +} +check({x: 0.7, p: "forty-two", y: null, z: undefined}); +check(Object.prototype); +b=[, , 2, 3]; +b.expando=true; +b[5]=5; +b[0]=0;b[4]=4; +check(b)([, , , , , , 6]) diff --git a/js/src/jit-test/tests/basic/bug744287.js b/js/src/jit-test/tests/basic/bug744287.js new file mode 100644 index 000000000..534b644e6 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug744287.js @@ -0,0 +1,6 @@ +function callbackfn(v) { + gczeal(4); + return arr[0] + (Uint8ClampedArray); +} +arr = [1,2,3,4,5]; +arr = arr.map(callbackfn); diff --git a/js/src/jit-test/tests/basic/bug744356.js b/js/src/jit-test/tests/basic/bug744356.js new file mode 100644 index 000000000..cba9dc3c8 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug744356.js @@ -0,0 +1,14 @@ +// |jit-test| error: ReferenceError; +gczeal(4); +function gen() { + var c = [1, "x"]; + try { + yield c; + } finally { + gc(); + } +} +var iter = gen(); +for (i in iter) { + (SECTION)(); +} diff --git a/js/src/jit-test/tests/basic/bug745360.js b/js/src/jit-test/tests/basic/bug745360.js new file mode 100644 index 000000000..7d17b722c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug745360.js @@ -0,0 +1,2 @@ +// |jit-test| error: TypeError +newGlobal().eval("eval.arguments") diff --git a/js/src/jit-test/tests/basic/bug749039.js b/js/src/jit-test/tests/basic/bug749039.js new file mode 100644 index 000000000..6461de777 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug749039.js @@ -0,0 +1,11 @@ +// |jit-test| error: ReferenceError; +gczeal(4); +try { jsTestDriverEnd(); } catch(exc1) {} +evaluate("\ +schedulegc(10);\ +for(var i=0; i<3; i++) {\ + var obj = { first: 'first', second: 'second' };\ + for (var elem in obj) {}\ + x.push(count);\ +}\ +"); diff --git a/js/src/jit-test/tests/basic/bug749620.js b/js/src/jit-test/tests/basic/bug749620.js new file mode 100644 index 000000000..75d11db36 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug749620.js @@ -0,0 +1,16 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var v = [0, 0x7fffffff]; +v.sort(); + +assertEq(v[0], 0); +assertEq(v[1], 0x7fffffff); + +v = [0x7fffffff, 0]; +v.sort(); + +assertEq(v[0], 0); +assertEq(v[1], 0x7fffffff); diff --git a/js/src/jit-test/tests/basic/bug750307.js b/js/src/jit-test/tests/basic/bug750307.js new file mode 100644 index 000000000..b60ad0894 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug750307.js @@ -0,0 +1,5 @@ +load(libdir + "asserts.js"); +var g = newGlobal(); +var a = g.RegExp("x"); +Object.defineProperty(a, "ignoreCase", {value: undefined}); +a.toString(); diff --git a/js/src/jit-test/tests/basic/bug751139.js b/js/src/jit-test/tests/basic/bug751139.js new file mode 100644 index 000000000..a889ab623 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug751139.js @@ -0,0 +1,7 @@ + +load(libdir + "asserts.js"); + +function C(a, b) {} +var f = C.bind(null, 2); +var that = this; +assertThrowsInstanceOf(function () { g = clone(f, that)}, TypeError); diff --git a/js/src/jit-test/tests/basic/bug754150.js b/js/src/jit-test/tests/basic/bug754150.js new file mode 100644 index 000000000..c66c16dbc --- /dev/null +++ b/js/src/jit-test/tests/basic/bug754150.js @@ -0,0 +1,49 @@ +// |jit-test| error: TypeError; + +// String.prototype.replace takes too long time with gczeal(4) if +// --no-baseline --no-ion options. +if (typeof inJit == "function" && typeof inJit() == "string") { + assertEq(inJit(), "Baseline is disabled."); + // This test expects TypeError. + toPrinted(null); +} + +function printStatus (msg) {} +function toPrinted(value) { + value = value.replace(/\\n/g, 'NL') +} +function reportCompare (expected, actual, description) { + printStatus ("Expected value '" + toPrinted(expected) + "' matched actual value '" + toPrinted(actual) + "'"); +} +var UBound = 0; +var statusitems = []; +var actual = ''; +var actualvalues = []; +var expect= ''; +var expectedvalues = []; +testThis('x()'); +testThis('"abc"()'); +testThis('x()'); +testThis('Date(12345)()'); +testThis('x()'); +testThis('1()'); +testThis('x()'); +testThis('void(0)()'); +testThis('x()'); +testThis('[1,2,3,4,5](1)'); +gczeal(4); +testThis('x(1)'); +checkThis('(function (y) {return y+1;})("abc")'); +checkThis('f("abc")'); +function testThis(sInvalidSyntax) { + expectedvalues[UBound] = expect; + actualvalues[UBound] = actual; + UBound++; +} +function checkThis(sValidSyntax) { + for (var i=0; i<UBound; i++) + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); +} +var actualvalues = []; +for (var i=0; i<UBound; i++) + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); diff --git a/js/src/jit-test/tests/basic/bug754242.js b/js/src/jit-test/tests/basic/bug754242.js new file mode 100644 index 000000000..58d4e0ee0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug754242.js @@ -0,0 +1,7 @@ +var g1 = newGlobal(); +schedulegc(g1); +gcslice(1); +function testEq(b) { + var a = deserialize(serialize(b)); +} +testEq(Array(1024).join(Array(1024).join((false)))); diff --git a/js/src/jit-test/tests/basic/bug756851.js b/js/src/jit-test/tests/basic/bug756851.js new file mode 100644 index 000000000..d45ace661 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug756851.js @@ -0,0 +1,10 @@ +o0 = {}; +g = new ArrayBuffer; +g2 = this; +v = g2.o0.t; +o0 = Object; +var y = { + x: gc(gcPreserveCode()) +} +y.toString(); +for (z = 0; z < 100; z++) {} diff --git a/js/src/jit-test/tests/basic/bug757199.js b/js/src/jit-test/tests/basic/bug757199.js new file mode 100644 index 000000000..73adacd8e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug757199.js @@ -0,0 +1,23 @@ +function ctor() +{ + this.a = 1; + this.b = 2; +} +function f2(o) +{ + o.c = 12; +} +function f() +{ + var x = new ctor(); + verifyprebarriers(); + f2(x); + verifyprebarriers(); +} +f(); +f(); +var o = {}; +for (var i=0; i<1000; i++) + o['a'+i] = 3; +f(); +f(); diff --git a/js/src/jit-test/tests/basic/bug757431.js b/js/src/jit-test/tests/basic/bug757431.js new file mode 100644 index 000000000..326f31efd --- /dev/null +++ b/js/src/jit-test/tests/basic/bug757431.js @@ -0,0 +1,18 @@ + +function setterFunction(v) { called = true; } +function getterFunction(v) { return "getter"; } +Object.defineProperty(Array.prototype, 1,{ + get: getterFunction, + set: setterFunction +}); +gczeal(4); +var N = 350; +var source = "".concat( + repeat_str("try { f(); } finally {\n", N), + repeat_str("}", N)); +function repeat_str(str, repeat_count) { + var arr = new Array(--repeat_count); + while (repeat_count != 0) + arr[--repeat_count] = str; + return str.concat.apply(str, arr); +} diff --git a/js/src/jit-test/tests/basic/bug763440.js b/js/src/jit-test/tests/basic/bug763440.js new file mode 100644 index 000000000..babc4f5ab --- /dev/null +++ b/js/src/jit-test/tests/basic/bug763440.js @@ -0,0 +1,26 @@ +load(libdir + "immutable-prototype.js"); + +var summary = ''; +var actual = ''; +gcPreserveCode() +function TestCase(n, d, e, a) { + this.name=n; +} +function reportCompare (expected, actual, description) { + new TestCase +} +reportCompare(true, eval++, "Dummy description."); +var p = new Proxy({}, { + has : function(id) {}, + set : function() {} +}); +if (globalPrototypeChainIsMutable()) + Object.prototype.__proto__ = p; +new TestCase; +var expect = ''; +reportCompare(expect, actual, summary); +gczeal(4); +try { + evalcx("."); +} catch (e) {} +reportCompare(expect, actual, summary); diff --git a/js/src/jit-test/tests/basic/bug767074.js b/js/src/jit-test/tests/basic/bug767074.js new file mode 100644 index 000000000..76704c657 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug767074.js @@ -0,0 +1,11 @@ +var callStack = new Array(); +function exitFunc (funcName) { + var lastFunc = callStack.pop(); +} +gczeal(4); +var sb = evalcx(''); +sb.parent = this; +this.f = function name(outer) { + return (exitFunc ('test')); +} +evalcx('this.f = parent.f; var s = ""; for (i = 0; i < 10; ++i) s += f(true); s', sb); diff --git a/js/src/jit-test/tests/basic/bug767234.js b/js/src/jit-test/tests/basic/bug767234.js new file mode 100644 index 000000000..0c073d111 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug767234.js @@ -0,0 +1,14 @@ +function gen() +{ + var local = new Date(); + yield 1; + local = null; + gc(); + gcslice(0); // Start IGC, but don't mark anything. + yield 2; +} + +var g = gen(); +g.next(); +g.next(); +gcslice(); diff --git a/js/src/jit-test/tests/basic/bug767273.js b/js/src/jit-test/tests/basic/bug767273.js new file mode 100644 index 000000000..2d8e99d3c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug767273.js @@ -0,0 +1,7 @@ +var prox = new Proxy({}, { + getOwnPropertyDescriptor: function() { return undefined; }, + has: function() { return true; }, +}); + +// Don't crash. +newGlobal().__lookupSetter__.call(prox, "e"); diff --git a/js/src/jit-test/tests/basic/bug768732.js b/js/src/jit-test/tests/basic/bug768732.js new file mode 100644 index 000000000..5be491c69 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug768732.js @@ -0,0 +1,6 @@ +a = '' +b = [] +a = b.concat(a) +Object.defineProperty(a, 3, { + e: gczeal(4, 2) +}) diff --git a/js/src/jit-test/tests/basic/bug769433.js b/js/src/jit-test/tests/basic/bug769433.js new file mode 100644 index 000000000..3eefcaa5b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug769433.js @@ -0,0 +1,8 @@ + +function stringConvert() { + var a = Uint32Array.prototype; + for (var i = 0; i < 10; i++) { + a[0] = i; + } +} +stringConvert(); diff --git a/js/src/jit-test/tests/basic/bug770952.js b/js/src/jit-test/tests/basic/bug770952.js new file mode 100644 index 000000000..2a6efeeb7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug770952.js @@ -0,0 +1,7 @@ +// |jit-test| error: TypeError +load(libdir + "iteration.js"); + +eval("var x; typeof x") +Array.prototype[Symbol.iterator] = function () { for(y in x); }; +for (var v of ['a', 'b', 'c', 'd']) + s = v; diff --git a/js/src/jit-test/tests/basic/bug773153.js b/js/src/jit-test/tests/basic/bug773153.js new file mode 100644 index 000000000..6eacea853 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug773153.js @@ -0,0 +1,3 @@ +function f() { + "" < ""; +} diff --git a/js/src/jit-test/tests/basic/bug774859.js b/js/src/jit-test/tests/basic/bug774859.js new file mode 100644 index 000000000..b1d4255bd --- /dev/null +++ b/js/src/jit-test/tests/basic/bug774859.js @@ -0,0 +1,16 @@ +gczeal(4,1); +function g() +{ + try { + return []; + } catch (e) {} +} +function f() +{ + for (var i=0; i<2; i++) { + var o = {a: g(), + a: g()}; + print(i); + } +} +f(); diff --git a/js/src/jit-test/tests/basic/bug777776.js b/js/src/jit-test/tests/basic/bug777776.js new file mode 100644 index 000000000..fc0753ffe --- /dev/null +++ b/js/src/jit-test/tests/basic/bug777776.js @@ -0,0 +1,5 @@ +gczeal(9, 2) +for (a = 0; a < 4; ++a) { + b = + evaluate("/x/g"); +} diff --git a/js/src/jit-test/tests/basic/bug777992.js b/js/src/jit-test/tests/basic/bug777992.js new file mode 100644 index 000000000..c86f41ceb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug777992.js @@ -0,0 +1,9 @@ +verifyprebarriers() +x = [] +function z() {} +Object.defineProperty(x, 2, { + value: z +}) +gczeal(2, 2) +y = x.slice(2) +y.e = (function() {}) diff --git a/js/src/jit-test/tests/basic/bug781393.js b/js/src/jit-test/tests/basic/bug781393.js new file mode 100644 index 000000000..2559b6fa0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug781393.js @@ -0,0 +1,14 @@ +gczeal(4,1); +function check(o) +{ + print(o); + assertEq(o.b, 3); +} +function f() +{ + for (var i=0; i<3; i++) { + var o = {b: 3}; + check(o); + } +} +f(); diff --git a/js/src/jit-test/tests/basic/bug782337.js b/js/src/jit-test/tests/basic/bug782337.js new file mode 100644 index 000000000..6f956ae56 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug782337.js @@ -0,0 +1,15 @@ +gc(); + +function recur(n) +{ + if (n == 0) { + gcslice(); + gc(); + } else { + recur(n-1); + } + var obj = new Object(); +} + +gcslice(1); +recur(10); diff --git a/js/src/jit-test/tests/basic/bug783989.js b/js/src/jit-test/tests/basic/bug783989.js new file mode 100644 index 000000000..88a9b627c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug783989.js @@ -0,0 +1,2 @@ +// |jit-test| error: Error +wrapWithProto(0); diff --git a/js/src/jit-test/tests/basic/bug785094.js b/js/src/jit-test/tests/basic/bug785094.js new file mode 100644 index 000000000..7c30f834e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug785094.js @@ -0,0 +1,2 @@ +// |jit-test| --dump-bytecode +Function("for(let b; true; x) \nfalse"); diff --git a/js/src/jit-test/tests/basic/bug785175.js b/js/src/jit-test/tests/basic/bug785175.js new file mode 100644 index 000000000..f6a36fd9b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug785175.js @@ -0,0 +1,9 @@ +var str = ' '; +// Generate a 4MB string = 2^(20+2) +for (var i = 0; i < 22; i++) { + str = str + str; +} +str += 'var a = 1 + 1;'; + +// don't throw an exception even though the column numbers cannot be maintained +eval(str); diff --git a/js/src/jit-test/tests/basic/bug786114.js b/js/src/jit-test/tests/basic/bug786114.js new file mode 100644 index 000000000..718d0426c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug786114.js @@ -0,0 +1,32 @@ +let expected = 'o!o!o!'; +let actual = ''; + +// g is a function that needs an implicit |this| if called within a |with| +// statement. If we fail to provide that implicit |this|, it will append +// "[object global]" instead of "o!". +let o = { + g: function() { actual += this.toString(); }, + toString: function() { return "o!"; } +} + +// g's presence within the |with| is detected by simple tracking of |with|s +// during parsing. +with (o) { + (function() { g(); })(); +} + +// The eval() defeats the tracking of |with| during parsing. Instead, g's +// presence within the |with| is detected by looking at the scopeChain of the +// ParseContext. +with (o) { + eval("(function() { g(); })()"); +} + +// This is like the above case, but the knowledge of the |with| presence must +// be inherited by the inner function. This is the case that was missed in bug +// 786114. +with (o) { + eval("(function() { (function() { g(); })(); })()"); +} + +assertEq(actual, expected); diff --git a/js/src/jit-test/tests/basic/bug787309.js b/js/src/jit-test/tests/basic/bug787309.js new file mode 100644 index 000000000..51129c88d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug787309.js @@ -0,0 +1,7 @@ +// |jit-test| error: TypeError +try { + h +} catch (x +if gc()) {} finally { + this.z.z +} diff --git a/js/src/jit-test/tests/basic/bug787847.js b/js/src/jit-test/tests/basic/bug787847.js new file mode 100644 index 000000000..3adc68fc2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug787847.js @@ -0,0 +1,22 @@ +var g = true; + +function get(name) +{ + if (g) + return 8; +} + +var p = new Proxy({}, { get: get } ); +var o2 = Object.create(p); + +function test(x, expected) { + for (var i=0; i<3; i++) { + var v = x.hello; + if (g) assertEq(v, 8); + } +} + +g = false +test(o2); +g = true; +test(o2); diff --git a/js/src/jit-test/tests/basic/bug787848.js b/js/src/jit-test/tests/basic/bug787848.js new file mode 100644 index 000000000..2972a4c8c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug787848.js @@ -0,0 +1,8 @@ +// |jit-test| error: TypeError +try { + i +} +catch (x if (function() {})()) {} +catch (d) { + this.z.z +} diff --git a/js/src/jit-test/tests/basic/bug791465.js b/js/src/jit-test/tests/basic/bug791465.js new file mode 100644 index 000000000..b3b2e2dd3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug791465.js @@ -0,0 +1,75 @@ +load(libdir + "asserts.js"); + +var valid_strict_funs = [ + // directive ends on next line + function () { + "use strict" + ; + }, + function () { + "use strict" + }, + // directive ends on same line + function () { "use strict"; }, + function () { "use strict" }, +]; + +for (var f of valid_strict_funs) { + assertThrowsInstanceOf(function() { f.caller }, TypeError); +} + + +var binary_ops = [ + "||", "&&", + "|", "^", "&", + "==", "!=", "===", "!==", + "<", "<=", ">", ">=", "in", "instanceof", + "<<", ">>", ">>>", + "+", "-", + "*", "/", "%", +]; + +var invalid_strict_funs = [ + function () { + "use strict" + , "not"; + }, + function () { + "use strict" + ? 1 : 0; + }, + function () { + "use strict" + .length; + }, + function () { + "use strict" + [0]; + }, + function () { + "use strict" + (); + }, + ...([]), + ...(binary_ops.map(op => Function("'use strict'\n " + op + " 'not'"))), +]; + +for (var f of invalid_strict_funs) { + f.caller; +} + + +var assignment_ops = [ + "=", "+=", "-=", + "|=", "^=", "&=", + "<<=", ">>=", ">>>=", + "*=", "/=", "%=", +]; + +var invalid_strict_funs_referror = assignment_ops.map(op => ("'use strict'\n " + op + " 'not'")); + +// assignment with string literal as LHS is an early error, therefore we +// can only test for ReferenceError +for (var f of invalid_strict_funs_referror) { + assertThrowsInstanceOf(function() { Function(f) }, ReferenceError); +} diff --git a/js/src/jit-test/tests/basic/bug792239.js b/js/src/jit-test/tests/basic/bug792239.js new file mode 100644 index 000000000..0635acf11 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug792239.js @@ -0,0 +1,6 @@ +var f = String.prototype.m = function () { + return [this.m, this]; +}; +var a = "s".m(); +gczeal(4); +evaluate("for (a = 0; a < 13; a++) {}", { noScriptRval: true }); diff --git a/js/src/jit-test/tests/basic/bug794025.js b/js/src/jit-test/tests/basic/bug794025.js new file mode 100644 index 000000000..c76eab73e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug794025.js @@ -0,0 +1,15 @@ +// |jit-test| error:RangeError + +function getterFunction(v) { return "getter"; } +Object.defineProperty(Array.prototype, 1,{ + get: getterFunction, +}); +var N = (10000); +repeat_str("try { f(); } finally {\n", N), +repeat_str("}", ("" )); +function repeat_str(str, repeat_count) { + var arr = new Array(--repeat_count); + while (repeat_count != 0) + arr[--repeat_count] = str; + return str.concat.apply(str, arr); +} diff --git a/js/src/jit-test/tests/basic/bug794286.js b/js/src/jit-test/tests/basic/bug794286.js new file mode 100644 index 000000000..a3c1a13cd --- /dev/null +++ b/js/src/jit-test/tests/basic/bug794286.js @@ -0,0 +1,6 @@ +// |jit-test| error: TypeError +for (var i = 0; i < 1; i++) { + let y + if (undefined) continue + undefined.e +} diff --git a/js/src/jit-test/tests/basic/bug794947.js b/js/src/jit-test/tests/basic/bug794947.js new file mode 100644 index 000000000..e8a2829da --- /dev/null +++ b/js/src/jit-test/tests/basic/bug794947.js @@ -0,0 +1,10 @@ +function f(o) +{ + print(o instanceof String); +} + +var g = newGlobal(); +f(new Object()); +var o1 = g.eval('new Object()'); +var o2 = Object.create(o1); +f(o2); diff --git a/js/src/jit-test/tests/basic/bug797495.js b/js/src/jit-test/tests/basic/bug797495.js new file mode 100644 index 000000000..23ffc74e1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug797495.js @@ -0,0 +1,6 @@ +try { + // Don't assert. + options("strict_mode"); + var f = Function("for(w in\\"); +} catch (e) { +} diff --git a/js/src/jit-test/tests/basic/bug797496.js b/js/src/jit-test/tests/basic/bug797496.js new file mode 100644 index 000000000..d8bc1897c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug797496.js @@ -0,0 +1,8 @@ +// |jit-test| error: TypeError +var set = new Set(['a']); +var n = 5; +for (let v of set) { + if (n === 0) + break; + let g = set(new Set(0xffffffff, n), 1); +} diff --git a/js/src/jit-test/tests/basic/bug798678.js b/js/src/jit-test/tests/basic/bug798678.js new file mode 100644 index 000000000..e68dae4d0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug798678.js @@ -0,0 +1,10 @@ +var w = new WeakMap(); +var g = newGlobal(); +var k = g.eval('for (var i=0; i<100; i++) new Object(); var q = new Object(); q'); +w.set(k, {}); +k = null; + +gc(); +g.eval('q = null'); +gc(g); +gc(); diff --git a/js/src/jit-test/tests/basic/bug798834.js b/js/src/jit-test/tests/basic/bug798834.js new file mode 100644 index 000000000..669fe20d3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug798834.js @@ -0,0 +1,5 @@ +(function(start, stop, step) { + stop = start; + step = arguments[2]; + assertEq(stop, true); +})(true); diff --git a/js/src/jit-test/tests/basic/bug806522.js b/js/src/jit-test/tests/basic/bug806522.js new file mode 100644 index 000000000..1507276c1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug806522.js @@ -0,0 +1,7 @@ +load(libdir + "asserts.js"); + +var g = evalcx("lazy"); +assertThrowsInstanceOf( + () => evaluate("{ let eval; eval()}", {global: g}), + g.TypeError); // eval is not a function +assertEq(evaluate("{ let eval = parseInt; eval()}", {global: g}), NaN); diff --git a/js/src/jit-test/tests/basic/bug807623.js b/js/src/jit-test/tests/basic/bug807623.js new file mode 100644 index 000000000..ce16ffd41 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug807623.js @@ -0,0 +1,17 @@ +var objectProxy = new Proxy({}, {}); +var functionProxy = new Proxy(function() {}, {}); + +assertEq(Object.prototype.toString.call(objectProxy), '[object Object]'); +assertEq(Object.prototype.toString.call(functionProxy), '[object Function]'); +try { + Function.prototype.toString.call(functionProxy); + assertEq(true, false); +} catch (e) { + assertEq(!!/incompatible/.exec(e), true); +} +try { + Function.prototype.toString.call(objectProxy); + assertEq(true, false); +} catch (e) { + assertEq(!!/incompatible/.exec(e), true); +} diff --git a/js/src/jit-test/tests/basic/bug808067.js b/js/src/jit-test/tests/basic/bug808067.js new file mode 100644 index 000000000..74f721ec9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug808067.js @@ -0,0 +1,19 @@ +function TestCase(n, d, e, a) + this.reason = ''; +function reportCompare (expected, actual, description) { + var output = ""; + var testcase = new TestCase("unknown-test-name", description, expected, actual); + testcase.reason = output; +} +gcPreserveCode(); +var summary = 'return with argument and lazy generator detection'; +expect = "generator function foo returns a value"; +actual = (function (j) {}).message; +reportCompare(expect, actual, summary + ": 1"); +reportCompare(expect, actual, summary + ": 2"); +gcslice(1); +gcslice(2); +gc(); +var strings = [ (0), ]; +for (var i = 0; i < strings.length; i++) + reportCompare(expect, actual, summary + (5e1) + strings[i]); diff --git a/js/src/jit-test/tests/basic/bug808483.js b/js/src/jit-test/tests/basic/bug808483.js new file mode 100644 index 000000000..9dd2be029 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug808483.js @@ -0,0 +1,16 @@ +pSandbox = newGlobal(); +evalcx("\ + x = ArrayBuffer;\ + y = new Map();\ + x += 1;\ + w = x;\ + x += '0';\ + z = x;\ +", pSandbox); +evalcx("\ + x + '0';\ +", pSandbox); +evalcx("\ + y.delete(z);\ + w.slice(2);\ +", pSandbox) diff --git a/js/src/jit-test/tests/basic/bug817002.js b/js/src/jit-test/tests/basic/bug817002.js new file mode 100644 index 000000000..e6839680b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug817002.js @@ -0,0 +1,13 @@ +gc() +evalcx("\ + if (!(\"gcslice\" in this))\ + gcslice = function() { };\ + array = new Uint8Array;\ + t0 = array.subarray();\ + gcslice(12); \ + array.subarray();\ + gc();\ + gc();\ + array.subarray().a = 1;\ + gc();", +newGlobal('')) diff --git a/js/src/jit-test/tests/basic/bug820124-1.js b/js/src/jit-test/tests/basic/bug820124-1.js new file mode 100644 index 000000000..6b6ec5d7b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug820124-1.js @@ -0,0 +1,5 @@ +// Don't assert. +verifyprebarriers(); +r = /()()()\3/.test(); +gc(); +RegExp().test(); diff --git a/js/src/jit-test/tests/basic/bug820124-2.js b/js/src/jit-test/tests/basic/bug820124-2.js new file mode 100644 index 000000000..a4a8dd9ec --- /dev/null +++ b/js/src/jit-test/tests/basic/bug820124-2.js @@ -0,0 +1,3 @@ +// Don't assert. +'123456'.replace(/1(\d+)3/, ''); +RegExp.lastMatch.toString(); diff --git a/js/src/jit-test/tests/basic/bug820124-3.js b/js/src/jit-test/tests/basic/bug820124-3.js new file mode 100644 index 000000000..1f0dfd0fa --- /dev/null +++ b/js/src/jit-test/tests/basic/bug820124-3.js @@ -0,0 +1,8 @@ +// Don't assert. +eval("\ + x = RegExp(\"()\", \"y\");\ + x.test();\ + x = {};\ +") +gc() +RegExp.$6 diff --git a/js/src/jit-test/tests/basic/bug820124-4.js b/js/src/jit-test/tests/basic/bug820124-4.js new file mode 100644 index 000000000..606a1e498 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug820124-4.js @@ -0,0 +1,8 @@ +// Don't assert. +eval("\ + r = RegExp(\"(?!()(((!))))\", \"g\");\ + \"^\".replace(r, '');\ + r = (\"1+\")\ +") +gc() +RegExp.$8 diff --git a/js/src/jit-test/tests/basic/bug821103.js b/js/src/jit-test/tests/basic/bug821103.js new file mode 100644 index 000000000..d2465e4a0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug821103.js @@ -0,0 +1,4 @@ +options("werror"); +load(libdir + "asserts.js"); + +eval("function x() { var x= 4; 'hi'; }"); diff --git a/js/src/jit-test/tests/basic/bug821850.js b/js/src/jit-test/tests/basic/bug821850.js new file mode 100644 index 000000000..fb0819c7b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug821850.js @@ -0,0 +1,9 @@ +load(libdir + "asserts.js"); + +m={} +Object.defineProperty(m, 'p', {value: 3}); +assertThrowsInstanceOf(function() {"use strict"; delete m.p;}, TypeError); + +x = new Proxy(m, {}) +assertEq(x.p, 3); +assertThrowsInstanceOf(function fun() {"use strict"; return delete x.p; }, TypeError); diff --git a/js/src/jit-test/tests/basic/bug823310.js b/js/src/jit-test/tests/basic/bug823310.js new file mode 100644 index 000000000..004a55639 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug823310.js @@ -0,0 +1,7 @@ +"use strict"; +options("werror"); + +// This construct causes a strict warning, but we shouldn't get one since +// JSOPTION_EXTRA_WARNINGS isn't enabled. +var x; +eval("if (x = 3) {}"); diff --git a/js/src/jit-test/tests/basic/bug824856.js b/js/src/jit-test/tests/basic/bug824856.js new file mode 100644 index 000000000..d2c31d579 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug824856.js @@ -0,0 +1,6 @@ +// |jit-test| error: TypeError +RegExp("(&)??\\1}").test("&D") +"xy".match(/((x)??){2}y/) +"\u66d6J".split(/((\u66d6)??){7}J/) +"2\"".match("(((2)??)+\")")() + diff --git a/js/src/jit-test/tests/basic/bug826581.js b/js/src/jit-test/tests/basic/bug826581.js new file mode 100644 index 000000000..bfeade610 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug826581.js @@ -0,0 +1,12 @@ +// Don't crash. + +try { + x = " () "; + for (var y = 0; y < 19; y++) { + x += x; + } +} catch (e) {} + +try { + "".replace(x, "", "gy"); +} catch (e) { } diff --git a/js/src/jit-test/tests/basic/bug827104.js b/js/src/jit-test/tests/basic/bug827104.js new file mode 100644 index 000000000..bed6466b4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug827104.js @@ -0,0 +1,13 @@ +function f() { + var a = []; + for (var i = 0; i < 1000; i++) { + a.x = {} + } + a[i][0] = 0; +} + +var e; +try { + f(); +} catch (error) {e = error;} +assertEq(e.toString(), 'TypeError: a[i] is undefined');
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug829795.js b/js/src/jit-test/tests/basic/bug829795.js new file mode 100644 index 000000000..236b5e68d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug829795.js @@ -0,0 +1,7 @@ +// |jit-test| error: TypeError + +try { + x = []; + Array.prototype.forEach() +} catch (e) {} +x.forEach() diff --git a/js/src/jit-test/tests/basic/bug829813.js b/js/src/jit-test/tests/basic/bug829813.js new file mode 100644 index 000000000..c3f9b145c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug829813.js @@ -0,0 +1,6 @@ + +for (x in [0]) { + (function() { + return Object.propertyIsEnumerable + })().call([0], x) +} diff --git a/js/src/jit-test/tests/basic/bug829821.js b/js/src/jit-test/tests/basic/bug829821.js new file mode 100644 index 000000000..9825e6e2b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug829821.js @@ -0,0 +1,5 @@ +// |jit-test| error:TypeError + +x = []; +x.unshift(Uint8ClampedArray); +x.forEach(Array.prototype.push.bind(new Uint8ClampedArray)) diff --git a/js/src/jit-test/tests/basic/bug830045.js b/js/src/jit-test/tests/basic/bug830045.js new file mode 100644 index 000000000..de1350f77 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug830045.js @@ -0,0 +1,6 @@ + +Array.prototype[1] = 'y'; +var a = [0, (8)]; +for (var i in a) { + delete a[1]; +} diff --git a/js/src/jit-test/tests/basic/bug830049.js b/js/src/jit-test/tests/basic/bug830049.js new file mode 100644 index 000000000..641134a27 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug830049.js @@ -0,0 +1,12 @@ +// |jit-test| error: TypeError +load(libdir + "immutable-prototype.js"); + +Object.defineProperty(Object.prototype, "name", + { set(v) { throw new TypeError("hit name"); }, + enumerable: true, + configurable: true }); + +function TestCase(n) { + this.name = n; +} +new TestCase(); diff --git a/js/src/jit-test/tests/basic/bug830967.js b/js/src/jit-test/tests/basic/bug830967.js new file mode 100644 index 000000000..e52892f64 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug830967.js @@ -0,0 +1,4 @@ +var x = Array.concat(Object.freeze([{}])); +assertEq(x.length, 1); +assertEq(0 in x, true); +assertEq(JSON.stringify(x[0]), "{}"); diff --git a/js/src/jit-test/tests/basic/bug831658.js b/js/src/jit-test/tests/basic/bug831658.js new file mode 100644 index 000000000..ae7d6a5a1 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug831658.js @@ -0,0 +1,4 @@ +// Don't assert. +String.prototype.search = evalcx('').String.prototype.search +x = /./.test() +''.search(/()/) diff --git a/js/src/jit-test/tests/basic/bug831846.js b/js/src/jit-test/tests/basic/bug831846.js new file mode 100644 index 000000000..30bb3aa86 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug831846.js @@ -0,0 +1,3 @@ +// |jit-test| error:TypeError + +evalcx('').watch("", /()/); diff --git a/js/src/jit-test/tests/basic/bug832197-1.js b/js/src/jit-test/tests/basic/bug832197-1.js new file mode 100644 index 000000000..4caf7cc2c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug832197-1.js @@ -0,0 +1,4 @@ +// Don't assert. +''.search(evalcx("/(?:}?)/", undefined)) +gc() +gc() diff --git a/js/src/jit-test/tests/basic/bug832197-2.js b/js/src/jit-test/tests/basic/bug832197-2.js new file mode 100644 index 000000000..b4e4ca47a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug832197-2.js @@ -0,0 +1,13 @@ +// Don't assert. +try { + var r = evalcx("new RegExp(\"\",\"\")", w); + var s = ""; + (s.search(r))(x) +} catch (e) {} + r = /()()()()/; +try { + for (let x = 0; x < 3; ++x) { + gc() + } +} catch (e) {} +var w diff --git a/js/src/jit-test/tests/basic/bug832203.js b/js/src/jit-test/tests/basic/bug832203.js new file mode 100644 index 000000000..3889edc9c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug832203.js @@ -0,0 +1,11 @@ +// Don't assert. +gczeal(2,1); +eval("(function() { " + "\ +var g1 = newGlobal('same-compartment');\ +function test(str, f) {\ + var x = f(eval(str));\ + assertEq(x, f(g1.eval(str)));\ +}\ +test('new RegExp(\"1\")', function(r) assertEq('a1'.search(r), 1));\ +" + " })();"); +eval("(function() { " + "" + " })();"); diff --git a/js/src/jit-test/tests/basic/bug836563.js b/js/src/jit-test/tests/basic/bug836563.js new file mode 100644 index 000000000..1b1c61095 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug836563.js @@ -0,0 +1,5 @@ + +var x = {}; +Object.defineProperty(x, 0, { configurable: true, value: null }); +x.p = 0 +Object.defineProperty(x, 0, { value: 2 }); diff --git a/js/src/jit-test/tests/basic/bug836623.js b/js/src/jit-test/tests/basic/bug836623.js new file mode 100644 index 000000000..d0d90dc78 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug836623.js @@ -0,0 +1,13 @@ + +x = [] +Object.defineProperty(x, 4, { + configurable: true +}) +Array.prototype.pop.call(x) +for (let y = 0; y < 9; ++y) { + Object.defineProperty(x, 7, { + configurable: true, + enumerable: (y != 2), + writable: true + }) +} diff --git a/js/src/jit-test/tests/basic/bug839420.js b/js/src/jit-test/tests/basic/bug839420.js new file mode 100644 index 000000000..66b2c87ef --- /dev/null +++ b/js/src/jit-test/tests/basic/bug839420.js @@ -0,0 +1,17 @@ +function f() { + var x = undefined; + try { + [1, 2, 3].map(x); + assertEq(0, 1); + } catch(e) { + assertEq(e.toString().includes("x is not"), true); + } + + try { + [1, 2, 3].filter(x, 1, 2); + assertEq(0, 1); + } catch(e) { + assertEq(e.toString().includes("x is not"), true); + } +} +f(); diff --git a/js/src/jit-test/tests/basic/bug842425.js b/js/src/jit-test/tests/basic/bug842425.js new file mode 100644 index 000000000..f95178776 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug842425.js @@ -0,0 +1,12 @@ +// |jit-test| error: TypeError + +function g() { + var a = []; + for (var i = 0; i < 10; i++) + a.push(i, 1.5); + for (var i = 0; i < 32 ; i++) { + print(i); + a[i].m = function() {} + } +} +g(); diff --git a/js/src/jit-test/tests/basic/bug842482.js b/js/src/jit-test/tests/basic/bug842482.js new file mode 100644 index 000000000..79e71e043 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug842482.js @@ -0,0 +1,2 @@ +var g = newGlobal(); +new g.DataView(new g.ArrayBuffer()); diff --git a/js/src/jit-test/tests/basic/bug842940.js b/js/src/jit-test/tests/basic/bug842940.js new file mode 100644 index 000000000..015b18bb3 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug842940.js @@ -0,0 +1 @@ +try { for (let v of wrapWithProto(new Proxy({}, {}), [])) { } } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug846080.js b/js/src/jit-test/tests/basic/bug846080.js new file mode 100644 index 000000000..2cc363d68 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug846080.js @@ -0,0 +1,3 @@ +// |jit-test| error: TypeError +this.__defineSetter__("x", [].map); +evaluate('[x]="";'); diff --git a/js/src/jit-test/tests/basic/bug851635.js b/js/src/jit-test/tests/basic/bug851635.js new file mode 100644 index 000000000..993fbb313 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug851635.js @@ -0,0 +1,7 @@ + +gcPreserveCode() +try { + eval("({a1:1});e i") +} catch (e) {} +gc() +eval("({a1:1})") diff --git a/js/src/jit-test/tests/basic/bug851756.js b/js/src/jit-test/tests/basic/bug851756.js new file mode 100644 index 000000000..fb98ed2b6 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug851756.js @@ -0,0 +1,3 @@ + +({ x: false })[String] = 7 +eval("[{x:3}]") diff --git a/js/src/jit-test/tests/basic/bug852016-2.js b/js/src/jit-test/tests/basic/bug852016-2.js new file mode 100644 index 000000000..e3a15bddb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug852016-2.js @@ -0,0 +1,8 @@ + +function foo(str) { + var x = eval(str); yield x[0]; +} +for (var i = 0; i < 5; i++) + assertEq(foo("[4,5,6]").next(), 4); +for (var i = 0; i < 5; i++) + assertEq(foo("arguments").next(), "arguments"); diff --git a/js/src/jit-test/tests/basic/bug852016.js b/js/src/jit-test/tests/basic/bug852016.js new file mode 100644 index 000000000..971d426a8 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug852016.js @@ -0,0 +1,9 @@ +//|jit-test| error: SyntaxError + +(function() { + x = "arguments"; + f = eval("(function(){return(c for (x in eval('print(arguments[0])')))})"); + for (e in f()) { + (function() {}); + } +})(3) diff --git a/js/src/jit-test/tests/basic/bug854124.js b/js/src/jit-test/tests/basic/bug854124.js new file mode 100644 index 000000000..505ed2dfb --- /dev/null +++ b/js/src/jit-test/tests/basic/bug854124.js @@ -0,0 +1,8 @@ +// Don't assert. +"p".match(/(p)/); +assertEq(RegExp.$1, "p"); +assertEq(RegExp.$2, ""); + +"x\ny\n".replace(/(^\n*)/, ""); +assertEq(RegExp.$1, ""); +assertEq(RegExp.$2, ""); diff --git a/js/src/jit-test/tests/basic/bug854137.js b/js/src/jit-test/tests/basic/bug854137.js new file mode 100644 index 000000000..d1f6b6976 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug854137.js @@ -0,0 +1,6 @@ +// Don't assert. +try { + eval("function x(y = {\ + x: (7) ? 0 : yield(0)\ + }"); +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug855088.js b/js/src/jit-test/tests/basic/bug855088.js new file mode 100644 index 000000000..9d1145616 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug855088.js @@ -0,0 +1,5 @@ + +(function (y) { + arguments.y = 2; + with (0) var arguments=5; +})(1); diff --git a/js/src/jit-test/tests/basic/bug858097.js b/js/src/jit-test/tests/basic/bug858097.js new file mode 100644 index 000000000..48bb395a5 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug858097.js @@ -0,0 +1,6 @@ +// |jit-test| allow-oom +function MyObject( value ) {} +gcparam("maxBytes", gcparam("gcBytes") + 4*(1)); +gczeal(4); +function test() {} +var obj = new test(); diff --git a/js/src/jit-test/tests/basic/bug862228.js b/js/src/jit-test/tests/basic/bug862228.js new file mode 100644 index 000000000..c151d9154 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug862228.js @@ -0,0 +1,3 @@ +// |jit-test| error: SyntaxError + +({"":y=""}= diff --git a/js/src/jit-test/tests/basic/bug863084.js b/js/src/jit-test/tests/basic/bug863084.js new file mode 100644 index 000000000..1bcb9cd47 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug863084.js @@ -0,0 +1,17 @@ +// |jit-test| error: too much recursion +function f(code) { + try { + eval(code) + } catch (e) {} + eval(code) +} +f("\ + z=evalcx('');\ + gc();\ + z.toString=(function(){\ + v=evaluate(\"(Math.atan2(\\\"\\\",this))\",{\ + global:z,catchTermination:this\ + });\ + });\ + String(z)\ +") diff --git a/js/src/jit-test/tests/basic/bug867946.js b/js/src/jit-test/tests/basic/bug867946.js new file mode 100644 index 000000000..a673966f4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug867946.js @@ -0,0 +1,7 @@ +// |jit-test| error: InternalError: too much recursion +b = {}; +b.__proto__ = evalcx("lazy"); +function g() { + g(b.toString()) +} +g(); diff --git a/js/src/jit-test/tests/basic/bug876226.js b/js/src/jit-test/tests/basic/bug876226.js new file mode 100644 index 000000000..4fb779b4f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug876226.js @@ -0,0 +1,6 @@ +// |jit-test| error: SyntaxError +try { + evaluate("throw 3"); +} catch(e) {} + +evaluate("()", {}); diff --git a/js/src/jit-test/tests/basic/bug877378.js b/js/src/jit-test/tests/basic/bug877378.js new file mode 100644 index 000000000..06d63c10e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug877378.js @@ -0,0 +1,18 @@ +evalcx("\ + let z = 'x';\ + for (var v of z) {\ + y = evaluate(\"Object.defineProperty(this,\\\"y\\\",\ + {get: function() {}}\ + );\",\ + {catchTermination: true}\ + );\ + }", + newGlobal('') +) + +evalcx("\ + for (x = 0; x < 1; ++x) { \ + v = evaluate(\"gc\",{ \ + })\ + }\ +", newGlobal('')); diff --git a/js/src/jit-test/tests/basic/bug880377.js b/js/src/jit-test/tests/basic/bug880377.js new file mode 100644 index 000000000..4332bd2a9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug880377.js @@ -0,0 +1,10 @@ +var actual = ''; +var obj0 = {} +obj2 = {}; +obj2['b'+1] = 1; +if (actual[0] != 0[0]) + throw new i(); +for (var k in obj2) { + for (var apply in obj0) + ++count; +}
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug882416.js b/js/src/jit-test/tests/basic/bug882416.js new file mode 100644 index 000000000..48dde9416 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug882416.js @@ -0,0 +1,5 @@ +// |jit-test| error: SyntaxError +Error.prototype.toString = Function; +evaluate("n f", { + noScriptRval: true, +}); diff --git a/js/src/jit-test/tests/basic/bug883523.js b/js/src/jit-test/tests/basic/bug883523.js new file mode 100644 index 000000000..c448b70c9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug883523.js @@ -0,0 +1 @@ +if(1) /a/.test("a"); // should not be a SyntaxError. diff --git a/js/src/jit-test/tests/basic/bug883623.js b/js/src/jit-test/tests/basic/bug883623.js new file mode 100644 index 000000000..d5599fb1f --- /dev/null +++ b/js/src/jit-test/tests/basic/bug883623.js @@ -0,0 +1,7 @@ + +(function() { + eval("\ + arguments.valueOf();\ + with (function(){}){};\ + "); +})()
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/bug884920.js b/js/src/jit-test/tests/basic/bug884920.js new file mode 100644 index 000000000..7f5737d30 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug884920.js @@ -0,0 +1,7 @@ +// |jit-test| error:SyntaxError + +function testcase({}, a = b, ... x) { + "use strict"; + function f() { }; + with ( f(3) ); +} diff --git a/js/src/jit-test/tests/basic/bug885648.js b/js/src/jit-test/tests/basic/bug885648.js new file mode 100644 index 000000000..60816962c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug885648.js @@ -0,0 +1,9 @@ +gczeal(4,1); +var iterable = {persistedProp: 17}; +iterable.__iterator__ = function() { + yield ["foo", 2]; + yield ["bar", 3]; +}; +var it = Iterator(iterable); +assertEq(it.next().toString(), "foo,2"); +assertEq(it.next().toString(), "bar,3"); diff --git a/js/src/jit-test/tests/basic/bug886803.js b/js/src/jit-test/tests/basic/bug886803.js new file mode 100644 index 000000000..c89e9bce9 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug886803.js @@ -0,0 +1,3 @@ + +f = Function("with({}) { var i; }"); +f(); diff --git a/js/src/jit-test/tests/basic/bug908915.js b/js/src/jit-test/tests/basic/bug908915.js new file mode 100644 index 000000000..f5a4dc43c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug908915.js @@ -0,0 +1,43 @@ +// |jit-test| error: 42 +load(libdir + "immutable-prototype.js"); + +// Suppress the large quantity of output on stdout (eg from calling +// dumpHeap()). +os.file.redirect(null); + +var blacklist = { + 'quit': true, + 'crash': true, + 'readline': true, + 'terminate': true, + 'nestedShell': true, +}; + +function f(y) {} +for each(let e in newGlobal()) { + if (e.name in blacklist) + continue; + print(e.name); + try { + e(); + } catch (r) {} +} +(function() { + arguments; + if (globalPrototypeChainIsMutable()) + Object.prototype.__proto__ = newGlobal() + function f(y) { + y() + } + var arr = []; + arr.__proto__ = newGlobal(); + for each (b in arr) { + if (b.name in blacklist) + continue; + try { + f(b) + } catch (e) {} + } +})(); + +throw 42; diff --git a/js/src/jit-test/tests/basic/bug911368.js b/js/src/jit-test/tests/basic/bug911368.js new file mode 100644 index 000000000..3006155f2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug911368.js @@ -0,0 +1,10 @@ +// |jit-test| +(function (stdlib, heap) { + "use asm"; + function f(i0) { + i0 = i0 | 0; + switch (0xc << (0xa % 1)) { + case -2: + }; + } +})() diff --git a/js/src/jit-test/tests/basic/bug913445.js b/js/src/jit-test/tests/basic/bug913445.js new file mode 100644 index 000000000..6b255914c --- /dev/null +++ b/js/src/jit-test/tests/basic/bug913445.js @@ -0,0 +1,17 @@ +// uneval works on objects with no callable .toSource method. + +var obj = Object.create(null); +assertEq(uneval(obj), "({})"); +assertEq(Function.prototype.toSource.call(obj), "({})"); +obj.x = 1; +obj.y = 2; +assertEq(uneval(obj), "({x:1, y:2})"); + +var d = new Date(); +delete Date.prototype.toSource; +assertEq(uneval(d), "({})"); + +delete Object.prototype.toSource; +assertEq(uneval({p: 2+2}), "({p:4})"); + +assertEq(uneval({toSource: [0]}), "({toSource:[0]})"); diff --git a/js/src/jit-test/tests/basic/bug920484.js b/js/src/jit-test/tests/basic/bug920484.js new file mode 100644 index 000000000..0c9e4c9ac --- /dev/null +++ b/js/src/jit-test/tests/basic/bug920484.js @@ -0,0 +1,33 @@ +load(libdir + "asserts.js"); + +// Add an invalid "localeMatcher" option to Object.prototype, the exact value does not matter, +// any value except "best fit" or "lookup" is okay. +Object.prototype.localeMatcher = "invalid matcher option"; + +// The Intl API may not be available in the testing environment. Note that |hasOwnProperty("Intl")| +// initializes the Intl API if present, so this if-statement needs to appear after "localeMatcher" +// was added to Object.prototype. +if (this.hasOwnProperty("Intl")) { + // Intl prototypes are properly initialized despite changed Object.prototype. + Intl.Collator.prototype.compare("a", "b"); + Intl.NumberFormat.prototype.format(10); + Intl.DateTimeFormat.prototype.format(new Date); + + // Intl constructors no longer work properly, because "localeMatcher" defaults to the invalid + // value from Object.prototype. Except for Intl.DateTimeFormat, cf. ECMA-402 ToDateTimeOptions. + assertThrowsInstanceOf(() => new Intl.Collator(), RangeError); + assertThrowsInstanceOf(() => new Intl.NumberFormat(), RangeError); + new Intl.DateTimeFormat().format(new Date); + + // If an explicit "localeMatcher" option is given, the default from Object.prototype is ignored. + new Intl.Collator(void 0, {localeMatcher: "lookup"}).compare("a", "b"); + new Intl.NumberFormat(void 0, {localeMatcher: "lookup"}).format(10); + new Intl.DateTimeFormat(void 0, {localeMatcher: "lookup"}).format(new Date); + + delete Object.prototype.localeMatcher; + + // After removing the default option from Object.prototype, everything works again as expected. + new Intl.Collator().compare("a", "b"); + new Intl.NumberFormat().format(10); + new Intl.DateTimeFormat().format(new Date); +} diff --git a/js/src/jit-test/tests/basic/bug934789-1.js b/js/src/jit-test/tests/basic/bug934789-1.js new file mode 100644 index 000000000..3b290e135 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug934789-1.js @@ -0,0 +1,13 @@ +if (typeof dis === "function") { + (function() { + function foo() {} + + dis(function bar(e) { + try { + (function() { e; }); + } catch (e) { + foo(); + } + }); + }()); +} diff --git a/js/src/jit-test/tests/basic/bug934789-2.js b/js/src/jit-test/tests/basic/bug934789-2.js new file mode 100644 index 000000000..5272d63e0 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug934789-2.js @@ -0,0 +1,15 @@ +load(libdir + "asserts.js"); +assertThrowsInstanceOf( + function() { + function foo() {} + foo = null; + (function bar(e) { + try { + (function() { e; }); + throw 1; + } catch (e) { + foo(); + } + })(); + }, + TypeError); diff --git a/js/src/jit-test/tests/basic/bug934997.js b/js/src/jit-test/tests/basic/bug934997.js new file mode 100644 index 000000000..91d81f029 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug934997.js @@ -0,0 +1,30 @@ +function test1() { + var BUGNUMBER = ''; + var summary = ''; + var actual = ''; + test(BUGNUMBER); + function test() { + try { + (function () { eval("'foo'.b()", arguments) })(); + } catch(ex) { + actual = ex + ''; + } + } + assertEq(actual, 'TypeError: "foo".b is not a function'); +} +test1(); + +function test2() { + var BUGNUMBER = ''; + var summary = ''; + function g() { + 'use strict'; + try { + eval('function foo() { var a, arguments, b;}'); + } catch (x) { + return (x instanceof SyntaxError); + } + }; + assertEq(g(), true); +} +test2(); diff --git a/js/src/jit-test/tests/basic/bug935294.js b/js/src/jit-test/tests/basic/bug935294.js new file mode 100644 index 000000000..c6dfc36e7 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug935294.js @@ -0,0 +1,5 @@ +// |jit-test| error: ReferenceError +for (var c in foo) + try { + throw new Error(); + } catch (e) {} diff --git a/js/src/jit-test/tests/basic/bug937089.js b/js/src/jit-test/tests/basic/bug937089.js new file mode 100644 index 000000000..09eedbe03 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug937089.js @@ -0,0 +1,10 @@ + +function test1() { + eval("with (arguments) var arguments = 0;"); +} +test1(); + +function test2() { + eval("eval('with (arguments) var arguments = 0;')"); +} +test2(); diff --git a/js/src/jit-test/tests/basic/bug942390.js b/js/src/jit-test/tests/basic/bug942390.js new file mode 100644 index 000000000..9b661a4f4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug942390.js @@ -0,0 +1,21 @@ +load(libdir + "immutable-prototype.js"); + +var count = 0; +if (globalPrototypeChainIsMutable()) { + Object.defineProperty(__proto__, "__iterator__", { + get: (function() { + count++; + }) + }); +} else { + count = 7; +} + +if (globalPrototypeChainIsMutable()) + __proto__ = (function(){}); + +for (var m = 0; m < 7; ++m) { + for (var a in 6) {} +} + +assertEq(count, 7); diff --git a/js/src/jit-test/tests/basic/bug943126.js b/js/src/jit-test/tests/basic/bug943126.js new file mode 100644 index 000000000..319274fb2 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug943126.js @@ -0,0 +1,16 @@ +// Test fast-path for String.split(""). + +load(libdir + 'eqArrayHelper.js'); + +assertEqArray("".split(""), []); +assertEqArray("a".split(""), ["a"]); +assertEqArray("abc".split(""), ["a", "b", "c"]); + +assertEqArray("abcd".split("", 2), ["a", "b"]); +assertEqArray("abcd".split("", 0), []); +assertEqArray("abcd".split("", -1), ["a", "b", "c", "d"]); + +// Note: V8 disagrees about this one, but we are correct by ecma-262 15.5.4.14 part 9. +assertEqArray("abcd".split(undefined, 0), []); + +assertEqArray("abcd".split(undefined, 1), ["abcd"]); diff --git a/js/src/jit-test/tests/basic/bug950725.js b/js/src/jit-test/tests/basic/bug950725.js new file mode 100644 index 000000000..c036ee041 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug950725.js @@ -0,0 +1,12 @@ +function test() { + + T[g].act +} +gc(); +var c = 0; +for (var i = 0; i < 20; test['$+']) { + if (c++ > 110) + break; + try { + __count__(f(2), 1); + } catch (e) {} +} diff --git a/js/src/jit-test/tests/basic/bug951213.js b/js/src/jit-test/tests/basic/bug951213.js new file mode 100644 index 000000000..0607980da --- /dev/null +++ b/js/src/jit-test/tests/basic/bug951213.js @@ -0,0 +1,8 @@ + +enableShellAllocationMetadataBuilder(); +function foo(x, y) { + this.g = x + y; +} +var a = 0; +var b = { valueOf: function() Object.defineProperty(Object.prototype, 'g', {}) }; +var c = new foo(a, b); diff --git a/js/src/jit-test/tests/basic/bug951346.js b/js/src/jit-test/tests/basic/bug951346.js new file mode 100644 index 000000000..a8ad67cb4 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug951346.js @@ -0,0 +1,3 @@ + +enableShellAllocationMetadataBuilder(); +eval(uneval({'-1':true})); diff --git a/js/src/jit-test/tests/basic/bug951632.js b/js/src/jit-test/tests/basic/bug951632.js new file mode 100644 index 000000000..140869b3e --- /dev/null +++ b/js/src/jit-test/tests/basic/bug951632.js @@ -0,0 +1,9 @@ +enableShellAllocationMetadataBuilder(); +var g = newGlobal() +g.eval("function f(a) { return h(); }"); +g.h = function () { + return [1, 2, 3]; +}; +var o = getAllocationMetadata(g.f(5)); +assertEq(o.stack.length, 1); +assertEq(o.stack[0], g.h); diff --git a/js/src/jit-test/tests/basic/bug970643.js b/js/src/jit-test/tests/basic/bug970643.js new file mode 100644 index 000000000..e409c8a66 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug970643.js @@ -0,0 +1,18 @@ +// |jit-test| exitstatus: 6; + +setJitCompilerOption("baseline.warmup.trigger", 1); +setJitCompilerOption("ion.warmup.trigger", 2); + +// The timepout function is made to trigger the interruption callback. The +// interruption callback will protect the code while a GC might be +// marking/updating pointers in it. +var x = 0; +function interrupt_gc() { + if (x++ >= 20) + return; + timeout(0.1, interrupt_gc); + while(x < 20) + gc(); +} + +interrupt_gc(); diff --git a/js/src/jit-test/tests/basic/bug972961.js b/js/src/jit-test/tests/basic/bug972961.js new file mode 100644 index 000000000..10df12cad --- /dev/null +++ b/js/src/jit-test/tests/basic/bug972961.js @@ -0,0 +1,40 @@ +// Bug 972961 - Test compiler with very long chains of property accesses + +// Return true if we can compile a chain of n property accesses, +// false if we cannot. Throw if compilation fails in an unexpected way. +function test(n) { + print("testing " + n); + try { + eval('if (false) {' + Array(n).join(("a.")) + 'a}'); + } catch (exc) { + // Expected outcome if the expression is too deeply nested is an InternalError. + if (!(exc instanceof InternalError)) + throw exc; + print(exc.message); + return false; + } + print("no exception"); + return true; +} + +// Find out how long a chain is enough to break the compiler. +var n = 4, LIMIT = 0x000fffff; +var lo = 1, hi = 1; +while (n <= LIMIT && test(n)) { + lo = n; + n *= 4; +} + +// Using binary search, find a pass/fail boundary (in order to +// test the edge case). +if (n <= LIMIT) { + hi = n; + while (lo !== hi) { + var mid = Math.floor((lo + hi) / 2); + if (test(mid)) + lo = mid + 1; + else + hi = mid; + } + print((lo - 1) + " attributes should be enough for anyone"); +} diff --git a/js/src/jit-test/tests/basic/bug976446.js b/js/src/jit-test/tests/basic/bug976446.js new file mode 100644 index 000000000..e99e22131 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug976446.js @@ -0,0 +1,16 @@ + +try { + +function f() {} +f("".match(/(?:(?=g)).{2147483648,}/ + (/[]/)), null); + +} catch (e) {} // Yarr throws on the above regexp + +var re = new RegExp("a[\x01-\\xDE]+M", "gi"); +re.exec(""); + +var re = new RegExp("a[\x01-\\u00b8]+?c", "gi"); +re.exec(""); + +var re = new RegExp("a[\x01-\\u00f8]?c", "gi"); +re.exec(""); diff --git a/js/src/jit-test/tests/basic/bug980013.js b/js/src/jit-test/tests/basic/bug980013.js new file mode 100644 index 000000000..d84295285 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug980013.js @@ -0,0 +1,9 @@ + +x = new Uint8ClampedArray; +x.__proto__ = {}; +Object.defineProperty(this, "y", { + get: function() { + return x.length; + } +}); +assertEq(y, undefined); diff --git a/js/src/jit-test/tests/basic/bug980450.js b/js/src/jit-test/tests/basic/bug980450.js new file mode 100644 index 000000000..afe1c5fac --- /dev/null +++ b/js/src/jit-test/tests/basic/bug980450.js @@ -0,0 +1,4 @@ + +var f32 = new Float32Array(1); +for(var n = 100; n; --n) + f32.hasOwnProperty(4) diff --git a/js/src/jit-test/tests/basic/bug984766.js b/js/src/jit-test/tests/basic/bug984766.js new file mode 100644 index 000000000..bd44fc31b --- /dev/null +++ b/js/src/jit-test/tests/basic/bug984766.js @@ -0,0 +1,17 @@ + +for (var i = 0; i < 10; i++) { + x = new ArrayBuffer(4) + x.f = (function() {}) + new Uint16Array(x).set(JSON.parse) + gcslice() +} + +if (!this.SharedArrayBuffer) + quit(0); + +for (var i = 0; i < 10; i++) { + x = new SharedArrayBuffer(4) + x.f = (function() {}) + new Uint16Array(x).set(JSON.parse) + gcslice() +} diff --git a/js/src/jit-test/tests/basic/builtinLocals.js b/js/src/jit-test/tests/basic/builtinLocals.js new file mode 100644 index 000000000..032b801d0 --- /dev/null +++ b/js/src/jit-test/tests/basic/builtinLocals.js @@ -0,0 +1,35 @@ + +/* Resolve 'arguments' and the name of the function itself in the presence of such local variables. */ + +function f() { + return typeof arguments; + function arguments() { + return 7; + } +} +assertEq(f(), "function"); + +function g() { + var arguments = 0; + return typeof arguments; +} +assertEq(g(), "number"); + +function h() { + return typeof h; + function h() { + return 7; + } +} +assertEq(h(), "function"); + +function i() { + return typeof i; + var i; +} +assertEq(i(), "undefined"); + +function j() { + return typeof j; +} +assertEq(j(), "function"); diff --git a/js/src/jit-test/tests/basic/call.js b/js/src/jit-test/tests/basic/call.js new file mode 100644 index 000000000..8e6b647b6 --- /dev/null +++ b/js/src/jit-test/tests/basic/call.js @@ -0,0 +1,28 @@ +function glob_f1() { + return 1; +} +function glob_f2() { + return glob_f1(); +} +function call() +{ + var q1 = 0, q2 = 0, q3 = 0, q4 = 0, q5 = 0; + var o = {}; + function f1() { + return 1; + } + function f2(f) { + return f(); + } + o.f = f1; + for (var i = 0; i < 100; ++i) { + q1 += f1(); + q2 += f2(f1); + q3 += glob_f1(); + q4 += o.f(); + q5 += glob_f2(); + } + var ret = String([q1, q2, q3, q4, q5]); + return ret; +} +assertEq(call(), "100,100,100,100,100"); diff --git a/js/src/jit-test/tests/basic/call2.js b/js/src/jit-test/tests/basic/call2.js new file mode 100644 index 000000000..9e68bb20a --- /dev/null +++ b/js/src/jit-test/tests/basic/call2.js @@ -0,0 +1,13 @@ +function g(x) { + if ((x & 1) == 1) return 1; + return 2; +} + +function f(n) { + var q = 0; + for (var i = 0; i < n; i++) + q += g(i); + return q; +} + +assertEq(f(1000), 1500); diff --git a/js/src/jit-test/tests/basic/compression-random-data.js b/js/src/jit-test/tests/basic/compression-random-data.js new file mode 100644 index 000000000..4e2bd579a --- /dev/null +++ b/js/src/jit-test/tests/basic/compression-random-data.js @@ -0,0 +1,26 @@ +// Deterministic Math.random, from Octane. +var seed = 49734321; +function rand() { + // Robert Jenkins' 32 bit integer hash function. + seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff; + seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff; + seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff; + seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff; + seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff; + seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff; + return (seed & 0xfffffff) / 0x10000000; +} +var randomS = ""; +function test(len) { + const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + var s = "var data = '"; + while (randomS.length < len) { + randomS += chars.charAt((rand() * chars.length)|0); + } + s += randomS; + s += "'; function f() {}; assertEq(f.toSource(), 'function f() {}');"; + eval(s); +} +for (var i=32740; i<32780; i += 5) { + test(i); +} diff --git a/js/src/jit-test/tests/basic/constAssignError.js b/js/src/jit-test/tests/basic/constAssignError.js new file mode 100644 index 000000000..3e93fb464 --- /dev/null +++ b/js/src/jit-test/tests/basic/constAssignError.js @@ -0,0 +1,23 @@ +// Can't assign to const is a runtime TypeError + +load(libdir + 'asserts.js'); + +function assertTypeError(str) { + assertThrowsInstanceOf(function () { eval(str); }, TypeError); +} + +assertTypeError("(function() { const x = 3; (() => x++)(); return x })()"); +assertTypeError("(function() { const x = 3; (() => x++)(); return x++ })()"); +assertTypeError("(function() { const x = 2; (() => x++)(); return ++x })()"); +assertTypeError("(function() { const x = 2; (() => x++)(); return x += 1 })()"); + +assertTypeError("(function() { const x = 3; x = 1; return (function() { return x})() })()"); +assertTypeError("(function() { const x = 3; x = 1; return (function() { return x})() })()"); +assertTypeError("(function() { const x = 3; x++; return (function() { return x})() })()"); +assertTypeError("(function() { const x = 3; ++x; return (function() { return x})() })()"); +assertTypeError("(function() { const x = 3; x--; return (function() { return x})() })()"); +assertTypeError("(function() { const x = 3; --x; return (function() { return x})() })()"); +assertTypeError("(function() { const x = 3; x += 1; return (function() { return x})() })()"); +assertTypeError("(function() { const x = 3; x -= 1; return (function() { return x})() })()"); + +assertTypeError("(function() { const x = 3; [x] = [1]; })()"); diff --git a/js/src/jit-test/tests/basic/constGlobalAssignError.js b/js/src/jit-test/tests/basic/constGlobalAssignError.js new file mode 100644 index 000000000..87c7b78f0 --- /dev/null +++ b/js/src/jit-test/tests/basic/constGlobalAssignError.js @@ -0,0 +1,3 @@ +// |jit-test| error: TypeError + +const x = 1; x = 2; diff --git a/js/src/jit-test/tests/basic/constant-folding-1.js b/js/src/jit-test/tests/basic/constant-folding-1.js new file mode 100644 index 000000000..5bcb73b13 --- /dev/null +++ b/js/src/jit-test/tests/basic/constant-folding-1.js @@ -0,0 +1,43 @@ +function bytecode(f) { + if (typeof disassemble !== "function") + return "unavailable"; + var d = disassemble(f); + return d.slice(d.indexOf("main:"), d.indexOf("\n\n")); +} +assertEq(bytecode(() => "hello" + "world"), + bytecode(() => "helloworld")); +assertEq(bytecode(() => 2 + "2" + "2"), + bytecode(() => "222")); +assertEq(bytecode(() => "x" + "3"), + bytecode(() => "x3")); + +var s = "hoge"; +assertEq(bytecode(() => "fo" + "o" + s + "ba" + "r"), + bytecode(() => "foo" + s + "bar")); +assertEq(bytecode(() => "fo" + "o" + 1 + s + 1 + "ba" + "r"), + bytecode(() => "foo1" + s + "1bar")); +assertEq(bytecode(() => 1 + (2 * 2) + "x"), + bytecode(() => 5 + "x")); +assertEq(s + 1 + 2, "hoge12"); +assertEq((() => s + 1 + 2)(), "hoge12"); + +// SpiderMonkey knows that 1 + 1 == "11". +assertEq(bytecode(() => "x" + s + 1 + 1), + bytecode(() => "x" + s + "11")); + +var n = 5; +assertEq(1 + n + 1 + "ba" + "r", "7bar"); +assertEq(1 + 2 + {valueOf: () => 3, toString: () => 'x'} + 4 + 5,15); +assertEq(1+2+n,8); +assertEq(bytecode(() => 1 + 2 + n + 1 + 2), + bytecode(() => 3 + n + 1 + 2)); +assertEq(1 + 2 + n + 1 + 2, 11); +assertEq(bytecode(() => 1 + 2 + s + 1 + 2), + bytecode(() => 3 + s + 1 + 2)); +assertEq(1 + 2 + s + 1 + 2, "3hoge12"); + +assertEq(bytecode(() => ["a" + "b" + n]), + bytecode(() => ["ab" + n])); +var a = ["a" + "b" + n]; +assertEq(a[0], "ab5"); + diff --git a/js/src/jit-test/tests/basic/construct-primitive-Function.prototype.prototype.js b/js/src/jit-test/tests/basic/construct-primitive-Function.prototype.prototype.js new file mode 100644 index 000000000..0b83325cf --- /dev/null +++ b/js/src/jit-test/tests/basic/construct-primitive-Function.prototype.prototype.js @@ -0,0 +1,5 @@ +Object.defineProperty(Function.prototype, "prototype", { + get: function() { throw 17; }, + set: function() { throw 42; } +}); +this.hasOwnProperty("Intl"); diff --git a/js/src/jit-test/tests/basic/constructor-name.js b/js/src/jit-test/tests/basic/constructor-name.js new file mode 100644 index 000000000..4bc6a61ea --- /dev/null +++ b/js/src/jit-test/tests/basic/constructor-name.js @@ -0,0 +1,28 @@ +function Ctor() {} + +var nested = {}; +nested.Ctor = function () {}; +nested.object = {}; + +function makeInstance() { + let LexicalCtor = function () {}; + return new LexicalCtor; +} + +function makeObject() { + let object = {}; + return object; +} + +let tests = [ + { name: "Ctor", object: new Ctor }, + { name: "nested.Ctor", object: new nested.Ctor }, + { name: "makeInstance/LexicalCtor", object: makeInstance() }, + { name: null, object: {} }, + { name: null, object: nested.object }, + { name: null, object: makeObject() }, +]; + +for (let { name, object } of tests) { + assertEq(getConstructorName(object), name); +} diff --git a/js/src/jit-test/tests/basic/createMandelSet.js b/js/src/jit-test/tests/basic/createMandelSet.js new file mode 100644 index 000000000..9898b5dc9 --- /dev/null +++ b/js/src/jit-test/tests/basic/createMandelSet.js @@ -0,0 +1,242 @@ +// |jit-test| slow; + +// XXXbz I would dearly like to wrap it up into a function to avoid polluting +// the global scope, but the function ends up heavyweight, and then we lose on +// the jit. +load(libdir + "mandelbrot-results.js"); +//function testMandelbrotAll() { + // Configuration options that affect which codepaths we follow. + var doImageData = true; + var avoidSparseArray = true; + + // Control of iteration numbers and sizing. We'll do + // scaler * colorNames.length iterations or so before deciding that we + // don't escape. + const scaler = 5; + const numRows = 600; + const numCols = 600; + + const colorNames = [ + "black", + "green", + "blue", + "red", + "purple", + "orange", + "cyan", + "yellow", + "magenta", + "brown", + "pink", + "chartreuse", + "darkorange", + "crimson", + "gray", + "deeppink", + "firebrick", + "lavender", + "lawngreen", + "lightsalmon", + "lime", + "goldenrod" + ]; + const threshold = (colorNames.length - 1) * scaler; + + // Now set up our colors + var colors = []; + // 3-part for loop (iterators buggy, we will add a separate test for them) + for (var colorNameIdx = 0; colorNameIdx < colorNames.length; ++colorNameIdx) { + //for (var colorNameIdx in colorNames) { + colorNameIdx = parseInt(colorNameIdx); + colors.push([colorNameIdx, colorNameIdx, colorNameIdx, 0]); + } + + // Storage for our point data + var points; + + var scratch = {}; + var scratchZ = {}; + function complexMult(a, b) { + var newr = a.r * b.r - a.i * b.i; + var newi = a.r * b.i + a.i * b.r; + scratch.r = newr; + scratch.i = newi; + return scratch; + } + function complexAdd(a, b) { + scratch.r = a.r + b.r; + scratch.i = a.i + b.i; + return scratch; + } + function abs(a) { + return Math.sqrt(a.r * a.r + a.i * a.i); + } + + function escapeAbsDiff(normZ, absC) { + var absZ = Math.sqrt(normZ); + return normZ > absZ + absC; + } + + function escapeNorm2(normZ) { + return normZ > 4; + } + + function fuzzyColors(i) { + return Math.floor(i / scaler) + 1; + } + + function moddedColors(i) { + return (i % (colorNames.length - 1)) + 1; + } + + function computeEscapeSpeedObjects(real, imag) { + var c = { r: real, i: imag } + scratchZ.r = scratchZ.i = 0; + var absC = abs(c); + for (var i = 0; i < threshold; ++i) { + scratchZ = complexAdd(c, complexMult(scratchZ, scratchZ)); + if (escape(scratchZ.r * scratchZ.r + scratchZ.i * scratchZ.i, + absC)) { + return colorMap(i); + } + } + return 0; + } + + function computeEscapeSpeedOneObject(real, imag) { + // fold in the fact that we start with 0 + var r = real; + var i = imag; + var absC = abs({r: real, i: imag}); + for (var j = 0; j < threshold; ++j) { + var r2 = r * r; + var i2 = i * i; + if (escape(r2 + i2, absC)) { + return colorMap(j); + } + i = 2 * r * i + imag; + r = r2 - i2 + real; + } + return 0; + } + + function computeEscapeSpeedDoubles(real, imag) { + // fold in the fact that we start with 0 + var r = real; + var i = imag; + var absC = Math.sqrt(real * real + imag * imag); + for (var j = 0; j < threshold; ++j) { + var r2 = r * r; + var i2 = i * i; + if (escape(r2 + i2, absC)) { + return colorMap(j); + } + i = 2 * r * i + imag; + r = r2 - i2 + real; + } + return 0; + } + + var computeEscapeSpeed = computeEscapeSpeedDoubles; + var escape = escapeNorm2; + var colorMap = fuzzyColors; + + function addPointOrig(pointArray, n, i, j) { + if (!points[n]) { + points[n] = []; + points[n].push([i, j, 1, 1]); + } else { + var point = points[n][points[n].length-1]; + if (point[0] == i && point[1] == j - point[3]) { + ++point[3]; + } else { + points[n].push([i, j, 1, 1]); + } + } + } + + function addPointImagedata(pointArray, n, col, row) { + var slotIdx = ((row * numCols) + col) * 4; + pointArray[slotIdx] = colors[n][0]; + pointArray[slotIdx+1] = colors[n][1]; + pointArray[slotIdx+2] = colors[n][2]; + pointArray[slotIdx+3] = colors[n][3]; + } + + function createMandelSet() { + var realRange = { min: -2.1, max: 1 }; + var imagRange = { min: -1.5, max: 1.5 }; + + var addPoint; + if (doImageData) { + addPoint = addPointImagedata; + points = new Array(4*numCols*numRows); + if (avoidSparseArray) { + for (var idx = 0; idx < 4*numCols*numRows; ++idx) { + points[idx] = 0; + } + } + } else { + addPoint = addPointOrig; + points = []; + } + var realStep = (realRange.max - realRange.min)/numCols; + var imagStep = (imagRange.min - imagRange.max)/numRows; + for (var i = 0, curReal = realRange.min; + i < numCols; + ++i, curReal += realStep) { + for (var j = 0, curImag = imagRange.max; + j < numRows; + ++j, curImag += imagStep) { + var n = computeEscapeSpeed(curReal, curImag); + addPoint(points, n, i, j) + } + } + var result; + if (doImageData) { + if (colorMap == fuzzyColors) { + result = mandelbrotImageDataFuzzyResult; + } else { + result = mandelbrotImageDataModdedResult; + } + } else { + result = mandelbrotNoImageDataResult; + } + return points.toSource() == result; + } + + const escapeTests = [ escapeAbsDiff ]; + const colorMaps = [ fuzzyColors, moddedColors ]; + const escapeComputations = [ computeEscapeSpeedObjects, + computeEscapeSpeedOneObject, + computeEscapeSpeedDoubles ]; + // Test all possible escape-speed generation codepaths, using the + // imageData + sparse array avoidance storage. + doImageData = true; + avoidSparseArray = true; + for (var escapeIdx in escapeTests) { + escape = escapeTests[escapeIdx]; + for (var colorMapIdx in colorMaps) { + colorMap = colorMaps[colorMapIdx]; + for (var escapeComputationIdx in escapeComputations) { + computeEscapeSpeed = escapeComputations[escapeComputationIdx]; + assertEq(createMandelSet(), true); + } + } + } + + // Test all possible storage strategies. Note that we already tested + // doImageData == true with avoidSparseArray == true. + escape = escapeAbsDiff; + colorMap = fuzzyColors; // This part doesn't really matter too much here + computeEscapeSpeed = computeEscapeSpeedDoubles; + + doImageData = true; + avoidSparseArray = false; + assertEq(createMandelSet(), true); + + escape = escapeNorm2; + doImageData = false; // avoidSparseArray doesn't matter here + assertEq(createMandelSet(), true); +//} +//testMandelbrotAll(); diff --git a/js/src/jit-test/tests/basic/cross-global-for-in.js b/js/src/jit-test/tests/basic/cross-global-for-in.js new file mode 100644 index 000000000..3fd772052 --- /dev/null +++ b/js/src/jit-test/tests/basic/cross-global-for-in.js @@ -0,0 +1,11 @@ +var global = newGlobal(); + +var arrayIter = (new global.Array())[global.Symbol.iterator](); +var ArrayIteratorPrototype = Object.getPrototypeOf(arrayIter); +var arrayIterProtoBase = Object.getPrototypeOf(ArrayIteratorPrototype); +var IteratorPrototype = arrayIterProtoBase; +delete IteratorPrototype.next; + +var obj = global.eval('({a: 1})') +for (var x in obj) {} +assertEq(x, "a"); diff --git a/js/src/jit-test/tests/basic/decompile-script.js b/js/src/jit-test/tests/basic/decompile-script.js new file mode 100644 index 000000000..523bc71fa --- /dev/null +++ b/js/src/jit-test/tests/basic/decompile-script.js @@ -0,0 +1,6 @@ +function example(a, b, c) { + var complicated = 3; + perform_some_operations(); +} +var myfun = function (a, b) a + b; +assertEq(decompileThis(), snarf(thisFilename())); diff --git a/js/src/jit-test/tests/basic/deep2.js b/js/src/jit-test/tests/basic/deep2.js new file mode 100644 index 000000000..2cf30b814 --- /dev/null +++ b/js/src/jit-test/tests/basic/deep2.js @@ -0,0 +1,11 @@ +function deep1(x) { + if (x > 90) + return 1; + return 2; +} +function deep2() { + for (var i = 0; i < 100; ++i) + deep1(i); + return "ok"; +} +assertEq(deep2(), "ok"); diff --git a/js/src/jit-test/tests/basic/deepForInLoop.js b/js/src/jit-test/tests/basic/deepForInLoop.js new file mode 100644 index 000000000..8bae45eb1 --- /dev/null +++ b/js/src/jit-test/tests/basic/deepForInLoop.js @@ -0,0 +1,12 @@ +function deepForInLoop() { + // NB: the number of props set in C is arefully tuned to match 8 = 2. + function C(){this.p = 1, this.q = 2} + C.prototype = {p:1, q:2, r:3, s:4, t:5}; + var o = new C; + var j = 0; + var a = []; + for (var i in o) + a[j++] = i; + return a.join(""); +} +assertEq(deepForInLoop(), "pqrst"); diff --git a/js/src/jit-test/tests/basic/defaultvalue-toString-is-noncallable-object-elem.js b/js/src/jit-test/tests/basic/defaultvalue-toString-is-noncallable-object-elem.js new file mode 100644 index 000000000..b5a28be55 --- /dev/null +++ b/js/src/jit-test/tests/basic/defaultvalue-toString-is-noncallable-object-elem.js @@ -0,0 +1,4 @@ +var arr = ["foo", "bar"]; +var obj = { toString: {}, valueOf: function() { return 1; } }; +for (var i = 0; i < 25; i++) + assertEq(arr[obj], "bar"); diff --git a/js/src/jit-test/tests/basic/defaultvalue-toString-is-noncallable-object.js b/js/src/jit-test/tests/basic/defaultvalue-toString-is-noncallable-object.js new file mode 100644 index 000000000..f0a30d115 --- /dev/null +++ b/js/src/jit-test/tests/basic/defaultvalue-toString-is-noncallable-object.js @@ -0,0 +1,3 @@ +var obj = { toString: {}, valueOf: function() { return "foopy"; } }; +for (var i = 0; i < 25; i++) + assertEq(String(obj), "foopy"); diff --git a/js/src/jit-test/tests/basic/defaultvalue-valueOf-is-noncallable-object.js b/js/src/jit-test/tests/basic/defaultvalue-valueOf-is-noncallable-object.js new file mode 100644 index 000000000..9bb2126b9 --- /dev/null +++ b/js/src/jit-test/tests/basic/defaultvalue-valueOf-is-noncallable-object.js @@ -0,0 +1,3 @@ +var obj = { valueOf: {}, toString: function() { return 0; } }; +for (var i = 0; i < 25; i++) + assertEq(obj < 1, true); diff --git a/js/src/jit-test/tests/basic/define-frozen-dense-strict.js b/js/src/jit-test/tests/basic/define-frozen-dense-strict.js new file mode 100644 index 000000000..a1e82e9c5 --- /dev/null +++ b/js/src/jit-test/tests/basic/define-frozen-dense-strict.js @@ -0,0 +1,16 @@ +"use strict"; +var t = [4]; +var stop; +Object.freeze(t); +do { + let ok = false; + stop = inIon(); + try { + t[1] = 2; + } catch(e) { + ok = true; + } + assertEq(ok, true); + assertEq(t.length, 1); + assertEq(t[1], undefined); +} while (!stop); diff --git a/js/src/jit-test/tests/basic/define-frozen-dense.js b/js/src/jit-test/tests/basic/define-frozen-dense.js new file mode 100644 index 000000000..7a7e2a97f --- /dev/null +++ b/js/src/jit-test/tests/basic/define-frozen-dense.js @@ -0,0 +1,9 @@ +var t = [4]; +var stop; +Object.freeze(t); +do { + stop = inIon(); + t[1] = 2; + assertEq(t.length, 1); + assertEq(t[1], undefined); +} while (!stop); diff --git a/js/src/jit-test/tests/basic/define-frozen-property-strict.js b/js/src/jit-test/tests/basic/define-frozen-property-strict.js new file mode 100644 index 000000000..7e2b2d818 --- /dev/null +++ b/js/src/jit-test/tests/basic/define-frozen-property-strict.js @@ -0,0 +1,14 @@ +function foo(x) { + "use strict"; + var ok = false; + try { + x.c = 10; + } catch(e) { + ok = true; + } + assertEq(ok, true); + assertEq(x.c, undefined); +} +x = {a:0,b:1}; +Object.freeze(x); +foo(x); diff --git a/js/src/jit-test/tests/basic/define-frozen-property.js b/js/src/jit-test/tests/basic/define-frozen-property.js new file mode 100644 index 000000000..759552c58 --- /dev/null +++ b/js/src/jit-test/tests/basic/define-frozen-property.js @@ -0,0 +1,7 @@ +function foo(x) { + x.c = 10; + assertEq(x.c, undefined); +} +x = {a:0,b:1}; +Object.freeze(x); +foo(x); diff --git a/js/src/jit-test/tests/basic/delete-array-elements.js b/js/src/jit-test/tests/basic/delete-array-elements.js new file mode 100644 index 000000000..e56fa36bd --- /dev/null +++ b/js/src/jit-test/tests/basic/delete-array-elements.js @@ -0,0 +1,7 @@ +var a = [0,1,2,3,4,5,6,7,8,9,10]; +for (var i = 0; i < 10; i++) + delete a[9 - i]; +assertEq(a.length, 11); +for (i = 0; i < 10; i++) + assertEq(a.hasOwnProperty(i), false); + diff --git a/js/src/jit-test/tests/basic/delete-indexed-names.js b/js/src/jit-test/tests/basic/delete-indexed-names.js new file mode 100644 index 000000000..9d30ebd17 --- /dev/null +++ b/js/src/jit-test/tests/basic/delete-indexed-names.js @@ -0,0 +1,7 @@ +var a = ['p', 'q', 'r', 's', 't']; +var o = {p:1, q:2, r:3, s:4, t:5}; +for (var i in o) + delete o[i]; +for each (var i in a) + assertEq(o.hasOwnProperty(i), false); + diff --git a/js/src/jit-test/tests/basic/delete-integer-nonid.js b/js/src/jit-test/tests/basic/delete-integer-nonid.js new file mode 100644 index 000000000..e016227cb --- /dev/null +++ b/js/src/jit-test/tests/basic/delete-integer-nonid.js @@ -0,0 +1,24 @@ +var JSID_INT_MIN = -(1 << 30); +var JSID_INT_MAX = (1 << 30) - 1; + +var o = {}; + + +for (var i = 0; i < 10; i++) + delete o[JSID_INT_MIN - 1]; + +for (var i = 0; i < 10; i++) + delete o[JSID_INT_MIN]; + +for (var i = 0; i < 10; i++) + delete o[JSID_INT_MIN + 1]; + + +for (var i = 0; i < 10; i++) + delete o[JSID_INT_MAX - 1]; + +for (var i = 0; i < 10; i++) + delete o[JSID_INT_MAX]; + +for (var i = 0; i < 10; i++) + delete o[JSID_INT_MAX + 1]; diff --git a/js/src/jit-test/tests/basic/delete-named-names.js b/js/src/jit-test/tests/basic/delete-named-names.js new file mode 100644 index 000000000..a4647bedd --- /dev/null +++ b/js/src/jit-test/tests/basic/delete-named-names.js @@ -0,0 +1,12 @@ +var a = ['p', 'q', 'r', 's', 't']; +var o = {p:1, q:2, r:3, s:4, t:5}; +for (var i in o) { + delete o.p; + delete o.q; + delete o.r; + delete o.s; + delete o.t; +} +for each (var i in a) + assertEq(o.hasOwnProperty(i), false); + diff --git a/js/src/jit-test/tests/basic/delete-non-config.js b/js/src/jit-test/tests/basic/delete-non-config.js new file mode 100644 index 000000000..da6020cad --- /dev/null +++ b/js/src/jit-test/tests/basic/delete-non-config.js @@ -0,0 +1,4 @@ +var a = [0,1,2,3,4,5,6,7,8,9,10]; +for (var i = 0; i < 10; i++) + assertEq(delete a.length, false); +assertEq(delete a.length, false); diff --git a/js/src/jit-test/tests/basic/deleteToString.js b/js/src/jit-test/tests/basic/deleteToString.js new file mode 100644 index 000000000..0b8dfc59d --- /dev/null +++ b/js/src/jit-test/tests/basic/deleteToString.js @@ -0,0 +1,5 @@ + +/* Inheritance of shadowed function properties from Object.prototype. */ + +delete Function.prototype.toString; +assertEq(Function.prototype.toString, Object.prototype.toString); diff --git a/js/src/jit-test/tests/basic/dense-elements-appear.js b/js/src/jit-test/tests/basic/dense-elements-appear.js new file mode 100644 index 000000000..351f8f676 --- /dev/null +++ b/js/src/jit-test/tests/basic/dense-elements-appear.js @@ -0,0 +1,28 @@ +function f() { + var x = [1, 2, 3]; + var y = {}; + x.__proto__ = y; + + for (var i = 0; i < 200; i++) { + if (i == 100) + y[100000] = 15; + else + assertEq(typeof x[100000], i > 100 ? "number" : "undefined"); + } +} + +function g() { + var x = [1, 2, 3]; + var y = {}; + x.__proto__ = y; + + for (var i = 0; i < 200; i++) { + if (i == 100) + y[4] = 15; + else + assertEq(typeof x[4], i > 100 ? "number" : "undefined"); + } +} + +f(); +g(); diff --git a/js/src/jit-test/tests/basic/dense-elements-hole-negative.js b/js/src/jit-test/tests/basic/dense-elements-hole-negative.js new file mode 100644 index 000000000..cf63da92e --- /dev/null +++ b/js/src/jit-test/tests/basic/dense-elements-hole-negative.js @@ -0,0 +1,31 @@ +// The index is negative before code generation. + +let v = {}; +let negativeIndex = -1; + +function f(obj) { + assertEq(obj[negativeIndex] === v, true); +} +for (let i = 0; i < 2000; i++) { + let obj = {}; + obj[1] = {}; + obj[negativeIndex] = v; + f(obj); +} + +// The sign of the index changes after the code generation. + +function g(obj, i) { + for (let j = 0; j < 4; j++) { + assertEq(obj[i-j] === v, true); + } +} +for (let i = 0; i < 2000; i++) { + let obj = {}; + obj[1] = {}; + let X = 2000 - i; + for (let j = 0; j < 10; j++) { + obj[X-j] = v; + } + g(obj, X); +} diff --git a/js/src/jit-test/tests/basic/dependentStrings.js b/js/src/jit-test/tests/basic/dependentStrings.js new file mode 100644 index 000000000..1dd38bbac --- /dev/null +++ b/js/src/jit-test/tests/basic/dependentStrings.js @@ -0,0 +1,11 @@ +function dependentStrings() +{ + var a = []; + var t = "abcdefghijklmnopqrst"; + for (var i = 0; i < 10; i++) { + var s = t.substring(2*i, 2*i + 2); + a[i] = s + s.length; + } + return a.join(""); +} +assertEq(dependentStrings(), "ab2cd2ef2gh2ij2kl2mn2op2qr2st2"); diff --git a/js/src/jit-test/tests/basic/destructuring-default.js b/js/src/jit-test/tests/basic/destructuring-default.js new file mode 100644 index 000000000..168977e80 --- /dev/null +++ b/js/src/jit-test/tests/basic/destructuring-default.js @@ -0,0 +1,254 @@ + +load(libdir + 'asserts.js'); +load(libdir + 'eqArrayHelper.js'); + +var arrayPattern = '[a = 1, b = 2, c = 3, d = 4, e = 5, f = 6]'; +var objectPattern = '{0: a = 1, 1: b = 2, 2: c = 3, 3: d = 4, 4: e = 5, 5: f = 6}'; +var objectPatternShorthand = '{a = 1, b = 2, c = 3, d = 4, e = 5, f = 6}'; +var nestedPattern = '{a: a = 1, b: [b = 2] = [], c: {c: [c]} = {c: [3]}, d: {d, e} = {d: 4, e: 5}, f: f = 6}'; + +function testAll(fn) { + assertEqArray(fn(arrayPattern, []), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(arrayPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]); + assertEqArray(fn(arrayPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]); + assertEqArray(fn(arrayPattern, [0, false]), [0, false, 3, 4, 5, 6]); + + assertEqArray(fn(objectPattern, []), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(objectPattern, [2, 3, 4, 5, 6, 7, 8, 9]), [2, 3, 4, 5, 6, 7]); + assertEqArray(fn(objectPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]); + assertEqArray(fn(objectPattern, [0, false]), [0, false, 3, 4, 5, 6]); + + assertEqArray(fn(objectPatternShorthand, {}), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(objectPatternShorthand, {a: 2, b: 3, c: 4, d: 5, e: 6, f: 7, g: 8, h: 9}), [2, 3, 4, 5, 6, 7]); + assertEqArray(fn(objectPatternShorthand, {a: undefined, b: 0, c: false, d: null, e: "", f: undefined}), + [1, 0, false, null, "", 6]); + assertEqArray(fn(objectPatternShorthand, {a: 0, b: false}), [0, false, 3, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {}), [1, 2, 3, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: 2, b: [], c: undefined}), [2, 2, 3, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}}), [1, 3, 4, 4, 5, 6]); + assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}, d: {d: 5, e: 6}}), [1, 3, 4, 5, 6, 6]); +} + +function testVar(pattern, input) { + return new Function('input', + 'var ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testVar); + +function testLet(pattern, input) { + return new Function('input', + 'let ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testLet); + +function testConst(pattern, input) { + return new Function('input', + 'const ' + pattern + ' = input;' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testConst); + +function testGlobal(pattern, input) { + return new Function('input', + '(' + pattern + ' = input);' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testGlobal); + +function testClosure(pattern, input) { + return new Function('input', + 'var rest; (function () {' + + '(' + pattern + ' = input);' + + '})();' + + 'return [a, b, c, d, e, f];' + )(input); +} +testAll(testClosure); + +function testArgument(pattern, input) { + return new Function('input', + 'return (function (' + pattern + ') {' + + 'return [a, b, c, d, e, f]; })(input);' + )(input); +} +testAll(testArgument); + +function testArgumentFunction(pattern, input) { + return new Function(pattern, + 'return [a, b, c, d, e, f];' + )(input); +} +// XXX: ES6 requires the `Function` constructor to accept arbitrary +// `BindingElement`s as formal parameters. See Bug 1037939. +// Once fixed, please update the assertions below. +assertThrowsInstanceOf(() => testAll(testArgumentFunction), SyntaxError); + +function testThrow(pattern, input) { + return new Function('input', + 'try { throw input }' + + 'catch(' + pattern + ') {' + + 'return [a, b, c, d, e, f]; }' + )(input); +} +testAll(testThrow); + +// test global const +const [ca = 1, cb = 2] = []; +assertEq(ca, 1); +assertEq(cb, 2); + +const {a: {a: cc = 3} = {a: undefined}} = {}; +assertEq(cc, 3); + +// test that the assignment happens in source order +var a = undefined, b = undefined, c = undefined; +({a: a = 1, c: c = 2, b: b = 3} = { + get a() { + assertEq(a, undefined); + assertEq(c, undefined); + assertEq(b, undefined); + return undefined; + }, + get b() { + assertEq(a, 1); + assertEq(c, 2); + assertEq(b, undefined); + return 4; + }, + get c() { + assertEq(a, 1); + assertEq(c, undefined); + assertEq(b, undefined); + return undefined; + } +}); +assertEq(b, 4); + +assertThrowsInstanceOf(() => { var {a: {a} = null} = {}; }, TypeError); +assertThrowsInstanceOf(() => { var [[a] = 2] = []; }, TypeError); + +// destructuring assignment might have duplicate variable names. +var [a = 1, a = 2] = [3]; +assertEq(a, 2); + +// assignment to properties of default params +[a = {y: 2}, a.x = 1] = []; +assertEq(typeof a, 'object'); +assertEq(a.x, 1); +assertEq(a.y, 2); + +// defaults are evaluated even if there is no binding +var evaled = false; +({a: {} = (evaled = true, {})} = {}); +assertEq(evaled, true); +evaled = false; +assertThrowsInstanceOf(() => { [[] = (evaled = true, 2)] = [] }, TypeError); +assertEq(evaled, true); + +assertThrowsInstanceOf(() => new Function('var [...rest = defaults] = [];'), SyntaxError); + +new Function(` + b = undefined; + for (var [a, b = 10] in " ") {} + assertEq(b, 10);`)(); + +new Function(` + b = undefined; + for (let [a, c = 10] in " ") { b = c; } + assertEq(b, 10);`)(); + +new Function(` + b = undefined; + for (let [a, c = (x => y)] in " ") { b = c; } + assertEq(typeof b, "function");`)(); + +new Function(` + b = undefined; + for (let [a, __proto__ = 10] in " ") { b = __proto__; } + assertEq(b, 10);`)(); + +new Function(` + b = undefined; + for (let [a, __proto__ = (x => y)] in " ") { b = __proto__; } + assertEq(typeof b, "function");`)(); + +new Function(` + b = undefined; + for (var {1: b = 10} in " ") {} + assertEq(b, 10);`)(); + +new Function(` + b = undefined; + for (let {1: c = 10} in " ") { b = c; } + assertEq(b, 10);`)(); + +new Function(` + b = undefined; + for (let { c = 10 } in " ") { b = c; } + assertEq(b, 10);`)(); + +new Function(` + b = undefined; + assertEq(Number.prototype.a, undefined); + for (var { a: c = (x => y) } in [{}]) { b = c; } + assertEq(typeof b, "function");`)(); + +new Function(` + b = undefined; + Object.defineProperty(String.prototype, "__proto__", + { value: undefined, configurable: true }); + for (var { __proto__: c = (x => y) } in [{}]) { b = c; } + delete String.prototype.__proto__; + assertEq(typeof b, "function");`)(); + +new Function(` + b = undefined; + for (var { a: c = (x => y) } of [{ a: undefined }]) { b = c; } + assertEq(typeof b, "function");`)(); + +new Function(` + b = undefined; + for (var { __proto__: c = (x => y) } of [{ ["__proto__"]: undefined }]) { b = c; } + assertEq(typeof b, "function");`)(); + +new Function(` + b = undefined; + var ts = Function.prototype.toString; + Function.prototype.toString = () => 'hi'; + String.prototype.hi = 42; + for (var { [(x => y)]: c } in [0]) { b = c; } + Function.prototype.toString = ts; + delete String.prototype.hi; + assertEq(b, 42);`)(); + +new Function(` + b = undefined; + var ts = Function.prototype.toString; + Function.prototype.toString = () => 'hi'; + String.prototype.hi = 42; + for (var { [(x => y)]: __proto__ } in [0]) { b = __proto__; } + Function.prototype.toString = ts; + delete String.prototype.hi; + assertEq(b, 42);`)(); + +new Function(` + b = undefined; + var ts = Function.prototype.toString; + Function.prototype.toString = () => 'hi'; + for (var { [(x => y)]: c } of [{ 'hi': 42 }]) { b = c; } + Function.prototype.toString = ts; + assertEq(b, 42);`)(); + +new Function(` + b = undefined; + var ts = Function.prototype.toString; + Function.prototype.toString = () => 'hi'; + for (var { [(x => y)]: __proto__ } of [{ hi: 42 }]) { b = __proto__; } + Function.prototype.toString = ts; + assertEq(b, 42);`)(); diff --git a/js/src/jit-test/tests/basic/destructuring-iterator.js b/js/src/jit-test/tests/basic/destructuring-iterator.js new file mode 100644 index 000000000..ca6593024 --- /dev/null +++ b/js/src/jit-test/tests/basic/destructuring-iterator.js @@ -0,0 +1,124 @@ + +load(libdir + 'asserts.js'); +load(libdir + 'iteration.js'); +load(libdir + 'eqArrayHelper.js'); + +// throw on non-iterables +assertThrowsInstanceOf(() => { [a, b, c] = {0: 0, 1: 1, 2: 2} }, TypeError); + +var nextcalls = 0, donecalls = 0, valuecalls = 0; +var doneafter = 0; +var iterable = {}; +iterable[Symbol.iterator] = function () { + return { + next: function () { + assertEq(arguments.length, 0, 'iterator.next() should be called with no arguments'); + nextcalls++; + return { + get done() { + donecalls++; + return --doneafter < 0; + }, + get value() { + valuecalls++; + return valuecalls; + } + }; + } + } +}; + +function assertIterable(expectCalls, fn, expectResult) { + [nextcalls, donecalls, valuecalls, doneafter] = [0,0,0, expectCalls[3]]; + assertEqArray(fn(iterable), expectResult); + assertEq(nextcalls, expectCalls[0], 'calls to iterator.next()'); + assertEq(donecalls, expectCalls[1], 'getting iterator.next().done'); + assertEq(valuecalls, expectCalls[2], 'getting iterator.next().value'); +} + +assertIterable([1,1,1,1], + it => { var [a] = it; return [a]; }, + [1]); +assertIterable([2,2,1,1], + it => { var [a,b,c] = it; return [a,b,c]; }, + [1,undefined,undefined]); +assertIterable([2,2,1,1], + it => { var [a,b,...rest] = it; return [a,b,...rest]; }, + [1,undefined]); +assertIterable([5,5,4,4], + it => { var [,,...rest] = it; return rest; }, + [3,4]); + +// the iterator should be exhausted before any error is thrown +assertIterable([5,5,4,4], + it => { + assertThrowsInstanceOf(function () { + "use strict"; + [...{0: "".x}] = it; + }, TypeError); + return []; + }, + []); + +var arraycalls = 0; +var ArrayIterator = Array.prototype[Symbol.iterator]; +Array.prototype[Symbol.iterator] = function () { + arraycalls++; + return ArrayIterator.apply(this, arguments); +}; +// [...rest] should not call Array#@@iterator for the LHS +var [...rest] = iterable; +assertEq(arraycalls, 0, 'calls to Array#@@iterator'); +// [...[...rest]] should do so, since it creates an implicit array for the +// first rest pattern, then destructures that again using @@iterator() for the +// second rest pattern. +var [...[...rest]] = iterable; +assertEq(arraycalls, 1, 'calls to Array#@@iterator'); + +// loop `fn` a few times, to get it JIT-compiled +function loop(fn) { + var i = 1e4; + while (i--) fn(); +} + +loop(() => { doneafter = 4; var [a] = iterable; return a; }); +loop(() => { doneafter = 4; var [a,b,...[...rest]] = iterable; return rest; }); + + +// destructuring assignment should always use iterators and not optimize +// to a "group assignment" +delete Array.prototype[Symbol.iterator]; +assertThrowsInstanceOf(() => { var [a,b] = [1,2]; }, TypeError); +Array.prototype[Symbol.iterator] = ArrayIterator; + +// observe the binding order +a = undefined, b = undefined, c = undefined; +var obj = {}; +obj[Symbol.iterator] = function* () { + // normal fields should be initialized right after |.next()| + yield 1; + assertEq(a, 1); + yield 2; + yield 3; + assertEq(b, 3); + yield 4; + yield 5; + // rest should be initialized after the iterator is exhausted + assertEq(c, undefined); +}; +[a, , b, ...c] = obj; +assertEqArray(c, [4,5]); + +// a throw inside the destructuring of the "catch" value should not enter +// the "catch" block + +assertThrowsValue(function () { + try { + Array.prototype[Symbol.iterator] = function () { throw 'from iterator'; }; + throw [1, 2]; + } catch ([x, y]) { + throw 'not reached'; + } +}, 'from iterator'); +Array.prototype[Symbol.iterator] = ArrayIterator; + diff --git a/js/src/jit-test/tests/basic/destructuring-null-or-undefined-into-computed-property-name.js b/js/src/jit-test/tests/basic/destructuring-null-or-undefined-into-computed-property-name.js new file mode 100644 index 000000000..c5d75801a --- /dev/null +++ b/js/src/jit-test/tests/basic/destructuring-null-or-undefined-into-computed-property-name.js @@ -0,0 +1,47 @@ +load(libdir + 'asserts.js'); +load(libdir + 'iteration.js'); + +var outer = "unmodified"; + +function f(v) +{ + if (v + "") + ({ [(outer = "modified")]: v } = v); +} + +assertEq(outer, "unmodified"); +f(true); +assertEq(outer, "modified"); + +outer = "unmodified"; +f({}); +assertEq(outer, "modified"); + +outer = "unmodified"; +assertThrowsInstanceOf(() => f(null), TypeError); +assertEq(outer, "unmodified"); + +assertThrowsInstanceOf(() => f(undefined), TypeError); +assertEq(outer, "unmodified"); + + +function g(v) +{ + if (v + "") + ({ [{ toString() { outer = "modified"; return 0; } }]: v } = v); +} + +outer = "unmodified"; +g(true); +assertEq(outer, "modified"); + +outer = "unmodified"; +g({}); +assertEq(outer, "modified"); + +outer = "unmodified"; +assertThrowsInstanceOf(() => g(undefined), TypeError); +assertEq(outer, "unmodified"); + +assertThrowsInstanceOf(() => g(null), TypeError); +assertEq(outer, "unmodified"); diff --git a/js/src/jit-test/tests/basic/destructuring-requireobjectcoercible.js b/js/src/jit-test/tests/basic/destructuring-requireobjectcoercible.js new file mode 100644 index 000000000..c2b1403d3 --- /dev/null +++ b/js/src/jit-test/tests/basic/destructuring-requireobjectcoercible.js @@ -0,0 +1,107 @@ +load(libdir + 'asserts.js'); +load(libdir + 'iteration.js'); + +function f(v) +{ + if (v + "") + ({} = v); +} + +f(true); +f({}); +assertThrowsInstanceOf(() => f(null), TypeError); +assertThrowsInstanceOf(() => f(undefined), TypeError); + +function g(v) +{ + if (v + "") + ({} = v); +} + +g(true); +g({}); +assertThrowsInstanceOf(() => g(undefined), TypeError); +assertThrowsInstanceOf(() => g(null), TypeError); + +function h(v) +{ + if (v + "") + ([] = v); +} + +h([true]); +h("foo"); +assertThrowsInstanceOf(() => h(undefined), TypeError); +assertThrowsInstanceOf(() => h(null), TypeError); + +Object.defineProperty(Boolean.prototype, "v", + { get() { "use strict"; return typeof this; }, + enumerable: true, + configurable: true }); + +Object.defineProperty(Number.prototype, "v", + { get() { "use strict"; return typeof this; }, + enumerable: true, + configurable: true }); + +Object.defineProperty(String.prototype, "v", + { get() { "use strict"; return typeof this; }, + enumerable: true, + configurable: true }); + +Object.defineProperty(Symbol.prototype, "v", + { get() { "use strict"; return typeof this; }, + enumerable: true, + configurable: true }); + +function primitiveThisSupported() +{ + return 3.14.custom === "number"; +} + +function primitiveThisTests() +{ + function f(v) + { + var type = typeof v; + + ({ v } = v); + + assertEq(v, type); + } + + f(true); + f(3.14); + f(72); + f("ohai"); + f(Symbol.iterator); + + assertThrowsInstanceOf(() => f(undefined), TypeError); + assertThrowsInstanceOf(() => f(null), TypeError); + + function g(v) + { + var type = typeof v; + + ({ v } = v); + + assertEq(v, type); + } + + g(true); + g(3.14); + g(72); + g("ohai"); + g(Symbol.iterator); + + assertThrowsInstanceOf(() => g(null), TypeError); + assertThrowsInstanceOf(() => g(undefined), TypeError); +} +if (primitiveThisSupported()) + primitiveThisTests(); + +// Ensure the internal implementation of destructuring object pattern +// assignment -- using a self-hosted intrinsic function -- works even when lazy +// standard class initialization hasn't occurred. Unfortunately we can't use +// |newGlobal()| because that method eagerly initializes standard classes. +evalcx("({} = 1);", evalcx("lazy")); diff --git a/js/src/jit-test/tests/basic/destructuring-rest-identifiers.js b/js/src/jit-test/tests/basic/destructuring-rest-identifiers.js new file mode 100644 index 000000000..437a66668 --- /dev/null +++ b/js/src/jit-test/tests/basic/destructuring-rest-identifiers.js @@ -0,0 +1,73 @@ + +load(libdir + 'asserts.js'); +load(libdir + 'eqArrayHelper.js'); + +var reserved = [ + 'break', + 'do', + 'in', + 'typeof', + 'case', + 'else', + 'instanceof', + 'var', + 'catch', + 'export', + 'new', + 'void', + 'class', + 'extends', + 'return', + 'while', + 'const', + 'finally', + 'super', + 'with', + 'continue', + 'for', + 'switch', + 'debugger', + 'function', + 'this', + 'delete', + 'import', + 'try', + 'enum', + 'null', + 'true', + 'false' +]; +reserved.forEach(ident => { + assertThrowsInstanceOf(() => new Function('var [...' + ident + '] = []'), SyntaxError); +}); + +var strictIdentifiers = [ + // XXX: see bug 1032150. Once fixed, please uncomment these values and + // remove the assertions below + //'yield', + //'let', + 'eval', + 'arguments', + 'implements', + 'interface', + 'package', + 'private', + 'protected', + 'public', + 'static' +]; +assertThrowsInstanceOf(() => new Function('[...yield] = []'), SyntaxError); +assertThrowsInstanceOf(() => new Function('"use strict"; [...let] = []'), SyntaxError); + +strictIdentifiers.forEach(ident => + assertThrowsInstanceOf(() => + new Function('"use strict"; [...' + ident + '] = []'), SyntaxError)); + +var globalEval = eval; +strictIdentifiers.forEach(ident => { + globalEval(ident + ' = null'); + assertEqArray(new Function('input', '[, ...' + ident + '] = input;' + + 'return ' + ident + )([1, 2, 3]), [2, 3]); +}); + diff --git a/js/src/jit-test/tests/basic/destructuring-rest.js b/js/src/jit-test/tests/basic/destructuring-rest.js new file mode 100644 index 000000000..f53f07e03 --- /dev/null +++ b/js/src/jit-test/tests/basic/destructuring-rest.js @@ -0,0 +1,148 @@ + +load(libdir + 'asserts.js'); +load(libdir + 'eqArrayHelper.js'); + +assertThrowsInstanceOf(() => new Function('[...a, ,] = []'), SyntaxError, 'trailing elision'); +assertThrowsInstanceOf(() => new Function('[a, ...b, c] = []'), SyntaxError, 'trailing param'); +assertThrowsInstanceOf(() => new Function('[...a=b] = []'), SyntaxError, 'assignment expression'); +assertThrowsInstanceOf(() => new Function('[...a()] = []'), SyntaxError, 'call expression'); +assertThrowsInstanceOf(() => new Function('[...(a,b)] = []'), SyntaxError, 'comma expression'); +assertThrowsInstanceOf(() => new Function('[...a++] = []'), SyntaxError, 'postfix expression'); +assertThrowsInstanceOf(() => new Function('[...!a] = []'), SyntaxError, 'unary expression'); +assertThrowsInstanceOf(() => new Function('[...a+b] = []'), SyntaxError, 'binary expression'); +assertThrowsInstanceOf(() => new Function('var [...a.x] = []'), SyntaxError, 'lvalue expression in declaration'); +assertThrowsInstanceOf(() => new Function('var [...(b)] = []'), SyntaxError); +assertThrowsInstanceOf(() => new Function('[...b,] = []'), SyntaxError); + +assertThrowsInstanceOf(() => { + try { + eval('let [...[...x]] = (() => { throw "foo"; } )();'); + } catch(e) { + assertEq(e, "foo"); + } + x; +}, ReferenceError); + +var inputArray = [1, 2, 3]; +var inputDeep = [1, inputArray]; +var inputObject = {a: inputArray}; +var inputStr = 'str'; +function *inputGenerator() { + yield 1; + yield 2; + yield 3; +} + +var o = {prop: null, call: function () { return o; }}; + +var expected = [2, 3]; +var expectedStr = ['t', 'r']; + +function testAll(fn) { + testDeclaration(fn); + + o.prop = null; + assertEqArray(fn('[, ...(o.prop)]', inputArray, 'o.prop'), expected); + o.prop = null; + assertEqArray(fn('[, ...(o.call().prop)]', inputArray, 'o.prop'), expected); + + o.prop = null; + assertEqArray(fn('[, ...[...(o.prop)]]', inputArray, 'o.prop'), expected); + o.prop = null; + assertEqArray(fn('[, ...[...(o.call().prop)]]', inputArray, 'o.prop'), expected); +} +function testDeclaration(fn) { + testStr(fn); + + assertEqArray(fn('[, ...rest]', inputArray), expected); + assertEqArray(fn('[, ...rest]', inputGenerator()), expected); + assertEqArray(fn('[, [, ...rest]]', inputDeep), expected); + assertEqArray(fn('{a: [, ...rest]}', inputObject), expected); + + assertEqArray(fn('[, ...[...rest]]', inputArray), expected); + assertEqArray(fn('[, ...[...rest]]', inputGenerator()), expected); + assertEqArray(fn('[, [, ...[...rest]]]', inputDeep), expected); + assertEqArray(fn('{a: [, ...[...rest]]}', inputObject), expected); + + assertEqArray(fn('[, ...{0: a, 1: b}]', inputArray, '[a, b]'), expected); + assertEqArray(fn('[, ...{0: a, 1: b}]', inputGenerator(), '[a, b]'), expected); + assertEqArray(fn('[, [, ...{0: a, 1: b}]]', inputDeep, '[a, b]'), expected); + assertEqArray(fn('{a: [, ...{0: a, 1: b}]}', inputObject, '[a, b]'), expected); +} + +function testStr(fn) { + assertEqArray(fn('[, ...rest]', inputStr), expectedStr); + + assertEqArray(fn('[, ...[...rest]]', inputStr), expectedStr); + + assertEqArray(fn('[, ...{0: a, 1: b}]', inputStr, '[a, b]'), expectedStr); +} + +function testForIn(pattern, input, binding) { + binding = binding || 'rest'; + return new Function('input', + 'for (var ' + pattern + ' in {[input]: 1}) {}' + + 'return ' + binding + )(input); +} +testStr(testForIn); + +function testVar(pattern, input, binding) { + binding = binding || 'rest'; + return new Function('input', + 'var ' + pattern + ' = input;' + + 'return ' + binding + )(input); +} +testDeclaration(testVar); + +function testGlobal(pattern, input, binding) { + binding = binding || 'rest'; + return new Function('input', + '(' + pattern + ' = input);' + + 'return ' + binding + )(input); +} +testAll(testGlobal); + +function testClosure(pattern, input, binding) { + binding = binding || 'rest'; + const decl = binding.replace('[', '').replace(']', ''); + return new Function('input', + 'var ' + decl + '; (function () {' + + '(' + pattern + ' = input);' + + '})();' + + 'return ' + binding + )(input); +} +testDeclaration(testClosure); + +function testArgument(pattern, input, binding) { + binding = binding || 'rest'; + return new Function('input', + 'return (function (' + pattern + ') {' + + 'return ' + binding + '; })(input);' + )(input); +} +testDeclaration(testArgument); + +function testArgumentFunction(pattern, input, binding) { + binding = binding || 'rest'; + return new Function(pattern, + 'return ' + binding + )(input); +} +// XXX: ES6 requires the `Function` constructor to accept arbitrary +// `BindingElement`s as formal parameters. See Bug 1037939. +// Once fixed, please update the assertions below. +assertThrowsInstanceOf(() => testDeclaration(testArgumentFunction), SyntaxError); + +function testThrow(pattern, input, binding) { + binding = binding || 'rest'; + return new Function('input', + 'try { throw input }' + + 'catch(' + pattern + ') {' + + 'return ' + binding + '; }' + )(input); +} +testDeclaration(testThrow); diff --git a/js/src/jit-test/tests/basic/display-url-in-stack-trace.js b/js/src/jit-test/tests/basic/display-url-in-stack-trace.js new file mode 100644 index 000000000..acab47ab6 --- /dev/null +++ b/js/src/jit-test/tests/basic/display-url-in-stack-trace.js @@ -0,0 +1,27 @@ +eval(` + function a() { + return b(); + } + //# sourceURL=source-a.js +`); + +eval(` + function b() { + return c(); + } + //# sourceURL=source-b.js +`); + +eval(` + function c() { + return Error().stack; + } + //# sourceURL=source-c.js +`); + +let filenames = a().split(/\n/) + .map(f => f.slice(f.indexOf("@") + 1, f.indexOf(":"))); +print(filenames.join("\n")); +assertEq(filenames[0], "source-c.js"); +assertEq(filenames[1], "source-b.js"); +assertEq(filenames[2], "source-a.js"); diff --git a/js/src/jit-test/tests/basic/doMath.js b/js/src/jit-test/tests/basic/doMath.js new file mode 100644 index 000000000..8129a466e --- /dev/null +++ b/js/src/jit-test/tests/basic/doMath.js @@ -0,0 +1,60 @@ +function map_test(t, cases) +{ + for (var i = 0; i < cases.length; i++) { + function c() { return t(cases[i].input); } + var expected = cases[i].expected; + assertEq(c(), expected); + } +} + +function lsh_inner(n) +{ + var r; + for (var i = 0; i < 35; i++) + r = 0x1 << n; + return r; +} +map_test (lsh_inner, + [{input: 15, expected: 32768}, + {input: 55, expected: 8388608}, + {input: 1, expected: 2}, + {input: 0, expected: 1}]); + +function rsh_inner(n) +{ + var r; + for (var i = 0; i < 35; i++) + r = 0x11010101 >> n; + return r; +} +map_test (rsh_inner, + [{input: 8, expected: 1114369}, + {input: 5, expected: 8914952}, + {input: 35, expected: 35659808}, + {input: -1, expected: 0}]); + +function ursh_inner(n) +{ + var r; + for (var i = 0; i < 35; i++) + r = -55 >>> n; + return r; +} +map_test (ursh_inner, + [{input: 8, expected: 16777215}, + {input: 33, expected: 2147483620}, + {input: 0, expected: 4294967241}, + {input: 1, expected: 2147483620}]); + +function doMath_inner(cos) +{ + var s = 0; + var sin = Math.sin; + for (var i = 0; i < 200; i++) + s = -Math.pow(sin(i) + cos(i * 0.75), 4); + return s; +} +function doMath() { + return doMath_inner(Math.cos); +} +assertEq(doMath(), -0.5405549555611059); diff --git a/js/src/jit-test/tests/basic/dumpStringRepresentation.js b/js/src/jit-test/tests/basic/dumpStringRepresentation.js new file mode 100644 index 000000000..43d3feefd --- /dev/null +++ b/js/src/jit-test/tests/basic/dumpStringRepresentation.js @@ -0,0 +1,70 @@ +// Try the dumpStringRepresentation shell function on various types of +// strings, and make sure it doesn't crash. + +if (typeof dumpStringRepresentation !== 'function') + quit(0); + +print("Empty string:"); +dumpStringRepresentation(""); + +print("\nResult of coercion to string:"); +dumpStringRepresentation(); + +print("\ns = Simple short atom:"); +var s = "xxxxxxxx"; +dumpStringRepresentation(s); + +// Simple non-atom flat. +print("\ns + s: Non-atom flat:"); +var s2 = s + s; +dumpStringRepresentation(s2); + +print("\nNon-Latin1 flat:"); +var j = "渋谷区"; +dumpStringRepresentation(j); + +print("\nt = Non-inline atom:"); +var t = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // 31 characters +dumpStringRepresentation(t); + +print("\nr1 = t + s: Simple rope:"); +var r1 = t + s; +dumpStringRepresentation(r1); + +// Flatten that rope, and re-examine the representations of both the result and +// its former leaves. This should be an extensible string. +print("\nr1, former rope after flattening, now extensible:"); +r1.match(/x/); +dumpStringRepresentation(r1); + +print("\nt, s: Original leaves, representation unchanged:"); +dumpStringRepresentation(t); +dumpStringRepresentation(s); + +// Create a new rope with the extensible string as its left child. +print("\nr2 = r1 + s: Rope with extensible leftmost child:"); +var r2 = r1 + s; +dumpStringRepresentation(r2); + +// Flatten that; this should re-use the extensible string's buffer. +print("\nr2: flattened, stole r1's buffer:"); +r2.match(/x/); +dumpStringRepresentation(r2); + +print("\nr1: mutated into a dependent string:"); +dumpStringRepresentation(r1); + +print("\nr3 = r2 + s: a new rope with an extensible leftmost child:"); +r3 = r2 + s; +r3.match(/x/); +dumpStringRepresentation(r3); + +print("\nr2: now mutated into a dependent string"); +dumpStringRepresentation(r2); + +print("\nr1: now a doubly-dependent string, because of r2's mutation:"); +dumpStringRepresentation(r1); + +print("\nt, s: Original leaves, representation unchanged:"); +dumpStringRepresentation(t); +dumpStringRepresentation(s); diff --git a/js/src/jit-test/tests/basic/eif-generator.js b/js/src/jit-test/tests/basic/eif-generator.js new file mode 100644 index 000000000..99a45bf5a --- /dev/null +++ b/js/src/jit-test/tests/basic/eif-generator.js @@ -0,0 +1,58 @@ +load(libdir + "evalInFrame.js"); + +function f() { + { + let x = 1; + while (true) { + yield evalInFrame(0, "x"); + x++; + { + let y = 1; + yield evalInFrame(0, "++y"); + yield evalInFrame(0, "++y"); + } + } + } +} + +var gen = f(); +assertEq(gen.next(), 1); +assertEq(gen.next(), 2); +gc(); +assertEq(gen.next(), 3); +gc(); +assertEq(gen.next(), 2); +assertEq(gen.next(), 2); +gc(); +assertEq(gen.next(), 3); +gc(); +assertEq(gen.next(), 3); +assertEq(gen.next(), 2); +gc(); +assertEq(gen.next(), 3); +gen = null; +gc(); + +function g() { + { + let x = 1; + while (true) { + var inner = function (inc) { x += inc; return evalInFrame(0, "x") }; + assertEq(inner(0), x); + yield inner; + assertEq(inner(0), x); + } + } +} + +var gen = g(); +var g1 = gen.next(); +var g2 = gen.next(); +gc(); +assertEq(g1(1), 2); +assertEq(g2(1), 3); +gc(); +assertEq(g1(1), 4); +assertEq(g2(1), 5); +gen = g1 = g2 = null; +gc(); diff --git a/js/src/jit-test/tests/basic/emulates-undefined.js b/js/src/jit-test/tests/basic/emulates-undefined.js new file mode 100644 index 000000000..616a37b19 --- /dev/null +++ b/js/src/jit-test/tests/basic/emulates-undefined.js @@ -0,0 +1,18 @@ +function test() { + var values = [undefined, null, Math, objectEmulatingUndefined()]; + var expected = [true, true, false, true]; + + for (var i=0; i<100; i++) { + var idx = i % values.length; + if (values[idx] == undefined) + assertEq(expected[idx], true); + else + assertEq(expected[idx], false); + + if (null != values[idx]) + assertEq(expected[idx], false); + else + assertEq(expected[idx], true); + } +} +test(); diff --git a/js/src/jit-test/tests/basic/equalInt.js b/js/src/jit-test/tests/basic/equalInt.js new file mode 100644 index 000000000..d63c8815d --- /dev/null +++ b/js/src/jit-test/tests/basic/equalInt.js @@ -0,0 +1,29 @@ +function equalInt() +{ + var i1 = 55, one = 1, zero = 0, undef; + var o1 = { }, o2 = { }; + var s = "5"; + var hits = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; + for (var i = 0; i < 5000; i++) { + if (i1 == 55) hits[0]++; + if (i1 != 56) hits[1]++; + if (i1 < 56) hits[2]++; + if (i1 > 50) hits[3]++; + if (i1 <= 60) hits[4]++; + if (i1 >= 30) hits[5]++; + if (i1 == 7) hits[6]++; + if (i1 != 55) hits[7]++; + if (i1 < 30) hits[8]++; + if (i1 > 90) hits[9]++; + if (i1 <= 40) hits[10]++; + if (i1 >= 70) hits[11]++; + if (o1 == o2) hits[12]++; + if (o2 != null) hits[13]++; + if (s < 10) hits[14]++; + if (true < zero) hits[15]++; + if (undef > one) hits[16]++; + if (undef < zero) hits[17]++; + } + return hits.toString(); +} +assertEq(equalInt(), "5000,5000,5000,5000,5000,5000,0,0,0,0,0,0,0,5000,5000,0,0,0"); diff --git a/js/src/jit-test/tests/basic/error-stack-accessors.js b/js/src/jit-test/tests/basic/error-stack-accessors.js new file mode 100644 index 000000000..9bbcae14b --- /dev/null +++ b/js/src/jit-test/tests/basic/error-stack-accessors.js @@ -0,0 +1,31 @@ +// Test the Error.prototype.stack getter/setter with various "fun" edge cases. + +load(libdir + "asserts.js"); + +// Stack should be accessible in subclasses. The accessor should walk up the +// prototype chain. +assertEq(typeof Object.create(Error()).stack, "string"); +assertEq(Object.create(Error.prototype).stack, ""); + +// Stack should be overridable in subclasses. +{ + let myError = Object.create(Error()); + myError.stack = 5; + assertEq(myError.stack, 5); + + let myOtherError = Object.create(Error.prototype); + myOtherError.stack = 2; + assertEq(myOtherError.stack, 2); +} + +// Should throw when there is no Error in the `this` object's prototype chain. +var obj = Object.create(null); +var desc = Object.getOwnPropertyDescriptor(Error.prototype, "stack"); +Object.defineProperty(obj, "stack", desc); +assertThrowsInstanceOf(() => obj.stack, TypeError); + +// Should throw with non-object `this` values. +assertThrowsInstanceOf(desc.set, TypeError); +assertThrowsInstanceOf(desc.set.bind("string"), TypeError); +assertThrowsInstanceOf(desc.get, TypeError); +assertThrowsInstanceOf(desc.get.bind("string"), TypeError); diff --git a/js/src/jit-test/tests/basic/error-toString.js b/js/src/jit-test/tests/basic/error-toString.js new file mode 100644 index 000000000..44839333d --- /dev/null +++ b/js/src/jit-test/tests/basic/error-toString.js @@ -0,0 +1,9 @@ +var errorToString = Error.prototype.toString; + + +assertEq(errorToString.call({message: "", name: ""}), ""); +assertEq(errorToString.call({name: undefined, message: ""}), "Error"); +assertEq(errorToString.call({name: "Test", message: undefined}), "Test"); +assertEq(errorToString.call({name: "Test", message: ""}), "Test"); +assertEq(errorToString.call({name: "", message: "Test"}), "Test"); +assertEq(errorToString.call({name: "Test", message: "it!"}), "Test: it!"); diff --git a/js/src/jit-test/tests/basic/eval-introduction-principals.js b/js/src/jit-test/tests/basic/eval-introduction-principals.js new file mode 100644 index 000000000..fe63e9191 --- /dev/null +++ b/js/src/jit-test/tests/basic/eval-introduction-principals.js @@ -0,0 +1,16 @@ +// Ensure the introduction info for eval scripts respects principal checks. + +function myAPI(f) { return f(); } + +var contentGlobal = newGlobal({principal: 0x1}); +contentGlobal.chrome = this; +contentGlobal.eval("\n" + + "function contentTest() { chrome.myAPI(eval.bind(undefined, 'chrome.stack = Error().stack;')) };\n" + + "contentTest();"); + +// Note that the stack below does not include the current filename or file +// line numbers, and there's no trace of the myAPI call between the two +// evals. +assertEq(stack, "@eval line 2 > eval:1:16\n" + + "contentTest@eval:2:26\n" + + "@eval:3:1\n"); diff --git a/js/src/jit-test/tests/basic/eval-scopes.js b/js/src/jit-test/tests/basic/eval-scopes.js new file mode 100644 index 000000000..1342ef564 --- /dev/null +++ b/js/src/jit-test/tests/basic/eval-scopes.js @@ -0,0 +1,133 @@ +function bytecode(f) { + if (typeof disassemble !== "function") + return "unavailable"; + var d = disassemble(f); + return d.slice(d.indexOf("main:"), d.indexOf("\n\n")); +} + +function hasGname(f, v, hasIt = true) { + // Do a try-catch that prints the full stack, so we can tell + // _which_ part of this test failed. + try { + var b = bytecode(f); + if (b != "unavailable") { + assertEq(b.includes(`getgname "${v}"`), hasIt); + assertEq(b.includes(`getname "${v}"`), !hasIt); + } + } catch (e) { + print(e.stack); + throw e; + } +} + +var x = "outer"; + +setLazyParsingDisabled(true); +{ + let x = "inner"; + eval("function g() { assertEq(x, 'inner');} g()"); + eval("function g2() { (function nest() { assertEq(x, 'inner'); })(); } g2()"); +} +eval(` + function g3() { + assertEq(x, 'outer'); + } + g3(); + hasGname(g3, 'x'); + `); +eval(` + function g4() { + function nest() { assertEq(x, 'outer'); } + nest(); + return nest; + } + hasGname(g4(), 'x'); + `); +setLazyParsingDisabled(false); + +{ + let x = "inner"; + eval("function h() { assertEq(x, 'inner');} h()"); + eval("function h2() { (function nest() { assertEq(x, 'inner'); })(); } h2()"); +} + +// GNAME optimizations should work through lazy parsing. +eval(` + function h3() { + assertEq(x, 'outer'); + } + h3(); + hasGname(h3, 'x', true); + `); +eval(` + function h4() { + function nest() { assertEq(x, 'outer'); } + nest(); + return nest; + } + hasGname(h4(), 'x', true); + `); + +setLazyParsingDisabled(true); +with ({}) { + let x = "inner"; + eval("function i() { assertEq(x, 'inner');} i()"); + eval("function i2() { (function nest() { assertEq(x, 'inner'); })(); } i2()"); +} +setLazyParsingDisabled(false); + +with ({}) { + let x = "inner"; + eval("function j() { assertEq(x, 'inner');} j()"); + eval("function j2() { (function nest() { assertEq(x, 'inner'); })(); } j2()"); +} + +setLazyParsingDisabled(true); +(function () { + var x = "inner"; + eval("function k() { assertEq(x, 'inner');} k()"); + eval("function k2() { (function nest() { assertEq(x, 'inner'); })(); } k2()"); +})(); +setLazyParsingDisabled(false); + +(function () { + let x = "inner"; + eval("function l() { assertEq(x, 'inner');} l()"); + eval("function l2() { (function nest() { assertEq(x, 'inner'); })(); } l2()"); +})(); + +var y1 = 5; +eval(` + 'use strict'; + var y1 = 6; + assertEq(y1, 6); + (function() { assertEq(y1, 6); })() + `); +assertEq(y1, 5); + +eval(` + 'use strict'; + var y2 = 6; + assertEq(y2, 6); + (function() { assertEq(y2, 6); })() + `); + +setLazyParsingDisabled(true); + +var y3 = 5; +eval(` + 'use strict'; + var y3 = 6; + assertEq(y3, 6); + (function() { assertEq(y3, 6); })() + `); +assertEq(y3, 5); + +eval(` + 'use strict'; + var y4 = 6; + assertEq(y4, 6); + (function() { assertEq(y4, 6); })() + `); + +setLazyParsingDisabled(false); diff --git a/js/src/jit-test/tests/basic/evalInWorker-interrupt.js b/js/src/jit-test/tests/basic/evalInWorker-interrupt.js new file mode 100644 index 000000000..f4ec3b831 --- /dev/null +++ b/js/src/jit-test/tests/basic/evalInWorker-interrupt.js @@ -0,0 +1,3 @@ +if (helperThreadCount() === 0) + quit(); +evalInWorker("setInterruptCallback(function() {}); timeout(1000);"); diff --git a/js/src/jit-test/tests/basic/evalInWorker-nested.js b/js/src/jit-test/tests/basic/evalInWorker-nested.js new file mode 100644 index 000000000..1ae480503 --- /dev/null +++ b/js/src/jit-test/tests/basic/evalInWorker-nested.js @@ -0,0 +1,5 @@ +try { + evalInWorker("evalInWorker('evalInWorker(\"assertEq(1, 1)\")')"); +} catch(e) { + assertEq(e.toString().includes("--no-threads"), true); +} diff --git a/js/src/jit-test/tests/basic/evalInWorker-stack-limit.js b/js/src/jit-test/tests/basic/evalInWorker-stack-limit.js new file mode 100644 index 000000000..c1a1f472f --- /dev/null +++ b/js/src/jit-test/tests/basic/evalInWorker-stack-limit.js @@ -0,0 +1,8 @@ +try { + evalInWorker(` + function f() { f(); } + try { f(); } catch(e) {} + `); +} catch(e) { + assertEq(e.toString().includes("--no-threads"), true); +} diff --git a/js/src/jit-test/tests/basic/evaluate-catchTermination.js b/js/src/jit-test/tests/basic/evaluate-catchTermination.js new file mode 100644 index 000000000..6a9d3c74a --- /dev/null +++ b/js/src/jit-test/tests/basic/evaluate-catchTermination.js @@ -0,0 +1,6 @@ +// Test evaluate's catchTermination option. + +var x = 0; +assertEq(evaluate('x = 1; terminate(); x = 2;', { catchTermination: true }), + "terminated"); +assertEq(x, 1); diff --git a/js/src/jit-test/tests/basic/evaluate-restore-options.js b/js/src/jit-test/tests/basic/evaluate-restore-options.js new file mode 100644 index 000000000..263cc7272 --- /dev/null +++ b/js/src/jit-test/tests/basic/evaluate-restore-options.js @@ -0,0 +1,11 @@ +// Bug 791157: the shell 'evaluate' function should properly restore the +// context's options. + +try { + evaluate('%', {noScriptRval: true}); +} catch(e) {} +new Function(""); + +try { + evaluate('new Function("");', {noScriptRval: true}); +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/evaluate-worker.js b/js/src/jit-test/tests/basic/evaluate-worker.js new file mode 100644 index 000000000..3c810a43e --- /dev/null +++ b/js/src/jit-test/tests/basic/evaluate-worker.js @@ -0,0 +1,22 @@ +// |jit-test| slow + +if (typeof evalInWorker == "undefined") + quit(); + +gcslice(11); +evalInWorker("print('helo world');"); +for (i = 0; i < 100000; i++) {} + +evalInWorker("\ + for (var i = 0; i < 10; i++) { \ + var o = {}; \ + for (var j = 0; j < 100; j++) \ + o['a' + j] = j; \ + JSON.stringify(o); \ + o = null; \ + gc(); \ +}"); +for (var i = 0; i < 10; i++) { + gc(); + for (var j = 0; j < 100000; j++) {} +} diff --git a/js/src/jit-test/tests/basic/exception-column-number.js b/js/src/jit-test/tests/basic/exception-column-number.js new file mode 100644 index 000000000..c1dc99a31 --- /dev/null +++ b/js/src/jit-test/tests/basic/exception-column-number.js @@ -0,0 +1,11 @@ +try { + Array.indexOf(); +} catch (e) { + assertEq(e.columnNumber, 5); + // Filter the filename from the stack, since we have no clue what + // to expect there. Search for ':' from the end, because the file + // path may contain ':' in it. + var lastColon = e.stack.lastIndexOf(':'); + var afterPath = e.stack.lastIndexOf(':', lastColon - 1); + assertEq(e.stack.substring(afterPath), ":2:5\n"); +} diff --git a/js/src/jit-test/tests/basic/expression-autopsy.js b/js/src/jit-test/tests/basic/expression-autopsy.js new file mode 100644 index 000000000..defbe8592 --- /dev/null +++ b/js/src/jit-test/tests/basic/expression-autopsy.js @@ -0,0 +1,138 @@ +load(libdir + "asserts.js"); +load(libdir + "iteration.js"); + +function check_one(expected, f, err) { + var failed = true; + try { + f(); + failed = false; + } catch (ex) { + var s = ex.toString(); + assertEq(s.slice(0, 11), "TypeError: "); + assertEq(s.slice(-err.length), err, "" + f); + assertEq(s.slice(11, -err.length), expected); + } + if (!failed) + throw new Error("didn't fail"); +} +ieval = eval; +function check(expr, expected=expr, testStrict=true) { + var end, err; + for ([end, err] of [[".random_prop", " is undefined"], ["()", " is not a function"]]) { + var statement = "o = {};" + expr + end, f; + var cases = [ + // Global scope + function () { + ieval("var o, undef;\n" + statement); + }, + // Function scope + Function("o", "undef", statement), + // Function scope with variables + Function("var o, undef;\n" + statement), + // Function scope with some different arugments + Function("arg1", "arg2", "var o, undef;\n" + statement), + // Deoptimized function scope + Function("o", "undef", "with (Object) {}\n" + statement), + // Inside with + Function("with (Object) { " + statement + " }"), + // Closure + Function("o", "undef", "function myfunc() { return o + undef; }\n" + statement), + // Let definitions in a block + Function("{ let o, undef;\n" + statement + "}"), + // Let in a switch + Function("var x = 4; switch (x) { case 4: let o, undef;" + statement + "\ncase 6: break;}"), + // Try-catch blocks + Function("o", "undef", "try { let q = 4; try { let p = 4; } catch (e) {} } catch (e) {} { let o, undef; " + statement + " }"), + // Let in for-in (uses with to prevent jit compilation: bug 942804, bug 831120 and bug 1041586) + Function("with ({}) {} var undef, o; for (let z in [1, 2]) { " + statement + " }"), + ]; + + if (testStrict) { + // Strict mode. + cases.push(Function("o", "undef", "\"use strict\";\n" + statement)); + } + + for (var f of cases) { + check_one(expected, f, err); + } + } +} + +check("undef"); +check("o.b"); +check("o.length"); +check("o[true]"); +check("o[false]"); +check("o[null]"); +check("o[0]"); +check("o[1]"); +check("o[3]"); +check("o[256]"); +check("o[65536]"); +check("o[268435455]"); +check("o['1.1']"); +check("o[4 + 'h']", "o['4h']"); +check("ieval(undef)", "ieval(...)"); +check("ieval.call()", "ieval.call(...)"); +check("ieval(...[])", "ieval(...)"); +check("ieval(...[undef])", "ieval(...)"); +check("ieval(...[undef, undef])", "ieval(...)"); +check("(o[0] = 4).foo", "o[0].foo"); +// NOTE: This one produces different output in strict mode since "this" is +// undefined in that case. +check("this.x", "this.x", false); + +for (let tok of ["|", "^", "&", "==", "!==", "===", "!==", "<", "<=", ">", ">=", + ">>", "<<", ">>>", "+", "-", "*", "/", "%"]) { + check("o[(undef " + tok + " 4)]"); +} + +check("o[!(o)]"); +check("o[~(o)]"); +check("o[+ (o)]"); +check("o[- (o)]"); + + +// A few one off tests +check_one("6", (function () { 6() }), " is not a function"); +check_one("4", (function() { (4||eval)(); }), " is not a function"); +check_one("0", (function () { Array.prototype.reverse.call('123'); }), " is read-only"); +check_one("(intermediate value)[Symbol.iterator](...).next(...).value", + function () { ieval("{ let x; var [a, b, [c0, c1]] = [x, x, x]; }") }, " is undefined"); +check_one("void 1", function() { (void 1)(); }, " is not a function"); +check_one("void o[1]", function() { var o = []; (void o[1])() }, " is not a function"); + +// Manual testing for this case: the only way to trigger an error is *not* on +// an attempted property access during destructuring, and the error message +// invoking ToObject(null) is different: "can't convert {0} to object". +try +{ + (function() { + var [{x}] = [null, {}]; + })(); + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "expected TypeError, got " + e); + assertEq(e.message, "can't convert null to object"); +} + +try { + (function() { + "use strict"; + var o = []; + Object.freeze(o); + o[0] = "foo"; + }()); + throw new Error("didn't throw"); +} catch (e) { + assertEq(e instanceof TypeError, true, + "expected TypeError, got " + e); + assertEq(e.message, + "can't define array index property past the end of an array with non-writable length"); +} + +// Check fallback behavior +assertThrowsInstanceOf(function () { for (let x of undefined) {} }, TypeError); diff --git a/js/src/jit-test/tests/basic/external-strings.js b/js/src/jit-test/tests/basic/external-strings.js new file mode 100644 index 000000000..e8d62ac8b --- /dev/null +++ b/js/src/jit-test/tests/basic/external-strings.js @@ -0,0 +1,16 @@ +assertEq(newExternalString(""), ""); +assertEq(newExternalString("abc"), "abc"); +assertEq(newExternalString("abc\0def\u1234"), "abc\0def\u1234"); + +var o = {foo: 2, "foo\0": 4}; +var ext = newExternalString("foo"); +assertEq(o[ext], 2); +var ext2 = newExternalString("foo\0"); +assertEq(o[ext2], 4); + +eval(newExternalString("assertEq(1, 1)")); + +// Make sure ensureFlat does the right thing for external strings. +ext = newExternalString("abc\0defg\0"); +assertEq(ensureFlatString(ext), "abc\0defg\0"); +assertEq(ensureFlatString(ext), "abc\0defg\0"); diff --git a/js/src/jit-test/tests/basic/fannkuch.js b/js/src/jit-test/tests/basic/fannkuch.js new file mode 100644 index 000000000..a6154f2df --- /dev/null +++ b/js/src/jit-test/tests/basic/fannkuch.js @@ -0,0 +1,17 @@ +function fannkuch() { + var count = Array(8); + var r = 8; + var done = 0; + while (done < 40) { + // write-out the first 30 permutations + done += r; + while (r != 1) { count[r - 1] = r; r--; } + while (true) { + count[r] = count[r] - 1; + if (count[r] > 0) break; + r++; + } + } + return done; +} +assertEq(fannkuch(), 41); diff --git a/js/src/jit-test/tests/basic/finally-implicit-return.js b/js/src/jit-test/tests/basic/finally-implicit-return.js new file mode 100644 index 000000000..3bbd78d38 --- /dev/null +++ b/js/src/jit-test/tests/basic/finally-implicit-return.js @@ -0,0 +1,45 @@ +// Implicit return at the end of a function should return |undefined|, +// even if we initially set another return value and then executed a finally +// block. + +function test1() { + try { + try { + return 3; + } finally { + throw 4; + } + } catch (e) {} +} +assertEq(test1(), undefined); + +function test2() { + L: try { + return 3; + } finally { + break L; + } +} +assertEq(test2(), undefined); + +function test3() { + for (var i=0; i<2; i++) { + try { + return 5; + } finally { + continue; + } + } +} +assertEq(test3(), undefined); + +// "return;" should work the same way. +function test4() { + L: try { + return 6; + } finally { + break L; + } + return; +} +assertEq(test4(), undefined); diff --git a/js/src/jit-test/tests/basic/firstSlotConflict.js b/js/src/jit-test/tests/basic/firstSlotConflict.js new file mode 100644 index 000000000..fa394691b --- /dev/null +++ b/js/src/jit-test/tests/basic/firstSlotConflict.js @@ -0,0 +1,10 @@ +(function(x) { + function f1() { return 1; } + function f2() { return 2; } + function f3() { return 3; } + function f4() { return 4; } + var g = function () { return x; } + var a = [f1, f2, f3, f4, g]; + for each (var v in a) + v.adhoc = 42; // Don't assertbotch in jsbuiltins.cpp setting g.adhoc +})(33); diff --git a/js/src/jit-test/tests/basic/folding-bug767660.js b/js/src/jit-test/tests/basic/folding-bug767660.js new file mode 100644 index 000000000..7fc8b7c2c --- /dev/null +++ b/js/src/jit-test/tests/basic/folding-bug767660.js @@ -0,0 +1,2 @@ +var j, w; +if (j && w && w && true) {} diff --git a/js/src/jit-test/tests/basic/forVarInWith.js b/js/src/jit-test/tests/basic/forVarInWith.js new file mode 100644 index 000000000..593805642 --- /dev/null +++ b/js/src/jit-test/tests/basic/forVarInWith.js @@ -0,0 +1,12 @@ +function forVarInWith() { + function foo() { return {notk:42}; } + function bar() { return {p:1, q:2, r:3, s:4, t:5}; }; + var o = foo(); + var a = []; + with (o) { + for (var k in bar()) + a[a.length] = k; + } + return a.join(""); +} +assertEq(forVarInWith(), "pqrst"); diff --git a/js/src/jit-test/tests/basic/function-apply-proxy.js b/js/src/jit-test/tests/basic/function-apply-proxy.js new file mode 100644 index 000000000..9a00fdb3d --- /dev/null +++ b/js/src/jit-test/tests/basic/function-apply-proxy.js @@ -0,0 +1,26 @@ +// fun.apply(null, proxy) should not invoke the proxy's Has trap. + +var proxy = new Proxy({}, { + get: function (target, name, proxy) { + switch (name) { + case "length": + return 2; + case "0": + return 15; + case "1": + return undefined; + default: + assertEq(false, true); + } + }, + has: function (target, name) { + assertEq(false, true); + } +}); +function foo() { + assertEq(arguments.length, 2); + assertEq(arguments[0], 15); + assertEq(1 in arguments, true); + assertEq(arguments[1], undefined); +} +foo.apply(null, proxy); diff --git a/js/src/jit-test/tests/basic/function-bind.js b/js/src/jit-test/tests/basic/function-bind.js new file mode 100644 index 000000000..7831ef068 --- /dev/null +++ b/js/src/jit-test/tests/basic/function-bind.js @@ -0,0 +1,21 @@ +var A = Array.bind(1, 1, 2); + +var a1; +for (var i = 0; i < 5; i++) + a1 = A(3, 4); + +assertEq(a1.length, 4); +assertEq(a1[0], 1); +assertEq(a1[1], 2); +assertEq(a1[2], 3); +assertEq(a1[3], 4); + +var a2; +for (var i = 0; i < 5; i++) + a2 = new A(3, 4); + +assertEq(a2.length, 4); +assertEq(a2[0], 1); +assertEq(a2[1], 2); +assertEq(a2[2], 3); +assertEq(a2[3], 4); diff --git a/js/src/jit-test/tests/basic/function-cloning-1.js b/js/src/jit-test/tests/basic/function-cloning-1.js new file mode 100644 index 000000000..92511b15b --- /dev/null +++ b/js/src/jit-test/tests/basic/function-cloning-1.js @@ -0,0 +1,4 @@ +var g = newGlobal(); +var f1 = g.evaluate("(function (x) { function inner() {}; })"); +gczeal(2, 1); // Exercise all the edge cases in cloning, please. +var f2 = clone(f1); diff --git a/js/src/jit-test/tests/basic/function-cloning-2.js b/js/src/jit-test/tests/basic/function-cloning-2.js new file mode 100644 index 000000000..755a178e7 --- /dev/null +++ b/js/src/jit-test/tests/basic/function-cloning-2.js @@ -0,0 +1,9 @@ +if (typeof oomAtAllocation === 'object') { + var a = []; + oomAtAllocation(1); + try { + a.forEach(); + } catch (e) { + } + a.forEach(()=>1); +} diff --git a/js/src/jit-test/tests/basic/function-gname.js b/js/src/jit-test/tests/basic/function-gname.js new file mode 100644 index 000000000..851ca6be2 --- /dev/null +++ b/js/src/jit-test/tests/basic/function-gname.js @@ -0,0 +1,49 @@ +function bytecode(f) { + if (typeof disassemble !== "function") + return "unavailable"; + var d = disassemble(f); + return d.slice(d.indexOf("main:"), d.indexOf("\n\n")); +} + +function hasGname(f, v) { + // Do a try-catch that prints the full stack, so we can tell + // _which_ part of this test failed. + try { + var b = bytecode(f); + if (b != "unavailable") { + assertEq(b.includes(`getgname "${v}"`), true); + assertEq(b.includes(`getname "${v}"`), false); + } + } catch (e) { + print(e.stack); + throw e; + } +} + +var x = "outer"; + +var f1 = new Function("assertEq(x, 'outer')"); +f1(); +hasGname(f1, 'x'); + +setLazyParsingDisabled(true); +var f2 = new Function("assertEq(x, 'outer')"); +f2(); +hasGname(f2, 'x'); +setLazyParsingDisabled(false); + +{ + let x = "inner"; + var f3 = new Function("assertEq(x, 'outer')"); + f3(); + hasGname(f3, 'x'); +} + +setLazyParsingDisabled(true); +{ + let x = "inner"; + var f4 = new Function("assertEq(x, 'outer')"); + f4(); + hasGname(f4, 'x'); +} +setLazyParsingDisabled(false); diff --git a/js/src/jit-test/tests/basic/function-tosource-bug779694.js b/js/src/jit-test/tests/basic/function-tosource-bug779694.js new file mode 100644 index 000000000..3893d3ff2 --- /dev/null +++ b/js/src/jit-test/tests/basic/function-tosource-bug779694.js @@ -0,0 +1,8 @@ +// This test creates poorly compressible input, which tests certain paths in +// source code compression. +var x = ""; +for (var i=0; i<400; ++i) { + x += String.fromCharCode(i * 289); +} +var s = "'" + x + "'"; +assertEq(Function("evt", s).toString(), "function anonymous(evt) {\n" + s + "\n}"); diff --git a/js/src/jit-test/tests/basic/function-tosource-constructor.js b/js/src/jit-test/tests/basic/function-tosource-constructor.js new file mode 100644 index 000000000..e1d144364 --- /dev/null +++ b/js/src/jit-test/tests/basic/function-tosource-constructor.js @@ -0,0 +1,14 @@ +var f = Function("a", "b", "return a + b;"); +assertEq(f.toString(), "function anonymous(a, b) {\nreturn a + b;\n}"); +assertEq(f.toSource(), "(function anonymous(a, b) {\nreturn a + b;\n})"); +assertEq(decompileFunction(f), f.toString()); +f = Function("a", "...rest", "return rest[42] + b;"); +assertEq(f.toString(), "function anonymous(a, ...rest) {\nreturn rest[42] + b;\n}"); +assertEq(f.toSource(), "(function anonymous(a, ...rest) {\nreturn rest[42] + b;\n})") +assertEq(decompileFunction(f), f.toString()); +f = Function(""); +assertEq(f.toString(), "function anonymous() {\n\n}"); +f = Function("", "(abc)"); +assertEq(f.toString(), "function anonymous() {\n(abc)\n}"); +f = Function("", "return function (a, b) a + b;")(); +assertEq(f.toString(), "function (a, b) a + b"); diff --git a/js/src/jit-test/tests/basic/function-tosource-exprbody-bug777834.js b/js/src/jit-test/tests/basic/function-tosource-exprbody-bug777834.js new file mode 100644 index 000000000..be5d60ccd --- /dev/null +++ b/js/src/jit-test/tests/basic/function-tosource-exprbody-bug777834.js @@ -0,0 +1,5 @@ +load(libdir + "asserts.js"); + +assertThrowsInstanceOf(function () { + eval("function f()((l()))++2s"); +}, SyntaxError); diff --git a/js/src/jit-test/tests/basic/function-tosource-exprbody.js b/js/src/jit-test/tests/basic/function-tosource-exprbody.js new file mode 100644 index 000000000..b78e06e04 --- /dev/null +++ b/js/src/jit-test/tests/basic/function-tosource-exprbody.js @@ -0,0 +1,31 @@ +function f1(foo, bar) foo + bar; +assertEq(f1.toString(), "function f1(foo, bar) foo + bar"); +assertEq(f1.toString(), f1.toSource()); +assertEq(decompileFunction(f1), f1.toString()); +// No semicolon on purpose +function f2(foo, bar) foo + bar +assertEq(f2.toString(), "function f2(foo, bar) foo + bar"); +assertEq(f2.toString(), f2.toSource()); +var f3 = function (foo, bar) foo + bar; +assertEq(f3.toSource(), "(function (foo, bar) foo + bar)"); +assertEq(f3.toString(), "function (foo, bar) foo + bar"); +// No semicolon on purpose +var f4 = function (foo, bar) foo + bar +assertEq(f4.toSource(), "(function (foo, bar) foo + bar)"); +assertEq(f4.toString(), "function (foo, bar) foo + bar"); +var f5 = function (foo, bar) foo + bar ; +assertEq(f5.toSource(), "(function (foo, bar) foo + bar)"); +assertEq(f5.toString(), "function (foo, bar) foo + bar"); +var f6 = function (foo, bar) foo + bar; var a = 42 +assertEq(f6.toSource(), "(function (foo, bar) foo + bar)"); +assertEq(f6.toString(), "function (foo, bar) foo + bar"); +var f7 = function (foo, bar) foo + bar + '\ +long\ +string\ +test\ +' +// a comment followed by some space + + +assertEq(f7.toString(), "function (foo, bar) foo + bar + '\\\nlong\\\nstring\\\ntest\\\n'"); +assertEq(f7.toSource(), "(" + f7.toString() + ")"); diff --git a/js/src/jit-test/tests/basic/function-tosource-func-proto.js b/js/src/jit-test/tests/basic/function-tosource-func-proto.js new file mode 100644 index 000000000..be14ddfb2 --- /dev/null +++ b/js/src/jit-test/tests/basic/function-tosource-func-proto.js @@ -0,0 +1,2 @@ +assertEq(Function.prototype.toString(), "function () {\n}"); +assertEq(Function.prototype.toSource(), "function () {\n}"); diff --git a/js/src/jit-test/tests/basic/function-tosource-getset.js b/js/src/jit-test/tests/basic/function-tosource-getset.js new file mode 100644 index 000000000..36c6d010e --- /dev/null +++ b/js/src/jit-test/tests/basic/function-tosource-getset.js @@ -0,0 +1,7 @@ +var o = {get prop() a + b, set prop(x) a + b}; +var prop = Object.getOwnPropertyDescriptor(o, "prop"); +assertEq(prop.get.toString(), "function get prop() a + b"); +assertEq(prop.get.toSource(), "(function get prop() a + b)"); +assertEq(prop.set.toString(), "function set prop(x) a + b"); +assertEq(prop.set.toSource(), "(function set prop(x) a + b)"); +assertEq(o.toSource(), "({get prop () a + b, set prop (x) a + b})"); diff --git a/js/src/jit-test/tests/basic/function-tosource-lambda.js b/js/src/jit-test/tests/basic/function-tosource-lambda.js new file mode 100644 index 000000000..5c013fcba --- /dev/null +++ b/js/src/jit-test/tests/basic/function-tosource-lambda.js @@ -0,0 +1,12 @@ +var f1 = function f0(a, b) { return a + b; } +assertEq(f1.toSource(), "(function f0(a, b) { return a + b; })"); +assertEq(f1.toString(), "function f0(a, b) { return a + b; }"); +assertEq(decompileFunction(f1), f1.toString()); +var f2 = function (a, b) { return a + b; }; +assertEq(f2.toSource(), "(function (a, b) { return a + b; })"); +assertEq(f2.toString(), "function (a, b) { return a + b; }"); +assertEq(decompileFunction(f2), f2.toString()); +var f3 = (function (a, b) { return a + b; }); +assertEq(f3.toSource(), "(function (a, b) { return a + b; })"); +assertEq(f3.toString(), "function (a, b) { return a + b; }"); +assertEq(decompileFunction(f3), f3.toString()); diff --git a/js/src/jit-test/tests/basic/function-tosource-statement.js b/js/src/jit-test/tests/basic/function-tosource-statement.js new file mode 100644 index 000000000..c0c990e4f --- /dev/null +++ b/js/src/jit-test/tests/basic/function-tosource-statement.js @@ -0,0 +1,11 @@ +function f1(a, b) { + return a + b; +} +assertEq(f1.toString(), "function f1(a, b) {\n return a + b;\n}"); +assertEq(f1.toSource(), f1.toString()); +function f2(a, /* ))))pernicious comment */ b, + c, // another comment(( + d) {} +assertEq(f2.toString(), "function f2(a, /* ))))pernicious comment */ b,\n c, // another comment((\n d) {}"); +function f3() { } +assertEq(f3.toString(), "function f3() { }"); diff --git a/js/src/jit-test/tests/basic/functionRedeclConst.js b/js/src/jit-test/tests/basic/functionRedeclConst.js new file mode 100644 index 000000000..fd7fec655 --- /dev/null +++ b/js/src/jit-test/tests/basic/functionRedeclConst.js @@ -0,0 +1,5 @@ +// |jit-test| error: SyntaxError +{ + const x = 0; + function x() { } +} diff --git a/js/src/jit-test/tests/basic/functionRedeclGlobalConst.js b/js/src/jit-test/tests/basic/functionRedeclGlobalConst.js new file mode 100644 index 000000000..117811b6b --- /dev/null +++ b/js/src/jit-test/tests/basic/functionRedeclGlobalConst.js @@ -0,0 +1,3 @@ +// |jit-test| error: SyntaxError +const x = 0; +function x() { } diff --git a/js/src/jit-test/tests/basic/functionRedeclLet.js b/js/src/jit-test/tests/basic/functionRedeclLet.js new file mode 100644 index 000000000..7014c3ba8 --- /dev/null +++ b/js/src/jit-test/tests/basic/functionRedeclLet.js @@ -0,0 +1,5 @@ +// |jit-test| error: SyntaxError +{ + let x; + function x() { } +} diff --git a/js/src/jit-test/tests/basic/functionnames.js b/js/src/jit-test/tests/basic/functionnames.js new file mode 100644 index 000000000..935292ee3 --- /dev/null +++ b/js/src/jit-test/tests/basic/functionnames.js @@ -0,0 +1,158 @@ +/* + * Most of these test cases are adapted from: + * http://johnjbarton.github.com/nonymous/index.html + */ + +function assertName(fn, name) { + assertEq(displayName(fn), name) +} + +/* simple names */ +var a = function b() {}; +function c() {}; +assertName(a, 'b'); +assertName(c, 'c'); + +var a = function(){}, + b = function(){}; +assertName(a, 'a'); +assertName(b, 'b'); + +/* nested names */ +var main = function() { + function Foo(a) { assertName(a, 'main/foo<') } + var foo = new Foo(function() {}); +}; +assertName(main, 'main') +main(); + +/* duplicated */ +var Baz = Bar = function(){} +assertName(Baz, 'Bar'); +assertName(Bar, 'Bar'); + +/* returned from an immediate function */ +var Foo = function (){ + assertName(arguments.callee, 'Foo<') + return function(){}; +}(); +assertName(Foo, 'Foo</<'); + +/* various properties and such */ +var x = {fox: { bax: function(){} } }; +assertName(x.fox.bax, 'x.fox.bax'); +var foo = {foo: {foo: {}}}; +foo.foo.foo = function(){}; +assertName(foo.foo.foo, 'foo.foo.foo'); +var z = { + foz: function() { + var baz = function() { + var y = {bay: function() {}}; + assertName(y.bay, 'z.foz/baz/y.bay'); + }; + assertName(baz, 'z.foz/baz'); + baz(); + } +}; +assertName(z.foz, 'z.foz'); +z.foz(); + +var outer = function() { + x.fox.bax.nx = function(){}; + var w = {fow: { baw: function(){} } }; + assertName(x.fox.bax.nx, 'outer/x.fox.bax.nx') + assertName(w.fow.baw, 'outer/w.fow.baw'); +}; +assertName(outer, 'outer'); +outer(); +function Fuz(){}; +Fuz.prototype = { + add: function() {} +} +assertName(Fuz.prototype.add, 'Fuz.prototype.add'); + +var x = 1; +x = function(){}; +assertName(x, 'x'); + +var a = {b: {}}; +a.b.c = (function() { + assertName(arguments.callee, 'a.b.c<') +}()); + +a.b = function() { + function foo(f) { assertName(f, 'a.b/<'); }; + return foo(function(){}); +} +a.b(); + +var bar = 'bar'; +a.b[bar] = function(){}; +assertName(a.b.bar, 'a.b[bar]'); + +a.b = function() { + assertName(arguments.callee, 'a.b<'); + return { a: function() {} } +}(); +assertName(a.b.a, 'a.b</<.a'); + +a = { + b: function(a) { + if (a) + return function() {}; + else + return function() {}; + } +}; +assertName(a.b, 'a.b'); +assertName(a.b(true), 'a.b/<') +assertName(a.b(false), 'a.b/<') + +function f(g) { + assertName(g, 'x<'); + return g(); +} +var x = f(function () { return function() {}; }); +assertName(x, 'x</<'); + +var a = {'b': function(){}}; +assertName(a.b, 'a.b'); + +function g(f) { + assertName(f, ''); +} +label: g(function () {}); + +var z = [function() {}]; +assertName(z[0], 'z<'); + +/* fuzz bug from 785089 */ +odeURIL:(function(){}) + +a = { 1: function () {} }; +assertName(a[1], 'a[1]'); + +a = { + "embedded spaces": function(){}, + "dots.look.like.property.references": function(){}, + "\"\'quotes\'\"": function(){}, + "!@#$%": function(){} +}; +assertName(a["embedded spaces"], 'a["embedded spaces"]'); +assertName(a["dots.look.like.property.references"], 'a["dots.look.like.property.references"]'); +assertName(a["\"\'quotes\'\""], 'a["\\\"\'quotes\'\\\""]'); +assertName(a["!@#$%"], 'a["!@#$%"]'); + +a.b = {}; +a.b.c = {}; +a.b["c"]["d e"] = { f: { 1: { "g": { "h i": function() {} } } } }; +assertName(a.b.c["d e"].f[1].g["h i"], 'a.b.c["d e"].f[1].g["h i"]'); + +this.m = function () {}; +assertName(m, "this.m"); + +function N() { + this.o = function () {} +} +let n = new N() +assertName(n.o, "N/this.o"); diff --git a/js/src/jit-test/tests/basic/getelem.js b/js/src/jit-test/tests/basic/getelem.js new file mode 100644 index 000000000..cfc2a70ed --- /dev/null +++ b/js/src/jit-test/tests/basic/getelem.js @@ -0,0 +1,30 @@ +var a; +function setelem() +{ + a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; + a = a.concat(a, a, a); + var l = a.length; + for (var i = 0; i < l; i++) { + a[i] = i; + } + return a.toString(); +} + +setelem(); + +function getelem_inner(a) +{ + var accum = 0; + var l = a.length; + for (var i = 0; i < l; i++) { + accum += a[i]; + } + return accum; +} + +function getelem() +{ + return getelem_inner(a); +} + +assertEq(getelem(), 3486); diff --git a/js/src/jit-test/tests/basic/getprop.js b/js/src/jit-test/tests/basic/getprop.js new file mode 100644 index 000000000..126af690b --- /dev/null +++ b/js/src/jit-test/tests/basic/getprop.js @@ -0,0 +1,16 @@ +var a = 2; +function getprop_inner(o2) +{ + var o = {a:5}; + var t = this; + var x = 0; + for (var i = 0; i < 20; i++) { + t = this; + x += o.a + o2.a + this.a + t.a; + } + return x; +} +function getprop() { + return getprop_inner({a:9}); +} +assertEq(getprop(), 360); diff --git a/js/src/jit-test/tests/basic/globalGet.js b/js/src/jit-test/tests/basic/globalGet.js new file mode 100644 index 000000000..53d73a6f6 --- /dev/null +++ b/js/src/jit-test/tests/basic/globalGet.js @@ -0,0 +1,6 @@ +globalName = 907; +var globalInt = 0; +for (var i = 0; i < 500; i++) + globalInt = globalName + i; + +assertEq(globalInt, globalName + 499); diff --git a/js/src/jit-test/tests/basic/globalOptimize-1.js b/js/src/jit-test/tests/basic/globalOptimize-1.js new file mode 100644 index 000000000..f90114c33 --- /dev/null +++ b/js/src/jit-test/tests/basic/globalOptimize-1.js @@ -0,0 +1,5 @@ +/* Test that NaN does not trigger js_InitMathClass & constants while parsing. */ +var NaN + +var x = 2; + diff --git a/js/src/jit-test/tests/basic/globalSet.js b/js/src/jit-test/tests/basic/globalSet.js new file mode 100644 index 000000000..ceb2852d0 --- /dev/null +++ b/js/src/jit-test/tests/basic/globalSet.js @@ -0,0 +1,4 @@ +for (var i = 0; i < 500; i++) + globalInt = i; + +assertEq(globalInt, 499); diff --git a/js/src/jit-test/tests/basic/globals-shared-shapes.js b/js/src/jit-test/tests/basic/globals-shared-shapes.js new file mode 100644 index 000000000..f2f0013ce --- /dev/null +++ b/js/src/jit-test/tests/basic/globals-shared-shapes.js @@ -0,0 +1,30 @@ +// Test that objects in different compartments can have the same shape. + +var g1 = newGlobal(); +var g2 = newGlobal({sameZoneAs: g1}); + +g1.eval("x1 = {foo: 1}"); +g2.eval("x2 = {foo: 2}"); +assertEq(unwrappedObjectsHaveSameShape(g1.x1, g2.x2), true); + +g1.eval("x1 = [1]"); +g2.eval("x2 = [2]"); +assertEq(unwrappedObjectsHaveSameShape(g1.x1, g2.x2), true); + +g1.eval("x1 = function f(){}"); +g2.eval("x2 = function f(){}"); +assertEq(unwrappedObjectsHaveSameShape(g1.x1, g2.x2), true); + +g1.eval("x1 = /abc/;"); +g2.eval("x2 = /def/"); +assertEq(unwrappedObjectsHaveSameShape(g1.x1, g2.x2), true); + +// Now the same, but we change Array.prototype.__proto__. +// The arrays should no longer get the same Shape, as their +// proto chain is different. +g1 = newGlobal(); +g2 = newGlobal({sameZoneAs: g1}); +g1.eval("x1 = [1];"); +g2.eval("Array.prototype.__proto__ = Math;"); +g2.eval("x2 = [2];"); +assertEq(unwrappedObjectsHaveSameShape(g1.x1, g2.x2), false); diff --git a/js/src/jit-test/tests/basic/homogenous-literals.js b/js/src/jit-test/tests/basic/homogenous-literals.js new file mode 100644 index 000000000..d9e3e7761 --- /dev/null +++ b/js/src/jit-test/tests/basic/homogenous-literals.js @@ -0,0 +1,50 @@ + +function processNoProperty(a) { + var total = 0; + for (var i = 0; i < a.length; i++) { + var sa = a[i]; + for (var j = 0; j < sa.length; j++) + total += sa[j]; + } + assertEq(total, 22); +} + +var literalArray = [ + [1,2,3,4], + [1.5,2.5,3.5,4.5] +]; + +var jsonArray = JSON.parse(`[ + [1,2,3,4], + [1.5,2.5,3.5,4.5] +]`); + +for (var i = 0; i < 1000; i++) { + processNoProperty(literalArray); + processNoProperty(jsonArray); +} + +function processWithProperty(a) { + var total = 0; + for (var i = 0; i < a.length; i++) { + var sa = a[i].p; + for (var j = 0; j < sa.length; j++) + total += sa[j]; + } + assertEq(total, 22); +} + +var literalPropertyArray = [ + {p:[1,2,3,4]}, + {p:[1.5,2.5,3.5,4.5]} +]; + +var jsonPropertyArray = JSON.parse(`[ + {"p":[1,2,3,4]}, + {"p":[1.5,2.5,3.5,4.5]} +]`); + +for (var i = 0; i < 1000; i++) { + processWithProperty(literalPropertyArray); + processWithProperty(jsonPropertyArray); +} diff --git a/js/src/jit-test/tests/basic/html-extensions.js b/js/src/jit-test/tests/basic/html-extensions.js new file mode 100644 index 000000000..169392508 --- /dev/null +++ b/js/src/jit-test/tests/basic/html-extensions.js @@ -0,0 +1,82 @@ +var noParamFuns = ["".bold, "".italics, "".fixed, "".strike, "".small, "".big, + "".blink, "".sup, "".sub]; +var noParamTags = ["b", "i", "tt", "strike", "small", "big", + "blink", "sup", "sub"]; + +function testNoParam(s) { + for (var i=0; i<noParamFuns.length; i++) { + var fun = noParamFuns[i]; + assertEq(fun.length, 0); + var res = fun.call(s); + var tag = noParamTags[i]; + assertEq(res, "<" + tag + ">" + String(s) + "</" + tag + ">"); + } +} +testNoParam("Foo"); +testNoParam('aaa"bbb\'c<>123'); +testNoParam(123); + +// toString should be called, not valueOf +testNoParam({toString: () => 1, valueOf: () => { throw "fail"; } }); + +assertEq("".anchor.length, 1); +assertEq("".link.length, 1); +assertEq("".fontsize.length, 1); +assertEq("".fontcolor.length, 1); + +// " in the attribute value is escaped (") +assertEq("bla\"<>'".anchor("foo'<>\"\"123\"/\\"), + "<a name=\"foo'<>""123"/\\\">bla\"<>'</a>"); +assertEq("bla\"<>'".link("foo'<>\"\"123\"/\\"), + "<a href=\"foo'<>""123"/\\\">bla\"<>'</a>"); +assertEq("bla\"<>'".fontsize("foo'<>\"\"123\"/\\"), + "<font size=\"foo'<>""123"/\\\">bla\"<>'</font>"); +assertEq("bla\"<>'".fontcolor("foo'<>\"\"123\"/\\"), + "<font color=\"foo'<>""123"/\\\">bla\"<>'</font>"); + +assertEq("".anchor('"'), '<a name="""></a>'); +assertEq("".link('"'), '<a href="""></a>'); +assertEq("".fontcolor('"'), '<font color="""></font>'); +assertEq("".fontsize('"'), '<font size="""></font>'); + +assertEq("".anchor('"1'), '<a name=""1"></a>'); +assertEq("".link('"1'), '<a href=""1"></a>'); +assertEq("".fontcolor('"1'), '<font color=""1"></font>'); +assertEq("".fontsize('"1'), '<font size=""1"></font>'); + +assertEq("".anchor('"""a"'), '<a name=""""a""></a>'); +assertEq("".link('"""a"'), '<a href=""""a""></a>'); +assertEq("".fontcolor('"""a"'), '<font color=""""a""></font>'); +assertEq("".fontsize('"""a"'), '<font size=""""a""></font>'); + +assertEq("".anchor(""), '<a name=""></a>'); +assertEq("".link(""), '<a href=""></a>'); +assertEq("".fontcolor(""), '<font color=""></font>'); +assertEq("".fontsize(""), '<font size=""></font>'); + +assertEq("foo".anchor(), "<a name=\"undefined\">foo</a>"); +assertEq("foo".link(), "<a href=\"undefined\">foo</a>"); +assertEq("foo".fontcolor(), "<font color=\"undefined\">foo</font>"); +assertEq("foo".fontsize(), "<font size=\"undefined\">foo</font>"); + +assertEq("foo".anchor(3.14), '<a name="3.14">foo</a>'); +assertEq("foo".link(3.14), '<a href="3.14">foo</a>'); +assertEq("foo".fontcolor(3.14), '<font color="3.14">foo</font>'); +assertEq("foo".fontsize(3.14), '<font size="3.14">foo</font>'); + +assertEq("foo".anchor({}), '<a name="[object Object]">foo</a>'); +assertEq("foo".link(Math), '<a href="[object Math]">foo</a>'); +assertEq("foo".fontcolor([1,2]), '<font color="1,2">foo</font>'); +assertEq("foo".fontsize({}), '<font size="[object Object]">foo</font>'); + +// toString should be called, not valueOf, and toString must be called on |this| +// before it's called on the argument. Also makes sure toString is called only +// once. +var count = 0; +var o1 = {toString: () => { return count += 1; }, valueOf: () => { throw "fail"; } }; +var o2 = {toString: () => { return count += 5; }, valueOf: () => { throw "fail"; } }; +assertEq("".anchor.call(o1, o2), '<a name="6">1</a>'); +assertEq("".link.call(o1, o2), '<a href="12">7</a>'); +assertEq("".fontcolor.call(o1, o2), '<font color="18">13</font>'); +assertEq("".fontsize.call(o1, o2), '<font size="24">19</font>'); +assertEq(count, 24); diff --git a/js/src/jit-test/tests/basic/hypot-approx.js b/js/src/jit-test/tests/basic/hypot-approx.js new file mode 100644 index 000000000..452e6c633 --- /dev/null +++ b/js/src/jit-test/tests/basic/hypot-approx.js @@ -0,0 +1,34 @@ +loadRelativeToScript("../../../tests/ecma_6/Math/shell.js"); + +for (var i = -20; i < 20; i++) { + assertEq(Math.hypot(+0, i), Math.abs(i)); + assertEq(Math.hypot(-0, i), Math.abs(i)); +} + +// The implementation must avoid underlow. +// The implementation must avoid overflow, where possible. +// The implementation must minimise rounding errors. + +assertNear(Math.hypot(1e-300, 1e-300), 1.414213562373095e-300); +assertNear(Math.hypot(1e-300, 1e-300, 1e-300), 1.732050807568877e-300); + +assertNear(Math.hypot(1e-3, 1e-3, 1e-3), 0.0017320508075688772); + +assertNear(Math.hypot(1e300, 1e300), 1.4142135623730952e+300); +assertNear(Math.hypot(1e100, 1e200, 1e300), 1e300); + +assertNear(Math.hypot(1e3, 1e-3), 1000.0000000005); +assertNear(Math.hypot(1e-300, 1e300), 1e300); +assertNear(Math.hypot(1e3, 1e-3, 1e3, 1e-3), 1414.2135623738021555); + +assertNear(Math.hypot(1e1, 1e2, 1e3), Math.sqrt(1e2 + 1e4 + 1e6)); +assertNear(Math.hypot(1e1, 1e2, 1e3, 1e4), Math.sqrt(1e2 + 1e4 + 1e6 + 1e8)); + +for (var i = 1, j = 2; i < 2; i += 0.05, j += 0.05) + assertNear(Math.hypot(i, j), Math.sqrt(i * i + j * j)); + +for (var i = 1, j = 2, k = 3; i < 2; i += 0.05, j += 0.05, k += 0.05) + assertNear(Math.hypot(i, j, k), Math.sqrt(i * i + j * j + k * k)); + +for (var i = 1, j = 2, k = 3, l = 4; i < 2; i += 0.05, j += 0.05, k += 0.05, l += 0.5) + assertNear(Math.hypot(i, j, k, l), Math.sqrt(i * i + j * j + k * k + l * l)); diff --git a/js/src/jit-test/tests/basic/hypot-exact.js b/js/src/jit-test/tests/basic/hypot-exact.js new file mode 100644 index 000000000..7c208d514 --- /dev/null +++ b/js/src/jit-test/tests/basic/hypot-exact.js @@ -0,0 +1,74 @@ +// Properties of Math.hypot that are guaranteed by the spec. + +// If no arguments are passed, the result is +0. +assertEq(Math.hypot(), +0); + +// If any argument is +∞, the result is +∞. +// If any argument is −∞, the result is +∞. +for (var inf of [Infinity, -Infinity]) { + assertEq(Math.hypot(inf, 0), Infinity); + assertEq(Math.hypot(0, inf), Infinity); + assertEq(Math.hypot(inf, inf), Infinity); + assertEq(Math.hypot(inf, -inf), Infinity); + + assertEq(Math.hypot(inf, -0), Infinity); + assertEq(Math.hypot(-0, inf), Infinity); + assertEq(Math.hypot(inf, Math.MIN_VALUE), Infinity); + assertEq(Math.hypot(Math.MIN_VALUE, inf), Infinity); + assertEq(Math.hypot(inf, 1), Infinity); + assertEq(Math.hypot(1, inf), Infinity); + + assertEq(Math.hypot(inf, 0, 0), Infinity); + assertEq(Math.hypot(0, inf, 0), Infinity); + assertEq(Math.hypot(0, 0, inf), Infinity); + + assertEq(Math.hypot(inf, NaN), Infinity); + assertEq(Math.hypot(NaN, inf), Infinity); + + assertEq(Math.hypot(inf, NaN, NaN), Infinity); + assertEq(Math.hypot(NaN, inf, NaN), Infinity); + assertEq(Math.hypot(NaN, NaN, inf), Infinity); + + assertEq(Math.hypot(inf, NaN, NaN, NaN), Infinity); + assertEq(Math.hypot(NaN, inf, NaN, NaN), Infinity); + assertEq(Math.hypot(NaN, NaN, inf, NaN), Infinity); + assertEq(Math.hypot(NaN, NaN, NaN, inf), Infinity); +} + +// If no argument is +∞ or −∞, and any argument is NaN, the result is NaN. +assertEq(Math.hypot(NaN), NaN); + +assertEq(Math.hypot(NaN, 0), NaN); +assertEq(Math.hypot(0, NaN), NaN); + +assertEq(Math.hypot(NaN, NaN), NaN); + +assertEq(Math.hypot(NaN, 0, 0), NaN); +assertEq(Math.hypot(0, NaN, 0), NaN); +assertEq(Math.hypot(0, 0, NaN), NaN); + +assertEq(Math.hypot(NaN, 0, 0, 0), NaN); +assertEq(Math.hypot(0, NaN, 0, 0), NaN); +assertEq(Math.hypot(0, 0, NaN, 0), NaN); +assertEq(Math.hypot(0, 0, 0, NaN), NaN); + +assertEq(Math.hypot(Number.MAX_VALUE, Number.MIN_VALUE, NaN), NaN); +assertEq(Math.hypot(Number.MAX_VALUE, Number.MIN_VALUE, Number.MIN_VALUE, NaN), NaN); + +// If all arguments are either +0 or -0, the result is +0. +assertEq(Math.hypot(-0, -0), +0); +assertEq(Math.hypot(+0, -0), +0); + +assertEq(Math.hypot(-0, -0, -0), +0); +assertEq(Math.hypot(+0, -0, -0), +0); +assertEq(Math.hypot(-0, +0, -0), +0); +assertEq(Math.hypot(+0, +0, -0), +0); + +assertEq(Math.hypot(-0, -0, -0, -0), +0); +assertEq(Math.hypot(+0, -0, -0, -0), +0); +assertEq(Math.hypot(-0, -0, +0, -0), +0); +assertEq(Math.hypot(+0, +0, +0, -0), +0); +assertEq(Math.hypot(-0, -0, -0, +0), +0); + +// The length property of the hypot function is 2. +assertEq(Math.hypot.length, 2); diff --git a/js/src/jit-test/tests/basic/ifInsideLoop.js b/js/src/jit-test/tests/basic/ifInsideLoop.js new file mode 100644 index 000000000..296e3f82d --- /dev/null +++ b/js/src/jit-test/tests/basic/ifInsideLoop.js @@ -0,0 +1,12 @@ +function ifInsideLoop() +{ + var cond = true, intCond = 5, count = 0; + for (var i = 0; i < 100; i++) { + if (cond) + count++; + if (intCond) + count++; + } + return count; +} +assertEq(ifInsideLoop(), 200); diff --git a/js/src/jit-test/tests/basic/inArrayTest.js b/js/src/jit-test/tests/basic/inArrayTest.js new file mode 100644 index 000000000..d57f013fd --- /dev/null +++ b/js/src/jit-test/tests/basic/inArrayTest.js @@ -0,0 +1,9 @@ +function inArrayTest() { + var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + for (var i = 0; i < a.length; i++) { + if (!(i in a)) + break; + } + return i; +} +assertEq(inArrayTest(), 10); diff --git a/js/src/jit-test/tests/basic/inObjectTest.js b/js/src/jit-test/tests/basic/inObjectTest.js new file mode 100644 index 000000000..f19fdbe42 --- /dev/null +++ b/js/src/jit-test/tests/basic/inObjectTest.js @@ -0,0 +1,13 @@ +function inObjectTest() { + var o = {p: 1, q: 2, r: 3, s: 4, t: 5}; + var r = 0; + for (var i in o) { + if (!(i in o)) + break; + if ((i + i) in o) + break; + ++r; + } + return r; +} +assertEq(inObjectTest(), 5); diff --git a/js/src/jit-test/tests/basic/indexed-iteration.js b/js/src/jit-test/tests/basic/indexed-iteration.js new file mode 100644 index 000000000..952aa105b --- /dev/null +++ b/js/src/jit-test/tests/basic/indexed-iteration.js @@ -0,0 +1,20 @@ + +// Don't use NativeIterator cache for objects with dense elements. + +function bar(a) { + var n = 0; + for (var b in a) { n++; } + return n; +} + +function foo() { + var x = {a:0,b:1}; + var y = {a:0,b:1}; + y[0] = 2; + y[1] = 3; + for (var i = 0; i < 10; i++) { + assertEq(bar(x), 2); + assertEq(bar(y), 4); + } +} +foo(); diff --git a/js/src/jit-test/tests/basic/inflate-oom.js b/js/src/jit-test/tests/basic/inflate-oom.js new file mode 100644 index 000000000..2a3187e41 --- /dev/null +++ b/js/src/jit-test/tests/basic/inflate-oom.js @@ -0,0 +1,15 @@ +if (!('oomTest' in this)) + quit(); +function test() { + function foo() { + return 1; + }; + oomTest(() => { + gc(); + foo.toString(); + }); +} +var s = ";".repeat(70000); +s += test.toString() + "test()"; +s += ";".repeat(70000); +eval(s); diff --git a/js/src/jit-test/tests/basic/innerLoopIntOuterDouble.js b/js/src/jit-test/tests/basic/innerLoopIntOuterDouble.js new file mode 100644 index 000000000..be820f956 --- /dev/null +++ b/js/src/jit-test/tests/basic/innerLoopIntOuterDouble.js @@ -0,0 +1,11 @@ +function innerLoopIntOuterDouble() { + var n = 1000, i=0, j=0, count=0, limit=0; + for (i = 1; i <= n; ++i) { + limit = i * 1; + for (j = 0; j < limit; ++j) { + ++count; + } + } + return "" + count; +} +assertEq(innerLoopIntOuterDouble(), "500500"); diff --git a/js/src/jit-test/tests/basic/inner_double_outer_int.js b/js/src/jit-test/tests/basic/inner_double_outer_int.js new file mode 100644 index 000000000..4051aa21a --- /dev/null +++ b/js/src/jit-test/tests/basic/inner_double_outer_int.js @@ -0,0 +1,10 @@ +function inner_double_outer_int() { + function f(i) { + for (var m = 0; m < 20; ++m) + for (var n = 0; n < 100; n += i) + ; + return n; + } + return f(.5); +} +assertEq(inner_double_outer_int(), 100); diff --git a/js/src/jit-test/tests/basic/invokeFunctionMagic.js b/js/src/jit-test/tests/basic/invokeFunctionMagic.js new file mode 100644 index 000000000..9fc364315 --- /dev/null +++ b/js/src/jit-test/tests/basic/invokeFunctionMagic.js @@ -0,0 +1,20 @@ +// JS_IS_CONSTRUCTING +var g = newGlobal(); +do { + new g.String(); // jit::CreateThis passes JS_IS_CONSTRUCTING +} while (!inIon()); + +// JS_UNINITIALIZED_LEXICAL +function dontAbortWholeCompilation() { + class B {}; + class D extends B { + constructor() { super(); } + }; + + return D; +} +var classImpl = dontAbortWholeCompilation(); + +do { + new classImpl(); // jit::CreateThis passes JS_UNINITIALIZED_LEXICAL +} while (!inIon()); diff --git a/js/src/jit-test/tests/basic/iterable-error-messages.js b/js/src/jit-test/tests/basic/iterable-error-messages.js new file mode 100644 index 000000000..4d10f92b2 --- /dev/null +++ b/js/src/jit-test/tests/basic/iterable-error-messages.js @@ -0,0 +1,39 @@ +function assertThrowsMsg(f, msg) { + try { + f(); + assertEq(0, 1); + } catch(e) { + assertEq(e instanceof TypeError, true); + assertEq(e.message, msg); + } +} + +// For-of +function testForOf(val) { + for (var x of val) {} +} +for (v of [{}, Math, new Proxy({}, {})]) { + assertThrowsMsg(() => testForOf(v), "val is not iterable"); +} +assertThrowsMsg(() => testForOf(null), "val is null"); +assertThrowsMsg(() => { for (var x of () => 1) {}}, "() => 1 is not iterable"); + +// Destructuring +function testDestr(val) { + var [a, b] = val; +} +for (v of [{}, Math, new Proxy({}, {})]) { + assertThrowsMsg(() => testDestr(v), "val is not iterable"); +} +assertThrowsMsg(() => testDestr(null), "val is null"); +assertThrowsMsg(() => { [a, b] = () => 1; }, "() => 1 is not iterable"); + +// Spread +function testSpread(val) { + [...val]; +} +for (v of [{}, Math, new Proxy({}, {})]) { + assertThrowsMsg(() => testSpread(v), "val is not iterable"); +} +assertThrowsMsg(() => testSpread(null), "val is null"); +assertThrowsMsg(() => { [...() => 1]; }, "() => 1 is not iterable"); diff --git a/js/src/jit-test/tests/basic/joinTest.js b/js/src/jit-test/tests/basic/joinTest.js new file mode 100644 index 000000000..1988da4f4 --- /dev/null +++ b/js/src/jit-test/tests/basic/joinTest.js @@ -0,0 +1,15 @@ +function joinTest() +{ + var s = ""; + var a = []; + for (var i = 0; i < 8; i++) + a[i] = [String.fromCharCode(97 + i)]; + for (i = 0; i < 8; i++) { + for (var j = 0; j < 8; j++) + a[i][1 + j] = j; + } + for (i = 0; i < 8; i++) + s += a[i].join(","); + return s; +} +assertEq(joinTest(), "a,0,1,2,3,4,5,6,7b,0,1,2,3,4,5,6,7c,0,1,2,3,4,5,6,7d,0,1,2,3,4,5,6,7e,0,1,2,3,4,5,6,7f,0,1,2,3,4,5,6,7g,0,1,2,3,4,5,6,7h,0,1,2,3,4,5,6,7"); diff --git a/js/src/jit-test/tests/basic/lazyparse.js b/js/src/jit-test/tests/basic/lazyparse.js new file mode 100644 index 000000000..b878c6302 --- /dev/null +++ b/js/src/jit-test/tests/basic/lazyparse.js @@ -0,0 +1,45 @@ + +function outer() { + var xyz = 0; + function foo() { + function bar() { xyz++; } + bar(); + let x = 3; + } + foo(); + assertEq(xyz, 1); +} +outer(); + +function mapfloor(a) { + var b = a.map(function(v) { + "use strict"; + try { + eval("delete String;"); + } catch (e) { + return e instanceof res; + } + }); + var res = ""; +} +try { + mapfloor([1,2]); +} catch (e) {} + +test(); +function test() { + try { + eval('let(z) { with({}) let y = 3; }'); + } catch(ex) { + (function(x) { return !(x) })(0/0) + } +} + +testCatch(15); +function testCatch(y) { + try { + throw 5; + } catch(ex) { + (function(x) { assertEq(x + y + ex, 25); })(5) + } +} diff --git a/js/src/jit-test/tests/basic/letTDZAfterInitializer.js b/js/src/jit-test/tests/basic/letTDZAfterInitializer.js new file mode 100644 index 000000000..575615c17 --- /dev/null +++ b/js/src/jit-test/tests/basic/letTDZAfterInitializer.js @@ -0,0 +1,19 @@ +function throwSomething() { + throw "something"; +} + +try { + // Use eval to force BINDNAME. Should throw "something" instead of the TDZ + // ReferenceError. + eval("x = throwSomething()"); + let x; +} catch (e) { + assertEq(e, "something"); +} + +try { + eval("x = 42"); + let x; +} catch (e) { + assertEq(e instanceof ReferenceError, true); +} diff --git a/js/src/jit-test/tests/basic/letTDZEffectful.js b/js/src/jit-test/tests/basic/letTDZEffectful.js new file mode 100644 index 000000000..62245d8c1 --- /dev/null +++ b/js/src/jit-test/tests/basic/letTDZEffectful.js @@ -0,0 +1,13 @@ +function assertThrowsReferenceError(f) { + var e = null; + try { + f(); + } catch (ex) { + e = ex; + } + assertEq(e instanceof ReferenceError, true); +} + +// TDZ is effectful, don't optimize out x. +assertThrowsReferenceError(function () { x; let x; }); +assertThrowsReferenceError(function () { x; const x = undefined; }); diff --git a/js/src/jit-test/tests/basic/letTDZSwitchClosure.js b/js/src/jit-test/tests/basic/letTDZSwitchClosure.js new file mode 100644 index 000000000..c601f9858 --- /dev/null +++ b/js/src/jit-test/tests/basic/letTDZSwitchClosure.js @@ -0,0 +1,60 @@ +function assertThrowsReferenceError(f) { + var err; + try { + f(); + } catch (e) { + err = e; + } + assertEq(err instanceof ReferenceError, true); +} + +function f() { + switch (0) { + case 1: + let x + case function() { + print(x) + }(): + } +} +assertThrowsReferenceError(f); + +function g() { + switch (0) { + case 1: + let x; + case 0: + var inner = function () { + print(x); + } + inner(); + break; + } +} +assertThrowsReferenceError(g); + +function h() { + switch (0) { + case 0: + var inner = function () { + print(x); + } + inner(); + case 1: + let x; + } +} +assertThrowsReferenceError(h); + +// Tests that a dominating lexical doesn't throw. +function F() { + switch (0) { + case 0: + let x = 42; + var inner = function () { + assertEq(x, 42); + } + inner(); + } +} +F(); diff --git a/js/src/jit-test/tests/basic/local.js b/js/src/jit-test/tests/basic/local.js new file mode 100644 index 000000000..0f8b12b3f --- /dev/null +++ b/js/src/jit-test/tests/basic/local.js @@ -0,0 +1,3 @@ +// A file in the same directory as testPaths.js + +x = 'local'; diff --git a/js/src/jit-test/tests/basic/matchInLoop.js b/js/src/jit-test/tests/basic/matchInLoop.js new file mode 100644 index 000000000..89f40ac5f --- /dev/null +++ b/js/src/jit-test/tests/basic/matchInLoop.js @@ -0,0 +1,8 @@ +function matchInLoop() { + var k = "hi"; + for (var i = 0; i < 10; i++) { + var result = k.match(/hi/) != null; + } + return result; +} +assertEq(matchInLoop(), true); diff --git a/js/src/jit-test/tests/basic/math-jit-tests.js b/js/src/jit-test/tests/basic/math-jit-tests.js new file mode 100644 index 000000000..32da64fed --- /dev/null +++ b/js/src/jit-test/tests/basic/math-jit-tests.js @@ -0,0 +1,520 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ + +// Apply FUNCNAME to ARGS, and check against EXPECTED. +// Expect a loop containing such a call to be traced. +// FUNCNAME and ARGS are both strings. +// ARGS has the form of an argument list: a comma-separated list of expressions. +// Certain Tracemonkey limitations require us to pass FUNCNAME as a string. +// Passing ARGS as a string allows us to assign better test names: +// expressions like Math.PI/4 haven't been evaluated to big hairy numbers. +function testmath(funcname, args, expected) { + var i, j; + + var arg_value_list = eval("[" + args + "]"); + var arity = arg_value_list.length; + + // Build the string "a[i][0],...,a[i][ARITY-1]". + var actuals = [] + for (i = 0; i < arity; i++) + actuals.push("a[i][" + i + "]"); + actuals = actuals.join(","); + + // Create a function that maps FUNCNAME across an array of input values. + // Unless we eval here, the call to funcname won't get traced. + // FUNCNAME="Infinity/Math.abs" and cases like that happen to + // parse, too, in a twisted way. + var mapfunc = eval("(function(a) {\n" + + " for (var i = 0; i < a.length; i++)\n" + + " a[i] = " + funcname + "(" + actuals +");\n" + + " })\n"); + + // To prevent the compiler from doing constant folding, produce an + // array to pass to mapfunc that contains enough dummy + // values at the front to get the loop body jitted, and then our + // actual test value. + var dummies_and_input = []; + for (i = 0; i < 9; i++) { + var dummy_list = []; + for (j = 0; j < arity; j++) + dummy_list[j] = .0078125 * ((i + j) % 128); + dummies_and_input[i] = dummy_list; + } + dummies_and_input[9] = arg_value_list; + + function testfunc() { + // Map the function across the dummy values and the test input. + mapfunc(dummies_and_input); + return dummies_and_input[9]; + } + + assertEq(close_enough(testfunc(), expected), true); +} + +function close_enough(expected, actual) +{ + if (typeof expected != typeof actual) + return false; + if (typeof expected != 'number') + return actual == expected; + + // Distinguish NaN from other values. Using x != x comparisons here + // works even if tests redefine isNaN. + if (actual != actual) + return expected != expected + if (expected != expected) + return false; + + // Tolerate a certain degree of error. + if (actual != expected) + return Math.abs(actual - expected) <= 1E-10; + + // Distinguish 0 and -0. + if (actual == 0) + return (1 / actual > 0) == (1 / expected > 0); + + return true; +} + +testmath("Math.abs", "void 0", Number.NaN) +testmath("Math.abs", "null", 0) +testmath("Math.abs", "true", 1) +testmath("Math.abs", "false", 0) +testmath("Math.abs", "\"a string primitive\"", Number.NaN) +testmath("Math.abs", "new String( 'a String object' )", Number.NaN) +testmath("Math.abs", "Number.NaN", Number.NaN) +testmath("Math.abs", "0", 0) +testmath("Math.abs", "-0", 0) +testmath("Infinity/Math.abs", "-0", Infinity) +testmath("Math.abs", "Number.NEGATIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.abs", "Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.abs", "- Number.MAX_VALUE", Number.MAX_VALUE) +testmath("Math.abs", "-Number.MIN_VALUE", Number.MIN_VALUE) +testmath("Math.abs", "Number.MAX_VALUE", Number.MAX_VALUE) +testmath("Math.abs", "Number.MIN_VALUE", Number.MIN_VALUE) +testmath("Math.abs", "-1", 1) +testmath("Math.abs", "new Number(-1)", 1) +testmath("Math.abs", "1", 1) +testmath("Math.abs", "Math.PI", Math.PI) +testmath("Math.abs", "-Math.PI", Math.PI) +testmath("Math.abs", "-1/100000000", 1/100000000) +testmath("Math.abs", "-Math.pow(2,32)", Math.pow(2,32)) +testmath("Math.abs", "Math.pow(2,32)", Math.pow(2,32)) +testmath("Math.abs", "-0xfff", 4095) +testmath("Math.abs", "-0777", 511) +testmath("Math.abs", "'-1e-1'", 0.1) +testmath("Math.abs", "'0xff'", 255) +testmath("Math.abs", "'077'", 77) +testmath("Math.abs", "'Infinity'", Infinity) +testmath("Math.abs", "'-Infinity'", Infinity) + +testmath("Math.acos", "void 0", Number.NaN) +testmath("Math.acos", "null", Math.PI/2) +testmath("Math.acos", "Number.NaN", Number.NaN) +testmath("Math.acos", "\"a string\"", Number.NaN) +testmath("Math.acos", "'0'", Math.PI/2) +testmath("Math.acos", "'1'", 0) +testmath("Math.acos", "'-1'", Math.PI) +testmath("Math.acos", "1.00000001", Number.NaN) +testmath("Math.acos", "-1.00000001", Number.NaN) +testmath("Math.acos", "1", 0) +testmath("Math.acos", "-1", Math.PI) +testmath("Math.acos", "0", Math.PI/2) +testmath("Math.acos", "-0", Math.PI/2) +testmath("Math.acos", "Math.SQRT1_2", Math.PI/4) +testmath("Math.acos", "-Math.SQRT1_2", Math.PI/4*3) +testmath("Math.acos", "0.9999619230642", Math.PI/360) +testmath("Math.acos", "-3.0", Number.NaN) + +testmath("Math.asin", "void 0", Number.NaN) +testmath("Math.asin", "null", 0) +testmath("Math.asin", "Number.NaN", Number.NaN) +testmath("Math.asin", "\"string\"", Number.NaN) +testmath("Math.asin", "\"0\"", 0) +testmath("Math.asin", "\"1\"", Math.PI/2) +testmath("Math.asin", "\"-1\"", -Math.PI/2) +testmath("Math.asin", "Math.SQRT1_2+''", Math.PI/4) +testmath("Math.asin", "-Math.SQRT1_2+''", -Math.PI/4) +testmath("Math.asin", "1.000001", Number.NaN) +testmath("Math.asin", "-1.000001", Number.NaN) +testmath("Math.asin", "0", 0) +testmath("Math.asin", "-0", -0) +testmath("Infinity/Math.asin", "-0", -Infinity) +testmath("Math.asin", "1", Math.PI/2) +testmath("Math.asin", "-1", -Math.PI/2) +testmath("Math.asin", "Math.SQRT1_2", Math.PI/4) +testmath("Math.asin", "-Math.SQRT1_2", -Math.PI/4) + +testmath("Math.atan", "void 0", Number.NaN) +testmath("Math.atan", "null", 0) +testmath("Math.atan", "Number.NaN", Number.NaN) +testmath("Math.atan", "\"a string\"", Number.NaN) +testmath("Math.atan", "'0'", 0) +testmath("Math.atan", "'1'", Math.PI/4) +testmath("Math.atan", "'-1'", -Math.PI/4) +testmath("Math.atan", "'Infinity'", Math.PI/2) +testmath("Math.atan", "'-Infinity'", -Math.PI/2) +testmath("Math.atan", "0", 0) +testmath("Math.atan", "-0", -0) +testmath("Infinity/Math.atan", "-0", -Infinity) +testmath("Math.atan", "Number.POSITIVE_INFINITY", Math.PI/2) +testmath("Math.atan", "Number.NEGATIVE_INFINITY", -Math.PI/2) +testmath("Math.atan", "1", Math.PI/4) +testmath("Math.atan", "-1", -Math.PI/4) + +testmath("Math.atan2", "Number.NaN,0", Number.NaN) +testmath("Math.atan2", "null, null", 0) +testmath("Math.atan2", "void 0, void 0", Number.NaN) +testmath("Math.atan2", "0,Number.NaN", Number.NaN) +testmath("Math.atan2", "1,0", Math.PI/2) +testmath("Math.atan2", "1,-0", Math.PI/2) +testmath("Math.atan2", "0,0.001", 0) +testmath("Math.atan2", "0,0", 0) +testmath("Math.atan2", "0,-0", Math.PI) +testmath("Math.atan2", "0, -1", Math.PI) +testmath("Math.atan2", "-0, 1", -0) +testmath("Infinity/Math.atan2", "-0,1", -Infinity) +testmath("Math.atan2", "-0,0", -0) +testmath("Math.atan2", "-0, -0", -Math.PI) +testmath("Math.atan2", "-0, -1", -Math.PI) +testmath("Math.atan2", "-1, 0", -Math.PI/2) +testmath("Math.atan2", "-1, -0", -Math.PI/2) +testmath("Math.atan2", "1, Number.POSITIVE_INFINITY", 0) +testmath("Math.atan2", "1, Number.NEGATIVE_INFINITY", Math.PI) +testmath("Math.atan2", "-1,Number.POSITIVE_INFINITY", -0) +testmath("Infinity/Math.atan2", "-1,Infinity", -Infinity) +testmath("Math.atan2", "-1,Number.NEGATIVE_INFINITY", -Math.PI) +testmath("Math.atan2", "Number.POSITIVE_INFINITY, 0", Math.PI/2) +testmath("Math.atan2", "Number.POSITIVE_INFINITY, 1", Math.PI/2) +testmath("Math.atan2", "Number.POSITIVE_INFINITY,-1", Math.PI/2) +testmath("Math.atan2", "Number.POSITIVE_INFINITY,-0", Math.PI/2) +testmath("Math.atan2", "Number.NEGATIVE_INFINITY, 0", -Math.PI/2) +testmath("Math.atan2", "Number.NEGATIVE_INFINITY,-0", -Math.PI/2) +testmath("Math.atan2", "Number.NEGATIVE_INFINITY, 1", -Math.PI/2) +testmath("Math.atan2", "Number.NEGATIVE_INFINITY,-1", -Math.PI/2) +testmath("Math.atan2", "Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY", Math.PI/4) +testmath("Math.atan2", "Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY", 3*Math.PI/4) +testmath("Math.atan2", "Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY", -Math.PI/4) +testmath("Math.atan2", "Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY", -3*Math.PI/4) +testmath("Math.atan2", "-1, 1", -Math.PI/4) + +testmath("Math.ceil", "Number.NaN", Number.NaN) +testmath("Math.ceil", "null", 0) +testmath("Math.ceil", "void 0", Number.NaN) +testmath("Math.ceil", "'0'", 0) +testmath("Math.ceil", "'-0'", -0) +testmath("Infinity/Math.ceil", "'0'", Infinity) +testmath("Infinity/Math.ceil", "'-0'", -Infinity) +testmath("Math.ceil", "0", 0) +testmath("Math.ceil", "-0", -0) +testmath("Infinity/Math.ceil", "0", Infinity) +testmath("Infinity/Math.ceil", "-0", -Infinity) +testmath("Math.ceil", "Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.ceil", "Number.NEGATIVE_INFINITY", Number.NEGATIVE_INFINITY) +testmath("Math.ceil", "-Number.MIN_VALUE", -0) +testmath("Infinity/Math.ceil", "-Number.MIN_VALUE", -Infinity) +testmath("Math.ceil", "1", 1) +testmath("Math.ceil", "-1", -1) +testmath("Math.ceil", "-0.9", -0) +testmath("Infinity/Math.ceil", "-0.9", -Infinity) +testmath("Math.ceil", "0.9", 1) +testmath("Math.ceil", "-1.1", -1) +testmath("Math.ceil", "1.1", 2) +testmath("Math.ceil", "Number.POSITIVE_INFINITY", -Math.floor(-Infinity)) +testmath("Math.ceil", "Number.NEGATIVE_INFINITY", -Math.floor(Infinity)) +testmath("Math.ceil", "-Number.MIN_VALUE", -Math.floor(Number.MIN_VALUE)) +testmath("Math.ceil", "1", -Math.floor(-1)) +testmath("Math.ceil", "-1", -Math.floor(1)) +testmath("Math.ceil", "-0.9", -Math.floor(0.9)) +testmath("Math.ceil", "0.9", -Math.floor(-0.9)) +testmath("Math.ceil", "-1.1", -Math.floor(1.1)) +testmath("Math.ceil", "1.1", -Math.floor(-1.1)) + +testmath("Math.cos", "void 0", Number.NaN) +testmath("Math.cos", "false", 1) +testmath("Math.cos", "null", 1) +testmath("Math.cos", "'0'", 1) +testmath("Math.cos", "\"Infinity\"", Number.NaN) +testmath("Math.cos", "'3.14159265359'", -1) +testmath("Math.cos", "Number.NaN", Number.NaN) +testmath("Math.cos", "0", 1) +testmath("Math.cos", "-0", 1) +testmath("Math.cos", "Number.POSITIVE_INFINITY", Number.NaN) +testmath("Math.cos", "Number.NEGATIVE_INFINITY", Number.NaN) +testmath("Math.cos", "0.7853981633974", 0.7071067811865) +testmath("Math.cos", "1.570796326795", 0) +testmath("Math.cos", "2.356194490192", -0.7071067811865) +testmath("Math.cos", "3.14159265359", -1) +testmath("Math.cos", "3.926990816987", -0.7071067811865) +testmath("Math.cos", "4.712388980385", 0) +testmath("Math.cos", "5.497787143782", 0.7071067811865) +testmath("Math.cos", "Math.PI*2", 1) +testmath("Math.cos", "Math.PI/4", Math.SQRT2/2) +testmath("Math.cos", "Math.PI/2", 0) +testmath("Math.cos", "3*Math.PI/4", -Math.SQRT2/2) +testmath("Math.cos", "Math.PI", -1) +testmath("Math.cos", "5*Math.PI/4", -Math.SQRT2/2) +testmath("Math.cos", "3*Math.PI/2", 0) +testmath("Math.cos", "7*Math.PI/4", Math.SQRT2/2) +testmath("Math.cos", "2*Math.PI", 1) +testmath("Math.cos", "-0.7853981633974", 0.7071067811865) +testmath("Math.cos", "-1.570796326795", 0) +testmath("Math.cos", "2.3561944901920", -.7071067811865) +testmath("Math.cos", "3.14159265359", -1) +testmath("Math.cos", "3.926990816987", -0.7071067811865) +testmath("Math.cos", "4.712388980385", 0) +testmath("Math.cos", "5.497787143782", 0.7071067811865) +testmath("Math.cos", "6.28318530718", 1) +testmath("Math.cos", "-Math.PI/4", Math.SQRT2/2) +testmath("Math.cos", "-Math.PI/2", 0) +testmath("Math.cos", "-3*Math.PI/4", -Math.SQRT2/2) +testmath("Math.cos", "-Math.PI", -1) +testmath("Math.cos", "-5*Math.PI/4", -Math.SQRT2/2) +testmath("Math.cos", "-3*Math.PI/2", 0) +testmath("Math.cos", "-7*Math.PI/4", Math.SQRT2/2) +testmath("Math.cos", "-Math.PI*2", 1) + +testmath("Math.exp", "null", 1) +testmath("Math.exp", "void 0", Number.NaN) +testmath("Math.exp", "1", Math.E) +testmath("Math.exp", "true", Math.E) +testmath("Math.exp", "false", 1) +testmath("Math.exp", "'1'", Math.E) +testmath("Math.exp", "'0'", 1) +testmath("Math.exp", "Number.NaN", Number.NaN) +testmath("Math.exp", "0", 1) +testmath("Math.exp", "-0", 1) +testmath("Math.exp", "Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.exp", "Number.NEGATIVE_INFINITY", 0) + +testmath("Math.floor", "void 0", Number.NaN) +testmath("Math.floor", "null", 0) +testmath("Math.floor", "true", 1) +testmath("Math.floor", "false", 0) +testmath("Math.floor", "\"1.1\"", 1) +testmath("Math.floor", "\"-1.1\"", -2) +testmath("Math.floor", "\"0.1\"", 0) +testmath("Math.floor", "\"-0.1\"", -1) +testmath("Math.floor", "Number.NaN", Number.NaN) +testmath("Math.floor(Number.NaN) == -Math.ceil", "-Number.NaN", false) +testmath("Math.floor", "0", 0) +testmath("Math.floor(0) == -Math.ceil", "-0", true) +testmath("Math.floor", "-0", -0) +testmath("Infinity/Math.floor", "-0", -Infinity) +testmath("Math.floor(-0)== -Math.ceil", "0", true) +testmath("Math.floor", "Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.floor(Number.POSITIVE_INFINITY) == -Math.ceil", "Number.NEGATIVE_INFINITY", true) +testmath("Math.floor", "Number.NEGATIVE_INFINITY", Number.NEGATIVE_INFINITY) +testmath("Math.floor(Number.NEGATIVE_INFINITY) == -Math.ceil", "Number.POSITIVE_INFINITY", true) +testmath("Math.floor", "0.0000001", 0) +testmath("Math.floor(0.0000001)==-Math.ceil", "-0.0000001", true) +testmath("Math.floor", "-0.0000001", -1) +testmath("Math.floor(-0.0000001)==-Math.ceil", "0.0000001", true) + +testmath("Math.log", "void 0", Number.NaN) +testmath("Math.log", "null", Number.NEGATIVE_INFINITY) +testmath("Math.log", "true", 0) +testmath("Math.log", "false", -Infinity) +testmath("Math.log", "'0'", -Infinity) +testmath("Math.log", "'1'", 0) +testmath("Math.log", "\"Infinity\"", Infinity) +testmath("Math.log", "Number.NaN", Number.NaN) +testmath("Math.log", "-0.000001", Number.NaN) +testmath("Math.log", "-1", Number.NaN) +testmath("Math.log", "0", Number.NEGATIVE_INFINITY) +testmath("Math.log", "-0", Number.NEGATIVE_INFINITY) +testmath("Math.log", "1", 0) +testmath("Math.log", "Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.log", "Number.NEGATIVE_INFINITY", Number.NaN) + +testmath("Math.max", "void 0, 1", Number.NaN) +testmath("Math.max", "void 0, void 0", Number.NaN) +testmath("Math.max", "null, 1", 1) +testmath("Math.max", "-1, null", 0) +testmath("Math.max", "true,false", 1) +testmath("Math.max", "\"-99\",\"99\"", 99) +testmath("Math.max", "Number.NaN,Number.POSITIVE_INFINITY", Number.NaN) +testmath("Math.max", "Number.NaN, 0", Number.NaN) +testmath("Math.max", "\"a string\", 0", Number.NaN) +testmath("Math.max", "Number.NaN,1", Number.NaN) +testmath("Math.max", "\"a string\", Number.POSITIVE_INFINITY", Number.NaN) +testmath("Math.max", "Number.POSITIVE_INFINITY, Number.NaN", Number.NaN) +testmath("Math.max", "Number.NaN, Number.NaN", Number.NaN) +testmath("Math.max", "0,Number.NaN", Number.NaN) +testmath("Math.max", "1, Number.NaN", Number.NaN) +testmath("Math.max", "0,0", 0) +testmath("Math.max", "0,-0", 0) +testmath("Math.max", "-0,0", 0) +testmath("Math.max", "-0,-0", -0) +testmath("Infinity/Math.max", "-0,-0", -Infinity) +testmath("Math.max", "Number.POSITIVE_INFINITY, Number.MAX_VALUE", Number.POSITIVE_INFINITY) +testmath("Math.max", "Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.max", "Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY", Number.NEGATIVE_INFINITY) +testmath("Math.max", "1,.99999999999999", 1) +testmath("Math.max", "-1,-.99999999999999", -.99999999999999) + +testmath("Math.min", "void 0, 1", Number.NaN) +testmath("Math.min", "void 0, void 0", Number.NaN) +testmath("Math.min", "null, 1", 0) +testmath("Math.min", "-1, null", -1) +testmath("Math.min", "true,false", 0) +testmath("Math.min", "\"-99\",\"99\"", -99) +testmath("Math.min", "Number.NaN,0", Number.NaN) +testmath("Math.min", "Number.NaN,1", Number.NaN) +testmath("Math.min", "Number.NaN,-1", Number.NaN) +testmath("Math.min", "0,Number.NaN", Number.NaN) +testmath("Math.min", "1,Number.NaN", Number.NaN) +testmath("Math.min", "-1,Number.NaN", Number.NaN) +testmath("Math.min", "Number.NaN,Number.NaN", Number.NaN) +testmath("Math.min", "1,1.0000000001", 1) +testmath("Math.min", "1.0000000001,1", 1) +testmath("Math.min", "0,0", 0) +testmath("Math.min", "0,-0", -0) +testmath("Math.min", "-0,-0", -0) +testmath("Infinity/Math.min", "0,-0", -Infinity) +testmath("Infinity/Math.min", "-0,-0", -Infinity) + +testmath("Math.pow", "null,null", 1) +testmath("Math.pow", "void 0, void 0", Number.NaN) +testmath("Math.pow", "true, false", 1) +testmath("Math.pow", "false,true", 0) +testmath("Math.pow", "'2','32'", 4294967296) +testmath("Math.pow", "1,Number.NaN", Number.NaN) +testmath("Math.pow", "0,Number.NaN", Number.NaN) +testmath("Math.pow", "Number.NaN,0", 1) +testmath("Math.pow", "Number.NaN,-0", 1) +testmath("Math.pow", "Number.NaN, 1", Number.NaN) +testmath("Math.pow", "Number.NaN, .5", Number.NaN) +testmath("Math.pow", "1.00000001, Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.pow", "1.00000001, Number.NEGATIVE_INFINITY", 0) +testmath("Math.pow", "-1.00000001,Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.pow", "-1.00000001,Number.NEGATIVE_INFINITY", 0) +testmath("Math.pow", "1, Number.POSITIVE_INFINITY", Number.NaN) +testmath("Math.pow", "1, Number.NEGATIVE_INFINITY", Number.NaN) +testmath("Math.pow", "-1, Number.POSITIVE_INFINITY", Number.NaN) +testmath("Math.pow", "-1, Number.NEGATIVE_INFINITY", Number.NaN) +testmath("Math.pow", ".0000000009, Number.POSITIVE_INFINITY", 0) +testmath("Math.pow", "-.0000000009, Number.POSITIVE_INFINITY", 0) +testmath("Math.pow", "-.0000000009, Number.NEGATIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.pow", "Number.POSITIVE_INFINITY,.00000000001", Number.POSITIVE_INFINITY) +testmath("Math.pow", "Number.POSITIVE_INFINITY, 1", Number.POSITIVE_INFINITY) +testmath("Math.pow", "Number.POSITIVE_INFINITY, -.00000000001", 0) +testmath("Math.pow", "Number.POSITIVE_INFINITY, -1", 0) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, 1", Number.NEGATIVE_INFINITY) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, 333", Number.NEGATIVE_INFINITY) +testmath("Math.pow", "Number.POSITIVE_INFINITY, 2", Number.POSITIVE_INFINITY) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, 666", Number.POSITIVE_INFINITY) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, 0.5", Number.POSITIVE_INFINITY) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, -1", -0) +testmath("Infinity/Math.pow", "Number.NEGATIVE_INFINITY, -1", -Infinity) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, -3", -0) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, -2", 0) +testmath("Math.pow", "Number.NEGATIVE_INFINITY,-0.5", 0) +testmath("Math.pow", "Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY", 0) +testmath("Math.pow", "0,1", 0) +testmath("Math.pow", "0,0", 1) +testmath("Math.pow", "1,0", 1) +testmath("Math.pow", "-1,0", 1) +testmath("Math.pow", "0,0.5", 0) +testmath("Math.pow", "0,1000", 0) +testmath("Math.pow", "0, Number.POSITIVE_INFINITY", 0) +testmath("Math.pow", "0, -1", Number.POSITIVE_INFINITY) +testmath("Math.pow", "0, -0.5", Number.POSITIVE_INFINITY) +testmath("Math.pow", "0, -1000", Number.POSITIVE_INFINITY) +testmath("Math.pow", "0, Number.NEGATIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.pow", "-0, 1", -0) +testmath("Math.pow", "-0,3", -0) +testmath("Infinity/Math.pow", "-0, 1", -Infinity) +testmath("Infinity/Math.pow", "-0,3", -Infinity) +testmath("Math.pow", "-0,2", 0) +testmath("Math.pow", "-0, Number.POSITIVE_INFINITY", 0) +testmath("Math.pow", "-0, -1", Number.NEGATIVE_INFINITY) +testmath("Math.pow", "-0, -10001", Number.NEGATIVE_INFINITY) +testmath("Math.pow", "-0, -2", Number.POSITIVE_INFINITY) +testmath("Math.pow", "-0, 0.5", 0) +testmath("Math.pow", "-0, Number.POSITIVE_INFINITY", 0) +testmath("Math.pow", "-1, 0.5", Number.NaN) +testmath("Math.pow", "-1, Number.NaN", Number.NaN) +testmath("Math.pow", "-1, -0.5", Number.NaN) + +testmath("Math.round", "0", 0) +testmath("Math.round", "void 0", Number.NaN) +testmath("Math.round", "true", 1) +testmath("Math.round", "false", 0) +testmath("Math.round", "'.99999'", 1) +testmath("Math.round", "'12345e-2'", 123) +testmath("Math.round", "Number.NaN", Number.NaN) +testmath("Math.round", "0", 0) +testmath("Math.round", "-0", -0) +testmath("Infinity/Math.round", "-0", -Infinity) +testmath("Math.round", "Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.round", "Number.NEGATIVE_INFINITY", Number.NEGATIVE_INFINITY) +testmath("Math.round", "0.49", 0) +testmath("Math.round", "0.5", 1) +testmath("Math.round", "0.51", 1) +testmath("Math.round", "-0.49", -0) +testmath("Math.round", "-0.5", -0) +testmath("Infinity/Math.round", "-0.49", -Infinity) +testmath("Infinity/Math.round", "-0.5", -Infinity) +testmath("Math.round", "-0.51", -1) +testmath("Math.round", "3.5", 4) +testmath("Math.round", "-3", -3) + +testmath("Math.sin", "null", 0) +testmath("Math.sin", "void 0", Number.NaN) +testmath("Math.sin", "false", 0) +testmath("Math.sin", "'2.356194490192'", 0.7071067811865) +testmath("Math.sin", "Number.NaN", Number.NaN) +testmath("Math.sin", "0", 0) +testmath("Math.sin", "-0", -0) +testmath("Math.sin", "Number.POSITIVE_INFINITY", Number.NaN) +testmath("Math.sin", "Number.NEGATIVE_INFINITY", Number.NaN) +testmath("Math.sin", "0.7853981633974", 0.7071067811865) +testmath("Math.sin", "1.570796326795", 1) +testmath("Math.sin", "2.356194490192", 0.7071067811865) +testmath("Math.sin", "3.14159265359", 0) + +testmath("Math.sqrt", "void 0", Number.NaN) +testmath("Math.sqrt", "null", 0) +testmath("Math.sqrt", "1", 1) +testmath("Math.sqrt", "false", 0) +testmath("Math.sqrt", "'225'", 15) +testmath("Math.sqrt", "Number.NaN", Number.NaN) +testmath("Math.sqrt", "Number.NEGATIVE_INFINITY", Number.NaN) +testmath("Math.sqrt", "-1", Number.NaN) +testmath("Math.sqrt", "-0.5", Number.NaN) +testmath("Math.sqrt", "0", 0) +testmath("Math.sqrt", "-0", -0) +testmath("Infinity/Math.sqrt", "-0", -Infinity) +testmath("Math.sqrt", "Number.POSITIVE_INFINITY", Number.POSITIVE_INFINITY) +testmath("Math.sqrt", "1", 1) +testmath("Math.sqrt", "2", Math.SQRT2) +testmath("Math.sqrt", "0.5", Math.SQRT1_2) +testmath("Math.sqrt", "4", 2) +testmath("Math.sqrt", "9", 3) +testmath("Math.sqrt", "16", 4) +testmath("Math.sqrt", "25", 5) +testmath("Math.sqrt", "36", 6) +testmath("Math.sqrt", "49", 7) +testmath("Math.sqrt", "64", 8) +testmath("Math.sqrt", "256", 16) +testmath("Math.sqrt", "10000", 100) +testmath("Math.sqrt", "65536", 256) +testmath("Math.sqrt", "0.09", 0.3) +testmath("Math.sqrt", "0.01", 0.1) +testmath("Math.sqrt", "0.00000001", 0.0001) + +testmath("Math.tan", "void 0", Number.NaN) +testmath("Math.tan", "null", 0) +testmath("Math.tan", "false", 0) +testmath("Math.tan", "Number.NaN", Number.NaN) +testmath("Math.tan", "0", 0) +testmath("Math.tan", "-0", -0) +testmath("Math.tan", "Number.POSITIVE_INFINITY", Number.NaN) +testmath("Math.tan", "Number.NEGATIVE_INFINITY", Number.NaN) +testmath("Math.tan", "Math.PI/4", 1) +testmath("Math.tan", "3*Math.PI/4", -1) +testmath("Math.tan", "Math.PI", -0) +testmath("Math.tan", "5*Math.PI/4", 1) +testmath("Math.tan", "7*Math.PI/4", -1) +testmath("Infinity/Math.tan", "-0", -Infinity) diff --git a/js/src/jit-test/tests/basic/math-random.js b/js/src/jit-test/tests/basic/math-random.js new file mode 100644 index 000000000..e9efab588 --- /dev/null +++ b/js/src/jit-test/tests/basic/math-random.js @@ -0,0 +1,43 @@ +function test() { + setRNGState(0x12341234, 0x98765); + + function f() { + let x = []; + for (let i = 0; i < 10000; i++) { + x.push(Math.random()); + } + return x; + } + let x = f(); + assertEq(x[0], 0.28443027522441433); + assertEq(x[10], 0.5283908544644392); + assertEq(x[100], 0.5593668121538891); + assertEq(x[1000], 0.7008807796441313); + assertEq(x[2000], 0.11737403776989574); + assertEq(x[3000], 0.08573924080320472); + assertEq(x[4000], 0.22428965439295678); + assertEq(x[5000], 0.4657521920883555); + assertEq(x[6000], 0.11816220100329233); + assertEq(x[7000], 0.6306689010335697); + assertEq(x[8000], 0.8654862148946609); + assertEq(x[9000], 0.31734259460387015); + assertEq(x[9999], 0.013959566914027777); + + // Test some other (arbitrary) seeds. + setRNGState(0, 1); + x = f(); + assertEq(x[0], 2.220446049250313e-16); + assertEq(x[2000], 0.8259328082050756); + assertEq(x[6000], 0.01060492365550314); + assertEq(x[9999], 0.7402370773147143); + + setRNGState(0x0fff0101, 0x44440001); + x = f(); + assertEq(x[0], 0.24994062119568194); + assertEq(x[2000], 0.4375430448883283); + assertEq(x[6000], 0.7298689950209452); + assertEq(x[9999], 0.13284280897626954); +} + +if (typeof setRNGState == "function") + test(); diff --git a/js/src/jit-test/tests/basic/mathImul.js b/js/src/jit-test/tests/basic/mathImul.js new file mode 100644 index 000000000..aa1861e5a --- /dev/null +++ b/js/src/jit-test/tests/basic/mathImul.js @@ -0,0 +1,71 @@ + +var table = [ + [NaN, 0, 0], + [Infinity, Infinity, 0], + [NaN, 1000, 0], + + [-1, -2, 2], + [1, 2, 2], + [-1, 2, -2], + [1, -2, -2], + [-0, 0, 0], + [0, -0, 0], + [-1, -0, 0], + [1, -0, 0], + + [0xffffffff, 1, -1], + + [0xffffffff, 0xffffffff, 1], + [0xffffffff, -0xffffffff, -1], + [0xffffffff, 0xfffffffe, 2], + [0xffffffff, -0xfffffffe, -2], + [0x10000, 0x10000, 0], + + [{}, {}, 0], + [[], [], 0], + [{}, [], 0], + [[], {}, 0], + + [{valueOf: function() { return -1; }}, 0x100000, -1048576], + ["3", "-4", -12], + [3.4, 6, 18] +]; + +try { + Math.imul({ valueOf: function() { throw "ha ha ha"; } }); + assertEq(true, false, "no error thrown"); +} catch (e) { + assertEq(e, "ha ha ha"); +} + +var order = []; +assertEq(Math.imul({ valueOf: function() { order.push("first"); return 0; } }, + { valueOf: function() { order.push("second"); return 0; } }), + 0); +assertEq(order[0], "first"); +assertEq(order[1], "second"); + +var seen = []; +try +{ + Math.imul({ valueOf: function() { seen.push("one"); return 17; } }, + { valueOf: function() { throw "abort!"; } }); + assertEq(true, false, "no error thrown"); +} +catch (e) +{ + assertEq(e, "abort!", "should have thrown partway through, instead threw " + e); +} +assertEq(seen.length, 1); +assertEq(seen[0], "one"); + +assertEq(Math.imul(), 0); +assertEq(Math.imul(100), 0); +assertEq(Math.imul(NaN, 100), 0); +assertEq(Math.imul(NaN, NaN), 0); +assertEq(Math.imul(5, Infinity), 0); + +for (var i = 0; i < table.length; i++) { + assertEq(Math.imul(table[i][0], table[i][1]), table[i][2]); + assertEq(Math.imul(table[i][1], table[i][0]), table[i][2]); +} diff --git a/js/src/jit-test/tests/basic/mathRoundBig.js b/js/src/jit-test/tests/basic/mathRoundBig.js new file mode 100644 index 000000000..e01ffa4f5 --- /dev/null +++ b/js/src/jit-test/tests/basic/mathRoundBig.js @@ -0,0 +1,10 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +assertEq(Math.round(9007199254740991), 9007199254740991); +assertEq(Math.round(-19007199254740990), -19007199254740990); + +assertEq(Math.round("9007199254740991"), 9007199254740991); +assertEq(Math.round("-19007199254740990"), -19007199254740990); diff --git a/js/src/jit-test/tests/basic/maxConvertAllArgs.js b/js/src/jit-test/tests/basic/maxConvertAllArgs.js new file mode 100644 index 000000000..9fd919840 --- /dev/null +++ b/js/src/jit-test/tests/basic/maxConvertAllArgs.js @@ -0,0 +1,11 @@ +//Bug 818620
+
+load(libdir + "asserts.js");
+
+assertThrowsInstanceOf(function () {
+ Math.max(NaN, { valueOf: function () { throw new Error() } });
+}, Error);
+
+assertThrowsInstanceOf(function () {
+ Math.min(NaN, { valueOf: function () { throw new Error() } });
+}, Error);
diff --git a/js/src/jit-test/tests/basic/merge_type_maps.js b/js/src/jit-test/tests/basic/merge_type_maps.js new file mode 100644 index 000000000..1be4b9df5 --- /dev/null +++ b/js/src/jit-test/tests/basic/merge_type_maps.js @@ -0,0 +1,9 @@ +var merge_type_maps_x = 0, merge_type_maps_y = 0; +function merge_type_maps() { + for (merge_type_maps_x = 0; merge_type_maps_x < 50; ++merge_type_maps_x) + if ((merge_type_maps_x & 1) == 1) + ++merge_type_maps_y; + return [merge_type_maps_x,merge_type_maps_y].join(","); +} +merge_type_maps(); + diff --git a/js/src/jit-test/tests/basic/metadata-hook.js b/js/src/jit-test/tests/basic/metadata-hook.js new file mode 100644 index 000000000..2b251ab8c --- /dev/null +++ b/js/src/jit-test/tests/basic/metadata-hook.js @@ -0,0 +1,30 @@ + +enableShellAllocationMetadataBuilder(); + +function Foo() { + this.x = 0; + this.y = 1; +} + +function hello() { + function there() { + w = new Foo(); + x = [1,2,3]; + y = [2,3,5]; + z = {a:0,b:1}; + } + callee = there; + callee(); +} +hello(); + +var wc = getAllocationMetadata(w).index; +var xc = getAllocationMetadata(x).index; +var yc = getAllocationMetadata(y).index; +var zc = getAllocationMetadata(z).index; + +assertEq(xc > wc, true); +assertEq(yc > xc, true); +assertEq(zc > yc, true); +assertEq(getAllocationMetadata(x).stack[0], callee); +assertEq(getAllocationMetadata(x).stack[1], hello); diff --git a/js/src/jit-test/tests/basic/missingArgTest.js b/js/src/jit-test/tests/basic/missingArgTest.js new file mode 100644 index 000000000..28fe79036 --- /dev/null +++ b/js/src/jit-test/tests/basic/missingArgTest.js @@ -0,0 +1,12 @@ +function arity1(x) +{ + return (x == undefined) ? 1 : 0; +} +function missingArgTest() { + var q; + for (var i = 0; i < 10; i++) { + q = arity1(); + } + return q; +} +assertEq(missingArgTest(), 1); diff --git a/js/src/jit-test/tests/basic/missingArgTest2.js b/js/src/jit-test/tests/basic/missingArgTest2.js new file mode 100644 index 000000000..3d48a369d --- /dev/null +++ b/js/src/jit-test/tests/basic/missingArgTest2.js @@ -0,0 +1,26 @@ +JSON = function () { + return { + stringify: function stringify(value, whitelist) { + switch (typeof(value)) { + case "object": + return value.constructor.name; + } + } + }; +}(); + +function missingArgTest2() { + var testPairs = [ + ["{}", {}], + ["[]", []], + ['{"foo":"bar"}', {"foo":"bar"}], + ] + + var a = []; + for (var i=0; i < testPairs.length; i++) { + var s = JSON.stringify(testPairs[i][1]) + a[i] = s; + } + return a.join(","); +} +assertEq(missingArgTest2(), "Object,Array,Object"); diff --git a/js/src/jit-test/tests/basic/mod.js b/js/src/jit-test/tests/basic/mod.js new file mode 100644 index 000000000..cd8f6f6b9 --- /dev/null +++ b/js/src/jit-test/tests/basic/mod.js @@ -0,0 +1,14 @@ +function mod() +{ + var mods = [-1,-1,-1,-1]; + var a = 9.5, b = -5, c = 42, d = (1/0); + for (var i = 0; i < 20; i++) { + mods[0] = a % b; + mods[1] = b % 1; + mods[2] = c % d; + mods[3] = c % a; + mods[4] = b % 0; + } + return mods.toString(); +} +assertEq(mod(), "4.5,0,42,4,NaN"); diff --git a/js/src/jit-test/tests/basic/multiple-declared-args-syntax.js b/js/src/jit-test/tests/basic/multiple-declared-args-syntax.js new file mode 100644 index 000000000..d41a98fcc --- /dev/null +++ b/js/src/jit-test/tests/basic/multiple-declared-args-syntax.js @@ -0,0 +1 @@ +assertEq((function (a, b, a) { return a; })(2, 4, 6), 6); diff --git a/js/src/jit-test/tests/basic/mutable-proto-teleporting.js b/js/src/jit-test/tests/basic/mutable-proto-teleporting.js new file mode 100644 index 000000000..a52faf1c5 --- /dev/null +++ b/js/src/jit-test/tests/basic/mutable-proto-teleporting.js @@ -0,0 +1,18 @@ +// The teleporting optimization should work correctly +// when we modify an object's proto. + +var A = {x: 1}; +var B = Object.create(A); + +var C = {}; +C.__proto__ = B; + +function f() { + for (var i=0; i<25; i++) { + assertEq(C.x, (i <= 20) ? 1 : 3); + if (i === 20) { + B.x = 3; + } + } +} +f(); diff --git a/js/src/jit-test/tests/basic/name-inactive-del.js b/js/src/jit-test/tests/basic/name-inactive-del.js new file mode 100644 index 000000000..ba2f69f09 --- /dev/null +++ b/js/src/jit-test/tests/basic/name-inactive-del.js @@ -0,0 +1,28 @@ +function mp(g) { + var ans = ''; + for (var i = 0; i < 5; ++i) { + ans += g(); + } + + return ans; +} + +function f() { + var k = 5; + + function g() { + return k; + } + + ans = ''; + + k = 6; + ans += mp(g); + + delete k; + ans += mp(g); + + return ans; +} + +assertEq(f(), '6666666666'); diff --git a/js/src/jit-test/tests/basic/name-inactive-eval-del.js b/js/src/jit-test/tests/basic/name-inactive-eval-del.js new file mode 100644 index 000000000..593ab39ff --- /dev/null +++ b/js/src/jit-test/tests/basic/name-inactive-eval-del.js @@ -0,0 +1,10 @@ +function mp(g) { + ans = '' + for (var i = 0; i < 5; ++i) { + ans += g(); + } + return ans; +} + +var f = eval("(function() { var k = 5; function g() { return k; } k = 6; mp(g); delete k; return mp(g); })"); +assertEq(f(), "66666"); diff --git a/js/src/jit-test/tests/basic/name-inactive-inferflags.js b/js/src/jit-test/tests/basic/name-inactive-inferflags.js new file mode 100644 index 000000000..0bbd3fb2c --- /dev/null +++ b/js/src/jit-test/tests/basic/name-inactive-inferflags.js @@ -0,0 +1,18 @@ +function addAccumulations(f) { + var a = f(); + var b = f(); + return a() + b(); +} + +function loopingAccumulator() { + var x = 0; + return function () { + for (var i = 0; i < 10; ++i) { + ++x; + } + return x; + } +} + +var x = addAccumulations(loopingAccumulator); +assertEq(x, 20); diff --git a/js/src/jit-test/tests/basic/name-inactive.js b/js/src/jit-test/tests/basic/name-inactive.js new file mode 100644 index 000000000..6f3b9c4c0 --- /dev/null +++ b/js/src/jit-test/tests/basic/name-inactive.js @@ -0,0 +1,15 @@ +function f(k) { + function g(j) { + return j + k; + } + return g; +} + +g = f(10); +var ans = ''; +for (var i = 0; i < 5; ++i) { + ans += g(i) + ','; +} + +assertEq(ans, '10,11,12,13,14,'); + diff --git a/js/src/jit-test/tests/basic/name.js b/js/src/jit-test/tests/basic/name.js new file mode 100644 index 000000000..92b76d022 --- /dev/null +++ b/js/src/jit-test/tests/basic/name.js @@ -0,0 +1,9 @@ +globalName = 907; +function name() +{ + var a = 0; + for (var i = 0; i < 100; i++) + a = globalName; + return a; +} +assertEq(name(), 907); diff --git a/js/src/jit-test/tests/basic/nestedContinue.js b/js/src/jit-test/tests/basic/nestedContinue.js new file mode 100644 index 000000000..23cd702bf --- /dev/null +++ b/js/src/jit-test/tests/basic/nestedContinue.js @@ -0,0 +1,11 @@ +x = 10; +outer: +while (x < 10) { + while (x < 10) { + if (x < 10) + continue outer; + while (x < 10) { + y = 0; + } + } +} diff --git a/js/src/jit-test/tests/basic/nestedExit2.js b/js/src/jit-test/tests/basic/nestedExit2.js new file mode 100644 index 000000000..a868954f2 --- /dev/null +++ b/js/src/jit-test/tests/basic/nestedExit2.js @@ -0,0 +1,17 @@ +function bitsinbyte(b) { + var m = 1, c = 0; + while(m<0x100) { + if(b & m) c++; + m <<= 1; + } + return 1; +} +function TimeFunc(func) { + var x,y; + for(var y=0; y<256; y++) func(y); +} +function nestedExit2() { + TimeFunc(bitsinbyte); + return "ok"; +} +assertEq(nestedExit2(), "ok"); diff --git a/js/src/jit-test/tests/basic/nestedExitLoop.js b/js/src/jit-test/tests/basic/nestedExitLoop.js new file mode 100644 index 000000000..fffc8573b --- /dev/null +++ b/js/src/jit-test/tests/basic/nestedExitLoop.js @@ -0,0 +1,14 @@ +function nestedExit(x) { + var q = 0; + for (var i = 0; i < 10; ++i) + { + if (x) + ++q; + } +} +function nestedExitLoop() { + for (var j = 0; j < 10; ++j) + nestedExit(j < 7); + return "ok"; +} +assertEq(nestedExitLoop(), "ok"); diff --git a/js/src/jit-test/tests/basic/new-Function-prototype.js b/js/src/jit-test/tests/basic/new-Function-prototype.js new file mode 100644 index 000000000..65198cabb --- /dev/null +++ b/js/src/jit-test/tests/basic/new-Function-prototype.js @@ -0,0 +1,16 @@ +var funProto = Function.prototype; +assertEq(Object.getOwnPropertyDescriptor(funProto, "prototype"), undefined); +assertEq(parseInt.prototype, undefined); +var oldObj; +for (var i = 0, sz = 9; i < sz; oldObj = obj, i++) +{ + + try { + var obj = new funProto; + } + catch (e) {} + assertEq(Object.getOwnPropertyDescriptor(funProto, "prototype"), undefined); + assertEq(Object.getOwnPropertyDescriptor(parseInt, "prototype"), undefined); + assertEq(parseInt.prototype, undefined); +} + diff --git a/js/src/jit-test/tests/basic/new-bound-function.js b/js/src/jit-test/tests/basic/new-bound-function.js new file mode 100644 index 000000000..49d06d8c3 --- /dev/null +++ b/js/src/jit-test/tests/basic/new-bound-function.js @@ -0,0 +1,20 @@ +var funProto = Function.prototype; +assertEq(Object.getOwnPropertyDescriptor(funProto, "prototype"), undefined); + +function Point(x, y) { this.x = x; this.y = y; } + +var YAxisPoint = Point.bind(null, 0); + +assertEq(YAxisPoint.prototype, undefined); + +var oldPoint; +for (var i = 0, sz = 9; i < sz; oldPoint = point, i++) +{ + var point = new YAxisPoint(5); + assertEq(point === oldPoint, false); + assertEq(point.x, 0); + assertEq(point.y, 5); + assertEq(Object.getOwnPropertyDescriptor(funProto, "prototype"), undefined); + assertEq(Object.getOwnPropertyDescriptor(YAxisPoint, "prototype"), undefined); +} + diff --git a/js/src/jit-test/tests/basic/new-read-before-write.js b/js/src/jit-test/tests/basic/new-read-before-write.js new file mode 100644 index 000000000..a5259b211 --- /dev/null +++ b/js/src/jit-test/tests/basic/new-read-before-write.js @@ -0,0 +1,24 @@ + +function Foo() { + var x = this.property; + this.property = 5; + glob = x; +} +Foo.prototype.property = 10; +for (var i = 0; i < 10; i++) { + new Foo(); + assertEq(glob, 10); +} + +function Bar() { + this.property; + this.other = 5; +} +Bar.prototype.other = 10; +Object.defineProperty(Bar.prototype, "property", { + get: function() { glob = this.other; } +}); +for (var i = 0; i < 10; i++) { + new Bar(); + assertEq(glob, 10); +} diff --git a/js/src/jit-test/tests/basic/newArrayTest.js b/js/src/jit-test/tests/basic/newArrayTest.js new file mode 100644 index 000000000..aca33bcfd --- /dev/null +++ b/js/src/jit-test/tests/basic/newArrayTest.js @@ -0,0 +1,8 @@ +function newArrayTest() +{ + var a = []; + for (var i = 0; i < 10; i++) + a[i] = new Array(); + return a.map(x => x.length).toString(); +} +assertEq(newArrayTest(), "0,0,0,0,0,0,0,0,0,0"); diff --git a/js/src/jit-test/tests/basic/newTargetOSR.js b/js/src/jit-test/tests/basic/newTargetOSR.js new file mode 100644 index 000000000..b90e96cf1 --- /dev/null +++ b/js/src/jit-test/tests/basic/newTargetOSR.js @@ -0,0 +1,6 @@ +function testOSRNewTarget(expected) { + for (let i = 0; i < 1100; i++) + assertEq(new.target, expected); +} + +new testOSRNewTarget(testOSRNewTarget); diff --git a/js/src/jit-test/tests/basic/newTargetRectifier.js b/js/src/jit-test/tests/basic/newTargetRectifier.js new file mode 100644 index 000000000..78716869f --- /dev/null +++ b/js/src/jit-test/tests/basic/newTargetRectifier.js @@ -0,0 +1,12 @@ +function testBailoutNewTarget() { + function Inner(ex, forceRectifier) { + bailout(); + assertEq(new.target, ex); + } + + for (let i = 0; i < 1100; i++) + new Inner(Inner); +} + +for (let i = 0; i < 15; i++) + testBailoutNewTarget(); diff --git a/js/src/jit-test/tests/basic/newTest.js b/js/src/jit-test/tests/basic/newTest.js new file mode 100644 index 000000000..5defbe9f2 --- /dev/null +++ b/js/src/jit-test/tests/basic/newTest.js @@ -0,0 +1,14 @@ +function MyConstructor(i) +{ + this.i = i; +} +MyConstructor.prototype.toString = function() {return this.i + ""}; + +function newTest() +{ + var a = []; + for (var i = 0; i < 10; i++) + a[i] = new MyConstructor(i); + return a.join(""); +} +assertEq(newTest(), "0123456789"); diff --git a/js/src/jit-test/tests/basic/non-extensible-array.js b/js/src/jit-test/tests/basic/non-extensible-array.js new file mode 100644 index 000000000..133ec2bf1 --- /dev/null +++ b/js/src/jit-test/tests/basic/non-extensible-array.js @@ -0,0 +1,7 @@ + +function foo(x) { + Object.seal(x); + x[3] = 4; + assertEq("" + x, "1,2,3"); +} +foo([1,2,3]); diff --git a/js/src/jit-test/tests/basic/nonEmptyStack1.js b/js/src/jit-test/tests/basic/nonEmptyStack1.js new file mode 100644 index 000000000..b3b260386 --- /dev/null +++ b/js/src/jit-test/tests/basic/nonEmptyStack1.js @@ -0,0 +1,13 @@ +function nonEmptyStack1Helper(o, farble) { + var a = []; + var j = 0; + for (var i in o) + a[j++] = i; + return a.join(""); +} + +function nonEmptyStack1() { + return nonEmptyStack1Helper({a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8}, "hi"); +} + +assertEq(nonEmptyStack1(), "abcdefgh"); diff --git a/js/src/jit-test/tests/basic/nonEmptyStack2.js b/js/src/jit-test/tests/basic/nonEmptyStack2.js new file mode 100644 index 000000000..fb8394245 --- /dev/null +++ b/js/src/jit-test/tests/basic/nonEmptyStack2.js @@ -0,0 +1,10 @@ +function nonEmptyStack2() +{ + var a = 0; + for (var c in {a:1, b:2, c:3}) { + for (var i = 0; i < 10; i++) + a += i; + } + return String(a); +} +assertEq(nonEmptyStack2(), "135"); diff --git a/js/src/jit-test/tests/basic/null-filename-Error.js b/js/src/jit-test/tests/basic/null-filename-Error.js new file mode 100644 index 000000000..acba37346 --- /dev/null +++ b/js/src/jit-test/tests/basic/null-filename-Error.js @@ -0,0 +1,11 @@ +// Compiling a script with null filename does not break the Error constructor. + +var exc = null; +try { + evaluate("throw Error('pass');", {fileName: null}); +} catch (x) { + exc = x; +} +assertEq(exc.constructor, Error); +assertEq(exc.message, "pass"); +assertEq(exc.fileName, ""); diff --git a/js/src/jit-test/tests/basic/number-isfinite.js b/js/src/jit-test/tests/basic/number-isfinite.js new file mode 100644 index 000000000..fc58b4c66 --- /dev/null +++ b/js/src/jit-test/tests/basic/number-isfinite.js @@ -0,0 +1,15 @@ +assertEq(Number.isFinite(Infinity), false); +assertEq(Number.isFinite(-Infinity), false); +assertEq(Number.isFinite(NaN), false); +assertEq(Number.isFinite(4), true); +assertEq(Number.isFinite(4.5), true); +assertEq(Number.isFinite("hi"), false); +assertEq(Number.isFinite("1.3"), false); +assertEq(Number.isFinite("51"), false); +assertEq(Number.isFinite(0), true); +assertEq(Number.isFinite(-0), true); +assertEq(Number.isFinite({valueOf: function () { return 3; }}), false); +assertEq(Number.isFinite({valueOf: function () { return 0/0; }}), false); +assertEq(Number.isFinite({ valueOf: function() { throw 17; } }), false); +assertEq(Number.isFinite({ toString: function() { throw 17; } }), false); +assertEq(Number.isFinite({ valueOf: function() { throw 17; }, toString: function() { throw 42; } }), false); diff --git a/js/src/jit-test/tests/basic/number-isinteger.js b/js/src/jit-test/tests/basic/number-isinteger.js new file mode 100644 index 000000000..750a98787 --- /dev/null +++ b/js/src/jit-test/tests/basic/number-isinteger.js @@ -0,0 +1,15 @@ +assertEq(Number.isInteger(4), true); +assertEq(Number.isInteger(4.), true); +assertEq(Number.isInteger(4.2), false); +assertEq(Number.isInteger(0.), true); +assertEq(Number.isInteger(-0.), true); +assertEq(Number.isInteger(Infinity), false); +assertEq(Number.isInteger(-Infinity), false); +assertEq(Number.isInteger(NaN), false); +assertEq(Number.isInteger(true), false); +assertEq(Number.isInteger(false), false); +assertEq(Number.isInteger({valueOf: function () { return 3; }}), false); +assertEq(Number.isInteger({valueOf: function () { return 0/0; }}), false); +assertEq(Number.isInteger({ valueOf: function() { throw 17; } }), false); +assertEq(Number.isInteger({ toString: function() { throw 17; } }), false); +assertEq(Number.isInteger({ valueOf: function() { throw 17; }, toString: function() { throw 42; } }), false); diff --git a/js/src/jit-test/tests/basic/number-isnan.js b/js/src/jit-test/tests/basic/number-isnan.js new file mode 100644 index 000000000..78e834591 --- /dev/null +++ b/js/src/jit-test/tests/basic/number-isnan.js @@ -0,0 +1,15 @@ +assertEq(Number.isNaN(NaN), true); +assertEq(Number.isNaN(0/0), true); +assertEq(Number.isNaN(Number("NaN")), true); +assertEq(Number.isNaN(4), false); +assertEq(Number.isNaN(4.5), false); +assertEq(Number.isNaN("hi"), false); +assertEq(Number.isNaN("1.3"), false); +assertEq(Number.isNaN("51"), false); +assertEq(Number.isNaN(0), false); +assertEq(Number.isNaN(-0), false); +assertEq(Number.isNaN({valueOf: function () { return 3; }}), false); +assertEq(Number.isNaN({valueOf: function () { return 0/0; }}), false); +assertEq(Number.isNaN({ valueOf: function() { throw 17; } }), false); +assertEq(Number.isNaN({ toString: function() { throw 17; } }), false); +assertEq(Number.isNaN({ valueOf: function() { throw 17; }, toString: function() { throw 42; } }), false); diff --git a/js/src/jit-test/tests/basic/object-is.js b/js/src/jit-test/tests/basic/object-is.js new file mode 100644 index 000000000..a62b5dfe8 --- /dev/null +++ b/js/src/jit-test/tests/basic/object-is.js @@ -0,0 +1,41 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var list = [ + [1, 1, true], + [0, 1, false], + [3.5, 3.5, true], + [0, 0, true], + [0, -0, false], + [-0, 0, false], + [-0, -0, true], + + [true, true, true], + [true, false, false], + [false, false, true], + + [NaN, NaN, true], + [NaN, undefined, false], + [Infinity, -Infinity, false], + [Infinity, Infinity, true], +] + +for (var test of list) { + assertEq(Object.is(test[0], test[1]), test[2]) +} + +var obj = {} +assertEq(Object.is(obj, obj), true); +assertEq(Object.is(obj, {}), false); +assertEq(Object.is([], []), false); + +assertEq(Object.is(null, null, null), true); + +/* Not defined parameters are undefined ... */ +assertEq(Object.is(null), false); +assertEq(Object.is(undefined), true); +assertEq(Object.is(), true); + +assertEq(Object.is.length, 2); diff --git a/js/src/jit-test/tests/basic/object-lookup-shadowing.js b/js/src/jit-test/tests/basic/object-lookup-shadowing.js new file mode 100644 index 000000000..927727e32 --- /dev/null +++ b/js/src/jit-test/tests/basic/object-lookup-shadowing.js @@ -0,0 +1,5 @@ +var x = {get prop() { return 2; }, set prop(v) {}}; +var y = {__proto__: x, prop: 1}; + +assertEq(y.__lookupGetter__("prop"), undefined); +assertEq(y.__lookupSetter__("prop"), undefined); diff --git a/js/src/jit-test/tests/basic/object-loose-equality.js b/js/src/jit-test/tests/basic/object-loose-equality.js new file mode 100644 index 000000000..b1f72960b --- /dev/null +++ b/js/src/jit-test/tests/basic/object-loose-equality.js @@ -0,0 +1,58 @@ +var obj = {}; +var sym = Symbol(); + +var notEqual = [ + [obj, sym], + + [0, {valueOf() { return null; }}], + [0, {toString() { return null; }}], + [null, {valueOf() { return null; }}], + [null, {toString() { return null; }}], + [undefined, {valueOf() { return null; }}], + [undefined, {toString() { return null; }}], + ["", {valueOf() { return null; }}], + ["", {toString() { return null; }}], + ["0", {valueOf() { return null; }}], + ["0", {toString() { return null; }}], + + [0, {valueOf() { return undefined; }}], + [0, {toString() { return undefined; }}], + [null, {valueOf() { return undefined; }}], + [null, {toString() { return undefined; }}], + [undefined, {valueOf() { return undefined; }}], + [undefined, {toString() { return undefined; }}], + ["", {valueOf() { return undefined; }}], + ["", {toString() { return undefined; }}], + ["0", {valueOf() { return undefined; }}], + ["0", {toString() { return undefined; }}], +] + +var equal = [ + [sym, {valueOf() { return sym; }}], + [sym, {toString() { return sym; }}], + + ["abc", {valueOf() { return "abc"; }}], + ["abc", {toString() { return "abc"; }}], + + [1, {valueOf() { return 1; }}], + [1, {toString() { return 1; }}], + + [1, {valueOf() { return true; }}], + [1, {toString() { return true; }}], + + [true, {valueOf() { return true; }}], + [true, {toString() { return true; }}], + + [true, {valueOf() { return 1; }}], + [true, {toString() { return 1; }}], +] + +for (var [lhs, rhs] of notEqual) { + assertEq(lhs == rhs, false); + assertEq(rhs == lhs, false); +} + +for (var [lhs, rhs] of equal) { + assertEq(lhs == rhs, true); + assertEq(rhs == lhs, true); +} diff --git a/js/src/jit-test/tests/basic/object-shorthand.js b/js/src/jit-test/tests/basic/object-shorthand.js new file mode 100644 index 000000000..934f46680 --- /dev/null +++ b/js/src/jit-test/tests/basic/object-shorthand.js @@ -0,0 +1,90 @@ + +load(libdir + 'asserts.js'); + +// globals: +a = b = get = set = eval = arguments = 10; + +assertEq({arguments}.arguments, 10); + +var o = {a, b: b, get, set: set}; +assertEq(o.a, 10); +assertEq(o.b, 10); +assertEq(o.get, 10); +assertEq(o.set, 10); + +var names = ['a', 'get', 'set', 'eval']; +// global +names.forEach(ident => + assertEq(new Function('return {' + ident + '}.' + ident + ';')(), 10)); +// local +names.forEach(ident => + assertEq(new Function('var ' + ident + ' = 20; return {' + ident + '}.' + ident + ';')(), 20)); +// scope +names.forEach(ident => + assertEq(new Function('var ' + ident + ' = 30; return (function () {return {' + ident + '}.' + ident + ';})();')(), 30)); + +var reserved = [ + 'break', + 'do', + 'in', + 'typeof', + 'case', + 'else', + 'instanceof', + 'var', + 'catch', + 'export', + 'new', + 'void', + 'class', + 'extends', + 'return', + 'while', + 'const', + 'finally', + 'super', + 'with', + 'continue', + 'for', + 'switch', + 'debugger', + 'function', + 'this', + 'delete', + 'import', + 'try', + 'enum', + 'null', + 'true', + 'false' +]; + +// non-identifiers should also throw +var nonidents = [ + '"str"', + '0' +]; + +reserved.concat(nonidents).forEach(ident => + assertThrowsInstanceOf(() => new Function('return {' + ident + '}'), SyntaxError)); + +var reservedStrict = [ + 'implements', + 'interface', + 'package', + 'private', + 'protected', + 'public', + 'static', + // XXX: according to 12.1.1, these should only be errors in strict code: + // see https://bugzilla.mozilla.org/show_bug.cgi?id=1032150 + //'let', + //'yield' +]; + +reservedStrict.forEach(ident => + assertEq(new Function('var ' + ident + ' = 10; return {' + ident + '}.' + ident + ';')(), 10)); + +reservedStrict.concat(['let', 'yield']).forEach(ident => + assertThrowsInstanceOf(() => new Function('"use strict"; return {' + ident + '}'), SyntaxError)); + diff --git a/js/src/jit-test/tests/basic/offThreadCompileScript-01.js b/js/src/jit-test/tests/basic/offThreadCompileScript-01.js new file mode 100644 index 000000000..5903b0df8 --- /dev/null +++ b/js/src/jit-test/tests/basic/offThreadCompileScript-01.js @@ -0,0 +1,21 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// Test off-thread parsing. + +load(libdir + 'asserts.js'); + +if (helperThreadCount() === 0) + quit(0); + +offThreadCompileScript('Math.sin(Math.PI/2)'); +assertEq(runOffThreadScript(), 1); + +offThreadCompileScript('a string which cannot be reduced to the start symbol'); +assertThrowsInstanceOf(runOffThreadScript, SyntaxError); + +offThreadCompileScript('smerg;'); +assertThrowsInstanceOf(runOffThreadScript, ReferenceError); + +offThreadCompileScript('throw "blerg";'); +assertThrowsValue(runOffThreadScript, 'blerg'); diff --git a/js/src/jit-test/tests/basic/offThreadCompileScript-02.js b/js/src/jit-test/tests/basic/offThreadCompileScript-02.js new file mode 100644 index 000000000..9a2276bd3 --- /dev/null +++ b/js/src/jit-test/tests/basic/offThreadCompileScript-02.js @@ -0,0 +1,20 @@ +// Test offThreadCompileScript option handling. + +if (helperThreadCount() === 0) + quit(0); + +offThreadCompileScript('Error()'); +assertEq(!!runOffThreadScript().stack.match(/^@<string>:1:1\n/), true); + +offThreadCompileScript('Error()', + { fileName: "candelabra", lineNumber: 6502 }); +assertEq(!!runOffThreadScript().stack.match(/^@candelabra:6502:1\n/), true); + +var element = {}; +offThreadCompileScript('Error()', { element: element }); // shouldn't crash +runOffThreadScript(); + +var elementAttributeName = "molybdenum"; +elementAttributeName += elementAttributeName + elementAttributeName + elementAttributeName; +offThreadCompileScript('Error()', { elementAttributeName: elementAttributeName }); // shouldn't crash +runOffThreadScript(); diff --git a/js/src/jit-test/tests/basic/orNaNTest1.js b/js/src/jit-test/tests/basic/orNaNTest1.js new file mode 100644 index 000000000..0b713b2c5 --- /dev/null +++ b/js/src/jit-test/tests/basic/orNaNTest1.js @@ -0,0 +1,3 @@ +load(libdir + 'orTestHelper.js'); +var orNaNTest1 = new Function("return orTestHelper(NaN, NaN, 10);"); +assertEq(orNaNTest1(), 0); diff --git a/js/src/jit-test/tests/basic/orNaNTest2.js b/js/src/jit-test/tests/basic/orNaNTest2.js new file mode 100644 index 000000000..113fe038f --- /dev/null +++ b/js/src/jit-test/tests/basic/orNaNTest2.js @@ -0,0 +1,3 @@ +load(libdir + 'orTestHelper.js'); +var orNaNTest2 = new Function("return orTestHelper(NaN, 1, 10);"); +assertEq(orNaNTest2(), 45); diff --git a/js/src/jit-test/tests/basic/outerline.js b/js/src/jit-test/tests/basic/outerline.js new file mode 100644 index 000000000..805686408 --- /dev/null +++ b/js/src/jit-test/tests/basic/outerline.js @@ -0,0 +1,15 @@ +function outerline(){ + var i=0; + var j=0; + + for (i = 3; i<= 100000; i+=2) + { + for (j = 3; j < 1000; j+=2) + { + if ((i & 1) == 1) + break; + } + } + return "ok"; +} +assertEq(outerline(), "ok"); diff --git a/js/src/jit-test/tests/basic/parseIntTests.js b/js/src/jit-test/tests/basic/parseIntTests.js new file mode 100644 index 000000000..852dd9021 --- /dev/null +++ b/js/src/jit-test/tests/basic/parseIntTests.js @@ -0,0 +1,23 @@ +function parseIntHelper(n) { + var a; + for (var i = 0; i < 5; i++) + a = parseInt(n); + return a; +} +function doParseIntTests() { + var inputs = [0, -0, .1, -.1, .7, -.7, 1.3, -1.3]; + var outputs = new Array(8); + //avoid jit, unrolled + outputs[0] = outputs[1] = outputs[2] = outputs[4] = 0; + outputs[3] = outputs[5] = -0; + outputs[6] = 1; + outputs[7] = -1; + for (var i = 0; i < 8; i++) { + var testfn = new Function('return parseIntHelper(' + uneval(inputs[i]) + ');'); + assertEq(testfn(), outputs[i]); + } +} +doParseIntTests(); + +assertEq(parseInt("08"), 8); +assertEq(parseInt("09"), 9); diff --git a/js/src/jit-test/tests/basic/parsingNumbers.js b/js/src/jit-test/tests/basic/parsingNumbers.js new file mode 100644 index 000000000..1630612b6 --- /dev/null +++ b/js/src/jit-test/tests/basic/parsingNumbers.js @@ -0,0 +1,23 @@ +function parsingNumbers() { + var s1 = "123"; + var s1z = "123zzz"; + var s2 = "123.456"; + var s2z = "123.456zzz"; + + var e1 = 123; + var e2 = 123.456; + + var r1, r1z, r2, r2z; + + for (var i = 0; i < 10; i++) { + r1 = parseInt(s1); + r1z = parseInt(s1z); + r2 = parseFloat(s2); + r2z = parseFloat(s2z); + } + + if (r1 == e1 && r1z == e1 && r2 == e2 && r2z == e2) + return "ok"; + return "fail"; +} +assertEq(parsingNumbers(), "ok"); diff --git a/js/src/jit-test/tests/basic/perf-smoketest.js b/js/src/jit-test/tests/basic/perf-smoketest.js new file mode 100644 index 000000000..7c442caee --- /dev/null +++ b/js/src/jit-test/tests/basic/perf-smoketest.js @@ -0,0 +1,34 @@ +function spin_loop() +{ + for (let i = 0; i < 10000; i++) ; +} + +function check_timing(label, count) { + if (count == -1) { + print("TEST-UNEXPECTED-FAIL | TestPerf | " + label); + throwError(); + } else { + print("TEST-PASS | TestPerf | " + label + " = " + count); + } +} + +var pm = new PerfMeasurement(PerfMeasurement.ALL); +if (pm.eventsMeasured == 0) { + print("TEST-KNOWN-FAIL | perf-smoketest | stub, skipping test"); +} else { + pm.start(); + spin_loop(); + pm.stop(); + + check_timing("cpu_cycles", pm.cpu_cycles); + check_timing("instructions", pm.instructions); + check_timing("cache_references", pm.cache_references); + check_timing("cache_misses", pm.cache_misses); + check_timing("branch_instructions", pm.branch_instructions); + check_timing("branch_misses", pm.branch_misses); + check_timing("bus_cycles", pm.bus_cycles); + check_timing("page_faults", pm.page_faults); + check_timing("major_page_faults", pm.major_page_faults); + check_timing("context_switches", pm.context_switches); + check_timing("cpu_migrations", pm.cpu_migrations); +} diff --git a/js/src/jit-test/tests/basic/primitiveProto.js b/js/src/jit-test/tests/basic/primitiveProto.js new file mode 100644 index 000000000..e9043225c --- /dev/null +++ b/js/src/jit-test/tests/basic/primitiveProto.js @@ -0,0 +1,24 @@ + +function fna() {} +fna.prototype = undefined; +new fna; + +function fnb() {} +fnb.prototype = null; +new fnb; + +function fnc() {} +fnc.prototype = 3; +new fnc; + +function fnd() {} +fnd.prototype = true; +new fnd; + +function fne() {} +fne.prototype = "foo"; +new fne; + +function fnf() {} +fnf.prototype = /foo/; +new fnf; diff --git a/js/src/jit-test/tests/basic/properly-remove-timeout-root-before-shutdown.js b/js/src/jit-test/tests/basic/properly-remove-timeout-root-before-shutdown.js new file mode 100644 index 000000000..99eae1892 --- /dev/null +++ b/js/src/jit-test/tests/basic/properly-remove-timeout-root-before-shutdown.js @@ -0,0 +1,5 @@ +// Bug 857050: Remove the timeout function root before shutting down. +function timeoutfunc() {} +timeout(1, timeoutfunc); +var g = newGlobal(); +var dbg = Debugger(g); diff --git a/js/src/jit-test/tests/basic/property-enumeration-order.js b/js/src/jit-test/tests/basic/property-enumeration-order.js new file mode 100644 index 000000000..2a891b436 --- /dev/null +++ b/js/src/jit-test/tests/basic/property-enumeration-order.js @@ -0,0 +1,37 @@ +function check(obj, expected, expectedAll = expected) { + assertEq(Reflect.ownKeys(obj).join(""), expectedAll); + assertEq(Object.getOwnPropertyNames(obj).join(""), expectedAll); + assertEq(Object.keys(obj).join(""), expected); + var s = ""; + for (var x in obj) + s += x; + assertEq(s, expected); +} + +var obj = {2: 0, 0: 0, "foo": "bar", 4: 0, "-5": 1}; +check(obj, "024foo-5"); +obj.x = 1; +check(obj, "024foo-5x"); +obj[1] = 1; +check(obj, "0124foo-5x"); +obj[1.2] = 1; +check(obj, "0124foo-5x1.2"); +Object.defineProperty(obj, '3', {value:1,enumerable:false,configurable:false,writable:false}); +check(obj, "0124foo-5x1.2", "01234foo-5x1.2"); +delete obj[2]; +check(obj, "014foo-5x1.2", "0134foo-5x1.2"); +obj[2] = 1; +check(obj, "0124foo-5x1.2", "01234foo-5x1.2"); + +assertEq(JSON.stringify(obj), '{"0":0,"1":1,"2":1,"4":0,"foo":"bar","-5":1,"x":1,"1.2":1}'); + +var arr = [1, 2, 3]; +Object.defineProperty(arr, '3', {value:1,enumerable:true,configurable:true,writable:true}); +check(arr, "0123", "0123length"); +Object.defineProperty(arr, '1000', {value:1,enumerable:true,configurable:true,writable:false}); +check(arr, "01231000", "01231000length"); + +arr = [1, 2, , , 5]; +check(arr, "014", "014length"); +arr[0xfffffff] = 4; +check(arr, "014268435455", "014268435455length"); diff --git a/js/src/jit-test/tests/basic/putargsNoReturn.js b/js/src/jit-test/tests/basic/putargsNoReturn.js new file mode 100644 index 000000000..73df78b49 --- /dev/null +++ b/js/src/jit-test/tests/basic/putargsNoReturn.js @@ -0,0 +1,6 @@ +function f(a) { + x = arguments; +} +for (var i = 0; i < 9; i++) + f(123); +assertEq(x[0], 123); diff --git a/js/src/jit-test/tests/basic/putargsReturn.js b/js/src/jit-test/tests/basic/putargsReturn.js new file mode 100644 index 000000000..1a6f3c358 --- /dev/null +++ b/js/src/jit-test/tests/basic/putargsReturn.js @@ -0,0 +1,7 @@ +function f(a) { + x = arguments; + return 99; +} +for (var i = 0; i < 9; i++) + f(123); +assertEq(x[0], 123); diff --git a/js/src/jit-test/tests/basic/regexp-removed-dot-star.js b/js/src/jit-test/tests/basic/regexp-removed-dot-star.js new file mode 100644 index 000000000..521849488 --- /dev/null +++ b/js/src/jit-test/tests/basic/regexp-removed-dot-star.js @@ -0,0 +1,49 @@ + +// Test that removal of leading or trailing .* from RegExp test() calls +// does not affect lastMatch or other RegExpStatics info. + +function first(input) { + var re = /.*b(cd)/; + for (var i = 0; i < 10; i++) + re.test(input); +} + +first("1234\nabcdefg\n1234"); +assertEq(RegExp.lastMatch, "abcd"); +assertEq(RegExp.$1, "cd"); +assertEq(RegExp.input, "1234\nabcdefg\n1234"); +assertEq(RegExp.leftContext, "1234\n"); +assertEq(RegExp.rightContext, "efg\n1234"); +assertEq(RegExp.lastParen, "cd"); + + +// Test that removal of leading or trailing .* from RegExp test() calls +// does not affect lastMatch or other RegExpStatics info. + +function second(input) { + var re = /bcd.*/; + for (var i = 0; i < 10; i++) + re.test(input); +} + +second("1234\nabcdefg\n1234"); +assertEq(RegExp.lastMatch, "bcdefg"); +assertEq(RegExp.$1, ""); +assertEq(RegExp.input, "1234\nabcdefg\n1234"); +assertEq(RegExp.leftContext, "1234\na"); +assertEq(RegExp.rightContext, "\n1234"); +assertEq(RegExp.lastParen, ""); + +function third(input) { + var re = /.*bcd.*/; + for (var i = 0; i < 10; i++) + re.test(input); +} + +third("1234\nabcdefg\n1234"); +assertEq(RegExp.lastMatch, "abcdefg"); +assertEq(RegExp.$1, ""); +assertEq(RegExp.input, "1234\nabcdefg\n1234"); +assertEq(RegExp.leftContext, "1234\n"); +assertEq(RegExp.rightContext, "\n1234"); +assertEq(RegExp.lastParen, ""); diff --git a/js/src/jit-test/tests/basic/regexp-reset-input.js b/js/src/jit-test/tests/basic/regexp-reset-input.js new file mode 100644 index 000000000..77cdd69dd --- /dev/null +++ b/js/src/jit-test/tests/basic/regexp-reset-input.js @@ -0,0 +1,8 @@ +var re = /(pattern)/g; +var input = "patternpatternpattern"; +re.exec(input) +RegExp.input = "satturn"; +assertEq(RegExp.$1, "pattern"); +assertEq(RegExp.lastMatch, "pattern"); +assertEq(RegExp.lastParen, "pattern"); +assertEq(RegExp.rightContext, "patternpattern"); diff --git a/js/src/jit-test/tests/basic/regexp-sticky-undef-capture.js b/js/src/jit-test/tests/basic/regexp-sticky-undef-capture.js new file mode 100644 index 000000000..3d96d4e44 --- /dev/null +++ b/js/src/jit-test/tests/basic/regexp-sticky-undef-capture.js @@ -0,0 +1,8 @@ +var re = /abc(WHOO!)?def/y; +var input = 'abcdefabcdefabcdef'; +var count = 0; +while ((match = re.exec(input)) !== null) { + print(count++); + assertEq(match[0], 'abcdef'); + assertEq(match[1], undefined); +} diff --git a/js/src/jit-test/tests/basic/regexp-test-direct-bug-694752.js b/js/src/jit-test/tests/basic/regexp-test-direct-bug-694752.js new file mode 100644 index 000000000..7e0bae7da --- /dev/null +++ b/js/src/jit-test/tests/basic/regexp-test-direct-bug-694752.js @@ -0,0 +1,15 @@ +function whoo() { + // Cause mjit to use the script's RegExpObject directly when it compiles this function. + assertEq(/foo.*baz/.test('foobarbaz'), true); +} + +var orig_test = RegExp.prototype.test +for (var i = 0; i < 50; ++i) + whoo(); +eval('RegExp.prototype.test = function(str) { return orig_test.call(this, str) }') +for (var i = 0; i < 50; ++i) + whoo(); +RegExp.prototype.test = orig_test; +gc(); +whoo(); + diff --git a/js/src/jit-test/tests/basic/regexp-undefined-match.js b/js/src/jit-test/tests/basic/regexp-undefined-match.js new file mode 100644 index 000000000..cf1d79983 --- /dev/null +++ b/js/src/jit-test/tests/basic/regexp-undefined-match.js @@ -0,0 +1,9 @@ + +function f(str) { + for (var i=0; i<10; i++) { + arr = /foo(ba(r))?/.exec(str); + var x = arr[0] + " " + arr[1] + " " + arr[2]; + } +} +f("foobar"); +f("foo"); diff --git a/js/src/jit-test/tests/basic/regexpLastIndex.js b/js/src/jit-test/tests/basic/regexpLastIndex.js new file mode 100644 index 000000000..80991fa4b --- /dev/null +++ b/js/src/jit-test/tests/basic/regexpLastIndex.js @@ -0,0 +1,13 @@ +function regexpLastIndex() +{ + var n = 0; + var re = /hi/g; + var ss = " hi hi hi hi hi hi hi hi hi hi"; + for (var i = 0; i < 10; i++) { + // re.exec(ss); + n += (re.lastIndex > 0) ? 3 : 0; + re.lastIndex = 0; + } + return n; +} +assertEq(regexpLastIndex(), 0); diff --git a/js/src/jit-test/tests/basic/regexpLastIndexReset.js b/js/src/jit-test/tests/basic/regexpLastIndexReset.js new file mode 100644 index 000000000..2a54d8ef5 --- /dev/null +++ b/js/src/jit-test/tests/basic/regexpLastIndexReset.js @@ -0,0 +1,26 @@ +// Bug 1207922 - lastIndex should be reset to 0 when match fails. + +var pattern = /abc/; +var string = 'aaaaaaaa'; + +function test() { + pattern.lastIndex = 3; + var result = pattern.exec(string); + assertEq(result, null); + assertEq(pattern.lastIndex, 0); +} + +for (let i = 0; i < 10; i++) { + test(); +} + +function test2() { + pattern.lastIndex = 3; + var result = pattern.test(string); + assertEq(result, false); + assertEq(pattern.lastIndex, 0); +} + +for (let i = 0; i < 10; i++) { + test2(); +} diff --git a/js/src/jit-test/tests/basic/relazify-selfhosted.js b/js/src/jit-test/tests/basic/relazify-selfhosted.js new file mode 100644 index 000000000..63cad1c2d --- /dev/null +++ b/js/src/jit-test/tests/basic/relazify-selfhosted.js @@ -0,0 +1,4 @@ +var g = newGlobal(); +g.eval("this.inner = getSelfHostedValue('outer')()"); +gc(); +g.inner(); diff --git a/js/src/jit-test/tests/basic/relazify.js b/js/src/jit-test/tests/basic/relazify.js new file mode 100644 index 000000000..01e7dcd49 --- /dev/null +++ b/js/src/jit-test/tests/basic/relazify.js @@ -0,0 +1,16 @@ +function f(x) { + return x * 3; +} +for (var i=0; i<100; i++) { + f(i); +} +relazifyFunctions(); + +f(1); +f(1); + +relazifyFunctions(); + +for (var i=0; i<10; i++) { + f.call(null, i); +} diff --git a/js/src/jit-test/tests/basic/runOnceClosures.js b/js/src/jit-test/tests/basic/runOnceClosures.js new file mode 100644 index 000000000..49c81b382 --- /dev/null +++ b/js/src/jit-test/tests/basic/runOnceClosures.js @@ -0,0 +1,11 @@ + +compare = (function() { + function inner() { return inner.caller; }; + globalInner = inner; + globalClosure = inner(); + return function(f) { return f === inner; } +})(); + +assertEq(compare(globalInner), true); +globalClosure(); +assertEq(compare(globalInner), false); diff --git a/js/src/jit-test/tests/basic/setArgumentsLength.js b/js/src/jit-test/tests/basic/setArgumentsLength.js new file mode 100644 index 000000000..775d3ef9f --- /dev/null +++ b/js/src/jit-test/tests/basic/setArgumentsLength.js @@ -0,0 +1,14 @@ +var count = 0; + +function f() { + arguments.length--; + for (var i = 0; i < arguments.length; ++i) { + ++count; + } +} + +f(1, 2); +f(1, 2); +f(2, 2); + +assertEq(count, 3); diff --git a/js/src/jit-test/tests/basic/setArgumentsLength2.js b/js/src/jit-test/tests/basic/setArgumentsLength2.js new file mode 100644 index 000000000..2dcb17424 --- /dev/null +++ b/js/src/jit-test/tests/basic/setArgumentsLength2.js @@ -0,0 +1,12 @@ +// don't crash + +var q; + +function f() { + while (arguments.length > 0) { + q = arguments[arguments.length-1]; + arguments.length--; + } +} + +f(1, 2, 3, 4, 5); diff --git a/js/src/jit-test/tests/basic/setCall.js b/js/src/jit-test/tests/basic/setCall.js new file mode 100644 index 000000000..0e4950e1c --- /dev/null +++ b/js/src/jit-test/tests/basic/setCall.js @@ -0,0 +1,22 @@ +function f() { + var x = 11; + + function g() { + var y = 12; + + function h() { + for (var i = 0; i < 5; ++i) { + y = 4; + x = i * 2; + } + } + h(); + + assertEq(y, 4); + } + g(); + + assertEq(x, 8); +} + +f(); diff --git a/js/src/jit-test/tests/basic/setCallEvalMiddle.js b/js/src/jit-test/tests/basic/setCallEvalMiddle.js new file mode 100644 index 000000000..71de2ac69 --- /dev/null +++ b/js/src/jit-test/tests/basic/setCallEvalMiddle.js @@ -0,0 +1,17 @@ +eval(1); // avoid global shape change when we call eval below +function q() { + var x = 1; + function f() { + function g() { + var t=0; + for (var i=0; i<3; i++) + x = i; + }; + g(); + eval("var x = 3"); + g(); + assertEq(x, 2); + } + f(); +} +q(); diff --git a/js/src/jit-test/tests/basic/setCallEvalMiddle2.js b/js/src/jit-test/tests/basic/setCallEvalMiddle2.js new file mode 100644 index 000000000..b93622f36 --- /dev/null +++ b/js/src/jit-test/tests/basic/setCallEvalMiddle2.js @@ -0,0 +1,18 @@ +eval(1); // avoid global shape change when we call eval below +function q() { + var x = 1; + function f() { + function g() { + var t=0; + for (var i=0; i<3; i++) + x = i; + assertEq(x, 2); + eval("var x = 3"); + }; + g(); + g(); + assertEq(x, 2); + } + f(); +} +q(); diff --git a/js/src/jit-test/tests/basic/setCallGlobal.js b/js/src/jit-test/tests/basic/setCallGlobal.js new file mode 100644 index 000000000..a4ba54bae --- /dev/null +++ b/js/src/jit-test/tests/basic/setCallGlobal.js @@ -0,0 +1,14 @@ +var x = 1; +function f() { + function g() { + var t=0; + for (var i=0; i<3; i++) + x = i; + }; + g(); + eval("var x = 2"); + g(); + assertEq(x, 2); +} +f(); +assertEq(x, 2); diff --git a/js/src/jit-test/tests/basic/setPrototypeOf.js b/js/src/jit-test/tests/basic/setPrototypeOf.js new file mode 100644 index 000000000..69558ac6c --- /dev/null +++ b/js/src/jit-test/tests/basic/setPrototypeOf.js @@ -0,0 +1,106 @@ +load(libdir + 'asserts.js'); + +function getObjects() { + function func(){} + return [func, + new func(), + {x: 5}, + /regexp/, + [1, 2, 3], + new Date(), + new Number(1), + new Boolean(true), + new String('str'), + Object.create(null)]; +} + +var coercibleValues = [1, + true, + 'string']; + +var nonCoercibleValues = [undefined, + null]; + +var valuesWithoutNull = coercibleValues.concat(undefined); + +function TestSetPrototypeOf(object, proto) { + assertEq(Object.setPrototypeOf(object, proto), object); + assertEq(Object.getPrototypeOf(object), proto); +} + +// check if Object.setPrototypeOf works with coercible values +for(var value of coercibleValues) { + assertEq(Object.setPrototypeOf(value, {}), value); +} + +// check if Object.setPrototypeOf fails on non-coercible values +for (var value of nonCoercibleValues) { + assertThrowsInstanceOf(() => Object.setPrototypeOf(value, {}), + TypeError, "Object.setPrototypeOf shouldn't work on non-coercible values"); +} + +// check if Object.setPrototypeOf works when prototype is set to non-objects +var objects = getObjects(); +for (var object of objects) { + for (var proto of valuesWithoutNull) { + assertThrowsInstanceOf(() => Object.setPrototypeOf(object, proto), + TypeError, "Object.setPrototypeOf fails when the prototype is set to non-objects"); + } +} + +// check if Object.setPrototypeOf works when prototype is set to objects +var objects1 = getObjects(); +var objects2 = getObjects(); +for (var object1 of objects1) { + for (var object2 of objects2) { + TestSetPrototypeOf(object1, object2); + } +} + +// check if Object.setPrototypeOf works when prototype is set to null +objects = getObjects(); +for (var object of objects) { + TestSetPrototypeOf(object, null); +} + +// check if Object.setPrototypeOf fails when object is not extensible +var objects = getObjects(); +var proto = {}; +for (var object of objects) { + Object.preventExtensions(object); + assertThrowsInstanceOf(() => Object.setPrototypeOf(object, proto), + TypeError, "Object.setPrototypeOf should fail when the object is not extensible"); +} + +// check if Object.setPrototypeof(A, B) succeeds on not extensible object A if +// prototype of A == B already +var objectProto = {}; +var nonExtensibleObject = Object.create(objectProto); +Object.preventExtensions(nonExtensibleObject); +assertEq(Object.setPrototypeOf(nonExtensibleObject, objectProto), nonExtensibleObject); + +// check if Object.setPrototypeOf works with prototype lookup +var object = {}; +assertEq('x' in object, false); +assertEq('y' in object, false); + +var oldProto = { + x: 'old x', + y: 'old y' +}; +Object.setPrototypeOf(object, oldProto); +assertEq(object.x, 'old x'); +assertEq(object.y, 'old y'); + +var newProto = { + x: 'new x' +}; +Object.setPrototypeOf(object, newProto); +assertEq(object.x, 'new x'); +assertEq('y' in object, false); + +// check if Object.setPrototypeOf throws TypeError on fewer arguments +assertThrowsInstanceOf(() => Object.setPrototypeOf(), + TypeError, "Object.setPrototypeOf throws TypeError when called without any parameters"); +assertThrowsInstanceOf(() => Object.setPrototypeOf({}), + TypeError, "Object.setPrototypeOf throws TypeError when called with 1 parameter"); diff --git a/js/src/jit-test/tests/basic/setelem.js b/js/src/jit-test/tests/basic/setelem.js new file mode 100644 index 000000000..cdbe035b4 --- /dev/null +++ b/js/src/jit-test/tests/basic/setelem.js @@ -0,0 +1,12 @@ +var a; +function setelem() +{ + a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; + a = a.concat(a, a, a); + var l = a.length; + for (var i = 0; i < l; i++) { + a[i] = i; + } + return a.toString(); +} +assertEq(setelem(), "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83"); diff --git a/js/src/jit-test/tests/basic/setprop-with-index.js b/js/src/jit-test/tests/basic/setprop-with-index.js new file mode 100644 index 000000000..8d39c7760 --- /dev/null +++ b/js/src/jit-test/tests/basic/setprop-with-index.js @@ -0,0 +1,5 @@ +function f() +{ + arguments['4294967295'] = 2; +} +assertEq(f(), undefined); diff --git a/js/src/jit-test/tests/basic/setprop.js b/js/src/jit-test/tests/basic/setprop.js new file mode 100644 index 000000000..bb93e1e49 --- /dev/null +++ b/js/src/jit-test/tests/basic/setprop.js @@ -0,0 +1,10 @@ +function setprop() +{ + var obj = { a:-1 }; + var obj2 = { b:-1, a:-1 }; + for (var i = 0; i < 20; i++) { + obj2.b = obj.a = i; + } + return [obj.a, obj2.a, obj2.b].toString(); +} +assertEq(setprop(), "19,-1,19"); diff --git a/js/src/jit-test/tests/basic/shapelessCalleeTest.js b/js/src/jit-test/tests/basic/shapelessCalleeTest.js new file mode 100644 index 000000000..fe10e9b42 --- /dev/null +++ b/js/src/jit-test/tests/basic/shapelessCalleeTest.js @@ -0,0 +1,67 @@ +// The following functions use a delay line of length 2 to change the value +// of the callee without exiting the traced loop. This is obviously tuned to +// match the current 8 setting of 2. +function shapelessArgCalleeLoop(f, g, h, a) +{ + for (var i = 0; i < 10; i++) { + f(i, a); + f = g; + g = h; + } +} + +function shapelessVarCalleeLoop(f0, g, h, a) +{ + var f = f0; + for (var i = 0; i < 10; i++) { + f(i, a); + f = g; + g = h; + } +} + +function shapelessLetCalleeLoop(f0, g, h, a) +{ + for (var i = 0; i < 10; i++) { + let f = f0; + f(i, a); + f = g; + g = h; + } +} + +function shapelessUnknownCalleeLoop(n, f, g, h, a) +{ + for (var i = 0; i < 10; i++) { + (n || f)(i, a); + f = g; + g = h; + } +} + +function shapelessCalleeTest() +{ + var a = []; + + var helper = function (i, a) a[i] = i; + shapelessArgCalleeLoop(helper, helper, function (i, a) a[i] = -i, a); + + helper = function (i, a) a[10 + i] = i; + shapelessVarCalleeLoop(helper, helper, function (i, a) a[10 + i] = -i, a); + + helper = function (i, a) a[20 + i] = i; + shapelessLetCalleeLoop(helper, helper, function (i, a) a[20 + i] = -i, a); + + helper = function (i, a) a[30 + i] = i; + shapelessUnknownCalleeLoop(null, helper, helper, function (i, a) a[30 + i] = -i, a); + + try { + helper = {hack: 42}; + shapelessUnknownCalleeLoop(null, helper, helper, helper, a); + } catch (e) { + if (e + "" != "TypeError: f is not a function") + print("shapelessUnknownCalleeLoop: unexpected exception " + e); + } + return a.join(""); +} +assertEq(shapelessCalleeTest(), "01-2-3-4-5-6-7-8-901-2-3-4-5-6-7-8-9012345678901-2-3-4-5-6-7-8-9"); diff --git a/js/src/jit-test/tests/basic/shell-principals.js b/js/src/jit-test/tests/basic/shell-principals.js new file mode 100644 index 000000000..a96ce69c7 --- /dev/null +++ b/js/src/jit-test/tests/basic/shell-principals.js @@ -0,0 +1,55 @@ +// Test the JS shell's toy principals. + +var count = 0; + +// Given a string of letters |expected|, say "abc", assert that the stack +// contains calls to a series of functions named by the next letter from +// the string, say a, b, and then c. Younger frames appear earlier in +// |expected| than older frames. +function check(expected, stack) { + print("check(" + uneval(expected) + ") against:\n" + stack); + count++; + + // Extract only the function names from the stack trace. Omit the frames + // for the top-level evaluation, if it is present. + var split = stack.split(/(.)?@.*\n/).slice(0, -1); + if (split[split.length - 1] === undefined) + split = split.slice(0, -2); + + // Check the function names against the expected sequence. + assertEq(split.length, expected.length * 2); + for (var i = 0; i < expected.length; i++) + assertEq(split[i * 2 + 1], expected[i]); +} + +var low = newGlobal({ principal: 0 }); +var mid = newGlobal({ principal: 0xffff }); +var high = newGlobal({ principal: 0xfffff }); + + eval('function a() { check("a", Error().stack); b(); }'); +low .eval('function b() { check("b", Error().stack); c(); }'); +mid .eval('function c() { check("cba", Error().stack); d(); }'); +high.eval('function d() { check("dcba", Error().stack); e(); }'); + +// Globals created with no explicit principals get 0xffff. + eval('function e() { check("ecba", Error().stack); f(); }'); + +low .eval('function f() { check("fb", Error().stack); g(); }'); +mid .eval('function g() { check("gfecba", Error().stack); h(); }'); +high.eval('function h() { check("hgfedcba", Error().stack); }'); + +// Make everyone's functions visible to each other, as needed. + b = low .b; +low .c = mid .c; +mid .d = high.d; +high.e = e; + f = low .f; +low .g = mid .g; +mid .h = high.h; + +low.check = mid.check = high.check = check; + +// Kick the whole process off. +a(); + +assertEq(count, 8); diff --git a/js/src/jit-test/tests/basic/shell-watchdog.js b/js/src/jit-test/tests/basic/shell-watchdog.js new file mode 100644 index 000000000..9eb08fc4f --- /dev/null +++ b/js/src/jit-test/tests/basic/shell-watchdog.js @@ -0,0 +1,16 @@ +// |jit-test| exitstatus: 6; + +/* This test will loop infinitely if the shell watchdog + fails to kick in. */ + +timeout(0.1); +var start = new Date(); + +while (true) { + var end = new Date(); + var duration = (end.getTime() - start.getTime()) / 1000; + if (duration > 1) { + print("tick"); + start = new Date(); + } +} diff --git a/js/src/jit-test/tests/basic/singleton.js b/js/src/jit-test/tests/basic/singleton.js new file mode 100644 index 000000000..8e7c4c8fa --- /dev/null +++ b/js/src/jit-test/tests/basic/singleton.js @@ -0,0 +1,12 @@ + +var a = [1,2,3,4]; +var b = [{a:0,b:1},{a:0,b:1},{a:0,b:1}]; +var c = {a:0,b:4.5}; +var d = [1,2,3,true]; +var e = {a:0,b:1,c:2}; +var f = {a:0,b:1,c:true}; + +var w = JSON.parse('[1,2,3,4]'); +var x = JSON.parse('{"a":0,"b":true,"c":4.5}'); +var y = JSON.parse('{"d":true,"b":true,"c":4.5}'); +var z = JSON.parse('[{"a":0,"b":1},{"a":0,"b":1},{"a":0,"b":1}]'); diff --git a/js/src/jit-test/tests/basic/sleep-without-timeout.js b/js/src/jit-test/tests/basic/sleep-without-timeout.js new file mode 100644 index 000000000..c912b1879 --- /dev/null +++ b/js/src/jit-test/tests/basic/sleep-without-timeout.js @@ -0,0 +1,6 @@ +// sleep() should work without timeout() prior to it. + +sleep(0.001); +sleep(0.01); +sleep(0.1); +sleep(1); diff --git a/js/src/jit-test/tests/basic/splice-675164.js b/js/src/jit-test/tests/basic/splice-675164.js new file mode 100644 index 000000000..10d0d9788 --- /dev/null +++ b/js/src/jit-test/tests/basic/splice-675164.js @@ -0,0 +1,15 @@ +function NPList() {} +NPList.prototype = new Array; + +var list = new NPList(); +list.push('a'); + +var cut = list.splice(0, 1); + +assertEq(cut[0], 'a'); +assertEq(cut.length, 1); +assertEq(list.length, 0); + +var desc = Object.getOwnPropertyDescriptor(list, "0"); +assertEq(desc, undefined); +assertEq("0" in list, false); diff --git a/js/src/jit-test/tests/basic/splice-call-plain-object-590780.js b/js/src/jit-test/tests/basic/splice-call-plain-object-590780.js new file mode 100644 index 000000000..4a0dc5d15 --- /dev/null +++ b/js/src/jit-test/tests/basic/splice-call-plain-object-590780.js @@ -0,0 +1,8 @@ +var o = { 0: 1, 1: 2, 2: 3, length: 3 }; +Array.prototype.splice.call(o, 0, 1); + +assertEq(o[0], 2); +assertEq(o[1], 3); +assertEq(Object.getOwnPropertyDescriptor(o, 2), undefined); +assertEq("2" in o, false); +assertEq(o.length, 2); diff --git a/js/src/jit-test/tests/basic/splice-check-steps.js b/js/src/jit-test/tests/basic/splice-check-steps.js new file mode 100644 index 000000000..25985e9f3 --- /dev/null +++ b/js/src/jit-test/tests/basic/splice-check-steps.js @@ -0,0 +1,297 @@ +/* + * Check the order of splice's internal operations, because the ordering is + * visible externally. + */ + +function handlerMaker(expected_exceptions) { + var order = []; + function note(trap, name) + { + order.push(trap + '-' + name); + if (expected_exceptions[trap] === name) { + throw ("fail"); + } + } + + return [{ + /* this is the only trap we care about */ + deleteProperty: function(target, name) { + note("del", name); + return Reflect.deleteProperty(target, name); + }, + // derived traps + has: function(target, name) { + note("has", name); + return name in target; + }, + get: function(target, name, receiver) { + note("get", name); + return Reflect.get(target, name, receiver); + }, + set: function(target, name, value, receiver) { + note("set", name); + return Reflect.set(target, name, value, receiver); + }, + }, order]; +} + +// arr: the array to splice +// expected_order: the expected order of operations on arr, stringified +function check_splice_proxy(arr, expected_order, expected_exceptions, expected_array, expected_result) { + print (arr); + var [handler, store] = handlerMaker(expected_exceptions); + var proxy = new Proxy(arr, handler); + + try { + var args = Array.prototype.slice.call(arguments, 5); + var result = Array.prototype.splice.apply(proxy, args); + assertEq(Object.keys(expected_exceptions).length, 0); + } catch (e) { + assertEq(Object.keys(expected_exceptions).length > 0, true); + } + + // check the order of the property accesses, etc + assertEq(store.toString(), expected_order); + + // The deleted elements are returned in an object that's always an Array. + assertEq(Array.isArray(result) || result === undefined, true); + + // check the return value + for (var i in expected_result) { + assertEq(result[i], expected_result[i]); + } + for (var i in result) { + assertEq(result[i], expected_result[i]); + } + + // check the value of arr + for (var i in expected_array) { + assertEq(arr[i], expected_array[i]); + } + for (var i in arr) { + assertEq(arr[i], expected_array[i]); + } + + return result; +} + +// Shrinking array +check_splice_proxy( + [10,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-3,get-3,set-0,has-4,get-4,set-1,has-5,get-5,set-2," + + "del-5,del-4,del-3," + + "set-length", + {}, + [3,4,5], + [10,1,2], + 0, 3 +); + +// Growing array +check_splice_proxy( + [11,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-5,get-5,set-9,has-4,get-4,set-8,has-3,get-3,set-7," + + "set-0,set-1,set-2,set-3,set-4,set-5,set-6," + + "set-length", + {}, + [9,9,9,9,9,9,9,3,4,5], + [11,1,2], + 0, 3, 9, 9, 9, 9, 9, 9, 9 +); + +// Same sized array +check_splice_proxy( + [12,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "set-0,set-1,set-2," + + "set-length", + {}, + [9,9,9,3,4,5], + [12,1,2], + 0, 3, 9, 9, 9 +); + + +/* + * Check that if we fail at a particular step in the algorithm, we don't + * continue with the algorithm beyond that step. + */ + + +// Step 3: fail when getting length +check_splice_proxy( + [13,1,2,3,4,5], + "get-length", + {get: 'length'}, + [13,1,2,3,4,5], + undefined, + 0, 3, 9, 9, 9 +); + +// Step 9b: fail when [[HasProperty]] +check_splice_proxy( + [14,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1", + {has: '1'}, + [14,1,2,3,4,5], + undefined, + 0, 3, 9, 9, 9 +); + +// Step 9c(i): fail when [[Get]] +check_splice_proxy( + [15,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1", + {get: '1'}, + [15,1,2,3,4,5], + undefined, + 0, 3, 9, 9, 9 +); + +// Step 12b(iii): fail when [[HasProperty]] +check_splice_proxy( + [16,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-3,get-3,set-0,has-4", + {has: '4'}, + [3,1,2,3,4,5], + undefined, + 0, 3 +); + + +// Step 12b(iv)1: fail when [[Get]] +check_splice_proxy( + [17,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-3,get-3,set-0,has-4,get-4", + {get: '4'}, + [3,1,2,3,4,5], + undefined, + 0, 3 +); + + +// Step 12b(iv)2: fail when [[Put]] +check_splice_proxy( + [18,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-3,get-3,set-0,has-4,get-4,set-1", + {set: '1'}, + [3,1,2,3,4,5], + undefined, + 0, 3 +); + +// Step 12b(v)1: fail when [[Delete]] +check_splice_proxy( + [19,1,2,3,,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-3,get-3,set-0,has-4,del-1", + {del: '1'}, + [3,1,2,3,,5], + undefined, + 0, 3 +); + +// Step 12d(i): fail when [[Delete]] +check_splice_proxy( + [20,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-3,get-3,set-0,has-4,get-4,set-1,has-5,get-5,set-2," + + "del-5,del-4", + {del: '4'}, + [3,4,5,3,4], + undefined, + 0, 3 +); + +// Step 13b(iii): fail when [[HasProperty]] +check_splice_proxy( + [21,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-5,get-5,set-8,has-4", + {has: '4'}, + [21,1,2,3,4,5,,,5], + undefined, + 0, 3, 9,9,9,9,9,9 +); + + +// Step 13b(iv)1: fail when [[Get]] +check_splice_proxy( + [22,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-5,get-5,set-8,has-4,get-4", + {get: '4'}, + [22,1,2,3,4,5,,,5], + undefined, + 0, 3, 9,9,9,9,9,9 +); + + +// Step 13b(iv)2: fail when [[Put]] +check_splice_proxy( + [23,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-5,get-5,set-8,has-4,get-4,set-7", + {set: '7'}, + [23,1,2,3,4,5,,,5], + undefined, + 0, 3, 9,9,9,9,9,9 +); + +// Step 13b(v)1: fail when [[Delete]] +check_splice_proxy( + [24,1,2,3,,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-5,get-5,set-8,has-4,del-7", + {del: '7'}, + [24,1,2,3,,5,,,5], + undefined, + 0, 3, 9,9,9,9,9,9 +); + +// Step 15b: fail when [[Put]] +check_splice_proxy( + [25,1,2,3,4,5], + "get-length," + + "get-constructor," + + "has-0,get-0,has-1,get-1,has-2,get-2," + + "has-5,get-5,set-8,has-4,get-4,set-7,has-3,get-3,set-6," + + "set-0,set-1,set-2", + {set: '2'}, + [9,9,2,3,4,5,3,4,5], + undefined, + 0, 3, 9,9,9,9,9,9 +); diff --git a/js/src/jit-test/tests/basic/splice-delete-non-configurable-during-shrink.js b/js/src/jit-test/tests/basic/splice-delete-non-configurable-during-shrink.js new file mode 100644 index 000000000..93dddb5cc --- /dev/null +++ b/js/src/jit-test/tests/basic/splice-delete-non-configurable-during-shrink.js @@ -0,0 +1,26 @@ +/* Test that splice causing deletion of a non-configurable property stops at exactly step 12(v) of ES5 15.4.4.12 */ + +var O = [1,2,3,4,5,6]; +var A = undefined; +Object.defineProperty(O, 3, { configurable: false }); + +try +{ + A = O.splice(0, 6); + throw new Error("didn't throw, returned " + A); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "deleting O[3] should have caused a TypeError"); +} + +assertEq(O.length, 6); // setting length not reached +assertEq(A, undefined); // return value not reached + +assertEq(O[5], undefined); // deletion reached +assertEq(O[4], undefined); // deletion reached +assertEq(O[3], 4); // deletion caused exception +assertEq(O[2], 3); // deletion not reached +assertEq(O[1], 2); // deletion not reached +assertEq(O[0], 1); // deletion not reached diff --git a/js/src/jit-test/tests/basic/splice-fail-step-16.js b/js/src/jit-test/tests/basic/splice-fail-step-16.js new file mode 100644 index 000000000..549ad0129 --- /dev/null +++ b/js/src/jit-test/tests/basic/splice-fail-step-16.js @@ -0,0 +1,25 @@ +/* Test that arrays resize normally during splice, even if .length is non-writable. */ + +var arr = [1, 2, 3, 4, 5, 6]; + +Object.defineProperty(arr, "length", {writable: false}); + +try +{ + var removed = arr.splice(3, 3, 9, 9, 9, 9); + throw new Error("splice didn't throw, returned [" + removed + "]"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "should have thrown a TypeError, instead threw " + e + ", arr is " + arr); +} + +// The exception should happen in step 16, which means we've already removed the array elements. +assertEq(arr[0], 1); +assertEq(arr[1], 2); +assertEq(arr[2], 3); +assertEq(arr[3], 9); +assertEq(arr[4], 9); +assertEq(arr[5], 9); +assertEq(arr.length, 6); diff --git a/js/src/jit-test/tests/basic/splice-huge-array-finishes.js b/js/src/jit-test/tests/basic/splice-huge-array-finishes.js new file mode 100644 index 000000000..d894e5088 --- /dev/null +++ b/js/src/jit-test/tests/basic/splice-huge-array-finishes.js @@ -0,0 +1,15 @@ +// Making the array huge and sparse shouldn't leave us iterating through the entire array. +// But it does, sadly. Disable, because it takes too long. +if (0) { + var arr = [1, 2, 3, 4, 5, 6, 7, 8]; + arr.length = Math.pow(2, 32) - 2; + arr.splice(5); // also test overflow + + assertEq(arr.length, 5); + assertEq(arr[0], 1); + assertEq(arr[1], 2); + assertEq(arr[2], 3); + assertEq(arr[3], 4); + assertEq(arr[4], 5); + assertEq(arr[5], undefined); +} diff --git a/js/src/jit-test/tests/basic/splice-on-arguments.js b/js/src/jit-test/tests/basic/splice-on-arguments.js new file mode 100644 index 000000000..e36522ae0 --- /dev/null +++ b/js/src/jit-test/tests/basic/splice-on-arguments.js @@ -0,0 +1,39 @@ +// test whether splice works on arguments + +function splice_args () { + args = arguments; + return Array.prototype.splice.apply(args, [0, 5]); +} + +var args; +var O = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; +var A = splice_args.apply(undefined, O) + +// args: [5, 6, 7, 8, 9] +assertEq(args[0], 5); +assertEq(args[1], 6); +assertEq(args[2], 7); +assertEq(args[3], 8); +assertEq(args[4], 9); +assertEq(args.length, 5); + +// A: [0, 1, 2, 3, 4] +assertEq(A[0], 0); +assertEq(A[1], 1); +assertEq(A[2], 2); +assertEq(A[3], 3); +assertEq(A[4], 4); +assertEq(A.length, 5); + +// O: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +assertEq(O[0], 0); +assertEq(O[1], 1); +assertEq(O[2], 2); +assertEq(O[3], 3); +assertEq(O[4], 4); +assertEq(O[5], 5); +assertEq(O[6], 6); +assertEq(O[7], 7); +assertEq(O[8], 8); +assertEq(O[9], 9); +assertEq(O.length, 10); diff --git a/js/src/jit-test/tests/basic/splice-throwing-length-getter-668024.js b/js/src/jit-test/tests/basic/splice-throwing-length-getter-668024.js new file mode 100644 index 000000000..695460b5c --- /dev/null +++ b/js/src/jit-test/tests/basic/splice-throwing-length-getter-668024.js @@ -0,0 +1,9 @@ +try +{ + Array.prototype.splice.call({ get length() { throw 'error'; } }); + throw new Error("should have thrown, didn't"); +} +catch (e) +{ + assertEq(e, "error", "wrong error thrown: " + e); +} diff --git a/js/src/jit-test/tests/basic/spread-array-bug842884.js b/js/src/jit-test/tests/basic/spread-array-bug842884.js new file mode 100644 index 000000000..909bb5c6b --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-array-bug842884.js @@ -0,0 +1,5 @@ +load(libdir + "asserts.js"); + +assertThrowsInstanceOf(function () { + var [] = [x, ...d]; +}, ReferenceError); diff --git a/js/src/jit-test/tests/basic/spread-array-decompile.js b/js/src/jit-test/tests/basic/spread-array-decompile.js new file mode 100644 index 000000000..10939664d --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-array-decompile.js @@ -0,0 +1,14 @@ +var samples = [ + "[...a]", + "[...[1]]", + "[1, ...a, 2]", + "[1, ...[2, 3], 4]", + "[...[1], , ]", + "[1, , ...[2]]", + "[, 1, ...[2], ...[3], , 4, 5, , ]" +]; +for (var sample of samples) { + var source = "function f() {\n return " + sample + ";\n}"; + eval(source); + assertEq(f.toString(), source); +} diff --git a/js/src/jit-test/tests/basic/spread-array-evaluation-order.js b/js/src/jit-test/tests/basic/spread-array-evaluation-order.js new file mode 100644 index 000000000..0887a0592 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-array-evaluation-order.js @@ -0,0 +1,12 @@ +load(libdir + "eqArrayHelper.js"); + +var check = []; +function t(token) { + check.push(token); + return token; +} +[3, ...[t(1)],, ...[t(2), t(3)], 34, 42, ...[t(4)]]; +assertEqArray(check, [1, 2, 3, 4]); + +var arr = [1, 2, 3]; +assertEqArray([...arr, arr.pop()], [1, 2, 3, 3]); diff --git a/js/src/jit-test/tests/basic/spread-array-invalid-syntax.js b/js/src/jit-test/tests/basic/spread-array-invalid-syntax.js new file mode 100644 index 000000000..a7bcd5205 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-array-invalid-syntax.js @@ -0,0 +1,19 @@ +load(libdir + "asserts.js"); + +var offenders = [ + "(1 ... n)", + "[1 ... n]", + "(...x)", + "[...x for (x of y)]", + "[...x, x for (x of y)]", + "[...]", + "(...)", + "[...,]", + "[... ...[]]", + "(... ...[])", + "[x, ...]", + "(x, ...)" +]; +for (var sample of offenders) { + assertThrowsInstanceOf(function () { eval(sample); }, SyntaxError); +} diff --git a/js/src/jit-test/tests/basic/spread-array-wrap.js b/js/src/jit-test/tests/basic/spread-array-wrap.js new file mode 100644 index 000000000..84a57bdd9 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-array-wrap.js @@ -0,0 +1,5 @@ +load(libdir + "eqArrayHelper.js"); + +// XXX disabled bug 827449 +//assertEqArray([...wrap([1])], [1]); +//assertEqArray([1,, ...wrap([2, 3, 4]), 5, ...wrap([6])], [1,, 2, 3, 4, 5, 6]); diff --git a/js/src/jit-test/tests/basic/spread-array.js b/js/src/jit-test/tests/basic/spread-array.js new file mode 100644 index 000000000..30d4cb52b --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-array.js @@ -0,0 +1,50 @@ +load(libdir + "asserts.js"); +load(libdir + "iteration.js"); +load(libdir + "eqArrayHelper.js"); + +assertEqArray([...[1, 2, 3]], [1, 2, 3]); +assertEqArray([1, ...[2, 3, 4], 5], [1, 2, 3, 4, 5]); +assertEqArray([1, ...[], 2], [1, 2]); +assertEqArray([1, ...[2, 3], 4, ...[5, 6]], [1, 2, 3, 4, 5, 6]); +assertEqArray([1, ...[], 2], [1, 2]); +assertEqArray([1,, ...[2]], [1,, 2]); +assertEqArray([1,, ...[2],, 3,, 4,], [1,, 2,, 3,, 4,]); +assertEqArray([...[1, 2, 3],,,,], [1, 2, 3,,,,]); +assertEqArray([,,...[1, 2, 3],,,,], [,,1,2,3,,,,]); +assertEqArray([...[1, 2, 3],,,,...[]], [1,2,3,,,,]); + +assertEqArray([...[undefined]], [undefined]); + +// other iterable objects +assertEqArray([...new Int32Array([1, 2, 3])], [1, 2, 3]); +assertEqArray([..."abc"], ["a", "b", "c"]); +assertEqArray([...[1, 2, 3][Symbol.iterator]()], [1, 2, 3]); +assertEqArray([...new Set([1, 2, 3])], [1, 2, 3]); +assertEqArray([...new Map([["a", "A"], ["b", "B"], ["c", "C"]])].map(([k, v]) => k + v), ["aA", "bB", "cC"]); +let itr = {}; +itr[Symbol.iterator] = function () { + return { + i: 1, + next: function() { + if (this.i < 4) + return { value: this.i++, done: false }; + else + return { value: undefined, done: true }; + } + }; +} +assertEqArray([...itr], [1, 2, 3]); +function* gen() { + for (let i = 1; i < 4; i ++) + yield i; +} +assertEqArray([...gen()], [1, 2, 3]); + +let a, b = [1, 2, 3]; +assertEqArray([...a=b], [1, 2, 3]); + +// 12.2.4.1.2 Runtime Semantics: ArrayAccumulation +// If Type(spreadObj) is not Object, then throw a TypeError exception. +assertThrowsInstanceOf(() => [...null], TypeError); +assertThrowsInstanceOf(() => [...undefined], TypeError); + diff --git a/js/src/jit-test/tests/basic/spread-call-eval.js b/js/src/jit-test/tests/basic/spread-call-eval.js new file mode 100644 index 000000000..1fad8e7a5 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-eval.js @@ -0,0 +1,54 @@ +load(libdir + "asserts.js"); +load(libdir + "iteration.js"); + +assertEq(eval(...[]), undefined); +assertEq(eval(...["1 + 2"]), 3); + +let a = 10, b = 1; +assertEq(eval(...["a + b"]), 11); + +(function() { + let a = 20; + assertEq(eval(...["a + b"]), 21); +})(); + +with ({ a: 30 }) { + assertEq(eval(...["a + b"]), 31); +} + +let line0 = Error().lineNumber; +try { // line0 + 1 + eval(...["("]); // line0 + 2 +} catch (e) { + assertEq(e.lineNumber, 1); +} + +// other iterable objects +assertEq(eval(...["a + b"][Symbol.iterator]()), 11); +assertEq(eval(...new Set(["a + b"])), 11); +let itr = {}; +itr[Symbol.iterator] = function() { + return { + i: 0, + next: function() { + this.i++; + if (this.i == 1) + return { value: "a + b", done: false }; + else + return { value: undefined, done: true }; + } + }; +}; +assertEq(eval(...itr), 11); +function* gen() { + yield "a + b"; +} +assertEq(eval(...gen()), 11); + +let c = ["C"], d = "D"; +assertEq(eval(...c=["c[0] + d"]), "c[0] + dD"); + +// 12.2.4.1.2 Runtime Semantics: ArrayAccumulation +// If Type(spreadObj) is not Object, then throw a TypeError exception. +assertThrowsInstanceOf(() => eval("a + b", ...null), TypeError); +assertThrowsInstanceOf(() => eval("a + b", ...undefined), TypeError); diff --git a/js/src/jit-test/tests/basic/spread-call-evaluation-order.js b/js/src/jit-test/tests/basic/spread-call-evaluation-order.js new file mode 100644 index 000000000..2c2f53953 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-evaluation-order.js @@ -0,0 +1,13 @@ +load(libdir + "eqArrayHelper.js"); + +var check = []; +function t(token) { + check.push(token); + return token; +} +let f = (...x) => x; +f(3, ...[t(1)], ...[t(2), t(3)], 34, 42, ...[t(4)]); +assertEqArray(check, [1, 2, 3, 4]); + +var arr = [1, 2, 3]; +assertEqArray(f(...arr, arr.pop()), [1, 2, 3, 3]); diff --git a/js/src/jit-test/tests/basic/spread-call-funapply.js b/js/src/jit-test/tests/basic/spread-call-funapply.js new file mode 100644 index 000000000..9362d2a2d --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-funapply.js @@ -0,0 +1,88 @@ +load(libdir + "asserts.js"); +load(libdir + "eqArrayHelper.js"); +load(libdir + "iteration.js"); + +function checkCommon(f) { + assertEqArray(f.apply(null, ...[[1, 2, 3]]), [1, 2, 3]); + assertEqArray(f.apply(...[null], [1, 2, 3]), [1, 2, 3]); + assertEqArray(f.apply(...[null], ...[[1, 2, 3]]), [1, 2, 3]); + assertEqArray(f.apply(...[null, [1, 2, 3]]), [1, 2, 3]); + + // other iterable objects + assertEqArray(f.apply(...new Set([null, [1, 2, 3]])), [1, 2, 3]); + assertEqArray(f.apply(...[null, [1, 2, 3]][Symbol.iterator]()), [1, 2, 3]); + let itr = {}; + itr[Symbol.iterator] = function() { + return { + i: 0, + next: function() { + this.i++; + if (this.i == 1) + return { value: null, done: false }; + else if (this.i == 2) + return { value: [1, 2, 3], done: false }; + else + return { value: undefined, done: true }; + } + }; + }; + assertEqArray(f.apply(...itr), [1, 2, 3]); + function* gen() { + yield null; + yield [1, 2, 3]; + } + assertEqArray(f.apply(...gen()), [1, 2, 3]); + + let a; + assertEqArray(f.apply(null, ...a=[[1, 2, 3]]), [1, 2, 3]); + + // 12.2.4.1.2 Runtime Semantics: ArrayAccumulation + // If Type(spreadObj) is not Object, then throw a TypeError exception. + assertThrowsInstanceOf(() => f.apply(null, ...null, [1, 2, 3]), TypeError); + assertThrowsInstanceOf(() => f.apply(null, ...undefined, [1, 2, 3]), TypeError); +} + +function checkNormal(f) { + checkCommon(f); + + assertEqArray(f.apply(null, ...[[]]), [undefined, undefined, undefined]); + assertEqArray(f.apply(null, ...[[1]]), [1, undefined, undefined]); + assertEqArray(f.apply(null, ...[[1, 2]]), [1, 2, undefined]); + assertEqArray(f.apply(null, ...[[1, 2, 3, 4]]), [1, 2, 3]); + + assertEqArray(f.apply(null, ...[[undefined]]), [undefined, undefined, undefined]); +} + +checkNormal(function(a, b, c) [a, b, c]); +checkNormal((a, b, c) => [a, b, c]); + +function checkDefault(f) { + checkCommon(f); + + assertEqArray(f.apply(null, ...[[]]), [-1, -2, -3]); + assertEqArray(f.apply(null, ...[[1]]), [1, -2, -3]); + assertEqArray(f.apply(null, ...[[1, 2]]), [1, 2, -3]); + assertEqArray(f.apply(null, ...[[1, 2, 3, 4]]), [1, 2, 3]); + + assertEqArray(f.apply(null, ...[[undefined]]), [-1, -2, -3]); +} + +checkDefault(function(a = -1, b = -2, c = -3) [a, b, c]); +checkDefault((a = -1, b = -2, c = -3) => [a, b, c]); + +function checkRest(f) { + checkCommon(f); + + assertEqArray(f.apply(null, ...[[]]), []); + assertEqArray(f.apply(null, ...[[1]]), [1]); + assertEqArray(f.apply(null, ...[[1, 2]]), [1, 2]); + assertEqArray(f.apply(null, ...[[1, 2, 3, 4]]), [1, 2, 3, 4]); + + assertEqArray(f.apply(null, ...[[undefined]]), [undefined]); + + // other iterable objects + assertEqArray(f.apply(null, ...new Map([[["a", "A"], ["b", "B"]]])).map(([k, v]) => k + v), ["aA", "bB"]); +} + +checkRest(function(...x) x); +checkRest((...x) => x); diff --git a/js/src/jit-test/tests/basic/spread-call-funcall.js b/js/src/jit-test/tests/basic/spread-call-funcall.js new file mode 100644 index 000000000..bcb3c0024 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-funcall.js @@ -0,0 +1,11 @@ +load(libdir + "eqArrayHelper.js"); + +function check(f) { + assertEqArray(f.call(...[null], 1, 2, 3), [1, 2, 3]); + assertEqArray(f.call(...[null], 1, ...[2, 3], 4, ...[5, 6]), [1, 2, 3, 4, 5, 6]); + assertEqArray(f.call(...[null, 1], ...[2, 3], 4, ...[5, 6]), [1, 2, 3, 4, 5, 6]); + assertEqArray(f.call(...[null, 1, ...[2, 3], 4, ...[5, 6]]), [1, 2, 3, 4, 5, 6]); +} + +check(function(...x) x); +check((...x) => x); diff --git a/js/src/jit-test/tests/basic/spread-call-invalid-syntax.js b/js/src/jit-test/tests/basic/spread-call-invalid-syntax.js new file mode 100644 index 000000000..c3288736d --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-invalid-syntax.js @@ -0,0 +1,15 @@ +load(libdir + "asserts.js"); + +var offenders = [ + "f(1 ... n)", + "f(...x for (x in y))", + "f(...)", + "f(...,)", + "f(... ...[])", + "f(x, ...)", + "f(...x, x for (x in y))", + "f(x for (x in y), ...x)" +]; +for (var sample of offenders) { + assertThrowsInstanceOf(function() { eval(sample); }, SyntaxError); +} diff --git a/js/src/jit-test/tests/basic/spread-call-length.js b/js/src/jit-test/tests/basic/spread-call-length.js new file mode 100644 index 000000000..3356c913a --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-length.js @@ -0,0 +1,52 @@ +load(libdir + 'iteration.js'); + +let makeCall = farg => Function("f", "arg", "return f(" + farg + ");"); +let makeFunCall = farg => Function("f", "arg", "return f.call(null, " + farg + ");"); +let makeNew = farg => Function("f", "arg", "return new f(" + farg + ").length;"); + +function checkLength(f, makeFn) { + assertEq(makeFn("...[1, 2, 3]")(f), 3); + assertEq(makeFn("1, ...[2], 3")(f), 3); + assertEq(makeFn("1, ...[2], ...[3]")(f), 3); + assertEq(makeFn("1, ...[2, 3]")(f), 3); + assertEq(makeFn("1, ...[], 2, 3")(f), 3); + + assertEq(makeFn("...[1]")(f), 1); + assertEq(makeFn("...[1, 2]")(f), 2); + assertEq(makeFn("...[1, 2, 3, 4]")(f), 4); + assertEq(makeFn("1, ...[2, 3, 4], 5")(f), 5); + + assertEq(makeFn("...[undefined]")(f), 1); + + // other iterable objects + assertEq(makeFn("...arg")(f, new Int32Array([1, 2, 3])), 3); + assertEq(makeFn("...arg")(f, "abc"), 3); + assertEq(makeFn("...arg")(f, [1, 2, 3][Symbol.iterator]()), 3); + assertEq(makeFn("...arg")(f, new Set([1, 2, 3])), 3); + assertEq(makeFn("...arg")(f, new Map([["a", "A"], ["b", "B"], ["c", "C"]])), 3); + let itr = {}; + itr[Symbol.iterator] = function() { + return { + i: 1, + next: function() { + if (this.i < 4) + return { value: this.i++, done: false }; + else + return { value: undefined, done: true }; + } + }; + } + assertEq(makeFn("...arg")(f, itr), 3); + function* gen() { + for (let i = 1; i < 4; i ++) + yield i; + } + assertEq(makeFn("...arg")(f, gen()), 3); +} + +checkLength(function(x) arguments.length, makeCall); +checkLength(function(x) arguments.length, makeFunCall); +function lengthClass(x) { + this.length = arguments.length; +} +checkLength(lengthClass, makeNew); diff --git a/js/src/jit-test/tests/basic/spread-call-maxarg.js b/js/src/jit-test/tests/basic/spread-call-maxarg.js new file mode 100644 index 000000000..2ff27d469 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-maxarg.js @@ -0,0 +1,73 @@ +var config = getBuildConfiguration(); + +// FIXME: ASAN and debug builds run this too slowly for now. +if (!config.debug && !config.asan) { + let longArray = []; + longArray.length = getMaxArgs() + 1; + let shortArray = []; + let a; + + let f = function() { + }; + + // Call_Scripted + // Optimized stub is used after some calls. + a = shortArray; + for (let i = 0; i < 4; i++) { + if (i == 3) { + a = longArray; + } + try { + f(...a); + } catch (e) { + assertEq(e.message, "too many function arguments"); + } + } + + // Call_Scripted (constructing) + a = shortArray; + for (let i = 0; i < 4; i++) { + if (i == 3) { + a = longArray; + } + try { + new f(...a); + } catch (e) { + assertEq(e.message, "too many constructor arguments"); + } + } + + // Call_Native + a = shortArray; + for (let i = 0; i < 4; i++) { + if (i == 3) { + a = longArray; + } + try { + Math.max(...a); + } catch (e) { + assertEq(e.message, "too many function arguments"); + } + } + + // Call_Native (constructing) + a = shortArray; + for (let i = 0; i < 4; i++) { + if (i == 3) { + a = longArray; + } + try { + new Date(...a); + } catch (e) { + assertEq(e.message, "too many constructor arguments"); + } + } + + // No optimized stub for eval. + a = longArray; + try { + eval(...a); + } catch (e) { + assertEq(e.message, "too many function arguments"); + } +} diff --git a/js/src/jit-test/tests/basic/spread-call-near-maxarg.js b/js/src/jit-test/tests/basic/spread-call-near-maxarg.js new file mode 100644 index 000000000..2a91b53ac --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-near-maxarg.js @@ -0,0 +1,73 @@ +var config = getBuildConfiguration(); + +// FIXME: ASAN and debug builds run this too slowly for now. +if (!config.debug && !config.asan) { + let longArray = []; + longArray.length = getMaxArgs() - 1; + let shortArray = []; + let a; + + let f = function() { + }; + + // Call_Scripted + // Optimized stub is used after some calls. + a = shortArray; + for (let i = 0; i < 4; i++) { + if (i == 3) { + a = longArray; + } + try { + f(...a); + } catch (e) { + assertEq(e.message, "too much recursion"); + } + } + + // Call_Scripted (constructing) + a = shortArray; + for (let i = 0; i < 4; i++) { + if (i == 3) { + a = longArray; + } + try { + new f(...a); + } catch (e) { + assertEq(e.message, "too much recursion"); + } + } + + // Call_Native + a = shortArray; + for (let i = 0; i < 4; i++) { + if (i == 3) { + a = longArray; + } + try { + Math.max(...a); + } catch (e) { + assertEq(e.message, "too much recursion"); + } + } + + // Call_Native (constructing) + a = shortArray; + for (let i = 0; i < 4; i++) { + if (i == 3) { + a = longArray; + } + try { + new Date(...a); + } catch (e) { + assertEq(e.message, "too much recursion"); + } + } + + // No optimized stub for eval. + a = longArray; + try { + eval(...a); + } catch (e) { + assertEq(e.message, "too much recursion"); + } +} diff --git a/js/src/jit-test/tests/basic/spread-call-new.js b/js/src/jit-test/tests/basic/spread-call-new.js new file mode 100644 index 000000000..dd26ff958 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-new.js @@ -0,0 +1,9 @@ +load(libdir + "eqArrayHelper.js"); + +function g(a, b, c) { + this.value = [a, b, c]; + assertEq(Object.getPrototypeOf(this), g.prototype); + assertEq(arguments.callee, g); +} + +assertEqArray(new g(...[1, 2, 3]).value, [1, 2, 3]); diff --git a/js/src/jit-test/tests/basic/spread-call-not-iterable.js b/js/src/jit-test/tests/basic/spread-call-not-iterable.js new file mode 100644 index 000000000..f1e16cc0e --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-not-iterable.js @@ -0,0 +1,28 @@ +load(libdir + "asserts.js"); +load(libdir + "iteration.js"); + +assertThrowsInstanceOf(() => Math.sin(...true), TypeError); +assertThrowsInstanceOf(() => Math.sin(...false), TypeError); +assertThrowsInstanceOf(() => Math.sin(...new Date()), TypeError); +assertThrowsInstanceOf(() => Math.sin(...Function("")), TypeError); +assertThrowsInstanceOf(() => Math.sin(...function () {}), TypeError); +assertThrowsInstanceOf(() => Math.sin(...(x => x)), TypeError); +assertThrowsInstanceOf(() => Math.sin(...1), TypeError); +assertThrowsInstanceOf(() => Math.sin(...{}), TypeError); +var foo = {} + +foo[Symbol.iterator] = 10; +assertThrowsInstanceOf(() => Math.sin(...foo), TypeError); + +foo[Symbol.iterator] = function() undefined; +assertThrowsInstanceOf(() => Math.sin(...foo), TypeError); + +foo[Symbol.iterator] = function() this; +assertThrowsInstanceOf(() => Math.sin(...foo), TypeError); + +foo[Symbol.iterator] = function() this; +foo.next = function() { throw 10; }; +assertThrowsValue(() => Math.sin(...foo), 10); + +assertThrowsInstanceOf(() => Math.sin(.../a/), TypeError); +assertThrowsInstanceOf(() => Math.sin(...new Error()), TypeError); diff --git a/js/src/jit-test/tests/basic/spread-call-optimized.js b/js/src/jit-test/tests/basic/spread-call-optimized.js new file mode 100644 index 000000000..afb1368f1 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-optimized.js @@ -0,0 +1,26 @@ +// Call_Scripted +let f = function(a, b, c, d, e) { + return a * 10000 + b * 1000 + c * 100 + d * 10 + e; +}; +for (let i = 0; i < 4; i++) { + assertEq(f(...[1, 2, 3, 4, 5]), 12345); +} + +// Call_Scripted (constructing) +let A = function(a, b, c, d, e) { + this.v = a * 10000 + b * 1000 + c * 100 + d * 10 + e; +}; +for (let i = 0; i < 4; i++) { + assertEq(new A(...[1, 2, 3, 4, 5]).v, 12345); +} + +// Call_Native +for (let i = 0; i < 4; i++) { + assertEq(Math.max(...[1, 2, 3, 4, 5]), 5); +} + +// Call_Native (constructing) +for (let i = 0; i < 4; i++) { + assertEq(new Date(...[2014, 4, 28, 8, 16, 1]).getTime(), + new Date(2014, 4, 28, 8, 16, 1).getTime()); +} diff --git a/js/src/jit-test/tests/basic/spread-call-recursion.js b/js/src/jit-test/tests/basic/spread-call-recursion.js new file mode 100644 index 000000000..58450d885 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-recursion.js @@ -0,0 +1,18 @@ +let a = []; +a.length = 30; + +function check(f) { + try { + f(); + } catch (e) { + assertEq(e.message, "too much recursion"); + } +} + +let f = function() f(...a) + 1; +let g = () => g(...a) + 1; +let h = function() new h(...a) + 1; + +check(f); +check(g); +check(h); diff --git a/js/src/jit-test/tests/basic/spread-call-rest.js b/js/src/jit-test/tests/basic/spread-call-rest.js new file mode 100644 index 000000000..6907ed34b --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-rest.js @@ -0,0 +1,73 @@ +// bug 1235092 +// Optimize spread call with rest parameter. + +load(libdir + "asserts.js"); + +function makeArray(...args) { + return args; +} + +// Optimizable Case. +function test(...args) { + return makeArray(...args); +} +assertDeepEq(test(1, 2, 3), [1, 2, 3]); + +// Not optimizable case 1: the array has hole. +function hole1(...args) { + args[4] = 5; + return makeArray(...args); +} +assertDeepEq(hole1(1, 2, 3), [1, 2, 3, undefined, 5]); + +function hole2(...args) { + args.length = 5; + return makeArray(...args); +} +assertDeepEq(hole2(1, 2, 3), [1, 2, 3, undefined, undefined]); + +function hole3(...args) { + delete args[1]; + return makeArray(...args); +} +assertDeepEq(hole3(1, 2, 3), [1, undefined, 3]); + +// Not optimizable case 2: array[@@iterator] is modified. +function modifiedIterator(...args) { + args[Symbol.iterator] = function*() { + for (let i = 0; i < this.length; i++) + yield this[i] * 10; + }; + return makeArray(...args); +} +assertDeepEq(modifiedIterator(1, 2, 3), [10, 20, 30]); + +// Not optimizable case 3: the array's prototype is modified. +function modifiedProto(...args) { + args.__proto__ = { + __proto__: Array.prototype, + *[Symbol.iterator]() { + for (let i = 0; i < this.length; i++) + yield this[i] * 10; + } + }; + return makeArray(...args); +} +assertDeepEq(modifiedProto(1, 2, 3), [10, 20, 30]); + +// Not optimizable case 4: Array.prototype[@@iterator] is modified. +let ArrayValues = Array.prototype[Symbol.iterator]; +Array.prototype[Symbol.iterator] = function*() { + for (let i = 0; i < this.length; i++) + yield this[i] * 10; +}; +assertDeepEq(test(1, 2, 3), [10, 20, 30]); +Array.prototype[Symbol.iterator] = ArrayValues; + +// Not optimizable case 5: %ArrayIteratorPrototype%.next is modified. +let ArrayIteratorPrototype = Object.getPrototypeOf(Array.prototype[Symbol.iterator]()); +let i = 1; +ArrayIteratorPrototype.next = function() { + return { done: i % 4 == 0, value: 10 * i++ }; +}; +assertDeepEq(test(1, 2, 3), [10, 20, 30]); diff --git a/js/src/jit-test/tests/basic/spread-call-setcall.js b/js/src/jit-test/tests/basic/spread-call-setcall.js new file mode 100644 index 000000000..5a1100b8e --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-setcall.js @@ -0,0 +1,29 @@ +load(libdir + "asserts.js"); + +function g() { +} + +let a = { + g: function() { + } +}; + +function check(expr) { + assertThrowsInstanceOf(Function(expr), ReferenceError); +} +function checkDestructuring(expr) { + assertThrowsInstanceOf(() => Function(expr), SyntaxError); +} + +check("g(...[]) = 1"); +check("a.g(...[]) = 1"); +check("eval(...['1']) = 1"); +check("g(...[]) ++"); +check("a.g(...[]) ++"); +check("eval(...['1']) ++"); +checkDestructuring("[g(...[])] = []"); +checkDestructuring("[a.g(...[])] = []"); +checkDestructuring("[eval(...['1'])] = []"); +checkDestructuring("({y: g(...[])} = 1)"); +checkDestructuring("({y: a.g(...[])} = 1)"); +checkDestructuring("({y: eval(...['1'])} = 1)"); diff --git a/js/src/jit-test/tests/basic/spread-call-this-strict.js b/js/src/jit-test/tests/basic/spread-call-this-strict.js new file mode 100644 index 000000000..3c88b1117 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-this-strict.js @@ -0,0 +1,105 @@ +"use strict"; + +let global = this; +let p = {}; +let q = {}; + +let g1 = function() { + assertEq(this, undefined); +}; +g1(...[]); + +let g2 = x => { + assertEq(this, global); +}; +g2(...[]); + +let g3 = function() { + assertEq(this, p); +}; +g3.apply(p, ...[]); +g3.call(p, ...[]); + +g2.apply(p, ...[]); +g2.call(p, ...[]); + +let o = { + f1: function() { + assertEq(this, o); + + let g1 = function() { + assertEq(this, undefined); + }; + g1(...[]); + + let g2 = x => { + assertEq(this, o); + }; + g2(...[]); + + let g3 = function() { + assertEq(this, q); + }; + g3.apply(q, ...[]); + g3.call(q, ...[]); + + let g4 = x => { + assertEq(this, o); + }; + g4.apply(q, ...[]); + g4.call(q, ...[]); + }, + f2: x => { + assertEq(this, global); + let g1 = function() { + assertEq(this, undefined); + }; + g1(...[]); + + let g2 = x => { + assertEq(this, global); + }; + g2(...[]); + + let g3 = function() { + assertEq(this, q); + }; + g3.apply(q, ...[]); + g3.call(q, ...[]); + + let g4 = x => { + assertEq(this, global); + }; + g4.apply(q, ...[]); + g4.call(q, ...[]); + }, + f3: function() { + assertEq(this, p); + + let g1 = function() { + assertEq(this, undefined); + }; + g1(...[]); + + let g2 = x => { + assertEq(this, p); + }; + g2(...[]); + + let g3 = function() { + assertEq(this, q); + }; + g3.apply(q, ...[]); + g3.call(q, ...[]); + + let g4 = x => { + assertEq(this, p); + }; + g4.apply(q, ...[]); + g4.call(q, ...[]); + } +}; +o.f1(...[]); +o.f2(...[]); +o.f3.apply(p, ...[]); +o.f2.apply(p, ...[]); diff --git a/js/src/jit-test/tests/basic/spread-call-this.js b/js/src/jit-test/tests/basic/spread-call-this.js new file mode 100644 index 000000000..7dac8ca62 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call-this.js @@ -0,0 +1,123 @@ +let global = this; +let p = {}; +let q = {}; + +let g1 = function() { + assertEq(this, global); + assertEq(arguments.callee, g1); +}; +g1(...[]); + +let g2 = x => { + assertEq(this, global); + // arguments.callee is unbound function object, and following assertion fails. + // see Bug 889158 + //assertEq(arguments.callee, g2); +}; +g2(...[]); + +let g3 = function() { + assertEq(this, p); + assertEq(arguments.callee, g3); +}; +g3.apply(p, ...[]); +g3.call(p, ...[]); + +g2.apply(p, ...[]); +g2.call(p, ...[]); + +let o = { + f1: function() { + assertEq(this, o); + assertEq(arguments.callee, o.f1); + + let g1 = function() { + assertEq(this, global); + assertEq(arguments.callee, g1); + }; + g1(...[]); + + let g2 = x => { + assertEq(this, o); + //assertEq(arguments.callee, g2); + }; + g2(...[]); + + let g3 = function() { + assertEq(this, q); + assertEq(arguments.callee, g3); + }; + g3.apply(q, ...[]); + g3.call(q, ...[]); + + let g4 = x => { + assertEq(this, o); + //assertEq(arguments.callee, g4); + }; + g4.apply(q, ...[]); + g4.call(q, ...[]); + }, + f2: x => { + assertEq(this, global); + //assertEq(arguments.callee, o.f2); + let g1 = function() { + assertEq(this, global); + assertEq(arguments.callee, g1); + }; + g1(...[]); + + let g2 = x => { + assertEq(this, global); + //assertEq(arguments.callee, g2); + }; + g2(...[]); + + let g3 = function() { + assertEq(this, q); + assertEq(arguments.callee, g3); + }; + g3.apply(q, ...[]); + g3.call(q, ...[]); + + let g4 = x => { + assertEq(this, global); + //assertEq(arguments.callee, g4); + }; + g4.apply(q, ...[]); + g4.call(q, ...[]); + }, + f3: function() { + assertEq(this, p); + assertEq(arguments.callee, o.f3); + + let g1 = function() { + assertEq(this, global); + assertEq(arguments.callee, g1); + }; + g1(...[]); + + let g2 = x => { + assertEq(this, p); + //assertEq(arguments.callee, g2); + }; + g2(...[]); + + let g3 = function() { + assertEq(this, q); + assertEq(arguments.callee, g3); + }; + g3.apply(q, ...[]); + g3.call(q, ...[]); + + let g4 = x => { + assertEq(this, p); + //assertEq(arguments.callee, g4); + }; + g4.apply(q, ...[]); + g4.call(q, ...[]); + } +}; +o.f1(...[]); +o.f2(...[]); +o.f3.apply(p, ...[]); +o.f2.apply(p, ...[]); diff --git a/js/src/jit-test/tests/basic/spread-call.js b/js/src/jit-test/tests/basic/spread-call.js new file mode 100644 index 000000000..927c6d0f4 --- /dev/null +++ b/js/src/jit-test/tests/basic/spread-call.js @@ -0,0 +1,110 @@ +load(libdir + "asserts.js"); +load(libdir + "eqArrayHelper.js"); +load(libdir + "iteration.js"); + +let makeCall = farg => Function("f", "arg", "return f(" + farg + ");"); +let makeFunCall = farg => Function("f", "arg", "return f.call(null, " + farg + ");"); +let makeNew = farg => Function("f", "arg", "return new f(" + farg + ").value;"); + +function checkCommon(f, makeFn) { + assertEqArray(makeFn("...[1, 2, 3]")(f), [1, 2, 3]); + assertEqArray(makeFn("1, ...[2], 3")(f), [1, 2, 3]); + assertEqArray(makeFn("1, ...[2], ...[3]")(f), [1, 2, 3]); + assertEqArray(makeFn("1, ...[2, 3]")(f), [1, 2, 3]); + assertEqArray(makeFn("1, ...[], 2, 3")(f), [1, 2, 3]); + + // other iterable objects + assertEqArray(makeFn("...arg")(f, new Int32Array([1, 2, 3])), [1, 2, 3]); + assertEqArray(makeFn("...arg")(f, "abc"), ["a", "b", "c"]); + assertEqArray(makeFn("...arg")(f, [1, 2, 3][Symbol.iterator]()), [1, 2, 3]); + assertEqArray(makeFn("...arg")(f, new Set([1, 2, 3])), [1, 2, 3]); + assertEqArray(makeFn("...arg")(f, new Map([["a", "A"], ["b", "B"], ["c", "C"]])).map(([k, v]) => k + v), ["aA", "bB", "cC"]); + let itr = {}; + itr[Symbol.iterator] = function() { + return { + i: 1, + next: function() { + if (this.i < 4) + return { value: this.i++, done: false }; + else + return { value: undefined, done: true }; + } + }; + }; + assertEqArray(makeFn("...arg")(f, itr), [1, 2, 3]); + function gen() { + for (let i = 1; i < 4; i ++) + yield i; + } + assertEqArray(makeFn("...arg")(f, gen()), [1, 2, 3]); + + assertEqArray(makeFn("...arg=[1, 2, 3]")(f), [1, 2, 3]); + + // 12.2.4.1.2 Runtime Semantics: ArrayAccumulation + // If Type(spreadObj) is not Object, then throw a TypeError exception. + assertThrowsInstanceOf(makeFn("1, ...null, 2, 3"), TypeError); + assertThrowsInstanceOf(makeFn("1, ...undefined, 2, 3"), TypeError); +} + +function checkNormal(f, makeFn) { + checkCommon(f, makeFn); + + assertEqArray(makeFn("...[]")(f), [undefined, undefined, undefined]); + assertEqArray(makeFn("...[1]")(f), [1, undefined, undefined]); + assertEqArray(makeFn("...[1, 2]")(f), [1, 2, undefined]); + assertEqArray(makeFn("...[1, 2, 3, 4]")(f), [1, 2, 3]); + + assertEqArray(makeFn("...[undefined]")(f), [undefined, undefined, undefined]); +} + +checkNormal(function(a, b, c) [a, b, c], makeCall); +checkNormal(function(a, b, c) [a, b, c], makeFunCall); +checkNormal((a, b, c) => [a, b, c], makeCall); +checkNormal((a, b, c) => [a, b, c], makeFunCall); +function normalClass(a, b, c) { + this.value = [a, b, c]; + assertEq(Object.getPrototypeOf(this), normalClass.prototype); +} +checkNormal(normalClass, makeNew); + +function checkDefault(f, makeFn) { + checkCommon(f, makeFn); + + assertEqArray(makeFn("...[]")(f), [-1, -2, -3]); + assertEqArray(makeFn("...[1]")(f), [1, -2, -3]); + assertEqArray(makeFn("...[1, 2]")(f), [1, 2, -3]); + assertEqArray(makeFn("...[1, 2, 3, 4]")(f), [1, 2, 3]); + + assertEqArray(makeFn("...[undefined]")(f), [-1, -2, -3]); +} + +checkDefault(function(a = -1, b = -2, c = -3) [a, b, c], makeCall); +checkDefault(function(a = -1, b = -2, c = -3) [a, b, c], makeFunCall); +checkDefault((a = -1, b = -2, c = -3) => [a, b, c], makeCall); +checkDefault((a = -1, b = -2, c = -3) => [a, b, c], makeFunCall); +function defaultClass(a = -1, b = -2, c = -3) { + this.value = [a, b, c]; + assertEq(Object.getPrototypeOf(this), defaultClass.prototype); +} +checkDefault(defaultClass, makeNew); + +function checkRest(f, makeFn) { + checkCommon(f, makeFn); + + assertEqArray(makeFn("...[]")(f), []); + assertEqArray(makeFn("1, ...[2, 3, 4], 5")(f), [1, 2, 3, 4, 5]); + assertEqArray(makeFn("1, ...[], 2")(f), [1, 2]); + assertEqArray(makeFn("1, ...[2, 3], 4, ...[5, 6]")(f), [1, 2, 3, 4, 5, 6]); + + assertEqArray(makeFn("...[undefined]")(f), [undefined]); +} + +checkRest(function(...x) x, makeCall); +checkRest(function(...x) x, makeFunCall); +checkRest((...x) => x, makeCall); +checkRest((...x) => x, makeFunCall); +function restClass(...x) { + this.value = x; + assertEq(Object.getPrototypeOf(this), restClass.prototype); +} +checkRest(restClass, makeNew); diff --git a/js/src/jit-test/tests/basic/statement-after-return.js b/js/src/jit-test/tests/basic/statement-after-return.js new file mode 100644 index 000000000..d101248a3 --- /dev/null +++ b/js/src/jit-test/tests/basic/statement-after-return.js @@ -0,0 +1,496 @@ +// Warning should be shown for unreachable statement after return (bug 1151931). + +function testWarn(code, lineNumber, columnNumber) { + enableLastWarning(); + eval(code); + var warning = getLastWarning(); + assertEq(warning !== null, true, "warning should be caught for " + code); + assertEq(warning.name, "Warning"); + assertEq(warning.lineNumber, lineNumber); + assertEq(warning.columnNumber, columnNumber); + + clearLastWarning(); + Reflect.parse(code); + warning = getLastWarning(); + assertEq(warning !== null, true, "warning should be caught for " + code); + assertEq(warning.name, "Warning"); + // Warning generated by Reflect.parse has line/column number for Reflect.parse + // itself, not parsed code. + disableLastWarning(); +} + +function testPass(code) { + enableLastWarning(); + eval(code); + var warning = getLastWarning(); + assertEq(warning, null, "warning should not be caught for " + code); + + clearLastWarning(); + Reflect.parse(code); + warning = getLastWarning(); + assertEq(warning, null, "warning should not be caught for " + code); + disableLastWarning(); +} + +testPass(` +function f() { + return ( + 1 + 2 + ); +} +`); + +// unary expression +testWarn(` +function f() { + var i = 0; + return + ++i; +} +`, 5, 4); +testWarn(` +function f() { + var i = 0; + return + --i; +} +`, 5, 4); + +// array +testWarn(` +function f() { + return + [1, 2, 3]; +} +`, 4, 4); + +// block (object) +testWarn(` +function f() { + return + {x: 10}; +} +`, 4, 4); +testWarn(` +function f() { + return + { + method() + { + f(); + } + }; +} +`, 4, 2); + +// expression in paren +testWarn(` +function f() { + return + (1 + 2); +} +`, 4, 4); + +// name +testWarn(` +function f() { + return + f; +} +`, 4, 4); + +// binary expression +testWarn(` +function f() { + return + 1 + 2; +} +`, 4, 4); +testWarn(` +function f() { + return + .1 + .2; +} +`, 4, 4); + +// string +testWarn(` +function f() { + return + "foo"; +} +`, 4, 4); +testWarn(` +function f() { + return + "use struct"; +} +`, 4, 4); +testWarn(` +function f() { + return + 'foo'; +} +`, 4, 4); + +// template string +testWarn(` +function f() { + return + \`foo\${1 + 2}\`; +} +`, 4, 4); +testWarn(` +function f() { + return + \`foo\`; +} +`, 4, 4); + +// RegExp +testWarn(` +function f() { + return + /foo/; +} +`, 4, 4); + +// boolean +testWarn(` +function f() { + return + true; +} +`, 4, 4); +testWarn(` +function f() { + return + false; +} +`, 4, 4); + +// null +testWarn(` +function f() { + return + null; +} +`, 4, 4); + +// this +testWarn(` +function f() { + return + this; +} +`, 4, 4); + +// new +testWarn(` +function f() { + return + new Array(); +} +`, 4, 4); + +// delete +testWarn(` +function f() { + var a = {x: 10}; + return + delete a.x; +} +`, 5, 4); + +// yield +testWarn(` +function* f() { + return + yield 1; +} +`, 4, 4); + +// class +testWarn(` +function f() { + return + class A { constructor() {} }; +} +`, 4, 4); + +// unary expression +testWarn(` +function f() { + return + +1; +} +`, 4, 4); +testWarn(` +function f() { + return + -1; +} +`, 4, 4); +testWarn(` +function f() { + return + !1; +} +`, 4, 4); +testWarn(` +function f() { + return + ~1; +} +`, 4, 4); + +// eof +testPass(` +var f = new Function("return\\n"); +`); + +// empty statement +testPass(` +function f() { + return; + ; // empty statement +} +`); + +// end of block +testPass(` +function f() { + { + return + } +} +`); + +// function (hosted) +testPass(` +function f() { + g(); + return + function g() {} +} +`); + +// if +testWarn(` +function f() { + return + if (true) + 1 + 2; +} +`, 4, 2); + +// else +testPass(` +function f() { + if (true) + return + else + 1 + 2; +} +`); + +// switch +testWarn(` +function f() { + return + switch (1) { + case 1: + break; + } +} +`, 4, 2); + +// return in switch +testWarn(` +function f() { + switch (1) { + case 1: + return; + 1 + 2; + break; + } +} +`, 6, 6); + +// break in switch +testPass(` +function f() { + switch (1) { + case 1: + return; + break; + } +} +`); + +// case +testPass(` +function f() { + switch (1) { + case 0: + return + case 1: + break; + } +} +`); + +// default +testPass(` +function f() { + switch (1) { + case 0: + return + default: + break; + } +} +`); + +// while +testWarn(` +function f() { + return + while (false) + 1 + 2; +} +`, 4, 2); +testPass(` +function f() { + do + return + while (false); +} +`); + +// do +testWarn(` +function f() { + return + do { + 1 + 2; + } while (false); +} +`, 4, 2); + +// for +testWarn(` +function f() { + return + for (;;) { + break; + } +} +`, 4, 2); + +// break in for +testPass(` +function f() { + for (;;) { + return + break; + } +} +`, 5, 4); + +// continue +testWarn(` +function f() { + for (;;) { + return + continue; + } +} +`, 5, 4); + +// var (hosted) +testPass(` +function f() { + return + var a = 1; +} +`); + +// const +testWarn(` +function f() { + return + const a = 1; +} +`, 4, 2); + +// with +testWarn(` +function f() { + return + with ({}) { + 1; + } +} +`, 4, 2); + +// return +testWarn(` +function f() { + return + return; +} +`, 4, 2); + +// try +testWarn(` +function f() { + return + try { + } catch (e) { + } +} +`, 4, 2); + +// throw +testPass(` +function f() { + return + throw 1; +} +`); + +// debugger +testWarn(` +function f() { + return + debugger; +} +`, 4, 2); + +// let +testWarn(` +function f() { + return + let a = 1; +} +`, 4, 2); + +// skip hoisted + +testWarn(` +function f() { + return + var a = 0; + (1 + 2); +} +`, 5, 2); + +testWarn(` +function f() { + return + function f() {} + var a = 0; + (1 + 2); +} +`, 6, 2); diff --git a/js/src/jit-test/tests/basic/strict-catch-ident-syntax.js b/js/src/jit-test/tests/basic/strict-catch-ident-syntax.js new file mode 100644 index 000000000..2058e5aa2 --- /dev/null +++ b/js/src/jit-test/tests/basic/strict-catch-ident-syntax.js @@ -0,0 +1,9 @@ +/* Parse correctly. */ + +function assignToClassListStrict(e) { + "use strict"; + try { + e.classList = "foo"; + ok(false, "assigning to classList didn't throw"); + } catch (e) { } +} diff --git a/js/src/jit-test/tests/basic/strict-compare-same-operands.js b/js/src/jit-test/tests/basic/strict-compare-same-operands.js new file mode 100644 index 000000000..57ca42505 --- /dev/null +++ b/js/src/jit-test/tests/basic/strict-compare-same-operands.js @@ -0,0 +1,49 @@ +function f(l, m) { + var a = NaN; + var b = 13; + var c = "test"; + var d = undefined; + var e = null; + var f = 15.7; + var g = Math.fround(189777.111); + var h = "ABC"; + var i = String.fromCharCode(65, 65, 65); + var j = {}; + var k = Math.fround("".charCodeAt(15)); + + // Special case rigt here: + assertEq(a === a, false); + assertEq(a !== a, true); + assertEq(k === k, false); + assertEq(k !== k, true); + assertEq(l === l, false); + assertEq(l !== l, true); + + assertEq(b === b, true); + assertEq(b !== b, false); + assertEq(c === c, true); + assertEq(c !== c, false); + assertEq(d === d, true); + assertEq(d !== d, false); + assertEq(e === e, true); + assertEq(e !== e, false); + assertEq(f === f, true); + assertEq(f !== f, false); + assertEq(g === g, true); + assertEq(g !== g, false); + assertEq(h === h, true); + assertEq(h !== h, false); + assertEq(i === i, true); + assertEq(i !== i, false); + assertEq(j === j, true); + assertEq(j !== j, false); + assertEq(m === m, true); + assertEq(m !== m, false); +} + +function test() { + for (var i = 0; i < 100; i++) + f("".charCodeAt(15), 42); +} + +test(); diff --git a/js/src/jit-test/tests/basic/strict-eval-loop-error.js b/js/src/jit-test/tests/basic/strict-eval-loop-error.js new file mode 100644 index 000000000..f09ad4402 --- /dev/null +++ b/js/src/jit-test/tests/basic/strict-eval-loop-error.js @@ -0,0 +1,3 @@ +var COUNT = 9; +eval("'use strict'; for (let j = 0; j < COUNT; j++); try { x; throw new Error(); } catch (e) { if (!(e instanceof ReferenceError)) throw e; }"); +assertEq(typeof j, "undefined"); diff --git a/js/src/jit-test/tests/basic/strictParseIntOctal.js b/js/src/jit-test/tests/basic/strictParseIntOctal.js new file mode 100644 index 000000000..59412f317 --- /dev/null +++ b/js/src/jit-test/tests/basic/strictParseIntOctal.js @@ -0,0 +1,16 @@ +"use strict"; + +assertEq(parseInt("08"), 8); +assertEq(parseInt("09"), 9); +assertEq(parseInt("014"), 14); +assertEq(parseInt("0xA"), 10); +assertEq(parseInt("00123"), 123); + +for (var i = 0; i < 5; i++) +{ + assertEq(parseInt("08"), 8); + assertEq(parseInt("09"), 9); + assertEq(parseInt("014"), 14); + assertEq(parseInt("0xA"), 10); + assertEq(parseInt("00123"), 123); +} diff --git a/js/src/jit-test/tests/basic/string-endswith.js b/js/src/jit-test/tests/basic/string-endswith.js new file mode 100644 index 000000000..6ba5a4f5d --- /dev/null +++ b/js/src/jit-test/tests/basic/string-endswith.js @@ -0,0 +1,262 @@ +/* +* Copyright (c) 2013 Mathias Bynens. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +function assertThrows(fun, errorType) { + try { + fun(); + assertEq(true, false, "Expected error, but none was thrown"); + } catch (e) { + assertEq(e instanceof errorType, true, "Wrong error type thrown"); + } +} +assertEq(String.prototype.endsWith.length, 1); +assertEq(String.prototype.propertyIsEnumerable('endsWith'), false); + +assertEq('undefined'.endsWith(), true); +assertEq('undefined'.endsWith(undefined), true); +assertEq('undefined'.endsWith(null), false); +assertEq('null'.endsWith(), false); +assertEq('null'.endsWith(undefined), false); +assertEq('null'.endsWith(null), true); + +assertEq('abc'.endsWith(), false); +assertEq('abc'.endsWith(''), true); +assertEq('abc'.endsWith('\0'), false); +assertEq('abc'.endsWith('c'), true); +assertEq('abc'.endsWith('b'), false); +assertEq('abc'.endsWith('a'), false); +assertEq('abc'.endsWith('ab'), false); +assertEq('abc'.endsWith('bc'), true); +assertEq('abc'.endsWith('abc'), true); +assertEq('abc'.endsWith('bcd'), false); +assertEq('abc'.endsWith('abcd'), false); +assertEq('abc'.endsWith('bcde'), false); + +assertEq('abc'.endsWith('', NaN), true); +assertEq('abc'.endsWith('\0', NaN), false); +assertEq('abc'.endsWith('c', NaN), false); +assertEq('abc'.endsWith('b', NaN), false); +assertEq('abc'.endsWith('a', NaN), false); +assertEq('abc'.endsWith('ab', NaN), false); +assertEq('abc'.endsWith('bc', NaN), false); +assertEq('abc'.endsWith('abc', NaN), false); +assertEq('abc'.endsWith('bcd', NaN), false); +assertEq('abc'.endsWith('abcd', NaN), false); +assertEq('abc'.endsWith('bcde', NaN), false); + +assertEq('abc'.endsWith('', false), true); +assertEq('abc'.endsWith('\0', false), false); +assertEq('abc'.endsWith('c', false), false); +assertEq('abc'.endsWith('b', false), false); +assertEq('abc'.endsWith('a', false), false); +assertEq('abc'.endsWith('ab', false), false); +assertEq('abc'.endsWith('bc', false), false); +assertEq('abc'.endsWith('abc', false), false); +assertEq('abc'.endsWith('bcd', false), false); +assertEq('abc'.endsWith('abcd', false), false); +assertEq('abc'.endsWith('bcde', false), false); + +assertEq('abc'.endsWith('', undefined), true); +assertEq('abc'.endsWith('\0', undefined), false); +assertEq('abc'.endsWith('c', undefined), true); +assertEq('abc'.endsWith('b', undefined), false); +assertEq('abc'.endsWith('a', undefined), false); +assertEq('abc'.endsWith('ab', undefined), false); +assertEq('abc'.endsWith('bc', undefined), true); +assertEq('abc'.endsWith('abc', undefined), true); +assertEq('abc'.endsWith('bcd', undefined), false); +assertEq('abc'.endsWith('abcd', undefined), false); +assertEq('abc'.endsWith('bcde', undefined), false); + +assertEq('abc'.endsWith('', null), true); +assertEq('abc'.endsWith('\0', null), false); +assertEq('abc'.endsWith('c', null), false); +assertEq('abc'.endsWith('b', null), false); +assertEq('abc'.endsWith('a', null), false); +assertEq('abc'.endsWith('ab', null), false); +assertEq('abc'.endsWith('bc', null), false); +assertEq('abc'.endsWith('abc', null), false); +assertEq('abc'.endsWith('bcd', null), false); +assertEq('abc'.endsWith('abcd', null), false); +assertEq('abc'.endsWith('bcde', null), false); + +assertEq('abc'.endsWith('', -Infinity), true); +assertEq('abc'.endsWith('\0', -Infinity), false); +assertEq('abc'.endsWith('c', -Infinity), false); +assertEq('abc'.endsWith('b', -Infinity), false); +assertEq('abc'.endsWith('a', -Infinity), false); +assertEq('abc'.endsWith('ab', -Infinity), false); +assertEq('abc'.endsWith('bc', -Infinity), false); +assertEq('abc'.endsWith('abc', -Infinity), false); +assertEq('abc'.endsWith('bcd', -Infinity), false); +assertEq('abc'.endsWith('abcd', -Infinity), false); +assertEq('abc'.endsWith('bcde', -Infinity), false); + +assertEq('abc'.endsWith('', -1), true); +assertEq('abc'.endsWith('\0', -1), false); +assertEq('abc'.endsWith('c', -1), false); +assertEq('abc'.endsWith('b', -1), false); +assertEq('abc'.endsWith('a', -1), false); +assertEq('abc'.endsWith('ab', -1), false); +assertEq('abc'.endsWith('bc', -1), false); +assertEq('abc'.endsWith('abc', -1), false); +assertEq('abc'.endsWith('bcd', -1), false); +assertEq('abc'.endsWith('abcd', -1), false); +assertEq('abc'.endsWith('bcde', -1), false); + +assertEq('abc'.endsWith('', -0), true); +assertEq('abc'.endsWith('\0', -0), false); +assertEq('abc'.endsWith('c', -0), false); +assertEq('abc'.endsWith('b', -0), false); +assertEq('abc'.endsWith('a', -0), false); +assertEq('abc'.endsWith('ab', -0), false); +assertEq('abc'.endsWith('bc', -0), false); +assertEq('abc'.endsWith('abc', -0), false); +assertEq('abc'.endsWith('bcd', -0), false); +assertEq('abc'.endsWith('abcd', -0), false); +assertEq('abc'.endsWith('bcde', -0), false); + +assertEq('abc'.endsWith('', +0), true); +assertEq('abc'.endsWith('\0', +0), false); +assertEq('abc'.endsWith('c', +0), false); +assertEq('abc'.endsWith('b', +0), false); +assertEq('abc'.endsWith('a', +0), false); +assertEq('abc'.endsWith('ab', +0), false); +assertEq('abc'.endsWith('bc', +0), false); +assertEq('abc'.endsWith('abc', +0), false); +assertEq('abc'.endsWith('bcd', +0), false); +assertEq('abc'.endsWith('abcd', +0), false); +assertEq('abc'.endsWith('bcde', +0), false); + +assertEq('abc'.endsWith('', 1), true); +assertEq('abc'.endsWith('\0', 1), false); +assertEq('abc'.endsWith('c', 1), false); +assertEq('abc'.endsWith('b', 1), false); +assertEq('abc'.endsWith('ab', 1), false); +assertEq('abc'.endsWith('bc', 1), false); +assertEq('abc'.endsWith('abc', 1), false); +assertEq('abc'.endsWith('bcd', 1), false); +assertEq('abc'.endsWith('abcd', 1), false); +assertEq('abc'.endsWith('bcde', 1), false); + +assertEq('abc'.endsWith('', 2), true); +assertEq('abc'.endsWith('\0', 2), false); +assertEq('abc'.endsWith('c', 2), false); +assertEq('abc'.endsWith('b', 2), true); +assertEq('abc'.endsWith('ab', 2), true); +assertEq('abc'.endsWith('bc', 2), false); +assertEq('abc'.endsWith('abc', 2), false); +assertEq('abc'.endsWith('bcd', 2), false); +assertEq('abc'.endsWith('abcd', 2), false); +assertEq('abc'.endsWith('bcde', 2), false); + +assertEq('abc'.endsWith('', +Infinity), true); +assertEq('abc'.endsWith('\0', +Infinity), false); +assertEq('abc'.endsWith('c', +Infinity), true); +assertEq('abc'.endsWith('b', +Infinity), false); +assertEq('abc'.endsWith('a', +Infinity), false); +assertEq('abc'.endsWith('ab', +Infinity), false); +assertEq('abc'.endsWith('bc', +Infinity), true); +assertEq('abc'.endsWith('abc', +Infinity), true); +assertEq('abc'.endsWith('bcd', +Infinity), false); +assertEq('abc'.endsWith('abcd', +Infinity), false); +assertEq('abc'.endsWith('bcde', +Infinity), false); + +assertEq('abc'.endsWith('', true), true); +assertEq('abc'.endsWith('\0', true), false); +assertEq('abc'.endsWith('c', true), false); +assertEq('abc'.endsWith('b', true), false); +assertEq('abc'.endsWith('ab', true), false); +assertEq('abc'.endsWith('bc', true), false); +assertEq('abc'.endsWith('abc', true), false); +assertEq('abc'.endsWith('bcd', true), false); +assertEq('abc'.endsWith('abcd', true), false); +assertEq('abc'.endsWith('bcde', true), false); + +assertEq('abc'.endsWith('', 'x'), true); +assertEq('abc'.endsWith('\0', 'x'), false); +assertEq('abc'.endsWith('c', 'x'), false); +assertEq('abc'.endsWith('b', 'x'), false); +assertEq('abc'.endsWith('a', 'x'), false); +assertEq('abc'.endsWith('ab', 'x'), false); +assertEq('abc'.endsWith('bc', 'x'), false); +assertEq('abc'.endsWith('abc', 'x'), false); +assertEq('abc'.endsWith('bcd', 'x'), false); +assertEq('abc'.endsWith('abcd', 'x'), false); +assertEq('abc'.endsWith('bcde', 'x'), false); + +assertEq('[a-z]+(bar)?'.endsWith('(bar)?'), true); +assertThrows(function() { '[a-z]+(bar)?'.endsWith(/(bar)?/); }, TypeError); +assertEq('[a-z]+(bar)?'.endsWith('[a-z]+', 6), true); +assertThrows(function() { '[a-z]+(bar)?'.endsWith(/(bar)?/); }, TypeError); +assertThrows(function() { '[a-z]+/(bar)?/'.endsWith(/(bar)?/); }, TypeError); +var global = newGlobal(); +global.eval('this.re = /(bar)?/'); +assertThrows(function() { '[a-z]+/(bar)?/'.endsWith(global.re); }, TypeError); + +// http://mathiasbynens.be/notes/javascript-unicode#poo-test +var string = 'I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\u2603\uD83D\uDCA9'; +assertEq(string.endsWith(''), true); +assertEq(string.endsWith('\xF1t\xEBr'), false); +assertEq(string.endsWith('\xF1t\xEBr', 5), true); +assertEq(string.endsWith('\xE0liz\xE6'), false); +assertEq(string.endsWith('\xE0liz\xE6', 16), true); +assertEq(string.endsWith('\xF8n\u2603\uD83D\uDCA9'), true); +assertEq(string.endsWith('\xF8n\u2603\uD83D\uDCA9', 23), true); +assertEq(string.endsWith('\u2603'), false); +assertEq(string.endsWith('\u2603', 21), true); +assertEq(string.endsWith('\uD83D\uDCA9'), true); +assertEq(string.endsWith('\uD83D\uDCA9', 23), true); + +assertThrows(function() { String.prototype.endsWith.call(undefined); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(undefined, 'b'); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(undefined, 'b', 4); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(null); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(null, 'b'); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(null, 'b', 4); }, TypeError); +assertEq(String.prototype.endsWith.call(42, '2'), true); +assertEq(String.prototype.endsWith.call(42, '4'), false); +assertEq(String.prototype.endsWith.call(42, 'b', 4), false); +assertEq(String.prototype.endsWith.call(42, '2', 1), false); +assertEq(String.prototype.endsWith.call(42, '2', 4), true); +assertEq(String.prototype.endsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 0), false); +assertEq(String.prototype.endsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 1), false); +assertEq(String.prototype.endsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 2), true); +assertThrows(function() { String.prototype.endsWith.call({ 'toString': function() { throw RangeError(); } }, /./); }, RangeError); +assertThrows(function() { String.prototype.endsWith.call({ 'toString': function() { return 'abc' } }, /./); }, TypeError); + +assertThrows(function() { String.prototype.endsWith.apply(undefined); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(undefined, ['b']); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(undefined, ['b', 4]); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(null); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(null, ['b']); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(null, ['b', 4]); }, TypeError); +assertEq(String.prototype.endsWith.apply(42, ['2']), true); +assertEq(String.prototype.endsWith.apply(42, ['4']), false); +assertEq(String.prototype.endsWith.apply(42, ['b', 4]), false); +assertEq(String.prototype.endsWith.apply(42, ['2', 1]), false); +assertEq(String.prototype.endsWith.apply(42, ['2', 4]), true); +assertEq(String.prototype.endsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 0]), false); +assertEq(String.prototype.endsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 1]), false); +assertEq(String.prototype.endsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 2]), true); +assertThrows(function() { String.prototype.endsWith.apply({ 'toString': function() { throw RangeError(); } }, [/./]); }, RangeError); +assertThrows(function() { String.prototype.endsWith.apply({ 'toString': function() { return 'abc' } }, [/./]); }, TypeError); diff --git a/js/src/jit-test/tests/basic/string-includes.js b/js/src/jit-test/tests/basic/string-includes.js new file mode 100644 index 000000000..f41b0c6d7 --- /dev/null +++ b/js/src/jit-test/tests/basic/string-includes.js @@ -0,0 +1,46 @@ +assertEq("abc".includes("a"), true); +assertEq("abc".includes("b"), true); +assertEq("abc".includes("abc"), true); +assertEq("abc".includes("bc"), true); +assertEq("abc".includes("d"), false); +assertEq("abc".includes("abcd"), false); +assertEq("abc".includes("ac"), false); +assertEq("abc".includes("abc", 0), true); +assertEq("abc".includes("bc", 0), true); +assertEq("abc".includes("de", 0), false); +assertEq("abc".includes("bc", 1), true); +assertEq("abc".includes("c", 1), true); +assertEq("abc".includes("a", 1), false); +assertEq("abc".includes("abc", 1), false); +assertEq("abc".includes("c", 2), true); +assertEq("abc".includes("d", 2), false); +assertEq("abc".includes("dcd", 2), false); +assertEq("abc".includes("a", 42), false); +assertEq("abc".includes("a", Infinity), false); +assertEq("abc".includes("ab", -43), true); +assertEq("abc".includes("cd", -42), false); +assertEq("abc".includes("ab", -Infinity), true); +assertEq("abc".includes("cd", -Infinity), false); +assertEq("abc".includes("ab", NaN), true); +assertEq("abc".includes("cd", NaN), false); +var myobj = {toString : () => "abc", includes : String.prototype.includes}; +assertEq(myobj.includes("abc"), true); +assertEq(myobj.includes("cd"), false); +var gotStr = false, gotPos = false; +myobj = {toString : (function () { + assertEq(gotPos, false); + gotStr = true; + return "xyz"; +}), +includes : String.prototype.includes}; +var idx = {valueOf : (function () { + assertEq(gotStr, true); + gotPos = true; + return 42; +})}; +myobj.includes("elephant", idx); +assertEq(gotPos, true); +assertEq("xyzzy".includes("zy\0", 2), false); +var dots = Array(10000).join('.'); +assertEq(dots.includes("\x01", 10000), false); +assertEq(dots.includes("\0", 10000), false); diff --git a/js/src/jit-test/tests/basic/string-regexp-capture-groups.js b/js/src/jit-test/tests/basic/string-regexp-capture-groups.js new file mode 100644 index 000000000..0fc1bb8a1 --- /dev/null +++ b/js/src/jit-test/tests/basic/string-regexp-capture-groups.js @@ -0,0 +1,21 @@ +"abcdefg".match(/(x)y(z)/g); +assertEq(RegExp.$1, ""); + +assertEq("abcdef".match(/a(b)cd/g)[0], "abcd"); +assertEq(RegExp.$1, "b"); +assertEq(RegExp.$2, ""); + +"abcdef".match(/(a)b(c)/g); +assertEq(RegExp.$1, "a"); +assertEq(RegExp.$2, "c"); +assertEq(RegExp.$3, ""); + +"abcabdabe".match(/(a)b(.)/g); +assertEq(RegExp.$1, "a"); +assertEq(RegExp.$2, "e"); + +"abcdefg".match(/(x)y(z)/g); +assertEq(RegExp.$1, "a"); //If there's no match, we don't update the statics. + +"abcdefg".match(/(g)/g); +assertEq(RegExp.$1, "g"); diff --git a/js/src/jit-test/tests/basic/string-repeat.js b/js/src/jit-test/tests/basic/string-repeat.js new file mode 100644 index 000000000..8e9e9ee66 --- /dev/null +++ b/js/src/jit-test/tests/basic/string-repeat.js @@ -0,0 +1,30 @@ +/* Test String.prototype.repeat */
+
+load(libdir + 'asserts.js');
+
+assertEq("abc".repeat(1), "abc");
+assertEq("abc".repeat(2), "abcabc");
+assertEq("abc".repeat(3), "abcabcabc");
+assertEq("a".repeat(10), "aaaaaaaaaa");
+assertEq("abc".repeat(0), "");
+assertEq("abc".repeat(2.9), "abcabc");
+
+var myobj = {toString : () => "abc", repeat : String.prototype.repeat};
+assertEq(myobj.repeat(1), "abc");
+assertEq(myobj.repeat(2), "abcabc");
+
+assertThrowsInstanceOf(function() {
+ "abc".repeat(-1);
+ }, RangeError,
+ "String.prototype.repeat should raise RangeError on negative arguments");
+assertThrowsInstanceOf(function() {
+ "abc".repeat(Number.POSITIVE_INFINITY);
+ }, RangeError,
+ "String.prototype.repeat should raise RangeError on excedding maximum string length");
+assertThrowsInstanceOf(function() {
+ "abc".repeat(1 << 29);
+ }, RangeError,
+ "String.prototype.repeat should raise RangeError on excedding maximum string length");
+
+assertEq("".repeat(5), "");
+assertEq("".repeat(1 << 29), "");
diff --git a/js/src/jit-test/tests/basic/string-startswith.js b/js/src/jit-test/tests/basic/string-startswith.js new file mode 100644 index 000000000..d788e30e8 --- /dev/null +++ b/js/src/jit-test/tests/basic/string-startswith.js @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2013 Mathias Bynens. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +function assertThrows(fun, errorType) { + try { + fun(); + assertEq(true, false, "Expected error, but none was thrown"); + } catch (e) { + assertEq(e instanceof errorType, true, "Wrong error type thrown"); + } +} + +Object.prototype[1] = 2; // try to break `arguments[1]` + +assertEq(String.prototype.startsWith.length, 1); +assertEq(String.prototype.propertyIsEnumerable('startsWith'), false); + +assertEq('undefined'.startsWith(), true); +assertEq('undefined'.startsWith(undefined), true); +assertEq('undefined'.startsWith(null), false); +assertEq('null'.startsWith(), false); +assertEq('null'.startsWith(undefined), false); +assertEq('null'.startsWith(null), true); + +assertEq('abc'.startsWith(), false); +assertEq('abc'.startsWith(''), true); +assertEq('abc'.startsWith('\0'), false); +assertEq('abc'.startsWith('a'), true); +assertEq('abc'.startsWith('b'), false); +assertEq('abc'.startsWith('ab'), true); +assertEq('abc'.startsWith('bc'), false); +assertEq('abc'.startsWith('abc'), true); +assertEq('abc'.startsWith('bcd'), false); +assertEq('abc'.startsWith('abcd'), false); +assertEq('abc'.startsWith('bcde'), false); + +assertEq('abc'.startsWith('', NaN), true); +assertEq('abc'.startsWith('\0', NaN), false); +assertEq('abc'.startsWith('a', NaN), true); +assertEq('abc'.startsWith('b', NaN), false); +assertEq('abc'.startsWith('ab', NaN), true); +assertEq('abc'.startsWith('bc', NaN), false); +assertEq('abc'.startsWith('abc', NaN), true); +assertEq('abc'.startsWith('bcd', NaN), false); +assertEq('abc'.startsWith('abcd', NaN), false); +assertEq('abc'.startsWith('bcde', NaN), false); + +assertEq('abc'.startsWith('', false), true); +assertEq('abc'.startsWith('\0', false), false); +assertEq('abc'.startsWith('a', false), true); +assertEq('abc'.startsWith('b', false), false); +assertEq('abc'.startsWith('ab', false), true); +assertEq('abc'.startsWith('bc', false), false); +assertEq('abc'.startsWith('abc', false), true); +assertEq('abc'.startsWith('bcd', false), false); +assertEq('abc'.startsWith('abcd', false), false); +assertEq('abc'.startsWith('bcde', false), false); + +assertEq('abc'.startsWith('', undefined), true); +assertEq('abc'.startsWith('\0', undefined), false); +assertEq('abc'.startsWith('a', undefined), true); +assertEq('abc'.startsWith('b', undefined), false); +assertEq('abc'.startsWith('ab', undefined), true); +assertEq('abc'.startsWith('bc', undefined), false); +assertEq('abc'.startsWith('abc', undefined), true); +assertEq('abc'.startsWith('bcd', undefined), false); +assertEq('abc'.startsWith('abcd', undefined), false); +assertEq('abc'.startsWith('bcde', undefined), false); + +assertEq('abc'.startsWith('', null), true); +assertEq('abc'.startsWith('\0', null), false); +assertEq('abc'.startsWith('a', null), true); +assertEq('abc'.startsWith('b', null), false); +assertEq('abc'.startsWith('ab', null), true); +assertEq('abc'.startsWith('bc', null), false); +assertEq('abc'.startsWith('abc', null), true); +assertEq('abc'.startsWith('bcd', null), false); +assertEq('abc'.startsWith('abcd', null), false); +assertEq('abc'.startsWith('bcde', null), false); + +assertEq('abc'.startsWith('', -Infinity), true); +assertEq('abc'.startsWith('\0', -Infinity), false); +assertEq('abc'.startsWith('a', -Infinity), true); +assertEq('abc'.startsWith('b', -Infinity), false); +assertEq('abc'.startsWith('ab', -Infinity), true); +assertEq('abc'.startsWith('bc', -Infinity), false); +assertEq('abc'.startsWith('abc', -Infinity), true); +assertEq('abc'.startsWith('bcd', -Infinity), false); +assertEq('abc'.startsWith('abcd', -Infinity), false); +assertEq('abc'.startsWith('bcde', -Infinity), false); + +assertEq('abc'.startsWith('', -1), true); +assertEq('abc'.startsWith('\0', -1), false); +assertEq('abc'.startsWith('a', -1), true); +assertEq('abc'.startsWith('b', -1), false); +assertEq('abc'.startsWith('ab', -1), true); +assertEq('abc'.startsWith('bc', -1), false); +assertEq('abc'.startsWith('abc', -1), true); +assertEq('abc'.startsWith('bcd', -1), false); +assertEq('abc'.startsWith('abcd', -1), false); +assertEq('abc'.startsWith('bcde', -1), false); + +assertEq('abc'.startsWith('', -0), true); +assertEq('abc'.startsWith('\0', -0), false); +assertEq('abc'.startsWith('a', -0), true); +assertEq('abc'.startsWith('b', -0), false); +assertEq('abc'.startsWith('ab', -0), true); +assertEq('abc'.startsWith('bc', -0), false); +assertEq('abc'.startsWith('abc', -0), true); +assertEq('abc'.startsWith('bcd', -0), false); +assertEq('abc'.startsWith('abcd', -0), false); +assertEq('abc'.startsWith('bcde', -0), false); + +assertEq('abc'.startsWith('', +0), true); +assertEq('abc'.startsWith('\0', +0), false); +assertEq('abc'.startsWith('a', +0), true); +assertEq('abc'.startsWith('b', +0), false); +assertEq('abc'.startsWith('ab', +0), true); +assertEq('abc'.startsWith('bc', +0), false); +assertEq('abc'.startsWith('abc', +0), true); +assertEq('abc'.startsWith('bcd', +0), false); +assertEq('abc'.startsWith('abcd', +0), false); +assertEq('abc'.startsWith('bcde', +0), false); + +assertEq('abc'.startsWith('', 1), true); +assertEq('abc'.startsWith('\0', 1), false); +assertEq('abc'.startsWith('a', 1), false); +assertEq('abc'.startsWith('b', 1), true); +assertEq('abc'.startsWith('ab', 1), false); +assertEq('abc'.startsWith('bc', 1), true); +assertEq('abc'.startsWith('abc', 1), false); +assertEq('abc'.startsWith('bcd', 1), false); +assertEq('abc'.startsWith('abcd', 1), false); +assertEq('abc'.startsWith('bcde', 1), false); + +assertEq('abc'.startsWith('', +Infinity), true); +assertEq('abc'.startsWith('\0', +Infinity), false); +assertEq('abc'.startsWith('a', +Infinity), false); +assertEq('abc'.startsWith('b', +Infinity), false); +assertEq('abc'.startsWith('ab', +Infinity), false); +assertEq('abc'.startsWith('bc', +Infinity), false); +assertEq('abc'.startsWith('abc', +Infinity), false); +assertEq('abc'.startsWith('bcd', +Infinity), false); +assertEq('abc'.startsWith('abcd', +Infinity), false); +assertEq('abc'.startsWith('bcde', +Infinity), false); + +assertEq('abc'.startsWith('', true), true); +assertEq('abc'.startsWith('\0', true), false); +assertEq('abc'.startsWith('a', true), false); +assertEq('abc'.startsWith('b', true), true); +assertEq('abc'.startsWith('ab', true), false); +assertEq('abc'.startsWith('bc', true), true); +assertEq('abc'.startsWith('abc', true), false); +assertEq('abc'.startsWith('bcd', true), false); +assertEq('abc'.startsWith('abcd', true), false); +assertEq('abc'.startsWith('bcde', true), false); + +assertEq('abc'.startsWith('', 'x'), true); +assertEq('abc'.startsWith('\0', 'x'), false); +assertEq('abc'.startsWith('a', 'x'), true); +assertEq('abc'.startsWith('b', 'x'), false); +assertEq('abc'.startsWith('ab', 'x'), true); +assertEq('abc'.startsWith('bc', 'x'), false); +assertEq('abc'.startsWith('abc', 'x'), true); +assertEq('abc'.startsWith('bcd', 'x'), false); +assertEq('abc'.startsWith('abcd', 'x'), false); +assertEq('abc'.startsWith('bcde', 'x'), false); + +assertEq('[a-z]+(bar)?'.startsWith('[a-z]+'), true); +assertThrows(function() { '[a-z]+(bar)?'.startsWith(/[a-z]+/); }, TypeError); +assertEq('[a-z]+(bar)?'.startsWith('(bar)?', 6), true); +assertThrows(function() { '[a-z]+(bar)?'.startsWith(/(bar)?/); }, TypeError); +assertThrows(function() { '[a-z]+/(bar)?/'.startsWith(/(bar)?/); }, TypeError); +var global = newGlobal(); +global.eval('this.re = /(bar)?/'); +assertThrows(function() { '[a-z]+/(bar)?/'.startsWith(global.re); }, TypeError); + +// http://mathiasbynens.be/notes/javascript-unicode#poo-test +var string = 'I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\u2603\uD83D\uDCA9'; +assertEq(string.startsWith(''), true); +assertEq(string.startsWith('\xF1t\xEBr'), false); +assertEq(string.startsWith('\xF1t\xEBr', 1), true); +assertEq(string.startsWith('\xE0liz\xE6'), false); +assertEq(string.startsWith('\xE0liz\xE6', 11), true); +assertEq(string.startsWith('\xF8n\u2603\uD83D\uDCA9'), false); +assertEq(string.startsWith('\xF8n\u2603\uD83D\uDCA9', 18), true); +assertEq(string.startsWith('\u2603'), false); +assertEq(string.startsWith('\u2603', 20), true); +assertEq(string.startsWith('\uD83D\uDCA9'), false); +assertEq(string.startsWith('\uD83D\uDCA9', 21), true); + +assertThrows(function() { String.prototype.startsWith.call(undefined); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(undefined, 'b'); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(undefined, 'b', 4); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(null); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(null, 'b'); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(null, 'b', 4); }, TypeError); +assertEq(String.prototype.startsWith.call(42, '2'), false); +assertEq(String.prototype.startsWith.call(42, '4'), true); +assertEq(String.prototype.startsWith.call(42, 'b', 4), false); +assertEq(String.prototype.startsWith.call(42, '2', 1), true); +assertEq(String.prototype.startsWith.call(42, '2', 4), false); +assertEq(String.prototype.startsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 0), false); +assertEq(String.prototype.startsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 1), true); +assertEq(String.prototype.startsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 2), false); +assertThrows(function() { String.prototype.startsWith.call({ 'toString': function() { throw RangeError(); } }, /./); }, RangeError); +assertThrows(function() { String.prototype.startsWith.call({ 'toString': function() { return 'abc'; } }, /./); }, TypeError); + +assertThrows(function() { String.prototype.startsWith.apply(undefined); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(undefined, ['b']); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(undefined, ['b', 4]); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(null); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(null, ['b']); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(null, ['b', 4]); }, TypeError); +assertEq(String.prototype.startsWith.apply(42, ['2']), false); +assertEq(String.prototype.startsWith.apply(42, ['4']), true); +assertEq(String.prototype.startsWith.apply(42, ['b', 4]), false); +assertEq(String.prototype.startsWith.apply(42, ['2', 1]), true); +assertEq(String.prototype.startsWith.apply(42, ['2', 4]), false); +assertEq(String.prototype.startsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 0]), false); +assertEq(String.prototype.startsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 1]), true); +assertEq(String.prototype.startsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 2]), false); +assertThrows(function() { String.prototype.startsWith.apply({ 'toString': function() { throw RangeError(); } }, [/./]); }, RangeError); +assertThrows(function() { String.prototype.startsWith.apply({ 'toString': function() { return 'abc'; } }, [/./]); }, TypeError); diff --git a/js/src/jit-test/tests/basic/stringConvert.js b/js/src/jit-test/tests/basic/stringConvert.js new file mode 100644 index 000000000..53181891d --- /dev/null +++ b/js/src/jit-test/tests/basic/stringConvert.js @@ -0,0 +1,18 @@ +function stringConvert() +{ + var a = []; + var s1 = "F", s2 = "1.3", s3 = "5"; + for (var i = 0; i < 10; i++) { + a[0] = 1 >> s1; + a[1] = 10 - s2; + a[2] = 15 * s3; + a[3] = s3 | 32; + a[4] = s2 + 60; + // a[5] = 9 + s3; + // a[6] = -s3; + a[7] = s3 & "7"; + // a[8] = ~s3; + } + return a.toString(); +} +assertEq(stringConvert(), "1,8.7,75,37,1.360,,,5"); diff --git a/js/src/jit-test/tests/basic/stringSplitIntoArrayTest.js b/js/src/jit-test/tests/basic/stringSplitIntoArrayTest.js new file mode 100644 index 000000000..e7fdb097b --- /dev/null +++ b/js/src/jit-test/tests/basic/stringSplitIntoArrayTest.js @@ -0,0 +1,9 @@ +function stringSplitIntoArrayTest() +{ + var s = "a,b" + var a = []; + for (var i = 0; i < 10; ++i) + a[i] = s.split(","); + return a.join(); +} +assertEq(stringSplitIntoArrayTest(), "a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b"); diff --git a/js/src/jit-test/tests/basic/stringSplitTest.js b/js/src/jit-test/tests/basic/stringSplitTest.js new file mode 100644 index 000000000..942c7e79b --- /dev/null +++ b/js/src/jit-test/tests/basic/stringSplitTest.js @@ -0,0 +1,9 @@ +function stringSplitTest() +{ + var s = "a,b" + var a = null; + for (var i = 0; i < 10; ++i) + a = s.split(","); + return a.join(); +} +assertEq(stringSplitTest(), "a,b"); diff --git a/js/src/jit-test/tests/basic/strings.js b/js/src/jit-test/tests/basic/strings.js new file mode 100644 index 000000000..19139b992 --- /dev/null +++ b/js/src/jit-test/tests/basic/strings.js @@ -0,0 +1,21 @@ +function strings() +{ + var a = [], b = -1; + var s = "abcdefghij", s2 = "a"; + var f = "f"; + var c = 0, d = 0, e = 0, g = 0; + for (var i = 0; i < 10; i++) { + a[i] = (s.substring(i, i+1) + s[i] + String.fromCharCode(s2.charCodeAt(0) + i)).concat(i) + i; + if (s[i] == f) + c++; + if (s[i] != 'b') + d++; + if ("B" > s2) + g++; // f already used + if (s2 < "b") + e++; + b = s.length; + } + return a.toString() + b + c + d + e + g; +} +assertEq(strings(), "aaa00,bbb11,ccc22,ddd33,eee44,fff55,ggg66,hhh77,iii88,jjj991019100"); diff --git a/js/src/jit-test/tests/basic/symbol-in-loop.js b/js/src/jit-test/tests/basic/symbol-in-loop.js new file mode 100644 index 000000000..cddef5265 --- /dev/null +++ b/js/src/jit-test/tests/basic/symbol-in-loop.js @@ -0,0 +1,8 @@ +function f() { + return Object(Symbol()); +} + +for (var i = 0; i < 4; i++) { + f(); + gc(); +} diff --git a/js/src/jit-test/tests/basic/syntax-error-function-body-eof.js b/js/src/jit-test/tests/basic/syntax-error-function-body-eof.js new file mode 100644 index 000000000..7015f83b1 --- /dev/null +++ b/js/src/jit-test/tests/basic/syntax-error-function-body-eof.js @@ -0,0 +1,9 @@ +var caught = false; +try { + new Function("switch (x) {} }"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("unexpected garbage after function body, starting with '}'") == -1, false); + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/syntax-error-primary.js b/js/src/jit-test/tests/basic/syntax-error-primary.js new file mode 100644 index 000000000..6be66ee0c --- /dev/null +++ b/js/src/jit-test/tests/basic/syntax-error-primary.js @@ -0,0 +1,69 @@ +var caught = false; +try { + new Function(")"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("expected expression, got ')'") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("...;"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("expected rest argument name, got ';'") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("...a;"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("expected closing parenthesis, got ';'") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("...a);"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("expected '=>' after argument list, got ';'") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("...a) @"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("expected '=>' after argument list, got '@'") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("(if)"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("expected expression, got keyword 'if'") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("("); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("expected expression, got end of script") == -1, false); + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/syntax-error-throw.js b/js/src/jit-test/tests/basic/syntax-error-throw.js new file mode 100644 index 000000000..c82c56cf8 --- /dev/null +++ b/js/src/jit-test/tests/basic/syntax-error-throw.js @@ -0,0 +1,39 @@ +var caught = false; +try { + new Function("throw;"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("throw statement is missing an expression") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("throw\n1;"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("no line break is allowed between 'throw' and its expression") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("throw}"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("throw statement is missing an expression") == -1, false); + caught = true; +} +assertEq(caught, true); + +caught = false; +try { + new Function("throw"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("throw statement is missing an expression") == -1, false); + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/syntax-error-toplevel-eof.js b/js/src/jit-test/tests/basic/syntax-error-toplevel-eof.js new file mode 100644 index 000000000..15aaaf780 --- /dev/null +++ b/js/src/jit-test/tests/basic/syntax-error-toplevel-eof.js @@ -0,0 +1,9 @@ +var caught = false; +try { + Reflect.parse("}"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + assertEq(e.message.startsWith("unexpected garbage after script, starting with '}'") == -1, false); + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/tagTempl.js b/js/src/jit-test/tests/basic/tagTempl.js new file mode 100644 index 000000000..7d06b0e8f --- /dev/null +++ b/js/src/jit-test/tests/basic/tagTempl.js @@ -0,0 +1,34 @@ +/* + * Tests tagged template string functionality. + */ + +function check(actual, expected) { + assertEq(actual.length, expected.length); + for (var i = 0; i < expected.length; i++) + assertEq(actual[i], expected[i]); +} + +function func(a) { return a; } + +function csoLoop() { + var cso = []; + for (var index = 0; index < 2000; index++) { + cso[index] = func`hey${4}there`; + if (index > 0) + assertEq(cso[index - 1], cso[index]); + } +} + +// Tests baseline and ion functionality. +csoLoop(); + +// Tests off thread compilation +if (helperThreadCount() !== 0) { + offThreadCompileScript("(x=>x)`abc`"); + a = runOffThreadScript(); + check(a, ["abc"]); + check(a.raw, ["abc"]); + assertEq(a === a.raw, false); + assertEq(Object.isFrozen(a), true); + assertEq(Object.isFrozen(a.raw), true); +} diff --git a/js/src/jit-test/tests/basic/teleporting-mutable-proto.js b/js/src/jit-test/tests/basic/teleporting-mutable-proto.js new file mode 100644 index 000000000..c9bfd7f28 --- /dev/null +++ b/js/src/jit-test/tests/basic/teleporting-mutable-proto.js @@ -0,0 +1,14 @@ +var A = {x: 3}; +var B = Object.create(A); +var C = Object.create(B); +var D = Object.create(C); + +function f() { + for (var i=0; i<30; i++) { + assertEq(D.x, (i <= 20) ? 3 : 10); + if (i === 20) { + C.__proto__ = {x: 10}; + } + } +} +f(); diff --git a/js/src/jit-test/tests/basic/terminate.js b/js/src/jit-test/tests/basic/terminate.js new file mode 100644 index 000000000..f2966d783 --- /dev/null +++ b/js/src/jit-test/tests/basic/terminate.js @@ -0,0 +1,10 @@ +// |jit-test| exitstatus: 3 +try { + terminate(); + assertEq("execution continued", "execution should not continue"); +} catch (x) { + assertEq("caught exception", "uncatchable"); +} finally { + assertEq("'finally' clause ran", "'finally' clause should not run"); +} +assertEq("top-level execution continued", "top-level execution should not continue"); diff --git a/js/src/jit-test/tests/basic/test-apply-many-args.js b/js/src/jit-test/tests/basic/test-apply-many-args.js new file mode 100644 index 000000000..ea02f4df3 --- /dev/null +++ b/js/src/jit-test/tests/basic/test-apply-many-args.js @@ -0,0 +1,14 @@ +function f(x) { + if (x == 0) + return; + arguments[0]--; + f.apply(null, arguments); +} + +// When the apply-optimization isn't on, each recursive call chews up the C +// stack, so don't push it. +a = [20]; + +for (var i = 0; i < 2000; ++i) + a.push(i); +f.apply(null, a); diff --git a/js/src/jit-test/tests/basic/test-error-accessors-with-wrappers.js b/js/src/jit-test/tests/basic/test-error-accessors-with-wrappers.js new file mode 100644 index 000000000..2afa881f3 --- /dev/null +++ b/js/src/jit-test/tests/basic/test-error-accessors-with-wrappers.js @@ -0,0 +1,11 @@ +let g = newGlobal(); + +let error = g.eval("Error()"); + +// This should not throw. +assertEq(typeof error.stack, "string"); + +g.error = Error(); + +// Nor should this. +assertEq(g.eval("typeof error.stack"), "string"); diff --git a/js/src/jit-test/tests/basic/test-jitinfo.js b/js/src/jit-test/tests/basic/test-jitinfo.js new file mode 100644 index 000000000..389029dd7 --- /dev/null +++ b/js/src/jit-test/tests/basic/test-jitinfo.js @@ -0,0 +1,24 @@ +// Test for the shell's FakeDOMObject constructor. This test +// ensures the fuzzers know about this object. +function f() { + var res = 0; + var d = new FakeDOMObject(); + assertEq(d !== new FakeDOMObject(), true); + + for (var i=0; i<100; i++) { + var x = d.x; + assertEq(typeof x, "number"); + + d.x = 10; + d.x = undefined; + + d.x = FakeDOMObject.prototype.x; + FakeDOMObject.prototype.x = d.x; + FakeDOMObject.prototype.doFoo(); + + assertEq(d.doFoo(), 0); + assertEq(d.doFoo(1), 1); + assertEq(d.doFoo(1, 2), 2); + } +} +f(); diff --git a/js/src/jit-test/tests/basic/test586387.js b/js/src/jit-test/tests/basic/test586387.js new file mode 100644 index 000000000..5ddc2d726 --- /dev/null +++ b/js/src/jit-test/tests/basic/test586387.js @@ -0,0 +1,14 @@ +function testFloatArray() { + var v = new Float32Array(32); + + for (var i = 0; i < v.length; ++i) + v[i] = i; + + var t = 0; + for (var i = 0; i < v.length; ++i) + t += v[i]; + + return t; +} + +assertEq(testFloatArray(), 496); diff --git a/js/src/jit-test/tests/basic/testAbortedImacroDecompilation.js b/js/src/jit-test/tests/basic/testAbortedImacroDecompilation.js new file mode 100644 index 000000000..b1cfdb92d --- /dev/null +++ b/js/src/jit-test/tests/basic/testAbortedImacroDecompilation.js @@ -0,0 +1,7 @@ +function f() { + for (var i=0; i<9; i++) + assertEq("" + f, expected); +} + +var expected = "" + f; +f(); diff --git a/js/src/jit-test/tests/basic/testAccessCanonicalArgInGetElem.js b/js/src/jit-test/tests/basic/testAccessCanonicalArgInGetElem.js new file mode 100644 index 000000000..644072461 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAccessCanonicalArgInGetElem.js @@ -0,0 +1,12 @@ +var o = {x:42}; + +function f(index,param) { + arguments[1] = 0; + var ret = 0; + for (var i = 0; i < 5; ++i) + ret = arguments[index].x; + return ret; +} + +assertEq(f(2,o,o), 42); +assertEq(f(1,o,o), undefined); diff --git a/js/src/jit-test/tests/basic/testAddAnyInconvertibleObject.js b/js/src/jit-test/tests/basic/testAddAnyInconvertibleObject.js new file mode 100644 index 000000000..4a4b1d857 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAddAnyInconvertibleObject.js @@ -0,0 +1,28 @@ +function testAddAnyInconvertibleObject() +{ + var count = 0; + function toString() { ++count; if (count == 95) return {}; return "" + count; } + var o = {valueOf: undefined, toString: toString}; + + var threw = false; + try + { + for (var i = 0; i < 100; i++) + var q = 5 + o; + } + catch (e) + { + threw = true; + if (i !== 94) + return "expected i === 94, got " + i; + if (q !== "594") + return "expected q === '594', got " + q + " (type " + typeof q + ")"; + if (count !== 95) + return "expected count === 95, got " + count; + } + if (!threw) + return "expected throw with 5 + o"; // hey, a rhyme! + + return "pass"; +} +assertEq(testAddAnyInconvertibleObject(), "pass"); diff --git a/js/src/jit-test/tests/basic/testAddInconvertibleObjectAny.js b/js/src/jit-test/tests/basic/testAddInconvertibleObjectAny.js new file mode 100644 index 000000000..aabf8ec57 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAddInconvertibleObjectAny.js @@ -0,0 +1,34 @@ +function testAddInconvertibleObjectAny() +{ + var count = 0; + function toString() + { + ++count; + if (count == 95) + return {}; + return "" + count; + } + var o = {valueOf: undefined, toString: toString}; + + var threw = false; + try + { + for (var i = 0; i < 100; i++) + var q = o + 5; + } + catch (e) + { + threw = true; + if (i !== 94) + return "expected i === 94, got " + i; + if (q !== "945") + return "expected q === '945', got " + q + " (type " + typeof q + ")"; + if (count !== 95) + return "expected count === 95, got " + count; + } + if (!threw) + return "expected throw with o + 5"; + + return "pass"; +} +assertEq(testAddInconvertibleObjectAny(), "pass"); diff --git a/js/src/jit-test/tests/basic/testAddInconvertibleObjectInconvertibleObject.js b/js/src/jit-test/tests/basic/testAddInconvertibleObjectInconvertibleObject.js new file mode 100644 index 000000000..5004dbbe5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAddInconvertibleObjectInconvertibleObject.js @@ -0,0 +1,33 @@ +function testAddInconvertibleObjectInconvertibleObject() +{ + var count1 = 0; + function toString1() { ++count1; if (count1 == 95) return {}; return "" + count1; } + var o1 = {valueOf: undefined, toString: toString1}; + var count2 = 0; + function toString2() { ++count2; if (count2 == 95) return {}; return "" + count2; } + var o2 = {valueOf: undefined, toString: toString2}; + + var threw = false; + try + { + for (var i = 0; i < 100; i++) + var q = o1 + o2; + } + catch (e) + { + threw = true; + if (i !== 94) + return "expected i === 94, got " + i; + if (q !== "9494") + return "expected q === '9494', got " + q + " (type " + typeof q + ")"; + if (count1 !== 95) + return "expected count1 === 95, got " + count1; + if (count2 !== 94) + return "expected count2 === 94, got " + count2; + } + if (!threw) + return "expected throw with o1 + o2"; + + return "pass"; +} +assertEq(testAddInconvertibleObjectInconvertibleObject(), "pass"); diff --git a/js/src/jit-test/tests/basic/testAddNull.js b/js/src/jit-test/tests/basic/testAddNull.js new file mode 100644 index 000000000..78b40a519 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAddNull.js @@ -0,0 +1,8 @@ +function testAddNull() +{ + var rv; + for (var x = 0; x < 9; ++x) + rv = null + [,,]; + return rv; +} +assertEq(testAddNull(), "null,"); diff --git a/js/src/jit-test/tests/basic/testAddUndefined.js b/js/src/jit-test/tests/basic/testAddUndefined.js new file mode 100644 index 000000000..9a21e2f93 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAddUndefined.js @@ -0,0 +1,5 @@ +function testAddUndefined() { + for (var j = 0; j < 3; ++j) + (0 + void 0) && 0; +} +testAddUndefined(); diff --git a/js/src/jit-test/tests/basic/testAliasedLet.js b/js/src/jit-test/tests/basic/testAliasedLet.js new file mode 100644 index 000000000..3ab016999 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAliasedLet.js @@ -0,0 +1,12 @@ +function f() { + { + let x, y, z; + eval('x = 1; y = 2; z = 3'); + for (var i = 0; i < 10000; ++i) { + assertEq(x, 1); + assertEq(y, 2); + assertEq(z, 3); + } + } +} +f(); diff --git a/js/src/jit-test/tests/basic/testApply.js b/js/src/jit-test/tests/basic/testApply.js new file mode 100644 index 000000000..73e359228 --- /dev/null +++ b/js/src/jit-test/tests/basic/testApply.js @@ -0,0 +1,7 @@ +function testApply() { + var q = []; + for (var i = 0; i < 10; ++i) + Array.prototype.push.apply(q, [5]); + return q.join(","); +} +assertEq(testApply(), "5,5,5,5,5,5,5,5,5,5"); diff --git a/js/src/jit-test/tests/basic/testApplyArrayInline.js b/js/src/jit-test/tests/basic/testApplyArrayInline.js new file mode 100644 index 000000000..d39770e19 --- /dev/null +++ b/js/src/jit-test/tests/basic/testApplyArrayInline.js @@ -0,0 +1,72 @@ +// Test inlining in Ion of fun.apply(..., array). + +if (!this.getJitCompilerOptions() || !getJitCompilerOptions()['ion.enable']) + quit(0); + +var itercount = 1000; +var warmup = 100; + +// Force Ion to do something predictable without having to wait +// forever for it. + +if (getJitCompilerOptions()["ion.warmup.trigger"] > warmup) + setJitCompilerOption("ion.warmup.trigger", warmup); + +setJitCompilerOption("offthread-compilation.enable", 0); + +function g(a, b, c, d) { + return a + b + c + (d === undefined); +} + +var g_inIonInLoop = false; +var g_inIonAtEnd = false; + +function f(xs) { + var sum = 0; + var inIonInLoop = 0; + for ( var i=0 ; i < itercount ; i++ ) { + inIonInLoop |= inIon(); + sum += g.apply(null, xs); + } + g_ionAtEnd = inIon(); + g_inIonInLoop = !!inIonInLoop; + return sum; +} + +// Basic test + +assertEq(f([1,2,3,4]), 6*itercount); + +// Attempt to detect a botched optimization: either we ion-compiled +// the loop, or we did not ion-compile the function (ion not actually +// effective at all, this can happen). + +assertEq(g_inIonInLoop || !g_inIonAtEnd, true); + +// If Ion is inert just leave. + +if (!g_inIonInLoop) { + print("Leaving early - ion not kicking in at all"); + quit(0); +} + +// Test that we get the correct argument value even if the array has +// fewer initialized members than its length. + +var headroom = [1,2,3]; +headroom.length = 13; +assertEq(f(headroom), 7*itercount); + +// Test that we throw when the array is too long. + +var thrown = false; +try { + var long = []; + long.length = getMaxArgs() + 1; + f(long); +} +catch (e) { + thrown = true; + assertEq(e instanceof RangeError, true); +} +assertEq(thrown, true); diff --git a/js/src/jit-test/tests/basic/testApplyAtJoinPoint.js b/js/src/jit-test/tests/basic/testApplyAtJoinPoint.js new file mode 100644 index 000000000..bb7f219ab --- /dev/null +++ b/js/src/jit-test/tests/basic/testApplyAtJoinPoint.js @@ -0,0 +1,12 @@ +var isTrue = true; + +function g(x) { + return x; +} + +function f() { + return g.apply(null, isTrue ? ["happy"] : arguments); +} + +for (var i = 0; i < 18; ++i) + assertEq(f("sad"), "happy"); diff --git a/js/src/jit-test/tests/basic/testApplyCall.js b/js/src/jit-test/tests/basic/testApplyCall.js new file mode 100644 index 000000000..0afe2ff7c --- /dev/null +++ b/js/src/jit-test/tests/basic/testApplyCall.js @@ -0,0 +1,42 @@ +function testApplyCallHelper(f) { + var r = []; + for (var i = 0; i < 10; ++i) f.call(); + r.push(x); + for (var i = 0; i < 10; ++i) f.call(this); + r.push(x); + for (var i = 0; i < 10; ++i) f.apply(this); + r.push(x); + for (var i = 0; i < 10; ++i) f.call(this,0); + r.push(x); + for (var i = 0; i < 10; ++i) f.apply(this,[0]); + r.push(x); + for (var i = 0; i < 10; ++i) f.call(this,0,1); + r.push(x); + for (var i = 0; i < 10; ++i) f.apply(this,[0,1]); + r.push(x); + for (var i = 0; i < 10; ++i) f.call(this,0,1,2); + r.push(x); + for (var i = 0; i < 10; ++i) f.apply(this,[0,1,2]); + r.push(x); + for (var i = 0; i < 10; ++i) f.call(this,0,1,2,3); + r.push(x); + for (var i = 0; i < 10; ++i) f.apply(this,[0,1,2,3]); + r.push(x); + for (var i = 0; i < 10; ++i) f.call(this,0,1,2,3,4); + r.push(x); + for (var i = 0; i < 10; ++i) f.apply(this,[0,1,2,3,4]); + r.push(x); + for (var i = 0; i < 10; ++i) f.call(this,0,1,2,3,4,5); + r.push(x); + for (var i = 0; i < 10; ++i) f.apply(this,[0,1,2,3,4,5]) + r.push(x); + return(r.join(",")); +} +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(function (a0,a1,a2,a3,a4,a5,a6,a7) { x = [a0,a1,a2,a3,a4,a5,a6,a7]; }); + return r; +} + +assertEq(testApplyCall(), ",,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,0,,,,,,,,0,1,,,,,,,0,1,,,,,,,0,1,2,,,,,,0,1,2,,,,,,0,1,2,3,,,,,0,1,2,3,,,,,0,1,2,3,4,,,,0,1,2,3,4,,,,0,1,2,3,4,5,,,0,1,2,3,4,5,," + +",,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,,0,,,,,,,,0,1,,,,,,,0,1,,,,,,,0,1,2,,,,,,0,1,2,,,,,,0,1,2,3,,,,,0,1,2,3,,,,,0,1,2,3,4,,,,0,1,2,3,4,,,,0,1,2,3,4,5,,,0,1,2,3,4,5,,"); diff --git a/js/src/jit-test/tests/basic/testApplyInterpretLowered.js b/js/src/jit-test/tests/basic/testApplyInterpretLowered.js new file mode 100644 index 000000000..e35659f9e --- /dev/null +++ b/js/src/jit-test/tests/basic/testApplyInterpretLowered.js @@ -0,0 +1,15 @@ + +/* Read correct return value when the interpreter pops a lowered call/apply. */ + +function recompile() {} + +function foo() { + if (arguments[0] == 9) + recompile(); + return arguments[0]; +} +function bar() { + for (var i = 0; i < 10; i++) + assertEq(foo.apply(null, [i]), i); +} +bar(); diff --git a/js/src/jit-test/tests/basic/testApplyInterpretLowered2.js b/js/src/jit-test/tests/basic/testApplyInterpretLowered2.js new file mode 100644 index 000000000..0564ead0b --- /dev/null +++ b/js/src/jit-test/tests/basic/testApplyInterpretLowered2.js @@ -0,0 +1,12 @@ + +/* Make sure the interpreter can pop lowered frames pushed by CompileFunction. */ + +function recompile() {} + +function bar() { + for (var i = 0; i < 50; i++) { + var foo = new Function("recompile(arguments[0] + " + i + "); return arguments[0]"); + assertEq(foo.apply(null, [i]), i); + } +} +bar(); diff --git a/js/src/jit-test/tests/basic/testApplySpeculationFailInCompiler.js b/js/src/jit-test/tests/basic/testApplySpeculationFailInCompiler.js new file mode 100644 index 000000000..8a79a5cf5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testApplySpeculationFailInCompiler.js @@ -0,0 +1,6 @@ +function baz(i) { return i } +function bar(x, y) { return baz.apply(null, x ? y : arguments) } +var s; +for (var i = 0; i < 1000; ++i) + s = bar(true, [42]); +assertEq(s, 42); diff --git a/js/src/jit-test/tests/basic/testApplyUnbox.js b/js/src/jit-test/tests/basic/testApplyUnbox.js new file mode 100644 index 000000000..5336ace07 --- /dev/null +++ b/js/src/jit-test/tests/basic/testApplyUnbox.js @@ -0,0 +1,11 @@ +function testApplyUnboxHelper(f,a) { + var q; + for (var i = 0; i < 10; ++i) + q = f.apply(f,a); + return q; +} +function testApplyUnbox() { + var f = function(x) { return x; } + return [testApplyUnboxHelper(f,[1]), testApplyUnboxHelper(f,[true])].join(","); +} +assertEq(testApplyUnbox(), "1,true"); diff --git a/js/src/jit-test/tests/basic/testArgumentsOptimizationFailCornerCase.js b/js/src/jit-test/tests/basic/testArgumentsOptimizationFailCornerCase.js new file mode 100644 index 000000000..90f4f11c9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testArgumentsOptimizationFailCornerCase.js @@ -0,0 +1,23 @@ +Object.prototype.blah = 42; + +function g(a,b,c) { + assertEq(a, 1); + assertEq(b, 2); + assertEq(c, 3); + return 43; +} + +function f() { + var a = arguments; + var b = a; + var s = "blah"; + assertEq(a[s], 42); + assertEq(b[s], 42); + assertEq(a[s], 42); + assertEq(b.length, 3); + assertEq(a.length, 3); + assertEq(g.apply(null, b), 43); +} + +for (var i = 0; i < 10; ++i) + f(1,2,3); diff --git a/js/src/jit-test/tests/basic/testArgumentsPropLookup.js b/js/src/jit-test/tests/basic/testArgumentsPropLookup.js new file mode 100644 index 000000000..6e8a4cda7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testArgumentsPropLookup.js @@ -0,0 +1,19 @@ +(function() { + var s = "__proto__"; + assertEq(arguments[s], Object.prototype); +})(); + +Object.defineProperty(Object.prototype, "foo", { + get:function() { + this.bar = 42; + return 41 + } +}); + +(function() { + var s = "foo"; + assertEq(arguments[s], 41); + s = "bar"; + assertEq(arguments[s], 42); + assertEq("bar" in Object.prototype, false); +})(); diff --git a/js/src/jit-test/tests/basic/testArrayBufferSlice.js b/js/src/jit-test/tests/basic/testArrayBufferSlice.js new file mode 100644 index 000000000..3b1f353de --- /dev/null +++ b/js/src/jit-test/tests/basic/testArrayBufferSlice.js @@ -0,0 +1,57 @@ +function testSlice() { + function test(subBuf, starts, size) { + var byteLength = size; + var subBuffer = eval(subBuf); + var subArray = new Int8Array(subBuffer); + assertEq(subBuffer.byteLength, byteLength); + for (var i = 0; i < size; ++i) + assertEq(starts + i, subArray[i]); + } + + var buffer = new ArrayBuffer(32); + var array = new Int8Array(buffer); + for (var i = 0; i < 32; ++i) + array[i] = i; + + test("buffer.slice(0)", 0, 32); + test("buffer.slice(16)", 16, 16); + test("buffer.slice(24)", 24, 8); + test("buffer.slice(32)", 32, 0); + test("buffer.slice(40)", 32, 0); + test("buffer.slice(80)", 32, 0); + + test("buffer.slice(-8)", 24, 8); + test("buffer.slice(-16)", 16, 16); + test("buffer.slice(-24)", 8, 24); + test("buffer.slice(-32)", 0, 32); + test("buffer.slice(-40)", 0, 32); + test("buffer.slice(-80)", 0, 32); + + test("buffer.slice(0, 32)", 0, 32); + test("buffer.slice(0, 16)", 0, 16); + test("buffer.slice(8, 24)", 8, 16); + test("buffer.slice(16, 32)", 16, 16); + test("buffer.slice(24, 16)", 24, 0); + + test("buffer.slice(16, -8)", 16, 8); + test("buffer.slice(-20, 30)", 12, 18); + + test("buffer.slice(-8, -20)", 24, 0); + test("buffer.slice(-20, -8)", 12, 12); + test("buffer.slice(-40, 16)", 0, 16); + test("buffer.slice(-40, 40)", 0, 32); + + gczeal(7, 100000); + var nurseryBuf = new ArrayBuffer(32); + var arr = new Int8Array(nurseryBuf); + arr[0] = 77; + + // tenure nurseryBuf during the slice operation + nurseryBuf.slice; // Creates an object + schedulegc(1); + var newbuf = nurseryBuf.slice(0); + var arr2 = new Int8Array(newbuf); + assertEq(arr2[0], 77); +} + +testSlice(); diff --git a/js/src/jit-test/tests/basic/testArrayBufferSpeciesDelete.js b/js/src/jit-test/tests/basic/testArrayBufferSpeciesDelete.js new file mode 100644 index 000000000..02e515d32 --- /dev/null +++ b/js/src/jit-test/tests/basic/testArrayBufferSpeciesDelete.js @@ -0,0 +1,5 @@ +delete ArrayBuffer[Symbol.species]; +var a = new Uint8Array(new Uint8Array([1, 2])); +assertEq(a.length, 2); +assertEq(a[0], 1); +assertEq(a[1], 2); diff --git a/js/src/jit-test/tests/basic/testArrayConcat.js b/js/src/jit-test/tests/basic/testArrayConcat.js new file mode 100644 index 000000000..ec29e4353 --- /dev/null +++ b/js/src/jit-test/tests/basic/testArrayConcat.js @@ -0,0 +1,10 @@ + +var x = Array(4); +x[0] = 1; +x[1] = 2; +x[2] = 3; +var y = x.concat(); +assertEq(y[3], undefined); + +var z = x.concat(/abc/).pop(); +assertEq(z.source, "abc"); diff --git a/js/src/jit-test/tests/basic/testArrayDensityChange.js b/js/src/jit-test/tests/basic/testArrayDensityChange.js new file mode 100644 index 000000000..b9dfabad1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testArrayDensityChange.js @@ -0,0 +1,17 @@ +function testArrayDensityChange() { + var x = []; + var count = 0; + for (var i=0; i < 100; ++i) { + x[i] = "asdf"; + } + for (var i=0; i < x.length; ++i) { + if (i == 51) + { + x[199] = "asdf"; + } + if (x[i]) + count += x[i].length; + } + return count; +} +assertEq(testArrayDensityChange(), 404); diff --git a/js/src/jit-test/tests/basic/testArrayInWithIndexedProto.js b/js/src/jit-test/tests/basic/testArrayInWithIndexedProto.js new file mode 100644 index 000000000..97da0ee07 --- /dev/null +++ b/js/src/jit-test/tests/basic/testArrayInWithIndexedProto.js @@ -0,0 +1,24 @@ +function testArrayInWithIndexedProto() +{ + Array.prototype[0] = "Got me"; + var zeroPresent, zeroPresent2; + // Need to go to 18 because in the failure mode this is + // testing we have various side-exits in there due to interp and + // tracer not agreeing that confuse the issue and cause us to not + // hit the bad case within 9 iterations. + for (var j = 0; j < 18; ++j) { + zeroPresent = 0 in []; + } + + var arr = [1, 2]; + delete arr[0]; + for (var j = 0; j < 18; ++j) { + zeroPresent2 = 0 in arr; + } + return [zeroPresent, zeroPresent2]; +} + +var [ret, ret2] = testArrayInWithIndexedProto(); +assertEq(ret, true); +assertEq(ret2, true); + diff --git a/js/src/jit-test/tests/basic/testArrayNaNIndex.js b/js/src/jit-test/tests/basic/testArrayNaNIndex.js new file mode 100644 index 000000000..671f6ff8f --- /dev/null +++ b/js/src/jit-test/tests/basic/testArrayNaNIndex.js @@ -0,0 +1,7 @@ +function testArrayNaNIndex() +{ + for (var j = 0; j < 4; ++j) { [this[NaN]]; } + for (var j = 0; j < 5; ++j) { if([1][-0]) { } } + return "ok"; +} +assertEq(testArrayNaNIndex(), "ok"); diff --git a/js/src/jit-test/tests/basic/testArrayNamedProp.js b/js/src/jit-test/tests/basic/testArrayNamedProp.js new file mode 100644 index 000000000..7357412dd --- /dev/null +++ b/js/src/jit-test/tests/basic/testArrayNamedProp.js @@ -0,0 +1,5 @@ +function testArrayNamedProp() { + for (var x = 0; x < 10; ++x) { [4].sort-- } + return "ok"; +} +assertEq(testArrayNamedProp(), "ok"); diff --git a/js/src/jit-test/tests/basic/testArrayPushPop.js b/js/src/jit-test/tests/basic/testArrayPushPop.js new file mode 100644 index 000000000..8e00dad23 --- /dev/null +++ b/js/src/jit-test/tests/basic/testArrayPushPop.js @@ -0,0 +1,11 @@ +function testArrayPushPop() { + var a = [], sum1 = 0, sum2 = 0; + for (var i = 0; i < 10; ++i) + sum1 += a.push(i); + for (var i = 0; i < 10; ++i) + sum2 += a.pop(); + a.push(sum1); + a.push(sum2); + return a.join(","); +} +assertEq(testArrayPushPop(), "55,45"); diff --git a/js/src/jit-test/tests/basic/testArraySpeciesDelete.js b/js/src/jit-test/tests/basic/testArraySpeciesDelete.js new file mode 100644 index 000000000..8677d2254 --- /dev/null +++ b/js/src/jit-test/tests/basic/testArraySpeciesDelete.js @@ -0,0 +1,5 @@ +delete Array[Symbol.species]; +var a = [1, 2, 3].slice(1); +assertEq(a.length, 2); +assertEq(a[0], 2); +assertEq(a[1], 3); diff --git a/js/src/jit-test/tests/basic/testAssigningWatchedDeletedProperty.js b/js/src/jit-test/tests/basic/testAssigningWatchedDeletedProperty.js new file mode 100644 index 000000000..c22eabed0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAssigningWatchedDeletedProperty.js @@ -0,0 +1,7 @@ +var o = {}; +o.watch("p", function() { }); + +for (var i = 0; i < 10; i++) { + o.p = 123; + delete o.p; +} diff --git a/js/src/jit-test/tests/basic/testAssignmentThatIgnoresSetterRetval.js b/js/src/jit-test/tests/basic/testAssignmentThatIgnoresSetterRetval.js new file mode 100644 index 000000000..1c5911348 --- /dev/null +++ b/js/src/jit-test/tests/basic/testAssignmentThatIgnoresSetterRetval.js @@ -0,0 +1,10 @@ +var o = { + set x(v) { + return 42; + } +}; + +for (var i = 0; i < 10; ++i) { + var z = o.x = "choose me"; + assertEq(z, "choose me"); +} diff --git a/js/src/jit-test/tests/basic/testAtomize.js b/js/src/jit-test/tests/basic/testAtomize.js new file mode 100644 index 000000000..16076eb6b --- /dev/null +++ b/js/src/jit-test/tests/basic/testAtomize.js @@ -0,0 +1,10 @@ +function testAtomize() { + x = {}; + for (var i = 0; i < 65536; ++i) + x[String.fromCharCode(i)] = 1; + var z = 0; + for (var p in x) + ++z; + return z; +} +assertEq(testAtomize(), 65536) diff --git a/js/src/jit-test/tests/basic/testBitOrAnyInconvertibleObject.js b/js/src/jit-test/tests/basic/testBitOrAnyInconvertibleObject.js new file mode 100644 index 000000000..d3daadbea --- /dev/null +++ b/js/src/jit-test/tests/basic/testBitOrAnyInconvertibleObject.js @@ -0,0 +1,28 @@ +function testBitOrAnyInconvertibleObject() +{ + var count = 0; + function toString() { ++count; if (count == 95) return {}; return count; } + var o = {valueOf: undefined, toString: toString}; + + var threw = false; + try + { + for (var i = 0; i < 100; i++) + var q = 1 | o; + } + catch (e) + { + threw = true; + if (i !== 94) + return "expected i === 94, got " + i; + if (q !== 95) + return "expected q === 95, got " + q; + if (count !== 95) + return "expected count === 95, got " + count; + } + if (!threw) + return "expected throw with 2 | o"; // hey, a rhyme! + + return "pass"; +} +assertEq(testBitOrAnyInconvertibleObject(), "pass"); diff --git a/js/src/jit-test/tests/basic/testBitOrInconvertibleObjectAny.js b/js/src/jit-test/tests/basic/testBitOrInconvertibleObjectAny.js new file mode 100644 index 000000000..29d983ab0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBitOrInconvertibleObjectAny.js @@ -0,0 +1,28 @@ +function testBitOrInconvertibleObjectAny() +{ + var count = 0; + function toString() { ++count; if (count == 95) return {}; return count; } + var o = {valueOf: undefined, toString: toString}; + + var threw = false; + try + { + for (var i = 0; i < 100; i++) + var q = o | 1; + } + catch (e) + { + threw = true; + if (i !== 94) + return "expected i === 94, got " + i; + if (q !== 95) + return "expected q === 95, got " + q; + if (count !== 95) + return "expected count === 95, got " + count; + } + if (!threw) + return "expected throw with o | 2"; + + return "pass"; +} +assertEq(testBitOrInconvertibleObjectAny(), "pass"); diff --git a/js/src/jit-test/tests/basic/testBitOrInconvertibleObjectInconvertibleObject.js b/js/src/jit-test/tests/basic/testBitOrInconvertibleObjectInconvertibleObject.js new file mode 100644 index 000000000..420b431ea --- /dev/null +++ b/js/src/jit-test/tests/basic/testBitOrInconvertibleObjectInconvertibleObject.js @@ -0,0 +1,33 @@ +function testBitOrInconvertibleObjectInconvertibleObject() +{ + var count1 = 0; + function toString1() { ++count1; if (count1 == 95) return {}; return count1; } + var o1 = {valueOf: undefined, toString: toString1}; + var count2 = 0; + function toString2() { ++count2; if (count2 == 95) return {}; return count2; } + var o2 = {valueOf: undefined, toString: toString2}; + + var threw = false; + try + { + for (var i = 0; i < 100; i++) + var q = o1 | o2; + } + catch (e) + { + threw = true; + if (i !== 94) + return "expected i === 94, got " + i; + if (q !== 94) + return "expected q === 94, got " + q; + if (count1 !== 95) + return "expected count1 === 95, got " + count1; + if (count2 !== 94) + return "expected count2 === 94, got " + count2; + } + if (!threw) + return "expected throw with o1 | o2"; + + return "pass"; +} +assertEq(testBitOrInconvertibleObjectInconvertibleObject(), "pass"); diff --git a/js/src/jit-test/tests/basic/testBitopWithConstan.js b/js/src/jit-test/tests/basic/testBitopWithConstan.js new file mode 100644 index 000000000..494994d7f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBitopWithConstan.js @@ -0,0 +1,741 @@ +function test1 (x) {
+ assertEq(x | -1, -1);
+ assertEq(-1 | x, -1);
+ assertEq(x & -1, 1);
+ assertEq(-1 & x, 1);
+ assertEq(x ^ -1, -2);
+ assertEq(-1 ^ x, -2);
+ assertEq(x >> -1, 0);
+ assertEq(-1 >> x, -1);
+ assertEq(x >>> -1, 0);
+ assertEq(-1 >>> x, 2147483647);
+ assertEq(x << -1, -2147483648);
+ assertEq(-1 << x, -2);
+ assertEq(x | 1, 1);
+ assertEq(1 | x, 1);
+ assertEq(x & 1, 1);
+ assertEq(1 & x, 1);
+ assertEq(x ^ 1, 0);
+ assertEq(1 ^ x, 0);
+ assertEq(x >> 1, 0);
+ assertEq(1 >> x, 0);
+ assertEq(x >>> 1, 0);
+ assertEq(1 >>> x, 0);
+ assertEq(x << 1, 2);
+ assertEq(1 << x, 2);
+ assertEq(x | 0, 1);
+ assertEq(0 | x, 1);
+ assertEq(x & 0, 0);
+ assertEq(0 & x, 0);
+ assertEq(x ^ 0, 1);
+ assertEq(0 ^ x, 1);
+ assertEq(x >> 0, 1);
+ assertEq(0 >> x, 0);
+ assertEq(x >>> 0, 1);
+ assertEq(0 >>> x, 0);
+ assertEq(x << 0, 1);
+ assertEq(0 << x, 0);
+ assertEq(x | 0xffffffff, -1);
+ assertEq(0xffffffff | x, -1);
+ assertEq(x & 0xffffffff, 1);
+ assertEq(0xffffffff & x, 1);
+ assertEq(x ^ 0xffffffff, -2);
+ assertEq(0xffffffff ^ x, -2);
+ assertEq(x >> 0xffffffff, 0);
+ assertEq(0xffffffff >> x, -1);
+ assertEq(x >>> 0xffffffff, 0);
+ assertEq(0xffffffff >>> x, 2147483647);
+ assertEq(x << 0xffffffff, -2147483648);
+ assertEq(0xffffffff << x, -2);
+ assertEq(x | "10.6", 11);
+ assertEq("10.6" | x, 11);
+ assertEq(x & "10.6", 0);
+ assertEq("10.6" & x, 0);
+ assertEq(x ^ "10.6", 11);
+ assertEq("10.6" ^ x, 11);
+ assertEq(x >> "10.6", 0);
+ assertEq("10.6" >> x, 5);
+ assertEq(x >>> "10.6", 0);
+ assertEq("10.6" >>> x, 5);
+ assertEq(x << "10.6", 1024);
+ assertEq("10.6" << x, 20);
+ assertEq(x | 2147483648, -2147483647);
+ assertEq(2147483648 | x, -2147483647);
+ assertEq(x & 2147483648, 0);
+ assertEq(2147483648 & x, 0);
+ assertEq(x ^ 2147483648, -2147483647);
+ assertEq(2147483648 ^ x, -2147483647);
+ assertEq(x >> 2147483648, 1);
+ assertEq(2147483648 >> x, -1073741824);
+ assertEq(x >>> 2147483648, 1);
+ assertEq(2147483648 >>> x, 1073741824);
+ assertEq(x << 2147483648, 1);
+ assertEq(2147483648 << x, 0);
+ assertEq(x | 4294967296, 1);
+ assertEq(4294967296 | x, 1);
+ assertEq(x & 4294967296, 0);
+ assertEq(4294967296 & x, 0);
+ assertEq(x ^ 4294967296, 1);
+ assertEq(4294967296 ^ x, 1);
+ assertEq(x >> 4294967296, 1);
+ assertEq(4294967296 >> x, 0);
+ assertEq(x >>> 4294967296, 1);
+ assertEq(4294967296 >>> x, 0);
+ assertEq(x << 4294967296, 1);
+ assertEq(4294967296 << x, 0);
+ assertEq(x | undefined, 1);
+ assertEq(undefined | x, 1);
+ assertEq(x & undefined, 0);
+ assertEq(undefined & x, 0);
+ assertEq(x ^ undefined, 1);
+ assertEq(undefined ^ x, 1);
+ assertEq(x >> undefined, 1);
+ assertEq(undefined >> x, 0);
+ assertEq(x >>> undefined, 1);
+ assertEq(undefined >>> x, 0);
+ assertEq(x << undefined, 1);
+ assertEq(undefined << x, 0);
+ assertEq(x | null, 1);
+ assertEq(null | x, 1);
+ assertEq(x & null, 0);
+ assertEq(null & x, 0);
+ assertEq(x ^ null, 1);
+ assertEq(null ^ x, 1);
+ assertEq(x >> null, 1);
+ assertEq(null >> x, 0);
+ assertEq(x >>> null, 1);
+ assertEq(null >>> x, 0);
+ assertEq(x << null, 1);
+ assertEq(null << x, 0);
+ assertEq(x | false, 1);
+ assertEq(false | x, 1);
+ assertEq(x & false, 0);
+ assertEq(false & x, 0);
+ assertEq(x ^ false, 1);
+ assertEq(false ^ x, 1);
+ assertEq(x >> false, 1);
+ assertEq(false >> x, 0);
+ assertEq(x >>> false, 1);
+ assertEq(false >>> x, 0);
+ assertEq(x << false, 1);
+ assertEq(false << x, 0);
+ assertEq(x | true, 1);
+ assertEq(true | x, 1);
+ assertEq(x & true, 1);
+ assertEq(true & x, 1);
+ assertEq(x ^ true, 0);
+ assertEq(true ^ x, 0);
+ assertEq(x >> true, 0);
+ assertEq(true >> x, 0);
+ assertEq(x >>> true, 0);
+ assertEq(true >>> x, 0);
+ assertEq(x << true, 2);
+ assertEq(true << x, 2);
+ assertEq(x | -1.5, -1);
+ assertEq(-1.5 | x, -1);
+ assertEq(x & -1.5, 1);
+ assertEq(-1.5 & x, 1);
+ assertEq(x ^ -1.5, -2);
+ assertEq(-1.5 ^ x, -2);
+ assertEq(x >> -1.5, 0);
+ assertEq(-1.5 >> x, -1);
+ assertEq(x >>> -1.5, 0);
+ assertEq(-1.5 >>> x, 2147483647);
+ assertEq(x << -1.5, -2147483648);
+ assertEq(-1.5 << x, -2);
+}
+test1(1)
+
+function test2 (x) {
+ assertEq(x | -1, -1);
+ assertEq(-1 | x, -1);
+ assertEq(x & -1, 0);
+ assertEq(-1 & x, 0);
+ assertEq(x ^ -1, -1);
+ assertEq(-1 ^ x, -1);
+ assertEq(x >> -1, 0);
+ assertEq(-1 >> x, -1);
+ assertEq(x >>> -1, 0);
+ assertEq(-1 >>> x, 4294967295);
+ assertEq(x << -1, 0);
+ assertEq(-1 << x, -1);
+ assertEq(x | 1, 1);
+ assertEq(1 | x, 1);
+ assertEq(x & 1, 0);
+ assertEq(1 & x, 0);
+ assertEq(x ^ 1, 1);
+ assertEq(1 ^ x, 1);
+ assertEq(x >> 1, 0);
+ assertEq(1 >> x, 1);
+ assertEq(x >>> 1, 0);
+ assertEq(1 >>> x, 1);
+ assertEq(x << 1, 0);
+ assertEq(1 << x, 1);
+ assertEq(x | 0, 0);
+ assertEq(0 | x, 0);
+ assertEq(x & 0, 0);
+ assertEq(0 & x, 0);
+ assertEq(x ^ 0, 0);
+ assertEq(0 ^ x, 0);
+ assertEq(x >> 0, 0);
+ assertEq(0 >> x, 0);
+ assertEq(x >>> 0, 0);
+ assertEq(0 >>> x, 0);
+ assertEq(x << 0, 0);
+ assertEq(0 << x, 0);
+ assertEq(x | 0xffffffff, -1);
+ assertEq(0xffffffff | x, -1);
+ assertEq(x & 0xffffffff, 0);
+ assertEq(0xffffffff & x, 0);
+ assertEq(x ^ 0xffffffff, -1);
+ assertEq(0xffffffff ^ x, -1);
+ assertEq(x >> 0xffffffff, 0);
+ assertEq(0xffffffff >> x, -1);
+ assertEq(x >>> 0xffffffff, 0);
+ assertEq(0xffffffff >>> x, 4294967295);
+ assertEq(x << 0xffffffff, 0);
+ assertEq(0xffffffff << x, -1);
+ assertEq(x | "10.6", 10);
+ assertEq("10.6" | x, 10);
+ assertEq(x & "10.6", 0);
+ assertEq("10.6" & x, 0);
+ assertEq(x ^ "10.6", 10);
+ assertEq("10.6" ^ x, 10);
+ assertEq(x >> "10.6", 0);
+ assertEq("10.6" >> x, 10);
+ assertEq(x >>> "10.6", 0);
+ assertEq("10.6" >>> x, 10);
+ assertEq(x << "10.6", 0);
+ assertEq("10.6" << x, 10);
+ assertEq(x | 2147483648, -2147483648);
+ assertEq(2147483648 | x, -2147483648);
+ assertEq(x & 2147483648, 0);
+ assertEq(2147483648 & x, 0);
+ assertEq(x ^ 2147483648, -2147483648);
+ assertEq(2147483648 ^ x, -2147483648);
+ assertEq(x >> 2147483648, 0);
+ assertEq(2147483648 >> x, -2147483648);
+ assertEq(x >>> 2147483648, 0);
+ assertEq(2147483648 >>> x, 2147483648);
+ assertEq(x << 2147483648, 0);
+ assertEq(2147483648 << x, -2147483648);
+ assertEq(x | 4294967296, 0);
+ assertEq(4294967296 | x, 0);
+ assertEq(x & 4294967296, 0);
+ assertEq(4294967296 & x, 0);
+ assertEq(x ^ 4294967296, 0);
+ assertEq(4294967296 ^ x, 0);
+ assertEq(x >> 4294967296, 0);
+ assertEq(4294967296 >> x, 0);
+ assertEq(x >>> 4294967296, 0);
+ assertEq(4294967296 >>> x, 0);
+ assertEq(x << 4294967296, 0);
+ assertEq(4294967296 << x, 0);
+ assertEq(x | undefined, 0);
+ assertEq(undefined | x, 0);
+ assertEq(x & undefined, 0);
+ assertEq(undefined & x, 0);
+ assertEq(x ^ undefined, 0);
+ assertEq(undefined ^ x, 0);
+ assertEq(x >> undefined, 0);
+ assertEq(undefined >> x, 0);
+ assertEq(x >>> undefined, 0);
+ assertEq(undefined >>> x, 0);
+ assertEq(x << undefined, 0);
+ assertEq(undefined << x, 0);
+ assertEq(x | null, 0);
+ assertEq(null | x, 0);
+ assertEq(x & null, 0);
+ assertEq(null & x, 0);
+ assertEq(x ^ null, 0);
+ assertEq(null ^ x, 0);
+ assertEq(x >> null, 0);
+ assertEq(null >> x, 0);
+ assertEq(x >>> null, 0);
+ assertEq(null >>> x, 0);
+ assertEq(x << null, 0);
+ assertEq(null << x, 0);
+ assertEq(x | false, 0);
+ assertEq(false | x, 0);
+ assertEq(x & false, 0);
+ assertEq(false & x, 0);
+ assertEq(x ^ false, 0);
+ assertEq(false ^ x, 0);
+ assertEq(x >> false, 0);
+ assertEq(false >> x, 0);
+ assertEq(x >>> false, 0);
+ assertEq(false >>> x, 0);
+ assertEq(x << false, 0);
+ assertEq(false << x, 0);
+ assertEq(x | true, 1);
+ assertEq(true | x, 1);
+ assertEq(x & true, 0);
+ assertEq(true & x, 0);
+ assertEq(x ^ true, 1);
+ assertEq(true ^ x, 1);
+ assertEq(x >> true, 0);
+ assertEq(true >> x, 1);
+ assertEq(x >>> true, 0);
+ assertEq(true >>> x, 1);
+ assertEq(x << true, 0);
+ assertEq(true << x, 1);
+ assertEq(x | -1.5, -1);
+ assertEq(-1.5 | x, -1);
+ assertEq(x & -1.5, 0);
+ assertEq(-1.5 & x, 0);
+ assertEq(x ^ -1.5, -1);
+ assertEq(-1.5 ^ x, -1);
+ assertEq(x >> -1.5, 0);
+ assertEq(-1.5 >> x, -1);
+ assertEq(x >>> -1.5, 0);
+ assertEq(-1.5 >>> x, 4294967295);
+ assertEq(x << -1.5, 0);
+ assertEq(-1.5 << x, -1);
+}
+test2(0)
+
+function test3 (x) {
+ assertEq(x | -1, -1);
+ assertEq(-1 | x, -1);
+ assertEq(x & -1, -1);
+ assertEq(-1 & x, -1);
+ assertEq(x ^ -1, 0);
+ assertEq(-1 ^ x, 0);
+ assertEq(x >> -1, -1);
+ assertEq(-1 >> x, -1);
+ assertEq(x >>> -1, 1);
+ assertEq(-1 >>> x, 1);
+ assertEq(x << -1, -2147483648);
+ assertEq(-1 << x, -2147483648);
+ assertEq(x | 1, -1);
+ assertEq(1 | x, -1);
+ assertEq(x & 1, 1);
+ assertEq(1 & x, 1);
+ assertEq(x ^ 1, -2);
+ assertEq(1 ^ x, -2);
+ assertEq(x >> 1, -1);
+ assertEq(1 >> x, 0);
+ assertEq(x >>> 1, 2147483647);
+ assertEq(1 >>> x, 0);
+ assertEq(x << 1, -2);
+ assertEq(1 << x, -2147483648);
+ assertEq(x | 0, -1);
+ assertEq(0 | x, -1);
+ assertEq(x & 0, 0);
+ assertEq(0 & x, 0);
+ assertEq(x ^ 0, -1);
+ assertEq(0 ^ x, -1);
+ assertEq(x >> 0, -1);
+ assertEq(0 >> x, 0);
+ assertEq(x >>> 0, 4294967295);
+ assertEq(0 >>> x, 0);
+ assertEq(x << 0, -1);
+ assertEq(0 << x, 0);
+ assertEq(x | 0xffffffff, -1);
+ assertEq(0xffffffff | x, -1);
+ assertEq(x & 0xffffffff, -1);
+ assertEq(0xffffffff & x, -1);
+ assertEq(x ^ 0xffffffff, 0);
+ assertEq(0xffffffff ^ x, 0);
+ assertEq(x >> 0xffffffff, -1);
+ assertEq(0xffffffff >> x, -1);
+ assertEq(x >>> 0xffffffff, 1);
+ assertEq(0xffffffff >>> x, 1);
+ assertEq(x << 0xffffffff, -2147483648);
+ assertEq(0xffffffff << x, -2147483648);
+ assertEq(x | "10.6", -1);
+ assertEq("10.6" | x, -1);
+ assertEq(x & "10.6", 10);
+ assertEq("10.6" & x, 10);
+ assertEq(x ^ "10.6", -11);
+ assertEq("10.6" ^ x, -11);
+ assertEq(x >> "10.6", -1);
+ assertEq("10.6" >> x, 0);
+ assertEq(x >>> "10.6", 4194303);
+ assertEq("10.6" >>> x, 0);
+ assertEq(x << "10.6", -1024);
+ assertEq("10.6" << x, 0);
+ assertEq(x | 2147483648, -1);
+ assertEq(2147483648 | x, -1);
+ assertEq(x & 2147483648, -2147483648);
+ assertEq(2147483648 & x, -2147483648);
+ assertEq(x ^ 2147483648, 2147483647);
+ assertEq(2147483648 ^ x, 2147483647);
+ assertEq(x >> 2147483648, -1);
+ assertEq(2147483648 >> x, -1);
+ assertEq(x >>> 2147483648, 4294967295);
+ assertEq(2147483648 >>> x, 1);
+ assertEq(x << 2147483648, -1);
+ assertEq(2147483648 << x, 0);
+ assertEq(x | 4294967296, -1);
+ assertEq(4294967296 | x, -1);
+ assertEq(x & 4294967296, 0);
+ assertEq(4294967296 & x, 0);
+ assertEq(x ^ 4294967296, -1);
+ assertEq(4294967296 ^ x, -1);
+ assertEq(x >> 4294967296, -1);
+ assertEq(4294967296 >> x, 0);
+ assertEq(x >>> 4294967296, 4294967295);
+ assertEq(4294967296 >>> x, 0);
+ assertEq(x << 4294967296, -1);
+ assertEq(4294967296 << x, 0);
+ assertEq(x | undefined, -1);
+ assertEq(undefined | x, -1);
+ assertEq(x & undefined, 0);
+ assertEq(undefined & x, 0);
+ assertEq(x ^ undefined, -1);
+ assertEq(undefined ^ x, -1);
+ assertEq(x >> undefined, -1);
+ assertEq(undefined >> x, 0);
+ assertEq(x >>> undefined, 4294967295);
+ assertEq(undefined >>> x, 0);
+ assertEq(x << undefined, -1);
+ assertEq(undefined << x, 0);
+ assertEq(x | null, -1);
+ assertEq(null | x, -1);
+ assertEq(x & null, 0);
+ assertEq(null & x, 0);
+ assertEq(x ^ null, -1);
+ assertEq(null ^ x, -1);
+ assertEq(x >> null, -1);
+ assertEq(null >> x, 0);
+ assertEq(x >>> null, 4294967295);
+ assertEq(null >>> x, 0);
+ assertEq(x << null, -1);
+ assertEq(null << x, 0);
+ assertEq(x | false, -1);
+ assertEq(false | x, -1);
+ assertEq(x & false, 0);
+ assertEq(false & x, 0);
+ assertEq(x ^ false, -1);
+ assertEq(false ^ x, -1);
+ assertEq(x >> false, -1);
+ assertEq(false >> x, 0);
+ assertEq(x >>> false, 4294967295);
+ assertEq(false >>> x, 0);
+ assertEq(x << false, -1);
+ assertEq(false << x, 0);
+ assertEq(x | true, -1);
+ assertEq(true | x, -1);
+ assertEq(x & true, 1);
+ assertEq(true & x, 1);
+ assertEq(x ^ true, -2);
+ assertEq(true ^ x, -2);
+ assertEq(x >> true, -1);
+ assertEq(true >> x, 0);
+ assertEq(x >>> true, 2147483647);
+ assertEq(true >>> x, 0);
+ assertEq(x << true, -2);
+ assertEq(true << x, -2147483648);
+ assertEq(x | -1.5, -1);
+ assertEq(-1.5 | x, -1);
+ assertEq(x & -1.5, -1);
+ assertEq(-1.5 & x, -1);
+ assertEq(x ^ -1.5, 0);
+ assertEq(-1.5 ^ x, 0);
+ assertEq(x >> -1.5, -1);
+ assertEq(-1.5 >> x, -1);
+ assertEq(x >>> -1.5, 1);
+ assertEq(-1.5 >>> x, 1);
+ assertEq(x << -1.5, -2147483648);
+ assertEq(-1.5 << x, -2147483648);
+}
+test3(-1)
+
+function test4 (x) {
+ assertEq(x | -1, -1);
+ assertEq(-1 | x, -1);
+ assertEq(x & -1, -2147483648);
+ assertEq(-1 & x, -2147483648);
+ assertEq(x ^ -1, 2147483647);
+ assertEq(-1 ^ x, 2147483647);
+ assertEq(x >> -1, -1);
+ assertEq(-1 >> x, -1);
+ assertEq(x >>> -1, 1);
+ assertEq(-1 >>> x, 4294967295);
+ assertEq(x << -1, 0);
+ assertEq(-1 << x, -1);
+ assertEq(x | 1, -2147483647);
+ assertEq(1 | x, -2147483647);
+ assertEq(x & 1, 0);
+ assertEq(1 & x, 0);
+ assertEq(x ^ 1, -2147483647);
+ assertEq(1 ^ x, -2147483647);
+ assertEq(x >> 1, -1073741824);
+ assertEq(1 >> x, 1);
+ assertEq(x >>> 1, 1073741824);
+ assertEq(1 >>> x, 1);
+ assertEq(x << 1, 0);
+ assertEq(1 << x, 1);
+ assertEq(x | 0, -2147483648);
+ assertEq(0 | x, -2147483648);
+ assertEq(x & 0, 0);
+ assertEq(0 & x, 0);
+ assertEq(x ^ 0, -2147483648);
+ assertEq(0 ^ x, -2147483648);
+ assertEq(x >> 0, -2147483648);
+ assertEq(0 >> x, 0);
+ assertEq(x >>> 0, 2147483648);
+ assertEq(0 >>> x, 0);
+ assertEq(x << 0, -2147483648);
+ assertEq(0 << x, 0);
+ assertEq(x | 0xffffffff, -1);
+ assertEq(0xffffffff | x, -1);
+ assertEq(x & 0xffffffff, -2147483648);
+ assertEq(0xffffffff & x, -2147483648);
+ assertEq(x ^ 0xffffffff, 2147483647);
+ assertEq(0xffffffff ^ x, 2147483647);
+ assertEq(x >> 0xffffffff, -1);
+ assertEq(0xffffffff >> x, -1);
+ assertEq(x >>> 0xffffffff, 1);
+ assertEq(0xffffffff >>> x, 4294967295);
+ assertEq(x << 0xffffffff, 0);
+ assertEq(0xffffffff << x, -1);
+ assertEq(x | "10.6", -2147483638);
+ assertEq("10.6" | x, -2147483638);
+ assertEq(x & "10.6", 0);
+ assertEq("10.6" & x, 0);
+ assertEq(x ^ "10.6", -2147483638);
+ assertEq("10.6" ^ x, -2147483638);
+ assertEq(x >> "10.6", -2097152);
+ assertEq("10.6" >> x, 10);
+ assertEq(x >>> "10.6", 2097152);
+ assertEq("10.6" >>> x, 10);
+ assertEq(x << "10.6", 0);
+ assertEq("10.6" << x, 10);
+ assertEq(x | 2147483648, -2147483648);
+ assertEq(2147483648 | x, -2147483648);
+ assertEq(x & 2147483648, -2147483648);
+ assertEq(2147483648 & x, -2147483648);
+ assertEq(x ^ 2147483648, 0);
+ assertEq(2147483648 ^ x, 0);
+ assertEq(x >> 2147483648, -2147483648);
+ assertEq(2147483648 >> x, -2147483648);
+ assertEq(x >>> 2147483648, 2147483648);
+ assertEq(2147483648 >>> x, 2147483648);
+ assertEq(x << 2147483648, -2147483648);
+ assertEq(2147483648 << x, -2147483648);
+ assertEq(x | 4294967296, -2147483648);
+ assertEq(4294967296 | x, -2147483648);
+ assertEq(x & 4294967296, 0);
+ assertEq(4294967296 & x, 0);
+ assertEq(x ^ 4294967296, -2147483648);
+ assertEq(4294967296 ^ x, -2147483648);
+ assertEq(x >> 4294967296, -2147483648);
+ assertEq(4294967296 >> x, 0);
+ assertEq(x >>> 4294967296, 2147483648);
+ assertEq(4294967296 >>> x, 0);
+ assertEq(x << 4294967296, -2147483648);
+ assertEq(4294967296 << x, 0);
+ assertEq(x | undefined, -2147483648);
+ assertEq(undefined | x, -2147483648);
+ assertEq(x & undefined, 0);
+ assertEq(undefined & x, 0);
+ assertEq(x ^ undefined, -2147483648);
+ assertEq(undefined ^ x, -2147483648);
+ assertEq(x >> undefined, -2147483648);
+ assertEq(undefined >> x, 0);
+ assertEq(x >>> undefined, 2147483648);
+ assertEq(undefined >>> x, 0);
+ assertEq(x << undefined, -2147483648);
+ assertEq(undefined << x, 0);
+ assertEq(x | null, -2147483648);
+ assertEq(null | x, -2147483648);
+ assertEq(x & null, 0);
+ assertEq(null & x, 0);
+ assertEq(x ^ null, -2147483648);
+ assertEq(null ^ x, -2147483648);
+ assertEq(x >> null, -2147483648);
+ assertEq(null >> x, 0);
+ assertEq(x >>> null, 2147483648);
+ assertEq(null >>> x, 0);
+ assertEq(x << null, -2147483648);
+ assertEq(null << x, 0);
+ assertEq(x | false, -2147483648);
+ assertEq(false | x, -2147483648);
+ assertEq(x & false, 0);
+ assertEq(false & x, 0);
+ assertEq(x ^ false, -2147483648);
+ assertEq(false ^ x, -2147483648);
+ assertEq(x >> false, -2147483648);
+ assertEq(false >> x, 0);
+ assertEq(x >>> false, 2147483648);
+ assertEq(false >>> x, 0);
+ assertEq(x << false, -2147483648);
+ assertEq(false << x, 0);
+ assertEq(x | true, -2147483647);
+ assertEq(true | x, -2147483647);
+ assertEq(x & true, 0);
+ assertEq(true & x, 0);
+ assertEq(x ^ true, -2147483647);
+ assertEq(true ^ x, -2147483647);
+ assertEq(x >> true, -1073741824);
+ assertEq(true >> x, 1);
+ assertEq(x >>> true, 1073741824);
+ assertEq(true >>> x, 1);
+ assertEq(x << true, 0);
+ assertEq(true << x, 1);
+ assertEq(x | -1.5, -1);
+ assertEq(-1.5 | x, -1);
+ assertEq(x & -1.5, -2147483648);
+ assertEq(-1.5 & x, -2147483648);
+ assertEq(x ^ -1.5, 2147483647);
+ assertEq(-1.5 ^ x, 2147483647);
+ assertEq(x >> -1.5, -1);
+ assertEq(-1.5 >> x, -1);
+ assertEq(x >>> -1.5, 1);
+ assertEq(-1.5 >>> x, 4294967295);
+ assertEq(x << -1.5, 0);
+ assertEq(-1.5 << x, -1);
+}
+test4(2147483648)
+
+function test5 (x) {
+ assertEq(x | -1, -1);
+ assertEq(-1 | x, -1);
+ assertEq(x & -1, -2147483648);
+ assertEq(-1 & x, -2147483648);
+ assertEq(x ^ -1, 2147483647);
+ assertEq(-1 ^ x, 2147483647);
+ assertEq(x >> -1, -1);
+ assertEq(-1 >> x, -1);
+ assertEq(x >>> -1, 1);
+ assertEq(-1 >>> x, 4294967295);
+ assertEq(x << -1, 0);
+ assertEq(-1 << x, -1);
+ assertEq(x | 1, -2147483647);
+ assertEq(1 | x, -2147483647);
+ assertEq(x & 1, 0);
+ assertEq(1 & x, 0);
+ assertEq(x ^ 1, -2147483647);
+ assertEq(1 ^ x, -2147483647);
+ assertEq(x >> 1, -1073741824);
+ assertEq(1 >> x, 1);
+ assertEq(x >>> 1, 1073741824);
+ assertEq(1 >>> x, 1);
+ assertEq(x << 1, 0);
+ assertEq(1 << x, 1);
+ assertEq(x | 0, -2147483648);
+ assertEq(0 | x, -2147483648);
+ assertEq(x & 0, 0);
+ assertEq(0 & x, 0);
+ assertEq(x ^ 0, -2147483648);
+ assertEq(0 ^ x, -2147483648);
+ assertEq(x >> 0, -2147483648);
+ assertEq(0 >> x, 0);
+ assertEq(x >>> 0, 2147483648);
+ assertEq(0 >>> x, 0);
+ assertEq(x << 0, -2147483648);
+ assertEq(0 << x, 0);
+ assertEq(x | 0xffffffff, -1);
+ assertEq(0xffffffff | x, -1);
+ assertEq(x & 0xffffffff, -2147483648);
+ assertEq(0xffffffff & x, -2147483648);
+ assertEq(x ^ 0xffffffff, 2147483647);
+ assertEq(0xffffffff ^ x, 2147483647);
+ assertEq(x >> 0xffffffff, -1);
+ assertEq(0xffffffff >> x, -1);
+ assertEq(x >>> 0xffffffff, 1);
+ assertEq(0xffffffff >>> x, 4294967295);
+ assertEq(x << 0xffffffff, 0);
+ assertEq(0xffffffff << x, -1);
+ assertEq(x | "10.6", -2147483638);
+ assertEq("10.6" | x, -2147483638);
+ assertEq(x & "10.6", 0);
+ assertEq("10.6" & x, 0);
+ assertEq(x ^ "10.6", -2147483638);
+ assertEq("10.6" ^ x, -2147483638);
+ assertEq(x >> "10.6", -2097152);
+ assertEq("10.6" >> x, 10);
+ assertEq(x >>> "10.6", 2097152);
+ assertEq("10.6" >>> x, 10);
+ assertEq(x << "10.6", 0);
+ assertEq("10.6" << x, 10);
+ assertEq(x | 2147483648, -2147483648);
+ assertEq(2147483648 | x, -2147483648);
+ assertEq(x & 2147483648, -2147483648);
+ assertEq(2147483648 & x, -2147483648);
+ assertEq(x ^ 2147483648, 0);
+ assertEq(2147483648 ^ x, 0);
+ assertEq(x >> 2147483648, -2147483648);
+ assertEq(2147483648 >> x, -2147483648);
+ assertEq(x >>> 2147483648, 2147483648);
+ assertEq(2147483648 >>> x, 2147483648);
+ assertEq(x << 2147483648, -2147483648);
+ assertEq(2147483648 << x, -2147483648);
+ assertEq(x | 4294967296, -2147483648);
+ assertEq(4294967296 | x, -2147483648);
+ assertEq(x & 4294967296, 0);
+ assertEq(4294967296 & x, 0);
+ assertEq(x ^ 4294967296, -2147483648);
+ assertEq(4294967296 ^ x, -2147483648);
+ assertEq(x >> 4294967296, -2147483648);
+ assertEq(4294967296 >> x, 0);
+ assertEq(x >>> 4294967296, 2147483648);
+ assertEq(4294967296 >>> x, 0);
+ assertEq(x << 4294967296, -2147483648);
+ assertEq(4294967296 << x, 0);
+ assertEq(x | undefined, -2147483648);
+ assertEq(undefined | x, -2147483648);
+ assertEq(x & undefined, 0);
+ assertEq(undefined & x, 0);
+ assertEq(x ^ undefined, -2147483648);
+ assertEq(undefined ^ x, -2147483648);
+ assertEq(x >> undefined, -2147483648);
+ assertEq(undefined >> x, 0);
+ assertEq(x >>> undefined, 2147483648);
+ assertEq(undefined >>> x, 0);
+ assertEq(x << undefined, -2147483648);
+ assertEq(undefined << x, 0);
+ assertEq(x | null, -2147483648);
+ assertEq(null | x, -2147483648);
+ assertEq(x & null, 0);
+ assertEq(null & x, 0);
+ assertEq(x ^ null, -2147483648);
+ assertEq(null ^ x, -2147483648);
+ assertEq(x >> null, -2147483648);
+ assertEq(null >> x, 0);
+ assertEq(x >>> null, 2147483648);
+ assertEq(null >>> x, 0);
+ assertEq(x << null, -2147483648);
+ assertEq(null << x, 0);
+ assertEq(x | false, -2147483648);
+ assertEq(false | x, -2147483648);
+ assertEq(x & false, 0);
+ assertEq(false & x, 0);
+ assertEq(x ^ false, -2147483648);
+ assertEq(false ^ x, -2147483648);
+ assertEq(x >> false, -2147483648);
+ assertEq(false >> x, 0);
+ assertEq(x >>> false, 2147483648);
+ assertEq(false >>> x, 0);
+ assertEq(x << false, -2147483648);
+ assertEq(false << x, 0);
+ assertEq(x | true, -2147483647);
+ assertEq(true | x, -2147483647);
+ assertEq(x & true, 0);
+ assertEq(true & x, 0);
+ assertEq(x ^ true, -2147483647);
+ assertEq(true ^ x, -2147483647);
+ assertEq(x >> true, -1073741824);
+ assertEq(true >> x, 1);
+ assertEq(x >>> true, 1073741824);
+ assertEq(true >>> x, 1);
+ assertEq(x << true, 0);
+ assertEq(true << x, 1);
+ assertEq(x | -1.5, -1);
+ assertEq(-1.5 | x, -1);
+ assertEq(x & -1.5, -2147483648);
+ assertEq(-1.5 & x, -2147483648);
+ assertEq(x ^ -1.5, 2147483647);
+ assertEq(-1.5 ^ x, 2147483647);
+ assertEq(x >> -1.5, -1);
+ assertEq(-1.5 >> x, -1);
+ assertEq(x >>> -1.5, 1);
+ assertEq(-1.5 >>> x, 4294967295);
+ assertEq(x << -1.5, 0);
+ assertEq(-1.5 << x, -1);
+}
+test5(-2147483648)
+
+
diff --git a/js/src/jit-test/tests/basic/testBitwise.js b/js/src/jit-test/tests/basic/testBitwise.js new file mode 100644 index 000000000..5d940a556 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBitwise.js @@ -0,0 +1,12 @@ +function testBitwise() { + var x = 10000; + var y = 123456; + var z = 987234; + for (var i = 0; i < 50; i++) { + x = x ^ y; + y = y | z; + z = ~x; + } + return x + y + z; +} +assertEq(testBitwise(), -1298); diff --git a/js/src/jit-test/tests/basic/testBoolToString.js b/js/src/jit-test/tests/basic/testBoolToString.js new file mode 100644 index 000000000..9eeb40c5d --- /dev/null +++ b/js/src/jit-test/tests/basic/testBoolToString.js @@ -0,0 +1,3 @@ +// |jit-test| error: TypeError; +var bts = true.toString; +bts(); diff --git a/js/src/jit-test/tests/basic/testBoxDoubleWithDoubleSizedInt.js b/js/src/jit-test/tests/basic/testBoxDoubleWithDoubleSizedInt.js new file mode 100644 index 000000000..5327e56e5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBoxDoubleWithDoubleSizedInt.js @@ -0,0 +1,10 @@ +function testBoxDoubleWithDoubleSizedInt() +{ + var i = 0; + var a = new Array(3); + + while (i < a.length) + a[i++] = 0x5a827999; + return a.join(","); +} +assertEq(testBoxDoubleWithDoubleSizedInt(), "1518500249,1518500249,1518500249"); diff --git a/js/src/jit-test/tests/basic/testBranchCse.js b/js/src/jit-test/tests/basic/testBranchCse.js new file mode 100644 index 000000000..1c9965817 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBranchCse.js @@ -0,0 +1,7 @@ +function testBranchCse() { + empty = []; + out = []; + for (var j=0;j<10;++j) { empty[42]; out.push((1 * (1)) | ""); } + return out.join(","); +} +assertEq(testBranchCse(), "1,1,1,1,1,1,1,1,1,1"); diff --git a/js/src/jit-test/tests/basic/testBranchingLoop.js b/js/src/jit-test/tests/basic/testBranchingLoop.js new file mode 100644 index 000000000..5c302425f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBranchingLoop.js @@ -0,0 +1,11 @@ +function testBranchingLoop() { + var x = 0; + for (var i=0; i < 100; ++i) { + if (i == 51) { + x += 10; + } + x++; + } + return x; +} +assertEq(testBranchingLoop(), 110); diff --git a/js/src/jit-test/tests/basic/testBranchingUnstableLoop.js b/js/src/jit-test/tests/basic/testBranchingUnstableLoop.js new file mode 100644 index 000000000..f8333ecff --- /dev/null +++ b/js/src/jit-test/tests/basic/testBranchingUnstableLoop.js @@ -0,0 +1,11 @@ +function testBranchingUnstableLoop() { + var x = 0; + for (var i=0; i < 100; ++i) { + if (i == 51) { + x += 10.1; + } + x++; + } + return x; +} +assertEq(testBranchingUnstableLoop(), 110.1); diff --git a/js/src/jit-test/tests/basic/testBranchingUnstableLoopCounter.js b/js/src/jit-test/tests/basic/testBranchingUnstableLoopCounter.js new file mode 100644 index 000000000..53fff9e08 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBranchingUnstableLoopCounter.js @@ -0,0 +1,11 @@ +function testBranchingUnstableLoopCounter() { + var x = 0; + for (var i=0; i < 100; ++i) { + if (i == 51) { + i += 1.1; + } + x++; + } + return x; +} +assertEq(testBranchingUnstableLoopCounter(), 99); diff --git a/js/src/jit-test/tests/basic/testBranchingUnstableObject.js b/js/src/jit-test/tests/basic/testBranchingUnstableObject.js new file mode 100644 index 000000000..338ae73c0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBranchingUnstableObject.js @@ -0,0 +1,13 @@ +function testBranchingUnstableObject() { + var x = {s: "a"}; + var t = ""; + for (var i=0; i < 100; ++i) { + if (i == 51) + { + x.s = 5; + } + t += x.s; + } + return t.length; +} +assertEq(testBranchingUnstableObject(), 100); diff --git a/js/src/jit-test/tests/basic/testBrandedVsGeneric.js b/js/src/jit-test/tests/basic/testBrandedVsGeneric.js new file mode 100644 index 000000000..f0a244bcc --- /dev/null +++ b/js/src/jit-test/tests/basic/testBrandedVsGeneric.js @@ -0,0 +1,17 @@ +const C = function (a, b, c) { + return function C() { + this.m1 = function () a; + this.m2 = function () b; + this.m3 = function () c; + } +}(2,3,4); +var c = new C(); +var d = function (e) {return {m0: function () e}}(5); +for (var i = 0; i < 5; i++) + d.m0(); +C.call(d); +d.__iterator__ = function() {yield 55}; +for (i = 0; i < 5; i++) { + for (j in d) + print(j); +} diff --git a/js/src/jit-test/tests/basic/testBug1126754.js b/js/src/jit-test/tests/basic/testBug1126754.js new file mode 100644 index 000000000..70f27c29e --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug1126754.js @@ -0,0 +1,9 @@ +// |jit-test| error:SyntaxError + +(function() { + with ({}) {} + function f() { + ({ *h(){} }) + } + function f +})() diff --git a/js/src/jit-test/tests/basic/testBug1235874.js b/js/src/jit-test/tests/basic/testBug1235874.js new file mode 100644 index 000000000..8e7841081 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug1235874.js @@ -0,0 +1 @@ +evaluate('evalcx("1")', { fileName: null }); diff --git a/js/src/jit-test/tests/basic/testBug458838.js b/js/src/jit-test/tests/basic/testBug458838.js new file mode 100644 index 000000000..59b55a50c --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug458838.js @@ -0,0 +1,14 @@ +var escape; +function testBug458838() { + var a = 1; + function g() { + var b = 0 + for (var i = 0; i < 10; ++i) { + b += a; + } + return b; + } + + return g(); +} +assertEq(testBug458838(), 10); diff --git a/js/src/jit-test/tests/basic/testBug462388.js b/js/src/jit-test/tests/basic/testBug462388.js new file mode 100644 index 000000000..7af29cbe4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug462388.js @@ -0,0 +1,6 @@ +//test no multitrees assert +function testBug462388() { + var c = 0, v; for each (let x in ["",v,v,v]) { for (c=0;c<4;++c) { } } + return true; +} +assertEq(testBug462388(), true); diff --git a/js/src/jit-test/tests/basic/testBug462407.js b/js/src/jit-test/tests/basic/testBug462407.js new file mode 100644 index 000000000..82f7340f1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug462407.js @@ -0,0 +1,6 @@ +//test no multitrees assert +function testBug462407() { + for each (let i in [0, {}, 0, 1.5, {}, 0, 1.5, 0, 0]) { } + return true; +} +assertEq(testBug462407(), true); diff --git a/js/src/jit-test/tests/basic/testBug463490.js b/js/src/jit-test/tests/basic/testBug463490.js new file mode 100644 index 000000000..730879ead --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug463490.js @@ -0,0 +1,18 @@ +//test no multitrees assert +function testBug463490() { + function f(a, b, d) { + for (var i = 0; i < 10; i++) { + if (d) + b /= 2; + } + return a + b; + } + //integer stable loop + f(2, 2, false); + //double stable loop + f(3, 4.5, false); + //integer unstable branch + f(2, 2, true); + return true; +}; +assertEq(testBug463490(), true); diff --git a/js/src/jit-test/tests/basic/testBug465261.js b/js/src/jit-test/tests/basic/testBug465261.js new file mode 100644 index 000000000..be409055c --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug465261.js @@ -0,0 +1,7 @@ +// Test no assert or crash +function testBug465261() { + for (let z = 0; z < 2; ++z) { for each (let x in [0, true, (void 0), 0, (void + 0)]) { if(x){} } }; + return true; +} +assertEq(testBug465261(), true); diff --git a/js/src/jit-test/tests/basic/testBug465272.js b/js/src/jit-test/tests/basic/testBug465272.js new file mode 100644 index 000000000..88a8f064f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug465272.js @@ -0,0 +1,6 @@ +function testBug465272() { + var a = new Array(5); + for (j=0;j<5;++j) a[j] = "" + ((5) - 2); + return a.join(","); +} +assertEq(testBug465272(), "3,3,3,3,3"); diff --git a/js/src/jit-test/tests/basic/testBug465483.js b/js/src/jit-test/tests/basic/testBug465483.js new file mode 100644 index 000000000..a2b3da635 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug465483.js @@ -0,0 +1,7 @@ +function testBug465483() { + var a = new Array(4); + var c = 0; + for each (i in [4, 'a', 'b', (void 0)]) a[c++] = '' + (i + i); + return a.join(','); +} +assertEq(testBug465483(), '8,aa,bb,NaN'); diff --git a/js/src/jit-test/tests/basic/testBug465688.js b/js/src/jit-test/tests/basic/testBug465688.js new file mode 100644 index 000000000..3eb1bd7cb --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug465688.js @@ -0,0 +1,6 @@ +//test no assert +function testBug465688() { + for each (let d in [-0x80000000, -0x80000000]) - -d; + return true; +} +assertEq(testBug465688(), true); diff --git a/js/src/jit-test/tests/basic/testBug466128.js b/js/src/jit-test/tests/basic/testBug466128.js new file mode 100644 index 000000000..c4f1918d3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug466128.js @@ -0,0 +1,9 @@ +//test no multitrees assert +function testBug466128() { + for (let a = 0; a < 3; ++a) { + for each (let b in [1, 2, "three", 4, 5, 6, 7, 8]) { + } + } + return true; +} +assertEq(testBug466128(), true); diff --git a/js/src/jit-test/tests/basic/testBug466262.js b/js/src/jit-test/tests/basic/testBug466262.js new file mode 100644 index 000000000..450d09503 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug466262.js @@ -0,0 +1,11 @@ +//test no assert +function testBug466262() { + var e = 1; + for (var d = 0; d < 3; ++d) { + if (d == 2) { + e = ""; + } + } + return true; +} +assertEq(testBug466262(), true); diff --git a/js/src/jit-test/tests/basic/testBug474769.js b/js/src/jit-test/tests/basic/testBug474769.js new file mode 100644 index 000000000..54dc1f44a --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug474769.js @@ -0,0 +1,10 @@ +delete b; +delete q; + +for each (testBug474769_b in [1, 1, 1, 1.5, 1, 1]) { + (function() { for each (let testBug474769_h in [0, 0, 1.4, ""]) {} })() +} +function testBug474769() { + return testBug474769_b; +} +assertEq(testBug474769(), 1); diff --git a/js/src/jit-test/tests/basic/testBug501690.js b/js/src/jit-test/tests/basic/testBug501690.js new file mode 100644 index 000000000..9fa65b6c2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug501690.js @@ -0,0 +1,14 @@ +function testBug501690() { + // Property cache assertion when 3 objects along a prototype chain have the same shape. + function B(){} + B.prototype = {x: 123}; + + function D(){} + D.prototype = new B; + D.prototype.x = 1; // [1] shapeOf(B.prototype) == shapeOf(D.prototype) + + arr = [new D, new D, new D, D.prototype]; // [2] all the same shape + for (var i = 0; i < 4; i++) + assertEq(arr[i].x, 1); // same kshape [2], same vshape [1] +} +testBug501690(); diff --git a/js/src/jit-test/tests/basic/testBug502914.js b/js/src/jit-test/tests/basic/testBug502914.js new file mode 100644 index 000000000..d01ee9786 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug502914.js @@ -0,0 +1,19 @@ +function testBug502914() { + // Assigning a non-function to a function-valued property on trace should + // bump the shape. + function f1() {} + function C() {} + var x = C.prototype = {m: f1}; + x.m(); // brand scope + var arr = [new C, new C, new C, x]; + try { + for (var i = 0; i < 4; i++) { + arr[i].m = 12; + x.m(); // should throw last time through + } + } catch (exc) { + return exc.constructor.name; + } + return "no exception"; +} +assertEq(testBug502914(), "TypeError"); diff --git a/js/src/jit-test/tests/basic/testBug504520.js b/js/src/jit-test/tests/basic/testBug504520.js new file mode 100644 index 000000000..ba5f76764 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug504520.js @@ -0,0 +1,11 @@ +function testBug504520() { + // A bug involving comparisons. + var arr = [1/0, 1/0, 1/0, 1/0, 1/0, 1/0, 1/0, 1/0, 1/0, 0]; + assertEq(arr.length > 9, true); + + var s = ''; + for (var i = 0; i < arr.length; i++) + arr[i] >= 1/0 ? null : (s += i); + assertEq(s, '9'); +} +testBug504520(); diff --git a/js/src/jit-test/tests/basic/testBug504520Harder.js b/js/src/jit-test/tests/basic/testBug504520Harder.js new file mode 100644 index 000000000..381bd3ae6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug504520Harder.js @@ -0,0 +1,33 @@ +function testBug504520Harder() { + // test 1024 similar cases + var vals = [1/0, -1/0, 0, 0/0]; + var ops = ["===", "!==", "==", "!=", "<", ">", "<=", ">="]; + for each (var x in vals) { + for each (var y in vals) { + for each (var op in ops) { + for each (var z in vals) { + // Assume eval is correct. This depends on the global + // Infinity property not having been reassigned. + var xz = eval(x + op + z); + var yz = eval(y + op + z); + + var arr = [x, x, x, x, x, x, x, x, x, y]; + assertEq(arr.length > 9, true); + var expected = [xz, xz, xz, xz, xz, xz, xz, xz, xz, yz]; + + // ?: looks superfluous but that's what we're testing here + var fun = eval( + '(function (arr, results) {\n' + + ' for (let i = 0; i < arr.length; i++)\n' + + ' results.push(arr[i]' + op + z + ' ? "true" : "false");\n' + + '});\n'); + var actual = []; + fun(arr, actual); + print(x, y, op, z); + assertEq("" + actual, "" + expected); + } + } + } + } +} +testBug504520Harder(); diff --git a/js/src/jit-test/tests/basic/testBug507425.js b/js/src/jit-test/tests/basic/testBug507425.js new file mode 100644 index 000000000..616bababd --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug507425.js @@ -0,0 +1,14 @@ +// |jit-test| allow-oom; +function testBug507425() { + var r = /x/; + for (var i = 0; i < 3; i++) + r.lastIndex = 0; // call a setter + var s = ';'; + try { + for (i = 0; i < 80; i++) + s += s; // call js_CanLeaveTrace + } catch (exc) { + return "ok"; + } +} +assertEq(testBug507425(), "ok"); diff --git a/js/src/jit-test/tests/basic/testBug520503-1.js b/js/src/jit-test/tests/basic/testBug520503-1.js new file mode 100644 index 000000000..a3730e5a3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug520503-1.js @@ -0,0 +1,3 @@ +(new Function("for (var j=0; j<9; ++j) { (function sum_indexing(array,start){return array.length==start ? 0 : array[start]+ sum_indexing(array,start+1)})([true,true,undefined],0)}"))() + +/* Should not have crashed. */ diff --git a/js/src/jit-test/tests/basic/testBug520503-2.js b/js/src/jit-test/tests/basic/testBug520503-2.js new file mode 100644 index 000000000..2f6699d40 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug520503-2.js @@ -0,0 +1,18 @@ +for each(let a in [new Boolean(false)]) {} +for (var b = 0; b < 13; ++b) { + if (b % 3 == 1) { + (function f(c) { + if (c <= 1) { + return 1; + } + return f(c - 1) + f(c - 2); + })(3) + } else { + (function g(d, e) {; + return d.length == e ? 0 : d[e] + g(d, e + 1); + })([false, new Boolean(true), false], 0) + } +} + +/* Should not have crashed. */ + diff --git a/js/src/jit-test/tests/basic/testBug520503-3.js b/js/src/jit-test/tests/basic/testBug520503-3.js new file mode 100644 index 000000000..1385af09a --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug520503-3.js @@ -0,0 +1,6 @@ +(Function("for (var a = 0; a < 6; a++) {\ + (function sum_indexing(b, c) {\ + return b.length == c ? 0 : b[c] + sum_indexing(b, c + 1)\ + })([(void 0), Infinity, Infinity], 0)\ +}"))() + diff --git a/js/src/jit-test/tests/basic/testBug529147.js b/js/src/jit-test/tests/basic/testBug529147.js new file mode 100644 index 000000000..8b700879d --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug529147.js @@ -0,0 +1,22 @@ +var magicNumbers = [1, -1, 0, 0]; +var magicIndex = 0; + +var sum = 0; + +function foo(n) { + for (var i = 0; i < n; ++i) { + sum += 10; + bar(); + } +} + +function bar() { + var q = magicNumbers[magicIndex++]; + if (q != -1) { + sum += 1; + foo(q); + } +} + +foo(3); +assertEq(sum, 43); diff --git a/js/src/jit-test/tests/basic/testBug547791.js b/js/src/jit-test/tests/basic/testBug547791.js new file mode 100644 index 000000000..2d4482eb5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug547791.js @@ -0,0 +1,21 @@ + +function Bext(k) { + if (k > 0) { + let i = k + 1; + if (k == 10) { + function x () { i = 2; } + } + Bext(i - 2); + Bext(i - 2); + } + return 0; +} + +function f() { + Bext(12); +} + +f(); + +/* Don't assert. */ + diff --git a/js/src/jit-test/tests/basic/testBug550210.js b/js/src/jit-test/tests/basic/testBug550210.js new file mode 100644 index 000000000..d4fa9d16a --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug550210.js @@ -0,0 +1,16 @@ +function g(e) { + return ("" + e); +} + +function blah() { + do { + yield; + } while ({}(p = arguments)); +} +rv = blah(); +try { + for (a in rv) ; +} catch (e) { + print("" + g(e)); +} +gc(); diff --git a/js/src/jit-test/tests/basic/testBug552248.js b/js/src/jit-test/tests/basic/testBug552248.js new file mode 100644 index 000000000..ec310d158 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug552248.js @@ -0,0 +1,37 @@ +load(libdir + "evalInFrame.js"); + +var a = new Array(); + +function i(save) { + var x = 9; + evalInFrame(0, "a.push(x)", save); + evalInFrame(1, "a.push(z)", save); + evalInFrame(2, "a.push(z)", save); + evalInFrame(3, "a.push(y)", save); + evalInFrame(4, "a.push(x)", save); +} + +function h() { + var z = 5; + evalInFrame(0, "a.push(z)"); + evalInFrame(1, "a.push(y)"); + evalInFrame(2, "a.push(x)"); + evalInFrame(0, "i(false)"); + evalInFrame(0, "a.push(z)", true); + evalInFrame(1, "a.push(y)", true); + evalInFrame(2, "a.push(x)", true); + evalInFrame(0, "i(true)", true); +} + +function g() { + var y = 4; + h(); +} + +function f() { + var x = 3; + g(); +} + +f(); +assertEq(a+'', [5, 4, 3, 9, 5, 5, 4, 3, 5, 4, 3, 9, 5, 5, 4, 3]+''); diff --git a/js/src/jit-test/tests/basic/testBug554043.js b/js/src/jit-test/tests/basic/testBug554043.js new file mode 100644 index 000000000..a0071aeb8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug554043.js @@ -0,0 +1,6 @@ +(function () { + for (var a = 0; a < 5; a++) { + print(-false) + assertEq(-false, -0.0); + } +})() diff --git a/js/src/jit-test/tests/basic/testBug555484.js b/js/src/jit-test/tests/basic/testBug555484.js new file mode 100644 index 000000000..f15f2b268 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug555484.js @@ -0,0 +1,8 @@ +var result = ""; +o = { valueOf:function(){ throw "cow" } }; +try { + String.fromCharCode(o); +} catch (e) { + result = e.toString(); +} +assertEq(result, "cow"); diff --git a/js/src/jit-test/tests/basic/testBug558446.js b/js/src/jit-test/tests/basic/testBug558446.js new file mode 100644 index 000000000..8560de094 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug558446.js @@ -0,0 +1,10 @@ +function f(a, b) { return a + " " + b; } + +for (var i = 0; i < 10; ++i) { + var s = ''; + var a = {toString: function () { s += 'a'; return 'a'; }}; + var b = {toString: function () { s += 'b'; return 'b'; }}; + f(a, b); + assertEq(s, 'ab'); +} + diff --git a/js/src/jit-test/tests/basic/testBug560098.js b/js/src/jit-test/tests/basic/testBug560098.js new file mode 100644 index 000000000..18b5e7609 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug560098.js @@ -0,0 +1,16 @@ +Function("\ + for each(let w in [(5), false, Number, false]) {\ + (function f(zzzzzz) {\ + return zzzzzz.length == 0 ? 0 : zzzzzz[0] + f(zzzzzz.slice(1))\ + })([, [], [], w, , ])\ + }\ +")() + +Function("\ + for each(let w in [(void 0), (void 0), false, false, false, false, false, \ + undefined, undefined, false, (void 0), undefined]) {\ + (function f(zzzzzz) {\ + return zzzzzz.length == 0 ? 0 : zzzzzz[0] + f(zzzzzz.slice(1))\ + })([w, , w, w, [], []])\ + }\ +")() diff --git a/js/src/jit-test/tests/basic/testBug566556.js b/js/src/jit-test/tests/basic/testBug566556.js new file mode 100644 index 000000000..244be57d2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug566556.js @@ -0,0 +1,9 @@ +var msg = ""; +try { + this.__defineSetter__('x', Object.create); + this.watch('x', function() {}); + x = 3; +} catch (e) { + msg = e.toString(); +} +assertEq(msg, "TypeError: undefined is not an object or null"); diff --git a/js/src/jit-test/tests/basic/testBug578044.js b/js/src/jit-test/tests/basic/testBug578044.js new file mode 100644 index 000000000..c5b811dc9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug578044.js @@ -0,0 +1,13 @@ +this.watch("x", Object.create) +try { + (function() { + this.__defineGetter__("x", + function() { + return this + }) + })() +} catch(e) {} +Object.defineProperty(x, "x", ({ + set: Uint16Array +})) + diff --git a/js/src/jit-test/tests/basic/testBug579602.js b/js/src/jit-test/tests/basic/testBug579602.js new file mode 100644 index 000000000..113a34dda --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug579602.js @@ -0,0 +1,21 @@ +// don't panic + +f = function() { + x = yield +} +rv = f() +for (a in rv) (function() {}) +x = new Proxy({}, (function() { + return { + defineProperty: gc + } +})()); +with({ + d: (({ + x: Object.defineProperty(x, "", ({ + set: Array.e + })) + })) +}) {} + +// don't crash diff --git a/js/src/jit-test/tests/basic/testBug579646.js b/js/src/jit-test/tests/basic/testBug579646.js new file mode 100644 index 000000000..d034410f9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug579646.js @@ -0,0 +1,22 @@ +if (typeof gczeal != "function") + gczeal = function() {} + +for (a = 0; a < 9; a++) + for (b = 0; b < 1; b++) + for (c = 0; c < 2; c++) + gczeal(); + +for each(e in [NaN]) + for (d = 0; d < 1; d++) + z = 0; + +for (w in [0, 0]) + {} + +x = 0; + +for (e = 0; e < 3; e++) + for (f = 0; f < 4; f++) + x = -x + +// don't crash diff --git a/js/src/jit-test/tests/basic/testBug582766.js b/js/src/jit-test/tests/basic/testBug582766.js new file mode 100644 index 000000000..cfcafbed0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug582766.js @@ -0,0 +1,18 @@ +expected = 4; + +var fourth = { nextSibling: null }; +var third = { nextSibling: fourth }; +var second = { nextSibling: third }; +var first = { nextSibling: second }; + +function f() { + let loopcount = 0; + for (let node = first; node; node = node.nextSibling) { + loopcount++; + } + return loopcount; +} + +actual = f(); + +assertEq(actual, expected); diff --git a/js/src/jit-test/tests/basic/testBug584650.js b/js/src/jit-test/tests/basic/testBug584650.js new file mode 100644 index 000000000..b6c9d8ab7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug584650.js @@ -0,0 +1,9 @@ +if (typeof gczeal != "function") + gczeal = function() {} + +// don't crash +x = (evalcx('lazy')) +x.watch("", function () {}) +gczeal(1) +for (w in x) {} + diff --git a/js/src/jit-test/tests/basic/testBug586866.js b/js/src/jit-test/tests/basic/testBug586866.js new file mode 100644 index 000000000..425bf2b78 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug586866.js @@ -0,0 +1,16 @@ +var magic = 8; + +var obj = {}; +for (var i = 1; i <= magic; ++i) + obj[i] = "a"; + +function func() { + var i = 1; + while (i in obj) { + ++i; + } + return i - 1; +} +assertEq(func(), magic); +assertEq(func(), magic); +assertEq(func(), magic); diff --git a/js/src/jit-test/tests/basic/testBug593559.js b/js/src/jit-test/tests/basic/testBug593559.js new file mode 100644 index 000000000..59994f362 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug593559.js @@ -0,0 +1,9 @@ +var gen = (function () {yield})(); +var t = gen.throw; +try { + new t; +} catch (e) { + actual = e; +} +assertEq(actual.name, "TypeError"); +assertEq(/is not a constructor/.test(actual.message), true); diff --git a/js/src/jit-test/tests/basic/testBug595916.js b/js/src/jit-test/tests/basic/testBug595916.js new file mode 100644 index 000000000..eada406d9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug595916.js @@ -0,0 +1,10 @@ +(function () { + try { + eval("\ + for each(let d in[0,0,0,0,0,0,0,0]) {\ + for(let b in[0,0]) {}\ + }\ + ") + } catch (e) {} +})() + diff --git a/js/src/jit-test/tests/basic/testBug602413.js b/js/src/jit-test/tests/basic/testBug602413.js new file mode 100644 index 000000000..eeef15cbe --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug602413.js @@ -0,0 +1,45 @@ +var so = []; + +function U(unusedV) +{ + for (var i = 0; i < so.length; ++i) + return false; + so.push(0); +} + +function C(v) +{ + if (typeof v == "object" || typeof v == "function") { + for (var i = 0; i < 10; ++i) {} + U(v); + } +} + +function exploreProperties(obj) +{ + var props = []; + for (var o = obj; o; o = Object.getPrototypeOf(o)) { + props = props.concat(Object.getOwnPropertyNames(o)); + } + for (var i = 0; i < props.length; ++i) { + var p = props[i]; + try { + var v = obj[p]; + C(v); + } catch(e) { } + } +} + +function boom() +{ + var a = []; + var b = function(){}; + var c = [{}]; + exploreProperties(a); + exploreProperties(b); + exploreProperties(c); + exploreProperties(c); +} + +boom(); + diff --git a/js/src/jit-test/tests/basic/testBug603193.js b/js/src/jit-test/tests/basic/testBug603193.js new file mode 100644 index 000000000..8bebb5fdf --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug603193.js @@ -0,0 +1,12 @@ +function g(code) { + f = Function(code); + for (a in f()) {} +} + +/* Get call ic in a state to call CompileFunction for new functions. */ +g() +g("(function(){})") +g() + +/* Call generator with frame created by call ic + CompileFunction. */ +g("yield") diff --git a/js/src/jit-test/tests/basic/testBug604210.js b/js/src/jit-test/tests/basic/testBug604210.js new file mode 100644 index 000000000..3f333ec54 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug604210.js @@ -0,0 +1,11 @@ +function f() { + var msg = ''; + try { + var x = undefined; + print(x.foo); + } catch (e) { + msg = '' + e; + } + assertEq(msg, "TypeError: x is undefined"); +} +f(); diff --git a/js/src/jit-test/tests/basic/testBug606138.js b/js/src/jit-test/tests/basic/testBug606138.js new file mode 100644 index 000000000..141bf2534 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug606138.js @@ -0,0 +1,3 @@ +// The proxy is going to mutate thisv in place. InvokeSessionGuard should be +// cool with that +with(evalcx(''))[7, 8].map((n) => new Int16Array(n), []) diff --git a/js/src/jit-test/tests/basic/testBug607659.js b/js/src/jit-test/tests/basic/testBug607659.js new file mode 100644 index 000000000..edfda935c --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug607659.js @@ -0,0 +1,8 @@ +var g = 0; +Object.defineProperty(RegExp.prototype, 'test', { get:function() { ++g } }); +function f() { + for (var i = 0; i < 100; ++i) + /a/.exec('a'); +} +f(); +assertEq(g, 0); diff --git a/js/src/jit-test/tests/basic/testBug614653.js b/js/src/jit-test/tests/basic/testBug614653.js new file mode 100644 index 000000000..e09759ae5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug614653.js @@ -0,0 +1,10 @@ +/* Bug 614653 - This test .2 seconds with the fix, 20 minutes without. */ +for (var i = 0; i < 10; ++i) { + var arr = []; + var s = "abcdefghijklmnop"; + for (var j = 0; j < 50000; ++j) { + s = "<" + s + ">"; + arr.push(s); + } + gc(); +} diff --git a/js/src/jit-test/tests/basic/testBug614752.js b/js/src/jit-test/tests/basic/testBug614752.js new file mode 100644 index 000000000..d34392da1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug614752.js @@ -0,0 +1,3 @@ +// |jit-test| error: TypeError +Object.prototype.apply = Function.prototype.apply; +({}).apply(null, null); // don't assert diff --git a/js/src/jit-test/tests/basic/testBug616454.js b/js/src/jit-test/tests/basic/testBug616454.js new file mode 100644 index 000000000..34ca440a7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug616454.js @@ -0,0 +1,2 @@ +function isnan(x) { return x !== x } +assertEq(isnan(deserialize(serialize(-'test'))), true); diff --git a/js/src/jit-test/tests/basic/testBug621202.js b/js/src/jit-test/tests/basic/testBug621202.js new file mode 100644 index 000000000..5bf826910 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug621202.js @@ -0,0 +1,16 @@ +const MAX = 10000; + +var arr = []; +var str = ""; +for (var i = 0; i < MAX; ++i) { + /x/.test(str); + str = str + 'xxxxxxxxxxxxxx'; + arr.push(str); +} + +arr.length = Math.floor(MAX/3); +gc(); + +for (var i = 0; i < MAX; ++i) { + /x/.test(arr[i]); +} diff --git a/js/src/jit-test/tests/basic/testBug628564.js b/js/src/jit-test/tests/basic/testBug628564.js new file mode 100644 index 000000000..8e9455064 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug628564.js @@ -0,0 +1,8 @@ +x = 0 +for (a = 0; a < 13; ++a) { + if (a == 7) { + if (!x) { + this.__defineSetter__("x", Object.defineProperties) + } + } +} diff --git a/js/src/jit-test/tests/basic/testBug629974.js b/js/src/jit-test/tests/basic/testBug629974.js new file mode 100644 index 000000000..50e7247f4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug629974.js @@ -0,0 +1,7 @@ +foo = {} +foo.y = 3; +foo.y = function () {} +Object.defineProperty(foo, "y", { set:function(){} }) +gc() +delete foo.y +gc(); diff --git a/js/src/jit-test/tests/basic/testBug630064.js b/js/src/jit-test/tests/basic/testBug630064.js new file mode 100644 index 000000000..aab4885cc --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug630064.js @@ -0,0 +1,48 @@ +var BUGNUMBER = ''; +function printBugNumber (num) +{ + return "foo"; +} +function optionsClear() { + var x = printBugNumber().split(','); +} +function optionsReset() { + optionsClear(); +} +var code = new Array(); +code.push("evaluate"); +var x0 = "\ + printBugNumber(BUGNUMBER);\n\ + function gen()\n\ + {\n\ + try {\n\ + yield 0;\n\ + } finally {\n\ + }\n\ + }\n\ + var iter1 = gen( iter1=\"NaN\", new gen(gen)) ;\n\ + gc();\n\ +"; +code.push(x0); +code.push("evaluate"); +var files = new Array(); +while (true) { + var file = code.shift(); + if (file == "evaluate") { + loadFiles(files); + } else if (file == undefined) { + break; + } else { + files.push(file); + } +} +function loadFiles(x) { + for (i in x) { + try { + eval(x[i]); + } catch (e) { + } + } + optionsReset(); +} + diff --git a/js/src/jit-test/tests/basic/testBug634590.js b/js/src/jit-test/tests/basic/testBug634590.js new file mode 100644 index 000000000..32df4f3bd --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug634590.js @@ -0,0 +1,12 @@ +this.name = "outer"; +var sb = evalcx(''); +sb.name = "inner"; +sb.parent = this; +function f() { return this.name; } +assertEq(evalcx('this.f = parent.f;\n' + + 'var s = "";\n' + + 'for (i = 0; i < 10; ++i)\n' + + ' s += f();\n' + + 's', + sb), + "outerouterouterouterouterouterouterouterouterouter"); diff --git a/js/src/jit-test/tests/basic/testBug634590b.js b/js/src/jit-test/tests/basic/testBug634590b.js new file mode 100644 index 000000000..42531a829 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug634590b.js @@ -0,0 +1,19 @@ +this.name = "outer"; +var sb = evalcx(''); +sb.name = "inner"; +sb.parent = this; +function f() { return this.name; } +f.notMuchTodo = '42'; +assertEq(evalcx('{\n' + + ' let f = parent.f;\n' + + ' let name = "block";\n' + + ' (function () {\n' + + ' eval(f.notMuchTodo);\n' + // reify Block + ' var s = "";\n' + + ' for (i = 0; i < 10; ++i)\n' + + ' s += f();\n' + + ' return s;\n' + + ' })();\n' + + '}', + sb), + "outerouterouterouterouterouterouterouterouterouter"); diff --git a/js/src/jit-test/tests/basic/testBug634590c.js b/js/src/jit-test/tests/basic/testBug634590c.js new file mode 100644 index 000000000..1ae2542de --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug634590c.js @@ -0,0 +1,20 @@ +this.name = "outer"; +var sb = evalcx(''); +sb.name = "inner"; +sb.parent = this; +function f() { return this.name; } +f.notMuchTodo = '42'; +assertEq(evalcx('(function () {\n' + + ' arguments = null;\n' + // force heavyweight + ' var f = parent.f;\n' + + ' var name = "call";\n' + + ' return (function () {\n' + + ' eval(f.notMuchTodo);\n' + // reify Call, make f() compile to JSOP_CALLNAME + ' var s = "";\n' + + ' for (i = 0; i < 10; ++i)\n' + + ' s += f();\n' + + ' return s;\n' + + ' })();\n' + + '})()', + sb), + "outerouterouterouterouterouterouterouterouterouter"); diff --git a/js/src/jit-test/tests/basic/testBug634590d.js b/js/src/jit-test/tests/basic/testBug634590d.js new file mode 100644 index 000000000..d2e47b51f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug634590d.js @@ -0,0 +1,19 @@ +this.name = "outer"; +var sb = evalcx(''); +sb.name = "inner"; +sb.parent = this; +this.f = function name(outer) { + if (outer) { + return function () { + return name(false); + }(); + } + return this.name; +} +assertEq(evalcx('this.f = parent.f;\n' + + 'var s = "";\n' + + 'for (i = 0; i < 10; ++i)\n' + + ' s += f(true);\n' + + 's', + sb), + "outerouterouterouterouterouterouterouterouterouter"); diff --git a/js/src/jit-test/tests/basic/testBug634590ma.js b/js/src/jit-test/tests/basic/testBug634590ma.js new file mode 100644 index 000000000..3914cba47 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug634590ma.js @@ -0,0 +1,14 @@ +// |jit-test| + +this.name = "outer"; +var sb = evalcx(''); +sb.name = "inner"; +sb.parent = this; +function f() { return this.name; } +assertEq(evalcx('this.f = parent.f;\n' + + 'var s = "";\n' + + 'for (i = 0; i < 10; ++i)\n' + + ' s += f();\n' + + 's', + sb), + "outerouterouterouterouterouterouterouterouterouter"); diff --git a/js/src/jit-test/tests/basic/testBug637014.js b/js/src/jit-test/tests/basic/testBug637014.js new file mode 100644 index 000000000..53e22f8bd --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug637014.js @@ -0,0 +1,2 @@ +var o = newGlobal(); +o.makeFinalizeObserver(); diff --git a/js/src/jit-test/tests/basic/testBug648438.js b/js/src/jit-test/tests/basic/testBug648438.js new file mode 100644 index 000000000..9bdfc0fbd --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug648438.js @@ -0,0 +1,7 @@ +for (var i = 0; i < 20; i++) { + (function () { + try { + JSON.parse(); + } catch (e) {} + }).call(); +} diff --git a/js/src/jit-test/tests/basic/testBug653396.js b/js/src/jit-test/tests/basic/testBug653396.js new file mode 100644 index 000000000..6eefdf228 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug653396.js @@ -0,0 +1,6 @@ +// |jit-test| error: RangeError +function g(a, b, c, d) {} +function f(a, b, c) { + arguments.length = getMaxArgs() + 1; + g.apply(this, arguments); +}f(); diff --git a/js/src/jit-test/tests/basic/testBug659577-1.js b/js/src/jit-test/tests/basic/testBug659577-1.js new file mode 100644 index 000000000..3ae1a605a --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug659577-1.js @@ -0,0 +1 @@ +Function("for(;(function(){([x],0)});x){}var x") diff --git a/js/src/jit-test/tests/basic/testBug659577-2.js b/js/src/jit-test/tests/basic/testBug659577-2.js new file mode 100644 index 000000000..dbd4ec240 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug659577-2.js @@ -0,0 +1,15 @@ +gczeal(4); +evaluate("\ +Date.formatFunctions = {count:0};\ +Date.prototype.dateFormat = function(format) {\ + var funcName = 'format' + Date.formatFunctions.count++;\ + var code = 'Date.prototype.' + funcName + ' = function(){return ';\ + var ch = '';\ + for (var i = 0; i < format.length; ++i) {\ + ch = format.charAt(i);\ + eval(code.substring(0, code.length - 3) + ';}');\ + }\ +};\ +var date = new Date('1/1/2007 1:11:11');\ + var shortFormat = date.dateFormat('Y-m-d');\ +"); diff --git a/js/src/jit-test/tests/basic/testBug663789-1.js b/js/src/jit-test/tests/basic/testBug663789-1.js new file mode 100644 index 000000000..4fdc262b5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug663789-1.js @@ -0,0 +1,6 @@ +function f() { + a = arguments; + return a[0] - a[1]; +} + +[1,2,3,4].sort(f); diff --git a/js/src/jit-test/tests/basic/testBug663789-2.js b/js/src/jit-test/tests/basic/testBug663789-2.js new file mode 100644 index 000000000..3e1a608bd --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug663789-2.js @@ -0,0 +1,6 @@ +load(libdir + "evalInFrame.js"); + +o = { toString:function() { return evalInFrame(1, "x") } } +var x = 'C'; +var s = "aaaaaaaaaa".replace(/a/g, function() { var x = 'B'; return o }); +assertEq(s, "CCCCCCCCCC"); diff --git a/js/src/jit-test/tests/basic/testBug666003.js b/js/src/jit-test/tests/basic/testBug666003.js new file mode 100644 index 000000000..b508e7aa5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug666003.js @@ -0,0 +1,13 @@ +function f() { + f = function() { g(); }; + f(); +} +g = f; + +var caught = false; +try { + f(); +} catch(e) { + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/testBug667915.js b/js/src/jit-test/tests/basic/testBug667915.js new file mode 100644 index 000000000..76d565b69 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug667915.js @@ -0,0 +1,8 @@ +for each(let y in [0, 0]) { + eval("\ + for each(e in[0,0,0,0,0,0,0,0]) {\ + x = undefined\ + }\ + ") +} + diff --git a/js/src/jit-test/tests/basic/testBug668479.js b/js/src/jit-test/tests/basic/testBug668479.js new file mode 100644 index 000000000..30eaca5c4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug668479.js @@ -0,0 +1,3 @@ +function a() { + with(a) eval("arguments[0]"); +} a(); diff --git a/js/src/jit-test/tests/basic/testBug672436.js b/js/src/jit-test/tests/basic/testBug672436.js new file mode 100644 index 000000000..95a6d07a1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug672436.js @@ -0,0 +1,25 @@ +try { new Error() } catch (e) {} + +const N = 18; + +var arr = []; +for (var i = 0; i < N; ++i) + arr[i] = 'a'; +arr[N] = '%'; + +function inner(i) { + decodeURI(arr[i]); +} +function outer() { + for (var i = 0; i <= N; ++i) + inner(i); +} + +var caught = false; +try { + outer(); +} catch (e) { + caught = true; +} +assertEq(caught, true); + diff --git a/js/src/jit-test/tests/basic/testBug673066.js b/js/src/jit-test/tests/basic/testBug673066.js new file mode 100644 index 000000000..28aa51802 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug673066.js @@ -0,0 +1,23 @@ +function f(code) { + a = code.replace(/s/, ""); + wtt = a + code = code.replace(/\/\*DUPTRY\d+\*\//, function(k) { + n = parseInt(k.substr(8), 0); + return g("try{}catch(e){}", n) + }); + f = eval("(function(){" + code + "})") + if (typeof disassemble == 'function') { + disassemble("-r", f) + } +} +function g(s, n) { + if (n == 0) { + return s + } + s2 = s + s + r = n % 2 + d = (n - r) / 2 + m = g(s2, d) + return r ? m + s : m +} +f("switch(''){default:break;/*DUPTRY525*/}") diff --git a/js/src/jit-test/tests/basic/testBug673068.js b/js/src/jit-test/tests/basic/testBug673068.js new file mode 100644 index 000000000..e3b622f69 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug673068.js @@ -0,0 +1,12 @@ +// |jit-test| + +function f(x) { + var x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; + var y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10; + var z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10; + if (x == 0) + return; + f(x - 1); +} + +f(1000); diff --git a/js/src/jit-test/tests/basic/testBug676486.js b/js/src/jit-test/tests/basic/testBug676486.js new file mode 100644 index 000000000..5f5de23c6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug676486.js @@ -0,0 +1,8 @@ +var proxy = new Proxy(function() { + return (function () { eval("foo") })(); + }, {}); + +try { + new proxy(); +} catch (e) { +} diff --git a/js/src/jit-test/tests/basic/testBug686274.js b/js/src/jit-test/tests/basic/testBug686274.js new file mode 100644 index 000000000..e03fd4354 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug686274.js @@ -0,0 +1,15 @@ +// Don't Baseline-compile the huge array literal with --baseline-eager +// as it's slow, especially in debug builds. +setJitCompilerOption("baseline.warmup.trigger", 2); + +function f(N) { + var body = "return ["; + for (var i = 0; i < N-1; i++) + body += "1,"; + body += "2]"; + var f = new Function(body); + var arr = f(); + assertEq(arr.length, N); + assertEq(arr[N-1], 2); +} +f(1000000); diff --git a/js/src/jit-test/tests/basic/testBug690959.js b/js/src/jit-test/tests/basic/testBug690959.js new file mode 100644 index 000000000..6f4b800c1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug690959.js @@ -0,0 +1,4 @@ +var s = 'abcdFF0123456789012345fail'; +s = s.replace("abcd", "0123456789012345678901234567890123456789012FF"); +s = s.replace("FF0123456789012345fail", "ok"); +assertEq(s, '0123456789012345678901234567890123456789012FFok'); diff --git a/js/src/jit-test/tests/basic/testBug692274-2.js b/js/src/jit-test/tests/basic/testBug692274-2.js new file mode 100644 index 000000000..dff5c9052 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug692274-2.js @@ -0,0 +1,7 @@ +function f() { + var ss = [new f("abc"), new String("foobar"), new String("quux")]; + for (let a6 = this ;; ) {} +} +try { + f(); +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/testBug692274-3.js b/js/src/jit-test/tests/basic/testBug692274-3.js new file mode 100644 index 000000000..a8c0afe65 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug692274-3.js @@ -0,0 +1,16 @@ +var x = -false; +switch(x) { + case 11: + let y = 42; +} +switch(x) { + case 11: + let y = 42; + let z = 'ponies'; +} +switch(x) { + case 11: + let y = 42; + let z = 'ponies'; + let a = false; +} diff --git a/js/src/jit-test/tests/basic/testBug701227.js b/js/src/jit-test/tests/basic/testBug701227.js new file mode 100644 index 000000000..cf12409fe --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug701227.js @@ -0,0 +1 @@ +(function f() { try {} catch(e) { let x } }).toString() diff --git a/js/src/jit-test/tests/basic/testBug701239.js b/js/src/jit-test/tests/basic/testBug701239.js new file mode 100644 index 000000000..665134c1d --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug701239.js @@ -0,0 +1 @@ +(function f(w) { for([w] in 1) {} }).toString(); diff --git a/js/src/jit-test/tests/basic/testBug701244.js b/js/src/jit-test/tests/basic/testBug701244.js new file mode 100644 index 000000000..4a9931f80 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug701244.js @@ -0,0 +1 @@ +(function f({length}) {}).toString(); diff --git a/js/src/jit-test/tests/basic/testBug703857.js b/js/src/jit-test/tests/basic/testBug703857.js new file mode 100644 index 000000000..dcdcc1e1f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug703857.js @@ -0,0 +1,13 @@ +Function.prototype.X = 42; +function ownProperties() { + var props = {}; + var r = function () {}; + for (var a in r) { + { + let a = function() { for (var r=0;r<6;++r) ++a; }; + a(); + } + props[a] = true; + } +} +ownProperties(); diff --git a/js/src/jit-test/tests/basic/testBug704351.js b/js/src/jit-test/tests/basic/testBug704351.js new file mode 100644 index 000000000..16b131468 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug704351.js @@ -0,0 +1,6 @@ +if (this.dis !== undefined) { + var generatorPrototype = (function() { yield 3; })().__proto__; + try { + this.dis(generatorPrototype); + } catch(e) {} +} diff --git a/js/src/jit-test/tests/basic/testBug705423.js b/js/src/jit-test/tests/basic/testBug705423.js new file mode 100644 index 000000000..4ce993c20 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug705423.js @@ -0,0 +1,19 @@ +gczeal(1); + +var g = newGlobal(); + +g.eval("\ +var f = function(x) { \ + arg = arguments; \ + fun = function() { return x }; \ +} \ +"); + +g.f(3); +g.f = null; +assertEq(g.fun(), 3); +assertEq(g.arg[0], 3); +gc(); +g.arg[0] = 9; +assertEq(g.fun(), 9); +assertEq(g.arg[0], 9); diff --git a/js/src/jit-test/tests/basic/testBug705879.js b/js/src/jit-test/tests/basic/testBug705879.js new file mode 100644 index 000000000..36168564c --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug705879.js @@ -0,0 +1,10 @@ +f = eval("\ + (function() {\ + with({}) {\ + yield\ + }\ + for(let d in[gc()])\ + for(b in[0,function(){}]);\ + })\ +") +for (e in f()) {} diff --git a/js/src/jit-test/tests/basic/testBug714650.js b/js/src/jit-test/tests/basic/testBug714650.js new file mode 100644 index 000000000..2284faa19 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug714650.js @@ -0,0 +1,36 @@ +{ + let [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], + [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = [], [] = []; + print("ok"); +} diff --git a/js/src/jit-test/tests/basic/testBug720695.js b/js/src/jit-test/tests/basic/testBug720695.js new file mode 100644 index 000000000..4e3dc764f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug720695.js @@ -0,0 +1,16 @@ +var v = [ -0x80000003, -0x80000002, -0x80000001, -0x80000000, -0x7fffffff, -0x7ffffffe, -0x7ffffffd, + -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 20, 21, 100, 101, 110, 111, 500, + 0x7ffffffd, 0x7ffffffe, 0x7fffffff, 0x80000000, 0x80000001, 0x80000002, 0x80000003]; + +function strcmp(x, y) { + return Number(String(x) > String(y)) +} + +for (var i = 0; i < v.length; ++i) { + for (var j = 0; j < v.length; ++j) { + var builtin = String([v[i], v[j]].sort()); + var manual = String([v[i], v[j]].sort(strcmp)); + assertEq(builtin, manual); + } +} diff --git a/js/src/jit-test/tests/basic/testBug723445.js b/js/src/jit-test/tests/basic/testBug723445.js new file mode 100644 index 000000000..7cbe0a017 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug723445.js @@ -0,0 +1,10 @@ +var global = newGlobal(); +global.eval("function f(b) { if (b) { new Error }; }"); + +function f(b) { global.f(b) } +function g(b) { f(b) } +function h() { + for (var i = 0; i < 1000; ++i) + g(i > 900); +} +h(); diff --git a/js/src/jit-test/tests/basic/testBug726380.js b/js/src/jit-test/tests/basic/testBug726380.js new file mode 100644 index 000000000..2f4475674 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug726380.js @@ -0,0 +1,2 @@ +var r = /a/; +r.compile(r); diff --git a/js/src/jit-test/tests/basic/testBug731181.js b/js/src/jit-test/tests/basic/testBug731181.js new file mode 100644 index 000000000..9ece97535 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug731181.js @@ -0,0 +1,2 @@ +gczeal(2,1); +/a/y.exec('a'); diff --git a/js/src/jit-test/tests/basic/testBug736012.js b/js/src/jit-test/tests/basic/testBug736012.js new file mode 100644 index 000000000..78767525a --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug736012.js @@ -0,0 +1,8 @@ +evaluate("\ +function fatty() {\ + try { fatty(); } catch (e) {\ + for each (foo in [1]) {}\ + }\ +}\ +fatty();\ +"); diff --git a/js/src/jit-test/tests/basic/testBug736807.js b/js/src/jit-test/tests/basic/testBug736807.js new file mode 100644 index 000000000..b279b02eb --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug736807.js @@ -0,0 +1,13 @@ +function f() { + newGlobal().eval('\ + try {\ + if (typeof gczeal === "function") \ + gczeal(2,1); \ + throw new Error();\ + } catch (e) { \ + gc(); \ + assertEq("" + e, "Error"); \ + } \ + '); +} +f({}, [1,2,4,5,6,7,8,1], new RegExp(), function() {}); diff --git a/js/src/jit-test/tests/basic/testBug737388.js b/js/src/jit-test/tests/basic/testBug737388.js new file mode 100644 index 000000000..1a97ab57f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug737388.js @@ -0,0 +1,8 @@ +function one() {}; +function two() { assertEq(arguments[0], undefined); } +function three() { + one("","","","","",""); + two(); +} +for (var i = 0; i < 10; ++i) + three(); diff --git a/js/src/jit-test/tests/basic/testBug737575.js b/js/src/jit-test/tests/basic/testBug737575.js new file mode 100644 index 000000000..5c0c9705f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug737575.js @@ -0,0 +1,6 @@ +function f(s) { + return arguments[s]; +} + +for (var i = 0; i < 10; ++i) + assertEq(f(String(i+1), 0,1,2,3,4,5,6,7,8,9), i); diff --git a/js/src/jit-test/tests/basic/testBug740442.js b/js/src/jit-test/tests/basic/testBug740442.js new file mode 100644 index 000000000..37333b8f8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug740442.js @@ -0,0 +1,10 @@ +function g1() {} +function g2() +function Int8Array () {} +function f1(other) { + eval("gc(); h = g1"); + for(var i=0; i<20; i++) { + i = i.name; + } +} +f1(g2); diff --git a/js/src/jit-test/tests/basic/testBug740445.js b/js/src/jit-test/tests/basic/testBug740445.js new file mode 100644 index 000000000..227ddfc23 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug740445.js @@ -0,0 +1,9 @@ +function testMethodInit() { + function o() {} + function k() { + for (i = 0; i < this.depth; ++i) {} + } + for (var i = 0; i < 10; i++) + (i) = {o: o, k: k}; +} +testMethodInit(); diff --git a/js/src/jit-test/tests/basic/testBug741497.js b/js/src/jit-test/tests/basic/testBug741497.js new file mode 100644 index 000000000..f61138aa4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug741497.js @@ -0,0 +1,3 @@ +// |jit-test| error: SyntaxError +"use strict"; +function inner() (([arguments, b] = this, c)()); diff --git a/js/src/jit-test/tests/basic/testBug743408.js b/js/src/jit-test/tests/basic/testBug743408.js new file mode 100644 index 000000000..2c5510658 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug743408.js @@ -0,0 +1,6 @@ +// |jit-test| error:ReferenceError +test(); +function test() { + (arguments); + F.prototype = new F(); +} diff --git a/js/src/jit-test/tests/basic/testBug747554.js b/js/src/jit-test/tests/basic/testBug747554.js new file mode 100644 index 000000000..8b77ef8a1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug747554.js @@ -0,0 +1,6 @@ +assertEq((function(x) { + (function () { x++ })(); + var z; + ({ z } = { z:'ponies' }) + return z; +})(), 'ponies'); diff --git a/js/src/jit-test/tests/basic/testBug752205.js b/js/src/jit-test/tests/basic/testBug752205.js new file mode 100644 index 000000000..edf734855 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug752205.js @@ -0,0 +1,6 @@ +var x = "one"; +var y = "two"; +const a = x + y; +var hit = false; +eval('switch("onetwo") { case a: hit = true; };'); +assertEq(hit, true); diff --git a/js/src/jit-test/tests/basic/testBug752379.js b/js/src/jit-test/tests/basic/testBug752379.js new file mode 100644 index 000000000..376657def --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug752379.js @@ -0,0 +1,10 @@ +var lfcode = new Array(); +lfcode.push(""); +lfcode.push("print('hi');"); +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + loadFile(file); +} +function loadFile(lfVarx) { + evaluate(lfVarx); +} diff --git a/js/src/jit-test/tests/basic/testBug753158.js b/js/src/jit-test/tests/basic/testBug753158.js new file mode 100644 index 000000000..50ba14b23 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug753158.js @@ -0,0 +1,67 @@ +function testFuncStmt1() { + var g = 3; + function f(b) { + if (b) { + function g() { return 42 } + assertEq(g(), 42); + } + } + f(true); +} +testFuncStmt1(); + +function testFuncStmt2() { + var g = 3; + (function(b) { + if (b) { + function g() { return 42 } + function f() { assertEq(g(), 42); } + f(); + } + })(true); +} +testFuncStmt2(); + +function testEval1() { + var g = 3; + function f() { + eval("var g = 42"); + assertEq(g, 42); + } + f(); +} +testEval1(); + +function testEval2() { + var g = 3; + (function() { + eval("var g = 42"); + function f() { + assertEq(g, 42); + } + f(); + })(); +} +testEval2(); + +function testWith1() { + var g = 3; + function f() { + with ({g:42}) { + assertEq(g, 42); + } + } + f(); +} +testWith1(); + +function testWith2() { + var g = 3; + with ({g:42}) { + function f() { + assertEq(g, 42); + } + } + f(); +} +testWith2(); diff --git a/js/src/jit-test/tests/basic/testBug755916.js b/js/src/jit-test/tests/basic/testBug755916.js new file mode 100644 index 000000000..157d3073a --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug755916.js @@ -0,0 +1,12 @@ +// |jit-test| error:InternalError + +Object.defineProperty(this, "t2", { + get: function() { + for (p in h2) { + t2 + } + } +}) +h2 = {} +h2.a = function() {} +Object(t2) diff --git a/js/src/jit-test/tests/basic/testBug756918.js b/js/src/jit-test/tests/basic/testBug756918.js new file mode 100644 index 000000000..2787b3881 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug756918.js @@ -0,0 +1,6 @@ +// |jit-test| error:Error + +with({}) + let([] = []) { + eval("throw new Error()"); + } diff --git a/js/src/jit-test/tests/basic/testBug756919.js b/js/src/jit-test/tests/basic/testBug756919.js new file mode 100644 index 000000000..47d45f160 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug756919.js @@ -0,0 +1,10 @@ +// |jit-test| allow-oom; allow-overrecursed + +gcparam("maxBytes", gcparam("gcBytes") + 1024); +test(); +function test() { + var upvar = ""; + function f() { upvar += ""; } + test(); + eval(''); +} diff --git a/js/src/jit-test/tests/basic/testBug761863.js b/js/src/jit-test/tests/basic/testBug761863.js new file mode 100644 index 000000000..fc5c12d20 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug761863.js @@ -0,0 +1,12 @@ +gczeal(4); +function blah() { + var i = 1; + function o() {} + function k() { i++; } + o.x = 0; + for (var j = 0; j < 100; ++j) { + i = {a: o, b: k}; + i++; + } +} +blah(); diff --git a/js/src/jit-test/tests/basic/testBug7618864.js b/js/src/jit-test/tests/basic/testBug7618864.js new file mode 100644 index 000000000..9b9ba0ec4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug7618864.js @@ -0,0 +1,55 @@ +function printStatus (msg) { + var lines = msg.split (""); +} +function printBugNumber (num) { + var digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]; +} +var lfcode = new Array(); +lfcode.push("gczeal(4);"); +lfcode.push("jsTestDriverEnd();"); +lfcode.push(""); +lfcode.push("var BUGNUMBER = \"(none)\";\ +var summary = \"gen.close(); gen.throw(ex) throws ex forever\";\ +var actual, expect;\ +printBugNumber(BUGNUMBER);\ +printStatus(summary);\ +function gen() {\ + var x = 5, y = 7;\ + yield z;\ +}\ +var failed = false;\ +var it = gen();\ +try {\ + it.close();\ + var doThrow = true;\ + var thrown = \"foobar\";\ + try { } catch (e) { }\ + try { } catch (e) { }\ + throw \"it.throw(\\\"\" + thrown + \"\\\") failed\";\ + var stopPassed = false;\ + try { } catch (e) {\ + if (\"1234\")\ + stopPassed = true;\ + }\ +} catch (e) {}\ +"); +var lfRunTypeId = -1; +while (true) { + var file = lfcode.shift(); if (file == undefined) { break; } + if (file == "evaluate") { + } else { + loadFile(file); + } +} +function loadFile(lfVarx) { + try { + if (lfVarx.substr(-3) == ".js") { + } else { + switch (lfRunTypeId) { + default: evaluate(lfVarx); + } + } + } catch (lfVare) { + print(lfVare); + } +} diff --git a/js/src/jit-test/tests/basic/testBug762105.js b/js/src/jit-test/tests/basic/testBug762105.js new file mode 100644 index 000000000..147a87eac --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug762105.js @@ -0,0 +1,33 @@ +function escapeme() {} + +function f1(x) { + escapeme(arguments); + var y = ++x; + return x + y; +} +for (var i = 0; i < 100; ++i) + assertEq(f1(2), 6); + +function f2(x) { + escapeme(arguments); + var y = --x; + return x + y; +} +for (var i = 0; i < 100; ++i) + assertEq(f2(2), 2); + +function f3(x) { + escapeme(arguments); + var y = x++; + return x + y; +} +for (var i = 0; i < 100; ++i) + assertEq(f3(2), 5); + +function f4(x) { + escapeme(arguments); + var y = x--; + return x + y; +} +for (var i = 0; i < 100; ++i) + assertEq(f4(2), 3); diff --git a/js/src/jit-test/tests/basic/testBug762432.js b/js/src/jit-test/tests/basic/testBug762432.js new file mode 100644 index 000000000..c010aefc1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug762432.js @@ -0,0 +1,15 @@ +function getter() { return 1; } +function setter() { } +function getDescriptor(target, name) { + if (name != 'prop') + throw "Unknown property: " + name; + return { configurable: true, enumerable: true, get: getter, set: setter }; +} +var handler = { + getOwnPropertyDescriptor: getDescriptor, +}; + +// Make sure that __lookup{Getter,Setter}__ works on proxies. +var proxy = new Proxy({}, handler); +assertEq(Object.prototype.__lookupGetter__.call(proxy, 'prop'), getter); +assertEq(Object.prototype.__lookupSetter__.call(proxy, 'prop'), setter); diff --git a/js/src/jit-test/tests/basic/testBug762450.js b/js/src/jit-test/tests/basic/testBug762450.js new file mode 100644 index 000000000..2813015a6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug762450.js @@ -0,0 +1,7 @@ +function f(a, b, c) { + arguments[0] = 3; + return (c--) + 1; +} +var r = f(); +print(r); +assertEq(r !== r, true); diff --git a/js/src/jit-test/tests/basic/testBug762473.js b/js/src/jit-test/tests/basic/testBug762473.js new file mode 100644 index 000000000..d79bc2e2e --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug762473.js @@ -0,0 +1,49 @@ +function f(i) { + var a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a16,a17; + var b = true; + if (b) + function f1() {} + if (b) + function f2() {} + if (b) + function f3() {} + if (b) + function f4() {} + if (b) + function f5() {} + if (b) + function f6() {} + if (b) + function f7() {} + if (b) + function f8() {} + if (b) + function f9() {} + if (b) + function f10() {} + if (b) + function f11() {} + if (b) + function f12() {} + if (b) + function f13() {} + if (b) + function f14() {} + if (b) + function f15() {} + if (b) + function f16() {} + if (b) + function f17() {} + + a1 = i; + + function f() { + return a1; + } + + return f(); +} + +for (var i = 0; i < 100; ++i) + assertEq(f(i), i); diff --git a/js/src/jit-test/tests/basic/testBug763384.js b/js/src/jit-test/tests/basic/testBug763384.js new file mode 100644 index 000000000..572941366 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug763384.js @@ -0,0 +1,9 @@ +var caught = false; +try { + ''.match('('); +} catch (e) { + caught = true; + assertEq(e instanceof Error, true); + assertEq(('' + e).indexOf('SyntaxError') === -1, false); +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/testBug763950.js b/js/src/jit-test/tests/basic/testBug763950.js new file mode 100644 index 000000000..6f685217f --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug763950.js @@ -0,0 +1,6 @@ +(function() { + var x; + for (let j = 0; j < 1; j = j + 1) + x = function() { return j; }; + assertEq(x(), 0); +})(); diff --git a/js/src/jit-test/tests/basic/testBug766064.js b/js/src/jit-test/tests/basic/testBug766064.js new file mode 100644 index 000000000..cd13f1f67 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug766064.js @@ -0,0 +1,7 @@ +function loop(actual = 0) { + if (function() { actual++ }) + {} + return actual; +} + +assertEq(loop(), 0); diff --git a/js/src/jit-test/tests/basic/testBug769987.js b/js/src/jit-test/tests/basic/testBug769987.js new file mode 100644 index 000000000..52bcdc111 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug769987.js @@ -0,0 +1,13 @@ +function h(code) { + f = Function(code); + g() +} +function g() { + f() +} +h() +h() +h("\ + arguments[\"0\"];\ + gc();\ +") diff --git a/js/src/jit-test/tests/basic/testBug770407.js b/js/src/jit-test/tests/basic/testBug770407.js new file mode 100644 index 000000000..54184fab4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug770407.js @@ -0,0 +1,4 @@ +// |jit-test| error:TypeError +var otherGlobal = newGlobal(); +var proxy = new (otherGlobal.Proxy)({}, {}); +Int8Array.set(proxy); diff --git a/js/src/jit-test/tests/basic/testBug772328.js b/js/src/jit-test/tests/basic/testBug772328.js new file mode 100644 index 000000000..4b465b0a2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug772328.js @@ -0,0 +1,20 @@ +function f(x) { + function x() {} + arguments[0] = 42; + return x; +} +assertEq(f(0), 42); + +function g(x) { + function x() {} + assertEq(arguments[0], x); +} +g(0); + +var caught = false; +try { + (function h(x) { function x() {} }).blah.baz; +} catch (e) { + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/testBug775801.js b/js/src/jit-test/tests/basic/testBug775801.js new file mode 100644 index 000000000..35ced600e --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug775801.js @@ -0,0 +1,8 @@ +function f() { + var x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,x20; + var b = {a:'ponies'}; + eval(''); + return function(e) { return b[e] } +} + +assertEq("aaa".replace(/a/g, f()), "poniesponiesponies"); diff --git a/js/src/jit-test/tests/basic/testBug775807.js b/js/src/jit-test/tests/basic/testBug775807.js new file mode 100644 index 000000000..b136b0a81 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug775807.js @@ -0,0 +1,19 @@ +// |jit-test| --dump-bytecode + +(function() { + const x = ((function() { + return { + e: function() { + (function() { + for (e in x) {} + })() + } + } + }(function() { + return { + t: { + c + } + } + }))) +})() diff --git a/js/src/jit-test/tests/basic/testBug776191.js b/js/src/jit-test/tests/basic/testBug776191.js new file mode 100644 index 000000000..043e50111 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug776191.js @@ -0,0 +1,8 @@ +(function() { + { + let a, b, c; + ((function() { + with({}) { { let b; { ((function() { c = 0 })()) } } } + })()) + } +})() diff --git a/js/src/jit-test/tests/basic/testBug778603.js b/js/src/jit-test/tests/basic/testBug778603.js new file mode 100644 index 000000000..9df17d04e --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug778603.js @@ -0,0 +1 @@ +assertEq(unescape("0%u0000".substr(0,2)), "0%"); diff --git a/js/src/jit-test/tests/basic/testBug780288-1.js b/js/src/jit-test/tests/basic/testBug780288-1.js new file mode 100644 index 000000000..90746a04a --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug780288-1.js @@ -0,0 +1,20 @@ +s = newGlobal() +try { + evalcx("\ + Object.defineProperty(this,\"i\",{enumerable:true,get:function(){t}});\ + for each(y in this)true\ + ", s) +} catch (e) {} +try { + evalcx("\ + for(z=0,(7).watch(\"\",eval);;g){\ + if(z=1){({t:function(){}})\ + }\ + ", s) +} catch (e) {} +try { + evalcx("\ + Object.defineProperty(this,\"g2\",{get:function(){return this}});\ + g2.y()\ + ", s) +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/testBug780288-2.js b/js/src/jit-test/tests/basic/testBug780288-2.js new file mode 100644 index 000000000..8c4c1737c --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug780288-2.js @@ -0,0 +1,20 @@ +s = newGlobal() +try { + evalcx("\ + Object.defineProperty(this,\"i\",{enumerable:true,get:function(){t}});\ + for each(y in this)true\ + ", s) +} catch (e) {} +try { + evalcx("\ + for(z=0,(7).watch(\"\",eval);;g){\ + if(z=1){({t:function(){}})\ + }\ + ", s) +} catch (e) {} +try { + evalcx("\ + Object.defineProperty(this,\"g2\",{get:function(){return this}});\ + g2.y(\"\")\ + ", s) +} catch (e) {} diff --git a/js/src/jit-test/tests/basic/testBug780712.js b/js/src/jit-test/tests/basic/testBug780712.js new file mode 100644 index 000000000..25df27b40 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug780712.js @@ -0,0 +1,9 @@ +r = evalcx("/x/", undefined); +s = ""; +gc() +Function("\ + s.match(r);\ + schedulegc(__proto__);\ + ({c:schedulegc(2)});\ + s.match(r);\ +")() diff --git a/js/src/jit-test/tests/basic/testBug783441.js b/js/src/jit-test/tests/basic/testBug783441.js new file mode 100644 index 000000000..088ecc8b1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug783441.js @@ -0,0 +1 @@ +assertEq((function(x, y, x) { return (function() x+y)(); })(1,2,5), 7); diff --git a/js/src/jit-test/tests/basic/testBug783540.js b/js/src/jit-test/tests/basic/testBug783540.js new file mode 100644 index 000000000..618570707 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug783540.js @@ -0,0 +1,5 @@ +gczeal(2, 2) +var stringA = "abcdef"; +var stringB = "ghijk"; +var stringC = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; +(stringA + stringB + stringC).replace('abc', 'AA') diff --git a/js/src/jit-test/tests/basic/testBug783543.js b/js/src/jit-test/tests/basic/testBug783543.js new file mode 100644 index 000000000..80e3495fc --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug783543.js @@ -0,0 +1,11 @@ +// |jit-test| error:ReferenceError + +try { + evaluate(" (function(c) { const x = 1; for (x in null); })();"); + var expect = "Passed"; +} catch ( e ) { + result = expect; +} +schedulegc(10); +eval("var o = new MyObject(); var result = 0; for (var o in foo) { result += this[o]; } ") +function MyObject() {} diff --git a/js/src/jit-test/tests/basic/testBug784639.js b/js/src/jit-test/tests/basic/testBug784639.js new file mode 100644 index 000000000..1380ae6ed --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug784639.js @@ -0,0 +1,17 @@ +evalcx("\ + Object.defineProperty(this, \"a\", {});\ + f = (function(j) {\ + a = Proxy\ + });\ + Object.defineProperty(this, \"g\", {\ + get: function() {\ + return ({\ + r: function() {},\ + t: function() {}\ + })\ + }\ + });\ + for (p in g) {\ + f(1)\ + }\ +", newGlobal()) diff --git a/js/src/jit-test/tests/basic/testBug840012.js b/js/src/jit-test/tests/basic/testBug840012.js new file mode 100644 index 000000000..33ce4d646 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug840012.js @@ -0,0 +1,18 @@ +// |jit-test| allow-oom; allow-overrecursed + +gcPreserveCode(); +evaluate("gcparam(\"maxBytes\", gcparam(\"gcBytes\") + 4*1024);"); +evaluate("\ +function testDontEnum(F) { \ + function test() {\ + var upvar = \"\";\ + function f() { upvar += \"\"; }\ + typeof (new test(\"1\")) != 'function'\ + }\ + test();\ +} \ +var list = [];\ +for (i in list)\ + var F = this[list[i]];\ +actual = testDontEnum(F);\ +"); diff --git a/js/src/jit-test/tests/basic/testBug878429.js b/js/src/jit-test/tests/basic/testBug878429.js new file mode 100644 index 000000000..edbb0523b --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug878429.js @@ -0,0 +1,9 @@ +function negZeroMinusNegZero() +{ + var x = -0.0; + var y = -0.0; + return +(x - y); +} + +assertEq(1 / negZeroMinusNegZero(), Infinity); +assertEq(1 / negZeroMinusNegZero(), Infinity); diff --git a/js/src/jit-test/tests/basic/testBug895774.js b/js/src/jit-test/tests/basic/testBug895774.js new file mode 100644 index 000000000..c97d095f6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug895774.js @@ -0,0 +1,14 @@ +var g1 = newGlobal(); +var g2 = newGlobal(); +g1.eval("function f1() { debugger; evaluate('debugger') }"); +g2.eval("function f2() { f1(); assertEq(Number(this), 42) }"); +g2.f1 = g1.f1; + +var dbg = new Debugger(g1,g2); +dbg.onDebuggerStatement = function(frame) { + var target = frame.older; + dbg.onDebuggerStatement = function(frame) { + assertEq(Number(target.this.unsafeDereference()), 42); + } +} +g2.f2.call(42); diff --git a/js/src/jit-test/tests/basic/testBug961969.js b/js/src/jit-test/tests/basic/testBug961969.js new file mode 100644 index 000000000..999e15e1d --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug961969.js @@ -0,0 +1,2 @@ +(()=>{ var x,y,z; ()=>{x++;y++;z++} })(); +(()=>{ var x,y; if (true) { function z() { x++;y++ } } })(); diff --git a/js/src/jit-test/tests/basic/testCallApply.js b/js/src/jit-test/tests/basic/testCallApply.js new file mode 100644 index 000000000..9141f80bc --- /dev/null +++ b/js/src/jit-test/tests/basic/testCallApply.js @@ -0,0 +1,168 @@ +function script1() { return arguments.length; } +function script2(x) { return x; } +function script3(x) { var o = arguments; return o[0]; } +function genClosure() { var x = 3; eval("x = 4"); return function(y) { return x + y } }; +var closed1 = genClosure(); +var closed2 = genClosure(); +var closed3 = genClosure(); +var native1 = String.prototype.search; +var native2 = String.prototype.match; +var tricky1 = { call:function(x,y) { return y }, apply:function(x,y) { return y } }; + +test0(); +test1(); +test2(); +test3(); + +function test0() { + assertEq(script1.call(null), 0); + assertEq(script1.call(null, 1), 1); + assertEq(script1.call(null, 1,2), 2); + assertEq(native1.call("aabc", /b/), 2); + assertEq(native1.call("abc"), 0); + assertEq(tricky1.call(null, 9), 9); + assertEq(script1.apply(null), 0); + assertEq(script1.apply(null, [1]), 1); + assertEq(script1.apply(null, [1,2]), 2); + assertEq(native1.apply("aabc", [/b/]), 2); + assertEq(native1.apply("abc"), 0); + assertEq(tricky1.apply(null, 1), 1); +} +test0(); + +function test1() { + function f(arr) { + for (var i = 0; i < 10; ++i) { + for (var j = 0; j < arr.length; ++j) { + arr[j].call('a'); + arr[j].apply('a', []); + var arg0 = []; + arr[j].apply('a', arg0); + (function() { arr[j].apply('a', arguments); })(); + + arr[j].call('a', 1); + arr[j].apply('a', [1]); + var arg0 = [1]; + arr[j].apply('a', arg0); + (function() { arr[j].apply('a', arguments); })(1); + + arr[j].call('a', 1,'g'); + arr[j].apply('a', [1,'g']); + var arg0 = [1,'g']; + arr[j].apply('a', arg0); + (function() { arr[j].apply('a', arguments); })(1,'g'); + + arr[j].call('a', 1,'g',3,4,5,6,7,8,9); + arr[j].apply('a', [1,'g',3,4,5,6,7,8,9]); + var arg0 = [1,'g',3,4,5,6,7,8,9]; + arr[j].apply('a', arg0); + (function() { arr[j].apply('a', arguments); })(1,'g',3,4,5,6,7,8,9); + } + } + } + + f([script1, script1, script1, script1, script2, script2, script1, script2]); + f([script1, script2, script3, script1, script2, script3, script3, script3]); + f([script1, script2, script2, script2, script2, script3, script1, script2]); + f([script1, script1, script1, native1, native1, native1, native1, script1]); + f([native1, native1, native1, native2, native2, native2, native2, native1]); + f([native1, native2, native1, native2, native1, native2, native1, native2]); + f([native1, native1, native1, script1, script2, script2, native1, script3]); + f([closed1, closed1, closed1, closed2, closed2, closed2, script3, script3]); + f([closed1, closed2, closed1, closed2, closed1, closed2, closed1, closed2]); + f([closed1, closed2, closed3, closed1, closed2, closed3, script1, script2]); + f([closed1, closed1, closed1, closed2, closed2, closed2, native1, native2]); + f([closed1, closed1, closed1, closed2, closed2, closed2, native1, native2]); + f([native1, native1, native1, closed1, closed2, script1, script2, native2]); +} + +// test things that break our speculation +function test2() { + var threw = false; + try { + (3).call(null, 1,2); + } catch (e) { + threw = true; + } + assertEq(threw, true); + + var threw = false; + try { + (3).apply(null, [1,2]); + } catch (e) { + threw = true; + } + assertEq(threw, true); + + var threw = false; + try { + var arr = [1,2]; + (3).apply(null, arr); + } catch (e) { + threw = true; + } + assertEq(threw, true); + + function tryAndFail(o) { + var threw = false; + try { + o.call(null, 1,2); + } catch(e) { + threw = true; + } + assertEq(threw, true); + threw = false; + try { + o.apply(null, [1,2]); + } catch(e) { + threw = true; + } + assertEq(threw, true); + } + + tryAndFail(1); + tryAndFail({}); + tryAndFail({call:{}, apply:{}}); + tryAndFail({call:function() { throw "not js_fun_call"}, apply:function(){ throw "not js_fun_apply" }}); +} + +// hit the stubs::CompileFunction path +function test3() { + function genFreshFunction(s) { return new Function(s, "return " + s); } + + function callIt(f) { + assertEq(f.call(null, 1,2), 1); + } + callIt(script2); callIt(script2); callIt(script2); callIt(script2); + callIt(genFreshFunction("x")); + callIt(genFreshFunction("y")); + callIt(genFreshFunction("z")); + + function applyIt(f) { + var arr = [1,2]; + assertEq(f.apply(null, arr), 1); + } + applyIt(script2); applyIt(script2); applyIt(script2); applyIt(script2); + applyIt(genFreshFunction("x")); + applyIt(genFreshFunction("y")); + applyIt(genFreshFunction("z")); + + function applyIt1(f) { + function g() { + assertEq(f.apply(null, arguments), 1); + } + g(1,2); + } + applyIt1(script2); applyIt1(script2); applyIt1(script2); applyIt1(script2); + applyIt1(genFreshFunction("x")); + applyIt1(genFreshFunction("y")); + applyIt1(genFreshFunction("z")); + + function applyIt2(f) { + assertEq(f.apply(null, [1,2]), 1); + } + applyIt2(script2); applyIt2(script2); applyIt2(script2); applyIt2(script2); + applyIt2(genFreshFunction("x")); + applyIt2(genFreshFunction("y")); + applyIt2(genFreshFunction("z")); +} diff --git a/js/src/jit-test/tests/basic/testCallApplySpeculationFailed.js b/js/src/jit-test/tests/basic/testCallApplySpeculationFailed.js new file mode 100644 index 000000000..f1b127839 --- /dev/null +++ b/js/src/jit-test/tests/basic/testCallApplySpeculationFailed.js @@ -0,0 +1,5 @@ +function foo(n) { return n; } +foo.apply = function(a, b) { return b[0]; } +function bar(value) { return foo.apply(null, arguments); } +for (var i = 1 ; i < 4; i++) + assertEq(bar(i), i); diff --git a/js/src/jit-test/tests/basic/testCallElem.js b/js/src/jit-test/tests/basic/testCallElem.js new file mode 100644 index 000000000..b40553edc --- /dev/null +++ b/js/src/jit-test/tests/basic/testCallElem.js @@ -0,0 +1,17 @@ +function testCALLELEM() +{ + function f() { + return 5; + } + + function g() { + return 7; + } + + var x = [f,f,f,f,g]; + var y = 0; + for (var i = 0; i < 5; ++i) + y = x[i](); + return y; +} +assertEq(testCALLELEM(), 7); diff --git a/js/src/jit-test/tests/basic/testCallFunctionPrototypeInALoop.js b/js/src/jit-test/tests/basic/testCallFunctionPrototypeInALoop.js new file mode 100644 index 000000000..5930cdc90 --- /dev/null +++ b/js/src/jit-test/tests/basic/testCallFunctionPrototypeInALoop.js @@ -0,0 +1,4 @@ +var x; +for (var a = 0; a < 8; a++) { + Function.prototype() +} diff --git a/js/src/jit-test/tests/basic/testCallPick.js b/js/src/jit-test/tests/basic/testCallPick.js new file mode 100644 index 000000000..7f1d9ade0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testCallPick.js @@ -0,0 +1,18 @@ +function testCallPick() { + function g(x,a) { + x.f(); + } + + var x = []; + x.f = function() { } + + var y = []; + y.f = function() { } + + var z = [x,x,x,x,x,y,y,y,y,y]; + + for (var i = 0; i < 10; ++i) + g.call(this, z[i], ""); + return true; +} +assertEq(testCallPick(), true); diff --git a/js/src/jit-test/tests/basic/testCallProtoMethod.js b/js/src/jit-test/tests/basic/testCallProtoMethod.js new file mode 100644 index 000000000..cd0be83cc --- /dev/null +++ b/js/src/jit-test/tests/basic/testCallProtoMethod.js @@ -0,0 +1,14 @@ +function testCallProtoMethod() { + function X() { this.x = 1; } + X.prototype.getName = function () { return "X"; } + + function Y() { this.x = 2; } + Y.prototype.getName = function() "Y"; + + var a = [new X, new X, new X, new X, new Y]; + var s = ''; + for (var i = 0; i < a.length; i++) + s += a[i].getName(); + return s; +} +assertEq(testCallProtoMethod(), 'XXXXY'); diff --git a/js/src/jit-test/tests/basic/testCaseAbort.js b/js/src/jit-test/tests/basic/testCaseAbort.js new file mode 100644 index 000000000..4e594bb86 --- /dev/null +++ b/js/src/jit-test/tests/basic/testCaseAbort.js @@ -0,0 +1,16 @@ +function testCaseAbort() +{ + var four = "4"; + var r = 0; + for (var i = 0; i < 5; i++) + { + switch (i) + { + case four: r += 1; break; + default: r += 2; break; + } + } + + return "" + r; +} +assertEq(testCaseAbort(), "10"); diff --git a/js/src/jit-test/tests/basic/testCaseTypeMismatchBadness.js b/js/src/jit-test/tests/basic/testCaseTypeMismatchBadness.js new file mode 100644 index 000000000..4bacba9aa --- /dev/null +++ b/js/src/jit-test/tests/basic/testCaseTypeMismatchBadness.js @@ -0,0 +1,19 @@ +function testCaseTypeMismatchBadness() +{ + for (var z = 0; z < 3; ++z) + { + switch ("") + { + default: + case 9: + break; + + case "": + case {}: + break; + } + } + + return "no crash"; +} +assertEq(testCaseTypeMismatchBadness(), "no crash"); diff --git a/js/src/jit-test/tests/basic/testChangingObjectWithLength.js b/js/src/jit-test/tests/basic/testChangingObjectWithLength.js new file mode 100644 index 000000000..9269d0de5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testChangingObjectWithLength.js @@ -0,0 +1,33 @@ +function testChangingObjectWithLength() +{ + var obj = { length: 10 }; + var dense = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + var slow = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; slow.slow = 5; + + /* + * The elements of objs constitute a De Bruijn sequence repeated 4x to trace + * and run native code for every object and transition. + */ + var objs = [obj, obj, obj, obj, + obj, obj, obj, obj, + dense, dense, dense, dense, + obj, obj, obj, obj, + slow, slow, slow, slow, + dense, dense, dense, dense, + dense, dense, dense, dense, + slow, slow, slow, slow, + slow, slow, slow, slow, + obj, obj, obj, obj]; + + var counter = 0; + + for (var i = 0, sz = objs.length; i < sz; i++) + { + var o = objs[i]; + for (var j = 0; j < o.length; j++) + counter++; + } + + return counter; +} +assertEq(testChangingObjectWithLength(), 400); diff --git a/js/src/jit-test/tests/basic/testChangingTypeDuringRecording.js b/js/src/jit-test/tests/basic/testChangingTypeDuringRecording.js new file mode 100644 index 000000000..5c6a576ca --- /dev/null +++ b/js/src/jit-test/tests/basic/testChangingTypeDuringRecording.js @@ -0,0 +1,6 @@ +X = { value: "" } +z = 0; +for (var i = 0; i < 20; i++) { + Object.defineProperty(this, "z", X); + z = 1; +} diff --git a/js/src/jit-test/tests/basic/testClosedVarInExtensibleScope.js b/js/src/jit-test/tests/basic/testClosedVarInExtensibleScope.js new file mode 100644 index 000000000..f06efa6bd --- /dev/null +++ b/js/src/jit-test/tests/basic/testClosedVarInExtensibleScope.js @@ -0,0 +1,13 @@ +function runTest() {
+ if (Math) {
+ function createTester(options) {
+ return function() {
+ return options.blah;
+ };
+ }
+
+ return createTester({blah:"bar"});
+ }
+}
+
+assertEq(runTest()(), "bar");
diff --git a/js/src/jit-test/tests/basic/testClosingRecursion.js b/js/src/jit-test/tests/basic/testClosingRecursion.js new file mode 100644 index 000000000..5b76d2ab1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testClosingRecursion.js @@ -0,0 +1,13 @@ +// Test no assert (bug 464089) +function shortRecursiveLoop(b, c) { + for (var i = 0; i < c; i++) { + if (b) + shortRecursiveLoop(c - 1); + } +} +function testClosingRecursion() { + shortRecursiveLoop(false, 1); + shortRecursiveLoop(true, 3); + return true; +} +assertEq(testClosingRecursion(), true); diff --git a/js/src/jit-test/tests/basic/testClosureIncrSideExit.js b/js/src/jit-test/tests/basic/testClosureIncrSideExit.js new file mode 100644 index 000000000..04251e3f3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testClosureIncrSideExit.js @@ -0,0 +1,19 @@ +function testClosureIncrSideExit() { + { + let f = function (y) { + { + let ff = function (g) { + for each(let h in g) { + if (++y > 5) { + return 'ddd'; + } + } + return 'qqq'; + }; + return ff(['', null, '', false, '', '', null]); + } + }; + return f(-1); + } +} +assertEq(testClosureIncrSideExit(), "ddd"); diff --git a/js/src/jit-test/tests/basic/testClosures.js b/js/src/jit-test/tests/basic/testClosures.js new file mode 100644 index 000000000..a8152c209 --- /dev/null +++ b/js/src/jit-test/tests/basic/testClosures.js @@ -0,0 +1,18 @@ +function testClosures() +{ + function MyObject(id) { + var thisObject = this; + this.id = id; + this.toString = str; + + function str() { + return "" + this.id + thisObject.id; + } + } + + var a = []; + for (var i = 0; i < 5; i++) + a.push(new MyObject(i)); + return a.toString(); +} +assertEq(testClosures(), "00,11,22,33,44"); diff --git a/js/src/jit-test/tests/basic/testComparisons.js b/js/src/jit-test/tests/basic/testComparisons.js new file mode 100644 index 000000000..b4ae997d5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testComparisons.js @@ -0,0 +1,988 @@ +function testComparisons() +{ + // All the special values from each of the types in + // ECMA-262, 3rd ed. section 8 + var undefinedType, nullType, booleanType, stringType, numberType, objectType; + + var types = []; + types[undefinedType = 0] = "Undefined"; + types[nullType = 1] = "Null"; + types[booleanType = 2] = "Boolean"; + types[stringType = 3] = "String"; + types[numberType = 4] = "Number"; + types[objectType = 5] = "Object"; + + var JSVAL_INT_MIN = -Math.pow(2, 30); + var JSVAL_INT_MAX = Math.pow(2, 30) - 1; + + // Values from every ES3 type, hitting all the edge-case and special values + // that can be dreamed up + var values = + { + "undefined": + { + value: function() { return undefined; }, + type: undefinedType + }, + "null": + { + value: function() { return null; }, + type: nullType + }, + "true": + { + value: function() { return true; }, + type: booleanType + }, + "false": + { + value: function() { return false; }, + type: booleanType + }, + '""': + { + value: function() { return ""; }, + type: stringType + }, + '"a"': + { + // a > [, for string-object comparisons + value: function() { return "a"; }, + type: stringType + }, + '"Z"': + { + // Z < [, for string-object comparisons + value: function() { return "Z"; }, + type: stringType + }, + "0": + { + value: function() { return 0; }, + type: numberType + }, + "-0": + { + value: function() { return -0; }, + type: numberType + }, + "1": + { + value: function() { return 1; }, + type: numberType + }, + "Math.E": + { + value: function() { return Math.E; }, + type: numberType + }, + "JSVAL_INT_MIN - 1": + { + value: function() { return JSVAL_INT_MIN - 1; }, + type: numberType + }, + "JSVAL_INT_MIN": + { + value: function() { return JSVAL_INT_MIN; }, + type: numberType + }, + "JSVAL_INT_MIN + 1": + { + value: function() { return JSVAL_INT_MIN + 1; }, + type: numberType + }, + "JSVAL_INT_MAX - 1": + { + value: function() { return JSVAL_INT_MAX - 1; }, + type: numberType + }, + "JSVAL_INT_MAX": + { + value: function() { return JSVAL_INT_MAX; }, + type: numberType + }, + "JSVAL_INT_MAX + 1": + { + value: function() { return JSVAL_INT_MAX + 1; }, + type: numberType + }, + "Infinity": + { + value: function() { return Infinity; }, + type: numberType + }, + "-Infinity": + { + value: function() { return -Infinity; }, + type: numberType + }, + "NaN": + { + value: function() { return NaN; }, + type: numberType + }, + "{}": + { + value: function() { return {}; }, + type: objectType + }, + "{ valueOf: undefined }": + { + value: function() { return { valueOf: undefined }; }, + type: objectType + }, + "[]": + { + value: function() { return []; }, + type: objectType + }, + '[""]': + { + value: function() { return [""]; }, + type: objectType + }, + '["a"]': + { + value: function() { return ["a"]; }, + type: objectType + }, + "[0]": + { + value: function() { return [0]; }, + type: objectType + } + }; + + var orderOps = + { + "<": function(a, b) { return a < b; }, + ">": function(a, b) { return a > b; }, + "<=": function(a, b) { return a <= b; }, + ">=": function(a, b) { return a >= b; } + }; + var eqOps = + { + "==": function(a, b) { return a == b; }, + "!=": function(a, b) { return a != b; }, + "===": function(a, b) { return a === b; }, + "!==": function(a, b) { return a !== b; } + }; + + + var notEqualIncomparable = + { + eq: { "==": false, "!=": true, "===": false, "!==": true }, + order: { "<": false, ">": false, "<=": false, ">=": false } + }; + var notEqualLessThan = + { + eq: { "==": false, "!=": true, "===": false, "!==": true }, + order: { "<": true, ">": false, "<=": true, ">=": false } + }; + var notEqualGreaterThan = + { + eq: { "==": false, "!=": true, "===": false, "!==": true }, + order: { "<": false, ">": true, "<=": false, ">=": true } + }; + var notEqualNorDifferent = + { + eq: { "==": false, "!=": true, "===": false, "!==": true }, + order: { "<": false, ">": false, "<=": true, ">=": true } + }; + var strictlyEqual = + { + eq: { "==": true, "!=": false, "===": true, "!==": false }, + order: { "<": false, ">": false, "<=": true, ">=": true } + }; + var looselyEqual = + { + eq: { "==": true, "!=": false, "===": false, "!==": true }, + order: { "<": false, ">": false, "<=": true, ">=": true } + }; + var looselyEqualNotDifferent = + { + eq: { "==": true, "!=": false, "===": false, "!==": true }, + order: { "<": false, ">": false, "<=": true, ">=": true } + }; + var looselyEqualIncomparable = + { + eq: { "==": true, "!=": false, "===": false, "!==": true }, + order: { "<": false, ">": false, "<=": false, ">=": false } + }; + var strictlyEqualNotDifferent = + { + eq: { "==": true, "!=": false, "===": true, "!==": false }, + order: { "<": false, ">": false, "<=": true, ">=": true } + }; + var strictlyEqualIncomparable = + { + eq: { "==": true, "!=": false, "===": true, "!==": false }, + order: { "<": false, ">": false, "<=": false, ">=": false } + }; + + var comparingZeroToSomething = + { + "undefined": notEqualIncomparable, + "null": notEqualNorDifferent, + "true": notEqualLessThan, + "false": looselyEqual, + '""': looselyEqualNotDifferent, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": strictlyEqual, + "-0": strictlyEqual, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": looselyEqual, + '[""]': looselyEqual, + '["a"]': notEqualIncomparable, + "[0]": looselyEqual + }; + + var comparingObjectOrObjectWithValueUndefined = + { + "undefined": notEqualIncomparable, + "null": notEqualIncomparable, + "true": notEqualIncomparable, + "false": notEqualIncomparable, + '""': notEqualGreaterThan, + '"a"': notEqualLessThan, + '"Z"': notEqualGreaterThan, + "0": notEqualIncomparable, + "-0": notEqualIncomparable, + "1": notEqualIncomparable, + "Math.E": notEqualIncomparable, + "JSVAL_INT_MIN - 1": notEqualIncomparable, + "JSVAL_INT_MIN": notEqualIncomparable, + "JSVAL_INT_MIN + 1": notEqualIncomparable, + "JSVAL_INT_MAX - 1": notEqualIncomparable, + "JSVAL_INT_MAX": notEqualIncomparable, + "JSVAL_INT_MAX + 1": notEqualIncomparable, + "Infinity": notEqualIncomparable, + "-Infinity": notEqualIncomparable, + "NaN": notEqualIncomparable, + "{}": notEqualNorDifferent, + "{ valueOf: undefined }": notEqualNorDifferent, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualLessThan, + "[0]": notEqualGreaterThan + }; + + // Constructed expected-value matrix + var expected = + { + "undefined": + { + "undefined": strictlyEqualIncomparable, + "null": looselyEqualIncomparable, + "true": notEqualIncomparable, + "false": notEqualIncomparable, + '""': notEqualIncomparable, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualIncomparable, + "-0": notEqualIncomparable, + "1": notEqualIncomparable, + "Math.E": notEqualIncomparable, + "JSVAL_INT_MIN - 1": notEqualIncomparable, + "JSVAL_INT_MIN": notEqualIncomparable, + "JSVAL_INT_MIN + 1": notEqualIncomparable, + "JSVAL_INT_MAX - 1": notEqualIncomparable, + "JSVAL_INT_MAX": notEqualIncomparable, + "JSVAL_INT_MAX + 1": notEqualIncomparable, + "Infinity": notEqualIncomparable, + "-Infinity": notEqualIncomparable, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualIncomparable, + '[""]': notEqualIncomparable, + '["a"]': notEqualIncomparable, + "[0]": notEqualIncomparable + }, + "null": + { + "undefined": looselyEqualIncomparable, + "null": strictlyEqualNotDifferent, + "true": notEqualLessThan, + "false": notEqualNorDifferent, + '""': notEqualNorDifferent, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualNorDifferent, + "-0": notEqualNorDifferent, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualNorDifferent, + '[""]': notEqualNorDifferent, + '["a"]': notEqualIncomparable, + "[0]": notEqualNorDifferent + }, + "true": + { + "undefined": notEqualIncomparable, + "null": notEqualGreaterThan, + "true": strictlyEqual, + "false": notEqualGreaterThan, + '""': notEqualGreaterThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualGreaterThan, + "-0": notEqualGreaterThan, + "1": looselyEqual, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualGreaterThan + }, + "false": + { + "undefined": notEqualIncomparable, + "null": notEqualNorDifferent, + "true": notEqualLessThan, + "false": strictlyEqual, + '""': looselyEqualNotDifferent, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": looselyEqual, + "-0": looselyEqual, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": looselyEqual, + '[""]': looselyEqual, + '["a"]': notEqualIncomparable, + "[0]": looselyEqual + }, + '""': + { + "undefined": notEqualIncomparable, + "null": notEqualNorDifferent, + "true": notEqualLessThan, + "false": looselyEqual, + '""': strictlyEqual, + '"a"': notEqualLessThan, + '"Z"': notEqualLessThan, + "0": looselyEqual, + "-0": looselyEqual, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualLessThan, + "{ valueOf: undefined }": notEqualLessThan, + "[]": looselyEqual, + '[""]': looselyEqual, + '["a"]': notEqualLessThan, + "[0]": notEqualLessThan + }, + '"a"': + { + "undefined": notEqualIncomparable, + "null": notEqualIncomparable, + "true": notEqualIncomparable, + "false": notEqualIncomparable, + '""': notEqualGreaterThan, + '"a"': strictlyEqual, + '"Z"': notEqualGreaterThan, + "0": notEqualIncomparable, + "-0": notEqualIncomparable, + "1": notEqualIncomparable, + "Math.E": notEqualIncomparable, + "JSVAL_INT_MIN - 1": notEqualIncomparable, + "JSVAL_INT_MIN": notEqualIncomparable, + "JSVAL_INT_MIN + 1": notEqualIncomparable, + "JSVAL_INT_MAX - 1": notEqualIncomparable, + "JSVAL_INT_MAX": notEqualIncomparable, + "JSVAL_INT_MAX + 1": notEqualIncomparable, + "Infinity": notEqualIncomparable, + "-Infinity": notEqualIncomparable, + "NaN": notEqualIncomparable, + "{}": notEqualGreaterThan, + "{ valueOf: undefined }": notEqualGreaterThan, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': looselyEqualNotDifferent, + "[0]": notEqualGreaterThan + }, + '"Z"': + { + "undefined": notEqualIncomparable, + "null": notEqualIncomparable, + "true": notEqualIncomparable, + "false": notEqualIncomparable, + '""': notEqualGreaterThan, + '"a"': notEqualLessThan, + '"Z"': strictlyEqual, + "0": notEqualIncomparable, + "-0": notEqualIncomparable, + "1": notEqualIncomparable, + "Math.E": notEqualIncomparable, + "JSVAL_INT_MIN - 1": notEqualIncomparable, + "JSVAL_INT_MIN": notEqualIncomparable, + "JSVAL_INT_MIN + 1": notEqualIncomparable, + "JSVAL_INT_MAX - 1": notEqualIncomparable, + "JSVAL_INT_MAX": notEqualIncomparable, + "JSVAL_INT_MAX + 1": notEqualIncomparable, + "Infinity": notEqualIncomparable, + "-Infinity": notEqualIncomparable, + "NaN": notEqualIncomparable, + "{}": notEqualLessThan, + "{ valueOf: undefined }": notEqualLessThan, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualLessThan, + "[0]": notEqualGreaterThan + }, + "0": comparingZeroToSomething, + "-0": comparingZeroToSomething, + "1": + { + "undefined": notEqualIncomparable, + "null": notEqualGreaterThan, + "true": looselyEqual, + "false": notEqualGreaterThan, + '""': notEqualGreaterThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualGreaterThan, + "-0": notEqualGreaterThan, + "1": strictlyEqual, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualGreaterThan + }, + "Math.E": + { + "undefined": notEqualIncomparable, + "null": notEqualGreaterThan, + "true": notEqualGreaterThan, + "false": notEqualGreaterThan, + '""': notEqualGreaterThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualGreaterThan, + "-0": notEqualGreaterThan, + "1": notEqualGreaterThan, + "Math.E": strictlyEqual, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualGreaterThan + }, + "JSVAL_INT_MIN - 1": + { + "undefined": notEqualIncomparable, + "null": notEqualLessThan, + "true": notEqualLessThan, + "false": notEqualLessThan, + '""': notEqualLessThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualLessThan, + "-0": notEqualLessThan, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": strictlyEqual, + "JSVAL_INT_MIN": notEqualLessThan, + "JSVAL_INT_MIN + 1": notEqualLessThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualLessThan, + '[""]': notEqualLessThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualLessThan + }, + "JSVAL_INT_MIN": + { + "undefined": notEqualIncomparable, + "null": notEqualLessThan, + "true": notEqualLessThan, + "false": notEqualLessThan, + '""': notEqualLessThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualLessThan, + "-0": notEqualLessThan, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": strictlyEqual, + "JSVAL_INT_MIN + 1": notEqualLessThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualLessThan, + '[""]': notEqualLessThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualLessThan + }, + "JSVAL_INT_MIN + 1": + { + "undefined": notEqualIncomparable, + "null": notEqualLessThan, + "true": notEqualLessThan, + "false": notEqualLessThan, + '""': notEqualLessThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualLessThan, + "-0": notEqualLessThan, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": strictlyEqual, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualLessThan, + '[""]': notEqualLessThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualLessThan + }, + "JSVAL_INT_MAX - 1": + { + "undefined": notEqualIncomparable, + "null": notEqualGreaterThan, + "true": notEqualGreaterThan, + "false": notEqualGreaterThan, + '""': notEqualGreaterThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualGreaterThan, + "-0": notEqualGreaterThan, + "1": notEqualGreaterThan, + "Math.E": notEqualGreaterThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": strictlyEqual, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualGreaterThan + }, + "JSVAL_INT_MAX": + { + "undefined": notEqualIncomparable, + "null": notEqualGreaterThan, + "true": notEqualGreaterThan, + "false": notEqualGreaterThan, + '""': notEqualGreaterThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualGreaterThan, + "-0": notEqualGreaterThan, + "1": notEqualGreaterThan, + "Math.E": notEqualGreaterThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualGreaterThan, + "JSVAL_INT_MAX": strictlyEqual, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualGreaterThan + }, + "JSVAL_INT_MAX + 1": + { + "undefined": notEqualIncomparable, + "null": notEqualGreaterThan, + "true": notEqualGreaterThan, + "false": notEqualGreaterThan, + '""': notEqualGreaterThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualGreaterThan, + "-0": notEqualGreaterThan, + "1": notEqualGreaterThan, + "Math.E": notEqualGreaterThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualGreaterThan, + "JSVAL_INT_MAX": notEqualGreaterThan, + "JSVAL_INT_MAX + 1": strictlyEqual, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualGreaterThan + }, + "Infinity": + { + "undefined": notEqualIncomparable, + "null": notEqualGreaterThan, + "true": notEqualGreaterThan, + "false": notEqualGreaterThan, + '""': notEqualGreaterThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualGreaterThan, + "-0": notEqualGreaterThan, + "1": notEqualGreaterThan, + "Math.E": notEqualGreaterThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualGreaterThan, + "JSVAL_INT_MAX": notEqualGreaterThan, + "JSVAL_INT_MAX + 1": notEqualGreaterThan, + "Infinity": strictlyEqual, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualGreaterThan + }, + "-Infinity": + { + "undefined": notEqualIncomparable, + "null": notEqualLessThan, + "true": notEqualLessThan, + "false": notEqualLessThan, + '""': notEqualLessThan, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualLessThan, + "-0": notEqualLessThan, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualLessThan, + "JSVAL_INT_MIN": notEqualLessThan, + "JSVAL_INT_MIN + 1": notEqualLessThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": strictlyEqual, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualLessThan, + '[""]': notEqualLessThan, + '["a"]': notEqualIncomparable, + "[0]": notEqualLessThan + }, + "NaN": + { + "undefined": notEqualIncomparable, + "null": notEqualIncomparable, + "true": notEqualIncomparable, + "false": notEqualIncomparable, + '""': notEqualIncomparable, + '"a"': notEqualIncomparable, + '"Z"': notEqualIncomparable, + "0": notEqualIncomparable, + "-0": notEqualIncomparable, + "1": notEqualIncomparable, + "Math.E": notEqualIncomparable, + "JSVAL_INT_MIN - 1": notEqualIncomparable, + "JSVAL_INT_MIN": notEqualIncomparable, + "JSVAL_INT_MIN + 1": notEqualIncomparable, + "JSVAL_INT_MAX - 1": notEqualIncomparable, + "JSVAL_INT_MAX": notEqualIncomparable, + "JSVAL_INT_MAX + 1": notEqualIncomparable, + "Infinity": notEqualIncomparable, + "-Infinity": notEqualIncomparable, + "NaN": notEqualIncomparable, + "{}": notEqualIncomparable, + "{ valueOf: undefined }": notEqualIncomparable, + "[]": notEqualIncomparable, + '[""]': notEqualIncomparable, + '["a"]': notEqualIncomparable, + "[0]": notEqualIncomparable + }, + "{}": comparingObjectOrObjectWithValueUndefined, + "{ valueOf: undefined }": comparingObjectOrObjectWithValueUndefined, + "[]": + { + "undefined": notEqualIncomparable, + "null": notEqualNorDifferent, + "true": notEqualLessThan, + "false": looselyEqual, + '""': looselyEqual, + '"a"': notEqualLessThan, + '"Z"': notEqualLessThan, + "0": looselyEqual, + "-0": looselyEqual, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualLessThan, + "{ valueOf: undefined }": notEqualLessThan, + "[]": notEqualNorDifferent, + '[""]': notEqualNorDifferent, + '["a"]': notEqualLessThan, + "[0]": notEqualLessThan + }, + '[""]': + { + "undefined": notEqualIncomparable, + "null": notEqualNorDifferent, + "true": notEqualLessThan, + "false": looselyEqual, + '""': looselyEqual, + '"a"': notEqualLessThan, + '"Z"': notEqualLessThan, + "0": looselyEqual, + "-0": looselyEqual, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualLessThan, + "{ valueOf: undefined }": notEqualLessThan, + "[]": notEqualNorDifferent, + '[""]': notEqualNorDifferent, + '["a"]': notEqualLessThan, + "[0]": notEqualLessThan + }, + '["a"]': + { + "undefined": notEqualIncomparable, + "null": notEqualIncomparable, + "true": notEqualIncomparable, + "false": notEqualIncomparable, + '""': notEqualGreaterThan, + '"a"': looselyEqual, + '"Z"': notEqualGreaterThan, + "0": notEqualIncomparable, + "-0": notEqualIncomparable, + "1": notEqualIncomparable, + "Math.E": notEqualIncomparable, + "JSVAL_INT_MIN - 1": notEqualIncomparable, + "JSVAL_INT_MIN": notEqualIncomparable, + "JSVAL_INT_MIN + 1": notEqualIncomparable, + "JSVAL_INT_MAX - 1": notEqualIncomparable, + "JSVAL_INT_MAX": notEqualIncomparable, + "JSVAL_INT_MAX + 1": notEqualIncomparable, + "Infinity": notEqualIncomparable, + "-Infinity": notEqualIncomparable, + "NaN": notEqualIncomparable, + "{}": notEqualGreaterThan, + "{ valueOf: undefined }": notEqualGreaterThan, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualNorDifferent, + "[0]": notEqualGreaterThan + }, + "[0]": + { + "undefined": notEqualIncomparable, + "null": notEqualNorDifferent, + "true": notEqualLessThan, + "false": looselyEqual, + '""': notEqualGreaterThan, + '"a"': notEqualLessThan, + '"Z"': notEqualLessThan, + "0": looselyEqual, + "-0": looselyEqual, + "1": notEqualLessThan, + "Math.E": notEqualLessThan, + "JSVAL_INT_MIN - 1": notEqualGreaterThan, + "JSVAL_INT_MIN": notEqualGreaterThan, + "JSVAL_INT_MIN + 1": notEqualGreaterThan, + "JSVAL_INT_MAX - 1": notEqualLessThan, + "JSVAL_INT_MAX": notEqualLessThan, + "JSVAL_INT_MAX + 1": notEqualLessThan, + "Infinity": notEqualLessThan, + "-Infinity": notEqualGreaterThan, + "NaN": notEqualIncomparable, + "{}": notEqualLessThan, + "{ valueOf: undefined }": notEqualLessThan, + "[]": notEqualGreaterThan, + '[""]': notEqualGreaterThan, + '["a"]': notEqualLessThan, + "[0]": notEqualNorDifferent + } + }; + + + + var failures = []; + function fail(a, ta, b, tb, ex, ac, op) + { + failures.push("(" + a + " " + op + " " + b + ") wrong: " + + "expected " + ex + ", got " + ac + + " (types " + types[ta] + ", " + types[tb] + ")"); + } + + var result = false; + for (var i in values) + { + for (var j in values) + { + // Constants, so hoist to help JIT know that + var vala = values[i], valb = values[j]; + var a = vala.value(), b = valb.value(); + + for (var opname in orderOps) + { + var op = orderOps[opname]; + var expect = expected[i][j].order[opname]; + var failed = false; + + for (var iter = 0; iter < 5; iter++) + { + result = op(a, b); + failed = failed || result !== expect; + } + + if (failed) + fail(i, vala.type, j, valb.type, expect, result, opname); + } + + for (var opname in eqOps) + { + var op = eqOps[opname]; + var expect = expected[i][j].eq[opname]; + var failed = false; + + for (var iter = 0; iter < 5; iter++) + { + result = op(a, b); + failed = failed || result !== expect; + } + + if (failed) + fail(i, vala.type, j, valb.type, expect, result, opname); + } + } + } + + if (failures.length == 0) + return "no failures reported!"; + + return "\n" + failures.join(",\n"); +} +assertEq(testComparisons(), "no failures reported!"); diff --git a/js/src/jit-test/tests/basic/testCompileScript.js b/js/src/jit-test/tests/basic/testCompileScript.js new file mode 100644 index 000000000..9ff375f0e --- /dev/null +++ b/js/src/jit-test/tests/basic/testCompileScript.js @@ -0,0 +1,40 @@ +// |jit-test| slow + +var nlocals = 50; +var localstr = ""; +for (var i = 0; i < nlocals; ++i) + localstr += "var x" + i + "; "; + +/* + * Attempt to test, in a stack-parameter-independent manner, ComileFunction + * hitting a stack-commit boundary (which is not an OOM, but requires checking + * and updating the stack limit). + */ +var arr = [function() {return 0}, function() {return 1}, function() {return 2}]; +var arg = "x"; +var body = localstr + + "if (x == 0) return; " + + "arr[3] = (new Function(arg, body));" + + "for (var i = 0; i < 4; ++i) arr[i](x-1);"; + +// XXX interpreter bailouts during recursion below can cause us to hit the limit quickly. +try { (new Function(arg, body))(1000); } catch (e) {} + +/* + * Also check for OOM in CompileFunction. To avoid taking 5 seconds, use a + * monster apply to chew up most the stack. + */ +var gotIn = false; +var threwOut = false; +try { + (function() { + gotIn = true; + (new Function(arg, body))(10000000); + }).apply(null, new Array(getMaxArgs())); +} catch(e) { + assertEq(""+e, "InternalError: too much recursion"); + threwOut = true; +} +assertEq(threwOut, true); +/* If tweaking some stack parameter makes this fail, shrink monster apply. */ +assertEq(gotIn, true); diff --git a/js/src/jit-test/tests/basic/testConcatNWithSideEffects.js b/js/src/jit-test/tests/basic/testConcatNWithSideEffects.js new file mode 100644 index 000000000..b7b636e5d --- /dev/null +++ b/js/src/jit-test/tests/basic/testConcatNWithSideEffects.js @@ -0,0 +1,12 @@ +var log; +function b(x) { log += 'b'; return 'B'; } +function g() { + log = ''; + var a = {toString: function () { log += 'a'; return 'A'; }}; + assertEq("[" + a + b() + "]", "[AB]"); + assertEq(log, "ab"); +} + +for (var i = 0; i < 1000; ++i) + g(); + diff --git a/js/src/jit-test/tests/basic/testCondSwitch1.js b/js/src/jit-test/tests/basic/testCondSwitch1.js new file mode 100644 index 000000000..a1318fb57 --- /dev/null +++ b/js/src/jit-test/tests/basic/testCondSwitch1.js @@ -0,0 +1,46 @@ +function get(x) { + return x; +} + +function f(x) { + switch(x) { + case get(0): + return 0; + case get(1): + return 1; + case get("foo"): + return "foo"; + case get(true): + return true; + case get(false): + return false; + case get({}): + return {}; + case get(null): + return null; + case Number.MIN_VALUE: + return Number.MIN_VALUE; + case Math: + return Math; + default: + return -123; + } +} + +assertEq(f(0), 0); +assertEq(f(-0), 0); +assertEq(f(1), 1); +assertEq(f("foo"), "foo"); +assertEq(f(true), true); +assertEq(f(false), false); +assertEq(f({}), -123); +assertEq(f([]), -123); +assertEq(f(Math), Math); + +assertEq(f({x:1}), -123); +assertEq(f(333), -123); +assertEq(f(null), null); +assertEq(f(undefined), -123); + +assertEq(f(Number.MIN_VALUE), Number.MIN_VALUE); + diff --git a/js/src/jit-test/tests/basic/testCondSwitch2.js b/js/src/jit-test/tests/basic/testCondSwitch2.js new file mode 100644 index 000000000..39bb5347a --- /dev/null +++ b/js/src/jit-test/tests/basic/testCondSwitch2.js @@ -0,0 +1,33 @@ + +var C1 = 1; +var C2 = 2; +const C3 = 3; + +function f(x) { + var s = ""; + + switch(x) { + case C1: + s += "1"; + case C2: + s += "2"; + break; + case C3: + s += "3"; + default: + s += "d"; + case 4: + s += "4"; + } + return s; +} +assertEq(f(1), "12"); +assertEq(f(2), "2"); +assertEq(f(3), "3d4"); +assertEq(f(4), "4"); + +assertEq(f(0), "d4"); +assertEq(f(-0), "d4"); + +assertEq(f(true), "d4"); + diff --git a/js/src/jit-test/tests/basic/testCondSwitch3.js b/js/src/jit-test/tests/basic/testCondSwitch3.js new file mode 100644 index 000000000..43ea73b7e --- /dev/null +++ b/js/src/jit-test/tests/basic/testCondSwitch3.js @@ -0,0 +1,22 @@ + +var C1 = 1; + +function f(x) { + var s = ""; + + switch(x) { + case 0: + s += "0"; + case C1: + s += "1"; + } + return s; +} + +assertEq(f(0), "01"); +assertEq(f(1), "1"); +assertEq(f(2), ""); + +assertEq(f(true), ""); +assertEq(f(Math), ""); + diff --git a/js/src/jit-test/tests/basic/testConstDestructringArguments.js b/js/src/jit-test/tests/basic/testConstDestructringArguments.js new file mode 100644 index 000000000..e07d93a55 --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstDestructringArguments.js @@ -0,0 +1,3 @@ +// |jit-test| error: TypeError + +(function () { const [arguments] = 0; })(); diff --git a/js/src/jit-test/tests/basic/testConstIf.js b/js/src/jit-test/tests/basic/testConstIf.js new file mode 100644 index 000000000..2fcde1caf --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstIf.js @@ -0,0 +1,6 @@ +function testConstIf() { + var x; + for (var j=0;j<5;++j) { if (1.1 || 5) { } x = 2;} + return x; +} +assertEq(testConstIf(), 2); diff --git a/js/src/jit-test/tests/basic/testConstSwitch.js b/js/src/jit-test/tests/basic/testConstSwitch.js new file mode 100644 index 000000000..f98959adf --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstSwitch.js @@ -0,0 +1,13 @@ +// No test case, just make sure this doesn't assert. +function testNegZero2() { + var z = 0; + for (let j = 0; j < 5; ++j) { ({p: (-z)}); } +} +testNegZero2(); + +function testConstSwitch() { + var x; + for (var j=0;j<5;++j) { switch(1.1) { case NaN: case 2: } x = 2; } + return x; +} +assertEq(testConstSwitch(), 2); diff --git a/js/src/jit-test/tests/basic/testConstSwitch2.js b/js/src/jit-test/tests/basic/testConstSwitch2.js new file mode 100644 index 000000000..48d5f2c9d --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstSwitch2.js @@ -0,0 +1,6 @@ +function testConstSwitch2() { + var x; + for (var j = 0; j < 4; ++j) { switch(0/0) { } } + return "ok"; +} +assertEq(testConstSwitch2(), "ok"); diff --git a/js/src/jit-test/tests/basic/testConstantBooleanExpr.js b/js/src/jit-test/tests/basic/testConstantBooleanExpr.js new file mode 100644 index 000000000..8cc5f3482 --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstantBooleanExpr.js @@ -0,0 +1,6 @@ +function testConstantBooleanExpr() +{ + for (var j = 0; j < 3; ++j) { if(true <= true) { } } + return "ok"; +} +assertEq(testConstantBooleanExpr(), "ok"); diff --git a/js/src/jit-test/tests/basic/testConstructorArgs-1.js b/js/src/jit-test/tests/basic/testConstructorArgs-1.js new file mode 100644 index 000000000..46b6c4e08 --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstructorArgs-1.js @@ -0,0 +1,11 @@ +function f(a, b) { + this.a = a; + assertEq(b, 'x'); +} + +for (var x = 0; x < 9; ++x) { + f.prototype = {}; + var obj = new f(x, 'x'); + assertEq(obj.a, x); + assertEq(Object.getPrototypeOf(obj), f.prototype); +} diff --git a/js/src/jit-test/tests/basic/testConstructorArgs-2.js b/js/src/jit-test/tests/basic/testConstructorArgs-2.js new file mode 100644 index 000000000..0a8292dd8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstructorArgs-2.js @@ -0,0 +1,12 @@ +function f(a, b, c) { + this.a = a; + assertEq(b, 'x'); + assertEq(c, void 0); +} + +for (var x = 0; x < 9; ++x) { + f.prototype = {}; + var obj = new f(x, 'x'); // fewer than f.length arguments + assertEq(obj.a, x); + assertEq(Object.getPrototypeOf(obj), f.prototype); +} diff --git a/js/src/jit-test/tests/basic/testConstructorArgs-3.js b/js/src/jit-test/tests/basic/testConstructorArgs-3.js new file mode 100644 index 000000000..eb594b3dd --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstructorArgs-3.js @@ -0,0 +1,11 @@ +function f(a) { + this.a = a; + assertEq(arguments[1], 'x'); +} + +for (var x = 0; x < 9; ++x) { + f.prototype = {}; + var obj = new f(x, 'x'); // more than f.length arguments + assertEq(obj.a, x); + assertEq(Object.getPrototypeOf(obj), f.prototype); +} diff --git a/js/src/jit-test/tests/basic/testConstructorBail.js b/js/src/jit-test/tests/basic/testConstructorBail.js new file mode 100644 index 000000000..0cd3397f7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testConstructorBail.js @@ -0,0 +1,4 @@ +function testConstructorBail() { + for (let i = 0; i < 5; ++i) new Number(/x/); +} +testConstructorBail(); diff --git a/js/src/jit-test/tests/basic/testContinue.js b/js/src/jit-test/tests/basic/testContinue.js new file mode 100644 index 000000000..a878bbb93 --- /dev/null +++ b/js/src/jit-test/tests/basic/testContinue.js @@ -0,0 +1,11 @@ +function testContinue() { + var i; + var total = 0; + for (i = 0; i < 20; ++i) { + if (i == 11) + continue; + total++; + } + return total; +} +assertEq(testContinue(), 19); diff --git a/js/src/jit-test/tests/basic/testContinueWithLabel.js b/js/src/jit-test/tests/basic/testContinueWithLabel.js new file mode 100644 index 000000000..b851b41de --- /dev/null +++ b/js/src/jit-test/tests/basic/testContinueWithLabel.js @@ -0,0 +1,16 @@ +function testContinueWithLabel() { + var i = 0; + var j = 20; + checkiandj : + while (i < 10) { + i += 1; + checkj : + while (j > 10) { + j -= 1; + if ((j % 2) == 0) + continue checkj; + } + } + return i + j; +} +assertEq(testContinueWithLabel(), 20); diff --git a/js/src/jit-test/tests/basic/testContinueWithLabel3.js b/js/src/jit-test/tests/basic/testContinueWithLabel3.js new file mode 100644 index 000000000..14ef74bc6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testContinueWithLabel3.js @@ -0,0 +1,6 @@ +// bug 511575 comment 3 +outer: +for (var j = 0; j < 10; j++) + for (var p in {x:1}) + if (p > "q") + continue outer; diff --git a/js/src/jit-test/tests/basic/testContinueWithLabel4.js b/js/src/jit-test/tests/basic/testContinueWithLabel4.js new file mode 100644 index 000000000..739726c7a --- /dev/null +++ b/js/src/jit-test/tests/basic/testContinueWithLabel4.js @@ -0,0 +1,25 @@ +// bug 511575 + +Function.prototype.X = 42; + +function ownProperties() { + var props = {}; + var r = function () {}; + + outer: + for (var a in r) { + for (var b in r) { + if (a == b) { + continue outer; + } + } + print("SHOULD NOT BE REACHED"); + props[a] = true; + } + return props; +} + +for (var i = 0; i < 12; ++i) { + print(i); + ownProperties(); +} diff --git a/js/src/jit-test/tests/basic/testConvertibleObjectEqUndefined.js b/js/src/jit-test/tests/basic/testConvertibleObjectEqUndefined.js new file mode 100644 index 000000000..89431affe --- /dev/null +++ b/js/src/jit-test/tests/basic/testConvertibleObjectEqUndefined.js @@ -0,0 +1,30 @@ +function x4(v) { return "" + v + v + v + v; } +function testConvertibleObjectEqUndefined() +{ + var compares = + [ + false, false, false, false, + undefined, undefined, undefined, undefined, + false, false, false, false, + undefined, undefined, undefined, undefined, + false, false, false, false, + undefined, undefined, undefined, undefined, + false, false, false, false, + undefined, undefined, undefined, undefined, + false, false, false, false, + undefined, undefined, undefined, undefined, + ]; + var count = 0; + var obj = { valueOf: function() { count++; return 1; } }; + var results = compares.map(function(v) { return "unwritten"; }); + + for (var i = 0, sz = compares.length; i < sz; i++) + results[i] = compares[i] == obj; + + return results.join("") + count; +} + +assertEq(testConvertibleObjectEqUndefined(), + x4(false) + x4(false) + x4(false) + x4(false) + x4(false) + x4(false) + + x4(false) + x4(false) + x4(false) + x4(false) + "20"); + diff --git a/js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js new file mode 100644 index 000000000..f9a48cdce --- /dev/null +++ b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js @@ -0,0 +1,159 @@ +// |jit-test| error: done + +var g1 = newGlobal('same-compartment'); +var g2 = newGlobal(); +var proxyStr = "new Proxy({}, "+ +" { getOwnPropertyDescriptor: () =>assertEq(true,false), "+ +" ownKeys: () =>assertEq(true,false), "+ +" defineProperty: () =>assertEq(true,false), "+ +" deleteProperty: () =>assertEq(true,false), "+ +" get: () =>assertEq(true,false), "+ +" set: () =>assertEq(true,false), "+ +"}); "; +var proxy1 = g1.eval(proxyStr); +var proxy2 = g2.eval(proxyStr); + +var test = (function() { +"use strict"; +return function test(str, f, isGeneric = false) { + + var x = f(eval(str)); + assertEq(x, f(g1.eval(str))); + assertEq(x, f(g2.eval(str))); + + var threw = false; + try { + f(g1.eval("new Object()")); + } catch (e) { + assertEq(Object.prototype.toString.call(e), "[object Error]"); + threw = true; + } + assertEq(threw, !isGeneric); + threw = false; + try { + f(g2.eval("new Object()")); + } catch (e) { + assertEq(Object.prototype.toString.call(e), "[object Error]"); + threw = true; + } + assertEq(threw, !isGeneric); + threw = false; + try { + f(proxy1); + } catch (e) { + assertEq(Object.prototype.toString.call(e), "[object Error]"); + threw = true; + } + assertEq(threw, !isGeneric); + threw = false; + try { + f(proxy2); + } catch (e) { + assertEq(Object.prototype.toString.call(e), "[object Error]"); + threw = true; + } + assertEq(threw, !isGeneric); +} +})(); + +test("new Boolean(true)", b => Boolean.prototype.toSource.call(b)); +test("new Boolean(true)", b => Boolean.prototype.toString.call(b)); +test("new Boolean(true)", b => Boolean.prototype.valueOf.call(b)); +test("new Number(1)", n => Number.prototype.toSource.call(n)); +test("new Number(1)", n => Number.prototype.toString.call(n)); +test("new Number(1)", n => Number.prototype.valueOf.call(n)); +test("new Number(1)", n => Number.prototype.toFixed.call(n)); +test("new Number(1)", n => Number.prototype.toExponential.call(n)); +test("new Number(1)", n => Number.prototype.toPrecision.call(n)); +test("new Iterator({x:1})", i => Iterator.prototype.next.call(i).toString()); +test("(function(){yield 1})()", i => (function(){yield})().next.call(i).toString()); +test("new String('one')", s => String.prototype.toSource.call(s)); +test("new String('one')", s => String.prototype.toString.call(s)); +test("new RegExp('1')", r => RegExp.prototype.exec.call(r, '1').toString()); +test("new RegExp('1')", r => RegExp.prototype.test.call(r, '1')); +test("new RegExp('1')", r => RegExp.prototype.compile.call(r, '1').toString()); +test("new RegExp('1')", r => assertEq("a1".search(r), 1)); +test("new RegExp('1')", r => assertEq("a1".match(r)[0], '1')); +test("new RegExp('1')", r => assertEq("a1".replace(r, 'A'), 'aA')); +test("new RegExp('1')", r => assertEq(String("a1b".split(r)), "a,b")); +test("new RegExp('1')", r => assertEq(String(new RegExp(r)), String(r))); +test("new RegExp('1')", r => assertEq(String(/x/.compile(r)), String(r))); +test("new WeakMap()", w => WeakMap.prototype.has.call(w, {})); +test("new WeakMap()", w => WeakMap.prototype.get.call(w, {})); +test("new WeakMap()", w => WeakMap.prototype.delete.call(w, {})); +test("new WeakMap()", w => WeakMap.prototype.set.call(w, {}).toString()); +test("new Map()", w => Map.prototype.has.call(w, {})); +test("new Map()", w => Map.prototype.get.call(w, {})); +test("new Map()", w => Map.prototype.delete.call(w, {})); +test("new Map()", w => Map.prototype.set.call(w, {}).toString()); +test("new Set()", w => Set.prototype.has.call(w, {})); +test("new Set()", w => Set.prototype.add.call(w, {}).toString()); +test("new Set()", w => Set.prototype.delete.call(w, {})); + +test("new Int8Array(1)", a => Int8Array.prototype.subarray.call(a).toString()); +test("new Uint8Array(1)", a => Uint8Array.prototype.subarray.call(a).toString()); +test("new Int16Array(1)", a => Int16Array.prototype.subarray.call(a).toString()); +test("new Uint16Array(1)", a => Uint16Array.prototype.subarray.call(a).toString()); +test("new Int32Array(1)", a => Int32Array.prototype.subarray.call(a).toString()); +test("new Uint32Array(1)", a => Uint32Array.prototype.subarray.call(a).toString()); +test("new Float32Array(1)", a => Float32Array.prototype.subarray.call(a).toString()); +test("new Float64Array(1)", a => Float64Array.prototype.subarray.call(a).toString()); +test("new Uint8ClampedArray(1)", a => Uint8ClampedArray.prototype.subarray.call(a).toString()); + +test("new Int8Array(1)", a => Int8Array.prototype.set.call(a, [])); +test("new Uint8Array(1)", a => Uint8Array.prototype.set.call(a, [])); +test("new Int16Array(1)", a => Int16Array.prototype.set.call(a, [])); +test("new Uint16Array(1)", a => Uint16Array.prototype.set.call(a, [])); +test("new Int32Array(1)", a => Int32Array.prototype.set.call(a, [])); +test("new Uint32Array(1)", a => Uint32Array.prototype.set.call(a, [])); +test("new Float32Array(1)", a => Float32Array.prototype.set.call(a, [])); +test("new Float64Array(1)", a => Float64Array.prototype.set.call(a, [])); +test("new Uint8ClampedArray(1)", a => Uint8ClampedArray.prototype.set.call(a, [])); + +function justDontThrow() {} +test("new Date()", d => justDontThrow(Date.prototype.getTime.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getYear.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getFullYear.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getUTCFullYear.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getMonth.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getUTCMonth.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getDate.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getUTCDate.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getDay.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getUTCDay.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getHours.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getUTCHours.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getMinutes.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getUTCMinutes.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getSeconds.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getUTCSeconds.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.getTimezoneOffset.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setTime.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setMilliseconds.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setUTCMilliseconds.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setSeconds.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setUTCSeconds.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setMinutes.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setUTCMinutes.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setHours.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setUTCHours.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setDate.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setUTCDate.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setMonth.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setUTCMonth.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setFullYear.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setUTCFullYear.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.setYear.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toGMTString.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toISOString.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toLocaleString.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toLocaleDateString.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toLocaleTimeString.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toLocaleFormat.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toTimeString.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toDateString.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toSource.call(d))); +test("new Date()", d => justDontThrow(Date.prototype.toString.call(d)), true); +test("new Date()", d => justDontThrow(Date.prototype.valueOf.call(d))); + +throw "done"; diff --git a/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js new file mode 100644 index 000000000..39319bc96 --- /dev/null +++ b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js @@ -0,0 +1,15 @@ +var g = newGlobal(); + +var array = g.eval("new Array(1,2,3)"); +assertEq([array,array].concat().toString(), "1,2,3,1,2,3"); +assertEq(Array.isArray(array), true); + +var number = g.eval("new Number(42)"); +var bool = g.eval("new Boolean(false)"); +var string = g.eval("new String('ponies')"); +assertEq(JSON.stringify({n:number, b:bool, s:string}), "{\"n\":42,\"b\":false,\"s\":\"ponies\"}"); +assertEq(JSON.stringify({arr:array}), "{\"arr\":[1,2,3]}"); +assertEq(JSON.stringify({2:'ponies', unicorns:'not real'}, array), "{\"2\":\"ponies\"}"); +assertEq(JSON.stringify({42:true, ponies:true, unicorns:'sad'}, [number, string]), "{\"42\":true,\"ponies\":true}"); +assertEq(JSON.stringify({a:true,b:false}, undefined, number), "{\n \"a\": true,\n \"b\": false\n}"); +assertEq(JSON.stringify({a:true,b:false}, undefined, string), "{\nponies\"a\": true,\nponies\"b\": false\n}"); diff --git a/js/src/jit-test/tests/basic/testCustomIterator.js b/js/src/jit-test/tests/basic/testCustomIterator.js new file mode 100644 index 000000000..24f915db2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testCustomIterator.js @@ -0,0 +1,26 @@ +function my_iterator_next() { + if (this.i == 10) { + this.i = 0; + throw this.StopIteration; + } + return this.i++; +} +function testCustomIterator() { + var o = { + __iterator__: function () { + return { + i: 0, + next: my_iterator_next, + StopIteration: StopIteration + }; + } + }; + var a=[]; + for (var k = 0; k < 100; k += 10) { + for(var j in o) { + a[k + (j >> 0)] = j*k; + } + } + return a.join(); +} +assertEq(testCustomIterator(), "0,0,0,0,0,0,0,0,0,0,0,10,20,30,40,50,60,70,80,90,0,20,40,60,80,100,120,140,160,180,0,30,60,90,120,150,180,210,240,270,0,40,80,120,160,200,240,280,320,360,0,50,100,150,200,250,300,350,400,450,0,60,120,180,240,300,360,420,480,540,0,70,140,210,280,350,420,490,560,630,0,80,160,240,320,400,480,560,640,720,0,90,180,270,360,450,540,630,720,810"); diff --git a/js/src/jit-test/tests/basic/testDateNow.js b/js/src/jit-test/tests/basic/testDateNow.js new file mode 100644 index 000000000..0a186caa2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDateNow.js @@ -0,0 +1,10 @@ +function testDateNow() { + // Accessing global.Date for the first time will change the global shape, + // so do it before the loop starts; otherwise we have to loop an extra time + // to pick things up. + var time = Date.now(); + for (var j = 0; j < 9; ++j) + time = Date.now(); + return "ok"; +} +assertEq(testDateNow(), "ok"); diff --git a/js/src/jit-test/tests/basic/testDecElem1.js b/js/src/jit-test/tests/basic/testDecElem1.js new file mode 100644 index 000000000..6739cab40 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDecElem1.js @@ -0,0 +1,7 @@ +var obj = {p: 100}; +var name = "p"; +var a = []; +for (var i = 0; i < 10; i++) + a[i] = --obj[name]; +assertEq(a.join(','), '99,98,97,96,95,94,93,92,91,90'); +assertEq(obj.p, 90); diff --git a/js/src/jit-test/tests/basic/testDecElem2.js b/js/src/jit-test/tests/basic/testDecElem2.js new file mode 100644 index 000000000..8fe74ff50 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDecElem2.js @@ -0,0 +1,11 @@ +var obj = {s: ""}; +var name = "s"; +var a = []; +for (var i = 0; i <= 13; i++) { + a[i] = 'x'; + if (i > 8) + a[i] = --obj[name]; // first recording changes obj.s from string to number +} +assertEq(a.join(','), Array(10).join('x,') + '-1,-2,-3,-4,-5'); +assertEq(obj.s, -5); + diff --git a/js/src/jit-test/tests/basic/testDecayingInnerLoop.js b/js/src/jit-test/tests/basic/testDecayingInnerLoop.js new file mode 100644 index 000000000..92e985cd6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDecayingInnerLoop.js @@ -0,0 +1,9 @@ +function testDecayingInnerLoop() { + var i, j, k = 10; + for (i = 0; i < 5000; ++i) { + for (j = 0; j < k; ++j); + --k; + } + return i; +} +assertEq(testDecayingInnerLoop(), 5000); diff --git a/js/src/jit-test/tests/basic/testDeepBail1.js b/js/src/jit-test/tests/basic/testDeepBail1.js new file mode 100644 index 000000000..779f96597 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDeepBail1.js @@ -0,0 +1,6 @@ +function testDeepBail1() { + var y = [1,2,3]; + for (var i = 0; i < 9; i++) + "" in y; +} +testDeepBail1(); diff --git a/js/src/jit-test/tests/basic/testDeepBailFromHasInstance.js b/js/src/jit-test/tests/basic/testDeepBailFromHasInstance.js new file mode 100644 index 000000000..33646da6c --- /dev/null +++ b/js/src/jit-test/tests/basic/testDeepBailFromHasInstance.js @@ -0,0 +1,12 @@ +var arr = [StopIteration, StopIteration, StopIteration, StopIteration, {}]; +var obj = {}; +var x; +var result = 'no error'; +try { + for (var i = 0; i < arr.length; i++) + x = (obj instanceof arr[i]); // last iteration throws, triggering deep bail +} catch (exc) { + result = exc.constructor.name; +} +assertEq(result, 'TypeError'); + diff --git a/js/src/jit-test/tests/basic/testDeepBailInMoreIter.js b/js/src/jit-test/tests/basic/testDeepBailInMoreIter.js new file mode 100644 index 000000000..3e6b68040 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDeepBailInMoreIter.js @@ -0,0 +1,5 @@ +w = (function() { yield })(); +w.next(); +for (var i = 0; i < 100; ++i) { + for (v in w) {} +} diff --git a/js/src/jit-test/tests/basic/testDeepBailWhileRecording.js b/js/src/jit-test/tests/basic/testDeepBailWhileRecording.js new file mode 100644 index 000000000..17c1086aa --- /dev/null +++ b/js/src/jit-test/tests/basic/testDeepBailWhileRecording.js @@ -0,0 +1,15 @@ +var o = {}; +var arr = [o,o,o,o,o,o,o,o,o,o,o,o,o]; +var out = []; + +const OUTER = 10; + +for (var i = 0; i < 10; ++i) { + for (var j = 0; j < arr.length; ++j) { + out.push(String.prototype.indexOf.call(arr[i], 'object')); + } +} + +assertEq(out.length, 10 * arr.length); +for (var i = 0; i < out.length; ++i) + assertEq(out[i], 1); diff --git a/js/src/jit-test/tests/basic/testDeepPropertyShadowing.js b/js/src/jit-test/tests/basic/testDeepPropertyShadowing.js new file mode 100644 index 000000000..65dbf8d5e --- /dev/null +++ b/js/src/jit-test/tests/basic/testDeepPropertyShadowing.js @@ -0,0 +1,17 @@ +function testDeepPropertyShadowing() +{ + function h(node) { + var x = 0; + while (node) { + x++; + node = node.parent; + } + return x; + } + var tree = {__proto__: {__proto__: {parent: null}}}; + h(tree); + h(tree); + tree.parent = {}; + assertEq(h(tree), 2); +} +testDeepPropertyShadowing(); diff --git a/js/src/jit-test/tests/basic/testDefinePropertyAcrossCompartment.js b/js/src/jit-test/tests/basic/testDefinePropertyAcrossCompartment.js new file mode 100644 index 000000000..b997089e7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDefinePropertyAcrossCompartment.js @@ -0,0 +1,7 @@ +var a = evalcx(''); +Object.defineProperty(a, "", ({ + get: function() {}, +})) +gc() + +// don't crash diff --git a/js/src/jit-test/tests/basic/testDenseArrayProp.js b/js/src/jit-test/tests/basic/testDenseArrayProp.js new file mode 100644 index 000000000..1ccb2e84d --- /dev/null +++ b/js/src/jit-test/tests/basic/testDenseArrayProp.js @@ -0,0 +1,12 @@ +function testDenseArrayProp() +{ + [].__proto__.x = 1; + ({}).__proto__.x = 2; + var a = [[],[],[],({}).__proto__]; + for (var i = 0; i < a.length; ++i) + uneval(a[i].x); + delete [].__proto__.x; + delete ({}).__proto__.x; + return "ok"; +} +assertEq(testDenseArrayProp(), "ok"); diff --git a/js/src/jit-test/tests/basic/testDenseToSlowArray.js b/js/src/jit-test/tests/basic/testDenseToSlowArray.js new file mode 100644 index 000000000..e4b6b5d2d --- /dev/null +++ b/js/src/jit-test/tests/basic/testDenseToSlowArray.js @@ -0,0 +1,185 @@ +// test dense -> slow array transitions during the recording and on trace +// for various array functions and property accessors + +function test_set_elem() { + + function f() { + var bag = []; + for (var i = 0; i != 100; ++i) { + var a = [0]; + a[100*100] = i; + bag.push(a); + } + + for (var i = 0; i != 100; ++i) { + var a = [0]; + a[200 + i] = i; + bag.push(a); + } + return bag; + } + + var bag = f(); + + for (var i = 0; i != 100; ++i) { + var a = bag[i]; + assertEq(a.length, 100 * 100 + 1); + assertEq(a[100*100], i); + assertEq(a[0], 0); + assertEq(1 + i in a, false); + } + + for (var i = 0; i != 100; ++i) { + var a = bag[100 + i]; + assertEq(a.length, 200 + i + 1); + assertEq(a[200 + i], i); + assertEq(a[0], 0); + assertEq(1 + i in a, false); + } +} + +function test_reverse() { + + function prepare_arays() { + var bag = []; + var base_index = 245; + for (var i = 0; i != 50; ++i) { + var a = [1, 2, 3, 4, 5]; + a.length = i + base_index; + bag.push(a); + } + return bag; + } + + function test(bag) { + for (var i = 0; i != bag.length; ++i) { + var a = bag[i]; + a.reverse(); + a[0] = 1; + } + } + + var bag = prepare_arays(); + test(bag); + for (var i = 0; i != bag.length; ++i) { + var a = bag[i]; + assertEq(a[0], 1); + for (var j = 1; j <= 5; ++j) { + assertEq(a[a.length - j], j); + } + for (var j = 1; j < a.length - 5; ++j) { + assertEq(j in a, false); + } + } + +} + +function test_push() { + + function prepare_arays() { + var bag = []; + var base_index = 245; + for (var i = 0; i != 50; ++i) { + var a = [0]; + a.length = i + base_index; + bag.push(a); + } + return bag; + } + + function test(bag) { + for (var i = 0; i != bag.length; ++i) { + var a = bag[i]; + a.push(2); + a[0] = 1; + } + } + + var bag = prepare_arays(); + test(bag); + for (var i = 0; i != bag.length; ++i) { + var a = bag[i]; + assertEq(a[0], 1); + assertEq(a[a.length - 1], 2); + for (var j = 1; j < a.length - 1; ++j) { + assertEq(j in a, false); + } + } +} + +function test_unshift() { + + function prepare_arays() { + var bag = []; + var base_index = 245; + for (var i = 0; i != 50; ++i) { + var a = [0]; + a.length = i + base_index; + bag.push(a); + } + return bag; + } + + function test(bag) { + for (var i = 0; i != bag.length; ++i) { + var a = bag[i]; + a.unshift(1); + a[2] = 2; + } + } + + var bag = prepare_arays(); + test(bag); + for (var i = 0; i != bag.length; ++i) { + var a = bag[i]; + assertEq(a[0], 1); + assertEq(a[1], 0); + assertEq(a[2], 2); + for (var j = 3; j < a.length; ++j) { + assertEq(j in a, false); + } + } +} + +function test_splice() { + + function prepare_arays() { + var bag = []; + var base_index = 245; + for (var i = 0; i != 50; ++i) { + var a = [1, 2]; + a.length = i + base_index; + bag.push(a); + } + return bag; + } + + function test(bag) { + for (var i = 0; i != bag.length; ++i) { + var a = bag[i]; + a.splice(1, 0, "a", "b", "c"); + a[2] = 100; + } + } + + var bag = prepare_arays(); + test(bag); + for (var i = 0; i != bag.length; ++i) { + var a = bag[i]; + assertEq(a[0], 1); + assertEq(a[1], "a"); + assertEq(a[2], 100); + assertEq(a[3], "c"); + assertEq(a[4], 2); + for (var j = 5; j < a.length; ++j) { + assertEq(j in a, false); + } + } +} + +test_set_elem(); +test_reverse(); +test_push(); +test_unshift(); +test_splice(); + diff --git a/js/src/jit-test/tests/basic/testDestructuring.js b/js/src/jit-test/tests/basic/testDestructuring.js new file mode 100644 index 000000000..05a267802 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDestructuring.js @@ -0,0 +1,9 @@ +function testDestructuring() { + var t = 0; + for (var i = 0; i < 9; ++i) { + var [r, g, b] = [1, 1, 1]; + t += r + g + b; + } + return t +} +assertEq(testDestructuring(), (9) * 3); diff --git a/js/src/jit-test/tests/basic/testDestructuringFormalError.js b/js/src/jit-test/tests/basic/testDestructuringFormalError.js new file mode 100644 index 000000000..1d1a8c2c0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDestructuringFormalError.js @@ -0,0 +1,6 @@ +// |jit-test| error:TypeError +(function({ + l +}) { + eval(); +})() diff --git a/js/src/jit-test/tests/basic/testDestructuringVarInsideWith.js b/js/src/jit-test/tests/basic/testDestructuringVarInsideWith.js new file mode 100644 index 000000000..b233c9ceb --- /dev/null +++ b/js/src/jit-test/tests/basic/testDestructuringVarInsideWith.js @@ -0,0 +1,4 @@ +with ({b:1}) {
+ const [ b ] = [];
+ assertEq(b, undefined);
+}
diff --git a/js/src/jit-test/tests/basic/testDifferingArgc.js b/js/src/jit-test/tests/basic/testDifferingArgc.js new file mode 100644 index 000000000..0cac5696f --- /dev/null +++ b/js/src/jit-test/tests/basic/testDifferingArgc.js @@ -0,0 +1,18 @@ +function doTestDifferingArgc(a, b) +{ + var k = 0; + for (var i = 0; i < 10; i++) + { + k += i; + } + return k; +} +function testDifferingArgc() +{ + var x = 0; + x += doTestDifferingArgc(1, 2); + x += doTestDifferingArgc(1); + x += doTestDifferingArgc(1, 2, 3); + return x; +} +assertEq(testDifferingArgc(), 45*3); diff --git a/js/src/jit-test/tests/basic/testDivModWithIntMin.js b/js/src/jit-test/tests/basic/testDivModWithIntMin.js new file mode 100644 index 000000000..a8ea2d2c4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDivModWithIntMin.js @@ -0,0 +1,62 @@ +var intMin = -2147483648; +var intMax = 2147483647; +var negativeZero = -0; +var zero = 0; + +function testModNegativeZero() { + assertEq(intMin % -2147483648, -0); + assertEq(intMin % -1, -0); + assertEq(intMin % 1, -0); + assertEq(intMin % -2147483648, -0); + + assertEq(((intMin|0) % -2147483648)|0, 0); + assertEq(((intMin|0) % -1)|0, 0); + assertEq(((intMin|0) % 1)|0, 0); + assertEq(((intMin|0) % -2147483648)|0, 0); +} + +testModNegativeZero(); +testModNegativeZero(); + +function testMinModulus1() { + assertEq(intMin % -3, -2); + assertEq(intMin % 3, -2); + assertEq(intMin % 10, -8); + assertEq(intMin % 2147483647, -1); + + assertEq(((intMin|0) % -3)|0, -2); + assertEq(((intMin|0) % 3)|0, -2); + assertEq(((intMin|0) % 10)|0, -8); + assertEq(((intMin|0) % 2147483647)|0, -1); +} + +testMinModulus1(); +testMinModulus1(); + +function testMinModulus2() { + for (var i = -10; i <= 10; ++i) + assertEq(i % -2147483648, i); + assertEq(intMax % -2147483648, intMax); + + for (var i = -10; i <= 10; ++i) + assertEq(((i|0) % -2147483648)|0, i); + assertEq(((intMax|0) % -2147483648)|0, intMax); +} + +testMinModulus2(); +testMinModulus2(); + +function testDivEdgeCases() { + assertEq(intMin / -2147483648, 1); + assertEq(intMin / -1, -intMin); + assertEq(negativeZero / -2147483648, 0); + assertEq(zero / -2147483648, -0); + + assertEq(((intMin|0) / -2147483648)|0, 1); + assertEq(((intMin|0) / -1)|0, intMin); + assertEq(((negativeZero|0) / -2147483648)|0, 0); + assertEq(((zero|0) / -2147483648)|0, 0); +} + +testDivEdgeCases(); +testDivEdgeCases(); diff --git a/js/src/jit-test/tests/basic/testDivOverflow.js b/js/src/jit-test/tests/basic/testDivOverflow.js new file mode 100644 index 000000000..f2af92b53 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDivOverflow.js @@ -0,0 +1,6 @@ +for (d in [0, 0]) { + const a = (d -= (++d).toString()) + for each(b in [Number(1) << d, 0, 0xC]) { + b / a + } +} diff --git a/js/src/jit-test/tests/basic/testDivision.js b/js/src/jit-test/tests/basic/testDivision.js new file mode 100644 index 000000000..52f3d9557 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDivision.js @@ -0,0 +1,10 @@ +function testDivision() { + var a = 32768; + var b; + while (b !== 1) { + b = a / 2; + a = b; + } + return a; +} +assertEq(testDivision(), 1); diff --git a/js/src/jit-test/tests/basic/testDivisionFloat.js b/js/src/jit-test/tests/basic/testDivisionFloat.js new file mode 100644 index 000000000..44f67659a --- /dev/null +++ b/js/src/jit-test/tests/basic/testDivisionFloat.js @@ -0,0 +1,10 @@ +function testDivisionFloat() { + var a = 32768.0; + var b; + while (b !== 1) { + b = a / 2.0; + a = b; + } + return a === 1.0; +} +assertEq(testDivisionFloat(), true); diff --git a/js/src/jit-test/tests/basic/testDivisionWithNegative1.js b/js/src/jit-test/tests/basic/testDivisionWithNegative1.js new file mode 100644 index 000000000..18a3b266f --- /dev/null +++ b/js/src/jit-test/tests/basic/testDivisionWithNegative1.js @@ -0,0 +1,6 @@ +function testDivisionWithNegative1() { + for (var i = 3; i >= 0; --i) + c = i / -1; + return 1/c; +} +assertEq(testDivisionWithNegative1(), -Infinity); diff --git a/js/src/jit-test/tests/basic/testDontClobberScannerError.js b/js/src/jit-test/tests/basic/testDontClobberScannerError.js new file mode 100644 index 000000000..a1ee58163 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDontClobberScannerError.js @@ -0,0 +1,9 @@ +var caught = false; +try { + Function("a, @", ""); +} catch(e) { + assertEq(e.toString().search("SyntaxError: malformed formal parameter") == -1, true); + assertEq(e.toString().search("SyntaxError: illegal character") == -1, false); + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/testDoubleComparison.js b/js/src/jit-test/tests/basic/testDoubleComparison.js new file mode 100644 index 000000000..1d4b3e33a --- /dev/null +++ b/js/src/jit-test/tests/basic/testDoubleComparison.js @@ -0,0 +1,13 @@ +function testDoubleComparison() +{ + for (var i = 0; i < 500000; ++i) + { + switch (1 / 0) + { + case Infinity: + } + } + + return "finished"; +} +assertEq(testDoubleComparison(), "finished"); diff --git a/js/src/jit-test/tests/basic/testDoubleToStr.js b/js/src/jit-test/tests/basic/testDoubleToStr.js new file mode 100644 index 000000000..9eea240bb --- /dev/null +++ b/js/src/jit-test/tests/basic/testDoubleToStr.js @@ -0,0 +1,9 @@ +function testDoubleToStr() { + var x = 0.0; + var y = 5.5; + for (var i = 0; i < 200; i++) { + x += parseFloat(y.toString()); + } + return x; +} +assertEq(testDoubleToStr(), 5.5*200); diff --git a/js/src/jit-test/tests/basic/testDoubleZeroInSwitch1.js b/js/src/jit-test/tests/basic/testDoubleZeroInSwitch1.js new file mode 100644 index 000000000..2b147aaf2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDoubleZeroInSwitch1.js @@ -0,0 +1,7 @@ +var a = Math.sin(Math.PI/2); // spec does not specify precise answer here... +if (a === 1) { // ...but if a === 1 here... + switch (a) { + case 1: break; // ...then it must also match here + default: throw "FAIL"; + } +} diff --git a/js/src/jit-test/tests/basic/testDoubleZeroInSwitch2.js b/js/src/jit-test/tests/basic/testDoubleZeroInSwitch2.js new file mode 100644 index 000000000..504d1b76d --- /dev/null +++ b/js/src/jit-test/tests/basic/testDoubleZeroInSwitch2.js @@ -0,0 +1,9 @@ +var arr = new Float32Array(1); +arr[0] = 15; +var a = arr[0]; +assertEq(a, 15); +switch (a) { + case 15: break; + default: throw "FAIL"; +} + diff --git a/js/src/jit-test/tests/basic/testDynamicLookup.js b/js/src/jit-test/tests/basic/testDynamicLookup.js new file mode 100644 index 000000000..781c9f8a7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDynamicLookup.js @@ -0,0 +1,67 @@ +(function() { var x = 2; eval("assertEq(x, 2)"); })(); +(function() { var x = 2; (function() { assertEq(x, 2) })() })(); +(function() { var x = 2; (function() { eval("assertEq(x, 2)") })() })(); +(function() { var x = 2; (function() { (function() { assertEq(x, 2) })()})() })(); +(function() { var x = 2; (function() { (function() { eval("assertEq(x, 2)") })()})() })(); + +(function() { var x = 2; with({}) { assertEq(x, 2) } })(); +(function() { var x = 2; with({}) { (function() { assertEq(x, 2) })() } })(); +(function() { var x = 3; with({x:2}) { assertEq(x, 2) } })(); +(function() { var x = 3; with({x:2}) { (function() { assertEq(x, 2) })() } })(); +(function() { var x = 2; (function() { with({}) { assertEq(x, 2) } })() })(); +(function() { var x = 2; (function() { with({}) { (function() { assertEq(x, 2) })() } })() })(); +(function() { var x = 3; (function() { with({x:2}) { assertEq(x, 2) } })() })(); +(function() { var x = 3; (function() { with({x:2}) { (function() { assertEq(x, 2) })() } })() })(); + +(function() { if (Math) function x() {}; assertEq(typeof x, "function") })(); +(function() { if (Math) function x() {}; eval('assertEq(typeof x, "function")') })(); +(function() { if (Math) function x() {}; (function() { assertEq(typeof x, "function") })() })(); +(function() { if (Math) function x() {}; (function() { eval('assertEq(typeof x, "function")') })() })(); + +(function() { eval("var x = 2"); assertEq(x, 2) })(); +(function() { eval("var x = 2"); (function() { assertEq(x, 2) })() })(); +(function() { eval("var x = 2"); (function() { (function() { assertEq(x, 2) })() })() })(); + +(function() { var x = 2; (function() { eval('var y = 3'); assertEq(x, 2) })() })(); +(function() { var x = 2; (function() { eval('var y = 3'); (function() { assertEq(x, 2) })() })() })(); + +(function() { var x = 3; (function() { eval('var x = 2'); assertEq(x, 2) })() })(); +(function() { var x = 3; (function() { eval('var x = 2'); (function() { assertEq(x, 2) })() })() })(); + +(function() { var x = 2; eval("eval('assertEq(x, 2)')") })(); +(function() { var x = 2; (function() { eval("eval('assertEq(x, 2)')") })() })(); +(function() { var x = 2; eval("(function() { eval('assertEq(x, 2)') })()") })(); +(function() { var x = 2; (function() { eval("(function() { eval('assertEq(x, 2)') })()") })() })(); +(function() { var x = 2; (function() { eval("(function() { eval('(function() { assertEq(x, 2) })()') })()") })() })(); + +(function() { var [x] = [2]; eval('assertEq(x, 2)') })(); +(function() { var [x] = [2]; (function() { assertEq(x, 2) })() })(); +(function() { var [x] = [2]; (function() { eval('assertEq(x, 2)') })() })(); +(function() { for (var [x] = [2];;) { return (function() { return assertEq(x, 2); })() } })(); +(function() { for (var [x] = [2];;) { return (function() { return eval('assertEq(x, 2)'); })() } })(); + +(function() { var {y:x} = {y:2}; eval('assertEq(x, 2)') })(); +(function() { var {y:x} = {y:2}; (function() { assertEq(x, 2) })() })(); +(function() { var {y:x} = {y:2}; (function() { eval('assertEq(x, 2)') })() })(); +(function() { for (var {y:x} = {y:2};;) { return (function() { return assertEq(x, 2); })() } })(); +(function() { for (var {y:x} = {y:2};;) { return (function() { return eval('assertEq(x, 2)'); })() } })(); + +(function([x]) { eval('assertEq(x, 2)') })([2]); +(function([x]) { (function() { assertEq(x, 2) })() })([2]); +(function([x]) { (function() { eval('assertEq(x, 2)') })() })([2]); + +(function f() { assertEq(f.length, 0) })(); +(function f() { eval('assertEq(f.length, 0)') })(); +(function f() { (function f(x) { eval('assertEq(f.length, 1)') })() })(); +(function f() { eval("(function f(x) { eval('assertEq(f.length, 1)') })()") })(); + +(function f() { arguments = 3; function arguments() {}; assertEq(arguments, 3) })(); +(function f() { function arguments() {}; arguments = 3; assertEq(arguments, 3) })(); +(function f() { var arguments = 3; function arguments() {}; assertEq(arguments, 3) })(); +(function f() { function arguments() {}; var arguments = 3; assertEq(arguments, 3) })(); + +function f1() { assertEq(typeof f1, "function") }; f1(); +with({}) { (function() { assertEq(typeof f1, "function") })() } +if (Math) + function f2(x) {} +assertEq(f2.length, 1); diff --git a/js/src/jit-test/tests/basic/testDynamicUsage.js b/js/src/jit-test/tests/basic/testDynamicUsage.js new file mode 100644 index 000000000..04cd51b71 --- /dev/null +++ b/js/src/jit-test/tests/basic/testDynamicUsage.js @@ -0,0 +1,82 @@ +assertEq((function() { var x = 3; return (function() { return x } )() })(), 3); +assertEq((function() { var g = function() { return x }; var x = 3; return g()})(), 3); +assertEq((function() { var x; x = 3; return (function() { return x } )() })(), 3); +assertEq((function() { x = 3; var x; return (function() { return x } )() })(), 3); +assertEq((function() { var x; var g = function() { return x }; x = 3; return g() })(), 3); + +assertEq((function() { function f() { return 3 }; assertEq(f(), 3); return (function() f())() })(), 3); +assertEq((function() { function f() { return 3 }; assertEq(f(), 3); return eval('f()') })(), 3); +assertEq((function() { function f() { return 3 }; (function() f())(); return f() })(), 3); + +assertEq((function() { var x = 3; return eval("x") })(), 3); +assertEq((function() { var x; x = 3; return eval("x") })(), 3); +assertEq((function() { x = 3; var x; return eval("x") })(), 3); + +assertEq((function() { var x; (function() {x = 2})(); return ++x })(), 3); +assertEq((function() { var x; (function() {x = 2})(); x++; return x })(), 3); +assertEq((function() { var x; (function() {x = 4})(); return --x })(), 3); +assertEq((function() { var x; (function() {x = 4})(); x--; return x })(), 3); + +assertEq((function(x) { return (function() { return x } )() })(3), 3); +assertEq((function(x) { var x = 3; return (function() { return x } )() })(4), 3); +assertEq((function(x) { x = 3; return (function() { return x } )() })(4), 3); +assertEq((function(x) { var g = function() { return x }; x = 3; return g()})(3), 3); + +assertEq((function(x) { return eval("x") })(3), 3); +assertEq((function(x) { x = 3; return eval("x") })(4), 3); + +assertEq((function(a) { var [x,y] = a; (function() { x += y })(); return x })([1,2]), 3); +assertEq((function(a) { var [x,y] = a; x += y; return (function() x)() })([1,2]), 3); +assertEq((function(a) { var [[l, x],[m, y]] = a; x += y; return (function() x)() })([[0,1],[0,2]]), 3); +assertEq((function(a) { var [x,y] = a; eval('x += y'); return x })([1,2]), 3); +assertEq((function(a) { var [x,y] = a; x += y; return eval('x') })([1,2]), 3); +assertEq((function(a) { var [x,y] = a; (function() { x += y })(); return x })([1,2]), 3); +assertEq((function(a) { var [x,y] = a; x += y; return (function() x)() })([1,2]), 3); +assertEq((function(a,x,y) { [x,y] = a; (function() { eval('x += y') })(); return x })([1,2]), 3); +assertEq((function(a,x,y) { [x,y] = a; x += y; return (function() eval('x'))() })([1,2]), 3); + +assertEq((function() { var [x,y] = [1,2]; x += y; return (function() x)() })(), 3); +assertEq((function() { var [x,y] = [1,2]; (function() x += y)(); return x })(), 3); +assertEq((function() { { let [x,y] = [1,2]; x += y; return (function() x)() } })(), 3); +assertEq((function() { { let [x,y] = [1,2]; (function() x += y)(); return x } })(), 3); + +assertEq((function([x,y]) { (function() { x += y })(); return x })([1,2]), 3); +assertEq((function([x,y]) { x += y; return (function() x)() })([1,2]), 3); +assertEq((function([[l,x],[m,y]]) { (function() { x += y })(); return x })([[0,1],[0,2]]), 3); +assertEq((function([[l,x],[m,y]]) { x += y; return (function() x)() })([[0,1],[0,2]]), 3); +assertEq((function([x,y]) { (function() { eval('x += y') })(); return x })([1,2]), 3); +assertEq((function([x,y]) { x += y; return (function() eval('x'))() })([1,2]), 3); +assertEq((function() { try { throw [1,2] } catch([x,y]) { eval('x += y'); return x }})(), 3); +assertEq((function() { try { throw [1,2] } catch([x,y]) { x += y; return eval('x') }})(), 3); +assertEq((function() { try { throw [1,2] } catch([x,y]) { (function() { x += y })(); return x }})(), 3); +assertEq((function() { try { throw [1,2] } catch([x,y]) { x += y; return (function() x)() }})(), 3); +assertEq((function() { try { throw [1,2] } catch([x,y]) { (function() { eval('x += y') })(); return x }})(), 3); +assertEq((function() { try { throw [1,2] } catch([x,y]) { x += y; return (function() eval('x'))() }})(), 3); + +assertEq((function(a) { let [x,y] = a; (function() { x += y })(); return x })([1,2]), 3); +assertEq((function(a) { let [x,y] = a; x += y; return (function() x)() })([1,2]), 3); +assertEq((function(a) { { let [x,y] = a; (function() { x += y })(); return x } })([1,2]), 3); +assertEq((function(a) { { let [x,y] = a; x += y; return (function() x)() } })([1,2]), 3); +assertEq((function(a) { { let [[l, x],[m, y]] = a; (function() { x += y })(); return x } })([[0,1],[0,2]]), 3); +assertEq((function(a) { { let [[l, x],[m, y]] = a; x += y; return (function() x)() } })([[0,1],[0,2]]), 3); + +assertEq((function() { let x = 3; return (function() { return x })() })(), 3); +assertEq((function() { let g = function() { return x }; let x = 3; return g() })(), 3); + +assertEq((function() { { let x = 3; return (function() { return x })() } })(), 3); +assertEq((function() { { let x = 3; (function() { assertEq(x, 3) })(); return x } })(), 3); +assertEq((function() { { let x = 2; x = 3; return (function() { return x })() } })(), 3); +assertEq((function() { { let x = 1; { let x = 3; (function() { assertEq(x,3) })() } return x } })(), 1); + +assertEq((function() { try { throw 3 } catch (e) { (function(){assertEq(e,3)})(); return e } })(), 3); +assertEq((function() { try { throw 3 } catch (e) { assertEq(e, 3); return (function() e)() } })(), 3); +assertEq((function() { try { throw 3 } catch (e) { (function(){eval('assertEq(e,3)')})(); return e } })(), 3); + +assertEq((function() { var x; function f() { return x } function f() { return 3 }; return f() })(), 3); +assertEq((function() { var x = 3; function f() { return 3 } function f() { return x }; return f() })(), 3); + +assertEq((function() { function f(x,y) { (function() { assertEq(f.length, 2) })(); }; return f.length })(), 2); +assertEq((function f(x,y) { (function() { assertEq(f.length, 2) })(); return f.length})(), 2); +function f1(x,y) { (function() { assertEq(f1.length, 2) })(); assertEq(f1.length, 2) }; f1(); + +String(function([]) { eval('') }); diff --git a/js/src/jit-test/tests/basic/testElemDec1.js b/js/src/jit-test/tests/basic/testElemDec1.js new file mode 100644 index 000000000..c03ea2ae0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testElemDec1.js @@ -0,0 +1,7 @@ +var obj = {p: 100}; +var name = "p"; +var a = []; +for (var i = 0; i < 10; i++) + a[i] = obj[name]--; +assertEq(a.join(','), '100,99,98,97,96,95,94,93,92,91'); +assertEq(obj.p, 90); diff --git a/js/src/jit-test/tests/basic/testElemDec2.js b/js/src/jit-test/tests/basic/testElemDec2.js new file mode 100644 index 000000000..7dc674645 --- /dev/null +++ b/js/src/jit-test/tests/basic/testElemDec2.js @@ -0,0 +1,7 @@ +var obj = {s: ""}; +var name = "s"; +for (var i = 0; i <= 13; i++) + if (i > 8) + obj[name]--; // first recording changes obj.s from string to number +assertEq(obj.s, -5); + diff --git a/js/src/jit-test/tests/basic/testElemInc1.js b/js/src/jit-test/tests/basic/testElemInc1.js new file mode 100644 index 000000000..c0d4f8c11 --- /dev/null +++ b/js/src/jit-test/tests/basic/testElemInc1.js @@ -0,0 +1,7 @@ +var obj = {p: 100}; +var name = "p"; +var a = []; +for (var i = 0; i < 10; i++) + a[i] = obj[name]++; +assertEq(a.join(','), '100,101,102,103,104,105,106,107,108,109'); +assertEq(obj.p, 110); diff --git a/js/src/jit-test/tests/basic/testElemInc2.js b/js/src/jit-test/tests/basic/testElemInc2.js new file mode 100644 index 000000000..56a926b2e --- /dev/null +++ b/js/src/jit-test/tests/basic/testElemInc2.js @@ -0,0 +1,7 @@ +var obj = {s: ""}; +var name = "s"; +for (var i = 0; i <= 13; i++) + if (i > 8) + obj[name]++; // first recording changes obj.s from string to number +assertEq(obj.s, 5); + diff --git a/js/src/jit-test/tests/basic/testEliminatedGuardWithinAnchor.js b/js/src/jit-test/tests/basic/testEliminatedGuardWithinAnchor.js new file mode 100644 index 000000000..25d0be96c --- /dev/null +++ b/js/src/jit-test/tests/basic/testEliminatedGuardWithinAnchor.js @@ -0,0 +1,6 @@ +function testEliminatedGuardWithinAnchor() { + for (let i = 0; i < 5; ++i) { i / (i * i); } + return "ok"; +} + +assertEq(testEliminatedGuardWithinAnchor(), "ok"); diff --git a/js/src/jit-test/tests/basic/testEqFalseEmptyString.js b/js/src/jit-test/tests/basic/testEqFalseEmptyString.js new file mode 100644 index 000000000..6fd70f107 --- /dev/null +++ b/js/src/jit-test/tests/basic/testEqFalseEmptyString.js @@ -0,0 +1,6 @@ +function testEqFalseEmptyString() { + var x = []; + for (var i=0;i<5;++i) x.push(false == ""); + return x.join(","); +} +assertEq(testEqFalseEmptyString(), "true,true,true,true,true"); diff --git a/js/src/jit-test/tests/basic/testErrorInFinalizerCalledWhileUnwinding.js b/js/src/jit-test/tests/basic/testErrorInFinalizerCalledWhileUnwinding.js new file mode 100644 index 000000000..41b1e3d0e --- /dev/null +++ b/js/src/jit-test/tests/basic/testErrorInFinalizerCalledWhileUnwinding.js @@ -0,0 +1,32 @@ +var finalizerRun = false; +var caught = false; + +function foo(arr) { + finalizerRun = true; + return not_defined; +} + +function gen() { + try { + yield 1; + } finally { + foo(); + } +} + +function test() { + var i_have_locals; + for (i in gen()) { + "this won't work"(); + } +} + +try { + test(); +} catch(e) { + caught = true; + assertEq(''+e, "ReferenceError: not_defined is not defined"); +} + +assertEq(finalizerRun, true); +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/testEvalCalledFromWatchOverSetter.js b/js/src/jit-test/tests/basic/testEvalCalledFromWatchOverSetter.js new file mode 100644 index 000000000..bcd60fd80 --- /dev/null +++ b/js/src/jit-test/tests/basic/testEvalCalledFromWatchOverSetter.js @@ -0,0 +1,3 @@ +this.__defineSetter__("x", function(){}); +this.watch("x", eval); +x = 0; diff --git a/js/src/jit-test/tests/basic/testEvalInFrameEdgeCase.js b/js/src/jit-test/tests/basic/testEvalInFrameEdgeCase.js new file mode 100644 index 000000000..d22a35757 --- /dev/null +++ b/js/src/jit-test/tests/basic/testEvalInFrameEdgeCase.js @@ -0,0 +1,11 @@ +load(libdir + "evalInFrame.js"); + +function g() { + var x = 100; + return evalInFrame(2, "x"); +} +function f() { + var x = 42; + return evalInFrame.call(null, 0, "g()"); +} +assertEq(f.call(), 42); diff --git a/js/src/jit-test/tests/basic/testEvalInFunctionCallee.js b/js/src/jit-test/tests/basic/testEvalInFunctionCallee.js new file mode 100644 index 000000000..81f757fa6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testEvalInFunctionCallee.js @@ -0,0 +1,4 @@ +function f(x,y) { + eval("assertEq(arguments.callee, f)"); +} +f(1,2); diff --git a/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-2.js b/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-2.js new file mode 100644 index 000000000..002da3f61 --- /dev/null +++ b/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-2.js @@ -0,0 +1,8 @@ +function f() { + var a = [], i, N = 10; + for (i = 0; i < N; i++) + a[i] = {m: i, m: function() { return 0; }}; + assertEq(a[N - 2].m === a[N - 1].m, false); +} +f(); +f(); diff --git a/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-3.js b/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-3.js new file mode 100644 index 000000000..573c33ef1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-3.js @@ -0,0 +1,15 @@ +function f() { + var a = [], i, N = 10; + for (i = 0; i < N; i++) { + a[i] = {}; + a[i].m = function() { return 0; }; + a[i].m = function() { return 1; }; + } + assertEq(a[N - 2].m === a[N - 1].m, false); + for (i = 0; i < N; i++) { + var f = a[i].m; + assertEq(f(), 1); + } +} +f(); +f(); diff --git a/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-4.js b/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-4.js new file mode 100644 index 000000000..8d0bc1b15 --- /dev/null +++ b/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt-4.js @@ -0,0 +1,12 @@ +function f() { + var a = [], i, N = 10; + for (i = 0; i < N; i++) + a[i] = {m: function() { return 0; }, m: function() { return 1; }}; + assertEq(a[N - 2].m === a[N - 1].m, false); + for (i = 0; i < N; i++) { + var f = a[i].m; + assertEq(f(), 1); + } +} +f(); +f(); diff --git a/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt.js b/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt.js new file mode 100644 index 000000000..0faafe2f4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testExistingPropToJoinedMethodAttempt.js @@ -0,0 +1,10 @@ +function f() { + var a = [], i, N = 10; + for (i = 0; i < N; i++) + a[i] = {m: i}; + for (i = 0; i < N; i++) + a[i].m = function() { return 0; }; + assertEq(a[N - 2].m === a[N - 1].m, false); +} +f(); +f(); diff --git a/js/src/jit-test/tests/basic/testFakeDOMWeakmapKey.js b/js/src/jit-test/tests/basic/testFakeDOMWeakmapKey.js new file mode 100644 index 000000000..80d116960 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFakeDOMWeakmapKey.js @@ -0,0 +1 @@ +(new WeakMap).set(FakeDOMObject.prototype, this) diff --git a/js/src/jit-test/tests/basic/testFewerGlobalsInInnerTree.js b/js/src/jit-test/tests/basic/testFewerGlobalsInInnerTree.js new file mode 100644 index 000000000..25a4a52ef --- /dev/null +++ b/js/src/jit-test/tests/basic/testFewerGlobalsInInnerTree.js @@ -0,0 +1,14 @@ +function testFewerGlobalsInInnerTree() { + for each (a in [new Number(1), new Number(1), {}, {}, new Number(1)]) { + for each (b in [2, "", 2, "", "", ""]) { + for each (c in [{}, {}, 3, 3, 3, 3, {}, {}]) { + 4 + a; + } + } + } + delete a; + delete b; + delete c; + return "ok"; +} +assertEq(testFewerGlobalsInInnerTree(), "ok"); diff --git a/js/src/jit-test/tests/basic/testFloatArrayIndex.js b/js/src/jit-test/tests/basic/testFloatArrayIndex.js new file mode 100644 index 000000000..564824778 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFloatArrayIndex.js @@ -0,0 +1,9 @@ +function testFloatArrayIndex() { + var a = []; + for (var i = 0; i < 10; ++i) { + a[3] = 5; + a[3.5] = 7; + } + return a[3] + "," + a[3.5]; +} +assertEq(testFloatArrayIndex(), "5,7"); diff --git a/js/src/jit-test/tests/basic/testFoldPropertyAccess.js b/js/src/jit-test/tests/basic/testFoldPropertyAccess.js new file mode 100644 index 000000000..2ccb5e21f --- /dev/null +++ b/js/src/jit-test/tests/basic/testFoldPropertyAccess.js @@ -0,0 +1,23 @@ + +var cases = [ + function (obj) { + return obj["ab"]; + }, + function (obj) { + return obj["a" + "b"]; + }, + function (obj) { + return obj[0 ? "cd" : "ab"]; + }, + function (obj) { + return obj[true ? "ab" : "cd"]; + }, + function (obj) { + return obj[(1 + 0) ? "ab" : "cd"]; + } +] + +for (var i = 0; i < cases.length; i++) { + assertEq(cases[i]({ab: 42}), 42); + assertEq(cases[i]({cd: 120}), undefined); +} diff --git a/js/src/jit-test/tests/basic/testForEach.js b/js/src/jit-test/tests/basic/testForEach.js new file mode 100644 index 000000000..09f6c8d9c --- /dev/null +++ b/js/src/jit-test/tests/basic/testForEach.js @@ -0,0 +1,11 @@ +function testForEach() { + var r; + var a = ["zero", "one", "two", "three"]; + for (var i = 0; i < 9; i++) { + r = ""; + for each (var s in a) + r += s + " "; + } + return r; +} +assertEq(testForEach(), "zero one two three "); diff --git a/js/src/jit-test/tests/basic/testForInLoopChangeIteratorType.js b/js/src/jit-test/tests/basic/testForInLoopChangeIteratorType.js new file mode 100644 index 000000000..0efce8364 --- /dev/null +++ b/js/src/jit-test/tests/basic/testForInLoopChangeIteratorType.js @@ -0,0 +1,11 @@ +function testForInLoopChangeIteratorType() { + for(y in [0,1,2]) y = NaN; + (function(){ + [].__proto__.u = void 0; + for (let y in [5,6,7,8]) + y = NaN; + delete [].__proto__.u; + })() + return "ok"; +} +assertEq(testForInLoopChangeIteratorType(), "ok"); diff --git a/js/src/jit-test/tests/basic/testFunApplyMadness1.js b/js/src/jit-test/tests/basic/testFunApplyMadness1.js new file mode 100644 index 000000000..dabc41be4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFunApplyMadness1.js @@ -0,0 +1,19 @@ +function g() { assertEq(false, true) } +var ct = 0; + +function f(b) { + var a = arguments; + if (b) + f(false); + else + g = { + apply:function(x,y) { + ++ct; + assertEq(x, null); + assertEq(typeof y[0], "boolean"); + } + }; + g.apply(null, a); +} +f(true); +assertEq(ct, 2); diff --git a/js/src/jit-test/tests/basic/testFunApplyMadness2.js b/js/src/jit-test/tests/basic/testFunApplyMadness2.js new file mode 100644 index 000000000..22684fdd3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFunApplyMadness2.js @@ -0,0 +1,20 @@ +function g() { assertEq(false, true) } +var ct = 0; + +function f(b) { + if (b) { + arguments = [false]; + f(false); + } else { + g = { + apply:function(x,y) { + ++ct; + assertEq(x, null); + assertEq(y[0], false); + } + }; + } + g.apply(null, arguments); +} +f(true); +assertEq(ct, 2); diff --git a/js/src/jit-test/tests/basic/testFunApplyMadness400.js b/js/src/jit-test/tests/basic/testFunApplyMadness400.js new file mode 100644 index 000000000..886d55934 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFunApplyMadness400.js @@ -0,0 +1,19 @@ +function g() { assertEq(false, true) } +var max = 400; ct = 0; + +function f(b) { + if (b) { + f(b - 1); + } else { + g = { + apply:function(x,y) { + assertEq(x, null); + assertEq(y[0], ct); + ++ct; + } + }; + } + g.apply(null, arguments); +} +f(max - 1); +assertEq(ct, max); diff --git a/js/src/jit-test/tests/basic/testFunApplyMisspeculation.js b/js/src/jit-test/tests/basic/testFunApplyMisspeculation.js new file mode 100644 index 000000000..d572d4ff2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFunApplyMisspeculation.js @@ -0,0 +1,3 @@ +var h = { apply:function() { return "ponies"; } }; +function f() { var x = 3; g = function() { return ++x }; return h.apply(null, arguments) } +assertEq(f(), "ponies"); diff --git a/js/src/jit-test/tests/basic/testFunApplyOverflow.js b/js/src/jit-test/tests/basic/testFunApplyOverflow.js new file mode 100644 index 000000000..45be944e9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFunApplyOverflow.js @@ -0,0 +1,10 @@ +function g(x,y) { + return x + y; +} + +function f(x) { + return g.apply(null, arguments); +} + +for (var i = 0; i < 100; ++i) + assertEq(f(i, 1), i+1); diff --git a/js/src/jit-test/tests/basic/testFunctionIdentityChange.js b/js/src/jit-test/tests/basic/testFunctionIdentityChange.js new file mode 100644 index 000000000..9f4b7dddf --- /dev/null +++ b/js/src/jit-test/tests/basic/testFunctionIdentityChange.js @@ -0,0 +1,16 @@ +function testFunctionIdentityChange() +{ + function a() {} + function b() {} + + var o = { a: a, b: b }; + + for (var prop in o) + { + for (var i = 0; i < 1000; i++) + o[prop](); + } + + return true; +} +assertEq(testFunctionIdentityChange(), true); diff --git a/js/src/jit-test/tests/basic/testFunctionStatementAliasLocals.js b/js/src/jit-test/tests/basic/testFunctionStatementAliasLocals.js new file mode 100644 index 000000000..7be49b7f3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFunctionStatementAliasLocals.js @@ -0,0 +1,16 @@ +function f1(b) { + var w = 3; + if (b) + function w() {} + return w; +} +assertEq(typeof f1(true), "function"); +assertEq(f1(false), 3); + +function f2(b, w) { + if (b) + function w() {} + return w; +} +assertEq(typeof f2(true, 3), "function"); +assertEq(f2(false, 3), 3); diff --git a/js/src/jit-test/tests/basic/testFunctionStatementNamedArguments.js b/js/src/jit-test/tests/basic/testFunctionStatementNamedArguments.js new file mode 100644 index 000000000..967ab3e93 --- /dev/null +++ b/js/src/jit-test/tests/basic/testFunctionStatementNamedArguments.js @@ -0,0 +1,10 @@ +var g; +function foo(b) { + if (b) + function arguments() {}; + return arguments; +} + +var a = foo(true); +assertEq(typeof a, "function"); +assertEq(a.name, "arguments"); diff --git a/js/src/jit-test/tests/basic/testGCWhileRecording.js b/js/src/jit-test/tests/basic/testGCWhileRecording.js new file mode 100644 index 000000000..cb1f0e806 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGCWhileRecording.js @@ -0,0 +1,8 @@ +function test() { + for (let z = 0; z < 4; ++z) { + uneval({ x: 9 }); + gc() + } + return "pass"; +} +assertEq(test(), "pass"); diff --git a/js/src/jit-test/tests/basic/testGeneratorDeepBail.js b/js/src/jit-test/tests/basic/testGeneratorDeepBail.js new file mode 100644 index 000000000..50c62b074 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGeneratorDeepBail.js @@ -0,0 +1,11 @@ +function testGeneratorDeepBail() { + function g() { yield 2; } + var iterables = [[1], [], [], [], g()]; + + var total = 0; + for (let i = 0; i < iterables.length; i++) + for each (let j in iterables[i]) + total += j; + return total; +} +assertEq(testGeneratorDeepBail(), 3); diff --git a/js/src/jit-test/tests/basic/testGeneratorDieButScopeAlive.js b/js/src/jit-test/tests/basic/testGeneratorDieButScopeAlive.js new file mode 100644 index 000000000..67ab73ddf --- /dev/null +++ b/js/src/jit-test/tests/basic/testGeneratorDieButScopeAlive.js @@ -0,0 +1,24 @@ +var g = newGlobal(); +var dbg = new Debugger(g); + +var hits = 0; +dbg.onDebuggerStatement = function(frame) { + ++hits; + frame.older.eval("escaped = function() { return y }"); +} + +var arr = []; +const N = 10; + +for (var i = 0; i < N; ++i) { + g.escaped = undefined; + g.eval("function h() { debugger }"); + g.eval("(function () { var y = {p:42}; h(); yield })().next();"); + assertEq(g.eval("escaped().p"), 42); + arr.push(g.escaped); +} + +gc(); + +for (var i = 0; i < N; ++i) + arr[i](); diff --git a/js/src/jit-test/tests/basic/testGetCallObj.js b/js/src/jit-test/tests/basic/testGetCallObj.js new file mode 100644 index 000000000..6c0902a0a --- /dev/null +++ b/js/src/jit-test/tests/basic/testGetCallObj.js @@ -0,0 +1,11 @@ +function testGetCallObjInlined(i) { + if (i > 7) eval("1"); + return 1; +} + +function testGetCallObj() { + for (var i = 0; i < 10; ++i) + testGetCallObjInlined(i); + return "ok"; +} +assertEq(testGetCallObj(), "ok"); diff --git a/js/src/jit-test/tests/basic/testGetThis.js b/js/src/jit-test/tests/basic/testGetThis.js new file mode 100644 index 000000000..3c2546a6b --- /dev/null +++ b/js/src/jit-test/tests/basic/testGetThis.js @@ -0,0 +1,7 @@ +function testGetThis() { + for (var i = 0; i < 3; ++i) { + (function() { return this; })(); + } + return "ok"; +} +assertEq(testGetThis(), "ok"); diff --git a/js/src/jit-test/tests/basic/testGlobalAsProto.js b/js/src/jit-test/tests/basic/testGlobalAsProto.js new file mode 100644 index 000000000..1ba24550a --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalAsProto.js @@ -0,0 +1,3 @@ +var b = Object.create(this); +for (var i = 0; i < 9; i++) + assertEq(b.i, i); diff --git a/js/src/jit-test/tests/basic/testGlobalMultitrees1.js b/js/src/jit-test/tests/basic/testGlobalMultitrees1.js new file mode 100644 index 000000000..108134d19 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalMultitrees1.js @@ -0,0 +1,11 @@ +//test no multitrees assert +function testGlobalMultitrees1() { + (function() { + for (var j = 0; j < 4; ++j) { + for each (e in ['A', 1, 'A']) { + } + } + })(); + return true; +} +assertEq(testGlobalMultitrees1(), true); diff --git a/js/src/jit-test/tests/basic/testGlobalOptimize-2.js b/js/src/jit-test/tests/basic/testGlobalOptimize-2.js new file mode 100644 index 000000000..3aa1db610 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalOptimize-2.js @@ -0,0 +1,8 @@ +var test; +{ + let a = 5; + with ({a: 2}) { + test = (function () { return a; })(); + } +} +assertEq(test, 2); diff --git a/js/src/jit-test/tests/basic/testGlobalOptimize-3.js b/js/src/jit-test/tests/basic/testGlobalOptimize-3.js new file mode 100644 index 000000000..ef62a7089 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalOptimize-3.js @@ -0,0 +1,10 @@ +var test; +{ + with ({a: 2}) { + { + let a = 5; + test = (function () { return a; })(); + } + } +} +assertEq(test, 5); diff --git a/js/src/jit-test/tests/basic/testGlobalOptimize-4.js b/js/src/jit-test/tests/basic/testGlobalOptimize-4.js new file mode 100644 index 000000000..30754214a --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalOptimize-4.js @@ -0,0 +1,8 @@ +var test; +{ + with ({a: 2}) { + test = (function () { return a; })(); + } + let a = 5; +} +assertEq(test, 2); diff --git a/js/src/jit-test/tests/basic/testGlobalOptimize-5.js b/js/src/jit-test/tests/basic/testGlobalOptimize-5.js new file mode 100644 index 000000000..e0a3aecc2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalOptimize-5.js @@ -0,0 +1,11 @@ +var test; +function f() { + { + let a = 5; + with ({a: 2}) { + test = (function () { return a;} )(); + } + } +} +f(); +assertEq(test, 2); diff --git a/js/src/jit-test/tests/basic/testGlobalOptimize-6.js b/js/src/jit-test/tests/basic/testGlobalOptimize-6.js new file mode 100644 index 000000000..4bc14058e --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalOptimize-6.js @@ -0,0 +1,11 @@ +var test; +function f() { + with ({a: 2}) { + { + let a = 5; + test = (function () { return a; })(); + } + } +} +f(); +assertEq(test, 5); diff --git a/js/src/jit-test/tests/basic/testGlobalProtoAccess.js b/js/src/jit-test/tests/basic/testGlobalProtoAccess.js new file mode 100644 index 000000000..97f161289 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalProtoAccess.js @@ -0,0 +1,5 @@ +function testGlobalProtoAccess() { + return "ok"; +} +this.__proto__.a = 3; for (var j = 0; j < 4; ++j) { [a]; } +assertEq(testGlobalProtoAccess(), "ok"); diff --git a/js/src/jit-test/tests/basic/testGlobalShapeChangeAfterDeepBail.js b/js/src/jit-test/tests/basic/testGlobalShapeChangeAfterDeepBail.js new file mode 100644 index 000000000..0839b370c --- /dev/null +++ b/js/src/jit-test/tests/basic/testGlobalShapeChangeAfterDeepBail.js @@ -0,0 +1,15 @@ +// Complicated whitebox test for bug 487845. +function testGlobalShapeChangeAfterDeepBail() { + function f(name) { + this[name] = 1; // may change global shape + for (var i = 0; i < 4; i++) + ; // MonitorLoopEdge eventually triggers assertion + } + + // When i==3, deep-bail, then change global shape enough times to exhaust + // the array of GlobalStates. + var arr = [[], [], [], ["bug0", "bug1", "bug2", "bug3", "bug4"]]; + for (var i = 0; i < arr.length; i++) + arr[i].forEach(f); +} +testGlobalShapeChangeAfterDeepBail(); diff --git a/js/src/jit-test/tests/basic/testGroupAssignment.js b/js/src/jit-test/tests/basic/testGroupAssignment.js new file mode 100644 index 000000000..015efbe54 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGroupAssignment.js @@ -0,0 +1,15 @@ +assertEq( + (function () { + var arr = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 ]; + + for (var i = 0; i < 4; ++i) { + var src = i * 8; + var dst = i * 8 + 7; + for (var j = 0; j < 4; ++j) { + [arr[dst--], arr[src++]] = [arr[src], arr[dst]]; + } + } + return arr; + })().toSource(), + "[7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 23, 22, 21, 20, 19, 18, 17, 16, 31, 30, 29, 28, 27, 26, 25, 24, 32]"); diff --git a/js/src/jit-test/tests/basic/testGrowDenseArray.js b/js/src/jit-test/tests/basic/testGrowDenseArray.js new file mode 100644 index 000000000..810c12ff6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGrowDenseArray.js @@ -0,0 +1,7 @@ +function testGrowDenseArray() { + var a = new Array(); + for (var i = 0; i < 10; ++i) + a[i] |= 5; + return a.join(","); +} +assertEq(testGrowDenseArray(), "5,5,5,5,5,5,5,5,5,5"); diff --git a/js/src/jit-test/tests/basic/testGuardCalleeSneakAttack.js b/js/src/jit-test/tests/basic/testGuardCalleeSneakAttack.js new file mode 100644 index 000000000..87939ef99 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGuardCalleeSneakAttack.js @@ -0,0 +1,31 @@ +function loop(f, expected) { + // This is the loop that breaks us. + // At record time, f's parent is a Call object with no fp. + // At second execute time, it is a Call object with fp, + // and all the Call object's dslots are still JSVAL_VOID. + for (var i = 0; i < 9; i++) + assertEq(f(), expected); +} + +function C(bad) { + var x = bad; + function f() { + return x; // We trick TR::callProp() into emitting code that gets + // JSVAL_VOID (from the Call object's dslots) + // rather than the actual value (true or false). + } + this.m = f; + return f; +} + +var obj = { + set m(f) { + if (f()) // Call once to resolve x on the Call object, + // for shape consistency. Otherwise loop gets + // recorded twice. + loop(f, true); + } +}; + +loop(C.call(obj, false), false); +C.call(obj, true); diff --git a/js/src/jit-test/tests/basic/testGuardCalleeSneakAttack2.js b/js/src/jit-test/tests/basic/testGuardCalleeSneakAttack2.js new file mode 100644 index 000000000..9bf3c0c38 --- /dev/null +++ b/js/src/jit-test/tests/basic/testGuardCalleeSneakAttack2.js @@ -0,0 +1,32 @@ +function loop(f, expected) { + // This is the loop that breaks us. + // At record time, f's parent is a Call object with no fp. + // At second execute time, it is a Call object with fp, + // and all the Call object's dslots are still JSVAL_VOID. + for (var i = 0; i < 9; i++) + assertEq(f(), expected); +} + +function C(bad) { + var x = bad; + function f() { + return x; // We trick TR::callProp() into emitting code that gets + // JSVAL_VOID (from the Call object's dslots) + // rather than the actual value (true or false). + } + if (bad) + void (f + "a!"); + return f; +} + +var obj = { +}; + +// Warm up and trace with C's Call object entrained but its stack frame gone. +loop(C.call(obj, false), false); + +// Sneaky access to f via a prototype method called implicitly by operator +. +Function.prototype.toString = function () { loop(this, true); return "hah"; }; + +// Fail hard if we don't handle the implicit call out of C to F.p.toString. +C.call(obj, true); diff --git a/js/src/jit-test/tests/basic/testHOTLOOPSize.js b/js/src/jit-test/tests/basic/testHOTLOOPSize.js new file mode 100644 index 000000000..9245a7f2f --- /dev/null +++ b/js/src/jit-test/tests/basic/testHOTLOOPSize.js @@ -0,0 +1,4 @@ +function test8Size() { + return 8 > 1; +} +assertEq(test8Size(), true); diff --git a/js/src/jit-test/tests/basic/testHeavy.js b/js/src/jit-test/tests/basic/testHeavy.js new file mode 100644 index 000000000..1d539fb2d --- /dev/null +++ b/js/src/jit-test/tests/basic/testHeavy.js @@ -0,0 +1,14 @@ +function heavyFn1(i) { + if (i == 3) { + var x = 3; + return [0, i].map(function (i) { return i + x; }); + } + return []; +} + +function testHeavy() { + for (var i = 0; i <= 3; i++) + heavyFn1(i); +} + +testHeavy(); diff --git a/js/src/jit-test/tests/basic/testHeavy2.js b/js/src/jit-test/tests/basic/testHeavy2.js new file mode 100644 index 000000000..12da3eee5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testHeavy2.js @@ -0,0 +1,20 @@ +function heavyFn1(i) { + if (i == 3) { + var x = 3; + return [0, i].map(function (i) { return i + x; }); + } + return []; +} + +function heavyFn2(i) { + if (i < 1000) + return heavyFn1(i); + return function () { return i; }; +} + +function testHeavy2() { + for (var i = 0; i <= 3; i++) + heavyFn2(i); +} + +testHeavy2(); diff --git a/js/src/jit-test/tests/basic/testHoleInDenseArray.js b/js/src/jit-test/tests/basic/testHoleInDenseArray.js new file mode 100644 index 000000000..29523262c --- /dev/null +++ b/js/src/jit-test/tests/basic/testHoleInDenseArray.js @@ -0,0 +1,16 @@ +var s; + +function f(i) { + if (i > 4) /* side exit when arr[i] changes from bool to undefined (via a hole) */ + assertEq(s, undefined); + else + assertEq(s, false); + return 1; +} + +/* trailing 'true' ensures array has capacity >= 10 */ +var arr = [ false, false, false, false, false, , , , , , true ]; + +for (var i = 0; i < 10; ++i) { + (s = arr[i]) + f(i); +} diff --git a/js/src/jit-test/tests/basic/testHolePushing.js b/js/src/jit-test/tests/basic/testHolePushing.js new file mode 100644 index 000000000..a2316130e --- /dev/null +++ b/js/src/jit-test/tests/basic/testHolePushing.js @@ -0,0 +1,13 @@ +function testHolePushing() { + var a = ["foobar", "baz"]; + for (var i = 0; i < 5; i++) + a = [, "overwritten", "new"]; + var s = "["; + for (i = 0; i < a.length; i++) { + s += (i in a) ? a[i] : "<hole>"; + if (i != a.length - 1) + s += ","; + } + return s + "], " + (0 in a); +} +assertEq(testHolePushing(), "[<hole>,overwritten,new], false"); diff --git a/js/src/jit-test/tests/basic/testHolesAndIndexPropertiesOnThePrototype.js b/js/src/jit-test/tests/basic/testHolesAndIndexPropertiesOnThePrototype.js new file mode 100644 index 000000000..1af2506bf --- /dev/null +++ b/js/src/jit-test/tests/basic/testHolesAndIndexPropertiesOnThePrototype.js @@ -0,0 +1,29 @@ +function f(x,y,z) { + return x + y + z; +} + +Array.prototype[1] = 10; + +function g() { + var arr = [1, ,3,4,5,6]; + + for (var i = 0; i < 10; ++i) { + assertEq(f.apply(null, arr), 14); + } +} +g(); + +Object.prototype[1] = 20; + +function h() { + delete arguments[1]; + return f.apply(null, arguments); +} +assertEq(h(1,2,3), 24); + +function i() { + o = arguments; + delete o[1]; + return f.apply(null, o); +} +assertEq(i(1,2,3), 24); diff --git a/js/src/jit-test/tests/basic/testINITELEM.js b/js/src/jit-test/tests/basic/testINITELEM.js new file mode 100644 index 000000000..2d7567a24 --- /dev/null +++ b/js/src/jit-test/tests/basic/testINITELEM.js @@ -0,0 +1,8 @@ +function testINITELEM() +{ + var x; + for (var i = 0; i < 10; ++i) + x = { 0: 5, 1: 5 }; + return x[0] + x[1]; +} +assertEq(testINITELEM(), 10); diff --git a/js/src/jit-test/tests/basic/testImplicitThisMiss.js b/js/src/jit-test/tests/basic/testImplicitThisMiss.js new file mode 100644 index 000000000..8539001ef --- /dev/null +++ b/js/src/jit-test/tests/basic/testImplicitThisMiss.js @@ -0,0 +1,2 @@ +// |jit-test| error:TypeError +Function("Object.defineProperty(this, 'x', { configurable:true, get:function() { delete this['x'] } }); x()")(); diff --git a/js/src/jit-test/tests/basic/testIn.js b/js/src/jit-test/tests/basic/testIn.js new file mode 100644 index 000000000..aeadab308 --- /dev/null +++ b/js/src/jit-test/tests/basic/testIn.js @@ -0,0 +1,19 @@ +function testIn() { + var array = [3]; + var obj = { "-1": 5, "1.7": 3, "foo": 5, "1": 7 }; + var a = []; + for (let j = 0; j < 5; ++j) { + a.push("0" in array); + a.push(-1 in obj); + a.push(1.7 in obj); + a.push("foo" in obj); + a.push(1 in obj); + a.push("1" in array); + a.push(-2 in obj); + a.push(2.7 in obj); + a.push("bar" in obj); + a.push(2 in obj); + } + return a.join(","); +} +assertEq(testIn(), "true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,false,false,false,false,false,true,true,true,true,true,false,false,false,false,false"); diff --git a/js/src/jit-test/tests/basic/testIncDec.js b/js/src/jit-test/tests/basic/testIncDec.js new file mode 100644 index 000000000..89b533517 --- /dev/null +++ b/js/src/jit-test/tests/basic/testIncDec.js @@ -0,0 +1,19 @@ +function testIncDec2(ii) { + var x = []; + for (let j=0;j<5;++j) { + ii=j; + jj=j; + var kk=j; + x.push(ii--); + x.push(jj--); + x.push(kk--); + x.push(++ii); + x.push(++jj); + x.push(++kk); + } + return x.join(","); +} +function testIncDec() { + return testIncDec2(0); +} +assertEq(testIncDec(), "0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4"); diff --git a/js/src/jit-test/tests/basic/testIncDecReadOnly.js b/js/src/jit-test/tests/basic/testIncDecReadOnly.js new file mode 100644 index 000000000..5ff23b249 --- /dev/null +++ b/js/src/jit-test/tests/basic/testIncDecReadOnly.js @@ -0,0 +1,22 @@ +var r; +Object.defineProperty(this, "x", {value: 0, writable: false}); + +for (var a = 0; a < 10; ++a) + r = ++x; +assertEq(x, 0); +assertEq(r, 1); + +for (var a = 0; a < 10; ++a) + r = --x; +assertEq(x, 0); +assertEq(r, -1); + +for (var a = 0; a < 10; ++a) + r = x++; +assertEq(x, 0); +assertEq(r, 0); + +for (var a = 0; a < 10; ++a) + r = x--; +assertEq(x, 0); +assertEq(r, 0); diff --git a/js/src/jit-test/tests/basic/testIncElem1.js b/js/src/jit-test/tests/basic/testIncElem1.js new file mode 100644 index 000000000..633c327cf --- /dev/null +++ b/js/src/jit-test/tests/basic/testIncElem1.js @@ -0,0 +1,7 @@ +var obj = {p: 100}; +var name = "p"; +var a = []; +for (var i = 0; i < 10; i++) + a[i] = ++obj[name]; +assertEq(a.join(','), '101,102,103,104,105,106,107,108,109,110'); +assertEq(obj.p, 110); diff --git a/js/src/jit-test/tests/basic/testIncElem2.js b/js/src/jit-test/tests/basic/testIncElem2.js new file mode 100644 index 000000000..cc2d7d08e --- /dev/null +++ b/js/src/jit-test/tests/basic/testIncElem2.js @@ -0,0 +1,11 @@ +var obj = {s: ""}; +var name = "s"; +var a = []; +for (var i = 0; i <= 13; i++) { + a[i] = 'x'; + if (i > 8) + a[i] = ++obj[name]; // first recording changes obj.s from string to number +} +assertEq(a.join(','), Array(10).join('x,') + '1,2,3,4,5'); +assertEq(obj.s, 5); + diff --git a/js/src/jit-test/tests/basic/testIncElem3.js b/js/src/jit-test/tests/basic/testIncElem3.js new file mode 100644 index 000000000..922aeb9b8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testIncElem3.js @@ -0,0 +1,6 @@ +var arr; +for (var j = 0; j < 18; ++j ) { + arr = [,]; + ++arr[0]; +} +assertEq(isNaN(arr[0]), true); diff --git a/js/src/jit-test/tests/basic/testIncElem4.js b/js/src/jit-test/tests/basic/testIncElem4.js new file mode 100644 index 000000000..a3cec1661 --- /dev/null +++ b/js/src/jit-test/tests/basic/testIncElem4.js @@ -0,0 +1,10 @@ + +var counter = 0; +var x = { toString: function() { counter++; } }; +var y = {}; + +for (var i = 0; i < 50; i++) + ++y[x]; + +// :FIXME: bug 672076 +//assertEq(counter, 50); diff --git a/js/src/jit-test/tests/basic/testInitPropOverMethod.js b/js/src/jit-test/tests/basic/testInitPropOverMethod.js new file mode 100644 index 000000000..5f70d3cd6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInitPropOverMethod.js @@ -0,0 +1,9 @@ +for (var i = 0; i < 10; i++) + x = {a: function () { return 33; }, a: 4}; + +try { + result = x.a(); +} catch (exc) { + result = "threw " + exc.name; +} +assertEq(result, "threw TypeError"); diff --git a/js/src/jit-test/tests/basic/testInitPropWithIntName.js b/js/src/jit-test/tests/basic/testInitPropWithIntName.js new file mode 100644 index 000000000..755cd726b --- /dev/null +++ b/js/src/jit-test/tests/basic/testInitPropWithIntName.js @@ -0,0 +1,2 @@ +for (var j=0; j<8; ++j) + ({'0': 0}); diff --git a/js/src/jit-test/tests/basic/testInitProtoPrimitive.js b/js/src/jit-test/tests/basic/testInitProtoPrimitive.js new file mode 100644 index 000000000..d84dd8ac2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInitProtoPrimitive.js @@ -0,0 +1,2 @@ +for (var i = 0; i < 10; i++) + "" + {__proto__: 'aaa'}; diff --git a/js/src/jit-test/tests/basic/testInitSingletons.js b/js/src/jit-test/tests/basic/testInitSingletons.js new file mode 100644 index 000000000..fb8dd641c --- /dev/null +++ b/js/src/jit-test/tests/basic/testInitSingletons.js @@ -0,0 +1,59 @@ + +var x = [1,2.5,"three",true,false,null,[1,2,3],{a:0,b:1}]; +assertEq(String(x), "1,2.5,three,true,false,,1,2,3,[object Object]"); +assertEq(x.length, 8); +assertEq(x[7].a, 0); +assertEq(x[7].b, 1); + +var y = {a:0,a:1,a:2}; +assertEq(y.a,2); + +var z = {a:0,b:1,__proto__:{c:2,d:3}}; +assertEq(z.a,0); +assertEq(z.b,1); +assertEq(z.c,2); +assertEq(z.d,3); + +function foo() { + var q = eval("[1,2,3]"); + var r = eval("[1,2,3]"); + assertEq(q === r, false); +} +foo(); + +var q = {0x4fffffff: 0, 0x7fffffff: 1, 0xffffffff: 2}; +assertEq(q[1342177279], 0); +assertEq(q[2147483647], 1); +assertEq(q[4294967295], 2); + +try { + [1,2,3,{a:0,b:1}].foo.bar; +} catch (e) { assertEq(e.message.search("\.foo is undefined") != -1, true); } + +var a = [1 + 1, 3 * 2, 6 - 5, 14 % 6, 15 / 5, 1 << 3, + 8 >> 2, 5 | 2, 5 ^ 3, ~3, -3,"a" + "b", !true, !false]; +assertEq(String(a), "2,6,1,2,3,8,2,7,6,-4,-3,ab,false,true"); +assertEq(a.length, 14); + +var b = { + a: 1 + 1, + b: 3 * 2, + c: 6 - 5, + d: 14 % 6, + e: 15 / 5, + f: 1 << 3, + g: 8 >> 2, + h: 5 | 2, + i: 5 ^ 3, + j: ~3, + k: -3, + l: "a" + "b", + m: !true, + n: !false, +} + +var char = "a".charCodeAt(0); +for (var i = 0; i < a.length; i++) { + assertEq(b[String.fromCharCode(char)], a[i]); + char++; +} diff --git a/js/src/jit-test/tests/basic/testInitSlowify.js b/js/src/jit-test/tests/basic/testInitSlowify.js new file mode 100644 index 000000000..fb6868c25 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInitSlowify.js @@ -0,0 +1,41 @@ + +var x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,gc(), + ]; +assertEq(x.length, 500); +assertEq(x[10], 11); +assertEq(x[90], 11); + +function stringify(a) { + var b = ""; + for (var c in a) { b += c + ","; } + return b; +} + +var y = {a:1,b:2,c:3,d:4,e:gc(),f:6,g:7,h:8,i:9,j:gc(), + k:11,l:12,m:13,n:14,o:gc(),p:16,q:17,r:18,s:19,t:gc()}; + +assertEq(stringify(y), "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,"); diff --git a/js/src/jit-test/tests/basic/testInitelemCond.js b/js/src/jit-test/tests/basic/testInitelemCond.js new file mode 100644 index 000000000..2f83c1210 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInitelemCond.js @@ -0,0 +1,13 @@ + +/* Element initializers with unknown index. */ + +function foo(i) { + var x = [1,2,i == 1 ? 3 : 4,5,6]; + var y = "" + x; + if (i == 1) + assertEq(y, "1,2,3,5,6"); + else + assertEq(y, "1,2,4,5,6"); +} +for (var i = 0; i < 10; i++) + foo(i); diff --git a/js/src/jit-test/tests/basic/testInitelemWithFloatIndex.js b/js/src/jit-test/tests/basic/testInitelemWithFloatIndex.js new file mode 100644 index 000000000..93477e7cb --- /dev/null +++ b/js/src/jit-test/tests/basic/testInitelemWithFloatIndex.js @@ -0,0 +1,3 @@ +for (i = 0; i < 9; i++) + x = {1.5: 0}; +assertEq(x["1.5"], 0); diff --git a/js/src/jit-test/tests/basic/testInitelemWithSetter.js b/js/src/jit-test/tests/basic/testInitelemWithSetter.js new file mode 100644 index 000000000..6753b3787 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInitelemWithSetter.js @@ -0,0 +1,3 @@ +Object.prototype.__defineSetter__(1, function () { throw "fit"; }); +for (var i =0; i<9; i++) + ({1:'a'}); diff --git a/js/src/jit-test/tests/basic/testInnerMissingArgs.js b/js/src/jit-test/tests/basic/testInnerMissingArgs.js new file mode 100644 index 000000000..d70b5d1aa --- /dev/null +++ b/js/src/jit-test/tests/basic/testInnerMissingArgs.js @@ -0,0 +1,21 @@ +function innerTestInnerMissingArgs(a,b,c,d) +{ + if (a) { + } else { + } +} + +function doTestInnerMissingArgs(k) +{ + for (i = 0; i < 10; i++) { + innerTestInnerMissingArgs(k); + } +} + +function testInnerMissingArgs() +{ + doTestInnerMissingArgs(1); + doTestInnerMissingArgs(0); +} + +testInnerMissingArgs(); diff --git a/js/src/jit-test/tests/basic/testInnerSwitchBreak.js b/js/src/jit-test/tests/basic/testInnerSwitchBreak.js new file mode 100644 index 000000000..4e9eafdbc --- /dev/null +++ b/js/src/jit-test/tests/basic/testInnerSwitchBreak.js @@ -0,0 +1,24 @@ +function innerSwitch(k) +{ + var m = 0; + + switch (k) + { + case 0: + m = 1; + break; + } + + return m; +} +function testInnerSwitchBreak() +{ + var r = new Array(5); + for (var i = 0; i < 5; i++) + { + r[i] = innerSwitch(0); + } + + return r.join(","); +} +assertEq(testInnerSwitchBreak(), "1,1,1,1,1"); diff --git a/js/src/jit-test/tests/basic/testInnerTreeMutatingUpvars.js b/js/src/jit-test/tests/basic/testInnerTreeMutatingUpvars.js new file mode 100644 index 000000000..97502f836 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInnerTreeMutatingUpvars.js @@ -0,0 +1,17 @@ +function f() { + for (var a = 0; a < 8; ++a) { + (function () { + var x; + for (var b = 0; b < 8; ++b) { + x = 0; + (function () { + for (var i = 0; i < 1; ++i) { + x = 1; + } + })(); + x++; + } + })(); + } +} +f(); diff --git a/js/src/jit-test/tests/basic/testInt32ToId.js b/js/src/jit-test/tests/basic/testInt32ToId.js new file mode 100644 index 000000000..3164ac5de --- /dev/null +++ b/js/src/jit-test/tests/basic/testInt32ToId.js @@ -0,0 +1,35 @@ +function testInt32ToId() +{ + // Ensure that a property which is a negative integer that does not fit in a + // jsval is properly detected by the 'in' operator. + var obj = { "-1073741828": 17 }; + var index = -1073741819; + var a = []; + for (var i = 0; i < 10; i++) + { + a.push(index in obj); + index--; + } + + // Ensure that a property which is a negative integer that does not fit in a + // jsval is properly *not* detected by the 'in' operator. In this case + // wrongly applying INT_TO_JSID to -2147483648 will shift off the sign bit + // (the only bit set in that number) and bitwise-or that value with 1, + // producing jsid(1) -- which actually represents "0", not "-2147483648". + // Thus 'in' will report a "-2147483648" property when none exists, because + // it thinks the request was really whether the object had property "0". + var obj2 = { 0: 17 }; + var b = []; + var index = -(1 << 28); + for (var i = 0; i < 10; i++) + { + b.push(index in obj2); + index = index - (1 << 28); + } + + return a.join(",") + b.join(","); +} + +assertEq(testInt32ToId(), + "false,false,false,false,false,false,false,false,false,true" + + "false,false,false,false,false,false,false,false,false,false"); diff --git a/js/src/jit-test/tests/basic/testIntFloor.js b/js/src/jit-test/tests/basic/testIntFloor.js new file mode 100644 index 000000000..80b4ea741 --- /dev/null +++ b/js/src/jit-test/tests/basic/testIntFloor.js @@ -0,0 +1,8 @@ +function testIntFloor() { + var a; + for (var x = 0; x < 3; ++x) { + a = Math.floor('') + } + return a; +} +assertEq(testIntFloor(), 0) diff --git a/js/src/jit-test/tests/basic/testIntOverflow.js b/js/src/jit-test/tests/basic/testIntOverflow.js new file mode 100644 index 000000000..cfe68983c --- /dev/null +++ b/js/src/jit-test/tests/basic/testIntOverflow.js @@ -0,0 +1,9 @@ +function testIntOverflow() { + // int32_max - 7 + var ival = 2147483647 - 7; + for (var i = 0; i < 30; i++) { + ival += 30; + } + return (ival < 2147483647); +} +assertEq(testIntOverflow(), false); diff --git a/js/src/jit-test/tests/basic/testIntUnderflow.js b/js/src/jit-test/tests/basic/testIntUnderflow.js new file mode 100644 index 000000000..65db00a0a --- /dev/null +++ b/js/src/jit-test/tests/basic/testIntUnderflow.js @@ -0,0 +1,9 @@ +function testIntUnderflow() { + // int32_min + 8 + var ival = -2147483648 + 8; + for (var i = 0; i < 30; i++) { + ival -= 2; + } + return (ival > -2147483648); +} +assertEq(testIntUnderflow(), false); diff --git a/js/src/jit-test/tests/basic/testInterpreterReentry.js b/js/src/jit-test/tests/basic/testInterpreterReentry.js new file mode 100644 index 000000000..d820b2333 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInterpreterReentry.js @@ -0,0 +1,6 @@ +function testInterpreterReentry() { + this.__defineSetter__('x', function(){}) + for (var j = 0; j < 5; ++j) { x = 3; } + return 1; +} +assertEq(testInterpreterReentry(), 1); diff --git a/js/src/jit-test/tests/basic/testInterpreterReentry2.js b/js/src/jit-test/tests/basic/testInterpreterReentry2.js new file mode 100644 index 000000000..030f088e1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInterpreterReentry2.js @@ -0,0 +1,10 @@ +function testInterpreterReentry2() { + var a = false; + var b = {}; + var c = false; + var d = {}; + this.__defineGetter__('e', function(){}); + for (let f in this) print(f); + return 1; +} +assertEq(testInterpreterReentry2(), 1); diff --git a/js/src/jit-test/tests/basic/testInterpreterReentry3.js b/js/src/jit-test/tests/basic/testInterpreterReentry3.js new file mode 100644 index 000000000..91de965a0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInterpreterReentry3.js @@ -0,0 +1,6 @@ +function testInterpreterReentry3() { + for (let i=0;i<5;++i) this["y" + i] = function(){}; + this.__defineGetter__('e', function (x2) { yield; }); + return 1; +} +assertEq(testInterpreterReentry3(), 1); diff --git a/js/src/jit-test/tests/basic/testInterpreterReentry4.js b/js/src/jit-test/tests/basic/testInterpreterReentry4.js new file mode 100644 index 000000000..b09e5cb9a --- /dev/null +++ b/js/src/jit-test/tests/basic/testInterpreterReentry4.js @@ -0,0 +1,6 @@ +function testInterpreterReentry4() { + var obj = {a:1, b:1, c:1, d:1, get e() { return 1000; } }; + for (var p in obj) + obj[p]; +} +testInterpreterReentry4(); diff --git a/js/src/jit-test/tests/basic/testInterpreterReentry5.js b/js/src/jit-test/tests/basic/testInterpreterReentry5.js new file mode 100644 index 000000000..1c9b698eb --- /dev/null +++ b/js/src/jit-test/tests/basic/testInterpreterReentry5.js @@ -0,0 +1,9 @@ +function testInterpreterReentry5() { + var arr = [0, 1, 2, 3, 4]; + arr.__defineGetter__("4", function() { return 1000; }); + for (var i = 0; i < 5; i++) + arr[i]; + for (var p in arr) + arr[p]; +} +testInterpreterReentry5(); diff --git a/js/src/jit-test/tests/basic/testInterpreterReentry6.js b/js/src/jit-test/tests/basic/testInterpreterReentry6.js new file mode 100644 index 000000000..c5a6b2863 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInterpreterReentry6.js @@ -0,0 +1,7 @@ +function testInterpreterReentry6() { + var obj = {a:1, b:1, c:1, d:1, set e(x) { this._e = x; }}; + for (var p in obj) + obj[p] = "grue"; + return obj._e; +} +assertEq(testInterpreterReentry6(), "grue"); diff --git a/js/src/jit-test/tests/basic/testInterpreterReentry7.js b/js/src/jit-test/tests/basic/testInterpreterReentry7.js new file mode 100644 index 000000000..36b34c6f0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInterpreterReentry7.js @@ -0,0 +1,11 @@ +function testInterpreterReentry7() { + var arr = [0, 1, 2, 3, 4]; + arr.__defineSetter__("4", function(x) { this._4 = x; }); + for (var i = 0; i < 5; i++) + arr[i] = "grue"; + var tmp = arr._4; + for (var p in arr) + arr[p] = "bleen"; + return tmp + " " + arr._4; +} +assertEq(testInterpreterReentry7(), "grue bleen"); diff --git a/js/src/jit-test/tests/basic/testInvalidCharCodeAt.js b/js/src/jit-test/tests/basic/testInvalidCharCodeAt.js new file mode 100644 index 000000000..748220fcd --- /dev/null +++ b/js/src/jit-test/tests/basic/testInvalidCharCodeAt.js @@ -0,0 +1,12 @@ +function doTestInvalidCharCodeAt(input) +{ + var q = ""; + for (var i = 0; i < 10; i++) + q += input.charCodeAt(i); + return q; +} +function testInvalidCharCodeAt() +{ + return doTestInvalidCharCodeAt(""); +} +assertEq(testInvalidCharCodeAt(), "NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN"); diff --git a/js/src/jit-test/tests/basic/testInvertNullAfterNegateNull.js b/js/src/jit-test/tests/basic/testInvertNullAfterNegateNull.js new file mode 100644 index 000000000..7e6a12b05 --- /dev/null +++ b/js/src/jit-test/tests/basic/testInvertNullAfterNegateNull.js @@ -0,0 +1,7 @@ +function testInvertNullAfterNegateNull() +{ + for (var i = 0; i < 5; i++) !null; + for (var i = 0; i < 5; i++) -null; + return "no assertion"; +} +assertEq(testInvertNullAfterNegateNull(), "no assertion"); diff --git a/js/src/jit-test/tests/basic/testIteratorReification.js b/js/src/jit-test/tests/basic/testIteratorReification.js new file mode 100644 index 000000000..8f89672bb --- /dev/null +++ b/js/src/jit-test/tests/basic/testIteratorReification.js @@ -0,0 +1 @@ +for (b in evalcx('')) {} diff --git a/js/src/jit-test/tests/basic/testLambdaCtor.js b/js/src/jit-test/tests/basic/testLambdaCtor.js new file mode 100644 index 000000000..ea91cd9a4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLambdaCtor.js @@ -0,0 +1,13 @@ +function testLambdaCtor() { + var a = []; + for (var x = 0; x < 9; ++x) { + var f = function(){}; + a[a.length] = new f; + } + + assertEq([8].__proto__ !== a[7].__proto__, true); + + // Assert that the last f was properly constructed. + return a[8].__proto__ === f.prototype; +} +assertEq(testLambdaCtor(), true); diff --git a/js/src/jit-test/tests/basic/testLambdaInitedVar.js b/js/src/jit-test/tests/basic/testLambdaInitedVar.js new file mode 100644 index 000000000..e37b4f9c7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLambdaInitedVar.js @@ -0,0 +1,8 @@ +function testLambdaInitedVar() { + var jQuery = function (a, b) { + return jQuery && jQuery.length; + } + return jQuery(); +} + +assertEq(testLambdaInitedVar(), 2); diff --git a/js/src/jit-test/tests/basic/testLengthInString.js b/js/src/jit-test/tests/basic/testLengthInString.js new file mode 100644 index 000000000..5950b509f --- /dev/null +++ b/js/src/jit-test/tests/basic/testLengthInString.js @@ -0,0 +1,12 @@ +function testLengthInString() +{ + var s = new String(); + var res = "length" in s; + for (var i = 0; i < 5; i++) + res = res && ("length" in s); + res = res && s.hasOwnProperty("length"); + for (var i = 0; i < 5; i++) + res = res && s.hasOwnProperty("length"); + return res; +} +assertEq(testLengthInString(), true); diff --git a/js/src/jit-test/tests/basic/testLengthOnNonNativeProto.js b/js/src/jit-test/tests/basic/testLengthOnNonNativeProto.js new file mode 100644 index 000000000..80d388f8d --- /dev/null +++ b/js/src/jit-test/tests/basic/testLengthOnNonNativeProto.js @@ -0,0 +1,20 @@ +function testLengthOnNonNativeProto() +{ + var o = {}; + o.__proto__ = [3]; + for (var j = 0; j < 5; j++) + o[0]; + + var o2 = {}; + o2.__proto__ = []; + for (var j = 0; j < 5; j++) + o2.length; + + function foo() { } + foo.__proto__ = []; + for (var j = 0; j < 5; j++) + foo.length; + + return "no assertion"; +} +assertEq(testLengthOnNonNativeProto(), "no assertion"); diff --git a/js/src/jit-test/tests/basic/testLet.js b/js/src/jit-test/tests/basic/testLet.js new file mode 100644 index 000000000..263c3eb8a --- /dev/null +++ b/js/src/jit-test/tests/basic/testLet.js @@ -0,0 +1,220 @@ +var otherGlobal = newGlobal(); + +function test(str, arg, result) +{ + arg = arg || 'ponies'; + if (arguments.length < 3) + result = 'ponies'; + + var fun = new Function('x', str); + + var got = fun.toSource(); + var expect = '(function anonymous(x) {\n' + str + '\n})'; + if (got !== expect) { + print("GOT: " + got); + print("EXPECT: " + expect); + assertEq(got, expect); + } + + // test reflection logic + Reflect.parse(got); + + // test xdr by cloning a cross-compartment function + var code = "(function (x) { " + str + " })"; + var c = clone(otherGlobal.evaluate(code)); + assertEq(c.toSource(), eval(code).toSource()); + + var got = fun(arg); + var expect = result; + if (got !== expect) { + print("GOT:" + got); + print("EXPECT: " + expect); + assertEq(got, expect); + } +} + +function isParseError(str) +{ + var caught = false; + try { + new Function(str); + } catch(e) { + assertEq(e instanceof TypeError || e instanceof SyntaxError, true); + caught = true; + } + assertEq(caught, true); +} + +function isRuntimeParseError(str, arg) +{ + var caught = false; + try { + (new Function("x", str))(arg); + } catch(e) { + assertEq(e instanceof TypeError || e instanceof SyntaxError, true); + caught = true; + } + assertEq(caught, true); +} + +function isReferenceError(str) +{ + var caught = false; + try { + (new Function(str))(); + } catch(e) { + assertEq(e instanceof ReferenceError, true); + caught = true; + } + assertEq(caught, true); +} + +// var declarations +test('var y;return x;'); +test('var y = x;return x;'); +test('var [] = x;return x;'); +test('var [, ] = x;return x;'); +test('var [, , , , ] = x;return x;'); +test('var x = x;return x;'); +test('var y = y;return "" + y;', 'unicorns', 'undefined'); +test('var x = eval("x");return x;'); +test('var X = x + 1, y = x;return y;'); +test('var X = x + 1, [] = X, [[, , ]] = X, y = x;return y;'); +test('var [{a: X}] = x, [, {b: y}] = x;var X = X + 1, y = y + 2;return X + y;', [{a:"p"},{b:"p"}], "p1p2"); +test('var [x] = [x];return x;'); +test('var [[a, [b, c]]] = [[x, []]];return a;'); +test('var [y] = [x];return y;'); +test('var [a] = (1, [x]);return a;'); +test('var [a] = (1, x, 1, x);return a;', ['ponies']); +test('var [x, y] = [x, x + 1];return x + y;', 1, 3); +test('var [x, y, z] = [x, x + 1, x + 2];return x + y + z;', 1, 6); +test('var [[x]] = [[x]];return x;'); +test('var [x, y] = [x, x + 1];return x;'); +test('var [x, [y, z]] = [x, x + 1];return x;'); +test('var [{x: [x]}, {y1: y, z1: z}] = [x, x + 1];return x;',{x:['ponies']}); +test('if (x) {var y = x;return x;}'); +test('if (x) {y = x;var y = y;return y;}'); +test('if (x) {var z = y;var [y] = x;z += y;}return z;', ['-'], 'undefined-'); + +// let declaration in context +test('if (x) {let y;return x;}'); +test('if (x) {let x;return "" + x;}', 'unicorns', 'undefined'); +test('if (x) {let y = x;return x;}'); +test('if (x) {let y = x;return x;}'); +test('if (x) {let [] = x;return x;}'); +test('if (x) {let [, ] = x;return x;}'); +test('if (x) {let [, , , , ] = x;return x;}'); +test('if (x) {let X = x + 1, y = x;return y;}'); +test('if (x) {let X = x + 1, [] = X, [[, , ]] = X, y = x;return y;}'); +test('if (x) {let [{a: X}] = x, [, {b: Y}] = x;var XX = X + 1, YY = Y + 2;return XX + YY;}', [{a:"p"},{b:"p"}], "p1p2"); +test('if (x) {let [[a, [b, c]]] = [[x, []]];return a;}'); +test('if (x) {let [X] = [x];return X;}'); +test('if (x) {let [y] = [x];return y;}'); +test('if (x) {let [a] = (1, [x]);return a;}'); +test('if (x) {let [a] = (1, x, 1, x);return a;}', ['ponies']); +test('if (x) {let [X, y] = [x, x + 1];return X + y;}', 1, 3); +test('if (x) {let [X, y, z] = [x, x + 1, x + 2];return X + y + z;}', 1, 6); +test('if (x) {let [[X]] = [[x]];return X;}'); +test('if (x) {let [X, y] = [x, x + 1];return X;}'); +test('if (x) {let [X, [y, z]] = [x, x + 1];return X;}'); +test('if (x) {let [{x: [X]}, {y1: y, z1: z}] = [x, x + 1];return X;}',{x:['ponies']}); +test('if (x) {let y = x;try {let x = 1;throw 2;} catch (e) {return y;}}'); +test('try {let x = 1;throw 2;} catch (e) {return x;}'); +test('x.foo;{let y = x;return y;}'); +test('x.foo;if (x) {x.bar;let y = x;return y;}'); +test('if (x) {let y = x;return function () {return eval("y");}();}'); +test('return eval("let y = x; y");'); +isRuntimeParseError('if (x) {let y = x;eval("var y = 2");return y;}', 'ponies'); +test('"use strict";if (x) {let y = x;eval("var y = 2");return y;}'); +test('"use strict";if (x) {let y = x;eval("let y = 2");return y;}'); +test('"use strict";if (x) {let y = 1;return eval("let y = x;y;");}'); +test('this.y = x;if (x) {let y = 1;return this.eval("y");}'); + +// for(;;) +test('for (;;) {return x;}'); +test('for (let y = 1;;) {return x;}'); +test('for (let y = 1;; ++y) {return x;}'); +test('for (let y = 1; ++y;) {return x;}'); +test('for (let [[a, [b, c]]] = [[x, []]];;) {return a;}'); +test('var sum = 0;for (let y = x; y < 4; ++y) {sum += y;}return sum;', 1, 6); +test('var sum = 0;for (let x = 1; eval("x") < 4; ++x) {sum += eval("x");}return sum;', 1, 6); +test('for (var y = 1;;) {return x;}'); +test('for (var y = 1;; ++y) {return x;}'); +test('for (var y = 1; ++y;) {return x;}'); +test('for (var X = 1, [y, z] = x, a = x; z < 4; ++z) {return X + y;}', [2,3], 3); +test('var sum = 0;for (var y = x; y < 4; ++y) {sum += y;}return sum;', 1, 6); +test('var sum = 0;for (var X = x, y = 10; X < 4; ++X) {sum += X;}return sum;', 1, 6); +test('var sum = 0;for (var X = x; X < 4; ++X) {sum += X;}return x;', 1, 1); +test('var sum = 0;for (var X = eval("x"); X < 4; ++X) {sum += X;}return sum;', 1, 6); +test('var sum = 0;for (var X = x; eval("X") < 4; ++X) {sum += eval("X");}return sum;', 1, 6); +test('var sum = 0;for (var X = eval("x"); eval("X") < 4; ++X) {sum += eval("X");}return sum;', 1, 6); +test('for (let y = x;;) {let x;return y;}'); +test('for (let y = x;;) {let y;return x;}'); +test('for (let y;;) {let y;return x;}'); +test('for (let a = x;;) {let c = x, d = x;return c;}'); +test('for (let [a, b] = x;;) {let c = x, d = x;return c;}'); +test('for (let [a] = (1, [x]);;) {return a;}'); +test('for (let [a] = (1, x, 1, x);;) {return a;}', ['ponies']); +isParseError('for (let x = 1, x = 2;;) {}'); +isParseError('for (let [x, y] = a, {a:x} = b;;) {}'); +isParseError('for (let [x, y, x] = a;;) {}'); +isParseError('for (let [x, [y, [x]]] = a;;) {}'); + +// for(in) +test('for (let i in x) {return x;}'); +test('for (let i in x) {let y;return x;}'); +test('for each (let [a, b] in x) {let y;return x;}'); +test('for (let i in x) {let i = x;return i;}'); +test('var s = "";for (let a in x) {for (let b in x) {s += a + b;}}return s;', [1,2], '00011011'); +test('var res = "";for (let i in x) {res += x[i];}return res;'); +test('var res = "";for (var i in x) {res += x[i];}return res;'); +isParseError('for ((let (x = {y: true}) x).y in eval("x")) {return eval("x");}'); +test('for (let i in x) {break;}return x;'); +test('for (let i in x) {break;}return eval("x");'); +test('a:for (let i in x) {for (let j in x) {break a;}}return x;'); +test('a:for (let i in x) {for (let j in x) {break a;}}return eval("x");'); +test('var j;for (let i in x) {j = i;break;}return j;', {ponies:true}); +isParseError('for (let [x, x] in o) {}'); +isParseError('for (let [x, y, x] in o) {}'); +isParseError('for (let [x, [y, [x]]] in o) {}'); + +// for(let ... in ...) scoping bugs (bug 1069480) +isReferenceError('for each (let [x, y] in x) {return x + y;}', [['ponies', '']]); +isReferenceError('for each (let [{0: x, 1: y}, z] in x) {return x + y + z;}', [[['po','nies'], '']], undefined); +isReferenceError('for (let x in eval("x")) {return x;}', {ponies:true}, undefined); +isReferenceError('for (let x in x) {return eval("x");}', {ponies:true}, undefined); +isReferenceError('for (let x in eval("x")) {return eval("x");}', {ponies:true}, undefined); +isReferenceError('for (let x in x) {break;}return x;'); +isReferenceError('for (let x in x) {break;}return eval("x");'); +isReferenceError('for (let x in eval("throw x")) {}', undefined, undefined); +isReferenceError('for each (let x in x) {eval("throw x");}', ['ponies'], undefined); +isReferenceError('for each (let {x: y, y: x} in [{x: x, y: x}]) {return y;}', undefined, undefined); + +// don't forget about switch craziness +test('var y = 3;switch (function () {return eval("y");}()) {case 3:let y;return x;default:;}'); +test('switch (x) {case 3:let y;return 3;case 4:let z;return 4;default:return x;}'); +isParseError('switch (x) {case 3:let y;return 3;case 4:let y;return 4;default:;}'); + +// TDZ checks +isReferenceError('x + 1; let x = 42;'); +isReferenceError('x = 42; let x;'); +isReferenceError('inner(); function inner() { x++; } let x;'); +isReferenceError('inner(); let x; function inner() { x++; }'); +isReferenceError('inner(); let x; function inner() { function innerer() { x++; } innerer(); }'); +isReferenceError('let x; var inner = function () { y++; }; inner(); let y;'); +isReferenceError('let x = x;'); +isReferenceError('let [x] = [x];'); +isReferenceError('let {x} = {x:x};'); +isReferenceError('switch (x) {case 3:let x;break;default:if (x === undefined) {return "ponies";}}'); +isReferenceError('let x = function() {} ? x() : function() {}'); +isReferenceError('(function() { let x = (function() { return x }()); }())'); +isReferenceError('var sum = 0;for (let x = x, y = 10; x < 4; ++x) {sum += x;}return sum;'); +isReferenceError('var sum = 0;for (let x = x; x < 4; ++x) {sum += x;}return x;'); +isReferenceError('var sum = 0;for (let x = eval("x"); x < 4; ++x) {sum += x;}return sum;'); +isReferenceError('var sum = 0;for (let x = x; eval("x") < 4; ++x) {sum += eval("x");}return sum;'); +isReferenceError('var sum = 0;for (let x = eval("x"); eval("x") < 4; ++x) {sum += eval("x");}return sum;'); +isReferenceError('for (let x = eval("throw x");;) {}'); +isReferenceError('for (let x = x + "s"; eval("throw x");) {}'); + +// redecl with function statements +isParseError('let a; function a() {}'); diff --git a/js/src/jit-test/tests/basic/testLetOverridingArgs.js b/js/src/jit-test/tests/basic/testLetOverridingArgs.js new file mode 100644 index 000000000..fbebe7a2f --- /dev/null +++ b/js/src/jit-test/tests/basic/testLetOverridingArgs.js @@ -0,0 +1,5 @@ +function f1() { { let arguments = 42; return arguments } } +assertEq(f1(), 42); + +function f2() { { let arguments; return arguments } } +assertEq(f2(), undefined); diff --git a/js/src/jit-test/tests/basic/testLetWithUnstableGlobal.js b/js/src/jit-test/tests/basic/testLetWithUnstableGlobal.js new file mode 100644 index 000000000..fb7984ce2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLetWithUnstableGlobal.js @@ -0,0 +1,11 @@ +var q = []; +for each (b in [0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF]) { + for each (let e in [{}, {}, {}, "", {}]) { + b = (b | 0x40000000) + 1; + q.push(b); + } +} +function testLetWithUnstableGlobal() { + return q.join(","); +} +assertEq(testLetWithUnstableGlobal(), "2147483648,-1073741823,-1073741822,-1073741821,-1073741820,2147483648,-1073741823,-1073741822,-1073741821,-1073741820,2147483648,-1073741823,-1073741822,-1073741821,-1073741820"); diff --git a/js/src/jit-test/tests/basic/testLirBufOOM.js b/js/src/jit-test/tests/basic/testLirBufOOM.js new file mode 100644 index 000000000..f9d4e1dc9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLirBufOOM.js @@ -0,0 +1,34 @@ +function testLirBufOOM() +{ + var a = [ + "12345678901234", + "123456789012", + "1234567890123456789012345678", + "12345678901234567890123456789012345678901234567890123456", + "f", + "$", + "", + "f()", + "(\\*)", + "b()", + "()", + "(#)", + "ABCDEFGHIJK", + "ABCDEFGHIJKLM", + "ABCDEFGHIJKLMNOPQ", + "ABCDEFGH", + "(.)", + "(|)", + "()$", + "/()", + "(.)$" + ]; + + for (var j = 0; j < 200; ++j) { + var js = "" + j; + for (var i = 0; i < a.length; i++) + "".match(a[i] + js) + } + return "ok"; +} +assertEq(testLirBufOOM(), "ok"); diff --git a/js/src/jit-test/tests/basic/testLocaleCompare.js b/js/src/jit-test/tests/basic/testLocaleCompare.js new file mode 100644 index 000000000..e9428b2c6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLocaleCompare.js @@ -0,0 +1,8 @@ +assertEq("undefined".localeCompare(), 0); +assertEq("a".localeCompare(), "a".localeCompare("undefined")); +assertEq("a".localeCompare("b"), -1); +assertEq("a".localeCompare("b", "en"), -1); +assertEq("b".localeCompare("a"), 1); +assertEq("b".localeCompare("a", "en"), 1); +assertEq("a".localeCompare("a"), 0); +assertEq("a".localeCompare("a", "en"), 0); diff --git a/js/src/jit-test/tests/basic/testLogicalNotNaN.js b/js/src/jit-test/tests/basic/testLogicalNotNaN.js new file mode 100644 index 000000000..6bb0251e2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLogicalNotNaN.js @@ -0,0 +1,8 @@ +function testLogicalNotNaN() { + var i = 0; + var a = new Array(5); + while (i < a.length) + a[i++] = !NaN; + return a.join(); +} +assertEq(testLogicalNotNaN(), "true,true,true,true,true"); diff --git a/js/src/jit-test/tests/basic/testLongNumToString.js b/js/src/jit-test/tests/basic/testLongNumToString.js new file mode 100644 index 000000000..def2b47a9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLongNumToString.js @@ -0,0 +1,7 @@ +function testLongNumToString() { + var s; + for (var i = 0; i < 5; i++) + s = (0x08000000).toString(2); + return s; +} +assertEq(testLongNumToString(), '1000000000000000000000000000'); diff --git a/js/src/jit-test/tests/basic/testLoopWithUndefined1.js b/js/src/jit-test/tests/basic/testLoopWithUndefined1.js new file mode 100644 index 000000000..63c4b97a8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLoopWithUndefined1.js @@ -0,0 +1,12 @@ +function loopWithUndefined1(t, val) { + var a = new Array(6); + for (var i = 0; i < 6; i++) + a[i] = (t > val); + return a; +} +loopWithUndefined1(5.0, 2); //compile version with val=int + +function testLoopWithUndefined1() { + return loopWithUndefined1(5.0).join(","); //val=undefined +}; +assertEq(testLoopWithUndefined1(), "false,false,false,false,false,false"); diff --git a/js/src/jit-test/tests/basic/testLoopWithUndefined2.js b/js/src/jit-test/tests/basic/testLoopWithUndefined2.js new file mode 100644 index 000000000..a6ba9dbe5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testLoopWithUndefined2.js @@ -0,0 +1,20 @@ +function loopWithUndefined2(t, dostuff, val) { + var a = new Array(6); + for (var i = 0; i < 6; i++) { + if (dostuff) { + val = 1; + a[i] = (t > val); + } else { + a[i] = (val == undefined); + } + } + return a; +} +function testLoopWithUndefined2() { + var a = loopWithUndefined2(5.0, true, 2); + var b = loopWithUndefined2(5.0, true); + var c = loopWithUndefined2(5.0, false, 8); + var d = loopWithUndefined2(5.0, false); + return [a[0], b[0], c[0], d[0]].join(","); +} +assertEq(testLoopWithUndefined2(), "true,true,false,true"); diff --git a/js/src/jit-test/tests/basic/testLoopingAccumulator.js b/js/src/jit-test/tests/basic/testLoopingAccumulator.js new file mode 100644 index 000000000..bacb29bea --- /dev/null +++ b/js/src/jit-test/tests/basic/testLoopingAccumulator.js @@ -0,0 +1,21 @@ +function addAccumulations(f) { + var a = f(); + var b = f(); + return a() + b(); +} + +function loopingAccumulator() { + var x = 0; + return function () { + for (var i = 0; i < 10; ++i) { + ++x; + } + return x; + } +} + +function testLoopingAccumulator() { + var x = addAccumulations(loopingAccumulator); + return x; +} +assertEq(testLoopingAccumulator(), 20); diff --git a/js/src/jit-test/tests/basic/testManyVars.js b/js/src/jit-test/tests/basic/testManyVars.js new file mode 100644 index 000000000..a89d4539c --- /dev/null +++ b/js/src/jit-test/tests/basic/testManyVars.js @@ -0,0 +1,13 @@ +const MANY_VARS = Math.pow(2,17); + +var code = "function f1() {\n"; +code += " var x0 = 0"; +for (var i = 1; i < MANY_VARS; i++) + code += ", x" + i + " = " + i; +code += ";\n"; +for (var i = 0; i < MANY_VARS; i += 100) + code += " assertEq(x" + i + ", " + i + ");\n"; +code += " return x80000;\n"; +code += "}\n"; +eval(code); +assertEq(f1(), 80000); diff --git a/js/src/jit-test/tests/basic/testMatchAsCondition.js b/js/src/jit-test/tests/basic/testMatchAsCondition.js new file mode 100644 index 000000000..8cb429f0c --- /dev/null +++ b/js/src/jit-test/tests/basic/testMatchAsCondition.js @@ -0,0 +1,8 @@ +function testMatchAsCondition() { + var a = ['0', '0', '0', '0']; + var r = /0/; + "x".q; + for (var z = 0; z < 4; z++) + a[z].match(r) ? 1 : 2; +} +testMatchAsCondition(); diff --git a/js/src/jit-test/tests/basic/testMatchStringObject.js b/js/src/jit-test/tests/basic/testMatchStringObject.js new file mode 100644 index 000000000..cde2da1ae --- /dev/null +++ b/js/src/jit-test/tests/basic/testMatchStringObject.js @@ -0,0 +1,8 @@ +function testMatchStringObject() { + var a = new String("foo"); + var b; + for (i = 0; i < 300; i++) + b = a.match(/bar/); + return b; +} +assertEq(testMatchStringObject(), null); diff --git a/js/src/jit-test/tests/basic/testMathClz32.js b/js/src/jit-test/tests/basic/testMathClz32.js new file mode 100644 index 000000000..0cc4aae89 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMathClz32.js @@ -0,0 +1,28 @@ +function f() { + var x = 0; + for (var i = 1; i < 1e6; i++) { + if (i > 0) + x += Math.clz32(i); + } + return x; +} + +function g() { + var x = 0; + for (var i = 1; i < 1e6; i++) { + x += Math.clz32(i); + } + return x; +} + +function h() { + var x = 0; + for (var i = 0; i < 1e6; i++) { + x += Math.clz32(i); + } + return x; +} + +assertEq(f(), 13048543); +assertEq(g(), 13048543); +assertEq(h(), 13048575);
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/testMathMinMax.js b/js/src/jit-test/tests/basic/testMathMinMax.js new file mode 100644 index 000000000..4c057fa6d --- /dev/null +++ b/js/src/jit-test/tests/basic/testMathMinMax.js @@ -0,0 +1,74 @@ +for (var i = 2; i < 10; i++) { + assertEq(Math.min(i, 1), 1); + assertEq(Math.min(i, -1), -1); + assertEq(Math.min(1, i), 1); + assertEq(Math.min(-1, i), -1); + assertEq(Math.min(5, 2), 2); + assertEq(Math.min(2, 5), 2); + assertEq(Math.min(5, -2), -2); + assertEq(Math.min(-2, 5), -2); +} + +for (i = 2; i < 10; i++) { + assertEq(Math.max(i, 1), i); + assertEq(Math.max(i, -1), i); + assertEq(Math.max(1, i), i); + assertEq(Math.max(-1, i), i); + assertEq(Math.max(5, -2), 5); + assertEq(Math.max(-2, 5), 5); + assertEq(Math.max(5, 2), 5); + assertEq(Math.max(2, 5), 5); +} + +for (i = 2.1; i < 13; i += 3.17584) { + assertEq(Math.max(i, 1), i); + assertEq(Math.max(i, 1.5), i); + assertEq(Math.max(1, i), i); + assertEq(Math.max(1.5, i), i); + + assertEq(Math.max(NaN, NaN), NaN); + assertEq(Math.max(NaN, Infinity), NaN); + assertEq(Math.max(Infinity, NaN), NaN); + + assertEq(Math.max(NaN, i), NaN); + assertEq(Math.max(i, NaN), NaN); + + assertEq(Math.max(i, Infinity), Infinity); + assertEq(Math.max(Infinity, i), Infinity); + + assertEq(Math.max(i, -Infinity), i); + assertEq(Math.max(-Infinity, i), i); +} + +for (i = 2.1; i < 13; i += 3.17584) { + assertEq(Math.min(i, 1), 1); + assertEq(Math.min(i, 1.5), 1.5); + assertEq(Math.min(1, i), 1); + assertEq(Math.min(1.5, i), 1.5); + + assertEq(Math.min(NaN, NaN), NaN); + assertEq(Math.min(NaN, Infinity), NaN); + assertEq(Math.min(Infinity, NaN), NaN); + + assertEq(Math.min(NaN, i), NaN); + assertEq(Math.min(i, NaN), NaN); + + assertEq(Math.min(i, Infinity), i); + assertEq(Math.min(Infinity, i), i); + + assertEq(Math.min(i, -Infinity), -Infinity); + assertEq(Math.min(-Infinity, i), -Infinity); +} + +function isNegZero(n) { + return n === 0 && 1/n === -Infinity; +} + +for (i = 0; i < 5; i++) { + assertEq(isNegZero(Math.min(0, -0)), true); + assertEq(isNegZero(Math.min(-0, 0)), true); + assertEq(isNegZero(Math.min(-0, -0)), true); + assertEq(isNegZero(Math.max(0, -0)), false); + assertEq(isNegZero(Math.max(-0, 0)), false); + assertEq(isNegZero(Math.max(-0, -0)), true); +} diff --git a/js/src/jit-test/tests/basic/testMethodInc.js b/js/src/jit-test/tests/basic/testMethodInc.js new file mode 100644 index 000000000..f283f8406 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMethodInc.js @@ -0,0 +1,5 @@ +for (var i = 0; i < 9; i++) { + var x = {f: function() {}}; + x.f++; + assertEq(""+x.f, "NaN"); +} diff --git a/js/src/jit-test/tests/basic/testMethodInit.js b/js/src/jit-test/tests/basic/testMethodInit.js new file mode 100644 index 000000000..64cfa4c37 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMethodInit.js @@ -0,0 +1,10 @@ +function testMethodInit() { // bug 503198 + function o() { return 'o'; } + function k() { return 'k'; } + + var x; + for (var i = 0; i < 10; i++) + x = {o: o, k: k}; + return x.o() + x.k(); +} +assertEq(testMethodInit(), "ok"); diff --git a/js/src/jit-test/tests/basic/testMethodInitSafety.js b/js/src/jit-test/tests/basic/testMethodInitSafety.js new file mode 100644 index 000000000..34177ab8f --- /dev/null +++ b/js/src/jit-test/tests/basic/testMethodInitSafety.js @@ -0,0 +1,14 @@ +function testMethodInitSafety() { + function f() { return 'fail'; } + function g() { return 'ok'; } + + var s; + var arr = [f, f, f, f, g]; + //assertEq(arr.length > 9, true); + for (var i = 0; i < arr.length; i++) { + var x = {m: arr[i]}; + s = x.m(); + } + return s; +} +assertEq(testMethodInitSafety(), "ok"); diff --git a/js/src/jit-test/tests/basic/testMethodSet.js b/js/src/jit-test/tests/basic/testMethodSet.js new file mode 100644 index 000000000..d7fcd7fc0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMethodSet.js @@ -0,0 +1,13 @@ +function testMethodSet() { // bug 503198 + function o() { return 'o'; } + function k() { return 'k'; } + + var x; + for (var i = 0; i < 10; i++) { + x = {}; + x.o = o; + x.k = k; + } + return x.o() + x.k(); +} +assertEq(testMethodSet(), "ok"); diff --git a/js/src/jit-test/tests/basic/testMethodWriteBarrier.js b/js/src/jit-test/tests/basic/testMethodWriteBarrier.js new file mode 100644 index 000000000..86f2b1722 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMethodWriteBarrier.js @@ -0,0 +1,4 @@ +var x = {p: 0.1, m: function(){}}; +x.m(); // the interpreter brands x +for (var i = 0; i < 9; i++) + x.p = 0.1; diff --git a/js/src/jit-test/tests/basic/testMethodWriteBarrier2.js b/js/src/jit-test/tests/basic/testMethodWriteBarrier2.js new file mode 100644 index 000000000..19b387198 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMethodWriteBarrier2.js @@ -0,0 +1,17 @@ +function C() { + this.m = function () {}; // JSOP_SETMETHOD +} + +var a = [new C, new C, new C, new C, new C, new C, new C, new C, new C]; +var b = [new C, new C, new C, new C, new C, new C, a[8], new C, new C]; + +var thrown = 'none'; +try { + for (var i = 0; i < 9; i++) { + a[i].m(); + b[i].m = 0.7; // MethodWriteBarrier required here + } +} catch (exc) { + thrown = exc.name; +} +assertEq(thrown, 'TypeError'); diff --git a/js/src/jit-test/tests/basic/testMethodWriteBarrier3.js b/js/src/jit-test/tests/basic/testMethodWriteBarrier3.js new file mode 100644 index 000000000..9ae20fed9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMethodWriteBarrier3.js @@ -0,0 +1,27 @@ +function g() {} + +function h() { + for (var i = 0; i < 9; i++) + x.f = i; +} + +function j() { + x.f(); +} + +var x = {f: 0.7, g: g}; +x.g(); // interpreter brands x +h(); +print(shapeOf(x)); +x.f = function (){}; // does not change x's shape +j(); +print(shapeOf(x)); +h(); // should change x's shape + +var thrown = 'none'; +try { + j(); // should throw since x.f === 8 +} catch (exc) { + thrown = exc.name; +} +assertEq(thrown, 'TypeError');
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/testMethodWriteBarrier4.js b/js/src/jit-test/tests/basic/testMethodWriteBarrier4.js new file mode 100644 index 000000000..f120c9450 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMethodWriteBarrier4.js @@ -0,0 +1,12 @@ +var z = 0; +function f() { + this.b = function() {}; + this.b = undefined; + if (z++ > 8) + this.b(); +} + +try { + for (var i = 0; i < 10; i++) + new f(); +} catch (exc) {} diff --git a/js/src/jit-test/tests/basic/testMissingMethod.js b/js/src/jit-test/tests/basic/testMissingMethod.js new file mode 100644 index 000000000..50ebb4bea --- /dev/null +++ b/js/src/jit-test/tests/basic/testMissingMethod.js @@ -0,0 +1,9 @@ +var o = {y: function () {}}; +var a = [o, o, o, o, o, o, o, o, o]; +a[7] = {}; +try { + for (var i = 0; i < 9; i++) + a[i].y(); +} catch (exc) { + assertEq(exc.name, "TypeError"); // should happen when i == 7 +} diff --git a/js/src/jit-test/tests/basic/testMissingMethod2.js b/js/src/jit-test/tests/basic/testMissingMethod2.js new file mode 100644 index 000000000..fabfa08a6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMissingMethod2.js @@ -0,0 +1,10 @@ +var o = {y: function() {}}; +var a = [o, o, o, o, o, o, o, o, o]; +Number.prototype.y = 0; +a[7] = 0; +try { + for (var i = 0; i < 9; i++) + a[i].y(); +} catch (exc) { + assertEq(exc.name, "TypeError"); // should happen when i == 7 +} diff --git a/js/src/jit-test/tests/basic/testMissingProperties.js b/js/src/jit-test/tests/basic/testMissingProperties.js new file mode 100644 index 000000000..71512c6f5 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMissingProperties.js @@ -0,0 +1,49 @@ +function isnan(n) { return n !== n } + +function f(x) { + var sum = 0; + for (var i = 0; i < 100; ++i) + sum += x.x; + return sum; +} +var o = {}; +assertEq(isnan(f(o)), true); +o.x = 1; +assertEq(f(o), 100); +var o = {a:1, b:2}; +assertEq(isnan(f(o)), true); +o.x = 2; +assertEq(f(o), 200); + +function g(x) { + var sum = 0; + for (var i = 0; i < 100; ++i) + sum += x.x; + return sum; +} +var o = {c:1, x:1}; +assertEq(g(o), 100); +var o = {}; +assertEq(isnan(g(o)), true); + +function h(x) { + var sum = 0; + for (var i = 0; i < 100; ++i) + sum += x.x; + return sum; +} + +var proto1 = {}; +var proto2 = Object.create(proto1); +var o = Object.create(proto2); +assertEq(isnan(f(o)), true); +assertEq(isnan(g(o)), true); +assertEq(isnan(h(o)), true); +proto2.x = 2; +assertEq(f(o), 200); +assertEq(g(o), 200); +assertEq(h(o), 200); +var o = {} +assertEq(isnan(f(o)), true); +assertEq(isnan(g(o)), true); +assertEq(isnan(h(o)), true); diff --git a/js/src/jit-test/tests/basic/testModuloWithNegative1.js b/js/src/jit-test/tests/basic/testModuloWithNegative1.js new file mode 100644 index 000000000..ed767a7a2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testModuloWithNegative1.js @@ -0,0 +1,11 @@ +function testModuloWithNegative1() { + var v = 0; + for (var i = 0; i < 2; ++i) { + c = v; + v -= 1; + for (var j = 0; j < 2; ++j) + c %= -1; + } + return 1/c; +} +assertEq(testModuloWithNegative1(), -Infinity); diff --git a/js/src/jit-test/tests/basic/testModuloWithNegative2.js b/js/src/jit-test/tests/basic/testModuloWithNegative2.js new file mode 100644 index 000000000..dfd1e3deb --- /dev/null +++ b/js/src/jit-test/tests/basic/testModuloWithNegative2.js @@ -0,0 +1,7 @@ +function f(v, e) { + for (var i = 0; i < 9; i++) + v %= e; + return v; +} +f(0, 1); +assertEq(f(-2, 2), -0); diff --git a/js/src/jit-test/tests/basic/testMoreArgcThanNargs.js b/js/src/jit-test/tests/basic/testMoreArgcThanNargs.js new file mode 100644 index 000000000..9fcda77e3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMoreArgcThanNargs.js @@ -0,0 +1,14 @@ +function doTestMoreArgcThanNargs() +{ + var x = 0; + for (var i = 0; i < 10; i++) + { + x = x + arguments[3]; + } + return x; +} +function testMoreArgcThanNargs() +{ + return doTestMoreArgcThanNargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +} +assertEq(testMoreArgcThanNargs(), 4*10); diff --git a/js/src/jit-test/tests/basic/testMoreClosures.js b/js/src/jit-test/tests/basic/testMoreClosures.js new file mode 100644 index 000000000..5592bcba3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMoreClosures.js @@ -0,0 +1,14 @@ +function testMoreClosures() { + var f = {}, max = 3; + + var hello = function(n) { + function howdy() { return n * n } + f.test = howdy; + }; + + for (var i = 0; i <= max; i++) + hello(i); + + return f.test(); +} +assertEq(testMoreClosures(), 9); diff --git a/js/src/jit-test/tests/basic/testMulOverflow.js b/js/src/jit-test/tests/basic/testMulOverflow.js new file mode 100644 index 000000000..5d7a1339f --- /dev/null +++ b/js/src/jit-test/tests/basic/testMulOverflow.js @@ -0,0 +1,6 @@ +function testMulOverflow() { + var a = []; + for (let j=0;j<5;++j) a.push(0 | ((0x60000009) * 0x60000009)); + return a.join(","); +} +assertEq(testMulOverflow(), "-1073741824,-1073741824,-1073741824,-1073741824,-1073741824"); diff --git a/js/src/jit-test/tests/basic/testMultipleArgumentsObjects.js b/js/src/jit-test/tests/basic/testMultipleArgumentsObjects.js new file mode 100644 index 000000000..dd8285d64 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMultipleArgumentsObjects.js @@ -0,0 +1,12 @@ +function testMultipleArgumentsObjects() { + var testargs = arguments; + var f = function (name, which) { + var args = [testargs, arguments]; + return args[which][0]; + }; + var arr = [0, 0, 0, 0, 1]; + for (var i = 0; i < arr.length; i++) + arr[i] = f("f", arr[i]); + return arr + ''; +} +assertEq(testMultipleArgumentsObjects(), ",,,,f"); diff --git a/js/src/jit-test/tests/basic/testMultipleFunctionRedeclarations.js b/js/src/jit-test/tests/basic/testMultipleFunctionRedeclarations.js new file mode 100644 index 000000000..701782378 --- /dev/null +++ b/js/src/jit-test/tests/basic/testMultipleFunctionRedeclarations.js @@ -0,0 +1,44 @@ +function f1() { + assertEq(g(), 3); + function g() { return 1 } + assertEq(g(), 3); + function g() { return 2 } + assertEq(g(), 3); + function g() { return 3 } + assertEq(g(), 3); +} +f1(); + +function f2() { + assertEq(g(), 2); + var g = 3; + assertEq(g, 3); + function g() { return 1 } + function g() { return 2 } +} +f2(); + +function f3() { + assertEq(g(), 2); + var g = 3; + assertEq(g, 3); + function g() { return 1 } + var g = 4; + assertEq(g, 4); + function g() { return 2 } +} +f3(); + +function f4() { + assertEq(g(), 4); + function g() { return 1 } + assertEq(g(), 4); + function g() { return 2 } + var g = 9; + assertEq(g, 9); + function g() { return 3 } + assertEq(g, 9); + function g() { return 4 } + assertEq(g, 9); +} +f4(); diff --git a/js/src/jit-test/tests/basic/testMultiplePendingGlobalWrites.js b/js/src/jit-test/tests/basic/testMultiplePendingGlobalWrites.js new file mode 100644 index 000000000..06d54dfbb --- /dev/null +++ b/js/src/jit-test/tests/basic/testMultiplePendingGlobalWrites.js @@ -0,0 +1,11 @@ +var a, b; +function g(x) { + var y = x++; + return [x, y]; +} +function f() { + for(var i=0; i<20; i++) { + [a,b] = g("10"); + } +} +f(); diff --git a/js/src/jit-test/tests/basic/testNEWINIT.js b/js/src/jit-test/tests/basic/testNEWINIT.js new file mode 100644 index 000000000..28fd227a2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNEWINIT.js @@ -0,0 +1,8 @@ +function testNEWINIT() +{ + var a; + for (var i = 0; i < 10; ++i) + a = [{}]; + return uneval(a); +} +assertEq(testNEWINIT(), "[{}]"); diff --git a/js/src/jit-test/tests/basic/testNEWINIT_DOUBLE.js b/js/src/jit-test/tests/basic/testNEWINIT_DOUBLE.js new file mode 100644 index 000000000..238e5de72 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNEWINIT_DOUBLE.js @@ -0,0 +1,6 @@ +function testNEWINIT_DOUBLE() +{ + for (var z = 0; z < 2; ++z) { ({ 0.1: null })} + return "ok"; +} +assertEq(testNEWINIT_DOUBLE(), "ok"); diff --git a/js/src/jit-test/tests/basic/testNativeArgsRooting.js b/js/src/jit-test/tests/basic/testNativeArgsRooting.js new file mode 100644 index 000000000..1ce8259f2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNativeArgsRooting.js @@ -0,0 +1,14 @@ +if ('gczeal' in this) +(function () { + (eval("\ + (function () {\ + for (var y = 0; y < 16; ++y) {\ + if (y % 3 == 2) {\ + gczeal(1);\ + } else {\ + print(0 / 0);\ + }\ + }\ + });\ + "))() +})(); diff --git a/js/src/jit-test/tests/basic/testNativeLog.js b/js/src/jit-test/tests/basic/testNativeLog.js new file mode 100644 index 000000000..5a81c79e7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNativeLog.js @@ -0,0 +1,8 @@ +function testNativeLog() { + var a = new Array(5); + for (var i = 0; i < 5; i++) { + a[i] = Math.log(Math.pow(Math.E, 10)); + } + return a.join(","); +} +assertEq(testNativeLog(), "10,10,10,10,10"); diff --git a/js/src/jit-test/tests/basic/testNativeMax.js b/js/src/jit-test/tests/basic/testNativeMax.js new file mode 100644 index 000000000..ef36dbe5c --- /dev/null +++ b/js/src/jit-test/tests/basic/testNativeMax.js @@ -0,0 +1,20 @@ +function testNativeMax() { + var out = [], k; + for (var i = 0; i < 5; ++i) { + k = Math.max(k, i); + } + out.push(k); + + k = 0; + for (var i = 0; i < 5; ++i) { + k = Math.max(k, i); + } + out.push(k); + + for (var i = 0; i < 5; ++i) { + k = Math.max(0, -0); + } + out.push((1 / k) < 0); + return out.join(","); +} +assertEq(testNativeMax(), "NaN,4,false"); diff --git a/js/src/jit-test/tests/basic/testNativeSetter.js b/js/src/jit-test/tests/basic/testNativeSetter.js new file mode 100644 index 000000000..79ddf56f9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNativeSetter.js @@ -0,0 +1,8 @@ +function testNativeSetter() { + var re = /foo/; + var N = 19; + for (var i = 0; i < N; i++) + re.lastIndex = i; + assertEq(re.lastIndex, N - 1); +} +testNativeSetter(); diff --git a/js/src/jit-test/tests/basic/testNegZero1.js b/js/src/jit-test/tests/basic/testNegZero1.js new file mode 100644 index 000000000..fe9aabdf2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNegZero1.js @@ -0,0 +1,9 @@ +function testNegZero1Helper(z) { + for (let j = 0; j < 5; ++j) { z = -z; } + return Math.atan2(0, -0) == Math.atan2(0, z); +} + +var testNegZero1 = function() { return testNegZero1Helper(0); } +testNegZero1.name = 'testNegZero1'; +testNegZero1Helper(1); +assertEq(testNegZero1(), true); diff --git a/js/src/jit-test/tests/basic/testNegativeArrayLength.js b/js/src/jit-test/tests/basic/testNegativeArrayLength.js new file mode 100644 index 000000000..1719ceeb9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNegativeArrayLength.js @@ -0,0 +1,10 @@ +function f() { + try { + for ( var i = 7; i > -2; i-- ) + new Array(i).join('*'); + } catch (e) { + return e instanceof RangeError; + } + return false; +} +assertEq(f(), true); diff --git a/js/src/jit-test/tests/basic/testNegativeGETELEMIndex.js b/js/src/jit-test/tests/basic/testNegativeGETELEMIndex.js new file mode 100644 index 000000000..da7b74812 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNegativeGETELEMIndex.js @@ -0,0 +1,6 @@ +function testNegativeGETELEMIndex() +{ + for (let i=0;i<3;++i) /x/[-4]; + return "ok"; +} +assertEq(testNegativeGETELEMIndex(), "ok"); diff --git a/js/src/jit-test/tests/basic/testNestedClosures.js b/js/src/jit-test/tests/basic/testNestedClosures.js new file mode 100644 index 000000000..445ea6e39 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNestedClosures.js @@ -0,0 +1,23 @@ +function testNestedClosures() { + function f(a, b) { + function g(x, y) { + function h(m, n) { + function k(u, v) { + var s = ''; + for (var i = 0; i < 5; ++i) + s = a + ',' + b + ',' + x + ',' + y + ',' + m + ',' + n + ',' + u + ',' + v; + return s; + } + return k(m+1, n+1); + } + return h(x+1, y+1); + } + return g(a+1, b+1); + } + + var s1; + for (var i = 0; i < 5; ++i) + s1 = f(i, i+i); + return s1; +} +assertEq(testNestedClosures(), '4,8,5,9,6,10,7,11'); diff --git a/js/src/jit-test/tests/basic/testNestedDeepBail.js b/js/src/jit-test/tests/basic/testNestedDeepBail.js new file mode 100644 index 000000000..8e59b04cd --- /dev/null +++ b/js/src/jit-test/tests/basic/testNestedDeepBail.js @@ -0,0 +1,20 @@ +var _quit; +function testNestedDeepBail() +{ + _quit = false; + function loop() { + for (var i = 0; i < 4; i++) + ; + } + loop(); + + function f() { + loop(); + _quit = true; + } + + var stk = [[1], [], [], [], []]; + while (!_quit) + stk.pop().forEach(f); +} +testNestedDeepBail(); diff --git a/js/src/jit-test/tests/basic/testNestedEscapingLambdas.js b/js/src/jit-test/tests/basic/testNestedEscapingLambdas.js new file mode 100644 index 000000000..8b896f193 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNestedEscapingLambdas.js @@ -0,0 +1,31 @@ +function testNestedEscapingLambdas() +{ + try { + return (function() { + var a = [], r = []; + function setTimeout(f, t) { + a.push(f); + } + + function runTimeouts() { + for (var i = 0; i < a.length; i++) + a[i](); + } + + var $foo = "#nothiddendiv"; + setTimeout(function(){ + r.push($foo); + setTimeout(function(){ + r.push($foo); + }, 100); + }, 100); + + runTimeouts(); + + return r.join(""); + })(); + } catch (e) { + return e; + } +} +assertEq(testNestedEscapingLambdas(), "#nothiddendiv#nothiddendiv"); diff --git a/js/src/jit-test/tests/basic/testNestedExitStackOuter.js b/js/src/jit-test/tests/basic/testNestedExitStackOuter.js new file mode 100644 index 000000000..5da8a1f96 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNestedExitStackOuter.js @@ -0,0 +1,29 @@ +// Test stack reconstruction after a nested exit +function testNestedExitStackInner(j, counter) { + ++counter; + var b = 0; + for (var i = 1; i <= 9; i++) { + ++b; + var a; + // Make sure that once everything has been traced we suddenly switch to + // a different control flow the first time we run the outermost tree, + // triggering a side exit. + if (j < 9) + a = 1; + else + a = 0; + ++b; + b += a; + } + return counter + b; +} +function testNestedExitStackOuter() { + var counter = 0; + for (var j = 1; j <= 9; ++j) { + for (var k = 1; k <= 9; ++k) { + counter = testNestedExitStackInner(j, counter); + } + } + return counter; +} +//assertEq(testNestedExitStackOuter(), 81); diff --git a/js/src/jit-test/tests/basic/testNestedForIn.js b/js/src/jit-test/tests/basic/testNestedForIn.js new file mode 100644 index 000000000..1541775f8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNestedForIn.js @@ -0,0 +1,9 @@ +function testNestedForIn() { + var a = {x: 1, y: 2, z: 3}; + var s = ''; + for (var p1 in a) + for (var p2 in a) + s += p1 + p2 + ' '; + return s; +} +assertEq(testNestedForIn(), 'xx xy xz yx yy yz zx zy zz '); diff --git a/js/src/jit-test/tests/basic/testNeutering.js b/js/src/jit-test/tests/basic/testNeutering.js new file mode 100644 index 000000000..fc49e3f99 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNeutering.js @@ -0,0 +1,23 @@ +var ab = new ArrayBuffer(4); +var i32 = new Int32Array(ab); +i32[0] = 42; +detachArrayBuffer(ab); +assertEq(i32.length, 0); +assertEq(ab.byteLength, 0); +assertEq(i32[0], undefined); + +var ab = new ArrayBuffer(12); +var i32 = new Int32Array(ab); +i32[0] = 42; +detachArrayBuffer(ab); +assertEq(i32.length, 0); +assertEq(ab.byteLength, 0); +assertEq(i32[0], undefined); + +var ab = new ArrayBuffer(4096); +var i32 = new Int32Array(ab); +i32[0] = 42; +detachArrayBuffer(ab); +assertEq(i32.length, 0); +assertEq(ab.byteLength, 0); +assertEq(i32[0], undefined); diff --git a/js/src/jit-test/tests/basic/testNewArrayCount.js b/js/src/jit-test/tests/basic/testNewArrayCount.js new file mode 100644 index 000000000..cb7e6d984 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNewArrayCount.js @@ -0,0 +1,12 @@ +function testNewArrayCount() +{ + function count(a) { var n = 0; for (var p in a) n++; return n; } + var a = []; + for (var i = 0; i < 5; i++) + a = [0]; + assertEq(count(a), 1); + for (var i = 0; i < 5; i++) + a = [0, , 2]; + assertEq(count(a), 2); +} +testNewArrayCount(); diff --git a/js/src/jit-test/tests/basic/testNewArrayCount2.js b/js/src/jit-test/tests/basic/testNewArrayCount2.js new file mode 100644 index 000000000..6318e4c25 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNewArrayCount2.js @@ -0,0 +1,8 @@ +function testNewArrayCount2() { + function count(a) { var n = 0; for (var p in a) n++; return n; } + var x = 0; + for (var i = 0; i < 10; ++i) + x = count(new Array(1,2,3)); + return x; +} +assertEq(testNewArrayCount2(), 3); diff --git a/js/src/jit-test/tests/basic/testNewObject.js b/js/src/jit-test/tests/basic/testNewObject.js new file mode 100644 index 000000000..028523c01 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNewObject.js @@ -0,0 +1,8 @@ +function testNewObject() +{ + var a = {}; + for (var i = 0; i < 10; ++i) + a = new Object(); + return a; +} +assertEq(testNewObject().__proto__, {}.__proto__); diff --git a/js/src/jit-test/tests/basic/testNewString.js b/js/src/jit-test/tests/basic/testNewString.js new file mode 100644 index 000000000..e0f378bbc --- /dev/null +++ b/js/src/jit-test/tests/basic/testNewString.js @@ -0,0 +1,21 @@ +function testNewString() +{ + var o = { toString: function() { return "string"; } }; + var r = []; + for (var i = 0; i < 5; i++) + r.push(typeof new String(o)); + for (var i = 0; i < 5; i++) + r.push(typeof new String(3)); + for (var i = 0; i < 5; i++) + r.push(typeof new String(2.5)); + for (var i = 0; i < 5; i++) + r.push(typeof new String("string")); + for (var i = 0; i < 5; i++) + r.push(typeof new String(null)); + for (var i = 0; i < 5; i++) + r.push(typeof new String(true)); + for (var i = 0; i < 5; i++) + r.push(typeof new String(undefined)); + return r.length === 35 && r.every(function(v) { return v === "object"; }); +} +assertEq(testNewString(), true); diff --git a/js/src/jit-test/tests/basic/testNewWithClone.js b/js/src/jit-test/tests/basic/testNewWithClone.js new file mode 100644 index 000000000..ef976df58 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNewWithClone.js @@ -0,0 +1,7 @@ +with({}) { + function f() { + this.foo = "bar"; + } + o = new f(); + assertEq(o.foo, "bar"); +} diff --git a/js/src/jit-test/tests/basic/testNewWithNonNativeProto.js b/js/src/jit-test/tests/basic/testNewWithNonNativeProto.js new file mode 100644 index 000000000..dc950efc7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNewWithNonNativeProto.js @@ -0,0 +1,9 @@ +function testNewWithNonNativeProto() +{ + function f() { } + var a = f.prototype = []; + for (var i = 0; i < 5; i++) + var o = new f(); + return Object.getPrototypeOf(o) === a && o.splice === Array.prototype.splice; +} +assertEq(testNewWithNonNativeProto(), true); diff --git a/js/src/jit-test/tests/basic/testNonStubGetter.js b/js/src/jit-test/tests/basic/testNonStubGetter.js new file mode 100644 index 000000000..58a698eb4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNonStubGetter.js @@ -0,0 +1,7 @@ +function testNonStubGetter() { + { let [] = []; (this.watch("x", function(p, o, n) { return /a/g.exec(p, o, n); })); }; + (function () { (eval("(function(){for each (x in [1, 2, 2]);});"))(); })(); + this.unwatch("x"); + return "ok"; +} +assertEq(testNonStubGetter(), "ok"); diff --git a/js/src/jit-test/tests/basic/testNot.js b/js/src/jit-test/tests/basic/testNot.js new file mode 100644 index 000000000..746ca5739 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNot.js @@ -0,0 +1,8 @@ +function testNot() { + var a = new Object(), b = null, c = "foo", d = "", e = 5, f = 0, g = 5.5, h = -0, i = true, j = false, k = undefined; + var r; + for (var i = 0; i < 10; ++i) + r = [!a, !b, !c, !d, !e, !f, !g, !h, !i, !j, !k]; + return r.join(","); +} +assertEq(testNot(), "false,true,false,true,false,true,false,true,false,true,true"); diff --git a/js/src/jit-test/tests/basic/testNullCallee.js b/js/src/jit-test/tests/basic/testNullCallee.js new file mode 100644 index 000000000..7eab7d55c --- /dev/null +++ b/js/src/jit-test/tests/basic/testNullCallee.js @@ -0,0 +1,16 @@ +function testNullCallee() { + try { + function f() { + var x = new Array(5); + for (var i = 0; i < 5; i++) + x[i] = a[i].toString(); + return x.join(','); + } + f([[1],[2],[3],[4],[5]]); + f([null, null, null, null, null]); + } catch (e) { + return true; + } + return false; +} +assertEq(testNullCallee(), true); diff --git a/js/src/jit-test/tests/basic/testNullIncrement.js b/js/src/jit-test/tests/basic/testNullIncrement.js new file mode 100644 index 000000000..b7ffd03b4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNullIncrement.js @@ -0,0 +1,14 @@ +function f() { + var n; + var k; + for (var i = 0; i < 18; ++i) { + n = null; + k = n++; + if (k) { } + } + return [k, n]; +} + +var [a, b] = f(); +assertEq(a, 0); +assertEq(b, 1); diff --git a/js/src/jit-test/tests/basic/testNullRelCmp.js b/js/src/jit-test/tests/basic/testNullRelCmp.js new file mode 100644 index 000000000..4531ea2c8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNullRelCmp.js @@ -0,0 +1,6 @@ +function testNullRelCmp() { + var out = []; + for(j=0;j<3;++j) { out.push(3 > null); out.push(3 < null); out.push(0 == null); out.push(3 == null); } + return out.join(","); +} +assertEq(testNullRelCmp(), "true,false,false,false,true,false,false,false,true,false,false,false"); diff --git a/js/src/jit-test/tests/basic/testNullToString.js b/js/src/jit-test/tests/basic/testNullToString.js new file mode 100644 index 000000000..c80feb1da --- /dev/null +++ b/js/src/jit-test/tests/basic/testNullToString.js @@ -0,0 +1,13 @@ +function testNullToString() +{ + var a = []; + for (var i = 0; i < 10; i++) + a.push(String(null)); + for (i = 0; i < 10; i++) { + var t = typeof a[i]; + if (t != "string") + a.push(t); + } + return a.join(","); +} +assertEq(testNullToString(), "null,null,null,null,null,null,null,null,null,null"); diff --git a/js/src/jit-test/tests/basic/testNumToString.js b/js/src/jit-test/tests/basic/testNumToString.js new file mode 100644 index 000000000..96f3cc725 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNumToString.js @@ -0,0 +1,18 @@ +function testNumToString() { + var r = []; + var d = 123456789; + for (var i = 0; i < 10; ++i) { + r = [ + d.toString(), + (-d).toString(), + d.toString(10), + (-d).toString(10), + d.toString(16), + (-d).toString(16), + d.toString(36), + (-d).toString(36) + ]; + } + return r.join(","); +} +assertEq(testNumToString(), "123456789,-123456789,123456789,-123456789,75bcd15,-75bcd15,21i3v9,-21i3v9"); diff --git a/js/src/jit-test/tests/basic/testNumberToString.js b/js/src/jit-test/tests/basic/testNumberToString.js new file mode 100644 index 000000000..5b7961664 --- /dev/null +++ b/js/src/jit-test/tests/basic/testNumberToString.js @@ -0,0 +1,6 @@ +function testNumberToString() { + var x = new Number(0); + for (var i = 0; i < 4; i++) + x.toString(); +} +testNumberToString(); diff --git a/js/src/jit-test/tests/basic/testOOMInAutoEnterCompartment.js b/js/src/jit-test/tests/basic/testOOMInAutoEnterCompartment.js new file mode 100644 index 000000000..693d61b08 --- /dev/null +++ b/js/src/jit-test/tests/basic/testOOMInAutoEnterCompartment.js @@ -0,0 +1,18 @@ +// |jit-test| slow +// This test is too slow to run with ASan in a debug configuration +if (getBuildConfiguration()['asan'] && getBuildConfiguration()['debug']) quit(0); + +function fatty() { + try { + fatty(); + } catch (e) { + foo(); + } +} + +if (!getBuildConfiguration()['root-analysis']) { // >:( + foo = evalcx("(function foo() { foo.bar() })"); + foo.bar = evalcx("(function bar() {})"); + + fatty(); +} diff --git a/js/src/jit-test/tests/basic/testObjectConstructorReturningObject.js b/js/src/jit-test/tests/basic/testObjectConstructorReturningObject.js new file mode 100644 index 000000000..c18863db6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testObjectConstructorReturningObject.js @@ -0,0 +1,12 @@ +for (var i = 0; i < 12; ++i) { + var o; + + o = new Object(Object); + assertEq(o, Object); + + (function () { + x = constructor + })(); + o = new(x)(x); + assertEq(o, Object); +} diff --git a/js/src/jit-test/tests/basic/testObjectLength.js b/js/src/jit-test/tests/basic/testObjectLength.js new file mode 100644 index 000000000..3813a6e51 --- /dev/null +++ b/js/src/jit-test/tests/basic/testObjectLength.js @@ -0,0 +1,10 @@ +function testObjectLength() +{ + var counter = 0; + var a = {}; + a.length = 10000; + for (var i = 0; i < a.length; i++) + counter++; + return counter; +} +assertEq(testObjectLength(), 10000); diff --git a/js/src/jit-test/tests/basic/testObjectOrderedCmp.js b/js/src/jit-test/tests/basic/testObjectOrderedCmp.js new file mode 100644 index 000000000..7065ad8fc --- /dev/null +++ b/js/src/jit-test/tests/basic/testObjectOrderedCmp.js @@ -0,0 +1,7 @@ +function testObjectOrderedCmp() +{ + var a = new Array(5); + for(var i=0;i<5;++i) a[i] = ({} < {}); + return a.join(","); +} +assertEq(testObjectOrderedCmp(), "false,false,false,false,false"); diff --git a/js/src/jit-test/tests/basic/testObjectOrderedCmp2.js b/js/src/jit-test/tests/basic/testObjectOrderedCmp2.js new file mode 100644 index 000000000..6790799c3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testObjectOrderedCmp2.js @@ -0,0 +1,7 @@ +function testObjectOrderedCmp2() +{ + var a = new Array(5); + for(var i=0;i<5;++i) a[i] = ("" <= null); + return a.join(","); +} +assertEq(testObjectOrderedCmp2(), "true,true,true,true,true"); diff --git a/js/src/jit-test/tests/basic/testObjectToNumber.js b/js/src/jit-test/tests/basic/testObjectToNumber.js new file mode 100644 index 000000000..d6353a6a6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testObjectToNumber.js @@ -0,0 +1,8 @@ +function testObjectToNumber() { + var o = {valueOf: () => -3}; + var x = 0; + for (var i = 0; i < 10; i++) + x -= o; + return x; +} +assertEq(testObjectToNumber(), 30); diff --git a/js/src/jit-test/tests/basic/testObjectToString.js b/js/src/jit-test/tests/basic/testObjectToString.js new file mode 100644 index 000000000..ba47d00f0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testObjectToString.js @@ -0,0 +1,8 @@ +function testObjectToString() { + var o = {toString: () => "foo"}; + var s = ""; + for (var i = 0; i < 10; i++) + s += o; + return s; +} +assertEq(testObjectToString(), "foofoofoofoofoofoofoofoofoofoo"); diff --git a/js/src/jit-test/tests/basic/testObjectVsPrototype.js b/js/src/jit-test/tests/basic/testObjectVsPrototype.js new file mode 100644 index 000000000..194b05fa7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testObjectVsPrototype.js @@ -0,0 +1,12 @@ +function testObjectVsPrototype() { + function D() {} + var b = D.prototype = {x: 1}; + var d = new D; + var arr = [b, b, b, d]; + for (var i = 0; i < 4; i++) + arr[i].x = i; + + d.y = 12; + assertEq(d.x, 3); +} +testObjectVsPrototype(); diff --git a/js/src/jit-test/tests/basic/testOverOOMInFixupArity.js b/js/src/jit-test/tests/basic/testOverOOMInFixupArity.js new file mode 100644 index 000000000..1b81d84ec --- /dev/null +++ b/js/src/jit-test/tests/basic/testOverOOMInFixupArity.js @@ -0,0 +1,15 @@ +function foo() { + bar(1,2,3,4,5,6,7,8,9); +} + +function bar() { + foo(1,2,3,4,5,6,7,8,9); +} + +var caught = false; +try { + foo(); +} catch (e) { + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/testOverRecursed1.js b/js/src/jit-test/tests/basic/testOverRecursed1.js new file mode 100644 index 000000000..d44da136c --- /dev/null +++ b/js/src/jit-test/tests/basic/testOverRecursed1.js @@ -0,0 +1,6 @@ +// |jit-test| error:InternalError + +var a = []; +var f = a.forEach.bind(a); +a.push(f); +f(f); diff --git a/js/src/jit-test/tests/basic/testOverRecursed2.js b/js/src/jit-test/tests/basic/testOverRecursed2.js new file mode 100644 index 000000000..bcd59d8b2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testOverRecursed2.js @@ -0,0 +1,7 @@ +// |jit-test| error:InternalError + +var a = []; +var sort = a.sort.bind(a); +a.push(sort); +a.push(sort); +sort(sort); diff --git a/js/src/jit-test/tests/basic/testOverRecursed3.js b/js/src/jit-test/tests/basic/testOverRecursed3.js new file mode 100644 index 000000000..100e7e762 --- /dev/null +++ b/js/src/jit-test/tests/basic/testOverRecursed3.js @@ -0,0 +1,6 @@ +// |jit-test| error:InternalError + +var x = []; +x.push(x, x); // more than one so the sort can't be optimized away +x.toString = x.sort; +x.toString(); diff --git a/js/src/jit-test/tests/basic/testOverRecursed4.js b/js/src/jit-test/tests/basic/testOverRecursed4.js new file mode 100644 index 000000000..e29d4bf7d --- /dev/null +++ b/js/src/jit-test/tests/basic/testOverRecursed4.js @@ -0,0 +1,9 @@ +function tryItOut(code) { + f = eval("(function(){" + code + "})") + try { + f() + } catch (e) {} +} +tryItOut("x=7"); +tryItOut("\"use strict\";for(d in[x=arguments]){}"); +tryItOut("for(v in((Object.seal)(x)));x.length=Function") diff --git a/js/src/jit-test/tests/basic/testOverRecursed5.js b/js/src/jit-test/tests/basic/testOverRecursed5.js new file mode 100644 index 000000000..fc8ceba9c --- /dev/null +++ b/js/src/jit-test/tests/basic/testOverRecursed5.js @@ -0,0 +1,13 @@ +JSON.__proto__[1] = new Uint8ClampedArray().buffer +f = (function() { + function g(c) { + Object.freeze(c).__proto__ = c + } + for each(b in []) { + try { + g(b) + } catch (e) {} + } +}) +f() +f() diff --git a/js/src/jit-test/tests/basic/testOverRecursed6.js b/js/src/jit-test/tests/basic/testOverRecursed6.js new file mode 100644 index 000000000..7c30bc7b6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testOverRecursed6.js @@ -0,0 +1,3 @@ +// |jit-test| error:InternalError + +"" + {toString: Date.prototype.toJSON}; diff --git a/js/src/jit-test/tests/basic/testOverwrittenArgumentsWithUndefined.js b/js/src/jit-test/tests/basic/testOverwrittenArgumentsWithUndefined.js new file mode 100644 index 000000000..5f899243b --- /dev/null +++ b/js/src/jit-test/tests/basic/testOverwrittenArgumentsWithUndefined.js @@ -0,0 +1,24 @@ +function f() { + var a = arguments; + eval("assertEq(arguments[0], 42)"); + eval("assertEq(arguments, a)"); + arguments = undefined; + eval("assertEq(arguments, undefined)"); + arguments = a; + eval("assertEq(arguments[0], 42)"); + eval("assertEq(arguments, a)"); +} +f(42); + +function f(z) { + var a = arguments; + eval("assertEq(arguments[0], 42)"); + eval("assertEq(arguments, a)"); + arguments = undefined; + eval("assertEq(arguments, undefined)"); + z = 17; + eval("assertEq(a[0], 17)"); + a[0] = 'ponies'; + eval("assertEq(z, 'ponies')"); +} +f(42); diff --git a/js/src/jit-test/tests/basic/testOwnPropertyWithInOperator.js b/js/src/jit-test/tests/basic/testOwnPropertyWithInOperator.js new file mode 100644 index 000000000..2224dba2d --- /dev/null +++ b/js/src/jit-test/tests/basic/testOwnPropertyWithInOperator.js @@ -0,0 +1,9 @@ +function testOwnPropertyWithInOperator() +{ + var o = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6 }; + var a = []; + for (var i = 0; i < 7; i++) + a.push(i in o); + return a.join(","); +} +assertEq(testOwnPropertyWithInOperator(), "true,true,true,true,true,true,true"); diff --git a/js/src/jit-test/tests/basic/testParseInt.js b/js/src/jit-test/tests/basic/testParseInt.js new file mode 100644 index 000000000..d3706b2f0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testParseInt.js @@ -0,0 +1,48 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function testInt(n, result) { + var x = 0; + for (var i = 0; i < 15; i++) { + assertEq(parseInt(n, 10), result); + assertEq(parseInt(n, 0), result); + assertEq(parseInt(n), result); + assertEq(parseInt(n, x), result); + + if (x % 2 == 0) + x = 10; + else + x = 0; + } +} + +function testDouble(n, result) { + var x = 0; + for (var i = 0; i < 15; i++) { + assertEq(parseInt(n, 10), result); + assertEq(parseInt(n, 0), result); + assertEq(parseInt(n), result); + assertEq(parseInt(n, x), result); + + if (x % 2 == 0) + x = 10; + else + x = 0; + } +} + +testInt(2147483647, 2147483647); +testInt(-2147483648, -2147483648); +testInt(17, 17); +testInt(-1, -1); +testInt(0, 0); + +testDouble(1e21, 1); +testDouble(-5.7, -5); +testDouble(1.7, 1); +testDouble(1.0e-6, 0); +testDouble(1.0e-7, 1); +testDouble(NaN, NaN); +testDouble(1e20, 1e20); diff --git a/js/src/jit-test/tests/basic/testPartialFlatClosure.js b/js/src/jit-test/tests/basic/testPartialFlatClosure.js new file mode 100644 index 000000000..9998ce306 --- /dev/null +++ b/js/src/jit-test/tests/basic/testPartialFlatClosure.js @@ -0,0 +1,10 @@ +assertEq((('-r', function (s) { + function C(i) { + this.m = function () { return i * t; } + } + var t = s; + var a = []; + for (var i = 0; i < 5; i++) + a[a.length] = new C(i); + return a; +})(42))[4].m(), 168); diff --git a/js/src/jit-test/tests/basic/testPaths.js b/js/src/jit-test/tests/basic/testPaths.js new file mode 100644 index 000000000..139c88e1e --- /dev/null +++ b/js/src/jit-test/tests/basic/testPaths.js @@ -0,0 +1,68 @@ +// load() and snarf() (aka read()) should resolve paths relative to the current +// working directory. This is a little hard to test because the shell doesn't +// really have any (portable) notion of the current directory (and it can't +// create files to enforce an expected layout.) loadRelativeToScript() and +// readRelativeToScript() do what their names say, which is much easier to +// test. + +loaded = {} +snarfed = {} +loadRel = {} +snarfRel = {} +for (let f of ['local.js', '../basic/local.js', 'Y.js']) { + try { + load(f); + loaded[f] = true; + } catch(e) { + loaded[f] = !/can't open/.test(e); + } + + try { + snarf(f); + snarfed[f] = true; + } catch(e) { + snarfed[f] = !/can't open/.test(e); + } + + try { + readRelativeToScript(f); + snarfRel[f] = true; + } catch(e) { + snarfRel[f] = !/can't open/.test(e); + } + + try { + loadRelativeToScript(f); + loadRel[f] = true; + } catch(e) { + loadRel[f] = !/can't open/.test(e); + } +} + +// local.js in the same dir as this script, so should be found by the +// script-relative calls but not the cwd-relative ones -- unless you happen to +// be in that directory +assertEq(loadRel['local.js'], true); +assertEq(loadRel['../basic/local.js'], true); +assertEq(snarfRel['local.js'], true); +assertEq(snarfRel['../basic/local.js'], true); +var cwd = os.getenv('PWD'); +if (cwd !== undefined && !(/test.*[\/\\]basic[\/\\]/.test(cwd))) { + assertEq(loaded['local.js'], false); + assertEq(loaded['../basic/local.js'], false); + assertEq(snarfed['local.js'], false); + assertEq(snarfed['../basic/local.js'], false); +} + +// Y.js is in the root of the objdir, where |make check| is normally +// run from. +assertEq(loadRel['Y.js'], false); +assertEq(snarfRel['Y.js'], false); +if (!snarfed['Y.js']) { + print("WARNING: expected to be able to find Y.js in current directory\n"); + print("(not failing because it depends on where this test was run from)\n"); +} +if (!loaded['Y.js']) { + print("WARNING: expected to be able to find Y.js in current directory\n"); + print("(not failing because it depends on where this test was run from)\n"); +} diff --git a/js/src/jit-test/tests/basic/testPrimitiveConstructorPrototype.js b/js/src/jit-test/tests/basic/testPrimitiveConstructorPrototype.js new file mode 100644 index 000000000..f0154082c --- /dev/null +++ b/js/src/jit-test/tests/basic/testPrimitiveConstructorPrototype.js @@ -0,0 +1,7 @@ +function testPrimitiveConstructorPrototype() { + var f = function(){}; + f.prototype = false; + for (let j=0;j<5;++j) { new f; } + return "ok"; +} +assertEq(testPrimitiveConstructorPrototype(), "ok"); diff --git a/js/src/jit-test/tests/basic/testPropagatedFunArgs.js b/js/src/jit-test/tests/basic/testPropagatedFunArgs.js new file mode 100644 index 000000000..19052d1fe --- /dev/null +++ b/js/src/jit-test/tests/basic/testPropagatedFunArgs.js @@ -0,0 +1,34 @@ +function testPropagatedFunArgs() +{ + var win = this; + var res = [], q = []; + function addEventListener(name, func, flag) { + q.push(func); + } + + var pageInfo, obs; + addEventListener("load", handleLoad, true); + + var observer = { + observe: function(win, topic, data) { + // obs.removeObserver(observer, "page-info-dialog-loaded"); + handlePageInfo(); + } + }; + + function handleLoad() { + pageInfo = { toString: function() { return "pageInfo"; } }; + obs = { addObserver: function (obs, topic, data) { obs.observe(win, topic, data); } }; + obs.addObserver(observer, "page-info-dialog-loaded", false); + } + + function handlePageInfo() { + res.push(pageInfo); + function $(aId) { res.push(pageInfo); }; + var feedTab = $("feedTab"); + } + + q[0](); + return res.join(','); +} +assertEq(testPropagatedFunArgs(), "pageInfo,pageInfo"); diff --git a/js/src/jit-test/tests/basic/testProxyDefinePropertyWithMissingSetter.js b/js/src/jit-test/tests/basic/testProxyDefinePropertyWithMissingSetter.js new file mode 100644 index 000000000..19bb71583 --- /dev/null +++ b/js/src/jit-test/tests/basic/testProxyDefinePropertyWithMissingSetter.js @@ -0,0 +1,21 @@ +// throw, don't crash + +var actual = ""; + +try { + +var x = new Proxy({}, { + defineProperty: function(target, name, desc) { + Object.defineProperty(x, name, desc) + }, +}); + +Object.defineProperty(x, "", ({ + get: function() {} +})) + +} catch (e) { + actual = '' + e; +} + +assertEq(actual, "InternalError: too much recursion"); diff --git a/js/src/jit-test/tests/basic/testProxyPrototypes.js b/js/src/jit-test/tests/basic/testProxyPrototypes.js new file mode 100644 index 000000000..3b805e4c4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testProxyPrototypes.js @@ -0,0 +1,81 @@ +"use strict" +// Helpers. +function makeAccessorProp(obj, propName, initialValue, hiddenName) { + if (!hiddenName) + hiddenName = propName + '_'; + if (initialValue) + Object.defineProperty(obj, hiddenName, { value: initialValue, writable: true, enumerable: false }); + Object.defineProperty(obj, propName, + { configurable: true, + enumerable: true, + get: function() { return this[hiddenName]; }, + set: function(x) { + Object.defineProperty(this, hiddenName, { value: x, writable: true, enumerable: false }); + } + }); +} + +// Set up a prototype with 4 properties. +var proto = {valueProp: 11, valuePropShadowed: 22}; +makeAccessorProp(proto, 'accessorProp', 33); +makeAccessorProp(proto, 'accessorPropShadowed', 44); + +// Set up a proxy that uses |proto| as a prototype. +var proxyTarget = {valuePropShadowed: 21}; +makeAccessorProp(proxyTarget, 'accessorPropShadowed', -44, 'accessorPropShadowed__'); +var proxy = wrapWithProto(proxyTarget, proto); + +// Value getters. +assertEq(proxy.valueProp, 11); +assertEq(proxy.valuePropShadowed, 21); +// Iteration, enumeration, etc. +var propNames = []; +for (var i in proxy) + propNames.push(i); +assertEq(propNames.length, 4); +assertEq('valueProp' in proxy, true); +assertEq(proxy.hasOwnProperty('valueProp'), false); +assertEq(Object.getOwnPropertyNames(proxy).indexOf('valueProp'), -1); +assertEq('valuePropShadowed' in proxy, true); +assertEq(Object.getOwnPropertyNames(proxy).indexOf('valuePropShadowed') == -1, false); +assertEq(proxy.hasOwnProperty('valuePropShadowed'), true); +// Value setters. +proxy.valuePropShadowed = 20; +proxy.valueProp = 10; +assertEq(proxyTarget.valuePropShadowed, 20); +assertEq(proxyTarget.valueProp, 10); +// Accessor getters. +assertEq(proxy.accessorProp, 33); +assertEq(proxy.accessorPropShadowed, -44); +// Accessor setters. +proxy.accessorProp = 32; +proxy.accessorPropShadowed = -43; +assertEq(proxy.accessorProp, 32); +assertEq(proxy.accessorPropShadowed, -43); +// Make sure the underlying objects look right. +assertEq(proto.accessorProp_, 33); +assertEq(proto.accessorPropShadowed_, 44); +assertEq(proto.hasOwnProperty('accessorPropShadowed__'), false); +assertEq(proxyTarget.accessorProp_, 32); +assertEq(proxyTarget.hasOwnProperty('accessorPropShadowed_'), false); +assertEq(proxyTarget.accessorPropShadowed__, -43); + +// Now, create a new object prototyped to |proxy| and make sure |proxy| behaves +// well on the prototype chain. +function Constructor() { + this.foo = 2; +} +Constructor.prototype = proxy; +var child = new Constructor(); +assertEq(child.valueProp, 10); +assertEq(child.valuePropShadowed, 20); +var childPropNames = []; +for (var i in child) + childPropNames.push(i); +assertEq(childPropNames.length, 5); +child.accessorProp = 5; +child.accessorPropShadowed = 6; +assertEq(child.accessorProp, 5); +assertEq(child.accessorPropShadowed, 6); +assertEq(child.accessorProp_, 5); +assertEq(child.accessorPropShadowed__, 6); diff --git a/js/src/jit-test/tests/basic/testPutOnEmptyArgsObject.js b/js/src/jit-test/tests/basic/testPutOnEmptyArgsObject.js new file mode 100644 index 000000000..b23089785 --- /dev/null +++ b/js/src/jit-test/tests/basic/testPutOnEmptyArgsObject.js @@ -0,0 +1,16 @@ +var g; + +function h() { + return arguments.length; +} + +function f() { + var args = arguments; + g = function() { return h.apply(this, args); } +} + +for (var i = 0; i < 10; ++i) { + f(); +} + +assertEq(g(), 0); diff --git a/js/src/jit-test/tests/basic/testReallyDeepNestedExit.js b/js/src/jit-test/tests/basic/testReallyDeepNestedExit.js new file mode 100644 index 000000000..f27c7315c --- /dev/null +++ b/js/src/jit-test/tests/basic/testReallyDeepNestedExit.js @@ -0,0 +1,38 @@ +function reallyDeepNestedExit(schedule) +{ + var c = 0, j = 0; + for (var i = 0; i < 5; i++) { + for (j = 0; j < 4; j++) { + c += (schedule[i*4 + j] == 1) ? 1 : 2; + } + } + return c; +} +function testReallyDeepNestedExit() +{ + var c = 0; + var schedule1 = new Array(5*4); + var schedule2 = new Array(5*4); + for (var i = 0; i < 5*4; i++) { + schedule1[i] = 0; + schedule2[i] = 0; + } + /** + * First innermost compile: true branch runs through. + * Second '': false branch compiles new loop edge. + * First outer compile: expect true branch. + * Second '': hit false branch. + */ + schedule1[0*4 + 3] = 1; + var schedules = [schedule1, + schedule2, + schedule1, + schedule2, + schedule2]; + + for (var i = 0; i < 5; i++) { + c += reallyDeepNestedExit(schedules[i]); + } + return c; +} +assertEq(testReallyDeepNestedExit(), 198); diff --git a/js/src/jit-test/tests/basic/testRebranding.js b/js/src/jit-test/tests/basic/testRebranding.js new file mode 100644 index 000000000..f21fc5c19 --- /dev/null +++ b/js/src/jit-test/tests/basic/testRebranding.js @@ -0,0 +1,10 @@ +q = ""; +function g() { q += "g"; } +function h() { q += "h"; } +a = [g, g, g, g, h]; +for (i=0; i<5; i++) { f = a[i]; f(); } + +function testRebranding() { + return q; +} +assertEq(testRebranding(), "ggggh"); diff --git a/js/src/jit-test/tests/basic/testRebranding2.js b/js/src/jit-test/tests/basic/testRebranding2.js new file mode 100644 index 000000000..7349c4fc0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testRebranding2.js @@ -0,0 +1,21 @@ +delete q; +delete g; +delete h; +delete a; +delete f; + +function testRebranding2() { + // Same as testRebranding, but the object to be rebranded isn't the global. + var x = "FAIL"; + function g(){} + function h(){ x = "ok"; } + var obj = {m: g}; + var arr = [g, g, g, g, h]; + //assertEq(arr.length > 9, true); + for (var i = 0; i < 5; i++) { + obj.m = arr[i]; + obj.m(); + } + return x; +} +assertEq(testRebranding2(), "ok"); diff --git a/js/src/jit-test/tests/basic/testRegExpTest.js b/js/src/jit-test/tests/basic/testRegExpTest.js new file mode 100644 index 000000000..d7121b987 --- /dev/null +++ b/js/src/jit-test/tests/basic/testRegExpTest.js @@ -0,0 +1,10 @@ +// |jit-test| valgrind + +function testRegExpTest() { + var r = /abc/; + var flag = false; + for (var i = 0; i < 10; ++i) + flag = r.test("abc"); + return flag; +} +assertEq(testRegExpTest(), true); diff --git a/js/src/jit-test/tests/basic/testRegexpGet.js b/js/src/jit-test/tests/basic/testRegexpGet.js new file mode 100644 index 000000000..c8900098f --- /dev/null +++ b/js/src/jit-test/tests/basic/testRegexpGet.js @@ -0,0 +1,8 @@ +function testRegexpGet() { + var re = /hi/; + var a = []; + for (let i = 0; i < 5; ++i) + a.push(re.source); + return a.toString(); +} +assertEq(testRegexpGet(), "hi,hi,hi,hi,hi"); diff --git a/js/src/jit-test/tests/basic/testReplace2.js b/js/src/jit-test/tests/basic/testReplace2.js new file mode 100644 index 000000000..20685adf2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testReplace2.js @@ -0,0 +1,7 @@ +function testReplace2() { + var s = "H e l l o", s1; + for (i = 0; i < 100; ++i) + s1 = s.replace(" ", ""); + return s1; +} +assertEq(testReplace2(), "He l l o"); diff --git a/js/src/jit-test/tests/basic/testReplaceMap.js b/js/src/jit-test/tests/basic/testReplaceMap.js new file mode 100644 index 000000000..929f52ce8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testReplaceMap.js @@ -0,0 +1,27 @@ + +// String.replace on functions returning hashmap elements. + +function first() { + var arr = {a: "hello", b: "there"}; + var s = 'a|b'; + return s.replace(/[a-z]/g, function(a) { return arr[a]; }, 'g'); +} +assertEq(first(), "hello|there"); + +function second() { + var arr = {a: "hello", c: "there"}; + var s = 'a|b|c'; + return s.replace(/[a-z]/g, function(a) { return arr[a]; }, 'g'); +} +assertEq(second(), "hello|undefined|there"); + +Object.defineProperty(Object.prototype, "b", {get: function() { return "what"; }}); + +assertEq(second(), "hello|what|there"); + +function third() { + var arr = {a: "hello", b: {toString: function() { arr = {}; return "three"; }}, c: "there"}; + var s = 'a|b|c'; + return s.replace(/[a-z]/g, function(a) { return arr[a]; }, 'g'); +} +assertEq(third(), "hello|three|undefined"); diff --git a/js/src/jit-test/tests/basic/testReplaceWithLambda.js b/js/src/jit-test/tests/basic/testReplaceWithLambda.js new file mode 100644 index 000000000..9aad5ef98 --- /dev/null +++ b/js/src/jit-test/tests/basic/testReplaceWithLambda.js @@ -0,0 +1,52 @@ +// optimized +(function(b) { + assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc'); +})({a:'A', b:'B' }); +(function() { + var b = {a:'A', b:'B' }; + assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc'); +})(); +(function() { + { + let b = {a:'A', b:'B' }; + assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc'); + } +})(); +(function() { + var b = {a:'A', b:'B' }; + (function () { + assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc'); + })(); +})(); +(function() { + { + let b = {a:'A', b:'B' }; + (function () { + assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc'); + })(); + } +})(); +(function() { + var b = {a:'A', b:'B' }; + (function () { + (function () { + assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc'); + })(); + })(); +})(); + +// not optimized: +(function() { + var b = {a:'A', b:'B' }; + with ({}) { + (function () { + assertEq("abc".replace(/a|b/g, function(a) { return b[a] }), 'ABc'); + })(); + } +})(); +(function() { + var b = {a:'A', b:'B' }; + var bad = function() { b = {a:1, b:2}; return 'X' } + Object.defineProperty(b, 'x', {get:bad}); + assertEq("xabc".replace(/x|a|b/g, function(a) { return b[a] }), 'X12c'); +})(); diff --git a/js/src/jit-test/tests/basic/testResumeOp.js b/js/src/jit-test/tests/basic/testResumeOp.js new file mode 100644 index 000000000..2acb18f56 --- /dev/null +++ b/js/src/jit-test/tests/basic/testResumeOp.js @@ -0,0 +1,8 @@ +function testResumeOp() { + var a = [1,"2",3,"4",5,"6",7,"8",9,"10",11,"12",13,"14",15,"16"]; + var x = ""; + while (a.length > 0) + x += a.pop(); + return x; +} +assertEq(testResumeOp(), "16151413121110987654321"); diff --git a/js/src/jit-test/tests/basic/testReverseArgTypes.js b/js/src/jit-test/tests/basic/testReverseArgTypes.js new file mode 100644 index 000000000..f36fed348 --- /dev/null +++ b/js/src/jit-test/tests/basic/testReverseArgTypes.js @@ -0,0 +1,5 @@ +function testReverseArgTypes() { + for (var j = 0; j < 4; ++j) ''.replace('', /x/); + return 1; +} +assertEq(testReverseArgTypes(), 1); diff --git a/js/src/jit-test/tests/basic/testRopeMarking.js b/js/src/jit-test/tests/basic/testRopeMarking.js new file mode 100644 index 000000000..fcf531141 --- /dev/null +++ b/js/src/jit-test/tests/basic/testRopeMarking.js @@ -0,0 +1,13 @@ +for (var i = 0; i < 10; ++i) { + var arr = []; + var s = "abcdefghijklmnop"; + for (var j = 0; j < 5000; ++j) { + s = "<" + s + ">"; + arr.push(s); + } + gc(); + for (var j = 0; j < 5000; ++j) { + arr[j].search("a"); + } + gc(); +} diff --git a/js/src/jit-test/tests/basic/testScriptCloning.js b/js/src/jit-test/tests/basic/testScriptCloning.js new file mode 100644 index 000000000..4099acfb9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testScriptCloning.js @@ -0,0 +1,21 @@ +var g = newGlobal(); + +g.f = new Function('return function(x) { return x };'); +assertEq(g.eval("clone(f)()(9)"), 9); + +g.f = new Function('return function(x) { { let y = x+1; return y } };'); +assertEq(g.eval("clone(f)()(9)"), 10); + +g.f = new Function('return function(x) { { let y = x, z = 1; return y+z } };'); +assertEq(g.eval("clone(f)()(9)"), 10); + +g.f = new Function('return function(x) { return x.search(/ponies/) };'); +assertEq(g.eval("clone(f)()('123ponies')"), 3); + +g.f = new Function('return function(x,y) { return x.search(/a/) + y.search(/b/) };'); +assertEq(g.eval("clone(f)()('12a','foo')"), 1); + +g.f = new Function('return function(x) { switch(x) { case "a": return "b"; case null: return "c" } };'); +assertEq(g.eval("clone(f)()('a')"), "b"); +assertEq(g.eval("clone(f)()(null)"), "c"); +assertEq(g.eval("clone(f)()(3)"), undefined); diff --git a/js/src/jit-test/tests/basic/testScriptGetter_JSOP_CALLPROP-2.js b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_CALLPROP-2.js new file mode 100644 index 000000000..f9899b192 --- /dev/null +++ b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_CALLPROP-2.js @@ -0,0 +1,13 @@ +// Test that the tracer is not confused by a.m() when a is the same shape each +// time through the loop but a.m is a scripted getter that returns different +// functions. + +function f() { return 'f'; } +function g() { return 'g'; } +var arr = [f, f, f, f, f, f, f, f, g]; +var a = {get m() { return arr[i]; }}; + +var s = ''; +for (var i = 0; i < 9; i++) + s += a.m(); +assertEq(s, 'ffffffffg'); diff --git a/js/src/jit-test/tests/basic/testScriptGetter_JSOP_CALLPROP.js b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_CALLPROP.js new file mode 100644 index 000000000..d16895e15 --- /dev/null +++ b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_CALLPROP.js @@ -0,0 +1,9 @@ +var a = {_val: 'q', + get p() { return f; }}; + +function f() { return this._val; } + +var g = ''; +for (var i = 0; i < 9; i++) + g += a.p(); +assertEq(g, 'qqqqqqqqq'); diff --git a/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETARGPROP.js b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETARGPROP.js new file mode 100644 index 000000000..3a865edcf --- /dev/null +++ b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETARGPROP.js @@ -0,0 +1,7 @@ +function test(a) { + var s = ''; + for (var i = 0; i < 9; i++) + s += a.p; + assertEq(s, 'qqqqqqqqq'); +} +test({get p() { return 'q'; }}); diff --git a/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETLOCALPROP.js b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETLOCALPROP.js new file mode 100644 index 000000000..1add26e6e --- /dev/null +++ b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETLOCALPROP.js @@ -0,0 +1,8 @@ +function test() { + var a = {get p() { return 'q'; }}; + var s = ''; + for (var i = 0; i < 9; i++) + s += a.p; + assertEq(s, 'qqqqqqqqq'); +} +test(); diff --git a/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETPROP.js b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETPROP.js new file mode 100644 index 000000000..963c506c4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETPROP.js @@ -0,0 +1,8 @@ +var a = {get p() { return 11; }}; + +function f() { return a; } + +var g = 0; +for (var i = 0; i < 9; i++) + g += f().p; +assertEq(g, 99); diff --git a/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETTHISPROP.js b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETTHISPROP.js new file mode 100644 index 000000000..b878a78ef --- /dev/null +++ b/js/src/jit-test/tests/basic/testScriptGetter_JSOP_GETTHISPROP.js @@ -0,0 +1,9 @@ +var a = { + get p() { return 11; }, + test: function () { + var s = 0; + for (var i = 0; i < 9; i++) + s += this.p; + assertEq(s, 99); + }}; +a.test(); diff --git a/js/src/jit-test/tests/basic/testSetGetterOnlyProperty.js b/js/src/jit-test/tests/basic/testSetGetterOnlyProperty.js new file mode 100644 index 000000000..d08ea7a56 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSetGetterOnlyProperty.js @@ -0,0 +1,5 @@ +var o = { get x() { return 17; } }; +for (var j = 0; j < 5; ++j) + o.x = 42; + +assertEq(true, true); diff --git a/js/src/jit-test/tests/basic/testSetPropNeitherMissNorHit.js b/js/src/jit-test/tests/basic/testSetPropNeitherMissNorHit.js new file mode 100644 index 000000000..906a2c147 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSetPropNeitherMissNorHit.js @@ -0,0 +1,5 @@ +function testSetPropNeitherMissNorHit() { + for (var j = 0; j < 5; ++j) { if (({}).__proto__ = 1) { } } + return "ok"; +} +assertEq(testSetPropNeitherMissNorHit(), "ok"); diff --git a/js/src/jit-test/tests/basic/testSetPropertyFail.js b/js/src/jit-test/tests/basic/testSetPropertyFail.js new file mode 100644 index 000000000..0ca625760 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSetPropertyFail.js @@ -0,0 +1,22 @@ +function test(name, fn, val) { + gc(); + var ok = {}, bad = {}; + bad.__defineSetter__(name, fn); + var arr = [ok, ok, ok, ok, ok, bad]; + + var log = ''; + try { + for (var i = 0; i < arr.length; i++) { + arr[i][name] = val; + log += '.'; + } + } catch (exc) { + log += 'E'; + } + assertEq(log, '.....E'); +} + +test("x", Function.prototype.call, null); // TypeError: Function.prototype.call called on incompatible [object Object] +test("y", Array, 0.1); // RangeError: invalid array length +test(1, Function.prototype.call, null); // TypeError: Function.prototype.call called on incompatible [object Object] +test(1, Array, 0.1); // RangeError: invalid array length diff --git a/js/src/jit-test/tests/basic/testSetProtoRegeneratesObjectShape.js b/js/src/jit-test/tests/basic/testSetProtoRegeneratesObjectShape.js new file mode 100644 index 000000000..1c6e0da3c --- /dev/null +++ b/js/src/jit-test/tests/basic/testSetProtoRegeneratesObjectShape.js @@ -0,0 +1,24 @@ +function testSetProtoRegeneratesObjectShape() +{ + var f = function() {}; + var g = function() {}; + g.prototype.__proto__ = {}; + + function iq(obj) + { + for (var i = 0; i < 10; ++i) + "" + obj.prototype; + } + + iq(f); + iq(f); + iq(f); + iq(f); + iq(g); + + if (shapeOf(f.prototype) === shapeOf(g.prototype)) + return "object shapes same after proto of one is changed"; + + return true; +} +assertEq(testSetProtoRegeneratesObjectShape(), true); diff --git a/js/src/jit-test/tests/basic/testSetelemWithFloatIndex.js b/js/src/jit-test/tests/basic/testSetelemWithFloatIndex.js new file mode 100644 index 000000000..20ec89758 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSetelemWithFloatIndex.js @@ -0,0 +1,4 @@ +var x, a = {}; +for (var i = 0; i < 9; i++) + x = a[-3.5] = "ok"; +assertEq(x, "ok"); diff --git a/js/src/jit-test/tests/basic/testSettingWatchPointOnReadOnlyProp.js b/js/src/jit-test/tests/basic/testSettingWatchPointOnReadOnlyProp.js new file mode 100644 index 000000000..78c281f05 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSettingWatchPointOnReadOnlyProp.js @@ -0,0 +1,7 @@ +for (var i = 0; i < 5; ++i) { + var o = {} + Object.defineProperty(o, 'x', { value:"cow", writable:false }); + var r = o.watch('x', function() {}); + assertEq(r, undefined); + o.x = 4; +} diff --git a/js/src/jit-test/tests/basic/testShiftLeft.js b/js/src/jit-test/tests/basic/testShiftLeft.js new file mode 100644 index 000000000..4cc78f5ea --- /dev/null +++ b/js/src/jit-test/tests/basic/testShiftLeft.js @@ -0,0 +1,38 @@ +// |jit-test| valgrind + +/* Test the proper operation of the left shift operator. This is especially + * important on ARM as an explicit mask is required at the native instruction + * level. */ + +load(libdir + 'range.js'); + +function testShiftLeft() +{ + var r = []; + var i = 0; + var j = 0; + + var shifts = [0,1,7,8,15,16,23,24,31]; + + /* Samples from the simple shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = 1 << shifts[i]; + + /* Samples outside the normal shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = 1 << (shifts[i] + 32); + + /* Samples far outside the normal shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = 1 << (shifts[i] + 224); + for (i = 0; i < shifts.length; i++) + r[j++] = 1 << (shifts[i] + 256); + + return r.join(","); +} + +assertEq(testShiftLeft(), + "1,2,128,256,32768,65536,8388608,16777216,-2147483648,"+ + "1,2,128,256,32768,65536,8388608,16777216,-2147483648,"+ + "1,2,128,256,32768,65536,8388608,16777216,-2147483648,"+ + "1,2,128,256,32768,65536,8388608,16777216,-2147483648"); diff --git a/js/src/jit-test/tests/basic/testShiftRightArithmetic.js b/js/src/jit-test/tests/basic/testShiftRightArithmetic.js new file mode 100644 index 000000000..7268dc0ba --- /dev/null +++ b/js/src/jit-test/tests/basic/testShiftRightArithmetic.js @@ -0,0 +1,44 @@ +/* Test the proper operation of the arithmetic right shift operator. This is + * especially important on ARM as an explicit mask is required at the native + * instruction level. */ + +load(libdir + 'range.js'); + +/* Test different combinations of literals/variables. */ +var s = 4; +var t = 100; +assertEq(42 >> s, 2); +assertEq(s >> 1, 2); +assertEq(23 >> 3, 2); +assertEq(t >> s, 6); + + +function testShiftRightArithmetic() +{ + var r = []; + var i = 0; + var j = 0; + + var shifts = [0,1,7,8,15,16,23,24,31]; + + /* Samples from the simple shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = -2147483648 >> shifts[i]; + + /* Samples outside the normal shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = -2147483648 >> (shifts[i] + 32); + + /* Samples far outside the normal shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = -2147483648 >> (shifts[i] + 224); + for (i = 0; i < shifts.length; i++) + r[j++] = -2147483648 >> (shifts[i] + 256); + + return r.join(","); +} +assertEq(testShiftRightArithmetic(), + "-2147483648,-1073741824,-16777216,-8388608,-65536,-32768,-256,-128,-1,"+ + "-2147483648,-1073741824,-16777216,-8388608,-65536,-32768,-256,-128,-1,"+ + "-2147483648,-1073741824,-16777216,-8388608,-65536,-32768,-256,-128,-1,"+ + "-2147483648,-1073741824,-16777216,-8388608,-65536,-32768,-256,-128,-1"); diff --git a/js/src/jit-test/tests/basic/testShiftRightLogical.js b/js/src/jit-test/tests/basic/testShiftRightLogical.js new file mode 100644 index 000000000..de2dda6f2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testShiftRightLogical.js @@ -0,0 +1,38 @@ +/* Test the proper operation of the logical right shift operator. This is + * especially important on ARM as an explicit mask is required at the native + * instruction level. */ + +load(libdir + 'range.js'); + +function testShiftRightLogical() +{ + var r = []; + var i = 0; + var j = 0; + + var shifts = [0,1,7,8,15,16,23,24,31]; + + /* Samples from the simple shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = -2147483648 >>> shifts[i]; + + /* Samples outside the normal shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = -2147483648 >>> (shifts[i] + 32); + + /* Samples far outside the normal shift range. */ + for (i = 0; i < shifts.length; i++) + r[j++] = -2147483648 >>> (shifts[i] + 224); + for (i = 0; i < shifts.length; i++) + r[j++] = -2147483648 >>> (shifts[i] + 256); + + return r.join(","); +} +/* Note: Arguments to the ">>>" operator are converted to unsigned 32-bit + * integers during evaluation. As a result, -2147483648 >>> 0 evaluates to the + * unsigned interpretation of the same value, which is 2147483648. */ +assertEq(testShiftRightLogical(), + "2147483648,1073741824,16777216,8388608,65536,32768,256,128,1,"+ + "2147483648,1073741824,16777216,8388608,65536,32768,256,128,1,"+ + "2147483648,1073741824,16777216,8388608,65536,32768,256,128,1,"+ + "2147483648,1073741824,16777216,8388608,65536,32768,256,128,1"); diff --git a/js/src/jit-test/tests/basic/testSlowArrayLength.js b/js/src/jit-test/tests/basic/testSlowArrayLength.js new file mode 100644 index 000000000..f19ec4bfa --- /dev/null +++ b/js/src/jit-test/tests/basic/testSlowArrayLength.js @@ -0,0 +1,10 @@ +function testSlowArrayLength() +{ + var counter = 0; + var a = []; + a[10000 - 1] = 0; + for (var i = 0; i < a.length; i++) + counter++; + return counter; +} +assertEq(testSlowArrayLength(), 10000); diff --git a/js/src/jit-test/tests/basic/testSlowArrayPop.js b/js/src/jit-test/tests/basic/testSlowArrayPop.js new file mode 100644 index 000000000..f3602aa09 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSlowArrayPop.js @@ -0,0 +1,12 @@ +function testSlowArrayPop() { + var a = []; + for (var i = 0; i < 9; i++) + a[i] = [0]; + a[8].__defineGetter__("0", function () { return 'xyzzy'; }); + + var last; + for (var i = 0; i < 9; i++) + last = a[i].pop(); // reenters interpreter in getter + return last; +} +assertEq(testSlowArrayPop(), 'xyzzy'); diff --git a/js/src/jit-test/tests/basic/testSlowArrayPopMultiFrame.js b/js/src/jit-test/tests/basic/testSlowArrayPopMultiFrame.js new file mode 100644 index 000000000..a1917ff64 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSlowArrayPopMultiFrame.js @@ -0,0 +1,24 @@ +// Same thing but it needs to reconstruct multiple stack frames (so, +// multiple functions called inside the loop) +function testSlowArrayPopMultiFrame() { + var a = []; + for (var i = 0; i < 9; i++) + a[i] = [0]; + a[8].__defineGetter__("0", function () { return 23; }); + + function child(a, i) { + return a[i].pop(); // reenters interpreter in getter + } + function parent(a, i) { + return child(a, i); + } + function gramps(a, i) { + return parent(a, i); + } + + var last; + for (var i = 0; i < 9; i++) + last = gramps(a, i); + return last; +} +assertEq(testSlowArrayPopMultiFrame(), 23); diff --git a/js/src/jit-test/tests/basic/testSlowArrayPopNestedTrees.js b/js/src/jit-test/tests/basic/testSlowArrayPopNestedTrees.js new file mode 100644 index 000000000..0ad4dbaae --- /dev/null +++ b/js/src/jit-test/tests/basic/testSlowArrayPopNestedTrees.js @@ -0,0 +1,36 @@ +// Same thing but nested trees, each reconstructing one or more stack frames +// (so, several functions with loops, such that the loops end up being +// nested though they are not lexically nested) + +function testSlowArrayPopNestedTrees() { + var a = []; + for (var i = 0; i < 9; i++) + a[i] = [0]; + a[8].__defineGetter__("0", function () { return 3.14159 }); + + function child(a, i, j, k) { + var last = 2.71828; + for (var l = 0; l < 9; l++) + if (i == 8 && j == 8 && k == 8) + last = a[l].pop(); // reenters interpreter in getter + return last; + } + function parent(a, i, j) { + var last; + for (var k = 0; k < 9; k++) + last = child(a, i, j, k); + return last; + } + function gramps(a, i) { + var last; + for (var j = 0; j < 9; j++) + last = parent(a, i, j); + return last; + } + + var last; + for (var i = 0; i < 9; i++) + last = gramps(a, i); + return last; +} +assertEq(testSlowArrayPopNestedTrees(), 3.14159); diff --git a/js/src/jit-test/tests/basic/testSlowNativeBail.js b/js/src/jit-test/tests/basic/testSlowNativeBail.js new file mode 100644 index 000000000..07def4543 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSlowNativeBail.js @@ -0,0 +1,11 @@ +function testSlowNativeBail() { + var a = ['0', '1', '2', '3', '+']; + try { + for (var i = 0; i < a.length; i++) + new RegExp(a[i]); + assertEq(true, false); + } catch (exc) { + assertEq(exc instanceof SyntaxError, true); + } +} +testSlowNativeBail(); diff --git a/js/src/jit-test/tests/basic/testSlowNativeCtor.js b/js/src/jit-test/tests/basic/testSlowNativeCtor.js new file mode 100644 index 000000000..345546a72 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSlowNativeCtor.js @@ -0,0 +1,7 @@ +delete _quit; + +function testSlowNativeCtor() { + for (var i = 0; i < 4; i++) + new Date().valueOf(); +} +testSlowNativeCtor(); diff --git a/js/src/jit-test/tests/basic/testSlowNativeWithNullThis.js b/js/src/jit-test/tests/basic/testSlowNativeWithNullThis.js new file mode 100644 index 000000000..b90b4f10d --- /dev/null +++ b/js/src/jit-test/tests/basic/testSlowNativeWithNullThis.js @@ -0,0 +1,6 @@ +x = 0 +for (a = 0; a < 3; a++) { + new ((function () { + return Float64Array + })())(x, 1) +} diff --git a/js/src/jit-test/tests/basic/testStaticEvalScope.js b/js/src/jit-test/tests/basic/testStaticEvalScope.js new file mode 100644 index 000000000..6850f3bf4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testStaticEvalScope.js @@ -0,0 +1,3 @@ +// Test that static eval scopes don't mess with statement nested scope logic in +// the frontend. +eval("if (true) { { let y; } } else {}") diff --git a/js/src/jit-test/tests/basic/testStaticsInRegExp.js b/js/src/jit-test/tests/basic/testStaticsInRegExp.js new file mode 100644 index 000000000..16d869874 --- /dev/null +++ b/js/src/jit-test/tests/basic/testStaticsInRegExp.js @@ -0,0 +1,8 @@ +'abcdef'.replace(/a(\w+)c/, function() { + assertEq(RegExp.lastMatch, 'abc'); + '123456'.replace(/1(\d+)3/, function() { + assertEq(RegExp.lastMatch, '123'); + }); + assertEq(RegExp.lastMatch, '123'); +}); +assertEq(RegExp.lastMatch, '123'); diff --git a/js/src/jit-test/tests/basic/testStrict.js b/js/src/jit-test/tests/basic/testStrict.js new file mode 100644 index 000000000..583a2b065 --- /dev/null +++ b/js/src/jit-test/tests/basic/testStrict.js @@ -0,0 +1,11 @@ +function testStrict() { + var n = 10, a = []; + for (var i = 0; i < 10; ++i) { + a[0] = (n === 10); + a[1] = (n !== 10); + a[2] = (n === null); + a[3] = (n == null); + } + return a.join(","); +} +assertEq(testStrict(), "true,false,false,false"); diff --git a/js/src/jit-test/tests/basic/testString.js b/js/src/jit-test/tests/basic/testString.js new file mode 100644 index 000000000..cb7e1e5b3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testString.js @@ -0,0 +1,14 @@ +function testString() { + var q; + for (var i = 0; i <= 9; ++i) { + q = []; + q.push(String(void 0)); + q.push(String(true)); + q.push(String(5)); + q.push(String(5.5)); + q.push(String("5")); + q.push(String([5])); + } + return q.join(","); +} +assertEq(testString(), "undefined,true,5,5.5,5,5"); diff --git a/js/src/jit-test/tests/basic/testStringBufferMallocAccounting.js b/js/src/jit-test/tests/basic/testStringBufferMallocAccounting.js new file mode 100644 index 000000000..e016f3b6b --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringBufferMallocAccounting.js @@ -0,0 +1,18 @@ +// first build a big honkin' string +str = "a"; +for (var i = 0; i < 20; ++i) + str = str + str; +str.indexOf('a'); + +var f; +f = makeFinalizeObserver(); +assertEq(finalizeCount(), 0); + +// Create another observer to make sure that we overwrite all conservative +// roots for the previous one and can observer the GC. +f = makeFinalizeObserver(); + +// if the assert fails, add more iterations +for (var i = 0; i < 80; ++i) + str.replace(/(a)/, '$1'); +//assertEq(finalizeCount(), 1); diff --git a/js/src/jit-test/tests/basic/testStringConstructorWithExtraArg.js b/js/src/jit-test/tests/basic/testStringConstructorWithExtraArg.js new file mode 100644 index 000000000..b4986c53f --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringConstructorWithExtraArg.js @@ -0,0 +1,6 @@ +function testStringConstructorWithExtraArg() { + for (let i = 0; i < 5; ++i) + new String(new String(), 2); + return "ok"; +} +assertEq(testStringConstructorWithExtraArg(), "ok"); diff --git a/js/src/jit-test/tests/basic/testStringIncrement.js b/js/src/jit-test/tests/basic/testStringIncrement.js new file mode 100644 index 000000000..b0cc6775e --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringIncrement.js @@ -0,0 +1,20 @@ +var a, b; + +function f(str) { + var n; + var k; + for (var i = 0; i < 18; ++i) { + n = str; + k = n++; + if (k) { } + } + return [k, n]; +} + +[a, b] = f("10"); +assertEq(a, 10); +assertEq(b, 11); + +[a, b] = f("5"); +assertEq(a, 5); +assertEq(b, 6); diff --git a/js/src/jit-test/tests/basic/testStringLengthNoTinyId.js b/js/src/jit-test/tests/basic/testStringLengthNoTinyId.js new file mode 100644 index 000000000..e08f5a697 --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringLengthNoTinyId.js @@ -0,0 +1,64 @@ +// Second testPropagatedFunArgs test -- this is a crash-test. +(function () { + var escapee; + + function testPropagatedFunArgs() + { + const magic = 42; + + var win = this; + var res = [], q = []; + function addEventListener(name, func, flag) { + q.push(func); + } + + var pageInfo = "pageInfo", obs; + addEventListener("load", handleLoad, true); + + var observer = { + observe: function(win, topic, data) { + // obs.removeObserver(observer, "page-info-dialog-loaded"); + handlePageInfo(); + } + }; + + function handleLoad() { + //pageInfo = { toString: function() { return "pageInfo"; } }; + obs = { addObserver: function (obs, topic, data) { obs.observe(win, topic, data); } }; + obs.addObserver(observer, "page-info-dialog-loaded", false); + } + + function handlePageInfo() { + res.push(pageInfo); + function $(aId) { + function notSafe() { + return magic; + } + notSafe(); + res.push(pageInfo); + }; + var feedTab = $("feedTab"); + } + + escapee = q[0]; + return res.join(','); + } + + testPropagatedFunArgs(); + + escapee(); +})(); + +function testStringLengthNoTinyId() +{ + var x = "unset"; + var t = new String(""); + for (var i = 0; i < 5; i++) + x = t["-1"]; + + var r = "t['-1'] is " + x; + t["-1"] = "foo"; + r += " when unset, '" + t["-1"] + "' when set"; + return r; +} +assertEq(testStringLengthNoTinyId(), "t['-1'] is undefined when unset, 'foo' when set"); diff --git a/js/src/jit-test/tests/basic/testStringObjectLength.js b/js/src/jit-test/tests/basic/testStringObjectLength.js new file mode 100644 index 000000000..d908ff63a --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringObjectLength.js @@ -0,0 +1,7 @@ +function testStringObjectLength() { + var x = new String("foo"), y = 0; + for (var i = 0; i < 10; ++i) + y = x.length; + return y; +} +assertEq(testStringObjectLength(), 3); diff --git a/js/src/jit-test/tests/basic/testStringResolve.js b/js/src/jit-test/tests/basic/testStringResolve.js new file mode 100644 index 000000000..348087b18 --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringResolve.js @@ -0,0 +1,9 @@ +function testStringResolve() { + var x = 0; + for each (let d in [new String('q'), new String('q'), new String('q')]) { + if (("" + (0 in d)) === "true") + x++; + } + return x; +} +assertEq(testStringResolve(), 3); diff --git a/js/src/jit-test/tests/basic/testStringToInt32.js b/js/src/jit-test/tests/basic/testStringToInt32.js new file mode 100644 index 000000000..ca1ca349f --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringToInt32.js @@ -0,0 +1,6 @@ +function testStringToInt32() { + var s = ""; + for (let j = 0; j < 5; ++j) s += ("1e+81" ^ 3); + return s; +} +assertEq(testStringToInt32(), "33333"); diff --git a/js/src/jit-test/tests/basic/testStringToNumber.js b/js/src/jit-test/tests/basic/testStringToNumber.js new file mode 100644 index 000000000..7f7aa5726 --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringToNumber.js @@ -0,0 +1,37 @@ +enableOsiPointRegisterChecks(); + +function convertToInt(str) { + return str | 0; +} + +function convertToIntOnTrace(str) { + var z; + for (var i = 0; i < 9; ++i) { + z = str | 0; + } + return z; +} + +function convertToDouble(str) { + return str * 1.5; +} + +function convertToDoubleOnTrace(str) { + var z; + for (var i = 0; i < 9; ++i) { + z = str * 1.5; + } + return z; +} + +assertEq(convertToInt("0x10"), 16); +assertEq(convertToInt("-0x10"), 0); + +assertEq(convertToIntOnTrace("0x10"), 16); +assertEq(convertToIntOnTrace("-0x10"), 0); + +assertEq(convertToDouble("0x10"), 24); +assertEq(convertToDouble("-0x10"), NaN); + +assertEq(convertToDoubleOnTrace("0x10"), 24); +assertEq(convertToDoubleOnTrace("-0x10"), NaN); diff --git a/js/src/jit-test/tests/basic/testStringify.js b/js/src/jit-test/tests/basic/testStringify.js new file mode 100644 index 000000000..003e4fd38 --- /dev/null +++ b/js/src/jit-test/tests/basic/testStringify.js @@ -0,0 +1,20 @@ +function testStringify() { + var t = true, f = false, u = undefined, n = 5, d = 5.5, s = "x"; + var a = []; + for (var i = 0; i < 10; ++i) { + a[0] = "" + t; + a[1] = t + ""; + a[2] = "" + f; + a[3] = f + ""; + a[4] = "" + u; + a[5] = u + ""; + a[6] = "" + n; + a[7] = n + ""; + a[8] = "" + d; + a[9] = d + ""; + a[10] = "" + s; + a[11] = s + ""; + } + return a.join(","); +} +assertEq(testStringify(), "true,true,false,false,undefined,undefined,5,5,5.5,5.5,x,x"); diff --git a/js/src/jit-test/tests/basic/testSubstring.js b/js/src/jit-test/tests/basic/testSubstring.js new file mode 100644 index 000000000..5916c23ab --- /dev/null +++ b/js/src/jit-test/tests/basic/testSubstring.js @@ -0,0 +1,7 @@ +function testSubstring() { + for (var i = 0; i < 5; ++i) { + actual = "".substring(5); + } + return actual; +} +assertEq(testSubstring(), ""); diff --git a/js/src/jit-test/tests/basic/testSuppressDeletedProperty.js b/js/src/jit-test/tests/basic/testSuppressDeletedProperty.js new file mode 100644 index 000000000..a867b35d2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSuppressDeletedProperty.js @@ -0,0 +1,8 @@ +var obj = { a:1, b:1, c:1, d:1, e:1, f:1, g:1 }; +var sum = 0; +for each (var i in obj) { + sum += i; + delete obj.f; +} + +// this isn't even implemented to work yet; just don't crash or iloop diff --git a/js/src/jit-test/tests/basic/testSwitch.js b/js/src/jit-test/tests/basic/testSwitch.js new file mode 100644 index 000000000..c2127d4a6 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSwitch.js @@ -0,0 +1,25 @@ +function testSwitch() { + var x = 0; + var ret = 0; + for (var i = 0; i < 100; ++i) { + switch (x) { + case 0: + ret += 1; + break; + case 1: + ret += 2; + break; + case 2: + ret += 3; + break; + case 3: + ret += 4; + break; + default: + x = 0; + } + x++; + } + return ret; +} +assertEq(testSwitch(), 226); diff --git a/js/src/jit-test/tests/basic/testSwitchString.js b/js/src/jit-test/tests/basic/testSwitchString.js new file mode 100644 index 000000000..323763a3f --- /dev/null +++ b/js/src/jit-test/tests/basic/testSwitchString.js @@ -0,0 +1,28 @@ +function testSwitchString() { + var x = "asdf"; + var ret = 0; + for (var i = 0; i < 100; ++i) { + switch (x) { + case "asdf": + x = "asd"; + ret += 1; + break; + case "asd": + x = "as"; + ret += 2; + break; + case "as": + x = "a"; + ret += 3; + break; + case "a": + x = "foo"; + ret += 4; + break; + default: + x = "asdf"; + } + } + return ret; +} +assertEq(testSwitchString(), 200); diff --git a/js/src/jit-test/tests/basic/testSwitchUndefined.js b/js/src/jit-test/tests/basic/testSwitchUndefined.js new file mode 100644 index 000000000..44d27ca38 --- /dev/null +++ b/js/src/jit-test/tests/basic/testSwitchUndefined.js @@ -0,0 +1,15 @@ +function testSwitchUndefined() +{ + var x = undefined; + var y = 0; + for (var i = 0; i < 5; i++) + { + switch (x) + { + default: + y++; + } + } + return y; +} +assertEq(testSwitchUndefined(), 5); diff --git a/js/src/jit-test/tests/basic/testTableSwitch1.js b/js/src/jit-test/tests/basic/testTableSwitch1.js new file mode 100644 index 000000000..db212c0de --- /dev/null +++ b/js/src/jit-test/tests/basic/testTableSwitch1.js @@ -0,0 +1,13 @@ +function testTableSwitch1() { + var x = 'miss'; + var i, j = 0; + for (i = 0; i < 19; i++) { + switch (x) { + case 1: case 2: case 3: case 4: case 5: throw "FAIL"; + default: j++; + } + } + assertEq(i, j); +} + +testTableSwitch1(); diff --git a/js/src/jit-test/tests/basic/testTableSwitch2.js b/js/src/jit-test/tests/basic/testTableSwitch2.js new file mode 100644 index 000000000..8953aa2eb --- /dev/null +++ b/js/src/jit-test/tests/basic/testTableSwitch2.js @@ -0,0 +1,18 @@ +function testTableSwitch2() { + var arr = [2, 2, 2, 2, 2, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5]; + var s = ''; + for (var i = 0; i < arr.length; i++) { + switch (arr[i]) { + case 0: case 1: case 3: case 4: + throw "FAIL"; + case 2: + s += '2'; + break; + case 5: + s += '5'; + } + } + assertEq(s, arr.join("")); +} + +testTableSwitch2(); diff --git a/js/src/jit-test/tests/basic/testThatGenExpsActuallyDecompile.js b/js/src/jit-test/tests/basic/testThatGenExpsActuallyDecompile.js new file mode 100644 index 000000000..1f309b962 --- /dev/null +++ b/js/src/jit-test/tests/basic/testThatGenExpsActuallyDecompile.js @@ -0,0 +1,4 @@ +// |jit-test| error: 3 +var str = (function (x) {return (i for (i in x));}).toSource().replace('\n', ''); +assertEq(str, "(function (x) {return (i for (i in x));})"); +throw 3; diff --git a/js/src/jit-test/tests/basic/testThinForEach.js b/js/src/jit-test/tests/basic/testThinForEach.js new file mode 100644 index 000000000..85e5ca2d3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testThinForEach.js @@ -0,0 +1,10 @@ +function testThinForEach() { + var a = ["red"]; + var n = 0; + for (var i = 0; i < 10; i++) + for each (var v in a) + if (v) + n++; + return n; +} +assertEq(testThinForEach(), 10); diff --git a/js/src/jit-test/tests/basic/testThinLoopDemote.js b/js/src/jit-test/tests/basic/testThinLoopDemote.js new file mode 100644 index 000000000..b26c460a7 --- /dev/null +++ b/js/src/jit-test/tests/basic/testThinLoopDemote.js @@ -0,0 +1,13 @@ +function testThinLoopDemote() { + function f() + { + var k = 1; + for (var n = 0; n < 4; n++) { + k = (k * 10); + } + return k; + } + f(); + return f(); +} +assertEq(testThinLoopDemote(), 10000); diff --git a/js/src/jit-test/tests/basic/testThrowWhileWrappingException.js b/js/src/jit-test/tests/basic/testThrowWhileWrappingException.js new file mode 100644 index 000000000..51169339a --- /dev/null +++ b/js/src/jit-test/tests/basic/testThrowWhileWrappingException.js @@ -0,0 +1,7 @@ +var caught = false; +try { + evalcx("eval(\"throw<x/>\")", Function.a) +} catch (e) { + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/basic/testThrowingObjectEqUndefined.js b/js/src/jit-test/tests/basic/testThrowingObjectEqUndefined.js new file mode 100644 index 000000000..5104c52ee --- /dev/null +++ b/js/src/jit-test/tests/basic/testThrowingObjectEqUndefined.js @@ -0,0 +1,15 @@ +function testThrowingObjectEqUndefined() +{ + try + { + var obj = { toString: function() { throw 0; } }; + for (var i = 0; i < 5; i++) + "" + (obj == undefined); + return i === 5; + } + catch (e) + { + return "" + e; + } +} +assertEq(testThrowingObjectEqUndefined(), true); diff --git a/js/src/jit-test/tests/basic/testToLocaleString.js b/js/src/jit-test/tests/basic/testToLocaleString.js new file mode 100644 index 000000000..158e08b46 --- /dev/null +++ b/js/src/jit-test/tests/basic/testToLocaleString.js @@ -0,0 +1,2 @@ +var str = (3.14).toLocaleString(); +assertEq(str[str.length-1], "4");
\ No newline at end of file diff --git a/js/src/jit-test/tests/basic/testToStringBeforeValueOf.js b/js/src/jit-test/tests/basic/testToStringBeforeValueOf.js new file mode 100644 index 000000000..b3550371e --- /dev/null +++ b/js/src/jit-test/tests/basic/testToStringBeforeValueOf.js @@ -0,0 +1,9 @@ +function testToStringBeforeValueOf() +{ + var o = {toString: function() { return "s"; }, valueOf: function() { return "v"; } }; + var a = []; + for (var i = 0; i < 10; i++) + a.push(String(o)); + return a.join(","); +} +assertEq(testToStringBeforeValueOf(), "s,s,s,s,s,s,s,s,s,s"); diff --git a/js/src/jit-test/tests/basic/testToUpperToLower.js b/js/src/jit-test/tests/basic/testToUpperToLower.js new file mode 100644 index 000000000..4bd78f353 --- /dev/null +++ b/js/src/jit-test/tests/basic/testToUpperToLower.js @@ -0,0 +1,9 @@ +function testToUpperToLower() { + var s = "Hello", s1, s2; + for (i = 0; i < 100; ++i) { + s1 = s.toLowerCase(); + s2 = s.toUpperCase(); + } + return s1 + s2; +} +assertEq(testToUpperToLower(), "helloHELLO"); diff --git a/js/src/jit-test/tests/basic/testTrueShiftTrue.js b/js/src/jit-test/tests/basic/testTrueShiftTrue.js new file mode 100644 index 000000000..44c1290d8 --- /dev/null +++ b/js/src/jit-test/tests/basic/testTrueShiftTrue.js @@ -0,0 +1,16 @@ +// Test no assert or crash from outer recorders (bug 465145) +function testBug465145() { + this.__defineSetter__("x", function(){}); + this.watch("x", function(){}); + y = this; + for (var z = 0; z < 2; ++z) { x = y }; + this.__defineSetter__("x", function(){}); + for (var z = 0; z < 2; ++z) { x = y }; +} + +function testTrueShiftTrue() { + var a = new Array(5); + for (var i=0;i<5;++i) a[i] = "" + (true << true); + return a.join(","); +} +assertEq(testTrueShiftTrue(), "2,2,2,2,2"); diff --git a/js/src/jit-test/tests/basic/testTruncatedMod.js b/js/src/jit-test/tests/basic/testTruncatedMod.js new file mode 100644 index 000000000..61789417c --- /dev/null +++ b/js/src/jit-test/tests/basic/testTruncatedMod.js @@ -0,0 +1,18 @@ +var f = function(i,j) { return i%j|0 }; +assertEq(f(10, 0), 0); +var f = function(i,j) { return i%j|0 }; +assertEq(f(0, 0), 0); +var f = function(i,j) { return i%j|0 }; +assertEq(f(-Math.pow(2,31), -1), 0); +var f = function(i,j) { return i%j|0 }; +assertEq(f(-4, 4), 0); + +var f = function(i) { return i%4|0 }; +assertEq(f(-4), 0); +var f = function(i) { return i%4|0 }; +assertEq(f(0), 0); + +var f = function(i) { return i%3|0 }; +assertEq(f(-3), 0); +var f = function(i) { return i%3|0 }; +assertEq(f(0), 0); diff --git a/js/src/jit-test/tests/basic/testTypeUnstableForIn.js b/js/src/jit-test/tests/basic/testTypeUnstableForIn.js new file mode 100644 index 000000000..0f6b10be4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypeUnstableForIn.js @@ -0,0 +1,10 @@ +function testTypeUnstableForIn() { + var a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; + var x = 0; + for (var i in a) { + i = parseInt(i); + x++; + } + return x; +} +assertEq(testTypeUnstableForIn(), 16); diff --git a/js/src/jit-test/tests/basic/testTypedArrayByteRegs.js b/js/src/jit-test/tests/basic/testTypedArrayByteRegs.js new file mode 100644 index 000000000..09c6d320b --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrayByteRegs.js @@ -0,0 +1,30 @@ +// Uint8Array and Int8Array need single byte registers. +// Test for id and value having the same backing. +function f() { + var x = new Uint8Array(30); + for (var i=0; i<x.length; i++) { + x[i] = i; + } + + var res = 0; + for (var i=0; i<x.length; i++) { + res += x[i]; + } + assertEq(res, 435); +} +f(); + +// Test for id and value having a different backing. +function g() { + var x = new Int8Array(30); + for (var i=1; i<x.length; i++) { + x[i-1] = i; + } + + var res = 0; + for (var i=0; i<x.length; i++) { + res += x[i]; + } + assertEq(res, 435); +} +g(); diff --git a/js/src/jit-test/tests/basic/testTypedArrayClamping.js b/js/src/jit-test/tests/basic/testTypedArrayClamping.js new file mode 100644 index 000000000..58015edbe --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrayClamping.js @@ -0,0 +1,41 @@ +function f() { + var input = []; + var expected = []; + + var add = function(inp, exp) { + input.push(inp); + expected.push(exp); + }; + + add(-0, 0); + add(-0.1, 0); + add(-0.7, 0); + add(0.1, 0); + add(NaN, 0); + add(-Infinity, 0); + add(Infinity, 255); + add(0.7, 1); + add(1.2, 1); + add(3.5, 4); + add(4.5, 4); + add(254.4, 254); + add(254.5, 254); + add(254.6, 255); + add(254.9, 255); + add(255.1, 255); + add(255.4, 255); + add(255.5, 255); + add(255.9, 255); + + var len = input.length; + var a = new Uint8ClampedArray(len); + + for (var i=0; i<len; i++) { + a[i] = input[i]; + } + for (var i=0; i<len; i++) { + assertEq(a[i], expected[i], "Failed: " + input[i]); + } +} +f(); +f(); diff --git a/js/src/jit-test/tests/basic/testTypedArrayInit.js b/js/src/jit-test/tests/basic/testTypedArrayInit.js new file mode 100644 index 000000000..1d85017d1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrayInit.js @@ -0,0 +1,25 @@ +// Arrays should be initialized to zero + +function f() { + for (var ctor of [ Int8Array, + Uint8Array, + Uint8ClampedArray, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array ]) + { + for (var len of [ 3, 30, 300, 3000, 30000 ]) { + var arr = new ctor(len); + for (var i = 0; i < arr.length; i++) + assertEq(arr[i], 0, "index " + i + " of " + ctor.name + " len " + len); + } + } +} + +f(); +f(); +gc() +f(); diff --git a/js/src/jit-test/tests/basic/testTypedArrayMaybeUndefined.js b/js/src/jit-test/tests/basic/testTypedArrayMaybeUndefined.js new file mode 100644 index 000000000..e2dc94192 --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrayMaybeUndefined.js @@ -0,0 +1,46 @@ +// Testing GETELEM and SETELEM on a typed array where the +// type set of the object may include undefined or other +// primitive types. + +// Argument x has type {void, double, Uint16Array}. +function testSet(x) { + var y = 0; + for (var i=0; i<40; i++) { + x[i] = 3; + } + return x[10]; +} + +// Argument x has type {void, int32, Uint16Array}. +function testGet(x) { + var y = 0; + for (var i=0; i<40; i++) { + y += x[i]; + } + return y; +} + +var arr = new Uint16Array(40); +assertEq(testSet(arr), 3); +try { + testSet(undefined); +} catch(e) { + assertEq(e instanceof TypeError, true); +} +try { + testSet(4.5); +} catch(e) { + assertEq(e instanceof TypeError, true); +} + +assertEq(testGet(arr), 120); +try { + testGet(undefined); +} catch(e) { + assertEq(e instanceof TypeError, true); +} +try { + testGet(12345); +} catch(e) { + assertEq(e instanceof TypeError, true); +} diff --git a/js/src/jit-test/tests/basic/testTypedArrayOutOfBounds.js b/js/src/jit-test/tests/basic/testTypedArrayOutOfBounds.js new file mode 100644 index 000000000..8c2d85441 --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrayOutOfBounds.js @@ -0,0 +1,32 @@ +function f1() { + var a = new Int32Array(50); + for (var i=0; i<100; i++) { + var x = a[i]; + assertEq(typeof x, i < a.length ? "number" : "undefined"); + } + + var b = new Float32Array(50); + for (var i=0; i<100; i++) { + var x = b[i]; + assertEq(typeof x, i < b.length ? "number" : "undefined"); + } +} +f1(); + +function f2() { + // Test that values on the prototype are ignored, + // even for OOB accesses. This behavior is new + // with ECMA 6 (see bug 829896). + Object.prototype[50] = 4.4; + Object.prototype[55] = Math; + + var a = new Int16Array(50); + for (var i=0; i<100; i++) { + var x = a[i]; + if (i < a.length) + assertEq(x, 0); + else + assertEq(x, undefined); + } +} +f2(); diff --git a/js/src/jit-test/tests/basic/testTypedArrayPunning.js b/js/src/jit-test/tests/basic/testTypedArrayPunning.js new file mode 100644 index 000000000..59f6b744f --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrayPunning.js @@ -0,0 +1,42 @@ +function testNonCanonicalNan() +{ + const bytes = 128; + var buf = new ArrayBuffer(bytes); + + /* create an array of non-canonical double nans */ + var ui8arr = new Uint8Array(buf); + for (var i = 0; i < ui8arr.length; ++i) + ui8arr[i] = 0xff; + + var dblarr = new Float64Array(buf); + assertEq(dblarr.length, bytes / 8); + + /* ensure they are canonicalized */ + for (var i = 0; i < dblarr.length; ++i) { + var asstr = dblarr[i] + ""; + var asnum = dblarr[i] + 0.0; + assertEq(asstr, "NaN"); + assertEq(asnum, NaN); + } + + /* create an array of non-canonical float nans */ + for (var i = 0; i < ui8arr.length; i += 4) { + ui8arr[i+0] = 0xffff; + ui8arr[i+1] = 0xffff; + ui8arr[i+2] = 0xffff; + ui8arr[i+3] = 0xffff; + } + + var fltarr = new Float32Array(buf); + assertEq(fltarr.length, bytes / 4); + + /* ensure they are canonicalized */ + for (var i = 0; i < fltarr.length; ++i) { + var asstr = fltarr[i] + ""; + var asnum = fltarr[i] + 0.0; + assertEq(asstr, "NaN"); + assertEq(asnum, NaN); + } +} + +testNonCanonicalNan(); diff --git a/js/src/jit-test/tests/basic/testTypedArraySetConversion.js b/js/src/jit-test/tests/basic/testTypedArraySetConversion.js new file mode 100644 index 000000000..c50cf236d --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArraySetConversion.js @@ -0,0 +1,15 @@ +var n = 16;
+var a = new Int32Array(n);
+for (var i = 0; i < n; ++i) {
+ a[i] = i;
+}
+var b = new Int32Array(n);
+for (var i = 0; i < n; ++i) {
+ b[i] = i * 2;
+}
+
+a.set(b, 0.99);
+
+for (var i = 0; i < n; ++i) {
+ assertEq(a[i], b[i]);
+}
diff --git a/js/src/jit-test/tests/basic/testTypedArrayUint32.js b/js/src/jit-test/tests/basic/testTypedArrayUint32.js new file mode 100644 index 000000000..587e70895 --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrayUint32.js @@ -0,0 +1,19 @@ +function f() { + var input = [0, 1, 2, 0x80000000, 0xfffffff0, + 0xffffffff, 0xffffffff + 1, 0xffffffff + 2, + 101]; + + var arr = new Uint32Array(input.length); + for (var i=0; i < arr.length; i++) { + arr[i] = input[i]; + } + + var expected = [0, 1, 2, 0x80000000, 0xfffffff0, + 0xffffffff, 0, 1, 101]; + for (var i=0; i < arr.length; i++) { + assertEq(arr[i], expected[i]); + } +} +for (var i=0; i<5; i++) { + f(); +} diff --git a/js/src/jit-test/tests/basic/testTypedArrayUndefinedAndHoles.js b/js/src/jit-test/tests/basic/testTypedArrayUndefinedAndHoles.js new file mode 100644 index 000000000..0800b1085 --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrayUndefinedAndHoles.js @@ -0,0 +1,32 @@ +function holeArray(sparse) { + var a = [,,]; + if (sparse) + a.length = 1000; + return a; +} + +function undefinedArray(sparse) { + var a = [ undefined, undefined, undefined ]; + if (sparse) + a.length = 1000; + return a; +} + +var a; +a = new Int32Array(holeArray(false)); +assertEq(a[0], 0); +a = new Int32Array(holeArray(true)); +assertEq(a[0], 0); +a = new Int32Array(undefinedArray(false)); +assertEq(a[0], 0); +a = new Int32Array(undefinedArray(true)); +assertEq(a[0], 0); + +a = new Float64Array(holeArray(false)); +assertEq(a[0], NaN); +a = new Float64Array(holeArray(true)); +assertEq(a[0], NaN); +a = new Float64Array(undefinedArray(false)); +assertEq(a[0], NaN); +a = new Float64Array(undefinedArray(true)); +assertEq(a[0], NaN); diff --git a/js/src/jit-test/tests/basic/testTypedArrays.js b/js/src/jit-test/tests/basic/testTypedArrays.js new file mode 100644 index 000000000..eb2ff4d23 --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypedArrays.js @@ -0,0 +1,96 @@ +function testBasicTypedArrays() +{ + var ar, aridx, idx; + + var a = new Uint8Array(16); + var b = new Uint16Array(16); + var c = new Uint32Array(16); + var d = new Int8Array(16); + var e = new Int16Array(16); + var f = new Int32Array(16); + + var g = new Float32Array(16); + var h = new Float64Array(16); + + var iarrays = [ a, b, c, d, e, f ]; + for (aridx = 0; aridx < iarrays.length; ++aridx) { + ar = iarrays[aridx]; + + for (idx = 0; idx < ar.length-4; ++idx) { + ar[idx] = 22; + ar[idx+1] = 12.7; + ar[idx+2] = "99"; + ar[idx+3] = { k: "thing" }; + ar[idx+4] = Infinity; + } + + assertEq(ar[ar.length-5], 22); + assertEq(ar[ar.length-4], 12); + assertEq(ar[ar.length-3], 99); + assertEq(ar[ar.length-2], 0); + assertEq(ar[ar.length-1], 0); + } + + var farrays = [ g, h ]; + for (aridx = 0; aridx < farrays.length; ++aridx) { + ar = farrays[aridx]; + + for (idx = 0; idx < ar.length-4; ++idx) { + ar[idx] = 22; + ar[idx+1] = 12.25; + ar[idx+2] = "99"; + ar[idx+3] = { k: "thing" }; + ar[idx+4] = Infinity; + } + + assertEq(ar[ar.length-5], 22); + assertEq(ar[ar.length-4], 12.25); + assertEq(ar[ar.length-3], 99); + assertEq(!(ar[ar.length-2] == ar[ar.length-2]), true); + assertEq(ar[ar.length-1], Infinity); + } +} + +function testSpecialTypedArrays() +{ + var ar, aridx, idx; + + ar = new Uint8ClampedArray(16); + for (idx = 0; idx < ar.length-4; ++idx) { + ar[idx] = -200; + ar[idx+1] = 127.5; + ar[idx+2] = 987; + ar[idx+3] = Infinity; + ar[idx+4] = "hello world"; + } + + assertEq(ar[ar.length-5], 0); + assertEq(ar[ar.length-4], 128); + assertEq(ar[ar.length-3], 255); + assertEq(ar[ar.length-2], 255); + assertEq(ar[ar.length-1], 0); +} + +function testTypedArrayOther() +{ + var ar = new Int32Array(16); + for (var i = 0; i < ar.length; ++i) { + ar[i] = i; + } + + for (var i = 0; i < ar.length; ++i) { + // deliberate out of bounds access + ar[i-2] = ar[i+2]; + } + + var t = 0; + for (var i = 0; i < ar.length; ++i) { + t += ar[i]; + } + + assertEq(t, 143); +} + +testBasicTypedArrays(); +testSpecialTypedArrays(); +testTypedArrayOther(); diff --git a/js/src/jit-test/tests/basic/testTypeofHole.js b/js/src/jit-test/tests/basic/testTypeofHole.js new file mode 100644 index 000000000..9538dd79c --- /dev/null +++ b/js/src/jit-test/tests/basic/testTypeofHole.js @@ -0,0 +1,8 @@ +function testTypeofHole() { + var a = new Array(6); + a[5] = 3; + for (var i = 0; i < 6; ++i) + a[i] = typeof a[i]; + return a.join(","); +} +assertEq(testTypeofHole(), "undefined,undefined,undefined,undefined,undefined,number"); diff --git a/js/src/jit-test/tests/basic/testUnaryImacros.js b/js/src/jit-test/tests/basic/testUnaryImacros.js new file mode 100644 index 000000000..884d856d2 --- /dev/null +++ b/js/src/jit-test/tests/basic/testUnaryImacros.js @@ -0,0 +1,26 @@ +function testUnaryImacros() +{ + function checkArg(x) + { + return 1; + } + + var o = { valueOf: checkArg, toString: null }; + var count = 0; + var v = 0; + for (var i = 0; i < 5; i++) + v += +o + -(-o); + + var results = [v === 10 ? "valueOf passed" : "valueOf failed"]; + + o.valueOf = null; + o.toString = checkArg; + + for (var i = 0; i < 5; i++) + v += +o + -(-o); + + results.push(v === 20 ? "toString passed" : "toString failed"); + + return results.join(", "); +} +assertEq(testUnaryImacros(), "valueOf passed, toString passed"); diff --git a/js/src/jit-test/tests/basic/testUndefinedBooleanCmp.js b/js/src/jit-test/tests/basic/testUndefinedBooleanCmp.js new file mode 100644 index 000000000..cd2146982 --- /dev/null +++ b/js/src/jit-test/tests/basic/testUndefinedBooleanCmp.js @@ -0,0 +1,24 @@ +function testUndefinedBooleanCmp() +{ + var t = true, f = false, x = []; + for (var i = 0; i < 10; ++i) { + x[0] = t == undefined; + x[1] = t != undefined; + x[2] = t === undefined; + x[3] = t !== undefined; + x[4] = t < undefined; + x[5] = t > undefined; + x[6] = t <= undefined; + x[7] = t >= undefined; + x[8] = f == undefined; + x[9] = f != undefined; + x[10] = f === undefined; + x[11] = f !== undefined; + x[12] = f < undefined; + x[13] = f > undefined; + x[14] = f <= undefined; + x[15] = f >= undefined; + } + return x.join(","); +} +assertEq(testUndefinedBooleanCmp(), "false,true,false,true,false,false,false,false,false,true,false,true,false,false,false,false"); diff --git a/js/src/jit-test/tests/basic/testUndefinedCmp.js b/js/src/jit-test/tests/basic/testUndefinedCmp.js new file mode 100644 index 000000000..48a0dd5a1 --- /dev/null +++ b/js/src/jit-test/tests/basic/testUndefinedCmp.js @@ -0,0 +1,6 @@ +function testUndefinedCmp() { + var a = false; + for (var j = 0; j < 4; ++j) { if (undefined < false) { a = true; } } + return a; +} +assertEq(testUndefinedCmp(), false); diff --git a/js/src/jit-test/tests/basic/testUndefinedIncrement.js b/js/src/jit-test/tests/basic/testUndefinedIncrement.js new file mode 100644 index 000000000..a42557b3b --- /dev/null +++ b/js/src/jit-test/tests/basic/testUndefinedIncrement.js @@ -0,0 +1,15 @@ +function f() { + var n; + var k; + for (var i = 0; i < 18; ++i) { + n = undefined; + k = n++; + if (k) { } + } + return [k, n]; +} + +var [a, b] = f(); + +assertEq(isNaN(a), true); +assertEq(isNaN(b), true); diff --git a/js/src/jit-test/tests/basic/testUndefinedPropertyAccess.js b/js/src/jit-test/tests/basic/testUndefinedPropertyAccess.js new file mode 100644 index 000000000..3828f326c --- /dev/null +++ b/js/src/jit-test/tests/basic/testUndefinedPropertyAccess.js @@ -0,0 +1,12 @@ +function testUndefinedPropertyAccess() { + var x = [1,2,3]; + var y = {}; + var a = { foo: 1 }; + y.__proto__ = x; + var z = [x, x, x, y, y, y, y, a, a, a]; + var s = ""; + for (var i = 0; i < z.length; ++i) + s += z[i].foo; + return s; +} +assertEq(testUndefinedPropertyAccess(), "undefinedundefinedundefinedundefinedundefinedundefinedundefined111"); diff --git a/js/src/jit-test/tests/basic/testUndemotableBinaryOp.js b/js/src/jit-test/tests/basic/testUndemotableBinaryOp.js new file mode 100644 index 000000000..6fd79cda0 --- /dev/null +++ b/js/src/jit-test/tests/basic/testUndemotableBinaryOp.js @@ -0,0 +1,6 @@ +function testUndemotableBinaryOp() { + var out = []; + for (let j = 0; j < 5; ++j) { out.push(6 - ((void 0) ^ 0x80000005)); } + return out.join(","); +} +assertEq(testUndemotableBinaryOp(), "2147483649,2147483649,2147483649,2147483649,2147483649"); diff --git a/js/src/jit-test/tests/basic/testUndemoteLateGlobalSlots.js b/js/src/jit-test/tests/basic/testUndemoteLateGlobalSlots.js new file mode 100644 index 000000000..27d98a37e --- /dev/null +++ b/js/src/jit-test/tests/basic/testUndemoteLateGlobalSlots.js @@ -0,0 +1,11 @@ +function testUndemoteLateGlobalSlots() { + for each (aaa in ["", "", 0/0, ""]) { + ++aaa; + for each (bbb in [0, "", aaa, "", 0, "", 0/0]) { + } + } + delete aaa; + delete bbb; + return "ok"; +} +assertEq(testUndemoteLateGlobalSlots(), "ok"); diff --git a/js/src/jit-test/tests/basic/testWatchRecursion.js b/js/src/jit-test/tests/basic/testWatchRecursion.js new file mode 100644 index 000000000..e5d5877df --- /dev/null +++ b/js/src/jit-test/tests/basic/testWatchRecursion.js @@ -0,0 +1,63 @@ +// Test that the watch handler is not called recursively for the same object +// and property. +(function() { + var obj1 = {}, obj2 = {}; + var handler_entry_count = 0; + var handler_exit_count = 0; + + obj1.watch('x', handler); + obj1.watch('y', handler); + obj2.watch('x', handler); + obj1.x = 1; + assertEq(handler_entry_count, 3); + assertEq(handler_exit_count, 3); + + function handler(id) { + handler_entry_count++; + assertEq(handler_exit_count, 0); + switch (true) { + case this === obj1 && id === "x": + assertEq(handler_entry_count, 1); + obj2.x = 3; + assertEq(handler_exit_count, 2); + break; + case this === obj2 && id === "x": + assertEq(handler_entry_count, 2); + obj1.y = 4; + assertEq(handler_exit_count, 1); + break; + default: + assertEq(this, obj1); + assertEq(id, "y"); + assertEq(handler_entry_count, 3); + + // We expect no more watch handler invocations + obj1.x = 5; + obj1.y = 6; + obj2.x = 7; + assertEq(handler_exit_count, 0); + break; + } + ++handler_exit_count; + assertEq(handler_entry_count, 3); + } +})(); + + +// Test that run-away recursion in watch handlers is properly handled. +(function() { + var obj = {}; + var i = 0; + try { + handler(); + throw new Error("Unreachable"); + } catch(e) { + assertEq(e instanceof InternalError, true); + } + + function handler() { + var prop = "a" + ++i; + obj.watch(prop, handler); + obj[prop] = 2; + } +})(); diff --git a/js/src/jit-test/tests/basic/testWeirdDateParse.js b/js/src/jit-test/tests/basic/testWeirdDateParse.js new file mode 100644 index 000000000..77fdd33bf --- /dev/null +++ b/js/src/jit-test/tests/basic/testWeirdDateParse.js @@ -0,0 +1,38 @@ +var global = this; +function testWeirdDateParseOuter() +{ + var vDateParts = ["11", "17", "2008"]; + var out = []; + for (var vI = 0; vI < vDateParts.length; vI++) + out.push(testWeirdDateParseInner(vDateParts[vI])); + /* Mutate the global shape so we fall off trace; this causes + * additional oddity */ + global.x = Math.random(); + return out; +} +function testWeirdDateParseInner(pVal) +{ + var vR = 0; + for (var vI = 0; vI < pVal.length; vI++) { + var vC = pVal.charAt(vI); + if ((vC >= '0') && (vC <= '9')) + vR = (vR * 10) + parseInt(vC); + } + return vR; +} +function testWeirdDateParse() { + var result = []; + result.push(testWeirdDateParseInner("11")); + result.push(testWeirdDateParseInner("17")); + result.push(testWeirdDateParseInner("2008")); + result.push(testWeirdDateParseInner("11")); + result.push(testWeirdDateParseInner("17")); + result.push(testWeirdDateParseInner("2008")); + result = result.concat(testWeirdDateParseOuter()); + result = result.concat(testWeirdDateParseOuter()); + result.push(testWeirdDateParseInner("11")); + result.push(testWeirdDateParseInner("17")); + result.push(testWeirdDateParseInner("2008")); + return result.join(","); +} +assertEq(testWeirdDateParse(), "11,17,2008,11,17,2008,11,17,2008,11,17,2008,11,17,2008"); diff --git a/js/src/jit-test/tests/basic/testWeirdGetterInvocation.js b/js/src/jit-test/tests/basic/testWeirdGetterInvocation.js new file mode 100644 index 000000000..f272f3df9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testWeirdGetterInvocation.js @@ -0,0 +1,6 @@ +function getArgs() { return arguments; } +var a1 = getArgs(1); +var a2 = getArgs(1); +a1.__proto__ = a2; +delete a1[0]; +a1[0]; diff --git a/js/src/jit-test/tests/basic/testWeirdThingsInFunctionConstructor.js b/js/src/jit-test/tests/basic/testWeirdThingsInFunctionConstructor.js new file mode 100644 index 000000000..f262f2202 --- /dev/null +++ b/js/src/jit-test/tests/basic/testWeirdThingsInFunctionConstructor.js @@ -0,0 +1,6 @@ +var f = new Function('x', 'var f = 3; if (x) function f() {}; return f'); +assertEq(f(false), 3); +assertEq(typeof f(true), "function"); + +var f = new Function('x', '"use strict"; x = 3; return arguments[0]'); +assertEq(f(42), 42); diff --git a/js/src/jit-test/tests/basic/testWhileObjectOrNull.js b/js/src/jit-test/tests/basic/testWhileObjectOrNull.js new file mode 100644 index 000000000..51316ae8e --- /dev/null +++ b/js/src/jit-test/tests/basic/testWhileObjectOrNull.js @@ -0,0 +1,18 @@ +function testWhileObjectOrNull() +{ + try + { + for (var i = 0; i < 3; i++) + { + var o = { p: { p: null } }; + while (o.p) + o = o.p; + } + return "pass"; + } + catch (e) + { + return "threw exception: " + e; + } +} +assertEq(testWhileObjectOrNull(), "pass"); diff --git a/js/src/jit-test/tests/basic/testWhileWithContinue.js b/js/src/jit-test/tests/basic/testWhileWithContinue.js new file mode 100644 index 000000000..823fdd9da --- /dev/null +++ b/js/src/jit-test/tests/basic/testWhileWithContinue.js @@ -0,0 +1,10 @@ +// Test using 'while' with 'continue' -- the most ancient, the most powerful, +// the most rare of all coding incantations. + +var i = 0; +while (i < 12) { + ++i; + continue; +} +assertEq(i, 12); + diff --git a/js/src/jit-test/tests/basic/testWith.js b/js/src/jit-test/tests/basic/testWith.js new file mode 100644 index 000000000..ec1a42a84 --- /dev/null +++ b/js/src/jit-test/tests/basic/testWith.js @@ -0,0 +1,8 @@ + +// basic 'with' functionality + +var o = {foo: true}; +with(o) { + foo = 10; +} +assertEq(o.foo, 10); diff --git a/js/src/jit-test/tests/basic/testWithAndShadowing.js b/js/src/jit-test/tests/basic/testWithAndShadowing.js new file mode 100644 index 000000000..07922c899 --- /dev/null +++ b/js/src/jit-test/tests/basic/testWithAndShadowing.js @@ -0,0 +1,14 @@ +// see bug 470795 +var o = [{},{},{i:42}] +var i; +var s = []; +for (var j = 0; j < 3; ++j) { + with (o[j]) { + for (i = 0; i < 2; ++i) { + s.push(j); + s.push(i); + } + } +} +assertEq(s.join(), '0,0,0,1,1,0,1,1,2,0,2,1'); + diff --git a/js/src/jit-test/tests/basic/test_JSOP_ARGCNT.js b/js/src/jit-test/tests/basic/test_JSOP_ARGCNT.js new file mode 100644 index 000000000..6e558a07f --- /dev/null +++ b/js/src/jit-test/tests/basic/test_JSOP_ARGCNT.js @@ -0,0 +1,27 @@ +function test_JSOP_ARGCNT() { + function f0() { return arguments.length; } + function f1() { return arguments.length; } + function f2() { return arguments.length; } + function f3() { return arguments.length; } + function f4() { return arguments.length; } + function f5() { return arguments.length; } + function f6() { return arguments.length; } + function f7() { return arguments.length; } + function f8() { return arguments.length; } + function f9() { return arguments.length; } + var a = []; + for (var i = 0; i < 10; i++) { + a[0] = f0('a'); + a[1] = f1('a','b'); + a[2] = f2('a','b','c'); + a[3] = f3('a','b','c','d'); + a[4] = f4('a','b','c','d','e'); + a[5] = f5('a','b','c','d','e','f'); + a[6] = f6('a','b','c','d','e','f','g'); + a[7] = f7('a','b','c','d','e','f','g','h'); + a[8] = f8('a','b','c','d','e','f','g','h','i'); + a[9] = f9('a','b','c','d','e','f','g','h','i','j'); + } + return a.join(","); +} +assertEq(test_JSOP_ARGCNT(), "1,2,3,4,5,6,7,8,9,10"); diff --git a/js/src/jit-test/tests/basic/test_JSOP_ARGSUB.js b/js/src/jit-test/tests/basic/test_JSOP_ARGSUB.js new file mode 100644 index 000000000..1a4d27cda --- /dev/null +++ b/js/src/jit-test/tests/basic/test_JSOP_ARGSUB.js @@ -0,0 +1,27 @@ +function test_JSOP_ARGSUB() { + function f0() { return arguments[0]; } + function f1() { return arguments[1]; } + function f2() { return arguments[2]; } + function f3() { return arguments[3]; } + function f4() { return arguments[4]; } + function f5() { return arguments[5]; } + function f6() { return arguments[6]; } + function f7() { return arguments[7]; } + function f8() { return arguments[8]; } + function f9() { return arguments[9]; } + var a = []; + for (var i = 0; i < 10; i++) { + a[0] = f0('a'); + a[1] = f1('a','b'); + a[2] = f2('a','b','c'); + a[3] = f3('a','b','c','d'); + a[4] = f4('a','b','c','d','e'); + a[5] = f5('a','b','c','d','e','f'); + a[6] = f6('a','b','c','d','e','f','g'); + a[7] = f7('a','b','c','d','e','f','g','h'); + a[8] = f8('a','b','c','d','e','f','g','h','i'); + a[9] = f9('a','b','c','d','e','f','g','h','i','j'); + } + return a.join(""); +} +assertEq(test_JSOP_ARGSUB(), "abcdefghij"); diff --git a/js/src/jit-test/tests/basic/testif.js b/js/src/jit-test/tests/basic/testif.js new file mode 100644 index 000000000..f7b2864e9 --- /dev/null +++ b/js/src/jit-test/tests/basic/testif.js @@ -0,0 +1,11 @@ +function testif() { + var q = 0; + for (var i = 0; i < 100; i++) { + if ((i & 1) == 0) + q++; + else + q--; + } + return q; +} +assertEq(testif(), 0); diff --git a/js/src/jit-test/tests/basic/testincops.js b/js/src/jit-test/tests/basic/testincops.js new file mode 100644 index 000000000..85e36abe3 --- /dev/null +++ b/js/src/jit-test/tests/basic/testincops.js @@ -0,0 +1,24 @@ +var globalinc = 0; +function testincops(n) { + var i = 0, o = {p:0}, a = [0]; + n = 100; + + for (i = 0; i < n; i++); + while (i-- > 0); + for (i = 0; i < n; ++i); + while (--i >= 0); + + for (o.p = 0; o.p < n; o.p++) globalinc++; + while (o.p-- > 0) --globalinc; + for (o.p = 0; o.p < n; ++o.p) ++globalinc; + while (--o.p >= 0) globalinc--; + + ++i; // set to 0 + for (a[i] = 0; a[i] < n; a[i]++); + while (a[i]-- > 0); + for (a[i] = 0; a[i] < n; ++a[i]); + while (--a[i] >= 0); + + return [++o.p, ++a[i], globalinc].toString(); +} +assertEq(testincops(), "0,0,0"); diff --git a/js/src/jit-test/tests/basic/this-binding-with-eval.js b/js/src/jit-test/tests/basic/this-binding-with-eval.js new file mode 100644 index 000000000..caeda0230 --- /dev/null +++ b/js/src/jit-test/tests/basic/this-binding-with-eval.js @@ -0,0 +1,51 @@ +function Test1() { + this.x = 8; + this.y = 5; + this.z = 2; + var o = {".this": {x: 1}}; + var res; + with (o) { + res = this.x + (() => this.z)() + eval("this.x + (() => this.y)()"); + } + assertEq(res, 23); +} +new Test1(); + +function Test2() { + this.x = 8; + var o = {".this": {x: 1}}; + with (o) { + return eval("() => this.x"); + } +} +var fun = new Test2(); +assertEq(fun(), 8); + +function Test3() { + this.x = 8; + var o = {".this": {x: 1}}; + with (o) { + assertEq(this.x, 8); + } +} +new Test3(); + +function test4() { + var o = {".this": {x: 1}}; + with (o) { + return () => this; + } +} +assertEq(test4()(), this); + +function test5() { + var o = {".this": {x: 1}}; + with (o) { + return this; + } +} +assertEq(test5(), this); + +var global = this; +evaluate("with({}) { assertEq(this, global); }"); +eval("with({}) { assertEq(this, global); }"); diff --git a/js/src/jit-test/tests/basic/throw-apply-too-many-args.js b/js/src/jit-test/tests/basic/throw-apply-too-many-args.js new file mode 100644 index 000000000..21569c289 --- /dev/null +++ b/js/src/jit-test/tests/basic/throw-apply-too-many-args.js @@ -0,0 +1,27 @@ +function g(a, b, c, d) {} +function f(a, b, c) +{ + arguments.length = getMaxArgs() + 1; + g.apply(this, arr); +} +let x = []; +x.length = getMaxArgs() + 1; +var args = [[5], [5], [5], [5], [5], [5], [5], [5], [5], [5], [5], x] +try +{ + for (var i = 0; i < args.length; i++) { arr = args[i]; f(); } + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e instanceof RangeError, true, "wrong exception: " + e); +} +try +{ + for (var i = 0; i < args.length; i++) { arr = args[i]; f(); } + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e instanceof RangeError, true, "wrong exception: " + e); +} diff --git a/js/src/jit-test/tests/basic/timeout-check.js b/js/src/jit-test/tests/basic/timeout-check.js new file mode 100644 index 000000000..159aa663c --- /dev/null +++ b/js/src/jit-test/tests/basic/timeout-check.js @@ -0,0 +1,14 @@ +// |jit-test| exitstatus: 6 +function f(x) { + if (x === 0) + return; + f(x - 1); + f(x - 1); + f(x - 1); + f(x - 1); + f(x - 1); + f(x - 1); +} +timeout(0.1); +f(100); +assertEq(0, 1); diff --git a/js/src/jit-test/tests/basic/track-allocation-sites.js b/js/src/jit-test/tests/basic/track-allocation-sites.js new file mode 100644 index 000000000..fb329b700 --- /dev/null +++ b/js/src/jit-test/tests/basic/track-allocation-sites.js @@ -0,0 +1,24 @@ +// Test that we can track allocation sites. + +enableTrackAllocations(); + +const tests = [ + { name: "object literal", object: {}, line: Error().lineNumber }, + { name: "array literal", object: [], line: Error().lineNumber }, + { name: "regexp literal", object: /(two|2)\s*problems/, line: Error().lineNumber }, + { name: "new constructor", object: new function Ctor(){}, line: Error().lineNumber }, + { name: "new Object", object: new Object(), line: Error().lineNumber }, + { name: "new Array", object: new Array(), line: Error().lineNumber }, + { name: "new Date", object: new Date(), line: Error().lineNumber } +]; + +disableTrackAllocations(); + +for (let { name, object, line } of tests) { + print("Entering test: " + name); + + let allocationSite = getAllocationMetadata(object); + print(allocationSite); + + assertEq(allocationSite.line, line); +} diff --git a/js/src/jit-test/tests/basic/trees.js b/js/src/jit-test/tests/basic/trees.js new file mode 100644 index 000000000..7638f089a --- /dev/null +++ b/js/src/jit-test/tests/basic/trees.js @@ -0,0 +1,10 @@ +function trees() { + var i = 0, o = [0,0,0]; + for (i = 0; i < 100; ++i) { + if ((i & 1) == 0) o[0]++; + else if ((i & 2) == 0) o[1]++; + else o[2]++; + } + return String(o); +} +assertEq(trees(), "50,25,25"); diff --git a/js/src/jit-test/tests/basic/truncateDouble.js b/js/src/jit-test/tests/basic/truncateDouble.js new file mode 100644 index 000000000..b5c499076 --- /dev/null +++ b/js/src/jit-test/tests/basic/truncateDouble.js @@ -0,0 +1,10 @@ + +// check correctness of truncation of doubles slightly outside the int32_t range. + +function truncate(x) { + return x | 0; +} + +assertEq(truncate(0xffffffff), -1); +assertEq(truncate(0xffffffff + 5000.5), 4999); +assertEq(truncate(-0xffffffff - 5000.5), -4999); diff --git a/js/src/jit-test/tests/basic/truthies.js b/js/src/jit-test/tests/basic/truthies.js new file mode 100644 index 000000000..3006ee7b3 --- /dev/null +++ b/js/src/jit-test/tests/basic/truthies.js @@ -0,0 +1,29 @@ +load(libdir + 'andTestHelper.js'); +load(libdir + 'orTestHelper.js'); + +(function () { + var opsies = ["||", "&&"]; + var falsies = [null, undefined, false, NaN, 0, ""]; + var truthies = [{}, true, 1, 42, 1/0, -1/0, "blah"]; + var boolies = [falsies, truthies]; + + // The for each here should abort tracing, so that this test framework + // relies only on the interpreter while the orTestHelper and andTestHelper + // functions get trace-JITed. + for each (var op in opsies) { + for (var i in boolies) { + for (var j in boolies[i]) { + var x = uneval(boolies[i][j]); + for (var k in boolies) { + for (var l in boolies[k]) { + var y = uneval(boolies[k][l]); + var prefix = (op == "||") ? "or" : "and"; + var f = new Function("return " + prefix + "TestHelper(" + x + "," + y + ",10)"); + var expected = eval(x + op + y) ? 45 : 0; + assertEq(f(), expected); + } + } + } + } + } + })(); diff --git a/js/src/jit-test/tests/basic/typeMonitorCall.js b/js/src/jit-test/tests/basic/typeMonitorCall.js new file mode 100644 index 000000000..d80a7dc62 --- /dev/null +++ b/js/src/jit-test/tests/basic/typeMonitorCall.js @@ -0,0 +1,19 @@ + +/* Make sure we are checking argument types when going through unknown but monomorphic call sites. */ + +function foo(x) { + return x + 10; +} + +var array = [1,2,3,4,5,6,7,"eight"]; + +/* Jump through hoops to make 'f' unknown. */ +var f = this[eval("'foo'")]; + +for (var i = 0; i < array.length; i++) { + var res = f(array[i]); + if (i != 7) + assertEq(res, i + 11); + else + assertEq(res, "eight10"); +} diff --git a/js/src/jit-test/tests/basic/typeMonitorSingleton.js b/js/src/jit-test/tests/basic/typeMonitorSingleton.js new file mode 100644 index 000000000..be01dcaeb --- /dev/null +++ b/js/src/jit-test/tests/basic/typeMonitorSingleton.js @@ -0,0 +1,17 @@ +// |jit-test| error: TypeError + +var x = {f:20}; + +function foo() { + for (var i = 0; i < 10; i++) + x.f; +} +foo(); + +gc(); + +// a type barrier needs to be generated for the access on x within foo, +// even though its type set is initially empty after the GC. +x = undefined; + +foo(); diff --git a/js/src/jit-test/tests/basic/typed-array-copyWithin.js b/js/src/jit-test/tests/basic/typed-array-copyWithin.js new file mode 100644 index 000000000..0bcc0bdd7 --- /dev/null +++ b/js/src/jit-test/tests/basic/typed-array-copyWithin.js @@ -0,0 +1,214 @@ +// Bug 1021379 - Rename typed arrays' move method to copyWithin, +// fix up to ES6 semantics +// Tests for TypedArray#copyWithin + +load(libdir + "asserts.js"); + +const constructors = [ + Int8Array, + Uint8Array, + Uint8ClampedArray, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array +]; + +for (var constructor of constructors) { + + assertEq(constructor.prototype.copyWithin.length, 2); + + // works with two arguments + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(0, 3), + new constructor([4, 5, 3, 4, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(1, 3), + new constructor([1, 4, 5, 4, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(1, 2), + new constructor([1, 3, 4, 5, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(2, 2), + new constructor([1, 2, 3, 4, 5])); + + // works with three arguments + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(0, 3, 4), + new constructor([4, 2, 3, 4, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(1, 3, 4), + new constructor([1, 4, 3, 4, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(1, 2, 4), + new constructor([1, 3, 4, 4, 5])); + + // works with negative arguments + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(0, -2), + new constructor([4, 5, 3, 4, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(0, -2, -1), + new constructor([4, 2, 3, 4, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(-4, -3, -2), + new constructor([1, 3, 3, 4, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(-4, -3, -1), + new constructor([1, 3, 4, 4, 5])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(-4, -3), + new constructor([1, 3, 4, 5, 5])); + + // throws on null/undefined values + assertThrowsInstanceOf(function() { + constructor.prototype.copyWithin.call(null, 0, 3); + }, TypeError, "Assert that copyWithin fails if this value is null"); + + assertThrowsInstanceOf(function() { + var throw42 = { valueOf: function() { throw 42; } }; + constructor.prototype.copyWithin.call(null, throw42, throw42, throw42); + }, TypeError, "Assert that copyWithin fails if this value is null"); + + assertThrowsInstanceOf(function() { + var throw42 = { valueOf: function() { throw 42; } }; + constructor.prototype.copyWithin.call(undefined, throw42, throw42, throw42); + }, TypeError, "Assert that copyWithin fails if this value is undefined"); + + assertThrowsInstanceOf(function() { + constructor.prototype.copyWithin.call(undefined, 0, 3); + }, TypeError, "Assert that copyWithin fails if this value is undefined"); + + // test with this value as string + assertThrowsInstanceOf(function() { + constructor.prototype.copyWithin.call("hello world", 0, 3); + }, TypeError, "Assert that copyWithin fails if this value is string"); + + assertThrowsInstanceOf(function() { + var throw42 = { valueOf: function() { throw 42; } }; + constructor.prototype.copyWithin.call("hello world", throw42, throw42, throw42); + }, TypeError, "Assert that copyWithin fails if this value is string"); + + // test with target > start on 2 arguments + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(3, 0), + new constructor([1, 2, 3, 1, 2])); + + // test with target > start on 3 arguments + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(3, 0, 4), + new constructor([1, 2, 3, 1, 2])); + + // test on fractional arguments + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(0.2, 3.9), + new constructor([4, 5, 3, 4, 5])); + + // test with -0 + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(-0, 3), + new constructor([4, 5, 3, 4, 5])); + + // test with arguments more than this.length + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(0, 7), + new constructor([1, 2, 3, 4, 5])); + + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(7, 0), + new constructor([1, 2, 3, 4, 5])); + + // test with arguments less than -this.length + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(-7, 0), + new constructor([1, 2, 3, 4, 5])); + + // test with arguments equal to -this.length + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(-5, 0), + new constructor([1, 2, 3, 4, 5])); + + // test on empty constructor + assertDeepEq(new constructor([]).copyWithin(0, 3), + new constructor([])); + + // test with target range being shorter than end - start + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(2, 1, 4), + new constructor([1, 2, 2, 3, 4])); + + // test overlapping ranges + arr = new constructor([1, 2, 3, 4, 5]); + arr.copyWithin(2, 1, 4); + assertDeepEq(arr.copyWithin(2, 1, 4), + new constructor([1, 2, 2, 2, 3])); + + // undefined as third argument + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(0, 3, undefined), + new constructor([4, 5, 3, 4, 5])); + + // test that this.length is never called + arr = new constructor([0, 1, 2, 3, 5]); + Object.defineProperty(arr, "length", { + get: function () { throw new Error("length accessor called"); } + }); + arr.copyWithin(1, 3); + + var large = 10000; + + // test on a large constructor + arr = new constructor(large); + assertDeepEq(arr.copyWithin(45, 900), arr); + + // test on floating point numbers + for (var i = 0; i < large; i++) { + arr[i] = Math.random(); + } + arr.copyWithin(45, 900); + + // test on constructor of objects + for (var i = 0; i < large; i++) { + arr[i] = { num: Math.random() }; + } + arr.copyWithin(45, 900); + + // test constructor length remains same + assertEq(arr.length, large); + + // test null on third argument is handled correctly + assertDeepEq(new constructor([1, 2, 3, 4, 5]).copyWithin(0, 3, null), + new constructor([1, 2, 3, 4, 5])); + + //Any argument referenced, but not provided, has the value |undefined| + var tarray = new constructor(8); + try + { + tarray.copyWithin({ valueOf: function() { throw 42; } }); + throw new Error("expected to throw"); + } + catch (e) + { + assertEq(e, 42, "should have failed converting target to index"); + } + + function detachAndConvertTo(x) { + return { valueOf() { + detachArrayBuffer(tarray.buffer); + return x; + } }; + } + + // Detaching during argument processing triggers a TypeError. + tarray = new constructor([1, 2, 3, 4, 5]); + try + { + tarray.copyWithin(0, 3, detachAndConvertTo(4)); + throw new Error("expected to throw"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "expected throw with detached buffer during set"); + } + + // ...unless no elements are to be copied. + tarray = new constructor([1, 2, 3, 4, 5]); + assertDeepEq(tarray.copyWithin(0, 3, detachAndConvertTo(3)), + new constructor([])); + + /* // fails, unclear whether it should, disabling for now + // test with a proxy object + var handler = { + get: function(recipient, name) { + return recipient[name] + 2; + } + }; + + var p = new Proxy(new constructor([1, 2, 3, 4, 5]), handler); + + assertThrowsInstanceOf(function() { + constructor.prototype.copyWithin.call(p, 0, 3); + }, TypeError, "Assert that copyWithin fails if used with a proxy object"); + */ +} diff --git a/js/src/jit-test/tests/basic/typed-array-getprop-out-of-range.js b/js/src/jit-test/tests/basic/typed-array-getprop-out-of-range.js new file mode 100644 index 000000000..601d9f3c5 --- /dev/null +++ b/js/src/jit-test/tests/basic/typed-array-getprop-out-of-range.js @@ -0,0 +1,11 @@ +var r = Object.prototype[0] = /a/; + +function test() +{ + for (var i = 0, sz = 9; i < sz; i++) + { + var ta = new Int8Array(); + assertEq(ta[0], undefined); + } +} +test(); diff --git a/js/src/jit-test/tests/basic/typed-array-index-out-of-range.js b/js/src/jit-test/tests/basic/typed-array-index-out-of-range.js new file mode 100644 index 000000000..a0506dfcf --- /dev/null +++ b/js/src/jit-test/tests/basic/typed-array-index-out-of-range.js @@ -0,0 +1,36 @@ + +// Out of bounds writes on typed arrays are uneffectful for all integers. + +var x = new Int32Array(10); + +function f() { + for (var i = -100; i < 100; i++) { + x[i] = i + 1; + if (i >= 0 && i < 10) + assertEq(x[i], i + 1); + else + assertEq(x[i], undefined); + } +} +f(); + +// Really big integers not representable with a double or uint64 are still integers. + +var bigint = "" + Math.pow(2, 53); +x[bigint] = "twelve"; +assertEq(x[bigint], undefined); + +x["9999999999999999999999"] = "twelve"; +assertEq(x["9999999999999999999999"], undefined); + +// Except when their toString() makes them not look like integers! +x[9999999999999999999999] = "twelve"; +assertEq(x[9999999999999999999999], "twelve"); + +// Infinity and -Infinity maybe are supposed to be integers, but they aren't currently. + +x["Infinity"] = "twelve"; +assertEq(x["Infinity"], "twelve"); + +x["-Infinity"] = "twelve"; +assertEq(x["-Infinity"], "twelve"); diff --git a/js/src/jit-test/tests/basic/typed-array-offsets.js b/js/src/jit-test/tests/basic/typed-array-offsets.js new file mode 100644 index 000000000..00e953edc --- /dev/null +++ b/js/src/jit-test/tests/basic/typed-array-offsets.js @@ -0,0 +1,11 @@ +function f(x, y) { + for (var i = 0; i < 100; i++) + assertEq(x[0], y); +} +var a = new ArrayBuffer(20); +var b = new Int32Array(a, 12, 2); +var c = new Int32Array(a, 0, 2); +b[0] = 10; +f(b, 10); +c[0] = 20; +f(c, 20); diff --git a/js/src/jit-test/tests/basic/typed-array-sealed-frozen.js b/js/src/jit-test/tests/basic/typed-array-sealed-frozen.js new file mode 100644 index 000000000..90c0b9a35 --- /dev/null +++ b/js/src/jit-test/tests/basic/typed-array-sealed-frozen.js @@ -0,0 +1,85 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +load(libdir + "asserts.js") + +const constructors = [ + Int8Array, + Uint8Array, + Uint8ClampedArray, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array +]; + +for (constructor of constructors) { + print("testing non-empty " + constructor.name); + let a = new constructor(10); + assertEq(Object.isExtensible(a), true); + assertEq(Object.isSealed(a), false); + assertEq(Object.isFrozen(a), false); + + // Should not throw. + Object.seal(a); + + // Should complain that it can't change attributes of indexed typed array properties. + assertThrowsInstanceOf(() => Object.freeze(a), TypeError); +} + +print(); + +for (constructor of constructors) { + print("testing zero-length " + constructor.name); + let a = new constructor(0); + assertEq(Object.isExtensible(a), true); + assertEq(Object.isSealed(a), false); + assertEq(Object.isFrozen(a), false); + + // Should not throw. + Object.seal(a); + Object.freeze(a); +} + +// isSealed and isFrozen should not try to build an array of all the +// property names of a typed array, since they're often especially large. +// This should not throw an allocation error. +let a = new Uint8Array(1 << 24); +Object.isSealed(a); +Object.isFrozen(a); + +for (constructor of constructors) { + print("testing extensibility " + constructor.name); + let a = new constructor(10); + + // New named properties should show up on typed arrays. + a.foo = "twelve"; + assertEq(a.foo, "twelve"); + + // New indexed properties should not show up on typed arrays. + a[20] = "twelve"; + assertEq(a[20], undefined); + + // Watch for especially large indexed properties. + a[-10 >>> 0] = "twelve"; + assertEq(a[-10 >>> 0], undefined); + + // Watch for really large indexed properties too. + a[Math.pow(2, 53)] = "twelve"; + assertEq(a[Math.pow(2, 53)], undefined); + + // Don't define old properties. + Object.defineProperty(a, 5, {value: 3}); + assertEq(a[5], 3); + + // Don't define new properties. + Object.defineProperty(a, 20, {value: 3}); + assertEq(a[20], undefined); + + // Don't delete indexed properties. + a[3] = 3; + delete a[3]; + assertEq(a[3], 3); +} diff --git a/js/src/jit-test/tests/basic/typedarray-selfhosted-cross-compartment.js b/js/src/jit-test/tests/basic/typedarray-selfhosted-cross-compartment.js new file mode 100644 index 000000000..ee2ef412c --- /dev/null +++ b/js/src/jit-test/tests/basic/typedarray-selfhosted-cross-compartment.js @@ -0,0 +1,13 @@ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +var global = newGlobal(); +var array = new global.Int8Array(10); + +assertEq(array.find(v => v == 1), undefined) +assertEq(array.findIndex(v => v == 0), 0) + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/jit-test/tests/basic/typeof-array.js b/js/src/jit-test/tests/basic/typeof-array.js new file mode 100644 index 000000000..d384dd973 --- /dev/null +++ b/js/src/jit-test/tests/basic/typeof-array.js @@ -0,0 +1,9 @@ + +function typeOf(o) { + assertEq(typeof o, "object"); +} + +typeOf([]); +typeOf(new Float32Array()); +typeOf(new Int32Array()); +typeOf(new ArrayBuffer()); diff --git a/js/src/jit-test/tests/basic/typeofTest.js b/js/src/jit-test/tests/basic/typeofTest.js new file mode 100644 index 000000000..90dadbb54 --- /dev/null +++ b/js/src/jit-test/tests/basic/typeofTest.js @@ -0,0 +1,8 @@ +function typeofTest() +{ + var values = ["hi", "hi", "hi", null, 5, 5.1, true, undefined, /foo/, typeofTest, [], {}], types = []; + for (var i = 0; i < values.length; i++) + types[i] = typeof values[i]; + return types.toString(); +} +assertEq(typeofTest(), "string,string,string,object,number,number,boolean,undefined,object,function,object,object"); diff --git a/js/src/jit-test/tests/basic/unboxed-object-clear-new-script.js b/js/src/jit-test/tests/basic/unboxed-object-clear-new-script.js new file mode 100644 index 000000000..f55456222 --- /dev/null +++ b/js/src/jit-test/tests/basic/unboxed-object-clear-new-script.js @@ -0,0 +1,49 @@ + +function Foo(a, b) { + this.a = a; + this.b = b; +} + +function invalidate_foo() { + var a = []; + var counter = 0; + for (var i = 0; i < 50; i++) + a.push(new Foo(i, i + 1)); + Object.defineProperty(Foo.prototype, "a", {configurable: true, set: function() { counter++; }}); + for (var i = 0; i < 50; i++) + a.push(new Foo(i, i + 1)); + delete Foo.prototype.a; + var total = 0; + for (var i = 0; i < a.length; i++) { + assertEq('a' in a[i], i < 50); + total += a[i].b; + } + assertEq(total, 2550); + assertEq(counter, 50); +} +invalidate_foo(); + +function Bar(a, b, fn) { + this.a = a; + if (b == 30) + Object.defineProperty(Bar.prototype, "b", {configurable: true, set: fn}); + this.b = b; +} + +function invalidate_bar() { + var a = []; + var counter = 0; + function fn() { counter++; } + for (var i = 0; i < 50; i++) + a.push(new Bar(i, i + 1, fn)); + delete Bar.prototype.b; + var total = 0; + for (var i = 0; i < a.length; i++) { + assertEq('a' in a[i], true); + assertEq('b' in a[i], i < 29); + total += a[i].a; + } + assertEq(total, 1225); + assertEq(counter, 21); +} +invalidate_bar(); diff --git a/js/src/jit-test/tests/basic/unboxed-object-convert-to-native.js b/js/src/jit-test/tests/basic/unboxed-object-convert-to-native.js new file mode 100644 index 000000000..691fe166c --- /dev/null +++ b/js/src/jit-test/tests/basic/unboxed-object-convert-to-native.js @@ -0,0 +1,47 @@ + +// Test various ways of converting an unboxed object to native. + +function Foo(a, b) { + this.a = a; + this.b = b; +} + +var proxyObj = { + get: function(recipient, name) { + return recipient[name] + 2; + } +}; + +function f() { + var a = []; + for (var i = 0; i < 50; i++) + a.push(new Foo(i, i + 1)); + + var prop = "a"; + + i = 0; + for (; i < 5; i++) + a[i].c = i; + for (; i < 10; i++) + Object.defineProperty(a[i], 'c', {value: i}); + for (; i < 15; i++) + a[i] = new Proxy(a[i], proxyObj); + for (; i < 20; i++) + a[i].a = 3.5; + for (; i < 25; i++) + delete a[i].b; + for (; i < 30; i++) + a[prop] = 4; + + var total = 0; + for (i = 0; i < a.length; i++) { + if ('a' in a[i]) + total += a[i].a; + if ('b' in a[i]) + total += a[i].b; + if ('c' in a[i]) + total += a[i].c; + } + assertEq(total, 2382.5); +} +f(); diff --git a/js/src/jit-test/tests/basic/unboxed-object-getelem.js b/js/src/jit-test/tests/basic/unboxed-object-getelem.js new file mode 100644 index 000000000..b30b8325a --- /dev/null +++ b/js/src/jit-test/tests/basic/unboxed-object-getelem.js @@ -0,0 +1,20 @@ + +function f() { + var propNames = ["a","b","c","d","e","f","g","h","i","j","x","y"]; + var arr = []; + for (var i=0; i<64; i++) + arr.push({x:1, y:2}); + for (var i=0; i<64; i++) { + // Make sure there are expandos with dynamic slots for each object. + for (var j = 0; j < propNames.length; j++) + arr[i][propNames[j]] = j; + } + var res = 0; + for (var i=0; i<100000; i++) { + var o = arr[i % 64]; + var p = propNames[i % propNames.length]; + res += o[p]; + } + assertEq(res, 549984); +} +f(); diff --git a/js/src/jit-test/tests/basic/unboxed-object-set-property.js b/js/src/jit-test/tests/basic/unboxed-object-set-property.js new file mode 100644 index 000000000..fdcfcf6b2 --- /dev/null +++ b/js/src/jit-test/tests/basic/unboxed-object-set-property.js @@ -0,0 +1,31 @@ + +// Use the correct receiver when non-native objects are prototypes of other objects. + +function Thing(a, b) { + this.a = a; + this.b = b; +} + +function foo() { + var array = []; + for (var i = 0; i < 10000; i++) + array.push(new Thing(i, i + 1)); + + var proto = new Thing(1, 2); + var obj = Object.create(proto); + + Object.defineProperty(Thing.prototype, "c", {set:function() { this.d = 0; }}); + obj.c = 3; + assertEq(obj.c, undefined); + assertEq(obj.d, 0); + assertEq(obj.hasOwnProperty("d"), true); + assertEq(proto.d, undefined); + assertEq(proto.hasOwnProperty("d"), false); + + obj.a = 3; + assertEq(obj.a, 3); + assertEq(proto.a, 1); + assertEq(obj.hasOwnProperty("a"), true); +} + +foo(); diff --git a/js/src/jit-test/tests/basic/unboxed-property-enumeration.js b/js/src/jit-test/tests/basic/unboxed-property-enumeration.js new file mode 100644 index 000000000..142d932dd --- /dev/null +++ b/js/src/jit-test/tests/basic/unboxed-property-enumeration.js @@ -0,0 +1,24 @@ +function O() { + this.x = 1; + this.y = 2; +} +function testUnboxed() { + var arr = []; + for (var i=0; i<100; i++) + arr.push(new O); + + var o = arr[arr.length-1]; + o[0] = 0; + o[2] = 2; + var sym = Symbol(); + o[sym] = 1; + o.z = 3; + Object.defineProperty(o, '3', {value:1,enumerable:false,configurable:false,writable:false}); + o[4] = 4; + + var props = Reflect.ownKeys(o); + assertEq(props[props.length-1], sym); + + assertEq(Object.getOwnPropertyNames(o).join(""), "0234xyz"); +} +testUnboxed(); diff --git a/js/src/jit-test/tests/basic/unboxint.js b/js/src/jit-test/tests/basic/unboxint.js new file mode 100644 index 000000000..1aa431297 --- /dev/null +++ b/js/src/jit-test/tests/basic/unboxint.js @@ -0,0 +1,8 @@ +function unboxint() { + var q = 0; + var o = [4]; + for (var i = 0; i < 100; ++i) + q = o[0] << 1; + return q; +} +assertEq(unboxint(), 8); diff --git a/js/src/jit-test/tests/basic/undefined-warning-bug1274499.js b/js/src/jit-test/tests/basic/undefined-warning-bug1274499.js new file mode 100644 index 000000000..d8e48323b --- /dev/null +++ b/js/src/jit-test/tests/basic/undefined-warning-bug1274499.js @@ -0,0 +1,13 @@ +options("strict", "werror");
+
+var o = {};
+var failureCode = 0;
+
+try {
+ // Don't throw here.
+ if (o.a || o.b)
+ failureCode = 1;
+} catch (e) {
+ failureCode = 2
+}
+assertEq(failureCode, 0);
diff --git a/js/src/jit-test/tests/basic/undefined-warning-bug565202.js b/js/src/jit-test/tests/basic/undefined-warning-bug565202.js new file mode 100644 index 000000000..011efc32a --- /dev/null +++ b/js/src/jit-test/tests/basic/undefined-warning-bug565202.js @@ -0,0 +1,7 @@ +options("strict", "werror");
+
+var o = {};
+
+// Don't throw here.
+if (o.a)
+ x = true;
diff --git a/js/src/jit-test/tests/basic/weird-scopechains.js b/js/src/jit-test/tests/basic/weird-scopechains.js new file mode 100644 index 000000000..035a934ec --- /dev/null +++ b/js/src/jit-test/tests/basic/weird-scopechains.js @@ -0,0 +1,34 @@ +function checkNameLookup() { + return "global"; +} + +function assertWithMessage(got, expected, message) { + assertEq(message + ": " + got, message + ": " + expected); +} + +function testFunc() { + assertWithMessage(checkNameLookup(), "local", "nameLookup"); + assertWithMessage(checkThisBinding(), "local", "thisBinding"); + + // Important: lambda needs to close over "reason", so it won't just get the + // scope of testFunc as its scope. Instead it'll get the Call object + // "reason" lives in. + var reason = " in lambda in Call"; + (function() { + assertWithMessage(checkNameLookup(), "local", "nameLookup" + reason); + assertWithMessage(checkThisBinding(), "local", "thisBinding" + reason); + })(); +} + +var obj = { + checkNameLookup: function() { + return "local"; + }, + + checkThisBinding: function() { + return this.checkNameLookup(); + }, +}; + +var cloneFunc = clone(testFunc, obj); +cloneFunc(); diff --git a/js/src/jit-test/tests/basic/werror.js b/js/src/jit-test/tests/basic/werror.js new file mode 100644 index 000000000..b44a3aee7 --- /dev/null +++ b/js/src/jit-test/tests/basic/werror.js @@ -0,0 +1,7 @@ +// |jit-test| error: unreachable code +function f() { + return 1; + return 2; +} +options("werror"); +f(); diff --git a/js/src/jit-test/tests/basic/withSourceHook.js b/js/src/jit-test/tests/basic/withSourceHook.js new file mode 100644 index 000000000..460c4efe1 --- /dev/null +++ b/js/src/jit-test/tests/basic/withSourceHook.js @@ -0,0 +1,56 @@ +// Check that withSourceHook passes URLs, propagates exceptions, and +// properly restores the original source hooks. + +load(libdir + 'asserts.js'); + +// withSourceHook isn't defined if you pass the shell the --fuzzing-safe +// option. Skip this test silently, to avoid spurious failures. +if (typeof withSourceHook != 'function') + quit(0); + +var log = ''; + +// Establish an outermost source hook. +withSourceHook(function (url) { + log += 'o'; + assertEq(url, 'outer'); + return '(function outer() { 3; })'; +}, function () { + log += 'O'; + // Verify that withSourceHook propagates exceptions thrown by source hooks. + assertThrowsValue(function () { + // Establish a source hook that throws. + withSourceHook(function (url) { + log += 'm'; + assertEq(url, 'middle'); + throw 'borborygmus'; // middle + }, function () { + log += 'M'; + // Establish an innermost source hook that does not throw, + // and verify that it is in force. + assertEq(withSourceHook(function (url) { + log += 'i'; + assertEq(url, 'inner'); + return '(function inner() { 1; })'; + }, function () { + log += 'I'; + return evaluate('(function inner() { 2; })', + { fileName: 'inner', sourceIsLazy: true }) + .toSource(); + }), + '(function inner() { 1; })'); + // Verify that the source hook that throws has been reinstated. + evaluate('(function middle() { })', + { fileName: 'middle', sourceIsLazy: true }) + .toSource(); + }); + }, 'borborygmus'); + + // Verify that the outermost source hook has been restored. + assertEq(evaluate('(function outer() { 4; })', + { fileName: 'outer', sourceIsLazy: true }) + .toSource(), + '(function outer() { 3; })'); +}); + +assertEq(log, 'OMIimo'); diff --git a/js/src/jit-test/tests/basic/write-frozen-dense-strict-inlinecache.js b/js/src/jit-test/tests/basic/write-frozen-dense-strict-inlinecache.js new file mode 100644 index 000000000..bdd8d055f --- /dev/null +++ b/js/src/jit-test/tests/basic/write-frozen-dense-strict-inlinecache.js @@ -0,0 +1,20 @@ +// |jit-test| --no-threads; --ion-eager; --ion-shared-stubs=off +setJitCompilerOption('ion.forceinlineCaches', 1); +function foo(t) { + "use strict"; + var stop; + do { + let ok = false; + stop = inIon(); + try { + t[0] = 2; + } catch(e) { + ok = true; + } + assertEq(ok, true); + } while (!stop); +} +var t = [4]; +Object.freeze(t); +foo(t); +foo(t); diff --git a/js/src/jit-test/tests/basic/write-frozen-dense-strict.js b/js/src/jit-test/tests/basic/write-frozen-dense-strict.js new file mode 100644 index 000000000..9ee6b6c6d --- /dev/null +++ b/js/src/jit-test/tests/basic/write-frozen-dense-strict.js @@ -0,0 +1,14 @@ +"use strict"; +var t = [4]; +var stop; +Object.freeze(t); +do { + let ok = false; + stop = inIon(); + try { + t[0] = 2; + } catch(e) { + ok = true; + } + assertEq(ok, true); +} while (!stop); diff --git a/js/src/jit-test/tests/basic/write-frozen-dense.js b/js/src/jit-test/tests/basic/write-frozen-dense.js new file mode 100644 index 000000000..7e09c330b --- /dev/null +++ b/js/src/jit-test/tests/basic/write-frozen-dense.js @@ -0,0 +1,8 @@ +var t = [4]; +var stop; +Object.freeze(t); +do { + stop = inIon(); + t[0] = 2; + assertEq(t[0], 4); +} while (!stop); diff --git a/js/src/jit-test/tests/basic/write-frozen-property-strict.js b/js/src/jit-test/tests/basic/write-frozen-property-strict.js new file mode 100644 index 000000000..c9c402761 --- /dev/null +++ b/js/src/jit-test/tests/basic/write-frozen-property-strict.js @@ -0,0 +1,14 @@ +function foo(x) { + "use strict"; + var ok = false; + try { + x.a = 10; + } catch(e) { + ok = true; + } + assertEq(ok, true); + assertEq(x.a, 0); +} +x = {a:0,b:1}; +Object.freeze(x); +foo(x); diff --git a/js/src/jit-test/tests/basic/write-frozen-property.js b/js/src/jit-test/tests/basic/write-frozen-property.js new file mode 100644 index 000000000..a6228fbb0 --- /dev/null +++ b/js/src/jit-test/tests/basic/write-frozen-property.js @@ -0,0 +1,7 @@ +function foo(x) { + x.a = 10; + assertEq(x.a, 0); +} +x = {a:0,b:1}; +Object.freeze(x); +foo(x); diff --git a/js/src/jit-test/tests/basic/xml-in-strict.js b/js/src/jit-test/tests/basic/xml-in-strict.js new file mode 100644 index 000000000..0e2ddf89b --- /dev/null +++ b/js/src/jit-test/tests/basic/xml-in-strict.js @@ -0,0 +1,17 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function checkSyntaxError(code) { + var error; + try { + eval(code); + } catch (e) { + error = e; + } + assertEq(error.name, 'SyntaxError'); +} + +checkSyntaxError('"use strict"; *'); +checkSyntaxError('"use strict"; @7'); diff --git a/js/src/jit-test/tests/basic/xprop.js b/js/src/jit-test/tests/basic/xprop.js new file mode 100644 index 000000000..9fdbb6663 --- /dev/null +++ b/js/src/jit-test/tests/basic/xprop.js @@ -0,0 +1,8 @@ +function xprop() +{ + a = 0; + for (var i = 0; i < 20; i++) + a += 7; + return a; +} +assertEq(xprop(), 140); |