summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_5/extensions
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /js/src/tests/ecma_5/extensions
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/tests/ecma_5/extensions')
-rw-r--r--js/src/tests/ecma_5/extensions/15.4.4.11.js32
-rw-r--r--js/src/tests/ecma_5/extensions/15.9.4.2.js59
-rw-r--r--js/src/tests/ecma_5/extensions/8.12.5-01.js97
-rw-r--r--js/src/tests/ecma_5/extensions/Boolean-toSource.js17
-rw-r--r--js/src/tests/ecma_5/extensions/Number-toSource.js17
-rw-r--r--js/src/tests/ecma_5/extensions/String-methods-infinite-recursion.js36
-rw-r--r--js/src/tests/ecma_5/extensions/String-toSource.js14
-rw-r--r--js/src/tests/ecma_5/extensions/__proto__.js53
-rw-r--r--js/src/tests/ecma_5/extensions/arguments-property-access-in-function.js58
-rw-r--r--js/src/tests/ecma_5/extensions/array-inherited-__proto__.js32
-rw-r--r--js/src/tests/ecma_5/extensions/array-pop-proxy.js24
-rw-r--r--js/src/tests/ecma_5/extensions/array-toString-recursion.js46
-rw-r--r--js/src/tests/ecma_5/extensions/browser.js0
-rw-r--r--js/src/tests/ecma_5/extensions/bug472534.js30
-rw-r--r--js/src/tests/ecma_5/extensions/bug496985.js12
-rw-r--r--js/src/tests/ecma_5/extensions/bug566661.js6
-rw-r--r--js/src/tests/ecma_5/extensions/builtin-function-arguments-caller.js60
-rw-r--r--js/src/tests/ecma_5/extensions/cross-global-eval-is-indirect.js60
-rw-r--r--js/src/tests/ecma_5/extensions/cross-global-getPrototypeOf.js55
-rw-r--r--js/src/tests/ecma_5/extensions/destructuring-__proto__-shorthand-assignment-before-var.js49
-rw-r--r--js/src/tests/ecma_5/extensions/destructuring-__proto__-shorthand-assignment.js49
-rw-r--r--js/src/tests/ecma_5/extensions/destructuring-__proto__-target-assignment.js50
-rw-r--r--js/src/tests/ecma_5/extensions/destructuring-for-inof-__proto__.js85
-rw-r--r--js/src/tests/ecma_5/extensions/error-tostring-function.js45
-rw-r--r--js/src/tests/ecma_5/extensions/es5ish-defineGetter-defineSetter.js281
-rw-r--r--js/src/tests/ecma_5/extensions/eval-native-callback-is-indirect.js43
-rw-r--r--js/src/tests/ecma_5/extensions/extension-methods-reject-null-undefined-this.js112
-rw-r--r--js/src/tests/ecma_5/extensions/function-caller-skips-eval-frames.js34
-rw-r--r--js/src/tests/ecma_5/extensions/function-caller-strict-cross-global.js28
-rw-r--r--js/src/tests/ecma_5/extensions/function-definition-with.js56
-rw-r--r--js/src/tests/ecma_5/extensions/function-properties.js21
-rw-r--r--js/src/tests/ecma_5/extensions/getOwnPropertyNames-__proto__.js26
-rw-r--r--js/src/tests/ecma_5/extensions/inc-dec-functioncall.js90
-rw-r--r--js/src/tests/ecma_5/extensions/iterator-in-catch.js20
-rw-r--r--js/src/tests/ecma_5/extensions/misplaced-inconsistent-directive.js74
-rw-r--r--js/src/tests/ecma_5/extensions/nested-delete-name-in-evalcode.js85
-rw-r--r--js/src/tests/ecma_5/extensions/preventExtensions-cross-global.js49
-rw-r--r--js/src/tests/ecma_5/extensions/proxy-array-target-length-definition.js55
-rw-r--r--js/src/tests/ecma_5/extensions/proxy-enumeration.js4
-rw-r--r--js/src/tests/ecma_5/extensions/proxy-strict.js12
-rw-r--r--js/src/tests/ecma_5/extensions/regress-bug567606.js19
-rw-r--r--js/src/tests/ecma_5/extensions/regress-bug607284.js16
-rw-r--r--js/src/tests/ecma_5/extensions/regress-bug629723.js16
-rw-r--r--js/src/tests/ecma_5/extensions/reviver-mutates-holder-array-ccw.js39
-rw-r--r--js/src/tests/ecma_5/extensions/reviver-mutates-holder-array-nonnative.js46
-rw-r--r--js/src/tests/ecma_5/extensions/reviver-mutates-holder-array.js39
-rw-r--r--js/src/tests/ecma_5/extensions/reviver-mutates-holder-object-ccw.js56
-rw-r--r--js/src/tests/ecma_5/extensions/reviver-mutates-holder-object-nonnative.js60
-rw-r--r--js/src/tests/ecma_5/extensions/reviver-mutates-holder-object.js56
-rw-r--r--js/src/tests/ecma_5/extensions/shell.js0
-rw-r--r--js/src/tests/ecma_5/extensions/strict-function-statements.js94
-rw-r--r--js/src/tests/ecma_5/extensions/strict-function-toSource.js17
-rw-r--r--js/src/tests/ecma_5/extensions/strict-option-redeclared-parameter.js30
-rw-r--r--js/src/tests/ecma_5/extensions/string-literal-getter-setter-decompilation.js34
-rw-r--r--js/src/tests/ecma_5/extensions/toLocaleString-infinite-recursion.js31
-rw-r--r--js/src/tests/ecma_5/extensions/toSource-infinite-recursion.js34
-rw-r--r--js/src/tests/ecma_5/extensions/watch-array-length.js41
-rw-r--r--js/src/tests/ecma_5/extensions/watch-inherited-property.js38
-rw-r--r--js/src/tests/ecma_5/extensions/watch-replaced-setter.js46
-rw-r--r--js/src/tests/ecma_5/extensions/watch-setter-become-setter.js44
-rw-r--r--js/src/tests/ecma_5/extensions/watch-value-prop-becoming-setter.js43
-rw-r--r--js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js56
62 files changed, 2831 insertions, 0 deletions
diff --git a/js/src/tests/ecma_5/extensions/15.4.4.11.js b/js/src/tests/ecma_5/extensions/15.4.4.11.js
new file mode 100644
index 000000000..a4c38faa7
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/15.4.4.11.js
@@ -0,0 +1,32 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function arr() {
+ return Object.defineProperty([20, 10, 30], 0, {writable: false});
+}
+
+assertEq(testLenientAndStrict('var a = arr(); a.sort()',
+ raisesException(TypeError),
+ raisesException(TypeError)),
+ true);
+
+function obj() {
+ var o = {0: 20, 1: 10, 2: 30, length: 3};
+ Object.defineProperty(o, 0, {writable: false});
+ return o;
+}
+
+assertEq(testLenientAndStrict('var o = obj(); Array.prototype.sort.call(o)',
+ raisesException(TypeError),
+ raisesException(TypeError)),
+ true);
+
+// The behavior of sort is implementation-defined if the object being
+// sorted is sparse, so I'm not sure how to test its behavior on
+// non-configurable properties.
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/15.9.4.2.js b/js/src/tests/ecma_5/extensions/15.9.4.2.js
new file mode 100644
index 000000000..c517f8be8
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/15.9.4.2.js
@@ -0,0 +1,59 @@
+/* -*- 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 = 682754;
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function iso(d)
+{
+ return new Date(d).toISOString();
+}
+
+function check(s, millis){
+ description = "Date.parse('"+s+"') == '"+iso(millis)+"'";
+ expected = millis;
+ actual = Date.parse(s);
+ reportCompare(expected, actual, description);
+}
+
+function checkInvalid(s)
+{
+ description = "Date.parse('"+s+"') produces invalid date";
+ expected = NaN;
+ actual = Date.parse(s);
+ reportCompare(expected, actual, description);
+}
+
+function dd(year, month, day, hour, minute, second, millis){
+ return Date.UTC(year, month-1, day, hour, minute, second, millis);
+}
+
+function TZAtDate(d){
+ return d.getTimezoneOffset() * 60000;
+}
+
+function TZInMonth(month){
+ return TZAtDate(new Date(dd(2009,month,1,0,0,0,0)));
+}
+
+function test()
+{
+ enterFunc ('test');
+ printBugNumber(BUGNUMBER);
+
+ JanTZ = TZInMonth(1);
+ JulTZ = TZInMonth(7);
+ CurrTZ = TZAtDate(new Date());
+
+ // Allow non-standard "-0700" as timezone, not just "-07:00"
+ check("2009-07-23T00:53:21.001-0700", dd(2009,7,23,7,53,21,1));
+
+ exitFunc ('test');
+}
diff --git a/js/src/tests/ecma_5/extensions/8.12.5-01.js b/js/src/tests/ecma_5/extensions/8.12.5-01.js
new file mode 100644
index 000000000..c6f1c18ee
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/8.12.5-01.js
@@ -0,0 +1,97 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jason Orendorff
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 523846;
+var summary =
+ "Assignments to a property that has a getter but not a setter should not " +
+ "throw a TypeError per ES5 (at least not until strict mode is supported)";
+var actual = "Early failure";
+var expect = "No errors";
+
+
+printBugNumber(BUGNUMBER);
+printStatus(summary);
+
+var o = { get p() { return "a"; } };
+
+function test1()
+{
+ o.p = "b"; // strict-mode violation here
+ assertEq(o.p, "a");
+}
+
+function test2()
+{
+ function T() {}
+ T.prototype = o;
+ y = new T();
+ y.p = "b"; // strict-mode violation here
+ assertEq(y.p, "a");
+}
+
+
+var errors = [];
+try
+{
+ try
+ {
+ test1();
+ }
+ catch (e)
+ {
+ errors.push(e);
+ }
+
+ try
+ {
+ test2();
+ }
+ catch (e)
+ {
+ errors.push(e);
+ }
+
+ options("strict");
+ options("werror");
+ try
+ {
+ test1();
+ errors.push("strict+werror didn't make test1 fail");
+ }
+ catch (e)
+ {
+ if (!(e instanceof TypeError))
+ errors.push("test1 with strict+werror failed without a TypeError: " + e);
+ }
+
+ try
+ {
+ test2();
+ errors.push("strict+werror didn't make test2 fail");
+ }
+ catch (e)
+ {
+ if (!(e instanceof TypeError))
+ errors.push("test2 with strict+werror failed without a TypeError: " + e);
+ }
+
+ options("strict");
+ options("werror");
+}
+catch (e)
+{
+ errors.push("Unexpected error: " + e);
+}
+finally
+{
+ actual = errors.length > 0 ? errors.join(", ") : "No errors";
+}
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/ecma_5/extensions/Boolean-toSource.js b/js/src/tests/ecma_5/extensions/Boolean-toSource.js
new file mode 100644
index 000000000..8d135a9fd
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/Boolean-toSource.js
@@ -0,0 +1,17 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+assertEq(raisesException(TypeError)('Boolean.prototype.toSource.call(42)'), true);
+assertEq(raisesException(TypeError)('Boolean.prototype.toSource.call("")'), true);
+assertEq(raisesException(TypeError)('Boolean.prototype.toSource.call({})'), true);
+assertEq(raisesException(TypeError)('Boolean.prototype.toSource.call(null)'), true);
+assertEq(raisesException(TypeError)('Boolean.prototype.toSource.call([])'), true);
+assertEq(raisesException(TypeError)('Boolean.prototype.toSource.call(undefined)'), true);
+assertEq(raisesException(TypeError)('Boolean.prototype.toSource.call(new String())'), true);
+
+assertEq(completesNormally('Boolean.prototype.toSource.call(true)'), true);
+assertEq(completesNormally('Boolean.prototype.toSource.call(new Boolean(true))'), true);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/Number-toSource.js b/js/src/tests/ecma_5/extensions/Number-toSource.js
new file mode 100644
index 000000000..c2e306f53
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/Number-toSource.js
@@ -0,0 +1,17 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+assertEq(raisesException(TypeError)('Number.prototype.toSource.call("")'), true);
+assertEq(raisesException(TypeError)('Number.prototype.toSource.call(true)'), true);
+assertEq(raisesException(TypeError)('Number.prototype.toSource.call({})'), true);
+assertEq(raisesException(TypeError)('Number.prototype.toSource.call(null)'), true);
+assertEq(raisesException(TypeError)('Number.prototype.toSource.call([])'), true);
+assertEq(raisesException(TypeError)('Number.prototype.toSource.call(undefined)'), true);
+assertEq(raisesException(TypeError)('Number.prototype.toSource.call(new Boolean(true))'), true);
+
+assertEq(completesNormally('Number.prototype.toSource.call(42)'), true);
+assertEq(completesNormally('Number.prototype.toSource.call(new Number(42))'), true);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/String-methods-infinite-recursion.js b/js/src/tests/ecma_5/extensions/String-methods-infinite-recursion.js
new file mode 100644
index 000000000..a5972d8c3
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/String-methods-infinite-recursion.js
@@ -0,0 +1,36 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 657585;
+var summary =
+ 'Guard against infinite recursion when converting |this| to string for the ' +
+ 'String.prototype.* methods';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ var obj = {};
+ obj.toString = String.prototype.charAt;
+ "" + obj;
+ throw new Error("should have thrown");
+}
+catch (e)
+{
+ assertEq(e instanceof InternalError, true,
+ "should have thrown InternalError for over-recursion, got: " + e);
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/String-toSource.js b/js/src/tests/ecma_5/extensions/String-toSource.js
new file mode 100644
index 000000000..0614e574c
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/String-toSource.js
@@ -0,0 +1,14 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+assertEq(raisesException(TypeError)('String.prototype.toSource.call(42)'), true);
+assertEq(raisesException(TypeError)('String.prototype.toSource.call(true)'), true);
+assertEq(raisesException(TypeError)('String.prototype.toSource.call({})'), true);
+assertEq(raisesException(TypeError)('String.prototype.toSource.call(null)'), true);
+assertEq(raisesException(TypeError)('String.prototype.toSource.call([])'), true);
+assertEq(raisesException(TypeError)('String.prototype.toSource.call(undefined)'), true);
+assertEq(completesNormally('String.prototype.toSource.call("")'), true);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/__proto__.js b/js/src/tests/ecma_5/extensions/__proto__.js
new file mode 100644
index 000000000..aa6d60876
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/__proto__.js
@@ -0,0 +1,53 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = '__proto__.js';
+var BUGNUMBER = 770344;
+var summary = "__proto__ as accessor";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var protoDesc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
+assertEq(protoDesc !== null, true);
+assertEq(typeof protoDesc, "object");
+assertEq(protoDesc.hasOwnProperty("get"), true);
+assertEq(protoDesc.hasOwnProperty("set"), true);
+assertEq(protoDesc.hasOwnProperty("enumerable"), true);
+assertEq(protoDesc.hasOwnProperty("configurable"), true);
+assertEq(protoDesc.hasOwnProperty("value"), false);
+assertEq(protoDesc.hasOwnProperty("writable"), false);
+
+assertEq(protoDesc.configurable, true);
+assertEq(protoDesc.enumerable, false);
+assertEq(typeof protoDesc.get, "function", protoDesc.get + "");
+assertEq(typeof protoDesc.set, "function", protoDesc.set + "");
+
+assertEq(delete Object.prototype.__proto__, true);
+assertEq(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"),
+ undefined);
+
+var obj = {};
+obj.__proto__ = 5;
+assertEq(Object.getPrototypeOf(obj), Object.prototype);
+assertEq(obj.hasOwnProperty("__proto__"), true);
+
+var desc = Object.getOwnPropertyDescriptor(obj, "__proto__");
+assertEq(desc !== null, true);
+assertEq(typeof desc, "object");
+assertEq(desc.value, 5);
+assertEq(desc.writable, true);
+assertEq(desc.enumerable, true);
+assertEq(desc.configurable, true);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/arguments-property-access-in-function.js b/js/src/tests/ecma_5/extensions/arguments-property-access-in-function.js
new file mode 100644
index 000000000..f8c7e97f1
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/arguments-property-access-in-function.js
@@ -0,0 +1,58 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 721322;
+var summary =
+ 'f.arguments must trigger an arguments object in non-strict mode functions';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var obj =
+ {
+ test: function()
+ {
+ var args = obj.test.arguments;
+ assertEq(args !== null, true);
+ assertEq(args[0], 5);
+ assertEq(args[1], undefined);
+ assertEq(args.length, 2);
+ }
+ };
+obj.test(5, undefined);
+
+var sobj =
+ {
+ test: function()
+ {
+ "use strict";
+
+ try
+ {
+ var args = sobj.test.arguments;
+ throw new Error("access to arguments property of strict mode " +
+ "function didn't throw");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "should have thrown TypeError, instead got: " + e);
+ }
+ }
+ };
+sobj.test(5, undefined);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/array-inherited-__proto__.js b/js/src/tests/ecma_5/extensions/array-inherited-__proto__.js
new file mode 100644
index 000000000..0409d4757
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/array-inherited-__proto__.js
@@ -0,0 +1,32 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'array-inherited-__proto__.js';
+var BUGNUMBER = 769041;
+var summary =
+ "The [[Prototype]] of an object whose prototype chain contains an array " +
+ "isn't that array's [[Prototype]]";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var arr = [];
+assertEq(Array.isArray(arr), true);
+var objWithArrPrototype = Object.create(arr);
+assertEq(!Array.isArray(objWithArrPrototype), true);
+assertEq(objWithArrPrototype.__proto__, arr);
+var objWithArrGrandPrototype = Object.create(objWithArrPrototype);
+assertEq(!Array.isArray(objWithArrGrandPrototype), true);
+assertEq(objWithArrGrandPrototype.__proto__, objWithArrPrototype);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/array-pop-proxy.js b/js/src/tests/ecma_5/extensions/array-pop-proxy.js
new file mode 100644
index 000000000..15c230977
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/array-pop-proxy.js
@@ -0,0 +1,24 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'array-pop-proxy.js';
+var BUGNUMBER = 858381;
+var summary = "Behavior of [].pop on proxies";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var p = new Proxy([0, 1, 2], {});
+Array.prototype.pop.call(p);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/array-toString-recursion.js b/js/src/tests/ecma_5/extensions/array-toString-recursion.js
new file mode 100644
index 000000000..aa5d856c3
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/array-toString-recursion.js
@@ -0,0 +1,46 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 635389;
+var summary = 'Infinite recursion via [].{toString,toLocaleString,join}';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ var x = [];
+ x.join = Array.prototype.toString;
+ "" + x;
+ throw new Error("should have thrown");
+}
+catch (e)
+{
+ assertEq(e instanceof InternalError, true,
+ "should have thrown for over-recursion");
+}
+
+try
+{
+ var x = { toString: Array.prototype.toString, join: Array.prototype.toString };
+ "" + x;
+ throw new Error("should have thrown");
+}
+catch (e)
+{
+ assertEq(e instanceof InternalError, true,
+ "should have thrown for over-recursion");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/browser.js b/js/src/tests/ecma_5/extensions/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/browser.js
diff --git a/js/src/tests/ecma_5/extensions/bug472534.js b/js/src/tests/ecma_5/extensions/bug472534.js
new file mode 100644
index 000000000..0c7d5f3ec
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/bug472534.js
@@ -0,0 +1,30 @@
+function monthNames () {
+ return [
+ /jan(uar(y)?)?/, 0,
+ /feb(ruar(y)?)?/, 1,
+ /m\u00e4r|mar|m\u00e4rz|maerz|march/, 2,
+ /apr(il)?/, 3,
+ /ma(i|y)/, 4,
+ /jun(i|o|e)?/, 5,
+ /jul(i|y)?/, 6,
+ /aug(ust)?/, 7,
+ /sep((t)?(ember))?/, 8,
+ /o(c|k)t(ober)?/, 9,
+ /nov(ember)?/, 10,
+ /de(c|z)(ember)?/, 11
+ ];
+};
+
+var actual = '';
+var expected = '(jan(uar(y)?)?)|(feb(ruar(y)?)?)|(m\\u00e4r|mar|m\\u00e4rz|maerz|march)|(apr(il)?)|(ma(i|y))|(jun(i|o|e)?)|(jul(i|y)?)|(aug(ust)?)|(sep((t)?(ember))?)|(o(c|k)t(ober)?)|(nov(ember)?)|(de(c|z)(ember)?)';
+var mn = monthNames();
+for (var i = 0; i < mn.length; ++i) {
+ if (actual)
+ actual += '|';
+ actual += '(' + mn[i++].source + ')';
+}
+
+assertEq(actual, expected);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/bug496985.js b/js/src/tests/ecma_5/extensions/bug496985.js
new file mode 100644
index 000000000..be1dd19cf
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/bug496985.js
@@ -0,0 +1,12 @@
+var a = function() {
+ return function ({x: arguments}) {
+ return arguments;
+ }
+}
+var b = eval(uneval(a));
+
+assertEq(a()({x: 1}), 1);
+assertEq(b()({x: 1}), 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/bug566661.js b/js/src/tests/ecma_5/extensions/bug566661.js
new file mode 100644
index 000000000..0e22d8dbd
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/bug566661.js
@@ -0,0 +1,6 @@
+var f = function (q) { return q['\xC7']; }
+var d = eval(uneval(f));
+assertEq(d({'\xC7': 'good'}), 'good');
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/builtin-function-arguments-caller.js b/js/src/tests/ecma_5/extensions/builtin-function-arguments-caller.js
new file mode 100644
index 000000000..2acf5f452
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/builtin-function-arguments-caller.js
@@ -0,0 +1,60 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'builtin-function-arguments-caller.js';
+var BUGNUMBER = 929642;
+var summary =
+ "Built-in functions defined in ECMAScript pick up arguments/caller " +
+ "properties from Function.prototype";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function expectNoProperty(obj, prop)
+{
+ var desc = Object.getOwnPropertyDescriptor(obj, prop);
+ assertEq(desc, undefined,
+ "should be no '" + prop + "' property on " + obj);
+}
+
+// Test a builtin that's native.
+expectNoProperty(Object, "arguments");
+expectNoProperty(Object, "caller");
+
+// Also test a builtin that's self-hosted.
+expectNoProperty(Array.prototype.indexOf, "arguments");
+expectNoProperty(Array.prototype.indexOf, "caller");
+
+// Test the Function construct for good measure, because it's so intricately
+// invovled in bootstrapping.
+expectNoProperty(Function, "arguments");
+expectNoProperty(Function, "caller");
+
+var argsDesc = Object.getOwnPropertyDescriptor(Function.prototype, "arguments");
+var callerDesc = Object.getOwnPropertyDescriptor(Function.prototype, "caller");
+
+var argsGet = argsDesc.get, argsSet = argsDesc.set;
+
+expectNoProperty(argsGet, "arguments");
+expectNoProperty(argsGet, "caller");
+expectNoProperty(argsSet, "arguments");
+expectNoProperty(argsSet, "caller");
+
+var callerGet = callerDesc.get, callerSet = callerDesc.set;
+
+expectNoProperty(callerGet, "arguments");
+expectNoProperty(callerGet, "caller");
+expectNoProperty(callerSet, "arguments");
+expectNoProperty(callerSet, "caller");
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/cross-global-eval-is-indirect.js b/js/src/tests/ecma_5/extensions/cross-global-eval-is-indirect.js
new file mode 100644
index 000000000..6cd35846b
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/cross-global-eval-is-indirect.js
@@ -0,0 +1,60 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs newGlobal()
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 608473;
+var summary =
+ '|var eval = otherWindow.eval; eval(...)| should behave like indirectly ' +
+ 'calling that eval from a script in that other window';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var originalEval = eval;
+var res;
+
+function f()
+{
+ return [this, eval("this")];
+}
+
+var otherGlobalSameCompartment = newGlobal("same-compartment");
+
+eval = otherGlobalSameCompartment.eval;
+res = new f();
+assertEq(res[0] !== res[1], true);
+assertEq(res[0] !== this, true);
+assertEq(res[0] instanceof f, true);
+assertEq(res[1], otherGlobalSameCompartment);
+
+res = f();
+assertEq(res[0] !== res[1], true);
+assertEq(res[0], this);
+assertEq(res[1], otherGlobalSameCompartment);
+
+var otherGlobalDifferentCompartment = newGlobal();
+
+eval = otherGlobalDifferentCompartment.eval;
+res = new f();
+assertEq(res[0] !== res[1], true);
+assertEq(res[0] !== this, true);
+assertEq(res[0] instanceof f, true);
+assertEq(res[1], otherGlobalDifferentCompartment);
+
+res = f();
+assertEq(res[0] !== res[1], true);
+assertEq(res[0], this);
+assertEq(res[1], otherGlobalDifferentCompartment);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/cross-global-getPrototypeOf.js b/js/src/tests/ecma_5/extensions/cross-global-getPrototypeOf.js
new file mode 100644
index 000000000..1480a8ea1
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/cross-global-getPrototypeOf.js
@@ -0,0 +1,55 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs newGlobal()
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 770344;
+var summary = "Object.getPrototypeOf behavior across compartments";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var other = newGlobal();
+
+var getProto = Object.getPrototypeOf;
+var otherGetProto = other.Object.getPrototypeOf;
+
+var proto = {};
+var obj = Object.create(proto);
+assertEq(getProto(obj), proto);
+assertEq(otherGetProto(obj), proto);
+
+other.proto = proto;
+var otherObj = other.evaluate("Object.create(proto)");
+assertEq(getProto(otherObj), proto);
+assertEq(otherGetProto(otherObj), proto);
+
+var p = other.evaluate("({})");
+var objOtherProto = Object.create(p);
+assertEq(getProto(objOtherProto), p);
+assertEq(otherGetProto(objOtherProto), p);
+
+other.evaluate("var otherProto = { otherProto: 1 }; " +
+ "var otherObj = Object.create(otherProto);");
+assertEq(getProto(other.otherObj), other.otherProto);
+assertEq(otherGetProto(other.otherObj), other.otherProto);
+
+other.evaluate("var newOtherProto = { newOtherProto: 1 }; " +
+ "otherObj.__proto__ = newOtherProto;");
+assertEq(otherGetProto(other.otherObj), other.newOtherProto);
+
+// TODO This assertion fails due to bug 764307
+//assertEq(getProto(other.otherObj), other.newOtherProto);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/destructuring-__proto__-shorthand-assignment-before-var.js b/js/src/tests/ecma_5/extensions/destructuring-__proto__-shorthand-assignment-before-var.js
new file mode 100644
index 000000000..da0da55c8
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/destructuring-__proto__-shorthand-assignment-before-var.js
@@ -0,0 +1,49 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'destructuring-__proto__-shorthand-assignment-before-var.js';
+var BUGNUMBER = 963641;
+var summary = "{ __proto__ } should work as a destructuring assignment pattern";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function objectWithProtoProperty(v)
+{
+ var obj = {};
+ return Object.defineProperty(obj, "__proto__",
+ {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: v
+ });
+}
+
+({ __proto__ } = objectWithProtoProperty(17));
+assertEq(__proto__, 17);
+
+var { __proto__ } = objectWithProtoProperty(42);
+assertEq(__proto__, 42);
+
+function nested()
+{
+ ({ __proto__ } = objectWithProtoProperty(undefined));
+ assertEq(__proto__, undefined);
+
+ var { __proto__ } = objectWithProtoProperty("fnord");
+ assertEq(__proto__, "fnord");
+}
+nested();
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/destructuring-__proto__-shorthand-assignment.js b/js/src/tests/ecma_5/extensions/destructuring-__proto__-shorthand-assignment.js
new file mode 100644
index 000000000..0ab26465f
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/destructuring-__proto__-shorthand-assignment.js
@@ -0,0 +1,49 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'destructuring-__proto__-shorthand-assignment.js';
+var BUGNUMBER = 963641;
+var summary = "{ __proto__ } should work as a destructuring assignment pattern";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function objectWithProtoProperty(v)
+{
+ var obj = {};
+ return Object.defineProperty(obj, "__proto__",
+ {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: v
+ });
+}
+
+var { __proto__ } = objectWithProtoProperty(42);
+assertEq(__proto__, 42);
+
+({ __proto__ } = objectWithProtoProperty(17));
+assertEq(__proto__, 17);
+
+function nested()
+{
+ var { __proto__ } = objectWithProtoProperty("fnord");
+ assertEq(__proto__, "fnord");
+
+ ({ __proto__ } = objectWithProtoProperty(undefined));
+ assertEq(__proto__, undefined);
+}
+nested();
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/destructuring-__proto__-target-assignment.js b/js/src/tests/ecma_5/extensions/destructuring-__proto__-target-assignment.js
new file mode 100644
index 000000000..9e8ec7217
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/destructuring-__proto__-target-assignment.js
@@ -0,0 +1,50 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'destructuring-__proto__-target--assignment.js';
+var BUGNUMBER = 963641;
+var summary =
+ "{ __proto__: target } should work as a destructuring assignment pattern";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function objectWithProtoProperty(v)
+{
+ var obj = {};
+ return Object.defineProperty(obj, "__proto__",
+ {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: v
+ });
+}
+
+var { __proto__: target } = objectWithProtoProperty(null);
+assertEq(target, null);
+
+({ __proto__: target } = objectWithProtoProperty("aacchhorrt"));
+assertEq(target, "aacchhorrt");
+
+function nested()
+{
+ var { __proto__: target } = objectWithProtoProperty(3.141592654);
+ assertEq(target, 3.141592654);
+
+ ({ __proto__: target } = objectWithProtoProperty(-0));
+ assertEq(target, -0);
+}
+nested();
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/destructuring-for-inof-__proto__.js b/js/src/tests/ecma_5/extensions/destructuring-for-inof-__proto__.js
new file mode 100644
index 000000000..283dee314
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/destructuring-for-inof-__proto__.js
@@ -0,0 +1,85 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'destructuring-for-inof-__proto__.js';
+var BUGNUMBER = 963641;
+var summary =
+ "__proto__ should work in destructuring patterns as the targets of " +
+ "for-in/for-of loops";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function objectWithProtoProperty(v)
+{
+ var obj = {};
+ return Object.defineProperty(obj, "__proto__",
+ {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: v
+ });
+}
+
+function* objectWithProtoGenerator(v)
+{
+ yield objectWithProtoProperty(v);
+}
+
+function* identityGenerator(v)
+{
+ yield v;
+}
+
+for (var { __proto__: target } of objectWithProtoGenerator(null))
+ assertEq(target, null);
+
+for ({ __proto__: target } of objectWithProtoGenerator("aacchhorrt"))
+ assertEq(target, "aacchhorrt");
+
+for ({ __proto__: target } of identityGenerator(42))
+ assertEq(target, Number.prototype);
+
+for (var { __proto__: target } in { prop: "kneedle" })
+ assertEq(target, String.prototype);
+
+for ({ __proto__: target } in { prop: "snork" })
+ assertEq(target, String.prototype);
+
+for ({ __proto__: target } in { prop: "ohia" })
+ assertEq(target, String.prototype);
+
+function nested()
+{
+ for (var { __proto__: target } of objectWithProtoGenerator(null))
+ assertEq(target, null);
+
+ for ({ __proto__: target } of objectWithProtoGenerator("aacchhorrt"))
+ assertEq(target, "aacchhorrt");
+
+ for ({ __proto__: target } of identityGenerator(42))
+ assertEq(target, Number.prototype);
+
+ for (var { __proto__: target } in { prop: "kneedle" })
+ assertEq(target, String.prototype);
+
+ for ({ __proto__: target } in { prop: "snork" })
+ assertEq(target, String.prototype);
+
+ for ({ __proto__: target } in { prop: "ohia" })
+ assertEq(target, String.prototype);
+}
+nested();
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/error-tostring-function.js b/js/src/tests/ecma_5/extensions/error-tostring-function.js
new file mode 100644
index 000000000..5e92f1075
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/error-tostring-function.js
@@ -0,0 +1,45 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 894653;
+var summary =
+ "Error.prototype.toString called on function objects should work as on any " +
+ "object";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function ErrorToString(v)
+{
+ return Error.prototype.toString.call(v);
+}
+
+// The name property of function objects isn't standardized, so this must be an
+// extension-land test.
+
+assertEq(ErrorToString(function f(){}), "f");
+assertEq(ErrorToString(function g(){}), "g");
+assertEq(ErrorToString(function(){}), "");
+
+var fn1 = function() {};
+fn1.message = "ohai";
+assertEq(ErrorToString(fn1), "ohai");
+
+var fn2 = function blerch() {};
+fn2.message = "fnord";
+assertEq(ErrorToString(fn2), "blerch: fnord");
+
+var fn3 = function() {};
+fn3.message = "";
+assertEq(ErrorToString(fn3), "");
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete!");
diff --git a/js/src/tests/ecma_5/extensions/es5ish-defineGetter-defineSetter.js b/js/src/tests/ecma_5/extensions/es5ish-defineGetter-defineSetter.js
new file mode 100644
index 000000000..681a157a8
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/es5ish-defineGetter-defineSetter.js
@@ -0,0 +1,281 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 715821;
+var summary = "Implement __define[GS]etter__ using Object.defineProperty";
+
+print(BUGNUMBER + ": " + summary);
+
+/*************
+ * UTILITIES *
+ *************/
+
+function s(desc)
+{
+ if (typeof desc === "undefined")
+ return "<undefined>";
+ assertEq(typeof desc, "object");
+ assertEq(desc !== null, true);
+
+ var str = "<enumerable: <" + desc.enumerable + ">, " +
+ " configurable: <" + desc.configurable + ">,";
+
+ if (desc.hasOwnProperty("value"))
+ {
+ return str +
+ " value: <" + desc.value + ">," +
+ " writable: <" + desc.writable + ">>";
+ }
+
+ return str +
+ " get: <" + desc.get + ">," +
+ " set: <" + desc.set + ">>";
+}
+
+function checkField(field, desc, expected)
+{
+ var present = desc.hasOwnProperty(field);
+ assertEq(present, expected.hasOwnProperty(field),
+ field + " presence mismatch (got " + s(desc) + ", expected " + s(expected) + ")");
+ if (present)
+ {
+ assertEq(desc[field], expected[field],
+ field + " value mismatch (got " + s(desc) + ", expected " + s(expected) + ")");
+ }
+}
+
+function check(obj, prop, expected)
+{
+ var desc = Object.getOwnPropertyDescriptor(obj, prop);
+ assertEq(typeof desc, typeof expected,
+ "type mismatch (got " + s(desc) + ", expected " + s(expected) + ")");
+
+ assertEq(desc.hasOwnProperty("get"), desc.hasOwnProperty("set"),
+ "bad descriptor: " + s(desc));
+ assertEq(desc.hasOwnProperty("value"), desc.hasOwnProperty("writable"),
+ "bad descriptor: " + s(desc));
+
+ assertEq(desc.hasOwnProperty("get"), !desc.hasOwnProperty("value"),
+ "bad descriptor: " + s(desc));
+
+ checkField("get", desc, expected);
+ checkField("set", desc, expected);
+ checkField("value", desc, expected);
+ checkField("writable", desc, expected);
+ checkField("enumerable", desc, expected);
+ checkField("configurable", desc, expected);
+}
+
+function expectTypeError(f)
+{
+ try
+ {
+ f();
+ throw new Error("no error thrown");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "wrong error thrown: got " + e + ", not a TypeError");
+ }
+}
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// Adding a new getter, overwriting an existing one
+
+function g1() { }
+var gobj = {};
+gobj.__defineGetter__("foo", g1);
+check(gobj, "foo", { get: g1, set: undefined, enumerable: true, configurable: true });
+
+function g2() { }
+gobj.__defineGetter__("foo", g2);
+check(gobj, "foo", { get: g2, set: undefined, enumerable: true, configurable: true });
+
+/******************************************************************************/
+
+// Adding a new setter, overwriting an existing one
+
+function s1() { }
+var sobj = {};
+sobj.__defineSetter__("bar", s1);
+check(sobj, "bar", { get: undefined, set: s1, enumerable: true, configurable: true });
+
+function s2() { }
+sobj.__defineSetter__("bar", s2);
+check(sobj, "bar", { get: undefined, set: s2, enumerable: true, configurable: true });
+
+/******************************************************************************/
+
+// Adding a new getter, then adding a setter
+// Changing an existing accessor's enumerability, then "null"-changing the accessor
+// Changing an accessor's configurability, then "null"-changing and real-changing the accessor
+
+function g3() { }
+var gsobj = {};
+gsobj.__defineGetter__("baz", g3);
+check(gsobj, "baz", { get: g3, set: undefined, enumerable: true, configurable: true });
+
+function s3() { }
+gsobj.__defineSetter__("baz", s3);
+check(gsobj, "baz", { get: g3, set: s3, enumerable: true, configurable: true });
+
+Object.defineProperty(gsobj, "baz", { enumerable: false });
+check(gsobj, "baz", { get: g3, set: s3, enumerable: false, configurable: true });
+
+gsobj.__defineGetter__("baz", g3);
+check(gsobj, "baz", { get: g3, set: s3, enumerable: true, configurable: true });
+
+Object.defineProperty(gsobj, "baz", { enumerable: false });
+check(gsobj, "baz", { get: g3, set: s3, enumerable: false, configurable: true });
+
+gsobj.__defineSetter__("baz", s3);
+check(gsobj, "baz", { get: g3, set: s3, enumerable: true, configurable: true });
+
+Object.defineProperty(gsobj, "baz", { configurable: false });
+expectTypeError(function() { gsobj.__defineSetter__("baz", s2); });
+expectTypeError(function() { gsobj.__defineSetter__("baz", s3); });
+check(gsobj, "baz", { get: g3, set: s3, enumerable: true, configurable: false });
+
+/******************************************************************************/
+
+// Adding a new setter, then adding a getter
+// Changing an existing accessor's enumerability, then "null"-changing the accessor
+// Changing an accessor's configurability, then "null"-changing and real-changing the accessor
+
+function s4() { }
+var sgobj = {};
+sgobj.__defineSetter__("baz", s4);
+check(sgobj, "baz", { get: undefined, set: s4, enumerable: true, configurable: true });
+
+function g4() { }
+sgobj.__defineGetter__("baz", g4);
+check(sgobj, "baz", { get: g4, set: s4, enumerable: true, configurable: true });
+
+Object.defineProperty(sgobj, "baz", { enumerable: false });
+check(sgobj, "baz", { get: g4, set: s4, enumerable: false, configurable: true });
+
+sgobj.__defineSetter__("baz", s4);
+check(sgobj, "baz", { get: g4, set: s4, enumerable: true, configurable: true });
+
+Object.defineProperty(sgobj, "baz", { enumerable: false });
+check(sgobj, "baz", { get: g4, set: s4, enumerable: false, configurable: true });
+
+sgobj.__defineSetter__("baz", s4);
+check(sgobj, "baz", { get: g4, set: s4, enumerable: true, configurable: true });
+
+Object.defineProperty(sgobj, "baz", { configurable: false });
+expectTypeError(function() { sgobj.__defineGetter__("baz", g3); });
+expectTypeError(function() { sgobj.__defineSetter__("baz", s4); });
+check(sgobj, "baz", { get: g4, set: s4, enumerable: true, configurable: false });
+
+/******************************************************************************/
+
+// Adding a getter over a writable data property
+
+function g5() { }
+var gover = { quux: 17 };
+check(gover, "quux", { value: 17, writable: true, enumerable: true, configurable: true });
+
+gover.__defineGetter__("quux", g5);
+check(gover, "quux", { get: g5, set: undefined, enumerable: true, configurable: true });
+
+/******************************************************************************/
+
+// Adding a setter over a writable data property
+
+function s5() { }
+var sover = { quux: 17 };
+check(sover, "quux", { value: 17, writable: true, enumerable: true, configurable: true });
+
+sover.__defineSetter__("quux", s5);
+check(sover, "quux", { get: undefined, set: s5, enumerable: true, configurable: true });
+
+/******************************************************************************/
+
+// Adding a getter over a non-writable data property
+
+function g6() { }
+var gnover = { eit: 17 };
+check(gnover, "eit", { value: 17, writable: true, enumerable: true, configurable: true });
+Object.defineProperty(gnover, "eit", { writable: false });
+check(gnover, "eit", { value: 17, writable: false, enumerable: true, configurable: true });
+
+gnover.__defineGetter__("eit", g6);
+check(gnover, "eit", { get: g6, set: undefined, enumerable: true, configurable: true });
+
+/******************************************************************************/
+
+// Adding a setter over a non-writable data property
+
+function s6() { }
+var snover = { eit: 17 };
+check(snover, "eit", { value: 17, writable: true, enumerable: true, configurable: true });
+Object.defineProperty(snover, "eit", { writable: false });
+check(snover, "eit", { value: 17, writable: false, enumerable: true, configurable: true });
+
+snover.__defineSetter__("eit", s6);
+check(snover, "eit", { get: undefined, set: s6, enumerable: true, configurable: true });
+
+/******************************************************************************/
+
+// Adding a getter over a non-configurable, writable data property
+
+function g7() { }
+var gncover = { moo: 17 };
+check(gncover, "moo", { value: 17, writable: true, enumerable: true, configurable: true });
+Object.defineProperty(gncover, "moo", { configurable: false });
+check(gncover, "moo", { value: 17, writable: true, enumerable: true, configurable: false });
+
+expectTypeError(function() { gncover.__defineGetter__("moo", g7); });
+check(gncover, "moo", { value: 17, writable: true, enumerable: true, configurable: false });
+
+/******************************************************************************/
+
+// Adding a setter over a non-configurable, writable data property
+
+function s7() { }
+var sncover = { moo: 17 };
+check(sncover, "moo", { value: 17, writable: true, enumerable: true, configurable: true });
+Object.defineProperty(sncover, "moo", { configurable: false });
+check(sncover, "moo", { value: 17, writable: true, enumerable: true, configurable: false });
+
+expectTypeError(function() { sncover.__defineSetter__("moo", s7); });
+check(sncover, "moo", { value: 17, writable: true, enumerable: true, configurable: false });
+
+/******************************************************************************/
+
+// Adding a getter over a non-configurable, non-writable data property
+
+function g8() { }
+var gncwover = { fwoosh: 17 };
+check(gncwover, "fwoosh", { value: 17, writable: true, enumerable: true, configurable: true });
+Object.defineProperty(gncwover, "fwoosh", { writable: false, configurable: false });
+check(gncwover, "fwoosh", { value: 17, writable: false, enumerable: true, configurable: false });
+
+expectTypeError(function() { gncwover.__defineGetter__("fwoosh", g7); });
+check(gncwover, "fwoosh", { value: 17, writable: false, enumerable: true, configurable: false });
+
+/******************************************************************************/
+
+// Adding a setter over a non-configurable, non-writable data property
+
+function s8() { }
+var sncwover = { fwoosh: 17 };
+check(sncwover, "fwoosh", { value: 17, writable: true, enumerable: true, configurable: true });
+Object.defineProperty(sncwover, "fwoosh", { writable: false, configurable: false });
+check(sncwover, "fwoosh", { value: 17, writable: false, enumerable: true, configurable: false });
+
+expectTypeError(function() { sncwover.__defineSetter__("fwoosh", s7); });
+check(sncwover, "fwoosh", { value: 17, writable: false, enumerable: true, configurable: false });
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/eval-native-callback-is-indirect.js b/js/src/tests/ecma_5/extensions/eval-native-callback-is-indirect.js
new file mode 100644
index 000000000..662f619ee
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/eval-native-callback-is-indirect.js
@@ -0,0 +1,43 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 604504;
+var summary = "eval called from a native function is indirect";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var originalEval = eval;
+
+var global = this;
+var directCheckCode = "this === global";
+
+function testArrayGeneric()
+{
+ var global = "psych!";
+ var eval = Array.map;
+
+ var mapped = eval([directCheckCode], originalEval);
+ assertEq(mapped[0], true);
+}
+
+function testStringGeneric()
+{
+ var global = "psych!";
+ var eval = String.replace;
+
+ var newString = eval(directCheckCode, directCheckCode, originalEval);
+ assertEq(newString, "true");
+}
+testStringGeneric();
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/extension-methods-reject-null-undefined-this.js b/js/src/tests/ecma_5/extensions/extension-methods-reject-null-undefined-this.js
new file mode 100644
index 000000000..5ea399fe8
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/extension-methods-reject-null-undefined-this.js
@@ -0,0 +1,112 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 619283;
+var summary =
+ "ECMAScript built-in methods that immediately throw when |this| is " +
+ "|undefined| or |null| (due to CheckObjectCoercible, ToObject, or ToString)";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// This test fills out for the non-standard methods which
+// ecma_5/misc/builtin-methods-reject-null-undefined-this.js declines to test.
+
+var ClassToMethodMap =
+ {
+ Object: [/*
+ * Don't box this just yet for these methods -- they're used too
+ * much without qualification to do that. :-(
+ */
+ /* "__defineGetter__", "__defineSetter__", */
+ "__lookupGetter__", "__lookupSetter__", "watch", "unwatch",
+ "toSource"],
+ Function: ["toSource"],
+ Array: ["toSource"],
+ String: ["toSource", "quote", "bold", "italics", "fixed", "fontsize",
+ "fontcolor", "link", "anchor", "strike", "small", "big", "blink",
+ "sup", "sub", "substr", "trimLeft", "trimRight", "toJSON"],
+ Boolean: ["toSource", "toJSON"],
+ Number: ["toSource", "toJSON"],
+ Date: ["toSource", "toLocaleFormat", "getYear", "setYear",
+ "toGMTString"],
+ RegExp: ["toSource"],
+ Error: ["toSource"],
+ };
+
+var badThisValues = [null, undefined];
+
+function testMethod(Class, className, method)
+{
+ var expr;
+
+ // Try out explicit this values
+ for (var i = 0, sz = badThisValues.length; i < sz; i++)
+ {
+ var badThis = badThisValues[i];
+
+ expr = className + ".prototype." + method + ".call(" + badThis + ")";
+ try
+ {
+ Class.prototype[method].call(badThis);
+ throw new Error(expr + " didn't throw a TypeError");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "wrong error for " + expr + ", instead threw " + e);
+ }
+
+ expr = className + ".prototype." + method + ".apply(" + badThis + ")";
+ try
+ {
+ Class.prototype[method].apply(badThis);
+ throw new Error(expr + " didn't throw a TypeError");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "wrong error for " + expr + ", instead threw " + e);
+ }
+ }
+
+ // ..and for good measure..
+
+ expr = "(0, " + className + ".prototype." + method + ")()"
+ try
+ {
+ // comma operator to call GetValue() on the method and de-Reference it
+ (0, Class.prototype[method])();
+ throw new Error(expr + " didn't throw a TypeError");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "wrong error for " + expr + ", instead threw " + e);
+ }
+}
+
+for (var className in ClassToMethodMap)
+{
+ var Class = this[className];
+
+ var methodNames = ClassToMethodMap[className];
+ for (var i = 0, sz = methodNames.length; i < sz; i++)
+ {
+ var method = methodNames[i];
+ testMethod(Class, className, method);
+ }
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/function-caller-skips-eval-frames.js b/js/src/tests/ecma_5/extensions/function-caller-skips-eval-frames.js
new file mode 100644
index 000000000..77eb99108
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/function-caller-skips-eval-frames.js
@@ -0,0 +1,34 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+function innermost() { return arguments.callee.caller; }
+function nest() { return eval("innermost();"); }
+function nest2() { return nest(); }
+
+assertEq(nest2(), nest);
+
+var innermost = function innermost() { return arguments.callee.caller.caller; };
+
+assertEq(nest2(), nest2);
+
+function nestTwice() { return eval("eval('innermost();');"); }
+var nest = nestTwice;
+
+assertEq(nest2(), nest2);
+
+function innermostEval() { return eval("arguments.callee.caller"); }
+var innermost = innermostEval;
+
+assertEq(nest2(), nestTwice);
+
+function innermostEvalTwice() { return eval('eval("arguments.callee.caller");'); }
+var innermost = innermostEvalTwice;
+
+assertEq(nest2(), nestTwice);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/function-caller-strict-cross-global.js b/js/src/tests/ecma_5/extensions/function-caller-strict-cross-global.js
new file mode 100644
index 000000000..45fd7b1b3
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/function-caller-strict-cross-global.js
@@ -0,0 +1,28 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs newGlobal()
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var g1 = newGlobal();
+g1.evaluate("function f() { return f.caller; }");
+
+var g2 = newGlobal();
+g2.f = g1.f;
+
+try
+{
+ g2.evaluate("function g() { 'use strict'; return f(); } g()");
+ throw new Error("failed to throw");
+}
+catch (e)
+{
+ assertEq(e.constructor.name, "TypeError",
+ "expected TypeError accessing strict .caller across globals, got " +
+ e);
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/function-definition-with.js b/js/src/tests/ecma_5/extensions/function-definition-with.js
new file mode 100644
index 000000000..2277ad45f
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/function-definition-with.js
@@ -0,0 +1,56 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs evaluate()
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 577325;
+var summary = 'Implement the ES5 algorithm for processing function statements';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var called, obj;
+
+function inFile1() { return "in file"; }
+called = false;
+obj = { set inFile1(v) { called = true; } };
+with (obj) {
+ function inFile1() { return "in file in with"; };
+}
+assertEq(inFile1(), "in file in with");
+assertEq("set" in Object.getOwnPropertyDescriptor(obj, "inFile1"), true);
+assertEq(called, false);
+
+evaluate("function notInFile1() { return 'not in file'; }");
+called = false;
+obj = { set notInFile1(v) { called = true; return "not in file 2"; } };
+with (obj) {
+ function notInFile1() { return "not in file in with"; };
+}
+assertEq(notInFile1(), "not in file in with");
+assertEq("set" in Object.getOwnPropertyDescriptor(obj, "notInFile1"), true);
+assertEq(called, false);
+
+function inFile2() { return "in file 1"; }
+called = false;
+obj =
+ Object.defineProperty({}, "inFile2",
+ { value: 42, configurable: false, enumerable: false });
+with (obj) {
+ function inFile2() { return "in file 2"; };
+}
+assertEq(inFile2(), "in file 2");
+assertEq(obj.inFile2, 42);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/function-properties.js b/js/src/tests/ecma_5/extensions/function-properties.js
new file mode 100644
index 000000000..9585322ef
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/function-properties.js
@@ -0,0 +1,21 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+function foo()
+{
+ assertEq(foo.arguments.length, 0);
+ assertEq(foo.caller, null);
+}
+
+assertEq(foo.arguments, null);
+assertEq(foo.caller, null);
+foo();
+assertEq(foo.arguments, null);
+assertEq(foo.caller, null);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/getOwnPropertyNames-__proto__.js b/js/src/tests/ecma_5/extensions/getOwnPropertyNames-__proto__.js
new file mode 100644
index 000000000..91ee2d203
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/getOwnPropertyNames-__proto__.js
@@ -0,0 +1,26 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 837630;
+var summary ='__proto__ should show up with O.getOwnPropertyNames(O.prototype)';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var keys = Object.getOwnPropertyNames(Object.prototype);
+assertEq(keys.indexOf("__proto__") >= 0, true,
+ "should have gotten __proto__ as a property of Object.prototype " +
+ "(got these properties: " + keys + ")");
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/inc-dec-functioncall.js b/js/src/tests/ecma_5/extensions/inc-dec-functioncall.js
new file mode 100644
index 000000000..b4de03c6c
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/inc-dec-functioncall.js
@@ -0,0 +1,90 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 609756;
+var summary =
+ "Perform ToNumber on the result of the |fun()| in |fun()++| before " +
+ "throwing";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var hadSideEffect;
+
+function f()
+{
+ return { valueOf: function() { hadSideEffect = true; return 0; } };
+}
+
+hadSideEffect = false;
+assertThrowsInstanceOf(function() { f()++; }, ReferenceError);
+assertEq(hadSideEffect, true);
+
+hadSideEffect = false;
+assertThrowsInstanceOf(function() {
+ for (var i = 0; i < 20; i++)
+ {
+ if (i > 18)
+ f()++;
+ }
+}, ReferenceError);
+assertEq(hadSideEffect, true);
+
+
+hadSideEffect = false;
+assertThrowsInstanceOf(function() { f()--; }, ReferenceError);
+assertEq(hadSideEffect, true);
+
+hadSideEffect = false;
+assertThrowsInstanceOf(function() {
+ for (var i = 0; i < 20; i++)
+ {
+ if (i > 18)
+ f()--;
+ }
+}, ReferenceError);
+assertEq(hadSideEffect, true);
+
+
+hadSideEffect = false;
+assertThrowsInstanceOf(function() { ++f(); }, ReferenceError);
+assertEq(hadSideEffect, true);
+
+hadSideEffect = false;
+assertThrowsInstanceOf(function() {
+ for (var i = 0; i < 20; i++)
+ {
+ if (i > 18)
+ ++f();
+ }
+}, ReferenceError);
+assertEq(hadSideEffect, true);
+
+
+hadSideEffect = false;
+assertThrowsInstanceOf(function() { --f(); }, ReferenceError);
+assertEq(hadSideEffect, true);
+
+hadSideEffect = false;
+assertThrowsInstanceOf(function() {
+ for (var i = 0; i < 20; i++)
+ {
+ if (i > 18)
+ --f();
+ }
+}, ReferenceError);
+assertEq(hadSideEffect, true);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/iterator-in-catch.js b/js/src/tests/ecma_5/extensions/iterator-in-catch.js
new file mode 100644
index 000000000..390b585e9
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/iterator-in-catch.js
@@ -0,0 +1,20 @@
+//Bug 350712
+
+function iterator () {
+ for (var i in []);
+}
+
+try {
+ try {
+ throw 5;
+ }
+ catch(error if iterator()) {
+ assertEq(false, true);
+ }
+}
+catch(error) {
+ assertEq(error, 5);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/misplaced-inconsistent-directive.js b/js/src/tests/ecma_5/extensions/misplaced-inconsistent-directive.js
new file mode 100644
index 000000000..b7b33001c
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/misplaced-inconsistent-directive.js
@@ -0,0 +1,74 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs evaluate()
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 1046964;
+var summary =
+ "Misplaced directives (e.g. 'use strict') should trigger warnings if they " +
+ "contradict the actually-used semantics";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+options("strict");
+options("werror");
+
+function evaluateNoRval(code)
+{
+ evaluate(code, { isRunOnce: true, noScriptRval: true });
+}
+
+function expectSyntaxError(code)
+{
+ try
+ {
+ evaluateNoRval(code);
+ throw new Error("didn't throw");
+ }
+ catch (e)
+ {
+ assertEq(e instanceof SyntaxError, true,
+ "should have thrown a SyntaxError, instead got:\n" +
+ " " + e + "\n" +
+ "when evaluating:\n" +
+ " " + code);
+ }
+}
+
+expectSyntaxError("function f1() {} 'use strict'; function f2() {}");
+expectSyntaxError("function f3() { var x; 'use strict'; }");
+
+if (isAsmJSCompilationAvailable())
+ expectSyntaxError("function f4() {} 'use asm'; function f5() {}");
+expectSyntaxError("function f6() { var x; 'use strict'; }");
+if (isAsmJSCompilationAvailable())
+ expectSyntaxError("'use asm'; function f7() {}");
+
+// No errors expected -- useless non-directives, but not contrary to used
+// semantics.
+evaluateNoRval("'use strict'; function f8() {} 'use strict'; function f9() {}");
+evaluateNoRval("'use strict'; function f10() { var z; 'use strict' }");
+
+if (isAsmJSCompilationAvailable()) {
+ try {
+ evaluateNoRval("function f11() { 'use asm'; return {}; }");
+ } catch(e) {
+ if (!e.toString().includes("Successfully compiled asm.js code"))
+ throw e;
+ }
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/nested-delete-name-in-evalcode.js b/js/src/tests/ecma_5/extensions/nested-delete-name-in-evalcode.js
new file mode 100644
index 000000000..7dfab0458
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/nested-delete-name-in-evalcode.js
@@ -0,0 +1,85 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 616294;
+var summary =
+ "|delete x| inside a function in eval code, where that eval code includes " +
+ "|var x| at top level, actually does delete the binding for x";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var f;
+
+function testOuterLet()
+{
+ return eval("let x; (function() { return delete x; })");
+}
+
+f = testOuterLet();
+
+assertEq(f(), false); // can't delete lexical declarations => false
+
+
+function testOuterForLet()
+{
+ return eval("for (let x; false; ); (function() { return delete x; })");
+}
+
+f = testOuterForLet();
+
+assertEq(f(), true); // not there => true (only non-configurable => false)
+
+
+function testOuterForInLet()
+{
+ return eval("for (let x in {}); (function() { return delete x; })");
+}
+
+f = testOuterForInLet();
+
+assertEq(f(), true); // configurable, so remove => true
+assertEq(f(), true); // not there => true (only non-configurable => false)
+
+
+function testOuterNestedVarInForLet()
+{
+ return eval("for (let q = 0; q < 5; q++) { var x; } (function() { return delete x; })");
+}
+
+f = testOuterNestedVarInForLet();
+
+assertEq(f(), true); // configurable, so remove => true
+assertEq(f(), true); // there => true
+
+
+function testArgumentShadowLet()
+{
+ return eval("let x; (function(x) { return delete x; })");
+}
+
+f = testArgumentShadowLet();
+
+assertEq(f(), false); // non-configurable argument => false
+
+
+function testFunctionLocal()
+{
+ return eval("(function() { let x; return delete x; })");
+}
+
+f = testFunctionLocal();
+
+assertEq(f(), false); // defined by function code => not configurable => false
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/preventExtensions-cross-global.js b/js/src/tests/ecma_5/extensions/preventExtensions-cross-global.js
new file mode 100644
index 000000000..0cc68e0fb
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/preventExtensions-cross-global.js
@@ -0,0 +1,49 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs newGlobal()
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+var gTestfile = 'preventExtensions-cross-global.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 789897;
+var summary =
+ "Object.preventExtensions and Object.isExtensible should work correctly " +
+ "across globals";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var otherGlobal = newGlobal();
+
+var obj = {};
+assertEq(otherGlobal.Object.isExtensible(obj), true);
+assertEq(otherGlobal.Object.preventExtensions(obj), obj);
+assertEq(otherGlobal.Object.isExtensible(obj), false);
+
+var objFromOther = otherGlobal.Object();
+assertEq(Object.isExtensible(objFromOther), true);
+assertEq(Object.preventExtensions(objFromOther), objFromOther);
+assertEq(Object.isExtensible(objFromOther), false);
+
+var proxy = new Proxy({}, {});
+assertEq(otherGlobal.Object.isExtensible(proxy), true);
+assertEq(otherGlobal.Object.preventExtensions(proxy), proxy);
+assertEq(otherGlobal.Object.isExtensible(proxy), false);
+
+var proxyFromOther = otherGlobal.evaluate("new Proxy({}, {})");
+assertEq(Object.isExtensible(proxyFromOther), true);
+assertEq(Object.preventExtensions(proxyFromOther), proxyFromOther);
+assertEq(Object.isExtensible(proxyFromOther), false);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/proxy-array-target-length-definition.js b/js/src/tests/ecma_5/extensions/proxy-array-target-length-definition.js
new file mode 100644
index 000000000..c573c4ba0
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/proxy-array-target-length-definition.js
@@ -0,0 +1,55 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'proxy-array-target-length-definition.js';
+var BUGNUMBER = 905947;
+var summary =
+ "Redefining an array's |length| property when redefining the |length| " +
+ "property on a proxy with an array as target";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var arr = [];
+var p = new Proxy(arr, {});
+
+function assertThrowsTypeError(f)
+{
+ try {
+ f();
+ assertEq(false, true, "Must have thrown");
+ } catch (e) {
+ assertEq(e instanceof TypeError, true, "Must have thrown TypeError");
+ }
+}
+
+// Redefining non-configurable length should throw a TypeError
+assertThrowsTypeError(function () { Object.defineProperty(p, "length", { value: 17, configurable: true }); });
+
+// Same here.
+assertThrowsTypeError(function () { Object.defineProperty(p, "length", { value: 42, enumerable: true }); });
+
+// Check the property went unchanged.
+var pd = Object.getOwnPropertyDescriptor(p, "length");
+assertEq(pd.value, 0);
+assertEq(pd.writable, true);
+assertEq(pd.enumerable, false);
+assertEq(pd.configurable, false);
+
+var ad = Object.getOwnPropertyDescriptor(arr, "length");
+assertEq(ad.value, 0);
+assertEq(ad.writable, true);
+assertEq(ad.enumerable, false);
+assertEq(ad.configurable, false);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/proxy-enumeration.js b/js/src/tests/ecma_5/extensions/proxy-enumeration.js
new file mode 100644
index 000000000..f872d635d
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/proxy-enumeration.js
@@ -0,0 +1,4 @@
+var list = Object.getOwnPropertyNames(this);
+var found = list.indexOf("Proxy") != -1;
+assertEq(found, true)
+reportCompare(true, true)
diff --git a/js/src/tests/ecma_5/extensions/proxy-strict.js b/js/src/tests/ecma_5/extensions/proxy-strict.js
new file mode 100644
index 000000000..9dc969685
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/proxy-strict.js
@@ -0,0 +1,12 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var s = "grape";
+function f() { "use strict"; return this; }
+var p = new Proxy(f, {});
+String.prototype.p = p;
+assertEq(s.p(), "grape");
+
+reportCompare(true,true);
diff --git a/js/src/tests/ecma_5/extensions/regress-bug567606.js b/js/src/tests/ecma_5/extensions/regress-bug567606.js
new file mode 100644
index 000000000..6bebc8063
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/regress-bug567606.js
@@ -0,0 +1,19 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var global = this;
+
+(function() {
+ function f() {
+ this.b = function() {};
+ Object.defineProperty(this, "b", ({
+ configurable: global.__defineSetter__("", function() {})
+ }));
+ }
+ for (y of [0]) {
+ _ = new f();
+ }
+})();
+uneval(this);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/regress-bug607284.js b/js/src/tests/ecma_5/extensions/regress-bug607284.js
new file mode 100644
index 000000000..7d2c4921d
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/regress-bug607284.js
@@ -0,0 +1,16 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+if ("evalcx" in this) {
+ var sandbox = evalcx("");
+ var obj = { get foo() { throw("FAIL"); } };
+ var getter = obj.__lookupGetter__("foo");
+ var desc = sandbox.Object.getOwnPropertyDescriptor(obj, "foo");
+ reportCompare(desc.get, getter, "getter is correct");
+ reportCompare(desc.set, undefined, "setter is correct");
+}
+else {
+ reportCompare(true, true);
+}
diff --git a/js/src/tests/ecma_5/extensions/regress-bug629723.js b/js/src/tests/ecma_5/extensions/regress-bug629723.js
new file mode 100644
index 000000000..6c826e0c2
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/regress-bug629723.js
@@ -0,0 +1,16 @@
+function f(foo) {
+ "use strict";
+ foo.bar;
+}
+
+var actual;
+try {
+ f();
+ actual = "no error";
+} catch (x) {
+ actual = (x instanceof TypeError) ? "type error" : "some other error";
+ actual += (/use strict/.test(x)) ? " with directive" : " without directive";
+}
+
+reportCompare("type error without directive", actual,
+ "decompiled expressions in error messages should not include directive prologues");
diff --git a/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array-ccw.js b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array-ccw.js
new file mode 100644
index 000000000..e51e19903
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array-ccw.js
@@ -0,0 +1,39 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 901351;
+var summary = "Behavior when the JSON.parse reviver mutates the holder array";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var proxyObj = null;
+
+var arr = JSON.parse('[0, 1]', function(prop, v) {
+ if (prop === "0")
+ {
+ proxyObj = newGlobal().evaluate("({ c: 17, d: 42 })");
+ this[1] = proxyObj;
+ }
+ return v;
+});
+
+assertEq(arr[0], 0);
+assertEq(arr[1], proxyObj);
+assertEq(arr[1].c, 17);
+assertEq(arr[1].d, 42);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array-nonnative.js b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array-nonnative.js
new file mode 100644
index 000000000..de4ad7032
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array-nonnative.js
@@ -0,0 +1,46 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 901380;
+var summary = "Behavior when JSON.parse walks over a non-native object";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var typedArray = null;
+
+var observedTypedArrayElementCount = 0;
+
+var arr = JSON.parse('[0, 1]', function(prop, v) {
+ if (prop === "0" && Array.isArray(this)) // exclude typedArray[0]
+ {
+ typedArray = new Int8Array(1);
+ this[1] = typedArray;
+ }
+ if (this instanceof Int8Array)
+ {
+ assertEq(prop, "0");
+ observedTypedArrayElementCount++;
+ }
+ return v;
+});
+
+assertEq(arr[0], 0);
+assertEq(arr[1], typedArray);
+
+assertEq(observedTypedArrayElementCount, 1);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array.js b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array.js
new file mode 100644
index 000000000..f4f89ac0a
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-array.js
@@ -0,0 +1,39 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 901351;
+var summary = "Behavior when the JSON.parse reviver mutates the holder array";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var proxyObj = null;
+
+var arr = JSON.parse('[0, 1]', function(prop, v) {
+ if (prop === "0")
+ {
+ proxyObj = new Proxy({ c: 17, d: 42 }, {});
+ this[1] = proxyObj;
+ }
+ return v;
+});
+
+assertEq(arr[0], 0);
+assertEq(arr[1], proxyObj);
+assertEq(arr[1].c, 17);
+assertEq(arr[1].d, 42);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object-ccw.js b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object-ccw.js
new file mode 100644
index 000000000..546a57e91
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object-ccw.js
@@ -0,0 +1,56 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 901351;
+var summary = "Behavior when the JSON.parse reviver mutates the holder object";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// A little trickiness to account for the undefined-ness of property
+// enumeration order.
+var first = "unset";
+
+var proxyObj = null;
+
+var obj = JSON.parse('{ "a": 0, "b": 1 }', function(prop, v) {
+ if (first === "unset")
+ {
+ first = prop;
+ var second = (prop === "a") ? "b" : "a";
+
+ proxyObj = newGlobal().evaluate("({ c: 42, d: 17 })");
+ Object.defineProperty(this, second, { value: proxyObj });
+ }
+ return v;
+});
+
+if (first === "a")
+{
+ assertEq(obj.a, 0);
+ assertEq(obj.b, proxyObj);
+ assertEq(obj.b.c, 42);
+ assertEq(obj.b.d, 17);
+}
+else
+{
+ assertEq(obj.a, proxyObj);
+ assertEq(obj.a.c, 42);
+ assertEq(obj.a.d, 17);
+ assertEq(obj.b, 1);
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object-nonnative.js b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object-nonnative.js
new file mode 100644
index 000000000..1300f8dd0
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object-nonnative.js
@@ -0,0 +1,60 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 901380;
+var summary = "Behavior when JSON.parse walks over a non-native object";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// A little trickiness to account for the undefined-ness of property
+// enumeration order.
+var first = "unset";
+
+var observedTypedArrayElementCount = 0;
+
+var typedArray = null;
+
+var obj = JSON.parse('{ "a": 0, "b": 1 }', function(prop, v) {
+ if (first === "unset")
+ {
+ first = prop;
+ var second = (prop === "a") ? "b" : "a";
+ typedArray = new Int8Array(1);
+ Object.defineProperty(this, second, { value: typedArray });
+ }
+ if (this instanceof Int8Array)
+ {
+ assertEq(prop, "0");
+ observedTypedArrayElementCount++;
+ }
+ return v;
+});
+
+if (first === "a")
+{
+ assertEq(obj.a, 0);
+ assertEq(obj.b, typedArray);
+}
+else
+{
+ assertEq(obj.a, typedArray);
+ assertEq(obj.b, 1);
+}
+
+assertEq(observedTypedArrayElementCount, 1);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object.js b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object.js
new file mode 100644
index 000000000..973766e9a
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/reviver-mutates-holder-object.js
@@ -0,0 +1,56 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 901351;
+var summary = "Behavior when the JSON.parse reviver mutates the holder object";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// A little trickiness to account for the undefined-ness of property
+// enumeration order.
+var first = "unset";
+
+var proxyObj = null;
+
+var obj = JSON.parse('{ "a": 0, "b": 1 }', function(prop, v) {
+ if (first === "unset")
+ {
+ first = prop;
+ var second = (prop === "a") ? "b" : "a";
+
+ proxyObj = new Proxy({ c: 42, d: 17 }, {});
+ Object.defineProperty(this, second, { value: proxyObj });
+ }
+ return v;
+});
+
+if (first === "a")
+{
+ assertEq(obj.a, 0);
+ assertEq(obj.b, proxyObj);
+ assertEq(obj.b.c, 42);
+ assertEq(obj.b.d, 17);
+}
+else
+{
+ assertEq(obj.a, proxyObj);
+ assertEq(obj.a.c, 42);
+ assertEq(obj.a.d, 17);
+ assertEq(obj.b, 1);
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_5/extensions/shell.js b/js/src/tests/ecma_5/extensions/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/shell.js
diff --git a/js/src/tests/ecma_5/extensions/strict-function-statements.js b/js/src/tests/ecma_5/extensions/strict-function-statements.js
new file mode 100644
index 000000000..e6dc15139
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/strict-function-statements.js
@@ -0,0 +1,94 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+// Ordinary function definitions should be unaffected.
+assertEq(testLenientAndStrict("function f() { }",
+ parsesSuccessfully,
+ parsesSuccessfully),
+ true);
+
+// Lambdas are always permitted within blocks.
+assertEq(testLenientAndStrict("{ (function f() { }) }",
+ parsesSuccessfully,
+ parsesSuccessfully),
+ true);
+
+// Function statements within unbraced blocks are forbidden in strict mode code.
+// They are allowed only under if statements in sloppy mode.
+assertEq(testLenientAndStrict("if (true) function f() { }",
+ parsesSuccessfully,
+ parseRaisesException(SyntaxError)),
+ true);
+assertEq(testLenientAndStrict("while (true) function f() { }",
+ parseRaisesException(SyntaxError),
+ parseRaisesException(SyntaxError)),
+ true);
+assertEq(testLenientAndStrict("do function f() { } while (true);",
+ parseRaisesException(SyntaxError),
+ parseRaisesException(SyntaxError)),
+ true);
+assertEq(testLenientAndStrict("for(;;) function f() { }",
+ parseRaisesException(SyntaxError),
+ parseRaisesException(SyntaxError)),
+ true);
+assertEq(testLenientAndStrict("for(x in []) function f() { }",
+ parseRaisesException(SyntaxError),
+ parseRaisesException(SyntaxError)),
+ true);
+assertEq(testLenientAndStrict("with(o) function f() { }",
+ parseRaisesException(SyntaxError),
+ parseRaisesException(SyntaxError)),
+ true);
+assertEq(testLenientAndStrict("switch(1) { case 1: function f() { } }",
+ parsesSuccessfully,
+ parsesSuccessfully),
+ true);
+assertEq(testLenientAndStrict("x: function f() { }",
+ parsesSuccessfully,
+ parseRaisesException(SyntaxError)),
+ true);
+assertEq(testLenientAndStrict("try { function f() { } } catch (x) { }",
+ parsesSuccessfully,
+ parsesSuccessfully),
+ true);
+
+// Lambdas are always permitted within any sort of statement.
+assertEq(testLenientAndStrict("if (true) (function f() { })",
+ parsesSuccessfully,
+ parsesSuccessfully),
+ true);
+
+// Function statements are permitted in blocks within lenient functions.
+assertEq(parsesSuccessfully("function f() { function g() { } }"),
+ true);
+
+// Function statements are permitted in if statement within lenient functions.
+assertEq(parsesSuccessfully("function f() { if (true) function g() { } }"),
+ true);
+
+assertEq(parseRaisesException(SyntaxError)
+ ("function f() { 'use strict'; if (true) function g() { } }"),
+ true);
+
+assertEq(parsesSuccessfully("function f() { 'use strict'; { function g() { } } }"),
+ true);
+
+assertEq(parsesSuccessfully("function f() { 'use strict'; if (true) (function g() { }) }"),
+ true);
+
+assertEq(parsesSuccessfully("function f() { 'use strict'; { (function g() { }) } }"),
+ true);
+
+// Eval should behave the same way. (The parse-only tests use the Function constructor.)
+assertEq(testLenientAndStrict("function f() { }",
+ completesNormally,
+ completesNormally),
+ true);
+assertEq(testLenientAndStrict("{ function f() { } }",
+ completesNormally,
+ completesNormally),
+ true);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/strict-function-toSource.js b/js/src/tests/ecma_5/extensions/strict-function-toSource.js
new file mode 100644
index 000000000..6d9b68560
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/strict-function-toSource.js
@@ -0,0 +1,17 @@
+/*
+ * Bug 800407 - Functions defined with Function construcor
+ * do have strict mode when JSOPTION_STRICT_MODE is on.
+ */
+
+options("strict_mode");
+function testRunOptionStrictMode(str, arg, result) {
+ var strict_inner = new Function('return typeof this == "undefined";');
+ return strict_inner;
+}
+let inner = testRunOptionStrictMode();
+assertEq(inner(), true);
+assertEq(eval(uneval(inner))(), true);
+
+assertEq((new Function('x', 'return x*2;')).toSource().includes('"use strict"'), false);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/strict-option-redeclared-parameter.js b/js/src/tests/ecma_5/extensions/strict-option-redeclared-parameter.js
new file mode 100644
index 000000000..5a36b6947
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/strict-option-redeclared-parameter.js
@@ -0,0 +1,30 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 630770;
+var summary =
+ 'Correctly warn about duplicate parameters when the strict option is enabled';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// Verify that duplicate parameters, with the strict option set, don't provoke
+// an assertion. Ideally we'd also verify that we warn exactly once per
+// duplicated parameter name, but at present there's no way to test that
+// without more effort (further customizing the shell JSErrorReporter) than we
+// want to make now.
+options("strict");
+eval("function a(x, x, x, x) { }");
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/string-literal-getter-setter-decompilation.js b/js/src/tests/ecma_5/extensions/string-literal-getter-setter-decompilation.js
new file mode 100644
index 000000000..a0a571405
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/string-literal-getter-setter-decompilation.js
@@ -0,0 +1,34 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var f;
+try
+{
+ f = eval("(function literalInside() { return { set 'c d e'(v) { } }; })");
+}
+catch (e)
+{
+ assertEq(true, false,
+ "string-literal property name in setter in object literal in " +
+ "function statement failed to parse: " + e);
+}
+
+var fstr = "" + f;
+assertEq(fstr.indexOf("set") < fstr.indexOf("c d e"), true,
+ "should be using new-style syntax with string literal in place of " +
+ "property identifier");
+assertEq(fstr.indexOf("setter") < 0, true, "using old-style syntax?");
+
+var o = f();
+var ostr = "" + o;
+assertEq("c d e" in o, true, "missing the property?");
+assertEq("set" in Object.getOwnPropertyDescriptor(o, "c d e"), true,
+ "'c d e' property not a setter?");
+// disabled because we still generate old-style syntax here (toSource
+// decompilation is as yet unfixed)
+// assertEq(ostr.indexOf("set") < ostr.indexOf("c d e"), true,
+// "should be using new-style syntax when getting the source of a " +
+// "getter/setter while decompiling an object");
+// assertEq(ostr.indexOf("setter") < 0, true, "using old-style syntax?");
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/toLocaleString-infinite-recursion.js b/js/src/tests/ecma_5/extensions/toLocaleString-infinite-recursion.js
new file mode 100644
index 000000000..a11433ce4
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/toLocaleString-infinite-recursion.js
@@ -0,0 +1,31 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 653789;
+var summary = 'Check for too-deep stack when calling toLocaleString';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ "" + { toString: Object.prototype.toLocaleString };
+ throw new Error("should have thrown on over-recursion");
+}
+catch (e)
+{
+ assertEq(e instanceof InternalError, true);
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/toSource-infinite-recursion.js b/js/src/tests/ecma_5/extensions/toSource-infinite-recursion.js
new file mode 100644
index 000000000..2ddcaa752
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/toSource-infinite-recursion.js
@@ -0,0 +1,34 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 650574;
+var summary = 'Check for too-deep stack when converting a value to source';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ var e = Error('');
+ e.fileName = e;
+ e.toSource();
+ throw new Error("should have thrown");
+}
+catch (e)
+{
+ assertEq(e instanceof InternalError, true,
+ "should have thrown for over-recursion");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/ecma_5/extensions/watch-array-length.js b/js/src/tests/ecma_5/extensions/watch-array-length.js
new file mode 100644
index 000000000..e9b356efa
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/watch-array-length.js
@@ -0,0 +1,41 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var hitCount;
+function watcher(p,o,n) { hitCount++; return n; }
+
+var a = [1];
+a.watch('length', watcher);
+hitCount = 0;
+a.length = 0;
+reportCompare(1, hitCount, "lenient; configurable: watchpoint hit");
+
+var b = Object.defineProperty([1],'0',{configurable:false});
+b.watch('length', watcher);
+hitCount = 0;
+var result;
+try {
+ b.length = 0;
+ result = "no error";
+} catch (x) {
+ result = x.toString();
+}
+reportCompare(1, hitCount, "lenient; non-configurable: watchpoint hit");
+reportCompare(1, b.length, "lenient; non-configurable: length unchanged");
+reportCompare("no error", result, "lenient; non-configurable: no error thrown");
+
+var c = Object.defineProperty([1],'0',{configurable:false});
+c.watch('length', watcher);
+hitCount = 0;
+var threwTypeError;
+try {
+ (function(){'use strict'; c.length = 0;})();
+ threwTypeError = false;
+} catch (x) {
+ threwTypeError = x instanceof TypeError;
+}
+reportCompare(1, hitCount, "strict; non-configurable: watchpoint hit");
+reportCompare(1, c.length, "strict; non-configurable: length unchanged");
+reportCompare(true, threwTypeError, "strict; non-configurable: TypeError thrown");
diff --git a/js/src/tests/ecma_5/extensions/watch-inherited-property.js b/js/src/tests/ecma_5/extensions/watch-inherited-property.js
new file mode 100644
index 000000000..1a0ad566b
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/watch-inherited-property.js
@@ -0,0 +1,38 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+/* Create a prototype object with a setter property. */
+var protoSetterCount;
+var proto = ({ set x(v) { protoSetterCount++; } });
+
+/* Put a watchpoint on that setter. */
+var protoWatchCount;
+proto.watch('x', function() { protoWatchCount++; });
+
+/* Make an object with the above as its prototype. */
+function C() { }
+C.prototype = proto;
+var o = new C();
+
+/*
+ * Set a watchpoint on the property in the inheriting object. We have
+ * defined this to mean "duplicate the property, setter and all, in the
+ * inheriting object." I don't think debugging observation mechanisms
+ * should mutate the program being run, but that's what we've got.
+ */
+var oWatchCount;
+o.watch('x', function() { oWatchCount++; });
+
+/*
+ * Assign to the property. This should trip the watchpoint on the inheriting object and
+ * the setter.
+ */
+protoSetterCount = protoWatchCount = oWatchCount = 0;
+o.x = 1;
+assertEq(protoWatchCount, 0);
+assertEq(oWatchCount, 1);
+assertEq(protoSetterCount, 1);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watch-replaced-setter.js b/js/src/tests/ecma_5/extensions/watch-replaced-setter.js
new file mode 100644
index 000000000..05cf60aff
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/watch-replaced-setter.js
@@ -0,0 +1,46 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+/* A stock watcher function. */
+var watcherCount;
+function watcher(id, oldval, newval) { watcherCount++; return newval; }
+
+/* Create an object with a JavaScript setter. */
+var setterCount;
+var o = { w:2, set x(v) { setterCount++; } };
+
+/*
+ * Put the object in dictionary mode, so that JSObject::putProperty will
+ * mutate its shapes instead of creating new ones.
+ */
+delete o.w;
+
+/*
+ * Place a watchpoint on the property. The watchpoint structure holds the
+ * original JavaScript setter, and a pointer to the shape.
+ */
+o.watch('x', watcher);
+
+/*
+ * Replace the accessor property with a value property. The shape's setter
+ * should become a non-JS setter, js_watch_set, and the watchpoint
+ * structure's saved setter should be updated (in this case, cleared).
+ */
+Object.defineProperty(o, 'x', { value:3,
+ writable:true,
+ enumerable:true,
+ configurable:true });
+
+/*
+ * Assign to the property. This should trigger js_watch_set, which should
+ * call the handler, and then see that there is no JS-level setter to pass
+ * control on to, and return.
+ */
+watcherCount = setterCount = 0;
+o.x = 3;
+assertEq(watcherCount, 1);
+assertEq(setterCount, 0);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watch-setter-become-setter.js b/js/src/tests/ecma_5/extensions/watch-setter-become-setter.js
new file mode 100644
index 000000000..f5eff98b8
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/watch-setter-become-setter.js
@@ -0,0 +1,44 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+/* Create an object with a JavaScript setter. */
+var firstSetterCount;
+var o = { w:2, set x(v) { firstSetterCount++; } };
+
+/*
+ * Put the object in dictionary mode, so that JSObject::putProperty will
+ * mutate its shapes instead of creating new ones.
+ */
+delete o.w;
+
+/* A stock watcher function. */
+var watcherCount;
+function watcher(id, oldval, newval) { watcherCount++; return newval; }
+
+/*
+ * Place a watchpoint on the property. The property's shape now has the
+ * watchpoint setter, with the original setter saved in the watchpoint
+ * structure.
+ */
+o.watch('x', watcher);
+
+/*
+ * Replace the setter with a new setter. The shape should get updated to
+ * refer to the new setter, and then the watchpoint setter should be
+ * re-established.
+ */
+var secondSetterCount;
+Object.defineProperty(o, 'x', { set: function () { secondSetterCount++ } });
+
+/*
+ * Assign to the property. This should trigger the watchpoint and the new setter.
+ */
+watcherCount = firstSetterCount = secondSetterCount = 0;
+o.x = 3;
+assertEq(watcherCount, 1);
+assertEq(firstSetterCount, 0);
+assertEq(secondSetterCount, 1);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watch-value-prop-becoming-setter.js b/js/src/tests/ecma_5/extensions/watch-value-prop-becoming-setter.js
new file mode 100644
index 000000000..03cdd788e
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/watch-value-prop-becoming-setter.js
@@ -0,0 +1,43 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+/* A stock watcher function. */
+var watcherCount;
+function watcher(id, old, newval) {
+ watcherCount++;
+ return newval;
+}
+
+/* Create an object with a value property. */
+var o = { w:2, x:3 };
+
+/*
+ * Place a watchpoint on the value property. The watchpoint structure holds
+ * the original JavaScript setter, and a pointer to the shape.
+ */
+o.watch('x', watcher);
+
+/*
+ * Put the object in dictionary mode, so that JSObject::putProperty will
+ * mutate its shapes instead of creating new ones.
+ */
+delete o.w;
+
+/*
+ * Replace the value property with a setter.
+ */
+var setterCount;
+o.__defineSetter__('x', function() { setterCount++; });
+
+/*
+ * Trigger the watchpoint. The watchpoint handler should run, and then the
+ * setter should run.
+ */
+watcherCount = setterCount = 0;
+o.x = 4;
+assertEq(watcherCount, 1);
+assertEq(setterCount, 1);
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js b/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js
new file mode 100644
index 000000000..85410bbd4
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/watchpoint-deletes-JSPropertyOp-setter.js
@@ -0,0 +1,56 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function make_watcher(name) {
+ return function (id, oldv, newv) {
+ print("watched " + name + "[0]");
+ };
+}
+
+var o, p;
+function f(flag) {
+ if (flag) {
+ o = arguments;
+ } else {
+ p = arguments;
+ o.watch(0, make_watcher('o'));
+ p.watch(0, make_watcher('p'));
+
+ /*
+ * Previously, the watchpoint implementation actually substituted its magic setter
+ * functions for the setters of shared shapes, and then 1) carefully ignored calls
+ * to its magic setter from unrelated objects, and 2) avoided restoring the
+ * original setter until all watchpoints on that shape had been removed.
+ *
+ * However, when the watchpoint code began using JSObject::changeProperty and
+ * js_ChangeNativePropertyAttrs to change shapes' setters, the shape tree code
+ * became conscious of the presence of watchpoints, and shared shapes between
+ * objects only when their watchpoint nature coincided. Clearing the magic setter
+ * from one object's shape would not affect other objects, because the
+ * watchpointed and non-watchpointed shapes were distinct if they were shared.
+ *
+ * Thus, the first unwatch call must go ahead and fix p's shape, even though a
+ * watchpoint exists on the same shape in o. o's watchpoint's presence shouldn't
+ * cause 'unwatch' to leave p's magic setter in place.
+ */
+
+ /* DropWatchPointAndUnlock would see o's watchpoint, and not change p's property. */
+ p.unwatch(0);
+
+ /* DropWatchPointAndUnlock would fix o's property, but not p's; p's setter would be gone. */
+ o.unwatch(0);
+
+ /* This would fail to invoke the arguments object's setter. */
+ p[0] = 4;
+
+ /* And the formal parameter would not get updated. */
+ assertEq(flag, 4);
+ }
+}
+
+f(true);
+f(false);
+
+reportCompare(true, true);