summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/arrow-functions
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit-test/tests/arrow-functions
parentInitial commit. (diff)
downloadfirefox-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')
-rw-r--r--js/src/jit-test/tests/arrow-functions/arguments-1.js5
-rw-r--r--js/src/jit-test/tests/arrow-functions/arguments-2.js9
-rw-r--r--js/src/jit-test/tests/arrow-functions/arguments-3.js16
-rw-r--r--js/src/jit-test/tests/arrow-functions/arguments-4.js22
-rw-r--r--js/src/jit-test/tests/arrow-functions/associativity-1.js8
-rw-r--r--js/src/jit-test/tests/arrow-functions/associativity-2.js8
-rw-r--r--js/src/jit-test/tests/arrow-functions/associativity-3.js5
-rw-r--r--js/src/jit-test/tests/arrow-functions/block-1.js6
-rw-r--r--js/src/jit-test/tests/arrow-functions/block-2.js4
-rw-r--r--js/src/jit-test/tests/arrow-functions/bug-885067-1.js3
-rw-r--r--js/src/jit-test/tests/arrow-functions/bug-885067-2.js28
-rw-r--r--js/src/jit-test/tests/arrow-functions/bug-885219.js2
-rw-r--r--js/src/jit-test/tests/arrow-functions/church-1.js17
-rw-r--r--js/src/jit-test/tests/arrow-functions/church-2.js19
-rw-r--r--js/src/jit-test/tests/arrow-functions/close-paren-arrow-after-expr.js8
-rw-r--r--js/src/jit-test/tests/arrow-functions/column-number.js6
-rw-r--r--js/src/jit-test/tests/arrow-functions/const-1.js11
-rw-r--r--js/src/jit-test/tests/arrow-functions/construct-1.js7
-rw-r--r--js/src/jit-test/tests/arrow-functions/eval-1.js9
-rw-r--r--js/src/jit-test/tests/arrow-functions/lazy-arrow-1.js18
-rw-r--r--js/src/jit-test/tests/arrow-functions/length.js11
-rw-r--r--js/src/jit-test/tests/arrow-functions/params-1.js6
-rw-r--r--js/src/jit-test/tests/arrow-functions/params-2.js6
-rw-r--r--js/src/jit-test/tests/arrow-functions/params-default-1.js5
-rw-r--r--js/src/jit-test/tests/arrow-functions/params-default-2.js8
-rw-r--r--js/src/jit-test/tests/arrow-functions/params-rest-1.js7
-rw-r--r--js/src/jit-test/tests/arrow-functions/params-rest-2.js7
-rw-r--r--js/src/jit-test/tests/arrow-functions/precedence-1.js7
-rw-r--r--js/src/jit-test/tests/arrow-functions/precedence-2.js6
-rw-r--r--js/src/jit-test/tests/arrow-functions/precedence-3.js4
-rw-r--r--js/src/jit-test/tests/arrow-functions/precedence-4.js6
-rw-r--r--js/src/jit-test/tests/arrow-functions/precedence-5.js3
-rw-r--r--js/src/jit-test/tests/arrow-functions/prototype-1.js4
-rw-r--r--js/src/jit-test/tests/arrow-functions/prototype-2.js4
-rw-r--r--js/src/jit-test/tests/arrow-functions/return-1.js9
-rw-r--r--js/src/jit-test/tests/arrow-functions/return-2.js8
-rw-r--r--js/src/jit-test/tests/arrow-functions/return-3.js10
-rw-r--r--js/src/jit-test/tests/arrow-functions/strict-1.js13
-rw-r--r--js/src/jit-test/tests/arrow-functions/strict-2.js11
-rw-r--r--js/src/jit-test/tests/arrow-functions/strict-3.js4
-rw-r--r--js/src/jit-test/tests/arrow-functions/syntax-errors.js38
-rw-r--r--js/src/jit-test/tests/arrow-functions/this-1.js17
-rw-r--r--js/src/jit-test/tests/arrow-functions/this-2.js13
-rw-r--r--js/src/jit-test/tests/arrow-functions/this-3.js13
-rw-r--r--js/src/jit-test/tests/arrow-functions/this-4.js5
-rw-r--r--js/src/jit-test/tests/arrow-functions/this-5.js12
-rw-r--r--js/src/jit-test/tests/arrow-functions/this-6.js11
-rw-r--r--js/src/jit-test/tests/arrow-functions/typeof.js4
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");