summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/Function
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_6/Function')
-rw-r--r--js/src/tests/ecma_6/Function/arguments-extra-property.js33
-rw-r--r--js/src/tests/ecma_6/Function/arguments-iterator.js167
-rw-r--r--js/src/tests/ecma_6/Function/arguments-parameter-shadowing.js22
-rw-r--r--js/src/tests/ecma_6/Function/arrow-has-duplicated.js15
-rw-r--r--js/src/tests/ecma_6/Function/bound-length-and-name.js40
-rw-r--r--js/src/tests/ecma_6/Function/bound-non-constructable.js17
-rw-r--r--js/src/tests/ecma_6/Function/bound-prototype.js37
-rw-r--r--js/src/tests/ecma_6/Function/browser.js0
-rw-r--r--js/src/tests/ecma_6/Function/configurable-length-builtins.js21
-rw-r--r--js/src/tests/ecma_6/Function/configurable-length.js86
-rw-r--r--js/src/tests/ecma_6/Function/construct-bound-proxy-with-many-arguments.js13
-rw-r--r--js/src/tests/ecma_6/Function/function-constructor-toString-arguments-before-parsing-params.js23
-rw-r--r--js/src/tests/ecma_6/Function/function-name.js64
-rw-r--r--js/src/tests/ecma_6/Function/has-instance-jitted.js96
-rw-r--r--js/src/tests/ecma_6/Function/has-instance.js101
-rw-r--r--js/src/tests/ecma_6/Function/length-with-destructuring-and-parameter-expression.js31
-rw-r--r--js/src/tests/ecma_6/Function/line-terminator-before-arrow.js9
-rw-r--r--js/src/tests/ecma_6/Function/method-has-duplicated.js19
-rw-r--r--js/src/tests/ecma_6/Function/parameter-redeclaration.js19
-rw-r--r--js/src/tests/ecma_6/Function/rest-has-duplicated.js17
-rw-r--r--js/src/tests/ecma_6/Function/rest-parameter-names.js68
-rw-r--r--js/src/tests/ecma_6/Function/return-finally.js172
-rw-r--r--js/src/tests/ecma_6/Function/shell.js0
-rw-r--r--js/src/tests/ecma_6/Function/spread-iterator-primitive.js28
24 files changed, 1098 insertions, 0 deletions
diff --git a/js/src/tests/ecma_6/Function/arguments-extra-property.js b/js/src/tests/ecma_6/Function/arguments-extra-property.js
new file mode 100644
index 000000000..017734382
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/arguments-extra-property.js
@@ -0,0 +1,33 @@
+var BUGNUMBER = 1263811;
+var summary = "GetElem for modified arguments shouldn't be optimized to get original argument.";
+
+print(BUGNUMBER + ": " + summary);
+
+function testModifyFirst() {
+ function f() {
+ Object.defineProperty(arguments, 1, { value: 30 });
+ assertEq(arguments[1], 30);
+ }
+ for (let i = 0; i < 10; i++)
+ f(10, 20);
+}
+testModifyFirst();
+
+function testModifyLater() {
+ function f() {
+ var ans = 20;
+ for (let i = 0; i < 10; i++) {
+ if (i == 5) {
+ Object.defineProperty(arguments, 1, { value: 30 });
+ ans = 30;
+ }
+ assertEq(arguments[1], ans);
+ }
+ }
+ for (let i = 0; i < 10; i++)
+ f(10, 20);
+}
+testModifyLater();
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Function/arguments-iterator.js b/js/src/tests/ecma_6/Function/arguments-iterator.js
new file mode 100644
index 000000000..5610b8a24
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/arguments-iterator.js
@@ -0,0 +1,167 @@
+var BUGNUMBER = 992617;
+var summary = "Implement arguments[@@iterator].";
+
+print(BUGNUMBER + ": " + summary);
+
+// MappedArgumentsObject
+let mapped = [
+ function(a, b, c) {
+ assertEq(Symbol.iterator in arguments, true);
+ delete arguments[Symbol.iterator];
+ assertEq(Symbol.iterator in arguments, false);
+ },
+ function(a, b, c) {
+ delete arguments[Symbol.iterator];
+ assertEq(Symbol.iterator in arguments, false);
+ },
+ function(a, b, c) {
+ arguments[Symbol.iterator] = 10;
+ delete arguments[Symbol.iterator];
+ assertEq(Symbol.iterator in arguments, false);
+ },
+ function(a, b, c) {
+ Object.defineProperty(arguments, Symbol.iterator, {
+ value: 10, writable: true, enumerable: true, configurable: true
+ });
+ delete arguments[Symbol.iterator];
+ assertEq(Symbol.iterator in arguments, false);
+ },
+ function(a, b, c) {
+ assertEq(arguments[Symbol.iterator], Array.prototype[Symbol.iterator]);
+ },
+ function(a, b, c) {
+ assertEq(arguments[Symbol.iterator].name, "values");
+ },
+ function(a, b, c) {
+ var desc = Object.getOwnPropertyDescriptor(arguments, Symbol.iterator);
+ assertEq("value" in desc, true);
+ assertEq(desc.value, Array.prototype[Symbol.iterator]);
+ assertEq(desc.writable, true);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, true);
+ },
+ function(a, b, c) {
+ var iter = arguments[Symbol.iterator]();
+ assertDeepEq(iter.next(), { value: 10, done: false });
+ assertDeepEq(iter.next(), { value: 20, done: false });
+ assertDeepEq(iter.next(), { value: 30, done: false });
+ assertDeepEq(iter.next(), { value: undefined, done: true });
+ },
+ function(a, b, c) {
+ assertDeepEq([...arguments], [10, 20, 30]);
+ },
+ function(a, b, c) {
+ b = 40;
+ assertDeepEq([...arguments], [10, 40, 30]);
+ },
+ function(a, b, c) {
+ arguments.length = 4;
+ assertDeepEq([...arguments], [10, 20, 30, undefined]);
+ },
+ function(a, b, c) {
+ arguments[5] = 50;
+ assertDeepEq([...arguments], [10, 20, 30]);
+ },
+ function(a, b, c) {
+ arguments[Symbol.iterator] = function*() {
+ yield 40;
+ yield 50;
+ yield 60;
+ };
+ assertDeepEq([...arguments], [40, 50, 60]);
+ },
+];
+for (let f of mapped) {
+ f(10, 20, 30);
+}
+
+var g1 = newGlobal();
+assertEq(g1.eval(`
+function f(a, b, c) {
+ return arguments[Symbol.iterator].name;
+}
+f(1, 2, 3);
+`), "values");
+
+// UnmappedArgumentsObject
+let unmapped = [
+ function([a], b, c) {
+ assertEq(Symbol.iterator in arguments, true);
+ delete arguments[Symbol.iterator];
+ assertEq(Symbol.iterator in arguments, false);
+ },
+ function([a], b, c) {
+ delete arguments[Symbol.iterator];
+ assertEq(Symbol.iterator in arguments, false);
+ },
+ function([a], b, c) {
+ arguments[Symbol.iterator] = 10;
+ delete arguments[Symbol.iterator];
+ assertEq(Symbol.iterator in arguments, false);
+ },
+ function([a], b, c) {
+ Object.defineProperty(arguments, Symbol.iterator, {
+ value: 10, writable: true, enumerable: true, configurable: true
+ });
+ delete arguments[Symbol.iterator];
+ assertEq(Symbol.iterator in arguments, false);
+ },
+ function([a], b, c) {
+ assertEq(arguments[Symbol.iterator], Array.prototype[Symbol.iterator]);
+ },
+ function([a], b, c) {
+ assertEq(arguments[Symbol.iterator].name, "values");
+ },
+ function([a], b, c) {
+ var desc = Object.getOwnPropertyDescriptor(arguments, Symbol.iterator);
+ assertEq("value" in desc, true);
+ assertEq(desc.value, Array.prototype[Symbol.iterator]);
+ assertEq(desc.writable, true);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, true);
+ },
+ function([a], b, c) {
+ var iter = arguments[Symbol.iterator]();
+ assertDeepEq(iter.next(), { value: [10], done: false });
+ assertDeepEq(iter.next(), { value: 20, done: false });
+ assertDeepEq(iter.next(), { value: 30, done: false });
+ assertDeepEq(iter.next(), { value: undefined, done: true });
+ },
+ function([a], b, c) {
+ assertDeepEq([...arguments], [[10], 20, 30]);
+ },
+ function([a], b, c) {
+ b = 40;
+ assertDeepEq([...arguments], [[10], 20, 30]);
+ },
+ function([a], b, c) {
+ arguments.length = 4;
+ assertDeepEq([...arguments], [[10], 20, 30, undefined]);
+ },
+ function([a], b, c) {
+ arguments[5] = 50;
+ assertDeepEq([...arguments], [[10], 20, 30]);
+ },
+ function([a], b, c) {
+ arguments[Symbol.iterator] = function*() {
+ yield 40;
+ yield 50;
+ yield 60;
+ };
+ assertDeepEq([...arguments], [40, 50, 60]);
+ },
+];
+for (let f of unmapped) {
+ f([10], 20, 30);
+}
+
+var g2 = newGlobal();
+assertEq(g2.eval(`
+function f([a], b, c) {
+ return arguments[Symbol.iterator].name;
+}
+f([1], 2, 3);
+`), "values");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Function/arguments-parameter-shadowing.js b/js/src/tests/ecma_6/Function/arguments-parameter-shadowing.js
new file mode 100644
index 000000000..bc2b43011
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/arguments-parameter-shadowing.js
@@ -0,0 +1,22 @@
+// Test that var declarations of arguments "shadows" the arguments binding
+// used in parameter expressions.
+
+function g8(h = () => arguments) {
+ var arguments = 0;
+ assertEq(arguments, 0);
+ assertEq(arguments === h(), false);
+}
+g8();
+
+function g9(h = () => arguments) {
+ var arguments;
+ assertEq(void 0 === arguments, false);
+ assertEq(h(), arguments);
+ arguments = 0;
+ assertEq(arguments, 0);
+ assertEq(arguments === h(), false);
+}
+g9();
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Function/arrow-has-duplicated.js b/js/src/tests/ecma_6/Function/arrow-has-duplicated.js
new file mode 100644
index 000000000..19096ebf8
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/arrow-has-duplicated.js
@@ -0,0 +1,15 @@
+// Make sure duplicated name is allowed in non-strict.
+function f0(a, a) {
+}
+
+// SyntaxError should be thrown if arrow function has duplicated name.
+assertThrowsInstanceOf(() => eval(`
+(a, a) => {
+};
+`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`
+(a, ...a) => {
+};
+`), SyntaxError);
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Function/bound-length-and-name.js b/js/src/tests/ecma_6/Function/bound-length-and-name.js
new file mode 100644
index 000000000..ef2f1ffbc
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/bound-length-and-name.js
@@ -0,0 +1,40 @@
+var proxy = new Proxy(function() {}, {
+ getOwnPropertyDescriptor(target, name) {
+ assertEq(name, "length");
+ return {value: 3, configurable: true};
+ },
+
+ get(target, name) {
+ if (name == "length")
+ return 3;
+ if (name == "name")
+ return "hello world";
+ assertEq(false, true);
+ }
+})
+
+var bound = Function.prototype.bind.call(proxy);
+assertEq(bound.name, "bound hello world");
+assertEq(bound.length, 3);
+
+var fun = function() {};
+Object.defineProperty(fun, "name", {value: 1337});
+Object.defineProperty(fun, "length", {value: "15"});
+bound = fun.bind();
+assertEq(bound.name, "bound ");
+assertEq(bound.length, 0);
+
+Object.defineProperty(fun, "length", {value: Number.MAX_SAFE_INTEGER});
+bound = fun.bind();
+assertEq(bound.length, Number.MAX_SAFE_INTEGER);
+
+Object.defineProperty(fun, "length", {value: -100});
+bound = fun.bind();
+assertEq(bound.length, 0);
+
+fun = function f(a, ...b) { };
+assertEq(fun.length, 1);
+bound = fun.bind();
+assertEq(bound.length, 1);
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Function/bound-non-constructable.js b/js/src/tests/ecma_6/Function/bound-non-constructable.js
new file mode 100644
index 000000000..cee1dd580
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/bound-non-constructable.js
@@ -0,0 +1,17 @@
+var objects = [
+ Math.sin.bind(null),
+ new Proxy(Math.sin.bind(null), {}),
+ Function.prototype.bind.call(new Proxy(Math.sin, {}))
+]
+
+for (var obj of objects) {
+ // Target is not constructable, so a new array should be created internally.
+ assertDeepEq(Array.from.call(obj, [1, 2, 3]), [1, 2, 3]);
+ assertDeepEq(Array.of.call(obj, 1, 2, 3), [1, 2, 3]);
+
+ // Make sure they are callable, but not constructable.
+ obj();
+ assertThrowsInstanceOf(() => new obj, TypeError);
+}
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Function/bound-prototype.js b/js/src/tests/ecma_6/Function/bound-prototype.js
new file mode 100644
index 000000000..8b0f295a5
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/bound-prototype.js
@@ -0,0 +1,37 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function Bound(fn) {
+ return Function.prototype.bind.call(fn);
+}
+
+var fnDefaultPrototype = function(){};
+assertEq(Object.getPrototypeOf(Bound(fnDefaultPrototype)), Function.prototype);
+
+var fnGeneratorPrototype = function*(){};
+assertEq(Object.getPrototypeOf(Bound(fnGeneratorPrototype)), function*(){}.constructor.prototype);
+
+var fnCustomPrototype = Object.setPrototypeOf(function(){}, Array.prototype);
+assertEq(Object.getPrototypeOf(Bound(fnCustomPrototype)), Array.prototype);
+
+var fnNullPrototype = Object.setPrototypeOf(function(){}, null);
+assertEq(Object.getPrototypeOf(Bound(fnNullPrototype)), null);
+
+
+function LoggingProxy(target) {
+ var log = [];
+ var proxy = new Proxy(target, new Proxy({}, {
+ get(target, propertyKey, receiver) {
+ log.push(propertyKey);
+ }
+ }));
+ return {proxy, log};
+}
+
+var {proxy, log} = LoggingProxy(function(){});
+Bound(proxy);
+assertEqArray(log, ["getPrototypeOf", "getOwnPropertyDescriptor", "get", "get"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/browser.js b/js/src/tests/ecma_6/Function/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/browser.js
diff --git a/js/src/tests/ecma_6/Function/configurable-length-builtins.js b/js/src/tests/ecma_6/Function/configurable-length-builtins.js
new file mode 100644
index 000000000..f28eaae15
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/configurable-length-builtins.js
@@ -0,0 +1,21 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Deleting .length from a variety of builtin functions works as expected.
+for (var fun of [Math.sin, Array.prototype.map, eval]) {
+ assertEq(delete fun.length, true);
+ assertEq(fun.hasOwnProperty("length"), false);
+ assertEq("length" in fun, true); // still inheriting Function.prototype.length
+ assertEq(fun.length, 0);
+
+ // The inherited property is nonwritable, so assigning still fails
+ // (silently, in sloppy mode).
+ fun.length = Math.hypot;
+ assertEq(fun.length, 0);
+
+ // It can be shadowed via defineProperty.
+ Object.defineProperty(fun, "length", {value: Math.hypot});
+ assertEq(fun.length, Math.hypot);
+}
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Function/configurable-length.js b/js/src/tests/ecma_6/Function/configurable-length.js
new file mode 100644
index 000000000..127038fb5
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/configurable-length.js
@@ -0,0 +1,86 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Very simple initial test that the "length" property of a function is
+// configurable. More thorough tests follow.
+var f = function (a1, a2, a3, a4) {};
+assertEq(delete f.length, true);
+assertEq(f.hasOwnProperty("length"), false);
+assertEq(f.length, 0); // inherited from Function.prototype.length
+assertEq(delete Function.prototype.length, true);
+assertEq(f.length, undefined);
+
+
+// Now for the details.
+//
+// Many of these tests are poking at the "resolve hook" mechanism SM uses to
+// lazily create this property, which is wonky and deserving of some extra
+// skepticism.
+
+// We've deleted Function.prototype.length. Check that the resolve hook does
+// not resurrect it.
+assertEq("length" in Function.prototype, false);
+Function.prototype.length = 7;
+assertEq(Function.prototype.length, 7);
+delete Function.prototype.length;
+assertEq(Function.prototype.length, undefined);
+
+// OK, define Function.prototype.length back to its original state per spec, so
+// the remaining tests can run in a more typical environment.
+Object.defineProperty(Function.prototype, "length", {value: 0, configurable: true});
+
+// Check the property descriptor of a function length property.
+var g = function f(a1, a2, a3, a4, a5) {};
+var desc = Object.getOwnPropertyDescriptor(g, "length");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, false);
+assertEq(desc.value, 5);
+
+// After deleting the length property, assigning to f.length fails because
+// Function.prototype.length is non-writable. In strict mode it would throw.
+delete g.length;
+g.length = 12;
+assertEq(g.hasOwnProperty("length"), false);
+assertEq(g.length, 0);
+
+// After deleting both the length property and Function.prototype.length,
+// assigning to f.length creates a new plain old data property.
+delete Function.prototype.length;
+g.length = 13;
+var desc = Object.getOwnPropertyDescriptor(g, "length");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, true);
+assertEq(desc.writable, true);
+assertEq(desc.value, 13);
+
+// Deleting the .length of one instance of a FunctionDeclaration does not
+// affect other instances.
+function mkfun() {
+ function fun(a1, a2, a3, a4, a5) {}
+ return fun;
+}
+g = mkfun();
+var h = mkfun();
+delete h.length;
+assertEq(g.length, 5);
+assertEq(mkfun().length, 5);
+
+// Object.defineProperty on a brand-new function is sufficient to cause the
+// LENGTH_RESOLVED flag to be set.
+g = mkfun();
+Object.defineProperty(g, "length", {value: 0});
+assertEq(delete g.length, true);
+assertEq(g.hasOwnProperty("length"), false);
+
+// Object.defineProperty on a brand-new function correctly merges new
+// attributes with the builtin ones.
+g = mkfun();
+Object.defineProperty(g, "length", { value: 42 });
+desc = Object.getOwnPropertyDescriptor(g, "length");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, false);
+assertEq(desc.value, 42);
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Function/construct-bound-proxy-with-many-arguments.js b/js/src/tests/ecma_6/Function/construct-bound-proxy-with-many-arguments.js
new file mode 100644
index 000000000..6c9bb41a3
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/construct-bound-proxy-with-many-arguments.js
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var proxy = Function.prototype.bind.call(new Proxy(Array, {}));
+for (var i = 10; i < 50; ++i) {
+ var args = Array(i).fill(i);
+ var array = new proxy(...args);
+ assertEqArray(array, args);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0, "ok");
diff --git a/js/src/tests/ecma_6/Function/function-constructor-toString-arguments-before-parsing-params.js b/js/src/tests/ecma_6/Function/function-constructor-toString-arguments-before-parsing-params.js
new file mode 100644
index 000000000..4e88a0096
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/function-constructor-toString-arguments-before-parsing-params.js
@@ -0,0 +1,23 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 920479;
+var summary =
+ "Convert all arguments passed to Function() to string before doing any " +
+ "parsing of the to-be-created Function's parameters or body text";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+assertThrowsValue(() => Function("@", { toString() { throw 42; } }), 42);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_6/Function/function-name.js b/js/src/tests/ecma_6/Function/function-name.js
new file mode 100644
index 000000000..7beca56df
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/function-name.js
@@ -0,0 +1,64 @@
+function testFunctionName(f) {
+ var name = f.name;
+ f.name = 'g';
+ assertEq(f.name, name);
+ assertEq(delete f.name, true);
+ assertEq(f.name, '');
+ assertEq(f.hasOwnProperty('name'), false);
+ f.name = 'g';
+ assertEq(f.name, '');
+ Object.defineProperty(f, 'name', {value: 'g'});
+ assertEq(f.name, 'g');
+}
+function testFunctionNameStrict(f) {
+ "use strict";
+ var name = f.name;
+ var error;
+ try {
+ f.name = 'g';
+ } catch (e) {
+ error = e;
+ }
+ assertEq(f.name, name);
+ assertEq(error instanceof TypeError, true);
+ assertEq(delete f.name, true);
+ assertEq(f.name, '');
+ assertEq(f.hasOwnProperty('name'), false);
+ error = null;
+ try {
+ f.name = 'g';
+ } catch (e) {
+ error = e;
+ }
+ assertEq(f.name, '');
+ assertEq(error instanceof TypeError, true);
+ Object.defineProperty(f, 'name', {value: 'g'});
+ assertEq(f.name, 'g');
+}
+
+assertEq(Object.getOwnPropertyDescriptor(Object, "name").writable, false);
+assertEq(Object.getOwnPropertyDescriptor(Object, "name").enumerable, false);
+assertEq(Object.getOwnPropertyDescriptor(Object, "name").configurable, true);
+assertEq(Object.getOwnPropertyDescriptor(Object, "name").value, 'Object');
+assertEq(Object.getOwnPropertyDescriptor(function f(){}, "name").writable, false);
+assertEq(Object.getOwnPropertyDescriptor(function f(){}, "name").enumerable, false);
+assertEq(Object.getOwnPropertyDescriptor(function f(){}, "name").configurable, true);
+assertEq(Object.getOwnPropertyDescriptor(function f(){}, "name").value, 'f');
+
+// Basic test ensuring that Object.defineProperty works on pristine function.
+function f() {};
+Object.defineProperty(f, 'name', {value: 'g'});
+assertEq(f.name, 'g');
+
+// .name behaves as expected on scripted function.
+testFunctionName(function f(){});
+testFunctionNameStrict(function f(){});
+// .name behaves as expected on builtin function.
+testFunctionName(Function.prototype.apply);
+testFunctionNameStrict(Function.prototype.call);
+// .name behaves as expected on self-hosted builtin function.
+testFunctionName(Array.prototype.forEach);
+testFunctionNameStrict(Array.prototype.some);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/has-instance-jitted.js b/js/src/tests/ecma_6/Function/has-instance-jitted.js
new file mode 100644
index 000000000..a2d33abc7
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/has-instance-jitted.js
@@ -0,0 +1,96 @@
+const OriginalHasInstance = Function.prototype[Symbol.hasInstance];
+
+// Ensure that folding doesn't impact user defined @@hasInstance methods.
+{
+ function Test() {
+ this.x = 1;
+ }
+
+ Object.defineProperty(Test, Symbol.hasInstance,
+ {writable: true, value: () => false});
+
+ function x(t) {
+ return t instanceof Test;
+ }
+
+ function y() {
+ let t = new Test;
+ let b = true;
+ for (let i = 0; i < 10; i++) {
+ b = b && x(t);
+ }
+ return b;
+ }
+
+
+ function z() {
+ let f = 0;
+ let t = 0;
+ for (let i = 0; i < 100; i++)
+ assertEq(y(), false);
+ }
+
+ z();
+}
+
+// Ensure that the jitting does not clobber user defined @@hasInstance methods.
+{
+ function a() {
+ function b() {};
+ b.__proto__ = a.prototype;
+ return b;
+ };
+ let c = new a();
+
+ let t = 0;
+ let f = 0;
+ let e = 0;
+ for (let i = 0; i < 40000; i++) {
+ if (i == 20000)
+ Object.defineProperty(a.prototype, Symbol.hasInstance,
+ {writable: true, value: () => true});
+ if (i == 30000)
+ Object.setPrototypeOf(c, Function.prototype);
+
+ if (1 instanceof c) {
+ t++;
+ } else {
+ f++;
+ }
+ }
+
+ assertEq(t, 10000);
+ assertEq(f, 30000);
+}
+
+{
+ function a() {};
+ function b() {};
+ Object.defineProperty(a, Symbol.hasInstance, {writable: true, value: () => true});
+ assertEq(b instanceof a, true);
+ for (let _ of Array(10000))
+ assertEq(b instanceof a, true);
+}
+
+{
+ function a(){};
+ function b(){};
+ function c(){};
+ function d(){};
+ function e(){};
+ Object.defineProperty(a, Symbol.hasInstance, {value: () => true });
+ Object.defineProperty(b, Symbol.hasInstance, {value: () => true });
+ Object.defineProperty(c, Symbol.hasInstance, {value: () => true });
+ Object.defineProperty(d, Symbol.hasInstance, {value: () => true });
+ let funcs = [a, b, c, d];
+ for (let f of funcs)
+ assertEq(e instanceof f, true);
+
+ for (let _ of Array(10001)) {
+ for (let f of funcs)
+ assertEq(e instanceof f, true);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Function/has-instance.js b/js/src/tests/ecma_6/Function/has-instance.js
new file mode 100644
index 000000000..f0c7bf28e
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/has-instance.js
@@ -0,0 +1,101 @@
+// It is possible to override Function.prototype[@@hasInstance].
+let passed = false;
+let obj = { foo: true };
+let C = function(){};
+
+Object.defineProperty(C, Symbol.hasInstance, {
+ value: function(inst) { passed = inst.foo; return false; }
+});
+
+assertEq(obj instanceof C, false);
+assertEq(passed, true);
+
+{
+ let obj = {
+ [Symbol.hasInstance](v) { return true; },
+ };
+ let whatevs = {};
+ assertEq(whatevs instanceof obj, true);
+}
+
+{
+
+ function zzzz() {};
+ let xxxx = new zzzz();
+ assertEq(xxxx instanceof zzzz, true);
+ assertEq(zzzz[Symbol.hasInstance](xxxx), true);
+
+}
+
+// Non-callable objects should return false.
+const nonCallables = [
+ 1,
+ undefined,
+ null,
+ "nope",
+]
+
+for (let nonCallable of nonCallables) {
+ assertEq(nonCallable instanceof Function, false);
+ assertEq(nonCallable instanceof Object, false);
+}
+
+// Non-callables should throw when used on the right hand side
+// of `instanceof`.
+assertThrowsInstanceOf(() => {
+ function foo() {};
+ let obj = {};
+ foo instanceof obj;
+}, TypeError);
+
+// Non-callables do not throw for overridden methods
+let o = {[Symbol.hasInstance](v) { return true; }}
+assertEq(1 instanceof o, true);
+
+// Non-callables return false instead of an exception when
+// Function.prototype[Symbol.hasInstance] is called directly.
+for (let nonCallable of nonCallables) {
+ assertEq(Function.prototype[Symbol.hasInstance].call(nonCallable, Object), false);
+}
+
+// It should be possible to call the Symbol.hasInstance method directly.
+assertEq(Function.prototype[Symbol.hasInstance].call(Function, () => 1), true);
+assertEq(Function.prototype[Symbol.hasInstance].call(Function, Object), true);
+assertEq(Function.prototype[Symbol.hasInstance].call(Function, null), false);
+assertEq(Function.prototype[Symbol.hasInstance].call(Function, Array), true);
+assertEq(Function.prototype[Symbol.hasInstance].call(Object, Array), true);
+assertEq(Function.prototype[Symbol.hasInstance].call(Array, Function), false);
+assertEq(Function.prototype[Symbol.hasInstance].call(({}), Function), false);
+assertEq(Function.prototype[Symbol.hasInstance].call(), false)
+assertEq(Function.prototype[Symbol.hasInstance].call(({})), false)
+
+// Ensure that bound functions are unwrapped properly
+let bindme = {x: function() {}};
+let instance = new bindme.x();
+let xOuter = bindme.x;
+let bound = xOuter.bind(bindme);
+let doubleBound = bound.bind(bindme);
+let tripleBound = bound.bind(doubleBound);
+assertEq(Function.prototype[Symbol.hasInstance].call(bound, instance), true);
+assertEq(Function.prototype[Symbol.hasInstance].call(doubleBound, instance), true);
+assertEq(Function.prototype[Symbol.hasInstance].call(tripleBound, instance), true);
+
+// Function.prototype[Symbol.hasInstance] is not configurable
+let desc = Object.getOwnPropertyDescriptor(Function.prototype, Symbol.hasInstance);
+assertEq(desc.configurable, false);
+
+// Attempting to use a non-callable @@hasInstance triggers a type error
+// Bug 1280892
+assertThrowsInstanceOf(() => {
+ var fun = function() {}
+ var p = new Proxy(fun, {
+ get(target, key) {
+ return /not-callable/;
+ }
+ });
+ fun instanceof p;
+}, TypeError);
+
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Function/length-with-destructuring-and-parameter-expression.js b/js/src/tests/ecma_6/Function/length-with-destructuring-and-parameter-expression.js
new file mode 100644
index 000000000..a3f00ac1f
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/length-with-destructuring-and-parameter-expression.js
@@ -0,0 +1,31 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+assertEq(function([a = 0]){}.length, 1);
+assertEq(function({p: a = 0}){}.length, 1);
+assertEq(function({a = 0}){}.length, 1);
+assertEq(function({[0]: a}){}.length, 1);
+
+assertEq(function([a = 0], [b = 0]){}.length, 2);
+assertEq(function({p: a = 0}, [b = 0]){}.length, 2);
+assertEq(function({a = 0}, [b = 0]){}.length, 2);
+assertEq(function({[0]: a}, [b = 0]){}.length, 2);
+
+assertEq(function(x, [a = 0]){}.length, 2);
+assertEq(function(x, {p: a = 0}){}.length, 2);
+assertEq(function(x, {a = 0}){}.length, 2);
+assertEq(function(x, {[0]: a}){}.length, 2);
+
+assertEq(function(x = 0, [a = 0]){}.length, 0);
+assertEq(function(x = 0, {p: a = 0}){}.length, 0);
+assertEq(function(x = 0, {a = 0}){}.length, 0);
+assertEq(function(x = 0, {[0]: a}){}.length, 0);
+
+assertEq(function([a = 0], ...r){}.length, 1);
+assertEq(function({p: a = 0}, ...r){}.length, 1);
+assertEq(function({a = 0}, ...r){}.length, 1);
+assertEq(function({[0]: a}, ...r){}.length, 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Function/line-terminator-before-arrow.js b/js/src/tests/ecma_6/Function/line-terminator-before-arrow.js
new file mode 100644
index 000000000..52bdce7f3
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/line-terminator-before-arrow.js
@@ -0,0 +1,9 @@
+assertThrowsInstanceOf(() => eval("() \n => {}"), SyntaxError);
+assertThrowsInstanceOf(() => eval("a \n => {}"), SyntaxError);
+assertThrowsInstanceOf(() => eval("(a) /*\n*/ => {}"), SyntaxError);
+assertThrowsInstanceOf(() => eval("(a, b) \n => {}"), SyntaxError);
+assertThrowsInstanceOf(() => eval("(a, b = 1) \n => {}"), SyntaxError);
+assertThrowsInstanceOf(() => eval("(a, ...b) \n => {}"), SyntaxError);
+assertThrowsInstanceOf(() => eval("(a, b = 1, ...c) \n => {}"), SyntaxError);
+
+reportCompare(0, 0, "ok");
diff --git a/js/src/tests/ecma_6/Function/method-has-duplicated.js b/js/src/tests/ecma_6/Function/method-has-duplicated.js
new file mode 100644
index 000000000..dc0a9dfb4
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/method-has-duplicated.js
@@ -0,0 +1,19 @@
+// Make sure duplicated name is allowed in non-strict.
+function f0(a) {
+}
+
+// SyntaxError should be thrown if method definition has duplicated name.
+assertThrowsInstanceOf(() => eval(`
+({
+ m1(a, a) {
+ }
+});
+`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`
+({
+ m2(a, ...a) {
+ }
+});
+`), SyntaxError);
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Function/parameter-redeclaration.js b/js/src/tests/ecma_6/Function/parameter-redeclaration.js
new file mode 100644
index 000000000..74e55e3aa
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/parameter-redeclaration.js
@@ -0,0 +1,19 @@
+// 'var' is allowed to redeclare parameters.
+function f1(a = 0) {
+ var a;
+}
+
+// 'let' and 'const' at body-level are not allowed to redeclare parameters.
+assertThrowsInstanceOf(() => {
+ eval(`function f2(a = 0) {
+ let a;
+ }`);
+}, SyntaxError);
+assertThrowsInstanceOf(() => {
+ eval(`function f3(a = 0) {
+ const a;
+ }`);
+}, SyntaxError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Function/rest-has-duplicated.js b/js/src/tests/ecma_6/Function/rest-has-duplicated.js
new file mode 100644
index 000000000..67577ab4e
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/rest-has-duplicated.js
@@ -0,0 +1,17 @@
+// Make sure duplicated name is allowed in non-strict.
+function f0(a, a) {
+}
+
+// SyntaxError should be thrown if rest parameter name is duplicated.
+assertThrowsInstanceOf(() => eval(`
+function f1(a, ...a) {
+}
+`), SyntaxError);
+
+// SyntaxError should be thrown if there is a duplicated parameter.
+assertThrowsInstanceOf(() => eval(`
+function f2(a, a, ...b) {
+}
+`), SyntaxError);
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Function/rest-parameter-names.js b/js/src/tests/ecma_6/Function/rest-parameter-names.js
new file mode 100644
index 000000000..6cfa01dcf
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/rest-parameter-names.js
@@ -0,0 +1,68 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 1288460;
+var summary =
+ "Rest parameters to functions can be named |yield| or |eval| or |let| in "
+ "non-strict code";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var f1 = (...yield) => yield + 42;
+assertEq(f1(), "42");
+assertEq(f1(1), "142");
+
+var f2 = (...eval) => eval + 42;
+assertEq(f2(), "42");
+assertEq(f2(1), "142");
+
+var f3 = (...let) => let + 42;
+assertEq(f3(), "42");
+assertEq(f3(1), "142");
+
+function g1(x, ...yield)
+{
+ return yield + x;
+}
+assertEq(g1(0, 42), "420");
+
+function g2(x, ...eval)
+{
+ return eval + x;
+}
+assertEq(g2(0, 42), "420");
+
+function g3(x, ...let)
+{
+ return let + x;
+}
+assertEq(g3(0, 42), "420");
+
+function h()
+{
+ "use strict";
+
+ var badNames = ["yield", "eval", "let"];
+
+ for (var badName of ["yield", "eval", "let"])
+ {
+ assertThrowsInstanceOf(() => eval(`var q = (...${badName}) => ${badName} + 42;`),
+ SyntaxError);
+
+ assertThrowsInstanceOf(() => eval(`function r(x, ...${badName}) { return x + ${badName}; }`),
+ SyntaxError);
+ }
+}
+h();
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_6/Function/return-finally.js b/js/src/tests/ecma_6/Function/return-finally.js
new file mode 100644
index 000000000..fe075d457
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/return-finally.js
@@ -0,0 +1,172 @@
+var BUGNUMBER = 1202134;
+var summary = "Return value should not be overwritten by finally block with normal execution.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== single ====
+
+var f;
+f = function() {
+ // F.[[type]] is normal
+ // B.[[type]] is return
+ try {
+ return 42;
+ } finally {
+ }
+};
+assertEq(f(), 42);
+
+f = function() {
+ // F.[[type]] is return
+ try {
+ return 42;
+ } finally {
+ return 43;
+ }
+};
+assertEq(f(), 43);
+
+f = function() {
+ // F.[[type]] is throw
+ try {
+ return 42;
+ } finally {
+ throw 43;
+ }
+};
+var caught = false;
+try {
+ f();
+} catch (e) {
+ assertEq(e, 43);
+ caught = true;
+}
+assertEq(caught, true);
+
+f = function() {
+ // F.[[type]] is break
+ do try {
+ return 42;
+ } finally {
+ break;
+ } while (false);
+ return 43;
+};
+assertEq(f(), 43);
+
+f = function() {
+ // F.[[type]] is break
+ L: try {
+ return 42;
+ } finally {
+ break L;
+ }
+ return 43;
+};
+assertEq(f(), 43);
+
+f = function() {
+ // F.[[type]] is continue
+ do try {
+ return 42;
+ } finally {
+ continue;
+ } while (false);
+ return 43;
+};
+assertEq(f(), 43);
+
+// ==== nested ====
+
+f = function() {
+ // F.[[type]] is normal
+ // B.[[type]] is return
+ try {
+ return 42;
+ } finally {
+ // F.[[type]] is break
+ do try {
+ return 43;
+ } finally {
+ break;
+ } while (0);
+ }
+};
+assertEq(f(), 42);
+
+f = function() {
+ // F.[[type]] is normal
+ // B.[[type]] is return
+ try {
+ return 42;
+ } finally {
+ // F.[[type]] is break
+ L: try {
+ return 43;
+ } finally {
+ break L;
+ }
+ }
+}
+assertEq(f(), 42);
+
+f = function() {
+ // F.[[type]] is normal
+ // B.[[type]] is return
+ try {
+ return 42;
+ } finally {
+ // F.[[type]] is continue
+ do try {
+ return 43;
+ } finally {
+ continue;
+ } while (0);
+ }
+};
+assertEq(f(), 42);
+
+f = function() {
+ // F.[[type]] is normal
+ // B.[[type]] is return
+ try {
+ return 42;
+ } finally {
+ // F.[[type]] is normal
+ // B.[[type]] is normal
+ try {
+ // F.[[type]] is throw
+ try {
+ return 43;
+ } finally {
+ throw 9;
+ }
+ } catch (e) {
+ }
+ }
+};
+assertEq(f(), 42);
+
+f = function() {
+ // F.[[type]] is return
+ try {
+ return 41;
+ } finally {
+ // F.[[type]] is normal
+ // B.[[type]] is return
+ try {
+ return 42;
+ } finally {
+ // F.[[type]] is break
+ do try {
+ return 43;
+ } finally {
+ break;
+ } while (0);
+ }
+ }
+};
+assertEq(f(), 42);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/Function/shell.js b/js/src/tests/ecma_6/Function/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/shell.js
diff --git a/js/src/tests/ecma_6/Function/spread-iterator-primitive.js b/js/src/tests/ecma_6/Function/spread-iterator-primitive.js
new file mode 100644
index 000000000..79320ad7f
--- /dev/null
+++ b/js/src/tests/ecma_6/Function/spread-iterator-primitive.js
@@ -0,0 +1,28 @@
+var BUGNUMBER = 1021835;
+var summary = "Returning non-object from @@iterator should throw";
+
+print(BUGNUMBER + ": " + summary);
+
+let primitives = [
+ 1,
+ true,
+ undefined,
+ null,
+ "foo",
+ Symbol.iterator
+];
+
+function f() {
+}
+
+for (let primitive of primitives) {
+ let arg = {
+ [Symbol.iterator]() {
+ return primitive;
+ }
+ };
+ assertThrowsInstanceOf(() => f(...arg), TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);