diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit-test/tests/arrow-functions | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/jit-test/tests/arrow-functions')
48 files changed, 463 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/arrow-functions/arguments-1.js b/js/src/jit-test/tests/arrow-functions/arguments-1.js new file mode 100644 index 0000000000..1bd8bc0cdc --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/arguments-1.js @@ -0,0 +1,5 @@ +// no 'arguments' binding in arrow functions + +var arguments = []; +var f = () => arguments; +assertEq(f(), arguments); diff --git a/js/src/jit-test/tests/arrow-functions/arguments-2.js b/js/src/jit-test/tests/arrow-functions/arguments-2.js new file mode 100644 index 0000000000..d6ad23ce8c --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/arguments-2.js @@ -0,0 +1,9 @@ +// 'arguments' is lexically scoped in arrow functions + +var args, g; +function f() { + g = () => arguments; + args = arguments; +} +f(); +assertEq(g(), args); diff --git a/js/src/jit-test/tests/arrow-functions/arguments-3.js b/js/src/jit-test/tests/arrow-functions/arguments-3.js new file mode 100644 index 0000000000..f4453438c1 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/arguments-3.js @@ -0,0 +1,16 @@ +// 'arguments' in eval + +function f() { + var g = s => eval(s); + assertEq(g("arguments"), arguments); +} + +f(); +f(0, 1, 2); + +function h() { + return s => eval(s); +} +var result = h(1, 2, 3, 4)("arguments"); +assertEq(result.length, 4); +assertEq(result[3], 4); diff --git a/js/src/jit-test/tests/arrow-functions/arguments-4.js b/js/src/jit-test/tests/arrow-functions/arguments-4.js new file mode 100644 index 0000000000..8a28cee06f --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/arguments-4.js @@ -0,0 +1,22 @@ +load(libdir + "asserts.js"); + +// 'arguments' is allowed in a non-arrow-function with a rest param. +assertEq((function(...rest) { return (x => arguments)(1, 2)})().length, 0); + +function restAndArgs(...rest) { + return () => eval("arguments"); +} + +var args = restAndArgs(1, 2, 3)(); +assertEq(args.length, 3); +assertEq(args[0], 1); +assertEq(args[1], 2); +assertEq(args[2], 3); + +(function() { + return ((...rest) => { + assertDeepEq(rest, [1, 2, 3]); + assertEq(arguments.length, 2); + assertEq(eval("arguments").length, 2); + })(1, 2, 3); +})(4, 5); diff --git a/js/src/jit-test/tests/arrow-functions/associativity-1.js b/js/src/jit-test/tests/arrow-functions/associativity-1.js new file mode 100644 index 0000000000..a3ce3ea34a --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/associativity-1.js @@ -0,0 +1,8 @@ +// Arrow right-associativity. + +var t = a => b => a; +assertEq(t('A')('B'), 'A'); + +var curry = f => a => b => f(a, b); +var curried_atan2 = curry(Math.atan2); +assertEq(curried_atan2(0)(1), 0); diff --git a/js/src/jit-test/tests/arrow-functions/associativity-2.js b/js/src/jit-test/tests/arrow-functions/associativity-2.js new file mode 100644 index 0000000000..45712965f0 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/associativity-2.js @@ -0,0 +1,8 @@ +// Arrow right-associativity with = + +var a, b, c; +a = b = c => a = b = c; +assertEq(a, b); +a(13); +assertEq(b, 13); +assertEq(a, 13); diff --git a/js/src/jit-test/tests/arrow-functions/associativity-3.js b/js/src/jit-test/tests/arrow-functions/associativity-3.js new file mode 100644 index 0000000000..2be671c5b9 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/associativity-3.js @@ -0,0 +1,5 @@ +// Arrow right-associativity with += + +var s = ""; +s += x => x.name; +assertEq(s, "x => x.name"); diff --git a/js/src/jit-test/tests/arrow-functions/block-1.js b/js/src/jit-test/tests/arrow-functions/block-1.js new file mode 100644 index 0000000000..7bfdf43a6d --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/block-1.js @@ -0,0 +1,6 @@ +// Braces after => indicate a block body as opposed to an expression body. + +var f = () => {}; +assertEq(f(), undefined); +var g = () => ({}); +assertEq(typeof g(), 'object'); diff --git a/js/src/jit-test/tests/arrow-functions/block-2.js b/js/src/jit-test/tests/arrow-functions/block-2.js new file mode 100644 index 0000000000..66637f53fa --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/block-2.js @@ -0,0 +1,4 @@ +// Block arrow functions don't return the last expression-statement value automatically. + +var f = a => { a + 1; }; +assertEq(f(0), undefined); diff --git a/js/src/jit-test/tests/arrow-functions/bug-885067-1.js b/js/src/jit-test/tests/arrow-functions/bug-885067-1.js new file mode 100644 index 0000000000..04ee5fe507 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/bug-885067-1.js @@ -0,0 +1,3 @@ +(function() { + a = (b => eval("0; [arguments]"))(); +})(); diff --git a/js/src/jit-test/tests/arrow-functions/bug-885067-2.js b/js/src/jit-test/tests/arrow-functions/bug-885067-2.js new file mode 100644 index 0000000000..a45bdccb8d --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/bug-885067-2.js @@ -0,0 +1,28 @@ +// deoptimize `arguments` in the arrow's closest enclosing non-arrow-function + +// non-arrow-function -> arrow function +a = 0; +(function() { + a = (() => eval("arguments"))(); +})(1, 2, 3, 4); +assertEq(a.length, 4); + +// non-arrow-function -> arrow function -> arrow function +a = 0; +(function() { + (() => { + a = (() => eval("arguments"))(); + })(); +})(1, 2, 3, 4); +assertEq(a.length, 4); + +// non-arrow-function -> arrow function -> non-arrow-function -> arrow function +a = 0; +(function() { + (() => { + (function () { + a = (() => eval("arguments"))(); + })(1, 2, 3, 4); + })(); +})(); +assertEq(a.length, 4); diff --git a/js/src/jit-test/tests/arrow-functions/bug-885219.js b/js/src/jit-test/tests/arrow-functions/bug-885219.js new file mode 100644 index 0000000000..70544bde8d --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/bug-885219.js @@ -0,0 +1,2 @@ +if (typeof disassemble === "function") + disassemble("-r", Function("()=>e,d")); diff --git a/js/src/jit-test/tests/arrow-functions/church-1.js b/js/src/jit-test/tests/arrow-functions/church-1.js new file mode 100644 index 0000000000..7849980a53 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/church-1.js @@ -0,0 +1,17 @@ +// Church booleans + +var True = t => f => t; +var False = t => f => f; +var bool_to_str = b => b("True")("False"); +var And = a => b => a(b)(a); +var Or = a => b => a(a)(b); + +assertEq(And(True)(True), True); +assertEq(And(True)(False), False); +assertEq(And(False)(True), False); +assertEq(And(False)(False), False); + +assertEq(Or(True)(True), True); +assertEq(Or(True)(False), True); +assertEq(Or(False)(True), True); +assertEq(Or(False)(False), False); diff --git a/js/src/jit-test/tests/arrow-functions/church-2.js b/js/src/jit-test/tests/arrow-functions/church-2.js new file mode 100644 index 0000000000..d38be6fdb4 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/church-2.js @@ -0,0 +1,19 @@ +// Church-Peano integers + +var Zero = f => x => x; +var Succ = n => f => x => n(f)(f(x)); +var Add = a => b => f => x => a(f)(b(f)(x)); +var Mul = a => b => f => x => a(b(f))(x); +var Exp = a => b => b(a); + +var n = f => f(k => k + 1)(0); + +assertEq(n(Zero), 0); +assertEq(n(Succ(Zero)), 1); +assertEq(n(Succ(Succ(Zero))), 2); + +var Three = Succ(Succ(Succ(Zero))); +var Five = Succ(Succ(Three)); +assertEq(n(Add(Three)(Five)), 8); +assertEq(n(Mul(Three)(Five)), 15); +assertEq(n(Exp(Three)(Five)), 243); diff --git a/js/src/jit-test/tests/arrow-functions/close-paren-arrow-after-expr.js b/js/src/jit-test/tests/arrow-functions/close-paren-arrow-after-expr.js new file mode 100644 index 0000000000..a9ecb7caaa --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/close-paren-arrow-after-expr.js @@ -0,0 +1,8 @@ +var caught = false; +try { + eval("1\n)=>"); +} catch (e) { + assertEq(e instanceof SyntaxError, true); + caught = true; +} +assertEq(caught, true); diff --git a/js/src/jit-test/tests/arrow-functions/column-number.js b/js/src/jit-test/tests/arrow-functions/column-number.js new file mode 100644 index 0000000000..eed3b6d72c --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/column-number.js @@ -0,0 +1,6 @@ +function f() { return g(abcd => Error()); } +function g(x) { return x(); } +var err = f(1, 2); +var lines = err.stack.split("\n"); +assertEq(lines[0].endsWith(":1:33"), true); +assertEq(lines[1].endsWith(":2:24"), true);
\ No newline at end of file diff --git a/js/src/jit-test/tests/arrow-functions/const-1.js b/js/src/jit-test/tests/arrow-functions/const-1.js new file mode 100644 index 0000000000..f8e7fce4c2 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/const-1.js @@ -0,0 +1,11 @@ +// Arguments with default parameters can shadow const locals. + +"use strict"; + +function f() { + const x = 1; + return (x = 0) => x; +} + +var g = f(); +assertEq(g(), 0); diff --git a/js/src/jit-test/tests/arrow-functions/construct-1.js b/js/src/jit-test/tests/arrow-functions/construct-1.js new file mode 100644 index 0000000000..0871888e3d --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/construct-1.js @@ -0,0 +1,7 @@ +// Arrow functions are not constructors. + +load(libdir + "asserts.js"); + +var f = a => { this.a = a; }; +assertThrowsInstanceOf(() => new f, TypeError); +assertThrowsInstanceOf(() => new f(1, 2), TypeError); diff --git a/js/src/jit-test/tests/arrow-functions/eval-1.js b/js/src/jit-test/tests/arrow-functions/eval-1.js new file mode 100644 index 0000000000..fba4de65f0 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/eval-1.js @@ -0,0 +1,9 @@ +// Arrow functions in direct eval code. + +function f(s) { + var a = 2; + return eval(s); +} + +var c = f("k => a + k"); // closure should see 'a' +assertEq(c(3), 5); diff --git a/js/src/jit-test/tests/arrow-functions/lazy-arrow-1.js b/js/src/jit-test/tests/arrow-functions/lazy-arrow-1.js new file mode 100644 index 0000000000..d8678f35dd --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/lazy-arrow-1.js @@ -0,0 +1,18 @@ +function f() { + let z = (a = (() => 10), + b = (() => 20)) => { + return [a, b]; + } + + function g() { + return 30; + } + + return [...z(), g]; +} + +let [a, b, c] = f(); + +assertEq(a(), 10); +assertEq(b(), 20); +assertEq(c(), 30); diff --git a/js/src/jit-test/tests/arrow-functions/length.js b/js/src/jit-test/tests/arrow-functions/length.js new file mode 100644 index 0000000000..53ca3e64df --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/length.js @@ -0,0 +1,11 @@ +// Arrow functions have a .length property like ordinary functions. + +assertEq((a => a).hasOwnProperty("length"), true); + +assertEq((a => a).length, 1); +assertEq((() => 0).length, 0); +assertEq(((a) => 0).length, 1); +assertEq(((a, b) => 0).length, 2); + +assertEq(((...arr) => arr).length, 0); +assertEq(((a=1, b=2) => 0).length, 0); diff --git a/js/src/jit-test/tests/arrow-functions/params-1.js b/js/src/jit-test/tests/arrow-functions/params-1.js new file mode 100644 index 0000000000..5c2395c394 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/params-1.js @@ -0,0 +1,6 @@ +// arrow functions may have empty arguments + +var f = () => 'x'; +assertEq(f.length, 0); +assertEq(f(), 'x'); +assertEq(f(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), 'x'); diff --git a/js/src/jit-test/tests/arrow-functions/params-2.js b/js/src/jit-test/tests/arrow-functions/params-2.js new file mode 100644 index 0000000000..a5520166a7 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/params-2.js @@ -0,0 +1,6 @@ +// (a) => expr + +var f = (a) => 2 * a; // parens are allowed +assertEq(f(12), 24); +var g = (a, b) => a + b; +assertEq([1, 2, 3, 4, 5].reduce((a, b) => a + b), 15); diff --git a/js/src/jit-test/tests/arrow-functions/params-default-1.js b/js/src/jit-test/tests/arrow-functions/params-default-1.js new file mode 100644 index 0000000000..c4ff50774b --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/params-default-1.js @@ -0,0 +1,5 @@ +// Parameter default values work in arrow functions + +var f = (a=0) => a + 1; +assertEq(f(), 1); +assertEq(f(50), 51); diff --git a/js/src/jit-test/tests/arrow-functions/params-default-2.js b/js/src/jit-test/tests/arrow-functions/params-default-2.js new file mode 100644 index 0000000000..746911e578 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/params-default-2.js @@ -0,0 +1,8 @@ +// Parameter default values work in arrow functions + +load(libdir + "asserts.js"); + +var f = (a=1, b=2, ...rest) => [a, b, rest]; +assertDeepEq(f(), [1, 2, []]); +assertDeepEq(f(0, 0), [0, 0, []]); +assertDeepEq(f(0, 1, 1, 2, 3, 5), [0, 1, [1, 2, 3, 5]]); diff --git a/js/src/jit-test/tests/arrow-functions/params-rest-1.js b/js/src/jit-test/tests/arrow-functions/params-rest-1.js new file mode 100644 index 0000000000..2e35fb15fa --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/params-rest-1.js @@ -0,0 +1,7 @@ +// Rest parameters are allowed in arrow functions. + +load(libdir + "asserts.js"); + +var A = (...x) => x; +assertDeepEq(A(), []); +assertEq("" + A(3, 4, 5), "3,4,5"); diff --git a/js/src/jit-test/tests/arrow-functions/params-rest-2.js b/js/src/jit-test/tests/arrow-functions/params-rest-2.js new file mode 100644 index 0000000000..b98650a61a --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/params-rest-2.js @@ -0,0 +1,7 @@ +// Rest parameters work in arrow functions + +load(libdir + "asserts.js"); + +var f = (a, b, ...rest) => [a, b, rest]; +assertDeepEq(f(), [(void 0), (void 0), []]); +assertDeepEq(f(1, 2, 3, 4), [1, 2, [3, 4]]); diff --git a/js/src/jit-test/tests/arrow-functions/precedence-1.js b/js/src/jit-test/tests/arrow-functions/precedence-1.js new file mode 100644 index 0000000000..f84826cf1e --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/precedence-1.js @@ -0,0 +1,7 @@ +// || binds tighter than =>. + +var f; +f = a => a || 'nothing'; // f = ((a => a) || 'nothing'); +assertEq(f.length, 1); +assertEq(f(0), 'nothing'); +assertEq(f(1), 1); diff --git a/js/src/jit-test/tests/arrow-functions/precedence-2.js b/js/src/jit-test/tests/arrow-functions/precedence-2.js new file mode 100644 index 0000000000..479cb20a45 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/precedence-2.js @@ -0,0 +1,6 @@ +// => binds tighter than , + +var f, g; +g = (f, h => h + 1); // sequence expression: (f, (h => h + 1)) +assertEq(g.length, 1); +assertEq(g(37), 38); diff --git a/js/src/jit-test/tests/arrow-functions/precedence-3.js b/js/src/jit-test/tests/arrow-functions/precedence-3.js new file mode 100644 index 0000000000..761b171888 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/precedence-3.js @@ -0,0 +1,4 @@ +// => binds tighter than , (on the other side) + +var h = (a => a, 13); // sequence expression +assertEq(h, 13); diff --git a/js/src/jit-test/tests/arrow-functions/precedence-4.js b/js/src/jit-test/tests/arrow-functions/precedence-4.js new file mode 100644 index 0000000000..ca3e30d6e2 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/precedence-4.js @@ -0,0 +1,6 @@ +// Funny case that looks kind of like default arguments isn't. + +var f = (msg='hi', w=window => w.alert(a, b)); // sequence expression +assertEq(msg, 'hi'); +assertEq(typeof w, 'function'); +assertEq(f, w); diff --git a/js/src/jit-test/tests/arrow-functions/precedence-5.js b/js/src/jit-test/tests/arrow-functions/precedence-5.js new file mode 100644 index 0000000000..9418aac0b3 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/precedence-5.js @@ -0,0 +1,3 @@ +// map(x => x, 32) is two arguments, not one + +assertEq("" + [1, 2, 3, 4].map(x => x, 32), "1,2,3,4"); diff --git a/js/src/jit-test/tests/arrow-functions/prototype-1.js b/js/src/jit-test/tests/arrow-functions/prototype-1.js new file mode 100644 index 0000000000..57922420f1 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/prototype-1.js @@ -0,0 +1,4 @@ +// The prototype of an arrow function is Function.prototype. + +assertEq(Object.getPrototypeOf(a => a), Function.prototype); +assertEq(Object.getPrototypeOf(() => {}), Function.prototype); diff --git a/js/src/jit-test/tests/arrow-functions/prototype-2.js b/js/src/jit-test/tests/arrow-functions/prototype-2.js new file mode 100644 index 0000000000..6573783a92 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/prototype-2.js @@ -0,0 +1,4 @@ +// Arrow functions do not have a .prototype property. + +assertEq("prototype" in (a => a), false); +assertEq("prototype" in (() => {}), false); diff --git a/js/src/jit-test/tests/arrow-functions/return-1.js b/js/src/jit-test/tests/arrow-functions/return-1.js new file mode 100644 index 0000000000..b89d979e2d --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/return-1.js @@ -0,0 +1,9 @@ +// return from a block function works when there is no other enclosing function + +var f = a => { + if (a) + return a + 1; + throw "FAIL"; +}; + +assertEq(f(1), 2); diff --git a/js/src/jit-test/tests/arrow-functions/return-2.js b/js/src/jit-test/tests/arrow-functions/return-2.js new file mode 100644 index 0000000000..b4ecebb842 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/return-2.js @@ -0,0 +1,8 @@ +// return exits the innermost enclosing arrow (not an enclosing function) + +function f() { + var g = x => { return !x; }; + return "f:" + g(true); +} + +assertEq(f(), "f:false"); diff --git a/js/src/jit-test/tests/arrow-functions/return-3.js b/js/src/jit-test/tests/arrow-functions/return-3.js new file mode 100644 index 0000000000..ea71fb138a --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/return-3.js @@ -0,0 +1,10 @@ +// return exits the innermost enclosing arrow (not an enclosing arrow) + +load(libdir + "asserts.js"); + +function f() { + var g = a => [0, 1].map(x => { return x + a; }); + return g(13); +} + +assertDeepEq(f(), [13, 14]); diff --git a/js/src/jit-test/tests/arrow-functions/strict-1.js b/js/src/jit-test/tests/arrow-functions/strict-1.js new file mode 100644 index 0000000000..9bb715a4c9 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/strict-1.js @@ -0,0 +1,13 @@ +// arrow functions are not implicitly strict-mode code + +load(libdir + "asserts.js"); + +var f = a => { with (a) return f(); }; +assertEq(f({f: () => 7}), 7); + +f = a => function () { with (a) return f(); }; +assertEq(f({f: () => 7})(), 7); + +f = (a = {x: 1, x: 2}) => b => { "use strict"; return a.x; }; +assertEq(f()(0), 2); + diff --git a/js/src/jit-test/tests/arrow-functions/strict-2.js b/js/src/jit-test/tests/arrow-functions/strict-2.js new file mode 100644 index 0000000000..150b2ddb0e --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/strict-2.js @@ -0,0 +1,11 @@ +// code in arrow function default arguments is strict if arrow is strict + +load(libdir + "asserts.js"); + +assertThrowsInstanceOf( + () => Function("'use strict'; (a = function (obj) { with (obj) f(); }) => { }"), + SyntaxError); + +assertThrowsInstanceOf( + () => Function("'use strict'; (a = obj => { with (obj) f(); }) => { }"), + SyntaxError); diff --git a/js/src/jit-test/tests/arrow-functions/strict-3.js b/js/src/jit-test/tests/arrow-functions/strict-3.js new file mode 100644 index 0000000000..24150cfd77 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/strict-3.js @@ -0,0 +1,4 @@ +// "use strict" is not special as the body of an arrow function without braces. + +var f = (a = obj => { with (obj) return x; }) => "use strict"; +assertEq(f(), "use strict"); diff --git a/js/src/jit-test/tests/arrow-functions/syntax-errors.js b/js/src/jit-test/tests/arrow-functions/syntax-errors.js new file mode 100644 index 0000000000..925fd5b894 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/syntax-errors.js @@ -0,0 +1,38 @@ +// Check that we correctly throw SyntaxErrors for various syntactic near-misses. + +load(libdir + "asserts.js"); + +var mistakes = [ + "((a)) => expr", + "a + b => a", + "'' + a => a", + "...x", + "[x] => x", + "([x] => x)", + "{p: p} => p", + "({p: p} => p)", + "{p} => p", + "(...x => expr)", + "1 || a => a", + "'use strict' => {}", + "package => {'use strict';}", // tricky: FutureReservedWord in strict mode code only + "'use strict'; arguments => 0", // names banned in strict mode code + "'use strict'; eval => 0", + "a => {'use strict'; with (a) return x; }", + "a => yield a", + "a => { yield a; }", + "a => { { let x; yield a; } }", + "(a = yield 0) => a", + "for (;;) a => { break; };", + "for (;;) a => { continue; };", + "...rest) =>", + "2 + ...rest) =>" +]; + +for (var s of mistakes) + assertThrowsInstanceOf(function () { Function(s); }, SyntaxError); + +// Check that the tricky case is not an error in non-strict-mode code. +var f = package => 0; +assertEq(f(1), 0); + diff --git a/js/src/jit-test/tests/arrow-functions/this-1.js b/js/src/jit-test/tests/arrow-functions/this-1.js new file mode 100644 index 0000000000..1367052700 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/this-1.js @@ -0,0 +1,17 @@ +// 'this' is lexically scoped in arrow functions + +var obj = { + f: function (expected) { + assertEq(this, expected); + return a => this; + } +}; + +var g = obj.f(obj); +assertEq(g(), obj); + +var obj2 = {f: obj.f}; +var g2 = obj2.f(obj2); +assertEq(g2(), obj2); +assertEq(g(), obj); + diff --git a/js/src/jit-test/tests/arrow-functions/this-2.js b/js/src/jit-test/tests/arrow-functions/this-2.js new file mode 100644 index 0000000000..3dac3c863d --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/this-2.js @@ -0,0 +1,13 @@ +// 'this' is lexically scoped in direct eval code in arrow functions + +var obj = { + f: function (s) { + return a => eval(s); + } +}; + +var g = obj.f("this"); +assertEq(g(), obj); + +var obj2 = {g: g, fail: true}; +assertEq(obj2.g(), obj); diff --git a/js/src/jit-test/tests/arrow-functions/this-3.js b/js/src/jit-test/tests/arrow-functions/this-3.js new file mode 100644 index 0000000000..59398a3cb3 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/this-3.js @@ -0,0 +1,13 @@ +// 'this' is lexically scoped in arrow functions in direct eval code + +var obj = { + f: function (s) { + return eval(s); + } +}; + +var g = obj.f("a => this"); +assertEq(g(), obj); + +var obj2 = {g: g, fail: true}; +assertEq(obj2.g(), obj); diff --git a/js/src/jit-test/tests/arrow-functions/this-4.js b/js/src/jit-test/tests/arrow-functions/this-4.js new file mode 100644 index 0000000000..0379ef86e5 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/this-4.js @@ -0,0 +1,5 @@ +// 'this' in a toplevel arrow is the global object. + +var f = () => this; +assertEq(f(), this); +assertEq({f: f}.f(), this); diff --git a/js/src/jit-test/tests/arrow-functions/this-5.js b/js/src/jit-test/tests/arrow-functions/this-5.js new file mode 100644 index 0000000000..98b7bf8168 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/this-5.js @@ -0,0 +1,12 @@ +// Arrow functions can have primitive |this| values. + +Number.prototype.foo = function() { + "use strict"; + return () => this; +} + +for (var i=0; i<5; i++) { + var n = i.foo()(); + assertEq(typeof n, "number"); + assertEq(n, i); +} diff --git a/js/src/jit-test/tests/arrow-functions/this-6.js b/js/src/jit-test/tests/arrow-functions/this-6.js new file mode 100644 index 0000000000..c5ee4d95a3 --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/this-6.js @@ -0,0 +1,11 @@ +// Eval expressions in arrow functions use the correct |this| value. + +function Dog(name) { + this.name = name; + this.getName = () => eval("this.name"); + this.getNameHard = () => eval("(() => this.name)()"); +} + +var d = new Dog("Max"); +assertEq(d.getName(), d.name); +assertEq(d.getNameHard(), d.name); diff --git a/js/src/jit-test/tests/arrow-functions/typeof.js b/js/src/jit-test/tests/arrow-functions/typeof.js new file mode 100644 index 0000000000..a610deb91c --- /dev/null +++ b/js/src/jit-test/tests/arrow-functions/typeof.js @@ -0,0 +1,4 @@ +// The typeof an arrow function is "function". + +assertEq(typeof (() => 1), "function"); +assertEq(typeof (a => { return a + 1; }), "function"); |