summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/Function
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/non262/Function')
-rw-r--r--js/src/tests/non262/Function/10.1.6-01.js29
-rw-r--r--js/src/tests/non262/Function/10.1.6.js23
-rw-r--r--js/src/tests/non262/Function/10.2.1.1.6.js35
-rw-r--r--js/src/tests/non262/Function/15.3.4.3-01.js245
-rw-r--r--js/src/tests/non262/Function/Function-arguments-gc.js40
-rw-r--r--js/src/tests/non262/Function/Function-prototype.js11
-rw-r--r--js/src/tests/non262/Function/Function-with-eval.js25
-rw-r--r--js/src/tests/non262/Function/Object-toSource.js373
-rw-r--r--js/src/tests/non262/Function/arguments-caller-callee.js64
-rw-r--r--js/src/tests/non262/Function/arguments-extra-property.js33
-rw-r--r--js/src/tests/non262/Function/arguments-iterator.js167
-rw-r--r--js/src/tests/non262/Function/arguments-parameter-shadowing.js22
-rw-r--r--js/src/tests/non262/Function/arguments-property-attributes.js98
-rw-r--r--js/src/tests/non262/Function/arrow-has-duplicated.js15
-rw-r--r--js/src/tests/non262/Function/bound-length-and-name.js40
-rw-r--r--js/src/tests/non262/Function/bound-non-constructable.js17
-rw-r--r--js/src/tests/non262/Function/bound-prototype.js37
-rw-r--r--js/src/tests/non262/Function/browser.js0
-rw-r--r--js/src/tests/non262/Function/builtin-no-construct.js52
-rw-r--r--js/src/tests/non262/Function/builtin-no-prototype.js40
-rw-r--r--js/src/tests/non262/Function/configurable-length-builtins.js21
-rw-r--r--js/src/tests/non262/Function/configurable-length.js86
-rw-r--r--js/src/tests/non262/Function/construct-bound-proxy-with-many-arguments.js13
-rw-r--r--js/src/tests/non262/Function/constructor-binding.js11
-rw-r--r--js/src/tests/non262/Function/create-function-parse-before-getprototype.js17
-rw-r--r--js/src/tests/non262/Function/function-bind.js280
-rw-r--r--js/src/tests/non262/Function/function-call.js134
-rw-r--r--js/src/tests/non262/Function/function-caller-restrictions.js29
-rw-r--r--js/src/tests/non262/Function/function-caller.js45
-rw-r--r--js/src/tests/non262/Function/function-constructor-toString-arguments-before-parsing-params.js23
-rw-r--r--js/src/tests/non262/Function/function-name-assignment.js139
-rw-r--r--js/src/tests/non262/Function/function-name-binding.js54
-rw-r--r--js/src/tests/non262/Function/function-name-class.js32
-rw-r--r--js/src/tests/non262/Function/function-name-for.js31
-rw-r--r--js/src/tests/non262/Function/function-name-method.js70
-rw-r--r--js/src/tests/non262/Function/function-name-property.js58
-rw-r--r--js/src/tests/non262/Function/function-name.js64
-rw-r--r--js/src/tests/non262/Function/function-toString-builtin-name.js53
-rw-r--r--js/src/tests/non262/Function/function-toString-builtin.js42
-rw-r--r--js/src/tests/non262/Function/get-function-realm.js45
-rw-r--r--js/src/tests/non262/Function/has-instance-jitted.js96
-rw-r--r--js/src/tests/non262/Function/has-instance.js101
-rw-r--r--js/src/tests/non262/Function/implicit-this-in-parameter-expression.js18
-rw-r--r--js/src/tests/non262/Function/invalid-parameter-list.js27
-rw-r--r--js/src/tests/non262/Function/length-with-destructuring-and-parameter-expression.js31
-rw-r--r--js/src/tests/non262/Function/line-terminator-before-arrow.js9
-rw-r--r--js/src/tests/non262/Function/method-has-duplicated.js19
-rw-r--r--js/src/tests/non262/Function/parameter-redeclaration.js19
-rw-r--r--js/src/tests/non262/Function/redefine-arguments-length.js65
-rw-r--r--js/src/tests/non262/Function/regress-123371.js19
-rw-r--r--js/src/tests/non262/Function/regress-131964.js159
-rw-r--r--js/src/tests/non262/Function/regress-137181.js76
-rw-r--r--js/src/tests/non262/Function/regress-178389.js26
-rw-r--r--js/src/tests/non262/Function/regress-193555.js99
-rw-r--r--js/src/tests/non262/Function/regress-222029-001.js123
-rw-r--r--js/src/tests/non262/Function/regress-222029-002.js132
-rw-r--r--js/src/tests/non262/Function/regress-292215.js37
-rw-r--r--js/src/tests/non262/Function/regress-313570.js30
-rw-r--r--js/src/tests/non262/Function/regress-338001.js42
-rw-r--r--js/src/tests/non262/Function/regress-338121-01.js33
-rw-r--r--js/src/tests/non262/Function/regress-338121-02.js36
-rw-r--r--js/src/tests/non262/Function/regress-338121-03.js38
-rw-r--r--js/src/tests/non262/Function/regress-344052.js27
-rw-r--r--js/src/tests/non262/Function/regress-364023.js37
-rw-r--r--js/src/tests/non262/Function/regress-49286.js100
-rw-r--r--js/src/tests/non262/Function/regress-518103.js27
-rw-r--r--js/src/tests/non262/Function/regress-524826.js28
-rw-r--r--js/src/tests/non262/Function/regress-528082.js20
-rw-r--r--js/src/tests/non262/Function/regress-533254.js28
-rw-r--r--js/src/tests/non262/Function/regress-545980.js41
-rw-r--r--js/src/tests/non262/Function/regress-58274.js189
-rw-r--r--js/src/tests/non262/Function/regress-85880.js136
-rw-r--r--js/src/tests/non262/Function/regress-94506.js126
-rw-r--r--js/src/tests/non262/Function/regress-97921.js115
-rw-r--r--js/src/tests/non262/Function/rest-has-duplicated.js17
-rw-r--r--js/src/tests/non262/Function/rest-parameter-names.js68
-rw-r--r--js/src/tests/non262/Function/return-finally.js172
-rw-r--r--js/src/tests/non262/Function/shell.js0
-rw-r--r--js/src/tests/non262/Function/spread-iterator-primitive.js28
-rw-r--r--js/src/tests/non262/Function/strict-arguments.js453
-rw-r--r--js/src/tests/non262/Function/throw-type-error.js16
81 files changed, 5476 insertions, 0 deletions
diff --git a/js/src/tests/non262/Function/10.1.6-01.js b/js/src/tests/non262/Function/10.1.6-01.js
new file mode 100644
index 0000000000..fbb98616e1
--- /dev/null
+++ b/js/src/tests/non262/Function/10.1.6-01.js
@@ -0,0 +1,29 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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 BUGNUMBER = 293782;
+var summary = 'Local variables should not be enumerable properties of the function';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+function f()
+{
+ var x,y
+ }
+
+var p;
+actual = '';
+
+for (p in f)
+{
+ actual += p + ',';
+}
+expect = '';
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/10.1.6.js b/js/src/tests/non262/Function/10.1.6.js
new file mode 100644
index 0000000000..504001cb1a
--- /dev/null
+++ b/js/src/tests/non262/Function/10.1.6.js
@@ -0,0 +1,23 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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 BUGNUMBER = 293782;
+var summary = 'Local variables can cause predefined function object properties to be undefined';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+function f()
+{
+ var name=1;
+}
+
+expect = 'f';
+actual = f.name;
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/10.2.1.1.6.js b/js/src/tests/non262/Function/10.2.1.1.6.js
new file mode 100644
index 0000000000..69613386cd
--- /dev/null
+++ b/js/src/tests/non262/Function/10.2.1.1.6.js
@@ -0,0 +1,35 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function strictThis() { 'use strict'; return this; }
+
+/* Check that calls of flat closure slots get the right |this|. */
+function flat(g) {
+ function h() { return g(); }
+ return h;
+}
+assertEq(flat(strictThis)(), undefined);
+
+/* Check that calls up upvars get the right |this|. */
+function upvar(f) {
+ function h() {
+ return f();
+ }
+ return h();
+}
+assertEq(upvar(strictThis), undefined);
+
+/* Check that calls to with-object properties get an appropriate 'this'. */
+var obj = { f: strictThis };
+with (obj) {
+ /*
+ * The method won't compile anything containing a 'with', but it can
+ * compile 'g'.
+ */
+ function g() { return f(); }
+ assertEq(g(), obj);
+}
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/Function/15.3.4.3-01.js b/js/src/tests/non262/Function/15.3.4.3-01.js
new file mode 100644
index 0000000000..955d773766
--- /dev/null
+++ b/js/src/tests/non262/Function/15.3.4.3-01.js
@@ -0,0 +1,245 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 562448;
+var summary = 'Function.prototype.apply should accept any arraylike arguments';
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function expectTypeError(fun, msg)
+{
+ try
+ {
+ fun();
+ assertEq(true, false, "should have thrown a TypeError");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true, msg + "; instead threw " + e);
+ }
+}
+
+function fun() { }
+
+var global = this;
+
+
+/* Step 1. */
+var nonfuns = [null, 1, -1, 2.5, "[[Call]]", undefined, true, false, {}];
+for (var i = 0, sz = nonfuns.length; i < sz; i++)
+{
+ var f = function()
+ {
+ Function.prototype.apply.apply(nonfuns[i], [1, 2, 3]);
+ };
+ var msg =
+ "expected TypeError calling Function.prototype.apply with uncallable this";
+ expectTypeError(f, msg);
+}
+
+
+/* Step 2. */
+var thisObj = {};
+
+var currentThis, currentThisBox;
+function funLength()
+{
+ assertEq(arguments.length, 0, "should have been called with no arguments");
+ assertEq(this, currentThis, "wrong this");
+}
+function strictFunLength()
+{
+ "use strict";
+ assertEq(arguments.length, 0, "should have been called with no arguments");
+ assertEq(this, currentThis, "wrong this");
+}
+
+currentThis = global;
+funLength.apply();
+funLength.apply(undefined);
+funLength.apply(undefined, undefined);
+funLength.apply(undefined, null);
+
+currentThis = undefined;
+strictFunLength.apply();
+strictFunLength.apply(undefined);
+strictFunLength.apply(undefined, undefined);
+strictFunLength.apply(undefined, null);
+
+currentThis = null;
+strictFunLength.apply(null);
+strictFunLength.apply(null, undefined);
+strictFunLength.apply(null, null);
+
+currentThis = thisObj;
+funLength.apply(thisObj);
+funLength.apply(thisObj, null);
+funLength.apply(thisObj, undefined);
+strictFunLength.apply(thisObj);
+strictFunLength.apply(thisObj, null);
+strictFunLength.apply(thisObj, undefined);
+
+currentThis = 17;
+strictFunLength.apply(17);
+strictFunLength.apply(17, null);
+strictFunLength.apply(17, undefined);
+
+function funThisPrimitive()
+{
+ assertEq(arguments.length, 0, "should have been called with no arguments");
+ assertEq(this instanceof currentThisBox, true,
+ "this not instanceof " + currentThisBox);
+ assertEq(this.valueOf(), currentThis,
+ "wrong this valueOf()");
+}
+
+currentThis = 17;
+currentThisBox = Number;
+funThisPrimitive.apply(17);
+funThisPrimitive.apply(17, undefined);
+funThisPrimitive.apply(17, null);
+
+currentThis = "foopy";
+currentThisBox = String;
+funThisPrimitive.apply("foopy");
+funThisPrimitive.apply("foopy", undefined);
+funThisPrimitive.apply("foopy", null);
+
+currentThis = false;
+currentThisBox = Boolean;
+funThisPrimitive.apply(false);
+funThisPrimitive.apply(false, undefined);
+funThisPrimitive.apply(false, null);
+
+
+/* Step 3. */
+var nonobjs = [1, -1, 2.5, "[[Call]]", true, false];
+for (var i = 0, sz = nonobjs.length; i < sz; i++)
+{
+ var f = function() { fun.apply(thisObj, nonobjs[i]); };
+ var msg = "should have thrown a TypeError with non-object arguments";
+ expectTypeError(f, msg);
+}
+
+
+/* Step 4. */
+var args = { get length() { throw 42; } };
+try
+{
+ fun.apply(thisObj, args);
+}
+catch (e)
+{
+ assertEq(e, 42, "didn't throw result of [[Get]] on arguments object");
+}
+
+
+/*
+ * NB: There was an erratum removing the steps numbered 5 and 7 in the original
+ * version of ES5; see also the comments in js_fun_apply.
+ */
+
+/* Step 5. */
+var called = false;
+var argsObjectLength =
+ { length: { valueOf: function() { called = true; return 17; } } };
+
+fun.apply({}, argsObjectLength);
+assertEq(called, true, "should have been set in valueOf called via ToUint32");
+
+var upvar = "unset";
+var argsObjectPrimitiveLength =
+ {
+ length:
+ {
+ valueOf: function() { upvar = "valueOf"; return {}; },
+ toString: function()
+ {
+ upvar = upvar === "valueOf" ? "both" : "toString";
+ return 17;
+ }
+ }
+ };
+fun.apply({}, argsObjectPrimitiveLength);
+assertEq(upvar, "both", "didn't call all hooks properly");
+
+
+/* Step 6-9. */
+var seenThis, res, steps;
+var argsAccessors =
+ {
+ length: 4,
+ get 0() { steps.push("0"); return 1; },
+ get 1() { steps.push("1"); return 2; },
+ // make sure values shine through holes
+ get 3() { steps.push("3"); return 8; },
+ };
+
+Object.prototype[2] = 729;
+
+seenThis = "not seen";
+function argsAsArray()
+{
+ seenThis = this;
+ steps.push(Math.PI);
+ return Array.prototype.map.call(arguments, function(v) { return v; });
+}
+
+steps = [];
+res = argsAsArray.apply(thisObj, argsAccessors);
+assertEq(seenThis, thisObj, "saw wrong this");
+
+assertEq(steps.length, 4, "wrong steps: " + steps);
+assertEq(steps[0], "0", "bad step 0");
+assertEq(steps[1], "1", "bad step 1");
+assertEq(steps[2], "3", "bad step 3");
+assertEq(steps[3], Math.PI, "bad last step");
+
+assertEq(res.length, 4, "wrong return: " + res);
+assertEq(res[0], 1, "wrong ret[0]");
+assertEq(res[1], 2, "wrong ret[0]");
+assertEq(res[2], 729, "wrong ret[0]");
+assertEq(res[3], 8, "wrong ret[0]");
+
+seenThis = "not seen";
+function strictArgsAsArray()
+{
+ "use strict";
+ seenThis = this;
+ steps.push(NaN);
+ return Array.prototype.map.call(arguments, function(v) { return v; });
+}
+
+steps = [];
+res = strictArgsAsArray.apply(null, argsAccessors);
+assertEq(seenThis, null, "saw wrong this");
+
+assertEq(steps.length, 4, "wrong steps: " + steps);
+assertEq(steps[0], "0", "bad step 0");
+assertEq(steps[1], "1", "bad step 1");
+assertEq(steps[2], "3", "bad step 3");
+assertEq(steps[3], 0 / 0, "bad last step");
+
+assertEq(res.length, 4, "wrong return: " + res);
+assertEq(res[0], 1, "wrong ret[0]");
+assertEq(res[1], 2, "wrong ret[0]");
+assertEq(res[2], 729, "wrong ret[0]");
+assertEq(res[3], 8, "wrong ret[0]");
+
+strictArgsAsArray.apply(17, argsAccessors);
+assertEq(seenThis, 17, "saw wrong this");
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/Function-arguments-gc.js b/js/src/tests/non262/Function/Function-arguments-gc.js
new file mode 100644
index 0000000000..2504523362
--- /dev/null
+++ b/js/src/tests/non262/Function/Function-arguments-gc.js
@@ -0,0 +1,40 @@
+// |reftest| skip-if(Android)
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Christian Holler <decoder@own-hero.net>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 623301;
+var summary = "Properly root argument names during Function()";
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+if (typeof gczeal === "function")
+ gczeal(2);
+
+function crashMe(n)
+{
+ var nasty = [];
+ while (n--)
+ nasty.push("a" + n);
+ return Function.apply(null, nasty);
+}
+
+var count = 64; // exact value not important
+assertEq(crashMe(count + 1).length, count);
+
+if (typeof gczeal === "function")
+ gczeal(0); // reset
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/Function-prototype.js b/js/src/tests/non262/Function/Function-prototype.js
new file mode 100644
index 0000000000..218b1d54ca
--- /dev/null
+++ b/js/src/tests/non262/Function/Function-prototype.js
@@ -0,0 +1,11 @@
+var desc = Object.getOwnPropertyDescriptor(Function.prototype, "length");
+assertDeepEq(desc,
+ {value: 0, writable: false, enumerable: false, configurable: true});
+
+assertEq(Function.prototype.prototype, undefined);
+assertEq(Function.prototype.callee, undefined);
+assertThrowsInstanceOf(() => Function.prototype.caller, TypeError);
+assertThrowsInstanceOf(() => Function.prototype.arguments, TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/Function/Function-with-eval.js b/js/src/tests/non262/Function/Function-with-eval.js
new file mode 100644
index 0000000000..981abf2d04
--- /dev/null
+++ b/js/src/tests/non262/Function/Function-with-eval.js
@@ -0,0 +1,25 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+assertEq(new Function(
+ "eval('var foo = 915805');" +
+ "return foo;"
+ )(),
+ 915805);
+
+assertEq(new Function(
+ "eval('function foo() {" +
+ "return 915805;" +
+ "}');" +
+ "return foo;"
+ )()(),
+ 915805);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/non262/Function/Object-toSource.js b/js/src/tests/non262/Function/Object-toSource.js
new file mode 100644
index 0000000000..16b2346fbf
--- /dev/null
+++ b/js/src/tests/non262/Function/Object-toSource.js
@@ -0,0 +1,373 @@
+// |reftest| skip-if(!Object.prototype.toSource)
+
+var BUGNUMBER = 1317400;
+var summary = "Function string representation in Object.prototype.toSource";
+
+print(BUGNUMBER + ": " + summary);
+
+// Methods.
+
+assertEq(({ foo(){} }).toSource(),
+ "({foo(){}})");
+assertEq(({ *foo(){} }).toSource(),
+ "({*foo(){}})");
+assertEq(({ async foo(){} }).toSource(),
+ "({async foo(){}})");
+
+assertEq(({ 1(){} }).toSource(),
+ "({1(){}})");
+
+// Methods with more spacing.
+// Spacing is kept.
+
+assertEq(({ foo (){} }).toSource(),
+ "({foo (){}})");
+assertEq(({ foo () {} }).toSource(),
+ "({foo () {}})");
+
+// Methods with computed name.
+// Method syntax is composed.
+
+let name = "foo";
+assertEq(({ [name](){} }).toSource(),
+ "({foo(){}})");
+assertEq(({ *[name](){} }).toSource(),
+ "({*foo(){}})");
+assertEq(({ async [name](){} }).toSource(),
+ "({async foo(){}})");
+
+assertEq(({ [ Symbol.iterator ](){} }).toSource(),
+ "({[Symbol.iterator](){}})");
+
+// Accessors.
+
+assertEq(({ get foo(){} }).toSource(),
+ "({get foo(){}})");
+assertEq(({ set foo(v){} }).toSource(),
+ "({set foo(v){}})");
+
+// Accessors with computed name.
+// Method syntax is composed.
+
+assertEq(({ get [name](){} }).toSource(),
+ "({get foo(){}})");
+assertEq(({ set [name](v){} }).toSource(),
+ "({set foo(v){}})");
+
+assertEq(({ get [ Symbol.iterator ](){} }).toSource(),
+ "({get [Symbol.iterator](){}})");
+assertEq(({ set [ Symbol.iterator ](v){} }).toSource(),
+ "({set [Symbol.iterator](v){}})");
+
+// Getter and setter with same name.
+// Getter always comes before setter.
+
+assertEq(({ get foo(){}, set foo(v){} }).toSource(),
+ "({get foo(){}, set foo(v){}})");
+assertEq(({ set foo(v){}, get foo(){} }).toSource(),
+ "({get foo(){}, set foo(v){}})");
+
+// Normal properties.
+
+assertEq(({ foo: function(){} }).toSource(),
+ "({foo:(function(){})})");
+assertEq(({ foo: function bar(){} }).toSource(),
+ "({foo:(function bar(){})})");
+assertEq(({ foo: function*(){} }).toSource(),
+ "({foo:(function*(){})})");
+assertEq(({ foo: async function(){} }).toSource(),
+ "({foo:(async function(){})})");
+
+// Normal properties with computed name.
+
+assertEq(({ [ Symbol.iterator ]: function(){} }).toSource(),
+ "({[Symbol.iterator]:(function(){})})");
+
+// Dynamically defined properties with function expression.
+// Never become a method syntax.
+
+let obj = {};
+obj.foo = function() {};
+assertEq(obj.toSource(),
+ "({foo:(function() {})})");
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: function() {}});
+assertEq(obj.toSource(),
+ "({})");
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: function() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({foo:(function() {})})");
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: function bar() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({foo:(function bar() {})})");
+
+obj = {};
+Object.defineProperty(obj, Symbol.iterator, {value: function() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({[Symbol.iterator]:(function() {})})");
+
+// Dynamically defined property with other object's method.
+// Method syntax is composed.
+
+let method = ({foo() {}}).foo;
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: method, enumerable: true});
+assertEq(obj.toSource(),
+ "({foo() {}})");
+
+obj = {};
+Object.defineProperty(obj, "bar", {value: method, enumerable: true});
+assertEq(obj.toSource(),
+ "({bar() {}})");
+
+method = ({*foo() {}}).foo;
+
+obj = {};
+Object.defineProperty(obj, "bar", {value: method, enumerable: true});
+assertEq(obj.toSource(),
+ "({*bar() {}})");
+
+method = ({async foo() {}}).foo;
+
+obj = {};
+Object.defineProperty(obj, "bar", {value: method, enumerable: true});
+assertEq(obj.toSource(),
+ "({async bar() {}})");
+
+// Dynamically defined accessors.
+// Accessor syntax is composed.
+
+obj = {};
+Object.defineProperty(obj, "foo", {get: function() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo() {}})");
+
+obj = {};
+Object.defineProperty(obj, "foo", {set: function() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo() {}})");
+
+obj = {};
+Object.defineProperty(obj, Symbol.iterator, {get: function() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({get [Symbol.iterator]() {}})");
+
+obj = {};
+Object.defineProperty(obj, Symbol.iterator, {set: function() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({set [Symbol.iterator]() {}})");
+
+// Dynamically defined accessors with other object's accessors.
+// Accessor syntax is composed.
+
+let accessor = Object.getOwnPropertyDescriptor({ get foo() {} }, "foo").get;
+obj = {};
+Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo() {}})");
+
+accessor = Object.getOwnPropertyDescriptor({ get bar() {} }, "bar").get;
+obj = {};
+Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo() {}})");
+
+accessor = Object.getOwnPropertyDescriptor({ set foo(v) {} }, "foo").set;
+obj = {};
+Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo(v) {}})");
+
+accessor = Object.getOwnPropertyDescriptor({ set bar(v) {} }, "bar").set;
+obj = {};
+Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo(v) {}})");
+
+accessor = Object.getOwnPropertyDescriptor({ get foo() {} }, "foo").get;
+obj = {};
+Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo() {}})");
+
+accessor = Object.getOwnPropertyDescriptor({ get bar() {} }, "bar").get;
+obj = {};
+Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo() {}})");
+
+accessor = Object.getOwnPropertyDescriptor({ set foo(v) {} }, "foo").set;
+obj = {};
+Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo(v) {}})");
+
+accessor = Object.getOwnPropertyDescriptor({ set bar(v) {} }, "bar").set;
+obj = {};
+Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo(v) {}})");
+
+// Methods with proxy.
+// Treated as normal property.
+
+method = ({foo() {}}).foo;
+let handler = {
+ get(that, name) {
+ if (name == "toSource") {
+ return function() {
+ return that.toSource();
+ };
+ }
+ return that[name];
+ }
+};
+let proxy = new Proxy(method, handler);
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: proxy, enumerable: true});
+assertEq(obj.toSource(),
+ "({foo:foo() {}})");
+
+// Accessors with proxy.
+// Accessor syntax is composed.
+
+accessor = Object.getOwnPropertyDescriptor({ get foo() {} }, "foo").get;
+proxy = new Proxy(accessor, handler);
+
+obj = {};
+Object.defineProperty(obj, "foo", {get: proxy, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo() {}})");
+
+obj = {};
+Object.defineProperty(obj, "foo", {set: proxy, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo() {}})");
+
+// Methods from other global.
+// Treated as normal property in the cross-compartment case.
+
+let g = newGlobal();
+
+method = g.eval("({ foo() {} }).foo");
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: method, enumerable: true});
+assertEq((obj.toSource() === "({foo:foo() {}})" ||
+ obj.toSource() === "({foo() {}})"),
+ true);
+
+// Accessors from other global.
+// Accessor syntax is composed.
+
+accessor = g.eval("Object.getOwnPropertyDescriptor({ get foo() {} }, 'foo').get");
+
+obj = {};
+Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo() {}})");
+
+accessor = g.eval("Object.getOwnPropertyDescriptor({ get bar() {} }, 'bar').get");
+
+obj = {};
+Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo() {}})");
+
+accessor = g.eval("Object.getOwnPropertyDescriptor({ set foo(v) {} }, 'foo').set");
+
+obj = {};
+Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo(v) {}})");
+
+accessor = g.eval("Object.getOwnPropertyDescriptor({ set bar(v) {} }, 'bar').set");
+
+obj = {};
+Object.defineProperty(obj, "foo", {get: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo(v) {}})");
+
+accessor = g.eval("Object.getOwnPropertyDescriptor({ get foo() {} }, 'foo').get");
+
+obj = {};
+Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo() {}})");
+
+accessor = g.eval("Object.getOwnPropertyDescriptor({ get bar() {} }, 'bar').get");
+
+obj = {};
+Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo() {}})");
+
+accessor = g.eval("Object.getOwnPropertyDescriptor({ set foo(v) {} }, 'foo').set");
+
+obj = {};
+Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo(v) {}})");
+
+accessor = g.eval("Object.getOwnPropertyDescriptor({ set bar(v) {} }, 'bar').set");
+
+obj = {};
+Object.defineProperty(obj, "foo", {set: accessor, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo(v) {}})");
+
+// **** Some weird cases ****
+
+// Accessors with generator or async.
+
+obj = {};
+Object.defineProperty(obj, "foo", {get: function*() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({get foo() {}})");
+
+obj = {};
+Object.defineProperty(obj, "foo", {set: async function() {}, enumerable: true});
+assertEq(obj.toSource(),
+ "({set foo() {}})");
+
+// Modified toSource.
+
+obj = { foo() {} };
+obj.foo.toSource = () => "hello";
+assertEq(obj.toSource(),
+ "({hello})");
+
+obj = { foo() {} };
+obj.foo.toSource = () => "bar() {}";
+assertEq(obj.toSource(),
+ "({bar() {}})");
+
+// Modified toSource with different method name.
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: function bar() {}, enumerable: true});
+obj.foo.toSource = () => "hello";
+assertEq(obj.toSource(),
+ "({foo:hello})");
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: function* bar() {}, enumerable: true});
+obj.foo.toSource = () => "hello";
+assertEq(obj.toSource(),
+ "({foo:hello})");
+
+obj = {};
+Object.defineProperty(obj, "foo", {value: async function bar() {}, enumerable: true});
+obj.foo.toSource = () => "hello";
+assertEq(obj.toSource(),
+ "({foo:hello})");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/Function/arguments-caller-callee.js b/js/src/tests/non262/Function/arguments-caller-callee.js
new file mode 100644
index 0000000000..57efd9eb91
--- /dev/null
+++ b/js/src/tests/non262/Function/arguments-caller-callee.js
@@ -0,0 +1,64 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'arguments-caller-callee.js';
+var BUGNUMBER = 514563;
+var summary = "arguments.caller and arguments.callee are poison pills in ES5, " +
+ "later changed in ES2017 to only poison pill arguments.callee.";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// behavior
+
+function expectTypeError(fun)
+{
+ try
+ {
+ fun();
+ throw new Error("didn't throw");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "expected TypeError calling function" +
+ ("name" in fun ? " " + fun.name : "") + ", instead got: " + e);
+ }
+}
+
+function bar() { "use strict"; return arguments; }
+assertEq(bar().caller, undefined); // No error when accessing arguments.caller in ES2017+
+expectTypeError(function barCallee() { bar().callee; });
+
+function baz() { return arguments; }
+assertEq(baz().callee, baz);
+
+
+// accessor identity
+
+function strictMode() { "use strict"; return arguments; }
+var canonicalTTE = Object.getOwnPropertyDescriptor(strictMode(), "callee").get;
+
+var args = strictMode();
+
+var argsCaller = Object.getOwnPropertyDescriptor(args, "caller");
+assertEq(argsCaller, undefined);
+
+var argsCallee = Object.getOwnPropertyDescriptor(args, "callee");
+assertEq("get" in argsCallee, true);
+assertEq("set" in argsCallee, true);
+assertEq(argsCallee.get, canonicalTTE);
+assertEq(argsCallee.set, canonicalTTE);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/arguments-extra-property.js b/js/src/tests/non262/Function/arguments-extra-property.js
new file mode 100644
index 0000000000..017734382d
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/arguments-iterator.js b/js/src/tests/non262/Function/arguments-iterator.js
new file mode 100644
index 0000000000..5610b8a245
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/arguments-parameter-shadowing.js b/js/src/tests/non262/Function/arguments-parameter-shadowing.js
new file mode 100644
index 0000000000..bc2b430112
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/arguments-property-attributes.js b/js/src/tests/non262/Function/arguments-property-attributes.js
new file mode 100644
index 0000000000..f50c1e6dad
--- /dev/null
+++ b/js/src/tests/non262/Function/arguments-property-attributes.js
@@ -0,0 +1,98 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'arguments-property-attributes.js';
+var BUGNUMBER = 516255;
+var summary = "Attributes for properties of arguments objects";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// normal
+
+function args() { return arguments; }
+var a = args(0, 1);
+
+var argProps = Object.getOwnPropertyNames(a).sort();
+assertEq(argProps.indexOf("callee") >= 0, true);
+assertEq(argProps.indexOf("0") >= 0, true);
+assertEq(argProps.indexOf("1") >= 0, true);
+assertEq(argProps.indexOf("length") >= 0, true);
+
+var calleeDesc = Object.getOwnPropertyDescriptor(a, "callee");
+assertEq(calleeDesc.value, args);
+assertEq(calleeDesc.writable, true);
+assertEq(calleeDesc.enumerable, false);
+assertEq(calleeDesc.configurable, true);
+
+var zeroDesc = Object.getOwnPropertyDescriptor(a, "0");
+assertEq(zeroDesc.value, 0);
+assertEq(zeroDesc.writable, true);
+assertEq(zeroDesc.enumerable, true);
+assertEq(zeroDesc.configurable, true);
+
+var oneDesc = Object.getOwnPropertyDescriptor(a, "1");
+assertEq(oneDesc.value, 1);
+assertEq(oneDesc.writable, true);
+assertEq(oneDesc.enumerable, true);
+assertEq(oneDesc.configurable, true);
+
+var lengthDesc = Object.getOwnPropertyDescriptor(a, "length");
+assertEq(lengthDesc.value, 2);
+assertEq(lengthDesc.writable, true);
+assertEq(lengthDesc.enumerable, false);
+assertEq(lengthDesc.configurable, true);
+
+
+// strict
+
+function strictArgs() { "use strict"; return arguments; }
+var sa = strictArgs(0, 1);
+
+var strictArgProps = Object.getOwnPropertyNames(sa).sort();
+assertEq(strictArgProps.indexOf("callee") >= 0, true);
+assertEq(strictArgProps.indexOf("caller") >= 0, false);
+assertEq(strictArgProps.indexOf("0") >= 0, true);
+assertEq(strictArgProps.indexOf("1") >= 0, true);
+assertEq(strictArgProps.indexOf("length") >= 0, true);
+
+var strictCalleeDesc = Object.getOwnPropertyDescriptor(sa, "callee");
+assertEq(typeof strictCalleeDesc.get, "function");
+assertEq(typeof strictCalleeDesc.set, "function");
+assertEq(strictCalleeDesc.get, strictCalleeDesc.set);
+assertEq(strictCalleeDesc.enumerable, false);
+assertEq(strictCalleeDesc.configurable, false);
+
+var strictCallerDesc = Object.getOwnPropertyDescriptor(sa, "caller");
+assertEq(strictCallerDesc, undefined);
+
+var strictZeroDesc = Object.getOwnPropertyDescriptor(sa, "0");
+assertEq(strictZeroDesc.value, 0);
+assertEq(strictZeroDesc.writable, true);
+assertEq(strictZeroDesc.enumerable, true);
+assertEq(strictZeroDesc.configurable, true);
+
+var strictOneDesc = Object.getOwnPropertyDescriptor(sa, "1");
+assertEq(strictOneDesc.value, 1);
+assertEq(strictOneDesc.writable, true);
+assertEq(strictOneDesc.enumerable, true);
+assertEq(strictOneDesc.configurable, true);
+
+var strictLengthDesc = Object.getOwnPropertyDescriptor(sa, "length");
+assertEq(strictLengthDesc.value, 2);
+assertEq(strictLengthDesc.writable, true);
+assertEq(strictLengthDesc.enumerable, false);
+assertEq(strictLengthDesc.configurable, true);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/arrow-has-duplicated.js b/js/src/tests/non262/Function/arrow-has-duplicated.js
new file mode 100644
index 0000000000..19096ebf88
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/bound-length-and-name.js b/js/src/tests/non262/Function/bound-length-and-name.js
new file mode 100644
index 0000000000..ef2f1ffbcd
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/bound-non-constructable.js b/js/src/tests/non262/Function/bound-non-constructable.js
new file mode 100644
index 0000000000..cee1dd580d
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/bound-prototype.js b/js/src/tests/non262/Function/bound-prototype.js
new file mode 100644
index 0000000000..8b0f295a58
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/browser.js b/js/src/tests/non262/Function/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/non262/Function/browser.js
diff --git a/js/src/tests/non262/Function/builtin-no-construct.js b/js/src/tests/non262/Function/builtin-no-construct.js
new file mode 100644
index 0000000000..b41ae56f11
--- /dev/null
+++ b/js/src/tests/non262/Function/builtin-no-construct.js
@@ -0,0 +1,52 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function checkMethod(method) {
+ try {
+ new method();
+ assertEq(0, 1, "not reached " + method);
+ } catch (e) {
+ assertEq(e.message.indexOf(" is not a constructor") === -1, false);
+ }
+}
+
+function checkMethods(proto) {
+ var names = Object.getOwnPropertyNames(proto);
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ if (["constructor", "arguments", "caller"].indexOf(name) >= 0)
+ continue;
+ var prop = proto[name];
+ if (typeof prop === "function")
+ checkMethod(prop);
+ }
+}
+
+checkMethod(Function.prototype);
+checkMethods(JSON);
+checkMethods(Math);
+checkMethods(Proxy);
+
+var builtin_ctors = [
+ Object, Function, Array, String, Boolean, Number, Date, RegExp, Error,
+ EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError,
+];
+
+for (var i = 0; i < builtin_ctors.length; i++) {
+ checkMethods(builtin_ctors[i]);
+ checkMethods(builtin_ctors[i].prototype);
+}
+
+var builtin_funcs = [
+ eval, isFinite, isNaN, parseFloat, parseInt,
+ decodeURI, decodeURIComponent, encodeURI, encodeURIComponent
+];
+
+for (var i = 0; i < builtin_funcs.length; i++) {
+ checkMethod(builtin_funcs[i]);
+}
+
+if (typeof reportCompare == 'function')
+ reportCompare(0, 0, "ok");
diff --git a/js/src/tests/non262/Function/builtin-no-prototype.js b/js/src/tests/non262/Function/builtin-no-prototype.js
new file mode 100644
index 0000000000..b5a8cc9f6e
--- /dev/null
+++ b/js/src/tests/non262/Function/builtin-no-prototype.js
@@ -0,0 +1,40 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+assertEq(undefined, void 0);
+
+assertEq(Function.prototype.hasOwnProperty('prototype'), false);
+assertEq(Function.prototype.prototype, undefined);
+
+var builtin_ctors = [
+ Object, Function, Array, String, Boolean, Number, Date, RegExp, Error,
+ EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError
+];
+
+for (var i = 0; i < builtin_ctors.length; i++) {
+ var c = builtin_ctors[i];
+ assertEq(typeof c.prototype, (c === Function) ? "function" : "object");
+ assertEq(c.prototype.constructor, c);
+}
+
+var builtin_funcs = [
+ eval, isFinite, isNaN, parseFloat, parseInt,
+ decodeURI, decodeURIComponent, encodeURI, encodeURIComponent
+];
+
+for (var i = 0; i < builtin_funcs.length; i++) {
+ assertEq(builtin_funcs[i].hasOwnProperty('prototype'), false);
+ assertEq(builtin_funcs[i].prototype, undefined);
+}
+
+var names = Object.getOwnPropertyNames(Math);
+for (var i = 0; i < names.length; i++) {
+ var m = Math[names[i]];
+ if (typeof m === "function")
+ assertEq(m.prototype, undefined);
+}
+
+reportCompare(0, 0, "don't crash");
diff --git a/js/src/tests/non262/Function/configurable-length-builtins.js b/js/src/tests/non262/Function/configurable-length-builtins.js
new file mode 100644
index 0000000000..f28eaae157
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/configurable-length.js b/js/src/tests/non262/Function/configurable-length.js
new file mode 100644
index 0000000000..127038fb56
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/construct-bound-proxy-with-many-arguments.js b/js/src/tests/non262/Function/construct-bound-proxy-with-many-arguments.js
new file mode 100644
index 0000000000..6c9bb41a38
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/constructor-binding.js b/js/src/tests/non262/Function/constructor-binding.js
new file mode 100644
index 0000000000..e82274d279
--- /dev/null
+++ b/js/src/tests/non262/Function/constructor-binding.js
@@ -0,0 +1,11 @@
+var BUGNUMBER = 636635;
+var summary = "A function created by Function constructor shouldn't have anonymous binding";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(new Function("return typeof anonymous")(), "undefined");
+assertEq(new Function("return function() { return typeof anonymous; }")()(), "undefined");
+assertEq(new Function("return function() { eval(''); return typeof anonymous; }")()(), "undefined");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/Function/create-function-parse-before-getprototype.js b/js/src/tests/non262/Function/create-function-parse-before-getprototype.js
new file mode 100644
index 0000000000..2095abfb28
--- /dev/null
+++ b/js/src/tests/non262/Function/create-function-parse-before-getprototype.js
@@ -0,0 +1,17 @@
+var getProtoCalled = false;
+
+var newTarget = Object.defineProperty(function(){}.bind(), "prototype", {
+ get() {
+ getProtoCalled = true;
+ return null;
+ }
+});
+
+assertThrowsInstanceOf(() => {
+ Reflect.construct(Function, ["@error"], newTarget);
+}, SyntaxError);
+
+assertEq(getProtoCalled, false);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/Function/function-bind.js b/js/src/tests/non262/Function/function-bind.js
new file mode 100644
index 0000000000..9fdaf41a97
--- /dev/null
+++ b/js/src/tests/non262/Function/function-bind.js
@@ -0,0 +1,280 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'function-bind.js';
+var BUGNUMBER = 429507;
+var summary = "ES5: Function.prototype.bind";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// ad-hoc testing
+
+assertEq(Function.prototype.hasOwnProperty("bind"), true);
+
+var bind = Function.prototype.bind;
+assertEq(bind.length, 1);
+
+
+var strictReturnThis = function() { "use strict"; return this; };
+
+assertEq(strictReturnThis.bind(undefined)(), undefined);
+assertEq(strictReturnThis.bind(null)(), null);
+
+var obj = {};
+assertEq(strictReturnThis.bind(obj)(), obj);
+
+assertEq(strictReturnThis.bind(NaN)(), NaN);
+
+assertEq(strictReturnThis.bind(true)(), true);
+assertEq(strictReturnThis.bind(false)(), false);
+
+assertEq(strictReturnThis.bind("foopy")(), "foopy");
+
+
+// rigorous, step-by-step testing
+
+function expectThrowTypeError(fun)
+{
+ try
+ {
+ var r = fun();
+ throw new Error("didn't throw TypeError, returned " + r);
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "didn't throw TypeError, got: " + e);
+ }
+}
+
+/*
+ * 1. Let Target be the this value.
+ * 2. If IsCallable(Target) is false, throw a TypeError exception.
+ */
+expectThrowTypeError(function() { bind.call(null); });
+expectThrowTypeError(function() { bind.call(undefined); });
+expectThrowTypeError(function() { bind.call(NaN); });
+expectThrowTypeError(function() { bind.call(0); });
+expectThrowTypeError(function() { bind.call(-0); });
+expectThrowTypeError(function() { bind.call(17); });
+expectThrowTypeError(function() { bind.call(42); });
+expectThrowTypeError(function() { bind.call("foobar"); });
+expectThrowTypeError(function() { bind.call(true); });
+expectThrowTypeError(function() { bind.call(false); });
+expectThrowTypeError(function() { bind.call([]); });
+expectThrowTypeError(function() { bind.call({}); });
+
+
+/*
+ * 3. Let A be a new (possibly empty) internal list of all of the argument
+ * values provided after thisArg (arg1, arg2 etc), in order.
+ * 4. Let F be a new native ECMAScript object .
+ * 5. Set all the internal methods, except for [[Get]], of F as specified in
+ * 8.12.
+ * 6. Set the [[Get]] internal property of F as specified in 15.3.5.4.
+ * 7. Set the [[TargetFunction]] internal property of F to Target.
+ * 8. Set the [[BoundThis]] internal property of F to the value of thisArg.
+ * 9. Set the [[BoundArgs]] internal property of F to A.
+ */
+// throughout
+
+
+/* 10. Set the [[Class]] internal property of F to "Function". */
+var toString = Object.prototype.toString;
+assertEq(toString.call(function(){}), "[object Function]");
+assertEq(toString.call(function a(){}), "[object Function]");
+assertEq(toString.call(function(a){}), "[object Function]");
+assertEq(toString.call(function a(b){}), "[object Function]");
+assertEq(toString.call(function(){}.bind()), "[object Function]");
+assertEq(toString.call(function a(){}.bind()), "[object Function]");
+assertEq(toString.call(function(a){}.bind()), "[object Function]");
+assertEq(toString.call(function a(b){}.bind()), "[object Function]");
+
+
+/*
+ * 11. Set the [[Prototype]] internal property of F to the standard built-in
+ * Function prototype object as specified in 15.3.3.1.
+ */
+assertEq(Object.getPrototypeOf(bind.call(function(){})), Function.prototype);
+assertEq(Object.getPrototypeOf(bind.call(function a(){})), Function.prototype);
+assertEq(Object.getPrototypeOf(bind.call(function(a){})), Function.prototype);
+assertEq(Object.getPrototypeOf(bind.call(function a(b){})), Function.prototype);
+
+
+/*
+ * 12. Set the [[Call]] internal property of F as described in 15.3.4.5.1.
+ */
+var a = Array.bind(1, 2);
+assertEq(a().length, 2);
+assertEq(a(4).length, 2);
+assertEq(a(4, 8).length, 3);
+
+function t() { return this; }
+var bt = t.bind(t);
+assertEq(bt(), t);
+
+function callee() { return arguments.callee; }
+var call = callee.bind();
+assertEq(call(), callee);
+assertEq(new call(), callee);
+
+
+/*
+ * 13. Set the [[Construct]] internal property of F as described in 15.3.4.5.2.
+ */
+function Point(x, y)
+{
+ this.x = x;
+ this.y = y;
+}
+var YAxisPoint = Point.bind(null, 0)
+
+assertEq(YAxisPoint.hasOwnProperty("prototype"), false);
+var p = new YAxisPoint(5);
+assertEq(p.x, 0);
+assertEq(p.y, 5);
+assertEq(p instanceof Point, true);
+assertEq(p instanceof YAxisPoint, true);
+assertEq(Object.prototype.toString.call(YAxisPoint), "[object Function]");
+assertEq(YAxisPoint.length, 1);
+
+
+/*
+ * 14. Set the [[HasInstance]] internal property of F as described in
+ * 15.3.4.5.3.
+ */
+function JoinArguments()
+{
+ this.args = Array.prototype.join.call(arguments, ", ");
+}
+
+var Join1 = JoinArguments.bind(null, 1);
+var Join2 = Join1.bind(null, 2);
+var Join3 = Join2.bind(null, 3);
+var Join4 = Join3.bind(null, 4);
+var Join5 = Join4.bind(null, 5);
+var Join6 = Join5.bind(null, 6);
+
+var r = new Join6(7);
+assertEq(r instanceof Join6, true);
+assertEq(r instanceof Join5, true);
+assertEq(r instanceof Join4, true);
+assertEq(r instanceof Join3, true);
+assertEq(r instanceof Join2, true);
+assertEq(r instanceof Join1, true);
+assertEq(r instanceof JoinArguments, true);
+assertEq(r.args, "1, 2, 3, 4, 5, 6, 7");
+
+
+/*
+ * 15. If the [[Class]] internal property of Target is "Function", then
+ * a. Let L be the length property of Target minus the length of A.
+ * b. Set the length own property of F to either 0 or L, whichever is larger.
+ * 16. Else set the length own property of F to 0.
+ */
+function none() { return arguments.length; }
+assertEq(none.bind(1, 2)(3, 4), 3);
+assertEq(none.bind(1, 2)(), 1);
+assertEq(none.bind(1)(2, 3), 2);
+assertEq(none.bind().length, 0);
+assertEq(none.bind(null).length, 0);
+assertEq(none.bind(null, 1).length, 0);
+assertEq(none.bind(null, 1, 2).length, 0);
+
+function one(a) { }
+assertEq(one.bind().length, 1);
+assertEq(one.bind(null).length, 1);
+assertEq(one.bind(null, 1).length, 0);
+assertEq(one.bind(null, 1, 2).length, 0);
+
+// retch
+var br = Object.create(null, { length: { value: 0 } });
+try
+{
+ br = bind.call(/a/g, /a/g, "aaaa");
+}
+catch (e) { /* nothing */ }
+assertEq(br.length, 0);
+
+
+/*
+ * 17. Set the attributes of the length own property of F to the values
+ * specified in 15.3.5.1.
+ */
+var len1Desc =
+ Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(), "length");
+assertEq(len1Desc.value, 3);
+assertEq(len1Desc.writable, false);
+assertEq(len1Desc.enumerable, false);
+assertEq(len1Desc.configurable, true);
+
+var len2Desc =
+ Object.getOwnPropertyDescriptor(function(a, b, c){}.bind(null, 2), "length");
+assertEq(len2Desc.value, 2);
+assertEq(len2Desc.writable, false);
+assertEq(len2Desc.enumerable, false);
+assertEq(len2Desc.configurable, true);
+
+
+/*
+ * 18. Set the [[Extensible]] internal property of F to true.
+ */
+var bound = (function() { }).bind();
+
+var isExtensible = Object.isExtensible || function() { return true; };
+assertEq(isExtensible(bound), true);
+
+bound.foo = 17;
+var fooDesc = Object.getOwnPropertyDescriptor(bound, "foo");
+assertEq(fooDesc.value, 17);
+assertEq(fooDesc.writable, true);
+assertEq(fooDesc.enumerable, true);
+assertEq(fooDesc.configurable, true);
+
+
+/*
+ * Steps 19-21 are removed from ES6, instead implemented through "arguments" and
+ * "caller" accessors on Function.prototype. So no own properties, but do check
+ * for the same observable behavior (modulo where the accessors live).
+ */
+function strict() { "use strict"; }
+function nonstrict() {}
+
+function testBound(fun)
+{
+ var boundf = fun.bind();
+
+ assertEq(Object.getOwnPropertyDescriptor(boundf, "arguments"), undefined,
+ "should be no arguments property");
+ assertEq(Object.getOwnPropertyDescriptor(boundf, "caller"), undefined,
+ "should be no caller property");
+
+ expectThrowTypeError(function() { return boundf.arguments; });
+ expectThrowTypeError(function() { return boundf.caller; });
+}
+
+testBound(strict);
+testBound(nonstrict);
+
+assertEq((function unbound(){"body"}).bind().toString(), `function() {
+ [native code]
+}`);
+
+
+/* 22. Return F. */
+var passim = function p(){}.bind(1);
+assertEq(typeof passim, "function");
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/function-call.js b/js/src/tests/non262/Function/function-call.js
new file mode 100644
index 0000000000..756b583842
--- /dev/null
+++ b/js/src/tests/non262/Function/function-call.js
@@ -0,0 +1,134 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 575535;
+var summary = 'Function.prototype.call';
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function expectTypeError(fun, msg)
+{
+ try
+ {
+ fun();
+ assertEq(true, false, "should have thrown a TypeError");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true, msg + "; instead threw " + e);
+ }
+}
+
+function fun() { }
+
+var global = this;
+
+assertEq(Function.prototype.call.length, 1);
+
+
+/* Step 1. */
+var nonfuns = [null, 1, -1, 2.5, "[[Call]]", undefined, true, false, {}];
+for (var i = 0, sz = nonfuns.length; i < sz; i++)
+{
+ var f = function()
+ {
+ Function.prototype.call.apply(nonfuns[i]);
+ };
+ var msg =
+ "expected TypeError calling Function.prototype.call with uncallable this";
+ expectTypeError(f, msg);
+}
+
+
+/* Steps 2-4. */
+function none()
+{
+ assertEq(this, global, "bad this");
+ assertEq(arguments.length, 0, "wrong arguments");
+}
+
+none.call();
+none.call(undefined);
+none.call(null);
+
+var seenThis;
+function strictNone()
+{
+ "use strict";
+ assertEq(this, seenThis, "bad this");
+ assertEq(arguments.length, 0, "wrong arguments");
+}
+
+seenThis = undefined;
+strictNone.call();
+strictNone.call(undefined);
+
+seenThis = null;
+strictNone.call(null);
+
+seenThis = 17;
+strictNone.call(17);
+
+var seenThisBox, args;
+function some()
+{
+ assertEq(this instanceof seenThisBox, true,
+ "this not instanceof " + seenThisBox);
+ assertEq(this.valueOf(), seenThis,
+ "wrong this valueOf()");
+ assertEq(arguments.length, args.length, "wrong arguments count");
+ for (var i = 0; i < args.length; i++)
+ assertEq(arguments[i], args[i], "wrong argument " + i);
+}
+
+seenThis = false;
+seenThisBox = Boolean;
+args = [8, 6, 7, NaN, undefined, 0.3];
+some.call(false, 8, 6, 7, NaN, undefined, 0.3);
+
+var obj = {};
+
+seenThis = "foo";
+seenThisBox = String;
+args = [obj];
+some.call("foo", obj);
+
+seenThis = obj;
+seenThisBox = Object;
+some.call(obj, obj);
+
+function strictSome()
+{
+ "use strict";
+ assertEq(this, seenThis, "wrong this");
+ assertEq(arguments.length, args.length, "wrong arguments count");
+ for (var i = 0; i < args.length; i++)
+ assertEq(arguments[i], args[i], "wrong argument " + i);
+}
+
+seenThis = NaN;
+args = [8, 6, 7, NaN, undefined, 0.3];
+strictSome.call(NaN, 8, 6, 7, NaN, undefined, 0.3);
+
+seenThis = "foo";
+args = [obj];
+strictSome.call("foo", obj);
+
+seenThis = obj;
+strictSome.call(obj, obj);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/function-caller-restrictions.js b/js/src/tests/non262/Function/function-caller-restrictions.js
new file mode 100644
index 0000000000..36c31279ba
--- /dev/null
+++ b/js/src/tests/non262/Function/function-caller-restrictions.js
@@ -0,0 +1,29 @@
+// Function#caller restrictions as proposed by
+// https://github.com/claudepache/es-legacy-function-reflection/
+
+function caller() {
+ return caller.caller;
+}
+
+assertEq(caller(), null);
+assertEq(Reflect.apply(caller, undefined, []), null);
+
+assertEq([0].map(caller)[0], null);
+
+(function strict() {
+ "use strict";
+ assertEq(caller(), null);
+})();
+
+(async function() {
+ assertEq(caller(), null);
+})();
+
+assertEq(function*() {
+ yield caller();
+}().next().value, null);
+
+
+if (typeof reportCompare === "function") {
+ reportCompare(true, true);
+}
diff --git a/js/src/tests/non262/Function/function-caller.js b/js/src/tests/non262/Function/function-caller.js
new file mode 100644
index 0000000000..2b0812d4f1
--- /dev/null
+++ b/js/src/tests/non262/Function/function-caller.js
@@ -0,0 +1,45 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'function-caller.js';
+var BUGNUMBER = 514581;
+var summary = "Function.prototype.caller should throw a TypeError for " +
+ "strict-mode functions";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// behavior
+
+function expectTypeError(fun)
+{
+ try
+ {
+ fun();
+ throw new Error("didn't throw");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "expected TypeError calling function" +
+ ("name" in fun ? " " + fun.name : "") + ", instead got: " + e);
+ }
+}
+
+function bar() { "use strict"; }
+expectTypeError(function barCaller() { bar.caller; });
+
+function baz() { "use strict"; return 17; }
+expectTypeError(function bazCaller() { baz.caller; });
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/function-constructor-toString-arguments-before-parsing-params.js b/js/src/tests/non262/Function/function-constructor-toString-arguments-before-parsing-params.js
new file mode 100644
index 0000000000..4e88a00966
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/function-name-assignment.js b/js/src/tests/non262/Function/function-name-assignment.js
new file mode 100644
index 0000000000..5e4d1c004f
--- /dev/null
+++ b/js/src/tests/non262/Function/function-name-assignment.js
@@ -0,0 +1,139 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on assignment";
+
+print(BUGNUMBER + ": " + summary);
+
+var fooSymbol = Symbol("foo");
+var emptySymbol = Symbol("");
+var undefSymbol = Symbol();
+var globalVar;
+
+var exprs = [
+ ["function() {}", false],
+ ["function named() {}", true],
+ ["function*() {}", false],
+ ["function* named() {}", true],
+ ["async function() {}", false],
+ ["async function named() {}", true],
+ ["() => {}", false],
+ ["async () => {}", false],
+ ["class {}", false],
+ ["class named {}", true],
+];
+
+function testAssignmentExpression(expr, named) {
+ eval(`
+ var assignment;
+ assignment = ${expr};
+ assertEq(assignment.name, named ? "named" : "assignment");
+
+ globalVar = ${expr};
+ assertEq(globalVar.name, named ? "named" : "globalVar");
+
+ var obj = { dynamic: null };
+ with (obj) {
+ dynamic = ${expr};
+ }
+ assertEq(obj.dynamic.name, named ? "named" : "dynamic");
+
+ (function namedLambda(param1, param2) {
+ var assignedToNamedLambda;
+ assignedToNamedLambda = namedLambda = ${expr};
+ assertEq(namedLambda.name, "namedLambda");
+ assertEq(assignedToNamedLambda.name, named ? "named" : "namedLambda");
+
+ param1 = ${expr};
+ assertEq(param1.name, named ? "named" : "param1");
+
+ {
+ let param1 = ${expr};
+ assertEq(param1.name, named ? "named" : "param1");
+
+ param2 = ${expr};
+ assertEq(param2.name, named ? "named" : "param2");
+ }
+ })();
+
+ {
+ let nextedLexical1, nextedLexical2;
+ {
+ let nextedLexical1 = ${expr};
+ assertEq(nextedLexical1.name, named ? "named" : "nextedLexical1");
+
+ nextedLexical2 = ${expr};
+ assertEq(nextedLexical2.name, named ? "named" : "nextedLexical2");
+ }
+ }
+ `);
+
+ // Not applicable cases: not IsIdentifierRef.
+ eval(`
+ var inParen;
+ (inParen) = ${expr};
+ assertEq(inParen.name, named ? "named" : "");
+ `);
+
+ // Not applicable cases: not direct RHS.
+ if (!expr.includes("=>")) {
+ eval(`
+ var a = true && ${expr};
+ assertEq(a.name, named ? "named" : "");
+ `);
+ } else {
+ // Arrow function cannot be RHS of &&.
+ eval(`
+ var a = true && (${expr});
+ assertEq(a.name, named ? "named" : "");
+ `);
+ }
+
+ // Not applicable cases: property.
+ eval(`
+ var obj = {};
+
+ obj.prop = ${expr};
+ assertEq(obj.prop.name, named ? "named" : "");
+
+ obj["literal"] = ${expr};
+ assertEq(obj["literal"].name, named ? "named" : "");
+ `);
+
+ // Not applicable cases: assigned again.
+ eval(`
+ var tmp = [${expr}];
+ assertEq(tmp[0].name, named ? "named" : "");
+
+ var assignment;
+ assignment = tmp[0];
+ assertEq(assignment.name, named ? "named" : "");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testAssignmentExpression(expr, named);
+}
+
+function testVariableDeclaration(expr, named) {
+ eval(`
+ var varDecl = ${expr};
+ assertEq(varDecl.name, named ? "named" : "varDecl");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testVariableDeclaration(expr, named);
+}
+
+function testLexicalBinding(expr, named) {
+ eval(`
+ let lexical = ${expr};
+ assertEq(lexical.name, named ? "named" : "lexical");
+
+ const constLexical = ${expr};
+ assertEq(constLexical.name, named ? "named" : "constLexical");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testLexicalBinding(expr, named);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/Function/function-name-binding.js b/js/src/tests/non262/Function/function-name-binding.js
new file mode 100644
index 0000000000..bdd6c131c0
--- /dev/null
+++ b/js/src/tests/non262/Function/function-name-binding.js
@@ -0,0 +1,54 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on binding pattern";
+
+print(BUGNUMBER + ": " + summary);
+
+var exprs = [
+ ["function() {}", false],
+ ["function named() {}", true],
+ ["function*() {}", false],
+ ["function* named() {}", true],
+ ["async function() {}", false],
+ ["async function named() {}", true],
+ ["() => {}", false],
+ ["async () => {}", false],
+ ["class {}", false],
+ ["class named {}", true],
+];
+
+function testAssignmentProperty(expr, named) {
+ var f = eval(`(function({ prop1 = ${expr} }) { return prop1; })`);
+ assertEq(f({}).name, named ? "named" : "prop1");
+
+ eval(`
+ var { prop1 = ${expr} } = {};
+ assertEq(prop1.name, named ? "named" : "prop1");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testAssignmentProperty(expr, named);
+}
+
+function testAssignmentElement(expr, named) {
+ var f = eval(`(function([elem1 = ${expr}]) { return elem1; })`);
+ assertEq(f([]).name, named ? "named" : "elem1");
+
+ eval(`
+ var [elem1 = ${expr}] = [];
+ assertEq(elem1.name, named ? "named" : "elem1");
+ `);
+}
+for (var [expr, named] of exprs) {
+ testAssignmentElement(expr, named);
+}
+
+function testSingleNameBinding(expr, named) {
+ var f = eval(`(function(param1 = ${expr}) { return param1; })`);
+ assertEq(f().name, named ? "named" : "param1");
+}
+for (var [expr, named] of exprs) {
+ testSingleNameBinding(expr, named);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/Function/function-name-class.js b/js/src/tests/non262/Function/function-name-class.js
new file mode 100644
index 0000000000..edde690556
--- /dev/null
+++ b/js/src/tests/non262/Function/function-name-class.js
@@ -0,0 +1,32 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous class with name method shouldn't be affected by assignment";
+
+print(BUGNUMBER + ": " + summary);
+
+var classWithStaticNameMethod = class { static name() {} };
+assertEq(typeof classWithStaticNameMethod.name, "function");
+
+var classWithStaticNameGetter = class { static get name() { return "static name"; } };
+assertEq(typeof Object.getOwnPropertyDescriptor(classWithStaticNameGetter, "name").get, "function");
+assertEq(classWithStaticNameGetter.name, "static name");
+
+var classWithStaticNameSetter = class { static set name(v) {} };
+assertEq(typeof Object.getOwnPropertyDescriptor(classWithStaticNameSetter, "name").set, "function");
+
+var n = "NAME".toLowerCase();
+var classWithStaticNameMethodComputed = class { static [n]() {} };
+assertEq(typeof classWithStaticNameMethodComputed.name, "function");
+
+// It doesn't apply for non-static method.
+
+var classWithNameMethod = class { name() {} };
+assertEq(classWithNameMethod.name, "classWithNameMethod");
+
+var classWithNameGetter = class { get name() { return "name"; } };
+assertEq(classWithNameGetter.name, "classWithNameGetter");
+
+var classWithNameSetter = class { set name(v) {} };
+assertEq(classWithNameSetter.name, "classWithNameSetter");
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/Function/function-name-for.js b/js/src/tests/non262/Function/function-name-for.js
new file mode 100644
index 0000000000..2f04a5fa8d
--- /dev/null
+++ b/js/src/tests/non262/Function/function-name-for.js
@@ -0,0 +1,31 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on for-in initializer";
+
+print(BUGNUMBER + ": " + summary);
+
+var exprs = [
+ ["function() {}", false],
+ ["function named() {}", true],
+ ["function*() {}", false],
+ ["function* named() {}", true],
+ ["async function() {}", false],
+ ["async function named() {}", true],
+ ["() => {}", false],
+ ["async () => {}", false],
+ ["class {}", false],
+ ["class named {}", true],
+];
+
+function testForInHead(expr, named) {
+ eval(`
+ for (var forInHead = ${expr} in {}) {
+ }
+ `);
+ assertEq(forInHead.name, named ? "named" : "forInHead");
+}
+for (var [expr, named] of exprs) {
+ testForInHead(expr, named);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/Function/function-name-method.js b/js/src/tests/non262/Function/function-name-method.js
new file mode 100644
index 0000000000..3b2eeee793
--- /dev/null
+++ b/js/src/tests/non262/Function/function-name-method.js
@@ -0,0 +1,70 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on method definition";
+
+print(BUGNUMBER + ": " + summary);
+
+var fooSymbol = Symbol("foo");
+var emptySymbol = Symbol("");
+var undefSymbol = Symbol();
+
+function testMethod(prefix, classPrefix="", prototype=false) {
+ var param = (prefix == "set" || prefix == "static set") ? "v" : "";
+ var sep = classPrefix ? "" : ",";
+ var objOrClass = eval(`(${classPrefix}{
+ ${prefix} prop(${param}) {} ${sep}
+ ${prefix} "literal"(${param}) {} ${sep}
+ ${prefix} ""(${param}) {} ${sep}
+ ${prefix} 5(${param}) {} ${sep}
+ ${prefix} [Symbol.iterator](${param}) {} ${sep}
+ ${prefix} [fooSymbol](${param}) {} ${sep}
+ ${prefix} [emptySymbol](${param}) {} ${sep}
+ ${prefix} [undefSymbol](${param}) {} ${sep}
+ ${prefix} [/a/](${param}) {} ${sep}
+ })`);
+
+ var target = prototype ? objOrClass.prototype : objOrClass;
+
+ function testOne(methodName, expectedName) {
+ var f;
+ if (prefix == "get" || prefix == "static get") {
+ f = Object.getOwnPropertyDescriptor(target, methodName).get;
+ expectedName = "get " + expectedName;
+ } else if (prefix == "set" || prefix == "static set") {
+ f = Object.getOwnPropertyDescriptor(target, methodName).set;
+ expectedName = "set " + expectedName;
+ } else {
+ f = Object.getOwnPropertyDescriptor(target, methodName).value;
+ }
+
+ assertEq(f.name, expectedName);
+ }
+ testOne("prop", "prop");
+ testOne("literal", "literal");
+ testOne("", "");
+ testOne(5, "5");
+ testOne(Symbol.iterator, "[Symbol.iterator]");
+ testOne(fooSymbol, "[foo]");
+ testOne(emptySymbol, "[]");
+ testOne(undefSymbol, "");
+ testOne(/a/, "/a/");
+}
+testMethod("");
+testMethod("*");
+testMethod("async");
+testMethod("get");
+testMethod("set");
+
+testMethod("", "class", true);
+testMethod("*", "class", true);
+testMethod("async", "class", true);
+testMethod("get", "class", true);
+testMethod("set", "class", true);
+
+testMethod("static", "class");
+testMethod("static *", "class");
+testMethod("static async", "class");
+testMethod("static get", "class");
+testMethod("static set", "class");
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/Function/function-name-property.js b/js/src/tests/non262/Function/function-name-property.js
new file mode 100644
index 0000000000..7ad174b10f
--- /dev/null
+++ b/js/src/tests/non262/Function/function-name-property.js
@@ -0,0 +1,58 @@
+var BUGNUMBER = 883377;
+var summary = "Anonymous function name should be set based on property name";
+
+print(BUGNUMBER + ": " + summary);
+
+var fooSymbol = Symbol("foo");
+var emptySymbol = Symbol("");
+var undefSymbol = Symbol();
+
+var exprs = [
+ ["function() {}", false],
+ ["function named() {}", true],
+ ["function*() {}", false],
+ ["function* named() {}", true],
+ ["async function() {}", false],
+ ["async function named() {}", true],
+ ["() => {}", false],
+ ["async () => {}", false],
+ ["class {}", false],
+ ["class named {}", true],
+];
+
+function testPropertyDefinition(expr, named) {
+ var obj = eval(`({
+ prop: ${expr},
+ "literal": ${expr},
+ "": ${expr},
+ 5: ${expr},
+ 0.4: ${expr},
+ [Symbol.iterator]: ${expr},
+ [fooSymbol]: ${expr},
+ [emptySymbol]: ${expr},
+ [undefSymbol]: ${expr},
+ [/a/]: ${expr},
+ })`);
+ assertEq(obj.prop.name, named ? "named" : "prop");
+ assertEq(obj["literal"].name, named ? "named" : "literal");
+ assertEq(obj[""].name, named ? "named" : "");
+ assertEq(obj[5].name, named ? "named" : "5");
+ assertEq(obj[0.4].name, named ? "named" : "0.4");
+ assertEq(obj[Symbol.iterator].name, named ? "named" : "[Symbol.iterator]");
+ assertEq(obj[fooSymbol].name, named ? "named" : "[foo]");
+ assertEq(obj[emptySymbol].name, named ? "named" : "[]");
+ assertEq(obj[undefSymbol].name, named ? "named" : "");
+ assertEq(obj[/a/].name, named ? "named" : "/a/");
+
+ // Not applicable cases: __proto__.
+ obj = {
+ __proto__: function() {}
+ };
+ assertEq(obj.__proto__.name, "");
+}
+for (var [expr, named] of exprs) {
+ testPropertyDefinition(expr, named);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/Function/function-name.js b/js/src/tests/non262/Function/function-name.js
new file mode 100644
index 0000000000..7beca56df5
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/function-toString-builtin-name.js b/js/src/tests/non262/Function/function-toString-builtin-name.js
new file mode 100644
index 0000000000..709e7e846b
--- /dev/null
+++ b/js/src/tests/non262/Function/function-toString-builtin-name.js
@@ -0,0 +1,53 @@
+// Repeats the test from 'Function/function-toString-builtin.js' and additionally
+// verifies the name matches the expected value.
+//
+// This behaviour is not required by the ECMAScript standard.
+
+// Greatly (!) simplified patterns for the PropertyName production.
+var propertyName = [
+ // PropertyName :: LiteralPropertyName :: IdentifierName
+ "\\w+",
+
+ // PropertyName :: LiteralPropertyName :: StringLiteral
+ "(?:'[^']*')",
+ "(?:\"[^\"]*\")",
+
+ // PropertyName :: LiteralPropertyName :: NumericLiteral
+ "\\d+",
+
+ // PropertyName :: ComputedPropertyName
+ "(?:\\[[^\\]]+\\])",
+].join("|")
+
+var nativeCode = RegExp([
+ "^", "function", ("(" + propertyName + ")?"), "\\(", "\\)", "\\{", "\\[native code\\]", "\\}", "$"
+].join("\\s*"));
+
+function assertFunctionName(fun, expected) {
+ var match = nativeCode.exec(fun.toString());
+ assertEq(match[1], expected);
+}
+
+// Bound functions are considered built-ins.
+assertFunctionName(function(){}.bind(), undefined);
+assertFunctionName(function fn(){}.bind(), undefined);
+
+// Built-ins which are well-known intrinsic objects.
+assertFunctionName(Array, "Array");
+assertFunctionName(Object.prototype.toString, "toString");
+assertFunctionName(decodeURI, "decodeURI");
+
+// Other built-in functions.
+assertFunctionName(Math.asin, "asin");
+assertFunctionName(String.prototype.blink, "blink");
+assertFunctionName(RegExp.prototype[Symbol.split], "[Symbol.split]");
+
+// Built-in getter functions.
+assertFunctionName(Object.getOwnPropertyDescriptor(RegExp.prototype, "flags").get, "flags");
+assertFunctionName(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").get, "__proto__");
+
+// Built-in setter functions.
+assertFunctionName(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set, "__proto__");
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/Function/function-toString-builtin.js b/js/src/tests/non262/Function/function-toString-builtin.js
new file mode 100644
index 0000000000..d4efc81c14
--- /dev/null
+++ b/js/src/tests/non262/Function/function-toString-builtin.js
@@ -0,0 +1,42 @@
+
+// Greatly (!) simplified patterns for the PropertyName production.
+var propertyName = [
+ // PropertyName :: LiteralPropertyName :: IdentifierName
+ "\\w+",
+
+ // PropertyName :: LiteralPropertyName :: StringLiteral
+ "(?:'[^']*')",
+ "(?:\"[^\"]*\")",
+
+ // PropertyName :: LiteralPropertyName :: NumericLiteral
+ "\\d+",
+
+ // PropertyName :: ComputedPropertyName
+ "(?:\\[[^\\]]+\\])",
+].join("|")
+
+var nativeCode = RegExp([
+ "^", "function", ("(?:" + propertyName + ")?"), "\\(", "\\)", "\\{", "\\[native code\\]", "\\}", "$"
+].join("\\s*"));
+
+
+// Bound functions are considered built-ins.
+reportMatch(nativeCode, function(){}.bind().toString());
+reportMatch(nativeCode, function fn(){}.bind().toString());
+
+// Built-ins which are well-known intrinsic objects.
+reportMatch(nativeCode, Array.toString());
+reportMatch(nativeCode, Object.prototype.toString.toString());
+reportMatch(nativeCode, decodeURI.toString());
+
+// Other built-in functions.
+reportMatch(nativeCode, Math.asin.toString());
+reportMatch(nativeCode, String.prototype.blink.toString());
+reportMatch(nativeCode, RegExp.prototype[Symbol.split].toString());
+
+// Built-in getter functions.
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(RegExp.prototype, "flags").get.toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").get.toString());
+
+// Built-in setter functions.
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set.toString());
diff --git a/js/src/tests/non262/Function/get-function-realm.js b/js/src/tests/non262/Function/get-function-realm.js
new file mode 100644
index 0000000000..4efd94f971
--- /dev/null
+++ b/js/src/tests/non262/Function/get-function-realm.js
@@ -0,0 +1,45 @@
+var g1 = newGlobal();
+var g1Fun = g1.eval("function Fun() {}; Fun");
+
+// Bound function => cross-realm function.
+var bound1 = Function.prototype.bind.call(g1Fun);
+assertEq(Object.getPrototypeOf(new bound1()), g1.Fun.prototype);
+
+// Proxy => cross-realm function.
+var proxy1 = new Proxy(g1Fun, {
+ get: function() {} // Ensure "prototype" is |undefined|.
+});
+assertEq(Object.getPrototypeOf(new proxy1()), g1.Object.prototype);
+
+// Proxy => bound function => cross-realm function.
+var proxy2 = new Proxy(bound1, {
+ get: function() {}
+});
+assertEq(Object.getPrototypeOf(new proxy2()), g1.Object.prototype);
+
+// Revoked proxy => cross-realm function.
+var r1 = Proxy.revocable(g1Fun, {
+ get: function(t, name) {
+ assertEq(name, "prototype");
+ r1.revoke();
+ }
+});
+assertThrowsInstanceOf(() => new r1.proxy(), g1.TypeError);
+
+// Bound function => proxy => bound function => cross-realm function.
+var bound2 = Function.prototype.bind.call(proxy2);
+assertEq(Object.getPrototypeOf(new bound2()), g1.Object.prototype);
+
+// Proxy => cross-realm revoked proxy => cross-realm function.
+var r2 = Proxy.revocable(g1Fun, {
+ get: function(t, name) {
+ assertEq(name, "prototype");
+ r2.revoke();
+ }
+});
+var g2 = newGlobal();
+var proxy3 = new g2.Proxy(r2.proxy, {});
+assertThrowsInstanceOf(() => new proxy3(), g1.TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/Function/has-instance-jitted.js b/js/src/tests/non262/Function/has-instance-jitted.js
new file mode 100644
index 0000000000..a2d33abc7f
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/has-instance.js b/js/src/tests/non262/Function/has-instance.js
new file mode 100644
index 0000000000..f0c7bf28e1
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/implicit-this-in-parameter-expression.js b/js/src/tests/non262/Function/implicit-this-in-parameter-expression.js
new file mode 100644
index 0000000000..c58c53e2af
--- /dev/null
+++ b/js/src/tests/non262/Function/implicit-this-in-parameter-expression.js
@@ -0,0 +1,18 @@
+
+function f(a = eval(`
+ function g() {
+ 'use strict';
+ return this;
+ }
+
+ with ({}) {
+ g() /* implicit return value */
+ }
+ `)) {
+ return a
+};
+
+assertEq(f(), undefined);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/Function/invalid-parameter-list.js b/js/src/tests/non262/Function/invalid-parameter-list.js
new file mode 100644
index 0000000000..8aae89ef15
--- /dev/null
+++ b/js/src/tests/non262/Function/invalid-parameter-list.js
@@ -0,0 +1,27 @@
+// This constructor behaves like `Function` without checking
+// if the parameter list end is at the expected position.
+// We use this to make sure that the tests we use are otherwise
+// syntactically correct.
+function DumpFunction(...args) {
+ let code = "function anonymous(";
+ code += args.slice(0, -1).join(", ");
+ code += ") {\n";
+ code += args[args.length -1];
+ code += "\n}";
+ eval(code);
+}
+
+const tests = [
+ ["/*", "*/) {"],
+ ["//", ") {"],
+ ["a = `", "` ) {"],
+ [") { var x = function (", "} "],
+ ["x = function (", "}) {"]
+];
+
+for (const test of tests) {
+ DumpFunction(...test);
+ assertThrowsInstanceOf(() => new Function(...test), SyntaxError);
+}
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/non262/Function/length-with-destructuring-and-parameter-expression.js b/js/src/tests/non262/Function/length-with-destructuring-and-parameter-expression.js
new file mode 100644
index 0000000000..a3f00ac1f2
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/line-terminator-before-arrow.js b/js/src/tests/non262/Function/line-terminator-before-arrow.js
new file mode 100644
index 0000000000..52bdce7f3b
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/method-has-duplicated.js b/js/src/tests/non262/Function/method-has-duplicated.js
new file mode 100644
index 0000000000..dc0a9dfb42
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/parameter-redeclaration.js b/js/src/tests/non262/Function/parameter-redeclaration.js
new file mode 100644
index 0000000000..74e55e3aa9
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/redefine-arguments-length.js b/js/src/tests/non262/Function/redefine-arguments-length.js
new file mode 100644
index 0000000000..ad9ae742ff
--- /dev/null
+++ b/js/src/tests/non262/Function/redefine-arguments-length.js
@@ -0,0 +1,65 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'redefine-arguments-length.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 539766;
+var summary =
+ "Object.defineProperty sets arguments.length without setting the " +
+ "length-overridden bit";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function test_JSOP_ARGCNT()
+{
+ var length = "length";
+ Object.defineProperty(arguments, length, { value: 17 });
+ assertEq(arguments.length, 17);
+ assertEq(arguments[length], 17);
+}
+test_JSOP_ARGCNT();
+
+function test_js_fun_apply()
+{
+ var length = "length";
+ Object.defineProperty(arguments, length, { value: 17 });
+
+ function fun()
+ {
+ assertEq(arguments.length, 17);
+ assertEq(arguments[length], 17);
+ assertEq(arguments[0], "foo");
+ for (var i = 1; i < 17; i++)
+ assertEq(arguments[i], undefined);
+ }
+ fun.apply(null, arguments);
+}
+test_js_fun_apply("foo");
+
+function test_array_toString_sub_1()
+{
+ Object.defineProperty(arguments, "length", { value: 1 });
+ arguments.join = [].join;
+ assertEq([].toString.call(arguments), "1");
+}
+test_array_toString_sub_1(1, 2);
+
+function test_array_toString_sub_2()
+{
+ Object.defineProperty(arguments, "length", { value: 1 });
+ assertEq([].toLocaleString.call(arguments), "1");
+}
+test_array_toString_sub_2(1, 2);
+
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/regress-123371.js b/js/src/tests/non262/Function/regress-123371.js
new file mode 100644
index 0000000000..58294c6a02
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-123371.js
@@ -0,0 +1,19 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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 BUGNUMBER = 123371;
+var summary = 'Do not crash when newline separates function name from arglist';
+var actual = 'No Crash';
+var expect = 'No Crash';
+
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+printStatus
+('function call succeeded');
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/regress-131964.js b/js/src/tests/non262/Function/regress-131964.js
new file mode 100644
index 0000000000..d7451f040e
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-131964.js
@@ -0,0 +1,159 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ *
+ * Date: 19 Mar 2002
+ * SUMMARY: Function declarations in global or function scope are {DontDelete}.
+ * Function declarations in eval scope are not {DontDelete}.
+ *
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=131964
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 131964;
+var summary = 'Functions defined in global or function scope are {DontDelete}';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+
+status = inSection(1);
+function f()
+{
+ return 'f lives!';
+}
+delete f;
+
+try
+{
+ actual = f();
+}
+catch(e)
+{
+ actual = 'f was deleted';
+}
+
+expect = 'f lives!';
+addThis();
+
+
+
+/*
+ * Try the same test in function scope -
+ */
+status = inSection(2);
+function g()
+{
+ function f()
+ {
+ return 'f lives!';
+ }
+ delete f;
+
+ try
+ {
+ actual = f();
+ }
+ catch(e)
+ {
+ actual = 'f was deleted';
+ }
+
+ expect = 'f lives!';
+ addThis();
+}
+g();
+
+
+
+/*
+ * Try the same test in eval scope - here we EXPECT the function to be deleted (?)
+ */
+status = inSection(3);
+var s = '';
+s += 'function h()';
+s += '{ ';
+s += ' return "h lives!";';
+s += '}';
+s += 'delete h;';
+
+s += 'try';
+s += '{';
+s += ' actual = h();';
+s += '}';
+s += 'catch(e)';
+s += '{';
+s += ' actual = "h was deleted";';
+s += '}';
+
+s += 'expect = "h was deleted";';
+s += 'addThis();';
+eval(s);
+
+
+/*
+ * Define the function in eval scope, but delete it in global scope -
+ */
+status = inSection(4);
+s = '';
+s += 'function k()';
+s += '{ ';
+s += ' return "k lives!";';
+s += '}';
+eval(s);
+
+delete k;
+
+try
+{
+ actual = k();
+}
+catch(e)
+{
+ actual = 'k was deleted';
+}
+
+expect = 'k was deleted';
+addThis();
+
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+function wasDeleted(functionName)
+{
+ return functionName + ' was deleted...';
+}
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/Function/regress-137181.js b/js/src/tests/non262/Function/regress-137181.js
new file mode 100644
index 0000000000..6fddde2d1a
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-137181.js
@@ -0,0 +1,76 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ *
+ * Date: 12 Apr 2002
+ * SUMMARY: delete arguments[i] should break connection to local reference
+ *
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=137181
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 137181;
+var summary = 'delete arguments[i] should break connection to local reference';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+
+status = inSection(1);
+function f1(x)
+{
+ x = 1;
+ delete arguments[0];
+ return x;
+}
+actual = f1(0); // (bug: Rhino was returning |undefined|)
+expect = 1;
+addThis();
+
+
+status = inSection(2);
+function f2(x)
+{
+ x = 1;
+ delete arguments[0];
+ arguments[0] = -1;
+ return x;
+}
+actual = f2(0); // (bug: Rhino was returning -1)
+expect = 1;
+addThis();
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/Function/regress-178389.js b/js/src/tests/non262/Function/regress-178389.js
new file mode 100644
index 0000000000..e1735adf86
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-178389.js
@@ -0,0 +1,26 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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 BUGNUMBER = 178389;
+var summary = 'Function.prototype.toSource should not override Function.prototype.toString';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+function f()
+{
+ var g = function (){};
+}
+
+expect = f.toString();
+
+Function.prototype.toSource = function () { return ''; };
+
+actual = f.toString();
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/regress-193555.js b/js/src/tests/non262/Function/regress-193555.js
new file mode 100644
index 0000000000..c9c45f3311
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-193555.js
@@ -0,0 +1,99 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ *
+ * Date: 17 February 2003
+ * SUMMARY: Testing access to function name from inside function
+ *
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=193555
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 193555;
+var summary = 'Testing access to function name from inside function';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+
+// test via function statement
+status = inSection(1);
+function f() {return f.toString();};
+actual = f();
+expect = f.toString();
+addThis();
+
+// test via function expression
+status = inSection(2);
+var x = function g() {return g.toString();};
+actual = x();
+expect = x.toString();
+addThis();
+
+// test via eval() outside function
+status = inSection(3);
+eval ('function a() {return a.toString();}');
+actual = a();
+expect = a.toString();
+addThis();
+
+status = inSection(4);
+eval ('var y = function b() {return b.toString();}');
+actual = y();
+expect = y.toString();
+addThis();
+
+// test via eval() inside function
+status = inSection(5);
+function c() {return eval('c').toString();};
+actual = c();
+expect = c.toString();
+addThis();
+
+status = inSection(6);
+var z = function d() {return eval('d').toString();};
+actual = z();
+expect = z.toString();
+addThis();
+
+// test via two evals!
+status = inSection(7);
+eval('var w = function e() {return eval("e").toString();}');
+actual = w();
+expect = w.toString();
+addThis();
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/Function/regress-222029-001.js b/js/src/tests/non262/Function/regress-222029-001.js
new file mode 100644
index 0000000000..a58e60bc3d
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-222029-001.js
@@ -0,0 +1,123 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ *
+ * Date: 13 Oct 2003
+ * SUMMARY: Make our f.caller property match IE's wrt f.apply and f.call
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=222029
+ *
+ * Below, when gg calls f via |f.call|, we have this call chain:
+ *
+ * calls calls
+ * gg() ---------> Function.prototype.call() ---------> f()
+ *
+ *
+ * The question this bug addresses is, "What should we say |f.caller| is?"
+ *
+ * Before this fix, SpiderMonkey said it was |Function.prototype.call|.
+ * After this fix, SpiderMonkey emulates IE and says |gg| instead.
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 222029;
+var summary = "Make our f.caller property match IE's wrt f.apply and f.call";
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+
+function f()
+{
+ return f.caller.p ;
+}
+
+
+/*
+ * Call |f| directly
+ */
+function g()
+{
+ return f();
+}
+g.p = "hello";
+
+
+/*
+ * Call |f| via |f.call|
+ */
+function gg()
+{
+ return f.call(this);
+}
+gg.p = "hello";
+
+
+/*
+ * Call |f| via |f.apply|
+ */
+function ggg()
+{
+ return f.apply(this);
+}
+ggg.p = "hello";
+
+
+/*
+ * Shadow |p| on |Function.prototype.call|, |Function.prototype.apply|.
+ * In Sections 2 and 3 below, we no longer expect to recover this value -
+ */
+Function.prototype.call.p = "goodbye";
+Function.prototype.apply.p = "goodbye";
+
+
+
+status = inSection(1);
+actual = g();
+expect = "hello";
+addThis();
+
+status = inSection(2);
+actual = gg();
+expect = "hello";
+addThis();
+
+status = inSection(3);
+actual = ggg();
+expect = "hello";
+addThis();
+
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/Function/regress-222029-002.js b/js/src/tests/non262/Function/regress-222029-002.js
new file mode 100644
index 0000000000..96f68a2661
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-222029-002.js
@@ -0,0 +1,132 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ *
+ * Date: 13 Oct 2003
+ * SUMMARY: Make our f.caller property match IE's wrt f.apply and f.call
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=222029
+ *
+ * Below, when gg calls f via |f.call|, we have this call chain:
+ *
+ * calls calls
+ * gg() ---------> Function.prototype.call() ---------> f()
+ *
+ *
+ * The question this bug addresses is, "What should we say |f.caller| is?"
+ *
+ * Before this fix, SpiderMonkey said it was |Function.prototype.call|.
+ * After this fix, SpiderMonkey emulates IE and says |gg| instead.
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 222029;
+var summary = "Make our f.caller property match IE's wrt f.apply and f.call";
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+/*
+ * Try to confuse the engine by adding a |p| property to everything!
+ */
+var p = 'global';
+var o = {p:'object'};
+
+
+function f(obj)
+{
+ return f.caller.p ;
+}
+
+
+/*
+ * Call |f| directly
+ */
+function g(obj)
+{
+ var p = 'local';
+ return f(obj);
+}
+g.p = "hello";
+
+
+/*
+ * Call |f| via |f.call|
+ */
+function gg(obj)
+{
+ var p = 'local';
+ return f.call(obj, obj);
+}
+gg.p = "hello";
+
+
+/*
+ * Call |f| via |f.apply|
+ */
+function ggg(obj)
+{
+ var p = 'local';
+ return f.apply(obj, [obj]);
+}
+ggg.p = "hello";
+
+
+/*
+ * Shadow |p| on |Function.prototype.call|, |Function.prototype.apply|.
+ * In Sections 2 and 3 below, we no longer expect to recover this value -
+ */
+Function.prototype.call.p = "goodbye";
+Function.prototype.apply.p = "goodbye";
+
+
+
+status = inSection(1);
+actual = g(o);
+expect = "hello";
+addThis();
+
+status = inSection(2);
+actual = gg(o);
+expect = "hello";
+addThis();
+
+status = inSection(3);
+actual = ggg(o);
+expect = "hello";
+addThis();
+
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/Function/regress-292215.js b/js/src/tests/non262/Function/regress-292215.js
new file mode 100644
index 0000000000..c264b74178
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-292215.js
@@ -0,0 +1,37 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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 BUGNUMBER = 292215;
+var summary = 'Set arguments';
+var actual = '';
+var expect = '00012';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+
+function zeroArguments () {
+ arguments[1] = '0';
+ actual += arguments[1];
+}
+
+function oneArgument (x) {
+ arguments[1] = '1';
+ actual += arguments[1];
+}
+
+function twoArguments (x,y) {
+ arguments[1] = '2';
+ actual += arguments[1];
+}
+
+zeroArguments();
+zeroArguments(1);
+zeroArguments('a', 'b');
+oneArgument();
+twoArguments();
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/regress-313570.js b/js/src/tests/non262/Function/regress-313570.js
new file mode 100644
index 0000000000..eb3039650b
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-313570.js
@@ -0,0 +1,30 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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 BUGNUMBER = 313570;
+var summary = 'length of objects whose prototype chain includes a function';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+function tmp() {}
+tmp.prototype = function(a, b, c) {};
+var obj = new tmp();
+
+// arity
+expect = 3;
+actual = obj.length;
+reportCompare(expect, actual, summary + ': arity');
+
+// immutable
+obj.length = 10;
+
+expect = 3;
+actual = obj.length;
+reportCompare(expect, actual, summary + ': immutable');
+
diff --git a/js/src/tests/non262/Function/regress-338001.js b/js/src/tests/non262/Function/regress-338001.js
new file mode 100644
index 0000000000..6afdc4f6fc
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-338001.js
@@ -0,0 +1,42 @@
+// |reftest| skip-if(Android) silentfail slow
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 BUGNUMBER = 338001;
+var summary = 'integer overflow in jsfun.c:Function';
+var actual = 'No Crash';
+var expect = /No Crash|InternalError: allocation size overflow/;
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+expectExitCode(0);
+expectExitCode(5);
+
+var fe="f";
+
+try
+{
+ for (i=0; i<25; i++)
+ fe += fe;
+
+ var fu=new Function(
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ "done"
+ );
+}
+catch(ex)
+{
+ // handle changed 1.9 branch behavior. see bug 422348
+ actual = ex + '';
+}
+
+print('Done: ' + actual);
+
+reportMatch(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/regress-338121-01.js b/js/src/tests/non262/Function/regress-338121-01.js
new file mode 100644
index 0000000000..e51d8c952e
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-338121-01.js
@@ -0,0 +1,33 @@
+// |reftest| skip-if(Android) silentfail slow
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 BUGNUMBER = 338121;
+var summary = 'Issues with JS_ARENA_ALLOCATE_CAST';
+var actual = 'No Crash';
+var expect = 'No Crash';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+expectExitCode(0);
+expectExitCode(5);
+expectExitCode(3);
+
+var fe="v";
+
+for (i=0; i<25; i++)
+ fe += fe;
+
+var fu=new Function(
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ "done"
+ );
+
+print('Done');
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/regress-338121-02.js b/js/src/tests/non262/Function/regress-338121-02.js
new file mode 100644
index 0000000000..f051c00ce2
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-338121-02.js
@@ -0,0 +1,36 @@
+// |reftest| skip-if(Android) silentfail skip -- disabled pending bug 657444
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 BUGNUMBER = 338121;
+var summary = 'Issues with JS_ARENA_ALLOCATE_CAST';
+var actual = 'No Crash';
+var expect = 'No Crash';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+expectExitCode(0);
+expectExitCode(5);
+
+var fe="vv";
+
+for (i=0; i<24; i++)
+ fe += fe;
+
+var fu=new Function(
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ "done"
+ );
+
+//alert("fu="+fu);
+//print("fu="+fu);
+var fuout = 'fu=' + fu;
+
+print('Done');
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/regress-338121-03.js b/js/src/tests/non262/Function/regress-338121-03.js
new file mode 100644
index 0000000000..4fd6ea2928
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-338121-03.js
@@ -0,0 +1,38 @@
+// |reftest| skip-if(Android) silentfail slow
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 BUGNUMBER = 338121;
+var summary = 'Issues with JS_ARENA_ALLOCATE_CAST';
+var actual = 'No Crash';
+var expect = 'No Crash';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+expectExitCode(0);
+expectExitCode(5);
+
+var fe="vv";
+
+for (i=0; i<24; i++)
+ fe += fe;
+
+var fu=new Function(
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe, fe,
+ fe, fe, fe,
+ "done"
+ );
+
+//alert("fu="+fu);
+//print("fu="+fu);
+var fuout = 'fu=' + fu;
+
+print('Done');
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/regress-344052.js b/js/src/tests/non262/Function/regress-344052.js
new file mode 100644
index 0000000000..f9f747276f
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-344052.js
@@ -0,0 +1,27 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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 BUGNUMBER = 344052;
+var summary = 'Function prototype - simple shared property';
+var actual = '';
+var expect = 'true';
+
+Function.prototype.foo = true;
+function y(){};
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ actual = String(y.foo);
+
+ reportCompare(expect, actual, summary);
+}
diff --git a/js/src/tests/non262/Function/regress-364023.js b/js/src/tests/non262/Function/regress-364023.js
new file mode 100644
index 0000000000..6102351a6a
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-364023.js
@@ -0,0 +1,37 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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 BUGNUMBER = 364023;
+var summary = 'Do not crash in JS::GetPrivate';
+var actual = 'No Crash';
+var expect = 'No Crash';
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ function exploit() {
+ var code = "";
+ for(var i = 0; i < 0x10000; i++) {
+ if(i == 125) {
+ code += "void 0x10000050505050;\n";
+ } else {
+ code += "void " + (0x10000000000000 + i) + ";\n";
+ }
+ }
+ code += "function foo() {}\n";
+ eval(code);
+ }
+ exploit();
+
+ reportCompare(expect, actual, summary);
+}
diff --git a/js/src/tests/non262/Function/regress-49286.js b/js/src/tests/non262/Function/regress-49286.js
new file mode 100644
index 0000000000..0b748b3ebf
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-49286.js
@@ -0,0 +1,100 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ * Date: 2001-07-10
+ *
+ * SUMMARY: Invoking try...catch through Function.call
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=49286
+ *
+ * 1) Define a function with a try...catch block in it
+ * 2) Invoke the function via the call method of Function
+ * 3) Pass bad syntax to the try...catch block
+ * 4) We should catch the error!
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 49286;
+var summary = 'Invoking try...catch through Function.call';
+var cnErrorCaught = 'Error caught';
+var cnErrorNotCaught = 'Error NOT caught';
+var cnGoodSyntax = '1==2';
+var cnBadSyntax = '1=2';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+
+var obj = new testObject();
+
+status = 'Section A of test: direct call of f';
+actual = f.call(obj);
+expect = cnErrorCaught;
+addThis();
+
+status = 'Section B of test: indirect call of f';
+actual = g.call(obj);
+expect = cnErrorCaught;
+addThis();
+
+
+
+//-----------------------------------------
+test();
+//-----------------------------------------
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
+
+
+// An object storing bad syntax as a property -
+function testObject()
+{
+ this.badSyntax = cnBadSyntax;
+ this.goodSyntax = cnGoodSyntax;
+}
+
+
+// A function wrapping a try...catch block
+function f()
+{
+ try
+ {
+ eval(this.badSyntax);
+ }
+ catch(e)
+ {
+ return cnErrorCaught;
+ }
+ return cnErrorNotCaught;
+}
+
+
+// A function wrapping a call to f -
+function g()
+{
+ return f.call(this);
+}
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
diff --git a/js/src/tests/non262/Function/regress-518103.js b/js/src/tests/non262/Function/regress-518103.js
new file mode 100644
index 0000000000..70bab0d572
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-518103.js
@@ -0,0 +1,27 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 518103;
+var summary = 'lambda constructor "method" vs. instanceof';
+var actual;
+var expect;
+
+printBugNumber(BUGNUMBER);
+printStatus(summary);
+
+var Y = {widget: {}};
+
+Y.widget.DataSource = function () {};
+Y.widget.DS_JSArray = function (A) { this.data = A; };
+Y.widget.DS_JSArray.prototype = new Y.widget.DataSource();
+
+var J = new Y.widget.DS_JSArray( [ ] );
+
+actual = J instanceof Y.widget.DataSource;
+expect = true;
+
+reportCompare(expect, actual, summary);
+
+printStatus("All tests passed!");
diff --git a/js/src/tests/non262/Function/regress-524826.js b/js/src/tests/non262/Function/regress-524826.js
new file mode 100644
index 0000000000..da1dfbba08
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-524826.js
@@ -0,0 +1,28 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 524826;
+var summary = 'null-closure property initialiser mis-brands object literal scope';
+var actual;
+var expect;
+
+printBugNumber(BUGNUMBER);
+printStatus(summary);
+
+function make(g) {
+ var o = {f: function(a,b) { return a*b; }, g: g};
+ return o;
+}
+var z = -1;
+var x = make(function(c) { return c*z; });
+var y = make(function(c) { return -c*z; });
+
+function callg(o, c) { return o.g(c); };
+actual = callg(x, 1);
+expect = -callg(y, 1);
+
+reportCompare(expect, actual, summary);
+
+printStatus("All tests passed!");
diff --git a/js/src/tests/non262/Function/regress-528082.js b/js/src/tests/non262/Function/regress-528082.js
new file mode 100644
index 0000000000..1ca7b77cbb
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-528082.js
@@ -0,0 +1,20 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 528082;
+var summary = 'named function expression function-name-as-upvar slot botch';
+
+printBugNumber(BUGNUMBER);
+printStatus(summary);
+
+function f() {
+ return function g(a) { return function () { return g; }(); }();
+}
+var actual = typeof f();
+var expect = "function";
+
+reportCompare(expect, actual, summary);
+
+printStatus("All tests passed!");
diff --git a/js/src/tests/non262/Function/regress-533254.js b/js/src/tests/non262/Function/regress-533254.js
new file mode 100644
index 0000000000..b0e319818b
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-533254.js
@@ -0,0 +1,28 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 533254;
+var summary = 'init-method late in table-big initialiser screwup';
+
+printBugNumber(BUGNUMBER);
+printStatus(summary);
+
+function f() {
+ var proto = {p8:8};
+ var obj = {
+ p0:0, p1:1, p2:2, p3:3, p4:4, p5:5, p6:6, p7:7, p8:8, p9:9,
+ p10:0, p11:1, p12:2, p13:3, p14:4, p15:5, p16:6, p17:7, p18:8, p19:9,
+ m: function() { return 42; }
+ };
+ return obj;
+}
+var expect = f(),
+ actual = f();
+
+expect += '';
+actual += '';
+reportCompare(expect, actual, summary);
+
+printStatus("All tests passed!");
diff --git a/js/src/tests/non262/Function/regress-545980.js b/js/src/tests/non262/Function/regress-545980.js
new file mode 100644
index 0000000000..5e29def494
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-545980.js
@@ -0,0 +1,41 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 518103;
+var summary = 'partial flat closures must not reach across funargs';
+var actual = "no crash";
+var expect = actual;
+
+function Timer(){}
+Timer.prototype = { initWithCallback: function (o) {Timer.q.push(o)} };
+Timer.q = [];
+
+var later;
+var ac = {startSearch: function(q,s,n,o){later=o}};
+
+var bm = {insertBookmark: function(){}, getIdForItemAt: function(){}};
+
+function run_test() {
+ var tagIds = [];
+
+ (function doSearch(query) {
+ ac.startSearch(query, "", null, {
+ onSearchResult: function() {
+ var num = tagIds.length;
+
+ var timer = new Timer;
+ var next = query.slice(1);
+ timer.initWithCallback({ notify: function() { return doSearch(next); } });
+ }
+ });
+ })("title");
+}
+
+run_test();
+later.onSearchResult();
+for (var i in Timer.q)
+ Timer.q[i].notify();
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/Function/regress-58274.js b/js/src/tests/non262/Function/regress-58274.js
new file mode 100644
index 0000000000..f8ef3e5880
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-58274.js
@@ -0,0 +1,189 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ *
+ * Date: 15 July 2002
+ * SUMMARY: Testing functions with double-byte names
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=58274
+ *
+ * Here is a sample of the problem:
+ *
+ * js> function f\u02B1 () {}
+ *
+ * js> f\u02B1.toSource();
+ * function f¦() {}
+ *
+ * js> f\u02B1.toSource().toSource();
+ * (new String("function f\xB1() {}"))
+ *
+ *
+ * See how the high-byte information (the 02) has been lost?
+ * The same thing was happening with the toString() method:
+ *
+ * js> f\u02B1.toString();
+ *
+ * function f¦() {
+ * }
+ *
+ * js> f\u02B1.toString().toSource();
+ * (new String("\nfunction f\xB1() {\n}\n"))
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 58274;
+var summary = 'Testing functions with double-byte names';
+var ERR = 'UNEXPECTED ERROR! \n';
+var ERR_MALFORMED_NAME = ERR + 'Could not find function name in: \n\n';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+var sEval;
+var sName;
+
+
+sEval = "function f\u02B2() {return 42;}";
+eval(sEval);
+sName = getFunctionName(f\u02B2);
+
+// Test function call -
+status = inSection(1);
+actual = f\u02B2();
+expect = 42;
+addThis();
+
+// Test both characters of function name -
+status = inSection(2);
+actual = sName[0];
+expect = sEval[9];
+addThis();
+
+status = inSection(3);
+actual = sName[1];
+expect = sEval[10];
+addThis();
+
+
+
+sEval = "function f\u02B2\u0AAA () {return 84;}";
+eval(sEval);
+sName = getFunctionName(f\u02B2\u0AAA);
+
+// Test function call -
+status = inSection(4);
+actual = f\u02B2\u0AAA();
+expect = 84;
+addThis();
+
+// Test all three characters of function name -
+status = inSection(5);
+actual = sName[0];
+expect = sEval[9];
+addThis();
+
+status = inSection(6);
+actual = sName[1];
+expect = sEval[10];
+addThis();
+
+status = inSection(7);
+actual = sName[2];
+expect = sEval[11];
+addThis();
+
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+/*
+ * Goal: test that f.toString() contains the proper function name.
+ *
+ * Note, however, f.toString() is implementation-independent. For example,
+ * it may begin with '\nfunction' instead of 'function'. Therefore we use
+ * a regexp to make sure we extract the name properly.
+ *
+ * Here we assume that f has been defined by means of a function statement,
+ * and not a function expression (where it wouldn't have to have a name).
+ *
+ * Rhino uses a Unicode representation for f.toString(); whereas
+ * SpiderMonkey uses an ASCII representation, putting escape sequences
+ * for non-ASCII characters. For example, if a function is called f\u02B1,
+ * then in Rhino the toString() method will present a 2-character Unicode
+ * string for its name, whereas SpiderMonkey will present a 7-character
+ * ASCII string for its name: the string literal 'f\u02B1'.
+ *
+ * So we force the lexer to condense the string before using it.
+ * This will give uniform results in Rhino and SpiderMonkey.
+ */
+function getFunctionName(f)
+{
+ var s = condenseStr(f.toString());
+ var re = /\s*function\s+(\S+)\s*\(/;
+ var arr = s.match(re);
+
+ if (!(arr && arr[1]))
+ return ERR_MALFORMED_NAME + s;
+ return arr[1];
+}
+
+
+/*
+ * This function is the opposite of functions like escape(), which take
+ * Unicode characters and return escape sequences for them. Here, we force
+ * the lexer to turn escape sequences back into single characters.
+ *
+ * Note we can't simply do |eval(str)|, since in practice |str| will be an
+ * identifier somewhere in the program (e.g. a function name); thus |eval(str)|
+ * would return the object that the identifier represents: not what we want.
+ *
+ * So we surround |str| lexicographically with quotes to force the lexer to
+ * evaluate it as a string. Have to strip out any linefeeds first, however -
+ */
+function condenseStr(str)
+{
+ /*
+ * You won't be able to do the next step if |str| has
+ * any carriage returns or linefeeds in it. For example:
+ *
+ * js> eval("'" + '\nHello' + "'");
+ * 1: SyntaxError: unterminated string literal:
+ * 1: '
+ * 1: ^
+ *
+ * So replace them with the empty string -
+ */
+ str = str.replace(/[\r\n]/g, '')
+ return eval("'" + str + "'");
+}
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/Function/regress-85880.js b/js/src/tests/non262/Function/regress-85880.js
new file mode 100644
index 0000000000..d5d6d63175
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-85880.js
@@ -0,0 +1,136 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ * Date: 2001-06-14
+ *
+ * SUMMARY: Regression test for Bugzilla bug 85880
+ *
+ * Rhino interpreted mode was nulling out the arguments object of a
+ * function if it happened to call another function inside its body.
+ *
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=85880
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 85880;
+var summary = 'Arguments object of g(){f()} should not be null';
+var cnNonNull = 'Arguments != null';
+var cnNull = 'Arguments == null';
+var cnRecurse = true;
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+
+function f1(x)
+{
+}
+
+
+function f2()
+{
+ return f2.arguments;
+}
+status = 'Section A of test';
+actual = (f2() == null);
+expect = false;
+addThis();
+
+status = 'Section B of test';
+actual = (f2(0) == null);
+expect = false;
+addThis();
+
+
+function f3()
+{
+ f1();
+ return f3.arguments;
+}
+status = 'Section C of test';
+actual = (f3() == null);
+expect = false;
+addThis();
+
+status = 'Section D of test';
+actual = (f3(0) == null);
+expect = false;
+addThis();
+
+
+function f4()
+{
+ f1();
+ f2();
+ f3();
+ return f4.arguments;
+}
+status = 'Section E of test';
+actual = (f4() == null);
+expect = false;
+addThis();
+
+status = 'Section F of test';
+actual = (f4(0) == null);
+expect = false;
+addThis();
+
+
+function f5()
+{
+ if (cnRecurse)
+ {
+ cnRecurse = false;
+ f5();
+ }
+ return f5.arguments;
+}
+status = 'Section G of test';
+actual = (f5() == null);
+expect = false;
+addThis();
+
+status = 'Section H of test';
+actual = (f5(0) == null);
+expect = false;
+addThis();
+
+
+
+//-------------------------------------------------------------------------------------------------
+test();
+//-------------------------------------------------------------------------------------------------
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = isThisNull(actual);
+ expectedvalues[UBound] = isThisNull(expect);
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ for (var i = 0; i < UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
+
+
+function isThisNull(bool)
+{
+ return bool? cnNull : cnNonNull
+ }
diff --git a/js/src/tests/non262/Function/regress-94506.js b/js/src/tests/non262/Function/regress-94506.js
new file mode 100644
index 0000000000..048c7fcfaf
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-94506.js
@@ -0,0 +1,126 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ * Date: 08 August 2001
+ *
+ * SUMMARY: When we invoke a function, the arguments object should take
+ * a back seat to any local identifier named "arguments".
+ *
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=94506
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 94506;
+var summary = 'Testing functions employing identifiers named "arguments"';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+var TYPE_OBJECT = typeof new Object();
+var arguments = 5555;
+
+
+// use a parameter named "arguments"
+function F1(arguments)
+{
+ return arguments;
+}
+
+
+// use a local variable named "arguments"
+function F2()
+{
+ var arguments = 55;
+ return arguments;
+}
+
+
+// same thing in a different order. CHANGES THE RESULT!
+function F3()
+{
+ return arguments;
+ var arguments = 555;
+}
+
+
+// use the global variable above named "arguments"
+function F4()
+{
+ return arguments;
+}
+
+
+
+/*
+ * In Sections 1 and 2, expect the local identifier, not the arguments object.
+ * In Sections 3 and 4, expect the arguments object, not the the identifier.
+ */
+
+status = 'Section 1 of test';
+actual = F1(5);
+expect = 5;
+addThis();
+
+
+status = 'Section 2 of test';
+actual = F2();
+expect = 55;
+addThis();
+
+
+status = 'Section 3 of test';
+actual = typeof F3();
+expect = TYPE_OBJECT;
+addThis();
+
+
+status = 'Section 4 of test';
+actual = typeof F4();
+expect = TYPE_OBJECT;
+addThis();
+
+
+// Let's try calling F1 without providing a parameter -
+status = 'Section 5 of test';
+actual = F1();
+expect = undefined;
+addThis();
+
+
+// Let's try calling F1 with too many parameters -
+status = 'Section 6 of test';
+actual = F1(3,33,333);
+expect = 3;
+addThis();
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ for (var i = 0; i < UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/Function/regress-97921.js b/js/src/tests/non262/Function/regress-97921.js
new file mode 100644
index 0000000000..1bea04a1dd
--- /dev/null
+++ b/js/src/tests/non262/Function/regress-97921.js
@@ -0,0 +1,115 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ * Date: 10 September 2001
+ *
+ * SUMMARY: Testing with() statement with nested functions
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=97921
+ *
+ * Brendan: "The bug is peculiar to functions that have formal parameters,
+ * but that are called with fewer actual arguments than the declared number
+ * of formal parameters."
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 97921;
+var summary = 'Testing with() statement with nested functions';
+var cnYES = 'Inner value === outer value';
+var cnNO = "Inner value !== outer value!";
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+var outerValue = '';
+var innerValue = '';
+var useWith = '';
+
+
+function F(i)
+{
+ i = 0;
+ if(useWith) with(1){i;}
+ i++;
+
+ outerValue = i; // capture value of i in outer function
+ F1 = function() {innerValue = i;}; // capture value of i in inner function
+ F1();
+}
+
+
+status = inSection(1);
+useWith=false;
+F(); // call F without supplying the argument
+actual = innerValue === outerValue;
+expect = true;
+addThis();
+
+status = inSection(2);
+useWith=true;
+F(); // call F without supplying the argument
+actual = innerValue === outerValue;
+expect = true;
+addThis();
+
+
+function G(i)
+{
+ i = 0;
+ with (new Object()) {i=100};
+ i++;
+
+ outerValue = i; // capture value of i in outer function
+ G1 = function() {innerValue = i;}; // capture value of i in inner function
+ G1();
+}
+
+
+status = inSection(3);
+G(); // call G without supplying the argument
+actual = innerValue === 101;
+expect = true;
+addThis();
+
+status = inSection(4);
+G(); // call G without supplying the argument
+actual = innerValue === outerValue;
+expect = true;
+addThis();
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = areTheseEqual(actual);
+ expectedvalues[UBound] = areTheseEqual(expect);
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ for (var i = 0; i < UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
+
+
+function areTheseEqual(yes)
+{
+ return yes? cnYES : cnNO
+ }
diff --git a/js/src/tests/non262/Function/rest-has-duplicated.js b/js/src/tests/non262/Function/rest-has-duplicated.js
new file mode 100644
index 0000000000..67577ab4e3
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/rest-parameter-names.js b/js/src/tests/non262/Function/rest-parameter-names.js
new file mode 100644
index 0000000000..6cfa01dcfb
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/return-finally.js b/js/src/tests/non262/Function/return-finally.js
new file mode 100644
index 0000000000..fe075d4576
--- /dev/null
+++ b/js/src/tests/non262/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/non262/Function/shell.js b/js/src/tests/non262/Function/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/non262/Function/shell.js
diff --git a/js/src/tests/non262/Function/spread-iterator-primitive.js b/js/src/tests/non262/Function/spread-iterator-primitive.js
new file mode 100644
index 0000000000..79320ad7f1
--- /dev/null
+++ b/js/src/tests/non262/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);
diff --git a/js/src/tests/non262/Function/strict-arguments.js b/js/src/tests/non262/Function/strict-arguments.js
new file mode 100644
index 0000000000..fce5f756c2
--- /dev/null
+++ b/js/src/tests/non262/Function/strict-arguments.js
@@ -0,0 +1,453 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'strict-arguments.js';
+var BUGNUMBER = 516255;
+var summary =
+ "ES5 strict mode: arguments objects of strict mode functions must copy " +
+ "argument values";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function arrayEvery(arr, fun)
+{
+ return Array.prototype.every.call(arr, fun);
+}
+
+function arraysEqual(a1, a2)
+{
+ return a1.length === a2.length &&
+ arrayEvery(a1, function(v, i) { return v === a2[i]; });
+}
+
+
+/************************
+ * NON-STRICT ARGUMENTS *
+ ************************/
+
+var obj = {};
+
+function noargs() { return arguments; }
+
+assertEq(arraysEqual(noargs(), []), true);
+assertEq(arraysEqual(noargs(1), [1]), true);
+assertEq(arraysEqual(noargs(2, obj, 8), [2, obj, 8]), true);
+
+function args(a) { return arguments; }
+
+assertEq(arraysEqual(args(), []), true);
+assertEq(arraysEqual(args(1), [1]), true);
+assertEq(arraysEqual(args(1, obj), [1, obj]), true);
+assertEq(arraysEqual(args("foopy"), ["foopy"]), true);
+
+function assign(a)
+{
+ a = 17;
+ return arguments;
+}
+
+assertEq(arraysEqual(assign(1), [17]), true);
+
+function getLaterAssign(a)
+{
+ var o = arguments;
+ a = 17;
+ return o;
+}
+
+assertEq(arraysEqual(getLaterAssign(1), [17]), true);
+
+function assignElementGetParameter(a)
+{
+ arguments[0] = 17;
+ return a;
+}
+
+assertEq(assignElementGetParameter(42), 17);
+
+function assignParameterGetElement(a)
+{
+ a = 17;
+ return arguments[0];
+}
+
+assertEq(assignParameterGetElement(42), 17);
+
+function assignArgSub(x, y)
+{
+ arguments[0] = 3;
+ return arguments[0];
+}
+
+assertEq(assignArgSub(1), 3);
+
+function assignArgSubParamUse(x, y)
+{
+ arguments[0] = 3;
+ assertEq(x, 3);
+ return arguments[0];
+}
+
+assertEq(assignArgSubParamUse(1), 3);
+
+function assignArgumentsElement(x, y)
+{
+ arguments[0] = 3;
+ return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations
+}
+
+assertEq(assignArgumentsElement(1), 3);
+
+function assignArgumentsElementParamUse(x, y)
+{
+ arguments[0] = 3;
+ assertEq(x, 3);
+ return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations
+}
+
+assertEq(assignArgumentsElementParamUse(1), 3);
+
+/********************
+ * STRICT ARGUMENTS *
+ ********************/
+
+function strictNoargs()
+{
+ "use strict";
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNoargs(), []), true);
+assertEq(arraysEqual(strictNoargs(1), [1]), true);
+assertEq(arraysEqual(strictNoargs(1, obj), [1, obj]), true);
+
+function strictArgs(a)
+{
+ "use strict";
+ return arguments;
+}
+
+assertEq(arraysEqual(strictArgs(), []), true);
+assertEq(arraysEqual(strictArgs(1), [1]), true);
+assertEq(arraysEqual(strictArgs(1, obj), [1, obj]), true);
+
+function strictAssign(a)
+{
+ "use strict";
+ a = 17;
+ return arguments;
+}
+
+assertEq(arraysEqual(strictAssign(), []), true);
+assertEq(arraysEqual(strictAssign(1), [1]), true);
+assertEq(arraysEqual(strictAssign(1, obj), [1, obj]), true);
+
+var upper;
+function strictAssignAfter(a)
+{
+ "use strict";
+ upper = arguments;
+ a = 42;
+ return upper;
+}
+
+assertEq(arraysEqual(strictAssignAfter(), []), true);
+assertEq(arraysEqual(strictAssignAfter(17), [17]), true);
+assertEq(arraysEqual(strictAssignAfter(obj), [obj]), true);
+
+function strictMaybeAssignOuterParam(p)
+{
+ "use strict";
+ function inner() { p = 17; }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictMaybeAssignOuterParam(), []), true);
+assertEq(arraysEqual(strictMaybeAssignOuterParam(42), [42]), true);
+assertEq(arraysEqual(strictMaybeAssignOuterParam(obj), [obj]), true);
+
+function strictAssignOuterParam(p)
+{
+ "use strict";
+ function inner() { p = 17; }
+ inner();
+ return arguments;
+}
+
+assertEq(arraysEqual(strictAssignOuterParam(), []), true);
+assertEq(arraysEqual(strictAssignOuterParam(17), [17]), true);
+assertEq(arraysEqual(strictAssignOuterParam(obj), [obj]), true);
+
+function strictAssignOuterParamPSYCH(p)
+{
+ "use strict";
+ function inner(p) { p = 17; }
+ inner();
+ return arguments;
+}
+
+assertEq(arraysEqual(strictAssignOuterParamPSYCH(), []), true);
+assertEq(arraysEqual(strictAssignOuterParamPSYCH(17), [17]), true);
+assertEq(arraysEqual(strictAssignOuterParamPSYCH(obj), [obj]), true);
+
+function strictEval(code, p)
+{
+ "use strict";
+ eval(code);
+ return arguments;
+}
+
+assertEq(arraysEqual(strictEval("1", 2), ["1", 2]), true);
+assertEq(arraysEqual(strictEval("arguments"), ["arguments"]), true);
+assertEq(arraysEqual(strictEval("p = 2"), ["p = 2"]), true);
+assertEq(arraysEqual(strictEval("p = 2", 17), ["p = 2", 17]), true);
+assertEq(arraysEqual(strictEval("arguments[0] = 17"), [17]), true);
+assertEq(arraysEqual(strictEval("arguments[0] = 17", 42), [17, 42]), true);
+
+function strictMaybeNestedEval(code, p)
+{
+ "use strict";
+ function inner() { eval(code); }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictMaybeNestedEval("1", 2), ["1", 2]), true);
+assertEq(arraysEqual(strictMaybeNestedEval("arguments"), ["arguments"]), true);
+assertEq(arraysEqual(strictMaybeNestedEval("p = 2"), ["p = 2"]), true);
+assertEq(arraysEqual(strictMaybeNestedEval("p = 2", 17), ["p = 2", 17]), true);
+
+function strictNestedEval(code, p)
+{
+ "use strict";
+ function inner() { eval(code); }
+ inner();
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedEval("1", 2), ["1", 2]), true);
+assertEq(arraysEqual(strictNestedEval("arguments"), ["arguments"]), true);
+assertEq(arraysEqual(strictNestedEval("p = 2"), ["p = 2"]), true);
+assertEq(arraysEqual(strictNestedEval("p = 2", 17), ["p = 2", 17]), true);
+assertEq(arraysEqual(strictNestedEval("arguments[0] = 17"), ["arguments[0] = 17"]), true);
+assertEq(arraysEqual(strictNestedEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true);
+
+function strictAssignArguments(a)
+{
+ "use strict";
+ arguments[0] = 42;
+ return a;
+}
+
+assertEq(strictAssignArguments(), undefined);
+assertEq(strictAssignArguments(obj), obj);
+assertEq(strictAssignArguments(17), 17);
+
+function strictAssignParameterGetElement(a)
+{
+ "use strict";
+ a = 17;
+ return arguments[0];
+}
+
+assertEq(strictAssignParameterGetElement(42), 42);
+
+function strictAssignArgSub(x, y)
+{
+ "use strict";
+ arguments[0] = 3;
+ return arguments[0];
+}
+
+assertEq(strictAssignArgSub(1), 3);
+
+function strictAssignArgSubParamUse(x, y)
+{
+ "use strict";
+ arguments[0] = 3;
+ assertEq(x, 1);
+ return arguments[0];
+}
+
+assertEq(strictAssignArgSubParamUse(1), 3);
+
+function strictAssignArgumentsElement(x, y)
+{
+ "use strict";
+ arguments[0] = 3;
+ return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations
+}
+
+assertEq(strictAssignArgumentsElement(1), 3);
+
+function strictAssignArgumentsElementParamUse(x, y)
+{
+ "use strict";
+ arguments[0] = 3;
+ assertEq(x, 1);
+ return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations
+}
+
+assertEq(strictAssignArgumentsElementParamUse(1), 3);
+
+function strictNestedAssignShadowVar(p)
+{
+ "use strict";
+ function inner()
+ {
+ var p = 12;
+ function innermost() { p = 1776; return 12; }
+ return innermost();
+ }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedAssignShadowVar(), []), true);
+assertEq(arraysEqual(strictNestedAssignShadowVar(99), [99]), true);
+assertEq(arraysEqual(strictNestedAssignShadowVar(""), [""]), true);
+assertEq(arraysEqual(strictNestedAssignShadowVar(obj), [obj]), true);
+
+function strictNestedAssignShadowCatch(p)
+{
+ "use strict";
+ function inner()
+ {
+ try
+ {
+ }
+ catch (p)
+ {
+ var f = function innermost() { p = 1776; return 12; };
+ f();
+ }
+ }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedAssignShadowCatch(), []), true);
+assertEq(arraysEqual(strictNestedAssignShadowCatch(99), [99]), true);
+assertEq(arraysEqual(strictNestedAssignShadowCatch(""), [""]), true);
+assertEq(arraysEqual(strictNestedAssignShadowCatch(obj), [obj]), true);
+
+function strictNestedAssignShadowCatchCall(p)
+{
+ "use strict";
+ function inner()
+ {
+ try
+ {
+ }
+ catch (p)
+ {
+ var f = function innermost() { p = 1776; return 12; };
+ f();
+ }
+ }
+ inner();
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedAssignShadowCatchCall(), []), true);
+assertEq(arraysEqual(strictNestedAssignShadowCatchCall(99), [99]), true);
+assertEq(arraysEqual(strictNestedAssignShadowCatchCall(""), [""]), true);
+assertEq(arraysEqual(strictNestedAssignShadowCatchCall(obj), [obj]), true);
+
+function strictNestedAssignShadowFunction(p)
+{
+ "use strict";
+ function inner()
+ {
+ function p() { }
+ p = 1776;
+ }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedAssignShadowFunction(), []), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunction(99), [99]), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunction(""), [""]), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunction(obj), [obj]), true);
+
+function strictNestedAssignShadowFunctionCall(p)
+{
+ "use strict";
+ function inner()
+ {
+ function p() { }
+ p = 1776;
+ }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(), []), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(99), [99]), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(""), [""]), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(obj), [obj]), true);
+
+function strictNestedShadowAndMaybeEval(code, p)
+{
+ "use strict";
+ function inner(p) { eval(code); }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedShadowAndMaybeEval("1", 2), ["1", 2]), true);
+assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments"), ["arguments"]), true);
+assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2"), ["p = 2"]), true);
+assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2", 17), ["p = 2", 17]), true);
+assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17"), ["arguments[0] = 17"]), true);
+assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true);
+
+function strictNestedShadowAndEval(code, p)
+{
+ "use strict";
+ function inner(p) { eval(code); }
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedShadowAndEval("1", 2), ["1", 2]), true);
+assertEq(arraysEqual(strictNestedShadowAndEval("arguments"), ["arguments"]), true);
+assertEq(arraysEqual(strictNestedShadowAndEval("p = 2"), ["p = 2"]), true);
+assertEq(arraysEqual(strictNestedShadowAndEval("p = 2", 17), ["p = 2", 17]), true);
+assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17"), ["arguments[0] = 17"]), true);
+assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true);
+
+function strictEvalContainsMutation(code)
+{
+ "use strict";
+ return eval(code);
+}
+
+assertEq(arraysEqual(strictEvalContainsMutation("code = 17; arguments"), ["code = 17; arguments"]), true);
+assertEq(arraysEqual(strictEvalContainsMutation("arguments[0] = 17; arguments"), [17]), true);
+assertEq(strictEvalContainsMutation("arguments[0] = 17; code"), "arguments[0] = 17; code");
+
+function strictNestedAssignShadowFunctionName(p)
+{
+ "use strict";
+ function inner()
+ {
+ function p() { p = 1776; }
+ p();
+ }
+ inner();
+ return arguments;
+}
+
+assertEq(arraysEqual(strictNestedAssignShadowFunctionName(), []), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunctionName(99), [99]), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunctionName(""), [""]), true);
+assertEq(arraysEqual(strictNestedAssignShadowFunctionName(obj), [obj]), true);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/Function/throw-type-error.js b/js/src/tests/non262/Function/throw-type-error.js
new file mode 100644
index 0000000000..68dd6e1d07
--- /dev/null
+++ b/js/src/tests/non262/Function/throw-type-error.js
@@ -0,0 +1,16 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+
+const ThrowTypeError = function(){
+ "use strict";
+ return Object.getOwnPropertyDescriptor(arguments, "callee").get;
+}();
+
+assertDeepEq(Object.getOwnPropertyDescriptor(ThrowTypeError, "length"), {
+ value: 0, writable: false, enumerable: false, configurable: false
+});
+
+assertEq(Object.isFrozen(ThrowTypeError), true);
+
+if (typeof reportCompare == "function")
+ reportCompare(true, true);