summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/object
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /js/src/tests/non262/object
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/non262/object')
-rw-r--r--js/src/tests/non262/object/15.2.3.12.js46
-rw-r--r--js/src/tests/non262/object/15.2.3.14-01.js92
-rw-r--r--js/src/tests/non262/object/15.2.3.3-01.js285
-rw-r--r--js/src/tests/non262/object/15.2.3.4-01.js30
-rw-r--r--js/src/tests/non262/object/15.2.3.4-02.js52
-rw-r--r--js/src/tests/non262/object/15.2.3.4-03.js55
-rw-r--r--js/src/tests/non262/object/15.2.3.4-04.js31
-rw-r--r--js/src/tests/non262/object/15.2.3.5-01.js60
-rw-r--r--js/src/tests/non262/object/15.2.3.6-define-over-method.js24
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-01-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-02-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-03-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-04-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-05-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-06-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-07-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-08-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-09-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-10-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-11-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-12-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-13-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-14-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-15-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-16-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-17-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-18-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-19-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-20-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-21-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-22-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-23-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-24-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-25-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-26-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-27-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-28-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-29-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-30-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-31-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-32-of-32.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-function-length.js35
-rw-r--r--js/src/tests/non262/object/15.2.3.6-middle-redefinition-1-of-8.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-middle-redefinition-2-of-8.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-middle-redefinition-3-of-8.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-middle-redefinition-4-of-8.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-middle-redefinition-5-of-8.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-middle-redefinition-6-of-8.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-middle-redefinition-7-of-8.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-middle-redefinition-8-of-8.js6
-rw-r--r--js/src/tests/non262/object/15.2.3.6-miscellaneous.js74
-rw-r--r--js/src/tests/non262/object/15.2.3.6-new-definition.js35
-rw-r--r--js/src/tests/non262/object/15.2.3.6-redefinition-1-of-4.js39
-rw-r--r--js/src/tests/non262/object/15.2.3.6-redefinition-2-of-4.js39
-rw-r--r--js/src/tests/non262/object/15.2.3.6-redefinition-3-of-4.js39
-rw-r--r--js/src/tests/non262/object/15.2.3.6-redefinition-4-of-4.js39
-rw-r--r--js/src/tests/non262/object/15.2.3.7-01.js137
-rw-r--r--js/src/tests/non262/object/15.2.3.9.js51
-rw-r--r--js/src/tests/non262/object/accessor-arguments-rest.js24
-rw-r--r--js/src/tests/non262/object/accessor-name.js35
-rw-r--r--js/src/tests/non262/object/accessor-non-constructor.js20
-rw-r--r--js/src/tests/non262/object/add-property-non-extensible.js118
-rw-r--r--js/src/tests/non262/object/assign.js303
-rw-r--r--js/src/tests/non262/object/browser.js7
-rw-r--r--js/src/tests/non262/object/bug-1150906.js13
-rw-r--r--js/src/tests/non262/object/bug-1206700.js10
-rw-r--r--js/src/tests/non262/object/clear-dictionary-accessor-getset.js55
-rw-r--r--js/src/tests/non262/object/defineGetter-defineSetter.js92
-rw-r--r--js/src/tests/non262/object/defineProperties-callable-accessor.js19
-rw-r--r--js/src/tests/non262/object/defineProperties-order.js17
-rw-r--r--js/src/tests/non262/object/defineProperty-proxy.js54
-rw-r--r--js/src/tests/non262/object/defineProperty-setup.js1071
-rw-r--r--js/src/tests/non262/object/destructuring-shorthand-defaults.js127
-rw-r--r--js/src/tests/non262/object/duplProps.js116
-rw-r--r--js/src/tests/non262/object/entries.js94
-rw-r--r--js/src/tests/non262/object/extensibility-01.js103
-rw-r--r--js/src/tests/non262/object/extensibility-02.js42
-rw-r--r--js/src/tests/non262/object/freeze-global-eval-const.js13
-rw-r--r--js/src/tests/non262/object/freeze-proxy.js27
-rw-r--r--js/src/tests/non262/object/freeze.js21
-rw-r--r--js/src/tests/non262/object/gOPD-vs-prototype-accessor.js15
-rw-r--r--js/src/tests/non262/object/getOwnPropertyDescriptor.js35
-rw-r--r--js/src/tests/non262/object/getOwnPropertySymbols-proxy.js28
-rw-r--r--js/src/tests/non262/object/getOwnPropertySymbols.js46
-rw-r--r--js/src/tests/non262/object/getPrototypeOf-array.js32
-rw-r--r--js/src/tests/non262/object/getPrototypeOf.js22
-rw-r--r--js/src/tests/non262/object/getter-name.js10
-rw-r--r--js/src/tests/non262/object/hasOwn.js18
-rw-r--r--js/src/tests/non262/object/isExtensible.js21
-rw-r--r--js/src/tests/non262/object/isFrozen.js21
-rw-r--r--js/src/tests/non262/object/isPrototypeOf.js86
-rw-r--r--js/src/tests/non262/object/isSealed.js21
-rw-r--r--js/src/tests/non262/object/keys.js23
-rw-r--r--js/src/tests/non262/object/method-non-constructor.js12
-rw-r--r--js/src/tests/non262/object/mutation-prevention-methods.js124
-rw-r--r--js/src/tests/non262/object/object-create-with-primitive-second-arg.js8
-rw-r--r--js/src/tests/non262/object/object-toString-01.js46
-rw-r--r--js/src/tests/non262/object/preventExtensions-idempotent.js30
-rw-r--r--js/src/tests/non262/object/preventExtensions-proxy.js23
-rw-r--r--js/src/tests/non262/object/preventExtensions.js21
-rw-r--r--js/src/tests/non262/object/property-descriptor-order.js17
-rw-r--r--js/src/tests/non262/object/propertyIsEnumerable-proxy.js59
-rw-r--r--js/src/tests/non262/object/propertyIsEnumerable.js199
-rw-r--r--js/src/tests/non262/object/proto-property-change-writability-set.js56
-rw-r--r--js/src/tests/non262/object/regress-137000.js203
-rw-r--r--js/src/tests/non262/object/regress-192105.js146
-rw-r--r--js/src/tests/non262/object/regress-308806-01.js20
-rw-r--r--js/src/tests/non262/object/regress-338709.js74
-rw-r--r--js/src/tests/non262/object/regress-361274.js30
-rw-r--r--js/src/tests/non262/object/regress-382503.js29
-rw-r--r--js/src/tests/non262/object/regress-382532.js33
-rw-r--r--js/src/tests/non262/object/regress-385393-07.js31
-rw-r--r--js/src/tests/non262/object/regress-444787.js101
-rw-r--r--js/src/tests/non262/object/regress-459405.js37
-rw-r--r--js/src/tests/non262/object/regress-465476.js60
-rw-r--r--js/src/tests/non262/object/regress-72773.js60
-rw-r--r--js/src/tests/non262/object/regress-79129-001.js44
-rw-r--r--js/src/tests/non262/object/regress-90596-003.js275
-rw-r--r--js/src/tests/non262/object/seal-proxy.js27
-rw-r--r--js/src/tests/non262/object/seal.js21
-rw-r--r--js/src/tests/non262/object/setPrototypeOf-cross-realm-cycle.js11
-rw-r--r--js/src/tests/non262/object/setPrototypeOf-cycle.js16
-rw-r--r--js/src/tests/non262/object/setPrototypeOf-same-value.js11
-rw-r--r--js/src/tests/non262/object/shell.js62
-rw-r--r--js/src/tests/non262/object/toLocaleString-01.js13
-rw-r--r--js/src/tests/non262/object/toLocaleString.js102
-rw-r--r--js/src/tests/non262/object/toPrimitive-callers.js57
-rw-r--r--js/src/tests/non262/object/toPrimitive.js101
-rw-r--r--js/src/tests/non262/object/vacuous-accessor-unqualified-name.js26
-rw-r--r--js/src/tests/non262/object/values-entries-indexed.js71
-rw-r--r--js/src/tests/non262/object/values-entries-lazy-props.js93
-rw-r--r--js/src/tests/non262/object/values-entries-typedarray.js53
-rw-r--r--js/src/tests/non262/object/values.js94
133 files changed, 6658 insertions, 0 deletions
diff --git a/js/src/tests/non262/object/15.2.3.12.js b/js/src/tests/non262/object/15.2.3.12.js
new file mode 100644
index 0000000000..00593a2409
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.12.js
@@ -0,0 +1,46 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+/* Object.isFrozen */
+
+assertEq(Object.isFrozen({}), false);
+
+assertEq(Object.isFrozen(Object.preventExtensions({})), true);
+
+var o = Object.defineProperty({}, 'x', { writable:true, configurable:true });
+Object.preventExtensions(o);
+assertEq(Object.isFrozen(o), false);
+
+var o = Object.defineProperty({}, 'x', { writable:false, configurable:true });
+Object.preventExtensions(o);
+assertEq(Object.isFrozen(o), false);
+
+var o = Object.defineProperty({}, 'x', { writable:true, configurable:false });
+Object.preventExtensions(o);
+assertEq(Object.isFrozen(o), false);
+
+var o = Object.defineProperty({}, 'x', { writable:false, configurable:false });
+assertEq(Object.isFrozen(o), false);
+
+var o = Object.defineProperty({}, 'x', { writable:false, configurable:false });
+Object.preventExtensions(o);
+assertEq(Object.isFrozen(o), true);
+
+var o = Object.defineProperties({}, { x: { writable:true, configurable:true },
+ y: { writable:false, configurable:false } });
+Object.preventExtensions(o);
+assertEq(Object.isFrozen(o), false);
+
+var o = Object.defineProperties({}, { x: { writable:false, configurable:false },
+ y: { writable:true, configurable:true } });
+Object.preventExtensions(o);
+assertEq(Object.isFrozen(o), false);
+
+var o = Object.defineProperties({}, { x: { writable:true, configurable:true },
+ y: { writable:true, configurable:true } });
+Object.preventExtensions(o);
+assertEq(Object.isFrozen(o), false);
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/object/15.2.3.14-01.js b/js/src/tests/non262/object/15.2.3.14-01.js
new file mode 100644
index 0000000000..6cb8965a6c
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.14-01.js
@@ -0,0 +1,92 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 307791;
+var summary = 'ES5 Object.keys(O)';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus(summary);
+
+function arraysEqual(a1, a2)
+{
+ return a1.length === a2.length &&
+ a1.every(function(v, i) { return v === a2[i]; });
+}
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+assertEq(Object.keys.length, 1);
+
+var o, keys;
+
+o = { a: 3, b: 2 };
+keys = Object.keys(o);
+assertEq(arraysEqual(keys, ["a", "b"]), true,
+ "" + keys);
+
+o = { get a() { return 17; }, b: 2 };
+keys = Object.keys(o),
+assertEq(arraysEqual(keys, ["a", "b"]), true,
+ "" + keys);
+
+o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } };
+keys = Object.keys(o);
+assertEq(arraysEqual(keys, ["__iterator__"]), true,
+ "" + keys);
+
+o = { a: 1, b: 2 };
+delete o.a;
+o.a = 3;
+keys = Object.keys(o);
+assertEq(arraysEqual(keys, ["b", "a"]), true,
+ "" + keys);
+
+o = [0, 1, 2];
+keys = Object.keys(o);
+assertEq(arraysEqual(keys, ["0", "1", "2"]), true,
+ "" + keys);
+
+o = /./.exec("abc");
+keys = Object.keys(o);
+assertEq(arraysEqual(keys, ["0", "index", "input", "groups"]), true,
+ "" + keys);
+
+o = { a: 1, b: 2, c: 3 };
+delete o.b;
+o.b = 5;
+keys = Object.keys(o);
+assertEq(arraysEqual(keys, ["a", "c", "b"]), true,
+ "" + keys);
+
+function f() { }
+f.prototype.p = 1;
+o = new f();
+o.g = 1;
+keys = Object.keys(o);
+assertEq(arraysEqual(keys, ["g"]), true,
+ "" + keys);
+
+if (typeof Namespace !== "undefined" && typeof QName !== "undefined")
+{
+ var o2 = {};
+ var qn = new QName(new Namespace("foo"), "v");
+ o2.f = 1;
+ o2[qn] = 3;
+ o2.baz = 4;
+ var keys2 = Object.keys(o2);
+ assertEq(arraysEqual(keys2, ["f", "foo::v", "baz"]), true,
+ "" + keys2);
+}
+
+/******************************************************************************/
+
+reportCompare(expect, actual, "Object.keys");
+
+printStatus("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.3-01.js b/js/src/tests/non262/object/15.2.3.3-01.js
new file mode 100644
index 0000000000..ed94a14f4a
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.3-01.js
@@ -0,0 +1,285 @@
+/* -*- 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 = 505587;
+var summary = 'ES5 Object.getOwnPropertyDescriptor(O)';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function assertEq(a, e, msg)
+{
+ function SameValue(v1, v2)
+ {
+ if (v1 === 0 && v2 === 0)
+ return 1 / v1 === 1 / v2;
+ if (v1 !== v1 && v2 !== v2)
+ return true;
+ return v1 === v2;
+ }
+
+ if (!SameValue(a, e))
+ {
+ var stack = new Error().stack || "";
+ throw "Assertion failed: got " + a + ", expected " + e +
+ (msg ? ": " + msg : "") +
+ (stack ? "\nStack:\n" + stack : "");
+ }
+}
+
+function expectDescriptor(actual, expected)
+{
+ if (actual === undefined && expected === undefined)
+ return;
+
+ assertEq(typeof actual, "object");
+ assertEq(typeof expected, "object");
+
+ var fields =
+ {
+ value: true,
+ get: true,
+ set: true,
+ enumerable: true,
+ writable: true,
+ configurable: true
+ };
+ for (var p in fields)
+ assertEq(actual.hasOwnProperty(p), expected.hasOwnProperty(p), p);
+ for (var p in actual)
+ assertEq(p in fields, true, p);
+ for (var p in expected)
+ assertEq(p in fields, true, p);
+
+ assertEq(actual.hasOwnProperty("value"), actual.hasOwnProperty("writable"));
+ assertEq(actual.hasOwnProperty("get"), actual.hasOwnProperty("set"));
+ if (actual.hasOwnProperty("value"))
+ {
+ assertEq(actual.value, expected.value);
+ assertEq(actual.writable, expected.writable);
+ }
+ else
+ {
+ assertEq(actual.get, expected.get);
+ assertEq(actual.set, expected.set);
+ }
+
+ assertEq(actual.hasOwnProperty("enumerable"), true);
+ assertEq(actual.hasOwnProperty("configurable"), true);
+ assertEq(actual.enumerable, expected.enumerable);
+ assertEq(actual.configurable, expected.configurable);
+}
+
+function adjustDescriptorField(o, actual, expect, field)
+{
+ assertEq(field === "get" || field === "set", true);
+ var lookup = "__lookup" + (field === "get" ? "G" : "S") + "etter";
+ if (typeof o[lookup] === "function")
+ expect[field] = o[lookup](field);
+ else
+ actual[field] = expect[field] = undefined; /* censor if we can't lookup */
+}
+
+/******************************************************************************/
+
+var o, pd, expected;
+
+o = { get x() { return 12; } };
+
+pd = Object.getOwnPropertyDescriptor(o, "x");
+expected =
+ {
+ set: undefined,
+ enumerable: true,
+ configurable: true
+ };
+adjustDescriptorField(o, pd, expected, "get");
+
+expectDescriptor(pd, expected);
+
+/******************************************************************************/
+
+var o2;
+
+o = Object.create(Object.prototype, { x: {get: function () { return 12; } } });
+
+pd = Object.getOwnPropertyDescriptor(o, "x");
+expected =
+ {
+ set: undefined,
+ enumerable: false,
+ configurable: false
+ };
+adjustDescriptorField(o, pd, expected, "get");
+
+expectDescriptor(pd, expected);
+
+o2 = Object.create(o);
+assertEq(Object.getOwnPropertyDescriptor(o2, "x"), undefined);
+
+/******************************************************************************/
+
+o = {};
+o.b = 12;
+
+pd = Object.getOwnPropertyDescriptor(o, "b");
+expected =
+ {
+ value: 12,
+ writable: true,
+ enumerable: true,
+ configurable: true
+ };
+expectDescriptor(pd, expected);
+
+/******************************************************************************/
+
+o = { get y() { return 17; }, set y(z) { } };
+
+pd = Object.getOwnPropertyDescriptor(o, "y");
+expected =
+ {
+ enumerable: true,
+ configurable: true
+ };
+adjustDescriptorField(o, pd, expected, "get");
+adjustDescriptorField(o, pd, expected, "set");
+
+expectDescriptor(pd, expected);
+
+/******************************************************************************/
+
+o = {};
+
+pd = Object.getOwnPropertyDescriptor(o, "absent");
+
+expectDescriptor(pd, undefined);
+
+/******************************************************************************/
+
+pd = Object.getOwnPropertyDescriptor([], "length");
+expected =
+ {
+ value: 0,
+ writable: true,
+ enumerable: false,
+ configurable: false
+ };
+
+expectDescriptor(pd, expected);
+
+pd = Object.getOwnPropertyDescriptor([1], "length");
+expected =
+ {
+ value: 1,
+ writable: true,
+ enumerable: false,
+ configurable: false
+ };
+
+expectDescriptor(pd, expected);
+
+pd = Object.getOwnPropertyDescriptor([1,], "length");
+expected =
+ {
+ value: 1,
+ writable: true,
+ enumerable: false,
+ configurable: false
+ };
+
+expectDescriptor(pd, expected);
+
+pd = Object.getOwnPropertyDescriptor([1,,], "length");
+expected =
+ {
+ value: 2,
+ writable: true,
+ enumerable: false,
+ configurable: false
+ };
+
+expectDescriptor(pd, expected);
+
+/******************************************************************************/
+
+pd = Object.getOwnPropertyDescriptor(new String("foobar"), "length");
+expected =
+ {
+ value: 6,
+ writable: false,
+ enumerable: false,
+ configurable: false
+ };
+
+expectDescriptor(pd, expected);
+
+/******************************************************************************/
+
+function foo() { }
+o = foo;
+
+pd = Object.getOwnPropertyDescriptor(o, "length");
+expected =
+ {
+ value: 0,
+ writable: false,
+ enumerable: false,
+ configurable: true
+ };
+
+expectDescriptor(pd, expected);
+
+pd = Object.getOwnPropertyDescriptor(o, "prototype");
+expected =
+ {
+ value: foo.prototype,
+ writable: true,
+ enumerable: false,
+ configurable: false
+ };
+
+expectDescriptor(pd, expected);
+
+/******************************************************************************/
+
+pd = Object.getOwnPropertyDescriptor(Function, "length");
+expected =
+ {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true
+ };
+
+expectDescriptor(pd, expected);
+
+/******************************************************************************/
+
+o = /foo/im;
+
+pd = Object.getOwnPropertyDescriptor(o, "lastIndex");
+expected =
+ {
+ value: 0,
+ writable: true,
+ enumerable: false,
+ configurable: false
+ };
+
+expectDescriptor(pd, expected);
+
+/******************************************************************************/
+
+reportCompare(expect, actual, "Object.getOwnPropertyDescriptor");
+
+printStatus("All tests passed");
diff --git a/js/src/tests/non262/object/15.2.3.4-01.js b/js/src/tests/non262/object/15.2.3.4-01.js
new file mode 100644
index 0000000000..3a84f0b667
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.4-01.js
@@ -0,0 +1,30 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 518663;
+var summary =
+ 'Object.getOwnPropertyNames should play nicely with enumerator caching';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+for (var p in JSON);
+var names = Object.getOwnPropertyNames(JSON);
+assertEq(names.length >= 2, true,
+ "wrong number of property names? [" + names + "]");
+assertEq(names.indexOf("parse") >= 0, true);
+assertEq(names.indexOf("stringify") >= 0, true);
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.4-02.js b/js/src/tests/non262/object/15.2.3.4-02.js
new file mode 100644
index 0000000000..b5e0842c26
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.4-02.js
@@ -0,0 +1,52 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 518663;
+var summary = 'Object.getOwnPropertyNames: array objects';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var a, names, expected;
+
+function arraysEqual(a1, a2)
+{
+ return a1.length === a2.length &&
+ a1.every(function(v, i) { return v === a2[i]; });
+}
+
+
+a = [0, 1, 2];
+
+names = Object.getOwnPropertyNames(a).sort();
+expected = ["0", "1", "2", "length"].sort();
+
+a = [1, , , 7];
+a.p = 2;
+Object.defineProperty(a, "q", { value: 42, enumerable: false });
+
+names = Object.getOwnPropertyNames(a).sort();
+expected = ["0", "3", "p", "q", "length"].sort();
+assertEq(arraysEqual(names, expected), true);
+
+
+a = [];
+
+names = Object.getOwnPropertyNames(a).sort();
+expected = ["length"];
+assertEq(arraysEqual(names, expected), true);
+
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.4-03.js b/js/src/tests/non262/object/15.2.3.4-03.js
new file mode 100644
index 0000000000..55dcc139c5
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.4-03.js
@@ -0,0 +1,55 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 518663;
+var summary = 'Object.getOwnPropertyNames: function objects';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function two(a, b) { }
+
+assertEq(Object.getOwnPropertyNames(two).indexOf("length") >= 0, true);
+
+var bound0 = Function.prototype.bind
+ ? two.bind("this")
+ : function two(a, b) { };
+
+assertEq(Object.getOwnPropertyNames(bound0).indexOf("length") >= 0, true);
+assertEq(bound0.length, 2);
+
+var bound1 = Function.prototype.bind
+ ? two.bind("this", 1)
+ : function one(a) { };
+
+assertEq(Object.getOwnPropertyNames(bound1).indexOf("length") >= 0, true);
+assertEq(bound1.length, 1);
+
+var bound2 = Function.prototype.bind
+ ? two.bind("this", 1, 2)
+ : function zero() { };
+
+assertEq(Object.getOwnPropertyNames(bound2).indexOf("length") >= 0, true);
+assertEq(bound2.length, 0);
+
+var bound3 = Function.prototype.bind
+ ? two.bind("this", 1, 2, 3)
+ : function zero() { };
+
+assertEq(Object.getOwnPropertyNames(bound3).indexOf("length") >= 0, true);
+assertEq(bound3.length, 0);
+
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.4-04.js b/js/src/tests/non262/object/15.2.3.4-04.js
new file mode 100644
index 0000000000..2561c7affc
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.4-04.js
@@ -0,0 +1,31 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 518663;
+var summary = 'Object.getOwnPropertyNames: regular expression objects';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var actual = Object.getOwnPropertyNames(/a/);
+var expected = ["lastIndex"];
+
+for (var i = 0; i < expected.length; i++)
+{
+ reportCompare(actual.indexOf(expected[i]) >= 0, true,
+ expected[i] + " should be a property name on a RegExp");
+}
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.5-01.js b/js/src/tests/non262/object/15.2.3.5-01.js
new file mode 100644
index 0000000000..70cfd64f59
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.5-01.js
@@ -0,0 +1,60 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 492840;
+var summary = 'ES5 Object.create(O [, Properties])';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+assertEq("create" in Object, true);
+assertEq(Object.create.length, 2);
+
+var o, desc, props, proto;
+
+o = Object.create(null);
+assertEq(Object.getPrototypeOf(o), null, "bad null-proto");
+
+o = Object.create(null, { a: { value: 17, enumerable: false } });
+assertEq(Object.getPrototypeOf(o), null, "bad null-proto");
+assertEq("a" in o, true);
+desc = Object.getOwnPropertyDescriptor(o, "a");
+assertEq(desc !== undefined, true, "no descriptor?");
+assertEq(desc.value, 17);
+assertEq(desc.enumerable, false);
+assertEq(desc.configurable, false);
+assertEq(desc.writable, false);
+
+props = Object.create({ bar: 15 });
+Object.defineProperty(props, "foo", { enumerable: false, value: 42 });
+proto = { baz: 12 };
+o = Object.create(proto, props);
+assertEq(Object.getPrototypeOf(o), proto);
+assertEq(Object.getOwnPropertyDescriptor(o, "foo"), undefined);
+assertEq("foo" in o, false);
+assertEq(Object.getOwnPropertyDescriptor(o, "bar"), undefined);
+assertEq("bar" in o, false);
+assertEq(Object.getOwnPropertyDescriptor(o, "baz"), undefined);
+assertEq(o.baz, 12);
+assertEq(o.hasOwnProperty("baz"), false);
+
+try {
+ var actual =
+ Object.create(Object.create({},
+ { boom: { get: function() { return "base"; }}}),
+ { boom: { get: function() { return "overridden"; }}}).boom
+} catch (e) {
+}
+assertEq(actual, "overridden");
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.6-define-over-method.js b/js/src/tests/non262/object/15.2.3.6-define-over-method.js
new file mode 100644
index 0000000000..1cc9e13e14
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-define-over-method.js
@@ -0,0 +1,24 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 568786;
+var summary =
+ 'Do not assert: !(attrs & (JSPROP_GETTER | JSPROP_SETTER)) with ' +
+ 'Object.defineProperty';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var o = { x: function(){} };
+Object.defineProperty(o, "x", { get: function(){} });
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-01-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-01-of-32.js
new file mode 100644
index 0000000000..aea3a41f92
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-01-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(1, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-02-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-02-of-32.js
new file mode 100644
index 0000000000..833ecfe937
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-02-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(2, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-03-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-03-of-32.js
new file mode 100644
index 0000000000..2f4673c49d
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-03-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(3, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-04-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-04-of-32.js
new file mode 100644
index 0000000000..7b2b89c878
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-04-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(4, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-05-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-05-of-32.js
new file mode 100644
index 0000000000..87bed4dbe2
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-05-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(5, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-06-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-06-of-32.js
new file mode 100644
index 0000000000..16b16d22d6
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-06-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(6, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-07-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-07-of-32.js
new file mode 100644
index 0000000000..2a0509c30a
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-07-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(7, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-08-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-08-of-32.js
new file mode 100644
index 0000000000..7d49565b44
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-08-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(8, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-09-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-09-of-32.js
new file mode 100644
index 0000000000..cf8e39e658
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-09-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(9, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-10-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-10-of-32.js
new file mode 100644
index 0000000000..a65d17dff1
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-10-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(10, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-11-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-11-of-32.js
new file mode 100644
index 0000000000..60e07c1c28
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-11-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(11, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-12-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-12-of-32.js
new file mode 100644
index 0000000000..69045d0d1d
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-12-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(12, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-13-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-13-of-32.js
new file mode 100644
index 0000000000..95d39424ee
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-13-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(13, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-14-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-14-of-32.js
new file mode 100644
index 0000000000..58bdb5e9f5
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-14-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(14, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-15-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-15-of-32.js
new file mode 100644
index 0000000000..5828adec23
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-15-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(15, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-16-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-16-of-32.js
new file mode 100644
index 0000000000..6e797312d8
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-16-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(16, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-17-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-17-of-32.js
new file mode 100644
index 0000000000..f2dbb6ae9a
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-17-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(17, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-18-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-18-of-32.js
new file mode 100644
index 0000000000..f062ceabf8
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-18-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(18, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-19-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-19-of-32.js
new file mode 100644
index 0000000000..96310b7bd7
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-19-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(19, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-20-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-20-of-32.js
new file mode 100644
index 0000000000..9c3c52a25f
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-20-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(20, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-21-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-21-of-32.js
new file mode 100644
index 0000000000..e3f99899f2
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-21-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(21, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-22-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-22-of-32.js
new file mode 100644
index 0000000000..85d6cf9645
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-22-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(22, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-23-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-23-of-32.js
new file mode 100644
index 0000000000..a1a8d40e3f
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-23-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(23, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-24-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-24-of-32.js
new file mode 100644
index 0000000000..ff561a5dd3
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-24-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(24, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-25-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-25-of-32.js
new file mode 100644
index 0000000000..0748343eec
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-25-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(25, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-26-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-26-of-32.js
new file mode 100644
index 0000000000..4ab28fe386
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-26-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(26, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-27-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-27-of-32.js
new file mode 100644
index 0000000000..f97d13b8f9
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-27-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(27, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-28-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-28-of-32.js
new file mode 100644
index 0000000000..1d28e785aa
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-28-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(28, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-29-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-29-of-32.js
new file mode 100644
index 0000000000..3d72404a0c
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-29-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(29, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-30-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-30-of-32.js
new file mode 100644
index 0000000000..d5ec96f312
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-30-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(30, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-31-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-31-of-32.js
new file mode 100644
index 0000000000..182499268c
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-31-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(31, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-32-of-32.js b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-32-of-32.js
new file mode 100644
index 0000000000..6f78157b59
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-dictionary-redefinition-32-of-32.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runDictionaryPropertyPresentTestsFraction(32, 32);
diff --git a/js/src/tests/non262/object/15.2.3.6-function-length.js b/js/src/tests/non262/object/15.2.3.6-function-length.js
new file mode 100644
index 0000000000..ddbb7b9f88
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-function-length.js
@@ -0,0 +1,35 @@
+// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 430133;
+var summary = 'ES5 Object.defineProperty(O, P, Attributes): Function.length';
+
+print(BUGNUMBER + ": " + summary);
+
+loadRelativeToScript("defineProperty-setup.js");
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ new TestRunner().runFunctionLengthTests();
+}
+catch (e)
+{
+ throw "Error thrown during testing: " + e +
+ " at line " + e.lineNumber + "\n" +
+ (e.stack
+ ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
+ : "");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete!");
diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-1-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-1-of-8.js
new file mode 100644
index 0000000000..2b693853ed
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-1-of-8.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runNonTerminalPropertyPresentTestsFraction(1, 8);
diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-2-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-2-of-8.js
new file mode 100644
index 0000000000..483485ab22
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-2-of-8.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runNonTerminalPropertyPresentTestsFraction(2, 8);
diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-3-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-3-of-8.js
new file mode 100644
index 0000000000..8dd876e1f6
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-3-of-8.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runNonTerminalPropertyPresentTestsFraction(3, 8);
diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-4-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-4-of-8.js
new file mode 100644
index 0000000000..14a2f0907f
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-4-of-8.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runNonTerminalPropertyPresentTestsFraction(4, 8);
diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-5-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-5-of-8.js
new file mode 100644
index 0000000000..d671a8ce49
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-5-of-8.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runNonTerminalPropertyPresentTestsFraction(5, 8);
diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-6-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-6-of-8.js
new file mode 100644
index 0000000000..5ff5922429
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-6-of-8.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runNonTerminalPropertyPresentTestsFraction(6, 8);
diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-7-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-7-of-8.js
new file mode 100644
index 0000000000..4a792d2f34
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-7-of-8.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runNonTerminalPropertyPresentTestsFraction(7, 8);
diff --git a/js/src/tests/non262/object/15.2.3.6-middle-redefinition-8-of-8.js b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-8-of-8.js
new file mode 100644
index 0000000000..8cea528150
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-middle-redefinition-8-of-8.js
@@ -0,0 +1,6 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+loadRelativeToScript("defineProperty-setup.js");
+runNonTerminalPropertyPresentTestsFraction(8, 8);
diff --git a/js/src/tests/non262/object/15.2.3.6-miscellaneous.js b/js/src/tests/non262/object/15.2.3.6-miscellaneous.js
new file mode 100644
index 0000000000..9f671c52ce
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-miscellaneous.js
@@ -0,0 +1,74 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 430133;
+var summary = 'ES5 Object.defineProperty(O, P, Attributes)';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var o = [];
+Object.defineProperty(o, 0, { value: 17 });
+var desc = Object.getOwnPropertyDescriptor(o, 0);
+assertEq(desc !== undefined, true);
+assertEq(desc.value, 17);
+assertEq(desc.enumerable, false);
+assertEq(desc.configurable, false);
+assertEq(desc.writable, false);
+
+desc = Object.getOwnPropertyDescriptor(o, "length");
+assertEq(desc !== undefined, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.configurable, false);
+assertEq(desc.writable, true);
+assertEq(desc.value, 1);
+assertEq(o.length, 1);
+
+Object.defineProperty(o, "foobar",
+ { value: 42, enumerable: false, configurable: true });
+assertEq(o.foobar, 42);
+desc = Object.getOwnPropertyDescriptor(o, "foobar");
+assertEq(desc !== undefined, true);
+assertEq(desc.value, 42);
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, false);
+
+var called = false;
+o = { set x(a) { called = true; } };
+Object.defineProperty(o, "x", { get: function() { return "get"; } });
+desc = Object.getOwnPropertyDescriptor(o, "x");
+assertEq("set" in desc, true);
+assertEq("get" in desc, true);
+assertEq(called, false);
+o.x = 13;
+assertEq(called, true);
+
+var toSource = Object.prototype.toSource || function() { };
+toSource.call(o); // a test for this not crashing
+
+var called = false;
+var o =
+ Object.defineProperty({}, "foo",
+ { get: function() { return 17; },
+ set: function(v) { called = true; } });
+
+assertEq(o.foo, 17);
+o.foo = 42;
+assertEq(called, true);
+
+/*
+ * XXX need tests for Object.defineProperty(array, "length", { ... }) when we
+ * support it!
+ */
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.6-new-definition.js b/js/src/tests/non262/object/15.2.3.6-new-definition.js
new file mode 100644
index 0000000000..7f938203e9
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-new-definition.js
@@ -0,0 +1,35 @@
+// |reftest| skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 430133;
+var summary = 'ES5 Object.defineProperty(O, P, Attributes): new definition';
+
+print(BUGNUMBER + ": " + summary);
+
+loadRelativeToScript("defineProperty-setup.js");
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ new TestRunner().runNotPresentTests();
+}
+catch (e)
+{
+ throw "Error thrown during testing: " + e +
+ " at line " + e.lineNumber + "\n" +
+ (e.stack
+ ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
+ : "");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete!");
diff --git a/js/src/tests/non262/object/15.2.3.6-redefinition-1-of-4.js b/js/src/tests/non262/object/15.2.3.6-redefinition-1-of-4.js
new file mode 100644
index 0000000000..d826a77551
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-redefinition-1-of-4.js
@@ -0,0 +1,39 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var PART = 1, PARTS = 4;
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 430133;
+var summary =
+ 'ES5 Object.defineProperty(O, P, Attributes): redefinition ' +
+ PART + ' of ' + PARTS;
+
+print(BUGNUMBER + ": " + summary);
+
+loadRelativeToScript("defineProperty-setup.js");
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ new TestRunner().runPropertyPresentTestsFraction(PART, PARTS);
+}
+catch (e)
+{
+ throw "Error thrown during testing: " + e +
+ " at line " + e.lineNumber + "\n" +
+ (e.stack
+ ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
+ : "");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete!");
diff --git a/js/src/tests/non262/object/15.2.3.6-redefinition-2-of-4.js b/js/src/tests/non262/object/15.2.3.6-redefinition-2-of-4.js
new file mode 100644
index 0000000000..78f862cb7e
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-redefinition-2-of-4.js
@@ -0,0 +1,39 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var PART = 2, PARTS = 4;
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 430133;
+var summary =
+ 'ES5 Object.defineProperty(O, P, Attributes): redefinition ' +
+ PART + ' of ' + PARTS;
+
+print(BUGNUMBER + ": " + summary);
+
+loadRelativeToScript("defineProperty-setup.js");
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ new TestRunner().runPropertyPresentTestsFraction(PART, PARTS);
+}
+catch (e)
+{
+ throw "Error thrown during testing: " + e +
+ " at line " + e.lineNumber + "\n" +
+ (e.stack
+ ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
+ : "");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete!");
diff --git a/js/src/tests/non262/object/15.2.3.6-redefinition-3-of-4.js b/js/src/tests/non262/object/15.2.3.6-redefinition-3-of-4.js
new file mode 100644
index 0000000000..0458a79577
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-redefinition-3-of-4.js
@@ -0,0 +1,39 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var PART = 3, PARTS = 4;
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 430133;
+var summary =
+ 'ES5 Object.defineProperty(O, P, Attributes): redefinition ' +
+ PART + ' of ' + PARTS;
+
+print(BUGNUMBER + ": " + summary);
+
+loadRelativeToScript("defineProperty-setup.js");
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ new TestRunner().runPropertyPresentTestsFraction(PART, PARTS);
+}
+catch (e)
+{
+ throw "Error thrown during testing: " + e +
+ " at line " + e.lineNumber + "\n" +
+ (e.stack
+ ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
+ : "");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete!");
diff --git a/js/src/tests/non262/object/15.2.3.6-redefinition-4-of-4.js b/js/src/tests/non262/object/15.2.3.6-redefinition-4-of-4.js
new file mode 100644
index 0000000000..8aa6d0a95a
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.6-redefinition-4-of-4.js
@@ -0,0 +1,39 @@
+// |reftest| slow skip-if(!xulRuntime.shell) -- uses shell load() function
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var PART = 4, PARTS = 4;
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 430133;
+var summary =
+ 'ES5 Object.defineProperty(O, P, Attributes): redefinition ' +
+ PART + ' of ' + PARTS;
+
+print(BUGNUMBER + ": " + summary);
+
+loadRelativeToScript("defineProperty-setup.js");
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ new TestRunner().runPropertyPresentTestsFraction(PART, PARTS);
+}
+catch (e)
+{
+ throw "Error thrown during testing: " + e +
+ " at line " + e.lineNumber + "\n" +
+ (e.stack
+ ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
+ : "");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete!");
diff --git a/js/src/tests/non262/object/15.2.3.7-01.js b/js/src/tests/non262/object/15.2.3.7-01.js
new file mode 100644
index 0000000000..5220e1483f
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.7-01.js
@@ -0,0 +1,137 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 430133;
+var summary = 'ES5 Object.defineProperties(O, Properties)';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+assertEq("defineProperties" in Object, true);
+assertEq(Object.defineProperties.length, 2);
+
+var o, props, desc, passed;
+
+o = {};
+props =
+ {
+ a: { value: 17, enumerable: true, configurable: true, writable: true },
+ b: { value: 42, enumerable: false, configurable: false, writable: false }
+ };
+Object.defineProperties(o, props);
+assertEq("a" in o, true);
+assertEq("b" in o, true);
+desc = Object.getOwnPropertyDescriptor(o, "a");
+assertEq(desc.value, 17);
+assertEq(desc.enumerable, true);
+assertEq(desc.configurable, true);
+assertEq(desc.writable, true);
+desc = Object.getOwnPropertyDescriptor(o, "b");
+assertEq(desc.value, 42);
+assertEq(desc.enumerable, false);
+assertEq(desc.configurable, false);
+assertEq(desc.writable, false);
+
+props =
+ {
+ c: { value: NaN, enumerable: false, configurable: true, writable: true },
+ b: { value: 44 }
+ };
+var error = "before";
+try
+{
+ Object.defineProperties(o, props);
+ error = "no exception thrown";
+}
+catch (e)
+{
+ if (e instanceof TypeError)
+ error = "typeerror";
+ else
+ error = "bad exception: " + e;
+}
+assertEq(error, "typeerror", "didn't throw or threw wrongly");
+assertEq("c" in o, true, "new property added");
+assertEq(o.b, 42, "old property value preserved");
+
+function Properties() { }
+Properties.prototype = { b: { value: 42, enumerable: true } };
+props = new Properties();
+Object.defineProperty(props, "a", { enumerable: false });
+o = {};
+Object.defineProperties(o, props);
+assertEq("a" in o, false);
+assertEq(Object.getOwnPropertyDescriptor(o, "a"), undefined,
+ "Object.defineProperties(O, Properties) should only use enumerable " +
+ "properties on Properties");
+assertEq("b" in o, false);
+assertEq(Object.getOwnPropertyDescriptor(o, "b"), undefined,
+ "Object.defineProperties(O, Properties) should only use enumerable " +
+ "properties directly on Properties");
+
+Number.prototype.foo = { value: 17, enumerable: true };
+Boolean.prototype.bar = { value: 8675309, enumerable: true };
+String.prototype.quux = { value: "Are you HAPPY yet?", enumerable: true };
+o = {};
+Object.defineProperties(o, 5); // ToObject only throws for null/undefined
+assertEq("foo" in o, false, "foo is not an enumerable own property");
+Object.defineProperties(o, false);
+assertEq("bar" in o, false, "bar is not an enumerable own property");
+Object.defineProperties(o, "");
+assertEq("quux" in o, false, "quux is not an enumerable own property");
+
+error = "before";
+try
+{
+ Object.defineProperties(o, "1");
+}
+catch (e)
+{
+ if (e instanceof TypeError)
+ error = "typeerror";
+ else
+ error = "bad exception: " + e;
+}
+assertEq(error, "typeerror",
+ "should throw on Properties == '1' due to '1'[0] not being a " +
+ "property descriptor");
+
+error = "before";
+try
+{
+ Object.defineProperties(o, null);
+}
+catch (e)
+{
+ if (e instanceof TypeError)
+ error = "typeerror";
+ else
+ error = "bad exception: " + e;
+}
+assertEq(error, "typeerror", "should throw on Properties == null");
+
+error = "before";
+try
+{
+ Object.defineProperties(o, undefined);
+}
+catch (e)
+{
+ if (e instanceof TypeError)
+ error = "typeerror";
+ else
+ error = "bad exception: " + e;
+}
+assertEq(error, "typeerror", "should throw on Properties == undefined");
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/15.2.3.9.js b/js/src/tests/non262/object/15.2.3.9.js
new file mode 100644
index 0000000000..c73437fa7d
--- /dev/null
+++ b/js/src/tests/non262/object/15.2.3.9.js
@@ -0,0 +1,51 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+/* Object.freeze */
+
+function getme() { return 42; };
+function setme(x) { };
+
+var properties = { all: { value:1, writable:true, configurable:true, enumerable: true },
+ readOnly: { value:2, writable:false, configurable:true, enumerable: true },
+ nonConfig: { value:3, writable:true, configurable:false, enumerable: true },
+ none: { value:4, writable:false, configurable:false, enumerable: true },
+ getter: { get: getme, configurable:false, enumerable: true },
+ setter: { set: setme, configurable:false, enumerable: true },
+ getandset: { get: getme, set: setme, configurable:false, enumerable: true }
+ };
+var o = Object.defineProperties({}, properties);
+
+Object.freeze(o);
+
+function getPropertyOf(obj) {
+ return function (prop) {
+ return Object.getOwnPropertyDescriptor(obj, prop);
+ };
+};
+
+assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'all'),
+ { value: 1, writable:false, enumerable:true, configurable:false }),
+ true);
+assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'readOnly'),
+ { value: 2, writable:false, enumerable:true, configurable:false }),
+ true);
+assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'nonConfig'),
+ { value: 3, writable:false, enumerable:true, configurable:false }),
+ true);
+assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'none'),
+ { value: 4, writable:false, enumerable:true, configurable:false }),
+ true);
+assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'getter'),
+ { get: getme, set: (void 0), enumerable:true, configurable:false }),
+ true);
+assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'setter'),
+ { set: setme, get: (void 0), enumerable:true, configurable:false }),
+ true);
+assertEq(deepEqual(Object.getOwnPropertyDescriptor(o, 'getandset'),
+ { get: getme, set: setme, enumerable:true, configurable:false }),
+ true);
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/object/accessor-arguments-rest.js b/js/src/tests/non262/object/accessor-arguments-rest.js
new file mode 100644
index 0000000000..82f37b62e3
--- /dev/null
+++ b/js/src/tests/non262/object/accessor-arguments-rest.js
@@ -0,0 +1,24 @@
+assertThrowsInstanceOf(() => eval("({ get x(...a) { } })"), SyntaxError);
+assertThrowsInstanceOf(() => eval("({ get x(a, ...b) { } })"), SyntaxError);
+assertThrowsInstanceOf(() => eval("({ get x([a], ...b) { } })"), SyntaxError);
+assertThrowsInstanceOf(() => eval("({ get x({a}, ...b) { } })"), SyntaxError);
+assertThrowsInstanceOf(() => eval("({ get x({a: A}, ...b) { } })"), SyntaxError);
+
+assertThrowsInstanceOf(() => eval("({ set x(...a) { } })"), SyntaxError);
+assertThrowsInstanceOf(() => eval("({ set x(a, ...b) { } })"), SyntaxError);
+assertThrowsInstanceOf(() => eval("({ set x([a], ...b) { } })"), SyntaxError);
+assertThrowsInstanceOf(() => eval("({ set x({a: A}, ...b) { } })"), SyntaxError);
+
+({ get(...a) { } });
+({ get(a, ...b) { } });
+({ get([a], ...b) { } });
+({ get({a}, ...b) { } });
+({ get({a: A}, ...b) { } });
+
+({ set(...a) { } });
+({ set(a, ...b) { } });
+({ set([a], ...b) { } });
+({ set({a: A}, ...b) { } });
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/accessor-name.js b/js/src/tests/non262/object/accessor-name.js
new file mode 100644
index 0000000000..f238a2aefc
--- /dev/null
+++ b/js/src/tests/non262/object/accessor-name.js
@@ -0,0 +1,35 @@
+function name(obj, property, get) {
+ let desc = Object.getOwnPropertyDescriptor(obj, property);
+ return (get ? desc.get : desc.set).name;
+}
+
+assertEq(name({get a() {}}, "a", true), "get a");
+assertEq(name({set a(v) {}}, "a", false), "set a");
+
+assertEq(name({get 123() {}}, "123", true), "get 123");
+assertEq(name({set 123(v) {}}, "123", false), "set 123");
+
+assertEq(name({get case() {}}, "case", true), "get case");
+assertEq(name({set case(v) {}}, "case", false), "set case");
+
+assertEq(name({get get() {}}, "get", true), "get get");
+assertEq(name({set set(v) {}}, "set", false), "set set");
+
+let o = {get a() { }, set a(v) {}};
+assertEq(name(o, "a", true), "get a");
+assertEq(name(o, "a", false), "set a");
+
+o = {get 123() { }, set 123(v) {}}
+assertEq(name(o, "123", true), "get 123");
+assertEq(name(o, "123", false), "set 123");
+
+o = {get case() { }, set case(v) {}}
+assertEq(name(o, "case", true), "get case");
+assertEq(name(o, "case", false), "set case");
+
+assertEq(name({get ["a"]() {}}, "a", true), "get a");
+assertEq(name({get [123]() {}}, "123", true), "get 123");
+assertEq(name({set ["a"](v) {}}, "a", false), "set a");
+assertEq(name({set [123](v) {}}, "123", false), "set 123");
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/object/accessor-non-constructor.js b/js/src/tests/non262/object/accessor-non-constructor.js
new file mode 100644
index 0000000000..32d1d34673
--- /dev/null
+++ b/js/src/tests/non262/object/accessor-non-constructor.js
@@ -0,0 +1,20 @@
+var obj = { get a() { return 1; } };
+assertThrowsInstanceOf(() => {
+ new Object.getOwnPropertyDescriptor(obj, "a").get
+}, TypeError);
+
+obj = { set a(b) { } };
+assertThrowsInstanceOf(() => {
+ new Object.getOwnPropertyDescriptor(obj, "a").set
+}, TypeError);
+
+obj = { get a() { return 1; }, set a(b) { } };
+assertThrowsInstanceOf(() => {
+ new Object.getOwnPropertyDescriptor(obj, "a").get
+}, TypeError);
+assertThrowsInstanceOf(() => {
+ new Object.getOwnPropertyDescriptor(obj, "a").set
+}, TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/add-property-non-extensible.js b/js/src/tests/non262/object/add-property-non-extensible.js
new file mode 100644
index 0000000000..2089a5678b
--- /dev/null
+++ b/js/src/tests/non262/object/add-property-non-extensible.js
@@ -0,0 +1,118 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+var gTestfile = 'add-property-non-extensible.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 602144;
+var summary =
+ 'Properly method-compile attempted addition of properties to ' +
+ 'non-extensible objects';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// No property
+
+var o1 = {};
+for (var i = 0; i < 5; i++)
+ o1.a = 3;
+assertEq(o1.a, 3);
+
+var o2 = Object.preventExtensions({});
+for (var i = 0; i < 5; i++)
+ o2.a = 3;
+assertEq(Object.getOwnPropertyDescriptor(o2, "a"), undefined);
+
+var o3 = Object.seal({});
+for (var i = 0; i < 5; i++)
+ o3.a = 3;
+assertEq(Object.getOwnPropertyDescriptor(o3, "a"), undefined);
+
+var o4 = Object.freeze({});
+for (var i = 0; i < 5; i++)
+ o4.a = 3;
+assertEq(Object.getOwnPropertyDescriptor(o4, "a"), undefined);
+
+
+// Has property
+
+var o5 = { a: 2 };
+for (var i = 0; i < 5; i++)
+ o5.a = 3;
+assertEq(o5.a, 3);
+
+var o6 = Object.preventExtensions({ a: 2 });
+for (var i = 0; i < 5; i++)
+ o6.a = 3;
+assertEq(o6.a, 3);
+
+var o7 = Object.seal({ a: 2 });
+for (var i = 0; i < 5; i++)
+ o7.a = 3;
+assertEq(o7.a, 3);
+
+var o8 = Object.freeze({ a: 2 });
+for (var i = 0; i < 5; i++)
+ o8.a = 3;
+assertEq(o8.a, 2);
+
+
+// Extensible, hit up the prototype chain
+
+var o9 = Object.create({ a: 2 });
+for (var i = 0; i < 5; i++)
+ o9.a = 3;
+assertEq(o9.a, 3);
+
+var o10 = Object.create(Object.preventExtensions({ a: 2 }));
+for (var i = 0; i < 5; i++)
+ o10.a = 3;
+assertEq(o10.a, 3);
+
+var o11 = Object.create(Object.seal({ a: 2 }));
+for (var i = 0; i < 5; i++)
+ o11.a = 3;
+assertEq(o11.a, 3);
+
+var o12 = Object.create(Object.freeze({ a: 2 }));
+for (var i = 0; i < 5; i++)
+ o12.a = 3;
+assertEq(Object.getOwnPropertyDescriptor(o12, "a"), undefined);
+
+
+// Not extensible, hit up the prototype chain
+
+var o13 = Object.preventExtensions(Object.create({ a: 2 }));
+for (var i = 0; i < 5; i++)
+ o13.a = 3;
+assertEq(Object.getOwnPropertyDescriptor(o13, "a"), undefined);
+
+var o14 =
+ Object.preventExtensions(Object.create(Object.preventExtensions({ a: 2 })));
+for (var i = 0; i < 5; i++)
+ o14.a = 3;
+assertEq(Object.getOwnPropertyDescriptor(o14, "a"), undefined);
+
+var o15 = Object.preventExtensions(Object.create(Object.seal({ a: 2 })));
+for (var i = 0; i < 5; i++)
+ o15.a = 3;
+assertEq(Object.getOwnPropertyDescriptor(o15, "a"), undefined);
+
+var o16 = Object.preventExtensions(Object.create(Object.freeze({ a: 2 })));
+for (var i = 0; i < 5; i++)
+ o16.a = 3;
+assertEq(Object.getOwnPropertyDescriptor(o16, "a"), undefined);
+
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/assign.js b/js/src/tests/non262/object/assign.js
new file mode 100644
index 0000000000..8828bdb21c
--- /dev/null
+++ b/js/src/tests/non262/object/assign.js
@@ -0,0 +1,303 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function checkDataProperty(object, propertyKey, value, writable, enumerable, configurable) {
+ var desc = Object.getOwnPropertyDescriptor(object, propertyKey);
+ assertEq(desc === undefined, false);
+ assertEq('value' in desc, true);
+ assertEq(desc.value, value);
+ assertEq(desc.writable, writable);
+ assertEq(desc.enumerable, enumerable);
+ assertEq(desc.configurable, configurable);
+}
+
+/* 19.1.2.1 Object.assign ( target, ...sources ) */
+assertEq(Object.assign.length, 2);
+
+// Basic functionality works with multiple sources
+function basicMultipleSources() {
+ var a = {};
+ var b = { bProp : 7 };
+ var c = { cProp : 8 };
+ Object.assign(a, b, c);
+ assertEq(a.bProp, 7);
+ assertEq(a.cProp, 8);
+}
+basicMultipleSources();
+
+// Basic functionality works with symbols (Bug 1052358)
+function basicSymbols() {
+ var a = {};
+ var b = { bProp : 7 };
+ var aSymbol = Symbol("aSymbol");
+ b[aSymbol] = 22;
+ Object.assign(a, b);
+ assertEq(a.bProp, 7);
+ assertEq(a[aSymbol], 22);
+}
+basicSymbols();
+
+// Calls ToObject() for target, skips null/undefined sources, uses
+// ToObject(source) otherwise.
+function testToObject() {
+ assertThrowsInstanceOf(() => Object.assign(null, null), TypeError);
+ assertThrowsInstanceOf(() => Object.assign(), TypeError);
+ assertThrowsInstanceOf(() => Object.assign(null, {}), TypeError);
+ assertEq(Object.assign({}, null) instanceof Object, true);
+ assertEq(Object.assign({}, undefined) instanceof Object, true);
+
+ // Technically an embedding could have this as extension acting differently
+ // from ours, so a feature-test is inadequate. We can move this subtest
+ // into extensions/ if that ever matters.
+ if (typeof createIsHTMLDDA === "function") {
+ var falsyObject = createIsHTMLDDA();
+ falsyObject.foo = 7;
+
+ var obj = Object.assign({}, falsyObject);
+ assertEq(obj instanceof Object, true);
+ assertEq(obj.foo, 7);
+ }
+
+ assertEq(Object.assign(true, {}) instanceof Boolean, true);
+ assertEq(Object.assign(1, {}) instanceof Number, true);
+ assertEq(Object.assign("string", {}) instanceof String, true);
+ var o = {};
+ assertEq(Object.assign(o, {}), o);
+}
+testToObject();
+
+// Invokes [[OwnPropertyKeys]] on ToObject(source)
+function testOwnPropertyKeys() {
+ assertThrowsInstanceOf(() => Object.assign(null, new Proxy({}, {
+ getOwnPropertyNames: () => { throw new Error("not called"); }
+ })), TypeError);
+
+ var ownKeysCalled = false;
+ Object.assign({}, new Proxy({}, {
+ ownKeys: function() {
+ ownKeysCalled = true;
+ return [];
+ }
+ }));
+ assertEq(ownKeysCalled, true);
+};
+testOwnPropertyKeys();
+
+// Ensure correct property traversal
+function correctPropertyTraversal() {
+ var log = "";
+ var source = new Proxy({a: 1, b: 2}, {
+ ownKeys: () => ["b", "c", "a"],
+ getOwnPropertyDescriptor: function(t, pk) {
+ log += "#" + pk;
+ return Object.getOwnPropertyDescriptor(t, pk);
+ },
+ get: function(t, pk, r) {
+ log += "-" + pk;
+ return t[pk];
+ },
+ });
+ Object.assign({}, source);
+ assertEq(log, "#b-b#c#a-a");
+}
+correctPropertyTraversal();
+
+// Only [[Enumerable]] properties are assigned to target
+function onlyEnumerablePropertiesAssigned() {
+ var source = Object.defineProperties({}, {
+ a: {value: 1, enumerable: true},
+ b: {value: 2, enumerable: false},
+ });
+ var target = Object.assign({}, source);
+ assertEq("a" in target, true);
+ assertEq("b" in target, false);
+}
+onlyEnumerablePropertiesAssigned();
+
+
+// Enumerability is decided on-time, not before main loop (1)
+function testEnumerabilityDeterminedInLoop1()
+{
+ var getterCalled = false;
+ var sourceTarget = {
+ get a() { getterCalled = true },
+ get b() { Object.defineProperty(sourceTarget, "a", {enumerable: false}) },
+ };
+ var source = new Proxy(sourceTarget, { ownKeys: () => ["b", "a"] });
+ Object.assign({}, source);
+ assertEq(getterCalled, false);
+}
+testEnumerabilityDeterminedInLoop1();
+
+// Enumerability is decided on-time, not before main loop (2)
+function testEnumerabilityDeterminedInLoop2()
+{
+ var getterCalled = false;
+ var sourceTarget = {
+ get a() { getterCalled = true },
+ get b() { Object.defineProperty(sourceTarget, "a", {enumerable: true}) },
+ };
+ var source = new Proxy(sourceTarget, {
+ ownKeys: () => ["b", "a"]
+ });
+ Object.defineProperty(sourceTarget, "a", {enumerable: false});
+ Object.assign({}, source);
+ assertEq(getterCalled, true);
+}
+testEnumerabilityDeterminedInLoop2();
+
+// Properties are retrieved through Get() and assigned onto
+// the target as data properties, not in any sense cloned over as descriptors
+function testPropertiesRetrievedThroughGet() {
+ var getterCalled = false;
+ Object.assign({}, {get a() { getterCalled = true }});
+ assertEq(getterCalled, true);
+}
+testPropertiesRetrievedThroughGet();
+
+// Properties are retrieved through Get()
+// Properties are assigned through Put()
+function testPropertiesAssignedThroughPut() {
+ var setterCalled = false;
+ Object.assign({set a(v) { setterCalled = v }}, {a: true});
+ assertEq(setterCalled, true);
+}
+testPropertiesAssignedThroughPut();
+
+// Properties are retrieved through Get()
+// Properties are assigned through Put(): Existing property attributes are not altered
+function propertiesAssignedExistingNotAltered() {
+ var source = {a: 1, b: 2, c: 3};
+ var target = {a: 0, b: 0, c: 0};
+ Object.defineProperty(target, "a", {enumerable: false});
+ Object.defineProperty(target, "b", {configurable: false});
+ Object.defineProperty(target, "c", {enumerable: false, configurable: false});
+ Object.assign(target, source);
+ checkDataProperty(target, "a", 1, true, false, true);
+ checkDataProperty(target, "b", 2, true, true, false);
+ checkDataProperty(target, "c", 3, true, false, false);
+}
+propertiesAssignedExistingNotAltered();
+
+// Properties are retrieved through Get()
+// Properties are assigned through Put(): Throws TypeError if non-writable
+function propertiesAssignedTypeErrorNonWritable() {
+ var source = {a: 1};
+ var target = {a: 0};
+ Object.defineProperty(target, "a", {writable: false});
+ assertThrowsInstanceOf(() => Object.assign(target, source), TypeError);
+ checkDataProperty(target, "a", 0, false, true, true);
+}
+propertiesAssignedTypeErrorNonWritable();
+
+// Properties are retrieved through Get()
+// Put() creates standard properties; Property attributes from source are ignored
+function createsStandardProperties() {
+ var source = {a: 1, b: 2, c: 3, get d() { return 4 }};
+ Object.defineProperty(source, "b", {writable: false});
+ Object.defineProperty(source, "c", {configurable: false});
+ var target = Object.assign({}, source);
+ checkDataProperty(target, "a", 1, true, true, true);
+ checkDataProperty(target, "b", 2, true, true, true);
+ checkDataProperty(target, "c", 3, true, true, true);
+ checkDataProperty(target, "d", 4, true, true, true);
+}
+createsStandardProperties();
+
+// Properties created during traversal are not copied
+function propertiesCreatedDuringTraversalNotCopied() {
+ var source = {get a() { this.b = 2 }};
+ var target = Object.assign({}, source);
+ assertEq("a" in target, true);
+ assertEq("b" in target, false);
+}
+propertiesCreatedDuringTraversalNotCopied();
+
+// Properties deleted during traversal are not copied
+function testDeletePropertiesNotCopied() {
+ var source = new Proxy({
+ get a() { delete this.b },
+ b: 2,
+ }, {
+ getOwnPropertyNames: () => ["a", "b"]
+ });
+ var target = Object.assign({}, source);
+ assertEq("a" in target, true);
+ assertEq("b" in target, false);
+}
+testDeletePropertiesNotCopied();
+
+function testDeletionExposingShadowedProperty()
+{
+ var srcProto = { b: 42 };
+ var src =
+ Object.create(srcProto,
+ { a: { enumerable: true, get: function() { delete this.b; } },
+ b: { value: 2, configurable: true, enumerable: true } });
+ var source = new Proxy(src, { getOwnPropertyNames: () => ["a", "b"] });
+ var target = Object.assign({}, source);
+ assertEq("a" in target, true);
+ assertEq("b" in target, false);
+}
+testDeletionExposingShadowedProperty();
+
+// Properties first deleted and then recreated during traversal are copied (1)
+function testDeletedAndRecreatedPropertiesCopied1() {
+ var source = new Proxy({
+ get a() { delete this.c },
+ get b() { this.c = 4 },
+ c: 3,
+ }, {
+ getOwnPropertyNames: () => ["a", "b", "c"]
+ });
+ var target = Object.assign({}, source);
+ assertEq("a" in target, true);
+ assertEq("b" in target, true);
+ assertEq("c" in target, true);
+ checkDataProperty(target, "c", 4, true, true, true);
+}
+testDeletedAndRecreatedPropertiesCopied1();
+
+// Properties first deleted and then recreated during traversal are copied (2)
+function testDeletedAndRecreatedPropertiesCopied2() {
+ var source = new Proxy({
+ get a() { delete this.c },
+ get b() { this.c = 4 },
+ c: 3,
+ }, {
+ ownKeys: () => ["a", "c", "b"]
+ });
+ var target = Object.assign({}, source);
+ assertEq("a" in target, true);
+ assertEq("b" in target, true);
+ assertEq("c" in target, false);
+}
+testDeletedAndRecreatedPropertiesCopied2();
+
+// String and Symbol valued properties are copied
+function testStringAndSymbolPropertiesCopied() {
+ var keyA = "str-prop";
+ var source = {"str-prop": 1};
+ var target = Object.assign({}, source);
+ checkDataProperty(target, keyA, 1, true, true, true);
+}
+testStringAndSymbolPropertiesCopied();
+
+// Intermediate exceptions stop traversal and throw exception
+function testExceptionsDoNotStopFirstReported1() {
+ var TestError = function TestError() {};
+ var source = new Proxy({}, {
+ getOwnPropertyDescriptor: function(t, pk) {
+ assertEq(pk, "b");
+ throw new TestError();
+ },
+ ownKeys: () => ["b", "a"]
+ });
+ assertThrowsInstanceOf(() => Object.assign({}, source), TestError);
+}
+testExceptionsDoNotStopFirstReported1();
+
+
+if (typeof reportCompare == "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/browser.js b/js/src/tests/non262/object/browser.js
new file mode 100644
index 0000000000..0e57d1fcd0
--- /dev/null
+++ b/js/src/tests/non262/object/browser.js
@@ -0,0 +1,7 @@
+var GLOBAL = 'Window';
+
+function isObject(obj)
+{
+ return obj instanceof Object || obj == window;
+}
+
diff --git a/js/src/tests/non262/object/bug-1150906.js b/js/src/tests/non262/object/bug-1150906.js
new file mode 100644
index 0000000000..27403cccfe
--- /dev/null
+++ b/js/src/tests/non262/object/bug-1150906.js
@@ -0,0 +1,13 @@
+function f(x) {
+ Object.defineProperty(arguments, 0, {
+ get: function() {}
+ });
+ return arguments;
+}
+
+var obj = f(1);
+assertEq(obj[0], undefined);
+assertEq(Object.getOwnPropertyDescriptor(obj, 0).set, undefined);
+assertThrowsInstanceOf(() => { "use strict"; obj[0] = 1; }, TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/bug-1206700.js b/js/src/tests/non262/object/bug-1206700.js
new file mode 100644
index 0000000000..4918bcbec5
--- /dev/null
+++ b/js/src/tests/non262/object/bug-1206700.js
@@ -0,0 +1,10 @@
+var x = {};
+Reflect.set(x, "prop", 5, Object.prototype);
+var y = {};
+Reflect.set(y, "prop", 6, Object.prototype);
+assertEq(x.hasOwnProperty("prop"), false);
+assertEq(y.hasOwnProperty("prop"), false);
+assertEq(Object.prototype.hasOwnProperty("prop"), true);
+assertEq(Object.prototype.prop, 6);
+
+reportCompare(0, 0, "ok");
diff --git a/js/src/tests/non262/object/clear-dictionary-accessor-getset.js b/js/src/tests/non262/object/clear-dictionary-accessor-getset.js
new file mode 100644
index 0000000000..f0d9e11ca6
--- /dev/null
+++ b/js/src/tests/non262/object/clear-dictionary-accessor-getset.js
@@ -0,0 +1,55 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = "clear-dictionary-accessor-getset.js";
+var BUGNUMBER = 1082662;
+var summary =
+ "Properly handle GC of a dictionary accessor property whose [[Get]] or " +
+ "[[Set]] has been changed to |undefined|";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function test(field)
+{
+ var prop = "[[" + field[0].toUpperCase() + field.substring(1) + "]]";
+ print("Testing for GC crashes after setting " + prop + " to undefined...");
+
+ function inner()
+ {
+ // Create an object with an accessor property.
+ var obj = { x: 42, get y() {}, set y(v) {} };
+
+ // 1) convert it to dictionary mode, in the process 2) creating a new
+ // version of that accessor property whose [[Get]] and [[Set]] are objects
+ // that trigger post barriers.
+ delete obj.x;
+
+ var desc = {};
+ desc[field] = undefined;
+
+ // Overwrite [[field]] with undefined. Note #1 above is necessary so this
+ // is an actual *overwrite*, and not (possibly) a shape-tree fork that
+ // doesn't overwrite.
+ Object.defineProperty(obj, "y", desc);
+
+ }
+
+ inner();
+ gc(); // In unfixed code, this crashes trying to mark a null [[field]].
+}
+
+test("get");
+test("set");
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/non262/object/defineGetter-defineSetter.js b/js/src/tests/non262/object/defineGetter-defineSetter.js
new file mode 100644
index 0000000000..b2bb21f67c
--- /dev/null
+++ b/js/src/tests/non262/object/defineGetter-defineSetter.js
@@ -0,0 +1,92 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+let count = 0;
+let verifyProxy = new Proxy({}, {
+ defineProperty(target, property, descriptor) {
+ assertEq(property, "x");
+
+ assertEq(descriptor.enumerable, true);
+ assertEq(descriptor.configurable, true);
+
+ if ("set" in descriptor)
+ assertEq(descriptor.set, Object.prototype.__defineSetter__);
+ else
+ assertEq(descriptor.get, Object.prototype.__defineGetter__);
+
+ assertEq(Object.keys(descriptor).length, 3);
+
+ count++;
+ return true;
+ }
+});
+
+for (let define of [Object.prototype.__defineGetter__, Object.prototype.__defineSetter__]) {
+ // null/undefined |this| value
+ for (let thisv of [undefined, null])
+ assertThrowsInstanceOf(() => define.call(thisv, "x", define), TypeError);
+
+ // non-callable getter/setter
+ let nonCallable = [{}, [], new Proxy({}, {})];
+ for (let value of nonCallable)
+ assertThrowsInstanceOf(() => define.call(verifyProxy, "x", value), TypeError);
+
+ // ToPropertyKey
+ let key = {
+ [Symbol.toPrimitive](hint) {
+ assertEq(hint, "string");
+ // Throws, because non-primitive is returned
+ return {};
+ },
+ valueOf() { throw "wrongly invoked"; },
+ toString() { throw "wrongly invoked"; }
+ };
+ assertThrowsInstanceOf(() => define.call(verifyProxy, key, define), TypeError);
+
+ key = {
+ [Symbol.toPrimitive](hint) {
+ assertEq(hint, "string");
+ return "x";
+ },
+ valueOf() { throw "wrongly invoked"; },
+ toString() { throw "wrongly invoked"; }
+ }
+ define.call(verifyProxy, key, define);
+
+ key = {
+ [Symbol.toPrimitive]: undefined,
+
+ valueOf() { throw "wrongly invoked"; },
+ toString() { return "x"; }
+ }
+ define.call(verifyProxy, key, define);
+
+ // Bog standard call
+ define.call(verifyProxy, "x", define);
+
+ let obj = {};
+ define.call(obj, "x", define);
+ let descriptor = Object.getOwnPropertyDescriptor(obj, "x");
+
+ assertEq(descriptor.enumerable, true);
+ assertEq(descriptor.configurable, true);
+
+ if (define == Object.prototype.__defineSetter__) {
+ assertEq(descriptor.get, undefined);
+ assertEq(descriptor.set, define);
+ } else {
+ assertEq(descriptor.get, define);
+ assertEq(descriptor.set, undefined);
+ }
+
+ assertEq(Object.keys(descriptor).length, 4);
+
+
+}
+
+// Number of calls that should succeed
+assertEq(count, 6);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/defineProperties-callable-accessor.js b/js/src/tests/non262/object/defineProperties-callable-accessor.js
new file mode 100644
index 0000000000..1e92a2c92e
--- /dev/null
+++ b/js/src/tests/non262/object/defineProperties-callable-accessor.js
@@ -0,0 +1,19 @@
+// ObjectDefineProperties with non callable accessor throws.
+const descriptors = [
+ {get: 1}, {set: 1},
+ {get: []}, {set: []},
+ {get: {}}, {set: {}},
+ {get: new Number}, {set: new Number},
+
+ {get: 1, set: 1},
+ {get: [], set: []},
+ {get: {}, set: {}},
+ {get: new Number, set: new Number},
+];
+
+for (const descriptor of descriptors) {
+ assertThrowsInstanceOf(() => Object.create(null, {x: descriptor}), TypeError);
+ assertThrowsInstanceOf(() => Object.defineProperties({}, {x: descriptor}), TypeError);
+}
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/object/defineProperties-order.js b/js/src/tests/non262/object/defineProperties-order.js
new file mode 100644
index 0000000000..417d101833
--- /dev/null
+++ b/js/src/tests/non262/object/defineProperties-order.js
@@ -0,0 +1,17 @@
+// Based on testcases provided by André Bargull
+
+let log = [];
+let logger = new Proxy({}, {
+ get(target, key) {
+ log.push(key);
+ }
+});
+
+Object.create(null, new Proxy({a: {value: 0}, b: {value: 1}}, logger));
+assertEq(log.join(), "ownKeys,getOwnPropertyDescriptor,get,getOwnPropertyDescriptor,get");
+
+log = [];
+Object.defineProperties({}, new Proxy({a: {value: 0}, b: {value: 1}}, logger));
+assertEq(log.join(), "ownKeys,getOwnPropertyDescriptor,get,getOwnPropertyDescriptor,get");
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/object/defineProperty-proxy.js b/js/src/tests/non262/object/defineProperty-proxy.js
new file mode 100644
index 0000000000..b5ece940bc
--- /dev/null
+++ b/js/src/tests/non262/object/defineProperty-proxy.js
@@ -0,0 +1,54 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Test details of the implementation of ToPropertyDescriptor exposed to scripts
+// thanks to scriptable proxies.
+
+// A LoggingProxy object logs certain operations performed on it.
+var log = [];
+function LoggingProxy(target) {
+ return new Proxy(target, {
+ has: function (t, id) {
+ log.push("has " + id);
+ return id in t;
+ },
+ get: function (t, id) {
+ log.push("get " + id);
+ return t[id];
+ }
+ });
+}
+
+// Tragically, we use separate code to implement Object.defineProperty on
+// arrays and on proxies. So run the test three times.
+var testSubjects = [
+ {},
+ [],
+ new Proxy({}, {})
+];
+
+for (var obj of testSubjects) {
+ log = [];
+
+ // Object.defineProperty is one public method that performs a
+ // ToPropertyDescriptor call.
+ Object.defineProperty(obj, "x", new LoggingProxy({
+ enumerable: true,
+ configurable: true,
+ value: 3,
+ writable: true
+ }));
+
+ // It should have performed exactly these operations on the proxy, in this
+ // order. See ES6 rev 24 (2014 April 27) 6.2.4.5 ToPropertyDescriptor.
+ assertDeepEq(log, [
+ "has enumerable", "get enumerable",
+ "has configurable", "get configurable",
+ "has value", "get value",
+ "has writable", "get writable",
+ "has get",
+ "has set"
+ ]);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/defineProperty-setup.js b/js/src/tests/non262/object/defineProperty-setup.js
new file mode 100644
index 0000000000..da6fe8f496
--- /dev/null
+++ b/js/src/tests/non262/object/defineProperty-setup.js
@@ -0,0 +1,1071 @@
+// |reftest| skip -- not a test.
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+assertEq("defineProperty" in Object, true);
+assertEq(Object.defineProperty.length, 3);
+
+/*
+ * Disable an assertion that is pathologically slow given the exhaustiveness of
+ * these tests.
+ */
+if (typeof enableStackWalkingAssertion === "function")
+ enableStackWalkingAssertion(false);
+
+if (!Object.prototype.toSource)
+{
+ Object.defineProperty(Object.prototype, "toSource",
+ {
+ value: function toSource()
+ {
+ if (this instanceof RegExp)
+ {
+ var v = "new RegExp(" + uneval(this.source);
+ var f = (this.multiline ? "m" : "") +
+ (this.global ? "g" : "") +
+ (this.ignoreCase ? "i" : "");
+ return v + (f ? ", '" + f + "'" : "") + ")";
+ }
+ return JSON.stringify(this);
+ },
+ enumerable: false,
+ configurable: true,
+ writable: true
+ });
+}
+if (!("uneval" in this))
+{
+ Object.defineProperty(this, "uneval",
+ {
+ value: function uneval(v)
+ {
+ if (v === null)
+ return "null";
+ if (typeof v === "object")
+ return v.toSource();
+ if (typeof v === "string")
+ {
+ v = JSON.stringify({v:v});
+ return v.substring(5, v.length - 1);
+ }
+ return "" + v;
+ },
+ enumerable: false,
+ configurable: true,
+ writable: true
+ });
+}
+
+// reimplemented for the benefit of engines which don't have this helper
+function assertEq(v1, v2, m)
+{
+ if (!SameValue(v1, v2))
+ {
+ throw "assertion failed: " +
+ "got " + uneval(v1) + ", expected " + uneval(v2) +
+ (m ? ": " + m : "");
+ }
+}
+
+function SameValue(v1, v2)
+{
+ if (v1 === 0 && v2 === 0)
+ return 1 / v1 === 1 / v2;
+ if (v1 !== v1 && v2 !== v2)
+ return true;
+ return v1 === v2;
+}
+
+function PropertyDescriptor(pd)
+{
+ if (pd)
+ this.update(pd);
+}
+PropertyDescriptor.prototype.update = function update(pd)
+{
+ if ("get" in pd)
+ this.get = pd.get;
+ if ("set" in pd)
+ this.set = pd.set;
+ if ("configurable" in pd)
+ this.configurable = pd.configurable;
+ if ("writable" in pd)
+ this.writable = pd.writable;
+ if ("enumerable" in pd)
+ this.enumerable = pd.enumerable;
+ if ("value" in pd)
+ this.value = pd.value;
+};
+PropertyDescriptor.prototype.convertToDataDescriptor = function convertToDataDescriptor()
+{
+ delete this.get;
+ delete this.set;
+ this.writable = false;
+ this.value = undefined;
+};
+PropertyDescriptor.prototype.convertToAccessorDescriptor = function convertToAccessorDescriptor()
+{
+ delete this.writable;
+ delete this.value;
+ this.get = undefined;
+ this.set = undefined;
+};
+
+function compareDescriptors(d1, d2)
+{
+ if (d1 === undefined)
+ {
+ assertEq(d2, undefined, "non-descriptors");
+ return;
+ }
+ if (d2 === undefined)
+ {
+ assertEq(true, false, "descriptor-equality mismatch: " + uneval(d1) + ", " + uneval(d2));
+ return;
+ }
+
+ var props = ["value", "get", "set", "enumerable", "configurable", "writable"];
+ for (var i = 0, sz = props.length; i < sz; i++)
+ {
+ var p = props[i];
+ assertEq(p in d1, p in d2, p + " different in d1/d2");
+ if (p in d1)
+ assertEq(d1[p], d2[p], p);
+ }
+}
+
+function examine(desc, field, allowDefault)
+{
+ if (field in desc)
+ return desc[field];
+ assertEq(allowDefault, true, "reimplementation error");
+ switch (field)
+ {
+ case "value":
+ case "get":
+ case "set":
+ return undefined;
+ case "writable":
+ case "enumerable":
+ case "configurable":
+ return false;
+ default:
+ assertEq(true, false, "bad field name: " + field);
+ }
+}
+
+function IsAccessorDescriptor(desc)
+{
+ if (!desc)
+ return false;
+ if (!("get" in desc) && !("set" in desc))
+ return false;
+ return true;
+}
+
+function IsDataDescriptor(desc)
+{
+ if (!desc)
+ return false;
+ if (!("value" in desc) && !("writable" in desc))
+ return false;
+ return true;
+}
+
+function IsGenericDescriptor(desc)
+{
+ if (!desc)
+ return false;
+ if (!IsAccessorDescriptor(desc) && !IsDataDescriptor(desc))
+ return true;
+ return false;
+}
+
+
+
+function CustomObject()
+{
+ this.properties = {};
+ this.extensible = true;
+}
+CustomObject.prototype =
+{
+ _reject: function _reject(throwing, msg)
+ {
+ if (throwing)
+ throw new TypeError(msg + "; rejected!");
+ return false;
+ },
+ defineOwnProperty: function defineOwnProperty(propname, desc, throwing)
+ {
+ assertEq(typeof propname, "string", "non-string propname");
+
+ // Step 1.
+ var current = this.properties[propname];
+
+ // Step 2.
+ var extensible = this.extensible;
+
+ // Step 3.
+ if (current === undefined && !extensible)
+ return this._reject(throwing, "object not extensible");
+
+ // Step 4.
+ if (current === undefined && extensible)
+ {
+ var p;
+ // Step 4(a).
+ if (IsGenericDescriptor(desc) || IsDataDescriptor(desc))
+ {
+ p = new PropertyDescriptor();
+ p.value = examine(desc, "value", true);
+ p.writable = examine(desc, "writable", true);
+ p.enumerable = examine(desc, "enumerable", true);
+ p.configurable = examine(desc, "configurable", true);
+ }
+ // Step 4(b).
+ else
+ {
+ p = new PropertyDescriptor();
+ p.get = examine(desc, "get", true);
+ p.set = examine(desc, "set", true);
+ p.enumerable = examine(desc, "enumerable", true);
+ p.configurable = examine(desc, "configurable", true);
+ }
+
+ this.properties[propname] = p;
+
+ // Step 4(c).
+ return true;
+ }
+
+ // Step 5.
+ if (!("value" in desc) && !("get" in desc) && !("set" in desc) &&
+ !("writable" in desc) && !("enumerable" in desc) &&
+ !("configurable" in desc))
+ {
+ return;
+ }
+
+ // Step 6.
+ do
+ {
+ if ("value" in desc)
+ {
+ if (!("value" in current) || !SameValue(desc.value, current.value))
+ break;
+ }
+ if ("get" in desc)
+ {
+ if (!("get" in current) || !SameValue(desc.get, current.get))
+ break;
+ }
+ if ("set" in desc)
+ {
+ if (!("set" in current) || !SameValue(desc.set, current.set))
+ break;
+ }
+ if ("writable" in desc)
+ {
+ if (!("writable" in current) ||
+ !SameValue(desc.writable, current.writable))
+ {
+ break;
+ }
+ }
+ if ("enumerable" in desc)
+ {
+ if (!("enumerable" in current) ||
+ !SameValue(desc.enumerable, current.enumerable))
+ {
+ break;
+ }
+ }
+ if ("configurable" in desc)
+ {
+ if (!("configurable" in current) ||
+ !SameValue(desc.configurable, current.configurable))
+ {
+ break;
+ }
+ }
+
+ // all fields in desc also in current, with the same values
+ return true;
+ }
+ while (false);
+
+ // Step 7.
+ if (!examine(current, "configurable"))
+ {
+ if ("configurable" in desc && examine(desc, "configurable"))
+ return this._reject(throwing, "can't make configurable again");
+ if ("enumerable" in desc &&
+ examine(current, "enumerable") !== examine(desc, "enumerable"))
+ {
+ return this._reject(throwing, "can't change enumerability");
+ }
+ }
+
+ // Step 8.
+ if (IsGenericDescriptor(desc))
+ {
+ // do nothing
+ }
+ // Step 9.
+ else if (IsDataDescriptor(current) !== IsDataDescriptor(desc))
+ {
+ // Step 9(a).
+ if (!examine(current, "configurable"))
+ return this._reject(throwing, "can't change unconfigurable descriptor's type");
+ // Step 9(b).
+ if (IsDataDescriptor(current))
+ current.convertToAccessorDescriptor();
+ // Step 9(c).
+ else
+ current.convertToDataDescriptor();
+ }
+ // Step 10.
+ else if (IsDataDescriptor(current) && IsDataDescriptor(desc))
+ {
+ // Step 10(a)
+ if (!examine(current, "configurable"))
+ {
+ // Step 10(a).i.
+ if (!examine(current, "writable") &&
+ "writable" in desc && examine(desc, "writable"))
+ {
+ return this._reject(throwing, "can't make data property writable again");
+ }
+ // Step 10(a).ii.
+ if (!examine(current, "writable"))
+ {
+ if ("value" in desc &&
+ !SameValue(examine(desc, "value"), examine(current, "value")))
+ {
+ return this._reject(throwing, "can't change value if not writable");
+ }
+ }
+ }
+ // Step 10(b).
+ else
+ {
+ assertEq(examine(current, "configurable"), true,
+ "spec bug step 10(b)");
+ }
+ }
+ // Step 11.
+ else
+ {
+ assertEq(IsAccessorDescriptor(current) && IsAccessorDescriptor(desc),
+ true,
+ "spec bug");
+
+ // Step 11(a).
+ if (!examine(current, "configurable"))
+ {
+ // Step 11(a).i.
+ if ("set" in desc &&
+ !SameValue(examine(desc, "set"), examine(current, "set")))
+ {
+ return this._reject(throwing, "can't change setter if not configurable");
+ }
+ // Step 11(a).ii.
+ if ("get" in desc &&
+ !SameValue(examine(desc, "get"), examine(current, "get")))
+ {
+ return this._reject(throwing, "can't change getter if not configurable");
+ }
+ }
+ }
+
+ // Step 12.
+ current.update(desc);
+
+ // Step 13.
+ return true;
+ }
+};
+
+function IsCallable(v)
+{
+ return typeof v === "undefined" || typeof v === "function";
+}
+
+var NativeTest =
+ {
+ newObject: function newObject()
+ {
+ return {};
+ },
+ defineProperty: function defineProperty(obj, propname, propdesc)
+ {
+ Object.defineProperty(obj, propname, propdesc);
+ },
+ getDescriptor: function getDescriptor(obj, propname)
+ {
+ return Object.getOwnPropertyDescriptor(obj, propname);
+ }
+ };
+
+var ReimplTest =
+ {
+ newObject: function newObject()
+ {
+ return new CustomObject();
+ },
+ defineProperty: function defineProperty(obj, propname, propdesc)
+ {
+ assertEq(obj instanceof CustomObject, true, "obj not instanceof CustomObject");
+ if ("get" in propdesc || "set" in propdesc)
+ {
+ if ("value" in propdesc || "writable" in propdesc)
+ throw new TypeError("get/set and value/writable");
+ if (!IsCallable(propdesc.get))
+ throw new TypeError("get defined, uncallable");
+ if (!IsCallable(propdesc.set))
+ throw new TypeError("set defined, uncallable");
+ }
+ return obj.defineOwnProperty(propname, propdesc, true);
+ },
+ getDescriptor: function getDescriptor(obj, propname)
+ {
+ if (!(propname in obj.properties))
+ return undefined;
+
+ return new PropertyDescriptor(obj.properties[propname]);
+ }
+ };
+
+var JSVAL_INT_MAX = Math.pow(2, 30) - 1;
+var JSVAL_INT_MIN = -Math.pow(2, 30);
+
+
+function isValidDescriptor(propdesc)
+{
+ if ("get" in propdesc || "set" in propdesc)
+ {
+ if ("value" in propdesc || "writable" in propdesc)
+ return false;
+
+ // We permit null here simply because this test's author believes the
+ // implementation may sometime be susceptible to making mistakes in this
+ // regard and would prefer to be cautious.
+ if (propdesc.get !== null && propdesc.get !== undefined && !IsCallable(propdesc.get))
+ return false;
+ if (propdesc.set !== null && propdesc.set !== undefined && !IsCallable(propdesc.set))
+ return false;
+ }
+
+ return true;
+}
+
+
+var OMIT = {};
+var VALUES =
+ [-Infinity, JSVAL_INT_MIN, -0, +0, 1.5, JSVAL_INT_MAX, Infinity,
+ NaN, "foo", "bar", null, undefined, true, false, {}, /a/, OMIT];
+var GETS =
+ [undefined, function get1() { return 1; }, function get2() { return 2; },
+ null, 5, OMIT];
+var SETS =
+ [undefined, function set1() { return 1; }, function set2() { return 2; },
+ null, 5, OMIT];
+var ENUMERABLES = [true, false, OMIT];
+var CONFIGURABLES = [true, false, OMIT];
+var WRITABLES = [true, false, OMIT];
+
+function mapTestDescriptors(filter)
+{
+ var descs = [];
+ var desc = {};
+
+ function put(field, value)
+ {
+ if (value !== OMIT)
+ desc[field] = value;
+ }
+
+ VALUES.forEach(function(value)
+ {
+ GETS.forEach(function(get)
+ {
+ SETS.forEach(function(set)
+ {
+ ENUMERABLES.forEach(function(enumerable)
+ {
+ CONFIGURABLES.forEach(function(configurable)
+ {
+ WRITABLES.forEach(function(writable)
+ {
+ desc = {};
+ put("value", value);
+ put("get", get);
+ put("set", set);
+ put("enumerable", enumerable);
+ put("configurable", configurable);
+ put("writable", writable);
+ if (filter(desc))
+ descs.push(desc);
+ });
+ });
+ });
+ });
+ });
+ });
+
+ return descs;
+}
+
+var ALL_DESCRIPTORS = mapTestDescriptors(function(d) { return true; });
+var VALID_DESCRIPTORS = mapTestDescriptors(isValidDescriptor);
+
+function TestRunner()
+{
+ this._logLines = [];
+}
+TestRunner.prototype =
+ {
+ // MAIN METHODS
+
+ runFunctionLengthTests: function runFunctionLengthTests()
+ {
+ var self = this;
+ function functionLengthTests()
+ {
+ self._fullFunctionLengthTests(() => Function("one", "/* body */"), 1);
+ self._fullFunctionLengthTests(() => function(one, two, three=null) { }, 2);
+ self._fullFunctionLengthTests(() => (one, two, ...etc) => 0, 2);
+ self._fullFunctionLengthTests(() => ({method(){}}.method), 0);
+ self._fullFunctionLengthTests(() => Object.getOwnPropertyDescriptor({set x(v){}}, "x").set, 1);
+ }
+
+ this._runTestSet(functionLengthTests, "Function length tests completed!");
+ },
+
+ runNotPresentTests: function runNotPresentTests()
+ {
+ var self = this;
+ function notPresentTests()
+ {
+ print("Running not-present tests now...");
+
+ for (var i = 0, sz = ALL_DESCRIPTORS.length; i < sz; i++)
+ self._runSingleNotPresentTest(ALL_DESCRIPTORS[i]);
+ };
+
+ this._runTestSet(notPresentTests, "Not-present length tests completed!");
+ },
+
+ runPropertyPresentTestsFraction:
+ function runPropertyPresentTestsFraction(part, parts)
+ {
+ var self = this;
+ function propertyPresentTests()
+ {
+ print("Running already-present tests now...");
+
+ var total = VALID_DESCRIPTORS.length;
+ var start = Math.floor((part - 1) / parts * total);
+ var end = Math.floor(part / parts * total);
+
+ for (var i = start; i < end; i++)
+ {
+ var old = VALID_DESCRIPTORS[i];
+ print("Starting test with old descriptor " + old.toSource() + "...");
+
+ for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
+ self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []);
+ }
+ }
+
+ this._runTestSet(propertyPresentTests,
+ "Property-present fraction " + part + " of " + parts +
+ " completed!");
+ },
+
+ runNonTerminalPropertyPresentTestsFraction:
+ function runNonTerminalPropertyPresentTestsFraction(part, parts)
+ {
+ var self = this;
+
+ /*
+ * A plain old property to define on the object before redefining the
+ * originally-added property, to test redefinition of a property that's
+ * not also lastProperty. NB: we could loop over every possible
+ * descriptor here if we wanted, even try adding more than one, but we'd
+ * hit cubic complexity and worse, and SpiderMonkey only distinguishes by
+ * the mere presence of the middle property, not its precise details.
+ */
+ var middleDefines =
+ [{
+ property: "middle",
+ descriptor:
+ { value: 17, writable: true, configurable: true, enumerable: true }
+ }];
+
+ function nonTerminalPropertyPresentTests()
+ {
+ print("Running non-terminal already-present tests now...");
+
+ var total = VALID_DESCRIPTORS.length;
+ var start = Math.floor((part - 1) / parts * total);
+ var end = Math.floor(part / parts * total);
+
+ for (var i = start; i < end; i++)
+ {
+ var old = VALID_DESCRIPTORS[i];
+ print("Starting test with old descriptor " + old.toSource() + "...");
+
+ for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
+ {
+ self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j],
+ middleDefines);
+ }
+ }
+ }
+
+ this._runTestSet(nonTerminalPropertyPresentTests,
+ "Non-terminal property-present fraction " +
+ part + " of " + parts + " completed!");
+ },
+
+ runDictionaryPropertyPresentTestsFraction:
+ function runDictionaryPropertyPresentTestsFraction(part, parts)
+ {
+ var self = this;
+
+ /*
+ * Add and readd properties such that the scope for the object is in
+ * dictionary mode.
+ */
+ var middleDefines =
+ [
+ {
+ property: "mid1",
+ descriptor:
+ { value: 17, writable: true, configurable: true, enumerable: true }
+ },
+ {
+ property: "mid2",
+ descriptor:
+ { value: 17, writable: true, configurable: true, enumerable: true }
+ },
+ {
+ property: "mid1",
+ descriptor:
+ { get: function g() { }, set: function s(v){}, configurable: false,
+ enumerable: true }
+ },
+ ];
+
+ function dictionaryPropertyPresentTests()
+ {
+ print("Running dictionary already-present tests now...");
+
+ var total = VALID_DESCRIPTORS.length;
+ var start = Math.floor((part - 1) / parts * total);
+ var end = Math.floor(part / parts * total);
+
+ for (var i = start; i < end; i++)
+ {
+ var old = VALID_DESCRIPTORS[i];
+ print("Starting test with old descriptor " + old.toSource() + "...");
+
+ for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
+ {
+ self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j],
+ middleDefines);
+ }
+ }
+ }
+
+ this._runTestSet(dictionaryPropertyPresentTests,
+ "Dictionary property-present fraction " +
+ part + " of " + parts + " completed!");
+ },
+
+
+ // HELPERS
+
+ runPropertyPresentTests: function runPropertyPresentTests()
+ {
+ print("Running already-present tests now...");
+
+ for (var i = 0, sz = VALID_DESCRIPTORS.length; i < sz; i++)
+ {
+ var old = VALID_DESCRIPTORS[i];
+ print("Starting test with old descriptor " + old.toSource() + "...");
+
+ for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
+ this._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []);
+ }
+ },
+ _runTestSet: function _runTestSet(fun, completeMessage)
+ {
+ try
+ {
+ fun();
+
+ print(completeMessage);
+ }
+ catch (e)
+ {
+ print("ERROR, EXITING (line " + (e.lineNumber || -1) + "): " + e);
+ throw e;
+ }
+ finally
+ {
+ this._reportAllErrors();
+ }
+ },
+ _reportAllErrors: function _reportAllErrors()
+ {
+ var errorCount = this._logLines.length;
+ print("Full accumulated number of errors: " + errorCount);
+ if (errorCount > 0)
+ throw errorCount + " errors detected, FAIL";
+ },
+ _fullFunctionLengthTests: function _fullFunctionLengthTests(funFactory, len)
+ {
+ print("Running Function.length (" + funFactory + ") tests now...");
+
+ for (var i = 0, sz = VALID_DESCRIPTORS.length; i < sz; i++)
+ {
+ var desc = VALID_DESCRIPTORS[i];
+ this._runSingleFunctionLengthTest(funFactory(), len, desc);
+ }
+ },
+ _log: function _log(v)
+ {
+ var m = "" + v;
+ print(m);
+ this._logLines.push(m);
+ },
+ _runSingleNotPresentTest: function _runSingleNotPresentTest(desc)
+ {
+ var nativeObj = NativeTest.newObject();
+ var reimplObj = ReimplTest.newObject();
+
+ try
+ {
+ NativeTest.defineProperty(nativeObj, "foo", desc);
+ }
+ catch (e)
+ {
+ try
+ {
+ ReimplTest.defineProperty(reimplObj, "foo", desc);
+ }
+ catch (e2)
+ {
+ if (e.constructor !== e2.constructor)
+ {
+ this._log("Difference when comparing native/reimplementation " +
+ "behavior for new descriptor " + desc.toSource() +
+ ", native threw " + e + ", reimpl threw " + e2);
+ }
+ return;
+ }
+ this._log("Difference when comparing native/reimplementation " +
+ "behavior for new descriptor " + desc.toSource() +
+ ", error " + e);
+ return;
+ }
+
+ try
+ {
+ ReimplTest.defineProperty(reimplObj, "foo", desc);
+ }
+ catch (e)
+ {
+ this._log("Reimpl threw defining new descriptor " + desc.toSource() +
+ ", error: " + e);
+ return;
+ }
+
+ var nativeDesc = NativeTest.getDescriptor(nativeObj, "foo");
+ var reimplDesc = ReimplTest.getDescriptor(reimplObj, "foo");
+ try
+ {
+ compareDescriptors(nativeDesc, reimplDesc);
+ }
+ catch (e)
+ {
+ this._log("Difference comparing returned descriptors for new " +
+ "property defined with descriptor " + desc.toSource() +
+ "; error: " + e);
+ return;
+ }
+ },
+ _runSinglePropertyPresentTest:
+ function _runSinglePropertyPresentTest(old, add, middleDefines)
+ {
+ var nativeObj = NativeTest.newObject();
+ var reimplObj = ReimplTest.newObject();
+
+ try
+ {
+ NativeTest.defineProperty(nativeObj, "foo", old);
+ }
+ catch (e)
+ {
+ if (!SameValue(NativeTest.getDescriptor(nativeObj, "foo"), undefined))
+ {
+ this._log("defining bad property descriptor: " + old.toSource());
+ return;
+ }
+
+ try
+ {
+ ReimplTest.defineProperty(reimplObj, "foo", old);
+ }
+ catch (e2)
+ {
+ if (!SameValue(ReimplTest.getDescriptor(reimplObj, "foo"),
+ undefined))
+ {
+ this._log("defining bad property descriptor: " + old.toSource() +
+ "; reimplObj: " + uneval(reimplObj));
+ }
+
+ if (e.constructor !== e2.constructor)
+ {
+ this._log("Different errors defining bad property descriptor: " +
+ old.toSource() + "; native threw " + e + ", reimpl " +
+ "threw " + e2);
+ }
+
+ return;
+ }
+
+ this._log("Difference defining a property with descriptor " +
+ old.toSource() + ", error " + e);
+ return;
+ }
+
+ try
+ {
+ ReimplTest.defineProperty(reimplObj, "foo", old);
+ }
+ catch (e)
+ {
+ this._log("Difference when comparing native/reimplementation " +
+ "behavior when adding descriptor " + add.toSource() +
+ ", error: " + e);
+ return;
+ }
+
+ // Now add (or even readd) however many properties were specified between
+ // the original property to add and the new one, to test redefining
+ // non-last-properties and properties in scopes in dictionary mode.
+ for (var i = 0, sz = middleDefines.length; i < sz; i++)
+ {
+ var middle = middleDefines[i];
+ var prop = middle.property;
+ var desc = middle.descriptor;
+
+ try
+ {
+ NativeTest.defineProperty(nativeObj, prop, desc);
+ ReimplTest.defineProperty(reimplObj, prop, desc);
+ }
+ catch (e)
+ {
+ this._log("failure defining middle descriptor: " + desc.toSource() +
+ ", error " + e);
+ return;
+ }
+
+ // Sanity check
+ var nativeDesc = NativeTest.getDescriptor(nativeObj, prop);
+ var reimplDesc = ReimplTest.getDescriptor(reimplObj, prop);
+
+ compareDescriptors(nativeDesc, reimplDesc);
+ compareDescriptors(nativeDesc, desc);
+ }
+
+ try
+ {
+ NativeTest.defineProperty(nativeObj, "foo", add);
+ }
+ catch (e)
+ {
+ try
+ {
+ ReimplTest.defineProperty(reimplObj, "foo", add);
+ }
+ catch (e2)
+ {
+ if (e.constructor !== e2.constructor)
+ {
+ this._log("Difference when comparing native/reimplementation " +
+ "behavior for descriptor " + add.toSource() +
+ " overwriting descriptor " + old.toSource() + "; " +
+ "native threw " + e + ", reimpl threw " + e2);
+ }
+ return;
+ }
+ this._log("Difference when comparing native/reimplementation " +
+ "behavior for added descriptor " + add.toSource() + ", " +
+ "initial was " + old.toSource() + "; error: " + e);
+ return;
+ }
+
+ try
+ {
+ ReimplTest.defineProperty(reimplObj, "foo", add);
+ }
+ catch (e)
+ {
+ this._log("Difference when comparing native/reimplementation " +
+ "behavior for readded descriptor " + add.toSource() + ", " +
+ "initial was " + old.toSource() + "; native readd didn't " +
+ "throw, reimpl add did, error: " + e);
+ return;
+ }
+
+ var nativeDesc = NativeTest.getDescriptor(nativeObj, "foo");
+ var reimplDesc = ReimplTest.getDescriptor(reimplObj, "foo");
+ try
+ {
+ compareDescriptors(nativeDesc, reimplDesc);
+ }
+ catch (e)
+ {
+ this._log("Difference comparing returned descriptors for readded " +
+ "property defined with descriptor " + add.toSource() + "; " +
+ "initial was " + old.toSource() + "; error: " + e);
+ return;
+ }
+ },
+ _runSingleFunctionLengthTest: function _runSingleFunctionLengthTest(fun, len, desc)
+ {
+ var nativeObj = fun;
+ var reimplObj = ReimplTest.newObject();
+ ReimplTest.defineProperty(reimplObj, "length",
+ {
+ value: len,
+ enumerable: false,
+ configurable: true,
+ writable: false
+ });
+
+ try
+ {
+ NativeTest.defineProperty(nativeObj, "length", desc);
+ }
+ catch (e)
+ {
+ try
+ {
+ ReimplTest.defineProperty(reimplObj, "length", desc);
+ }
+ catch (e2)
+ {
+ if (e.constructor !== e2.constructor)
+ {
+ this._log("Difference when comparing native/reimplementation " +
+ "behavior defining fun.length with " + desc.toSource() +
+ "; native threw " + e + ", reimpl threw " + e2);
+ }
+ return;
+ }
+ this._log("Difference when comparing Function.length native/reimpl " +
+ "behavior for descriptor " + desc.toSource() +
+ ", native impl threw error " + e);
+ return;
+ }
+
+ try
+ {
+ ReimplTest.defineProperty(reimplObj, "length", desc);
+ }
+ catch (e)
+ {
+ this._log("Difference defining new Function.length descriptor: impl " +
+ "succeeded, reimpl threw for descriptor " +
+ desc.toSource() + ", error: " + e);
+ return;
+ }
+
+ var nativeDesc = NativeTest.getDescriptor(nativeObj, "length");
+ var reimplDesc = ReimplTest.getDescriptor(reimplObj, "length");
+ try
+ {
+ compareDescriptors(nativeDesc, reimplDesc);
+ }
+ catch (e)
+ {
+ this._log("Difference comparing returned descriptors for " +
+ "Function.length with descriptor " + desc.toSource() +
+ "; error: " + e);
+ return;
+ }
+ }
+ };
+
+function runDictionaryPropertyPresentTestsFraction(PART, PARTS)
+{
+ var testfile =
+ '15.2.3.6-dictionary-redefinition-' + PART + '-of-' + PARTS + '.js';
+ var BUGNUMBER = 560566;
+ var summary =
+ 'ES5 Object.defineProperty(O, P, Attributes): dictionary redefinition ' +
+ PART + ' of ' + PARTS;
+
+ print(BUGNUMBER + ": " + summary);
+
+ try
+ {
+ new TestRunner().runDictionaryPropertyPresentTestsFraction(PART, PARTS);
+ }
+ catch (e)
+ {
+ throw "Error thrown during testing: " + e +
+ " at line " + e.lineNumber + "\n" +
+ (e.stack
+ ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
+ : "");
+ }
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+ print("Tests complete!");
+}
+
+function runNonTerminalPropertyPresentTestsFraction(PART, PARTS)
+{
+ var BUGNUMBER = 560566;
+ var summary =
+ 'ES5 Object.defineProperty(O, P, Attributes): middle redefinition ' +
+ PART + ' of ' + PARTS;
+
+ print(BUGNUMBER + ": " + summary);
+
+
+ /**************
+ * BEGIN TEST *
+ **************/
+
+ try
+ {
+ new TestRunner().runNonTerminalPropertyPresentTestsFraction(PART, PARTS);
+ }
+ catch (e)
+ {
+ throw "Error thrown during testing: " + e +
+ " at line " + e.lineNumber + "\n" +
+ (e.stack
+ ? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
+ : "");
+ }
+
+ /******************************************************************************/
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+ print("Tests complete!");
+}
diff --git a/js/src/tests/non262/object/destructuring-shorthand-defaults.js b/js/src/tests/non262/object/destructuring-shorthand-defaults.js
new file mode 100644
index 0000000000..3ca240e0b7
--- /dev/null
+++ b/js/src/tests/non262/object/destructuring-shorthand-defaults.js
@@ -0,0 +1,127 @@
+/* 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/. */
+
+// Ensure that the syntax used in shorthand destructuring with defaults
+// e.g. |{x=1, y=2} = {}| properly raises a syntax error within an object
+// literal. As per ES6 12.2.6 Object Initializer, "NOTE 3."
+
+const SYNTAX_ERROR_STMTS = [
+ // expressions
+ "({x={}={}}),",
+ "({y={x={}={}={}={}={}={}={}={}}={}}),",
+ "({a=1, b=2, c=3, x=({}={})}),",
+ "({x=1, y={z={1}}})",
+ "({x=1} = {y=1});",
+ "({x: y={z=1}}={})",
+ "({x=1}),",
+ "({z={x=1}})=>{};",
+ "({x = ({y=1}) => y})",
+ "(({x=1})) => x",
+ "({e=[]}==(;",
+ "({x=1}[-1]);",
+ "({x=y}[-9])",
+ "({x=y}.x.z[-9])",
+ "({x=y}`${-9}`)",
+ "(new {x=y}(-9))",
+ "new {x=1}",
+ "new {x=1}={}",
+ "typeof {x=1}",
+ "typeof ({x=1})",
+ "({x=y, [-9]:0})",
+ "((({w = x} >(-9)",
+ "++({x=1})",
+ "--{x=1}",
+ "!{x=1}={}",
+ "delete {x=1}",
+ "delete ({x=1})",
+ "delete {x=1} = {}",
+ "({x=1}.abc)",
+ "x > (0, {a = b} );",
+ // declarations
+ "var x = 0 + {a=1} = {}",
+ "let o = {x=1};",
+ "var j = {x=1};",
+ "var j = {x={y=1}}={};",
+ "const z = {x=1};",
+ "const z = {x={y=1}}={};",
+ "const {x=1};",
+ "const {x={y=33}}={};",
+ "var {x=1};",
+ "let {x=1};",
+ "let x, y, {z=1}={}, {w=2}, {e=3};",
+ // array initialization
+ "[{x=1, y = ({z=2} = {})}];",
+ // try/catch
+ "try {throw 'a';} catch ({x={y=1}}) {}",
+ // if/else
+ "if ({k: 1, x={y=2}={}}) {}",
+ "if (false) {} else if (true) { ({x=1}) }",
+ // switch
+ "switch ('c') { case 'c': ({x=1}); }",
+ // for
+ "for ({x=1}; 1;) {1}",
+ "for ({x={y=2}}; 1;) {1}",
+ "for (var x = 0; x < 2; x++) { ({x=1, y=2}) }",
+ "for (let x=1;{x=1};){}",
+ "for (let x=1;{x={y=2}};){}",
+ "for (let x=1;1;{x=1}){}",
+ "for (let x=1;1;{x={y=2}}){}",
+ // while
+ "while ({x=1}) {1};",
+ "while ({x={y=2}}={}) {1};",
+ // with
+ "with ({x=1}) {};",
+ "with ({x={y=3}={}}) {};",
+ "with (Math) { ({x=1}) };",
+ // ternary
+ "true ? {x=1} : 1;",
+ "false ? 1 : {x=1};",
+ "{x=1} ? 2 : 3;",
+ // assignment
+ "({x} += {});",
+ "({x = 1}) = {x: 2};",
+]
+
+for (var stmt of SYNTAX_ERROR_STMTS) {
+ assertThrowsInstanceOf(() => {
+ Function(stmt);
+ }, SyntaxError);
+}
+
+// A few tricky but acceptable cases:
+// see https://bugzilla.mozilla.org/show_bug.cgi?id=932080#c2
+
+assertEq((({a = 0}) => a)({}), 0);
+assertEq((({a = 0} = {}) => a)({}), 0);
+assertEq((({a = 0} = {}) => a)({a: 1}), 1);
+
+{
+ let x, y;
+ ({x=1} = {});
+ assertEq(x, 1);
+ ({x=1} = {x: 4});
+ assertEq(x, 4);
+ ({x=1, y=2} = {})
+ assertEq(x, 1);
+ assertEq(y, 2);
+}
+
+{
+ let {x={i=1, j=2}={}}={};
+ assertDeepEq(x, ({}));
+ assertEq(i, 1);
+ assertEq(j, 2);
+}
+
+// Default destructuring values, which are variables, should be defined
+// within closures (Bug 1255167).
+{
+ let f = function(a){
+ return (function({aa = a}){ return aa; })({});
+ };
+ assertEq(f(9999), 9999);
+}
+
+if (typeof reportCompare == "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/duplProps.js b/js/src/tests/non262/object/duplProps.js
new file mode 100644
index 0000000000..41b8d67fb0
--- /dev/null
+++ b/js/src/tests/non262/object/duplProps.js
@@ -0,0 +1,116 @@
+/*
+ * ES6 allows duplicate property names in object literals, even in strict mode.
+ * These tests modify the tests in test262 to reflect this change.
+ */
+
+// test262/ch11/11.1/11.1.5/11.1.5-4-4-a-1-s.js
+a = function() { "use strict"; return { foo: 0, foo : 1 }};
+assertEq(a().foo, 1);
+a = function() { return { foo: 0, foo : 1 }};
+assertEq(a().foo, 1);
+
+// test262/ch11/11.1/11.1.5/11.1.5_4-4-b-1.js
+a = function() { "use strict"; return { foo : 1, get foo() { return 2; }}};
+assertEq(a().foo, 2);
+a = function() { return { foo : 1, get foo() { return 2;} }};
+assertEq(a().foo, 2);
+
+// test262/ch11/11.1/11.1.5/11.1.5_4-4-c-1.js
+a = function() { "use strict"; return { get foo() { return 2; }, foo : 1 }};
+assertEq(a().foo, 1);
+a = function() { return { get foo() { return 2; }, foo : 1 }};
+assertEq(a().foo, 1);
+
+// test262/ch11/11.1/11.1.5/11.1.5_4-4-b-2.js
+a = function() { "use strict"; return { foo : 1, set foo(a) { throw 2; }}};
+try {
+ a().foo = 5;
+ throw new Error("2 should be thrown here");
+} catch (e) {
+ if (e !== 2)
+ throw new Error("2 should be thrown here");
+}
+a = function() { return { foo : 1, set foo(a) { throw 2;} }};
+try {
+ a().foo = 5;
+ throw new Error("2 should be thrown here");
+} catch (e) {
+ if (e !== 2)
+ throw new Error("2 should be thrown here");
+}
+
+// test262/ch11/11.1/11.1.5/11.1.5_4-4-d-1.js
+a = function() { "use strict"; return { get foo() { return 2; }, get foo() { return 3; } }};
+assertEq(a().foo, 3);
+a = function() { return { get foo() { return 2; }, get foo() { return 3; } }};
+assertEq(a().foo, 3);
+
+// test262/ch11/11.1/11.1.5/11.1.5_4-4-c-2.js
+a = function() { "use strict"; return { set foo(a) { throw 2; }, foo : 1 }};
+assertEq(a().foo, 1);
+a = function() { return { set foo(a) { throw 2; }, foo : 1 }};
+assertEq(a().foo, 1);
+
+// test262/ch11/11.1/11.1.5/11.1.5_4-4-d-2.js
+a = function() { "use strict"; return { set foo(a) { throw 2; }, set foo(a) { throw 3; }}};
+try {
+ a().foo = 5;
+ throw new Error("3 should be thrown here");
+} catch (e) {
+ if (e !== 3)
+ throw new Error("3 should be thrown here");
+}
+a = function() { return { set foo(a) { throw 2; }, set foo(a) { throw 3; }}};
+try {
+ a().foo = 5;
+ throw new Error("3 should be thrown here");
+} catch (e) {
+ if (e !== 3)
+ throw new Error("3 should be thrown here");
+}
+
+// test262/ch11/11.1/11.1.5/11.1.5_4-4-d-3.js
+a = function() { "use strict"; return { get foo() { return 2; }, set foo(a) { throw 3; },
+ get foo() { return 4; }}};
+try {
+ assertEq(a().foo, 4);
+ a().foo = 5;
+ throw new Error("3 should be thrown here");
+} catch (e) {
+ if (e !== 3)
+ throw new Error("3 should be thrown here");
+}
+a = function() { return { get foo() { return 2; }, set foo(a) { throw 3; },
+ get foo() { return 4; }}};
+try {
+ assertEq(a().foo, 4);
+ a().foo = 5;
+ throw new Error("3 should be thrown here");
+} catch (e) {
+ if (e !== 3)
+ throw new Error("3 should be thrown here");
+}
+
+// test262/ch11/11.1/11.1.5/11.1.5_4-4-d-4.js
+a = function() { "use strict"; return { set foo(a) { throw 2; }, get foo() { return 4; },
+ set foo(a) { throw 3; }}};
+try {
+ assertEq(a().foo, 4);
+ a().foo = 5;
+ throw new Error("3 should be thrown here");
+} catch (e) {
+ if (e !== 3)
+ throw new Error("3 should be thrown here");
+}
+a = function() { return { set foo(a) { throw 2; }, get foo() { return 4; },
+ set foo(a) { throw 3; }}};
+try {
+ assertEq(a().foo, 4);
+ a().foo = 5;
+ throw new Error("3 should be thrown here");
+} catch (e) {
+ if (e !== 3)
+ throw new Error("3 should be thrown here");
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/entries.js b/js/src/tests/non262/object/entries.js
new file mode 100644
index 0000000000..1a03ceb421
--- /dev/null
+++ b/js/src/tests/non262/object/entries.js
@@ -0,0 +1,94 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+if ("entries" in Object) {
+ assertEq(Object.entries.length, 1);
+
+ var o, entries;
+
+ o = { a: 3, b: 2 };
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["a", 3], ["b", 2]]);
+
+ o = { get a() { return 17; }, b: 2 };
+ entries = Object.entries(o),
+ assertDeepEq(entries, [["a", 17], ["b", 2]]);
+
+ o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } };
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["__iterator__", o.__iterator__]]);
+
+ o = { a: 1, b: 2 };
+ delete o.a;
+ o.a = 3;
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["b", 2], ["a", 3]]);
+
+ o = [0, 1, 2];
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["0", 0], ["1", 1], ["2", 2]]);
+
+ o = /./.exec("abc");
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["0", "a"], ["index", 0], ["input", "abc"], ["groups", undefined]]);
+
+ o = { a: 1, b: 2, c: 3 };
+ delete o.b;
+ o.b = 5;
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["a", 1], ["c", 3], ["b", 5]]);
+
+ function f() { }
+ f.prototype.p = 1;
+ o = new f();
+ o.g = 1;
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["g", 1]]);
+
+ var o = {get a() {delete this.b; return 1}, b: 2, c: 3};
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["a", 1], ["c", 3]]);
+
+ assertThrowsInstanceOf(() => Object.entries(), TypeError);
+ assertThrowsInstanceOf(() => Object.entries(undefined), TypeError);
+ assertThrowsInstanceOf(() => Object.entries(null), TypeError);
+
+ assertDeepEq(Object.entries(1), []);
+ assertDeepEq(Object.entries(true), []);
+ if (typeof Symbol === "function")
+ assertDeepEq(Object.entries(Symbol("foo")), []);
+
+ assertDeepEq(Object.entries("foo"), [["0", "f"], ["1", "o"], ["2", "o"]]);
+
+ entries = Object.entries({
+ get a(){
+ Object.defineProperty(this, "b", {enumerable: false});
+ return "A";
+ },
+ b: "B"
+ });
+ assertDeepEq(entries, [["a", "A"]]);
+
+ let ownKeysCallCount = 0;
+ let getOwnPropertyDescriptorCalls = [];
+ let target = { a: 1, b: 2, c: 3 };
+ o = new Proxy(target, {
+ ownKeys() {
+ ownKeysCallCount++;
+ return ["c", "a"];
+ },
+ getOwnPropertyDescriptor(target, key) {
+ getOwnPropertyDescriptorCalls.push(key);
+ return Object.getOwnPropertyDescriptor(target, key);
+ }
+ });
+ entries = Object.entries(o);
+ assertEq(ownKeysCallCount, 1);
+ assertDeepEq(entries, [["c", 3], ["a", 1]]);
+ assertDeepEq(getOwnPropertyDescriptorCalls, ["c", "a"]);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/extensibility-01.js b/js/src/tests/non262/object/extensibility-01.js
new file mode 100644
index 0000000000..c001f38254
--- /dev/null
+++ b/js/src/tests/non262/object/extensibility-01.js
@@ -0,0 +1,103 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+var gTestfile = '15.2.3.10-01.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 492849;
+var summary = 'ES5: Implement Object.preventExtensions, Object.isExtensible';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function trySetProperty(o, p, v, strict)
+{
+ function strictSetProperty()
+ {
+ "use strict";
+ o[p] = v;
+ }
+
+ function setProperty()
+ {
+ o[p] = v;
+ }
+
+ assertEq(Object.prototype.hasOwnProperty.call(o, p), false);
+
+ try
+ {
+ if (strict)
+ strictSetProperty();
+ else
+ setProperty();
+ if (o[p] === v)
+ return "set";
+ if (p in o)
+ return "set-converted";
+ return "swallowed";
+ }
+ catch (e)
+ {
+ return "throw";
+ }
+}
+
+function tryDefineProperty(o, p, v)
+{
+ assertEq(Object.prototype.hasOwnProperty.call(o, p), false);
+
+ try
+ {
+ Object.defineProperty(o, p, { value: v });
+ if (o[p] === v)
+ return "set";
+ if (p in o)
+ return "set-converted";
+ return "swallowed";
+ }
+ catch (e)
+ {
+ return "throw";
+ }
+}
+
+assertEq(typeof Object.preventExtensions, "function");
+assertEq(Object.preventExtensions.length, 1);
+
+var slowArray = [1, 2, 3];
+slowArray.slow = 5;
+var objs =
+ [{}, { 1: 2 }, { a: 3 }, [], [1], [, 1], slowArray, function a(){}, /a/];
+
+for (var i = 0, sz = objs.length; i < sz; i++)
+{
+ var o = objs[i];
+ assertEq(Object.isExtensible(o), true, "object " + i + " not extensible?");
+
+ var o2 = Object.preventExtensions(o);
+ assertEq(o, o2);
+
+ assertEq(Object.isExtensible(o), false, "object " + i + " is extensible?");
+
+ assertEq(trySetProperty(o, "baz", 17, true), "throw",
+ "unexpected behavior for strict-mode property-addition to " +
+ "object " + i);
+ assertEq(trySetProperty(o, "baz", 17, false), "swallowed",
+ "unexpected behavior for property-addition to object " + i);
+
+ assertEq(tryDefineProperty(o, "baz", 17), "throw",
+ "unexpected behavior for new property definition on object " + i);
+}
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/extensibility-02.js b/js/src/tests/non262/object/extensibility-02.js
new file mode 100644
index 0000000000..c61e367281
--- /dev/null
+++ b/js/src/tests/non262/object/extensibility-02.js
@@ -0,0 +1,42 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+var gTestfile = '15.2.3.4-01.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 492849;
+var summary = 'ES5: Implement Object.preventExtensions, Object.isExtensible';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+assertEq(typeof Object.isExtensible, "function");
+assertEq(Object.isExtensible.length, 1);
+
+var slowArray = [1, 2, 3];
+slowArray.slow = 5;
+var objs =
+ [{}, { 1: 2 }, { a: 3 }, [], [1], [, 1], slowArray, function a(){}, /a/];
+
+for (var i = 0, sz = objs.length; i < sz; i++)
+{
+ var o = objs[i];
+ assertEq(Object.isExtensible(o), true, "object " + i + " not extensible?");
+
+ var o2 = Object.preventExtensions(o);
+ assertEq(o, o2);
+
+ assertEq(Object.isExtensible(o), false, "object " + i + " is extensible?");
+}
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/freeze-global-eval-const.js b/js/src/tests/non262/object/freeze-global-eval-const.js
new file mode 100644
index 0000000000..a43f5c51c9
--- /dev/null
+++ b/js/src/tests/non262/object/freeze-global-eval-const.js
@@ -0,0 +1,13 @@
+// |reftest| skip-if(!xulRuntime.shell) -- uses evalcx
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+try {
+ evalcx("Object.freeze(this); eval('const q = undefined;')");
+} catch (e) {
+ assertEq(e.message, "({lazy:false}) is not extensible");
+}
+
+reportCompare(0, 0, "don't crash");
diff --git a/js/src/tests/non262/object/freeze-proxy.js b/js/src/tests/non262/object/freeze-proxy.js
new file mode 100644
index 0000000000..3d95a28d4f
--- /dev/null
+++ b/js/src/tests/non262/object/freeze-proxy.js
@@ -0,0 +1,27 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function logProxy(object = {}, handler = {}) {
+ var log = [];
+ var proxy = new Proxy(object, new Proxy(handler, {
+ get(target, propertyKey, receiver) {
+ log.push(propertyKey);
+ return target[propertyKey];
+ }
+ }));
+ return {proxy, log};
+}
+
+// The order of operations is backwards when compared to ES6 draft rev 27
+// (2014 August 24), but see https://bugs.ecmascript.org/show_bug.cgi?id=3215
+// for an explanation on why the spec version is clearly wrong.
+
+var {proxy, log} = logProxy();
+Object.freeze(proxy);
+assertDeepEq(log, ["preventExtensions", "ownKeys"]);
+
+var {proxy, log} = logProxy();
+Object.freeze(Object.freeze(proxy));
+assertDeepEq(log, ["preventExtensions", "ownKeys", "preventExtensions", "ownKeys"]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/freeze.js b/js/src/tests/non262/object/freeze.js
new file mode 100644
index 0000000000..18f71f76d6
--- /dev/null
+++ b/js/src/tests/non262/object/freeze.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1076588;
+var summary = "Object.freeze() should return its argument with no conversion when the argument is a primitive value";
+
+print(BUGNUMBER + ": " + summary);
+assertEq(Object.freeze(), undefined);
+assertEq(Object.freeze(undefined), undefined);
+assertEq(Object.freeze(null), null);
+assertEq(Object.freeze(1), 1);
+assertEq(Object.freeze("foo"), "foo");
+assertEq(Object.freeze(true), true);
+if (typeof Symbol === "function") {
+ assertEq(Object.freeze(Symbol.for("foo")), Symbol.for("foo"));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/gOPD-vs-prototype-accessor.js b/js/src/tests/non262/object/gOPD-vs-prototype-accessor.js
new file mode 100644
index 0000000000..472887f90b
--- /dev/null
+++ b/js/src/tests/non262/object/gOPD-vs-prototype-accessor.js
@@ -0,0 +1,15 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+assertEq(function testcase() {
+ var proto = {};
+ Object.defineProperty(proto, "prop", {get: function () {return {};}, enumerable: true});
+ var ConstructFun = function () {};
+ ConstructFun.prototype = proto;
+ var child = new ConstructFun;
+ return Object.getOwnPropertyNames(child).indexOf('prop');
+}(), -1);
+
+reportCompare(0, 0, "ok");
diff --git a/js/src/tests/non262/object/getOwnPropertyDescriptor.js b/js/src/tests/non262/object/getOwnPropertyDescriptor.js
new file mode 100644
index 0000000000..7aaba7b5ee
--- /dev/null
+++ b/js/src/tests/non262/object/getOwnPropertyDescriptor.js
@@ -0,0 +1,35 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1079188;
+var summary = "Coerce the argument passed to Object.getOwnPropertyDescriptor using ToObject";
+print(BUGNUMBER + ": " + summary);
+
+assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(), TypeError);
+assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(undefined), TypeError);
+assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(null), TypeError);
+
+Object.getOwnPropertyDescriptor(1);
+Object.getOwnPropertyDescriptor(true);
+if (typeof Symbol === "function") {
+ Object.getOwnPropertyDescriptor(Symbol("foo"));
+}
+
+assertDeepEq(Object.getOwnPropertyDescriptor("foo", "length"), {
+ value: 3,
+ writable: false,
+ enumerable: false,
+ configurable: false
+});
+
+assertDeepEq(Object.getOwnPropertyDescriptor("foo", 0), {
+ value: "f",
+ writable: false,
+ enumerable: true,
+ configurable: false
+});
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/getOwnPropertySymbols-proxy.js b/js/src/tests/non262/object/getOwnPropertySymbols-proxy.js
new file mode 100644
index 0000000000..c538b3015c
--- /dev/null
+++ b/js/src/tests/non262/object/getOwnPropertySymbols-proxy.js
@@ -0,0 +1,28 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// getOwnPropertySymbols(proxy) calls the getOwnPropertyNames hook (only).
+
+var symbols = [Symbol(), Symbol("moon"), Symbol.for("sun"), Symbol.iterator];
+var hits = 0;
+
+function HandlerProxy() {
+ return new Proxy({}, {
+ get: function (t, key) {
+ if (key !== "ownKeys")
+ throw new Error("tried to access handler[" + String(key) + "]");
+ hits++;
+ return t => symbols;
+ }
+ });
+}
+
+function OwnKeysProxy() {
+ return new Proxy({}, new HandlerProxy);
+}
+
+assertDeepEq(Object.getOwnPropertySymbols(new OwnKeysProxy), symbols);
+assertEq(hits, 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/getOwnPropertySymbols.js b/js/src/tests/non262/object/getOwnPropertySymbols.js
new file mode 100644
index 0000000000..b92d14ef17
--- /dev/null
+++ b/js/src/tests/non262/object/getOwnPropertySymbols.js
@@ -0,0 +1,46 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+assertDeepEq(Object.getOwnPropertySymbols({}), []);
+
+// String keys are ignored.
+assertEq(Object.getOwnPropertySymbols({a: 1, b: 2}).length, 0);
+assertEq(Object.getOwnPropertySymbols([0, 1, 2, 3]).length, 0);
+
+// Symbol keys are observed.
+var iterable = {};
+Object.defineProperty(iterable, Symbol.iterator, {
+ value: () => [][Symbol.iterator]()
+});
+assertDeepEq(Object.getOwnPropertySymbols(iterable), [Symbol.iterator]);
+assertDeepEq(Object.getOwnPropertySymbols(new Proxy(iterable, {})), [Symbol.iterator]);
+
+// Test on an object with a thousand own properties.
+var obj = {};
+for (var i = 0; i < 1000; i++) {
+ obj[Symbol.for("x" + i)] = 1;
+}
+assertEq(Object.getOwnPropertyNames(obj).length, 0);
+var symbols = Object.getOwnPropertySymbols(obj);
+assertEq(symbols.length, 1000);
+assertEq(symbols.indexOf(Symbol.for("x0")) !== -1, true);
+assertEq(symbols.indexOf(Symbol.for("x241")) !== -1, true);
+assertEq(symbols.indexOf(Symbol.for("x999")) !== -1, true);
+assertEq(Object.getOwnPropertySymbols(new Proxy(obj, {})).length, 1000);
+
+// The prototype chain is not consulted.
+assertEq(Object.getOwnPropertySymbols(Object.create(obj)).length, 0);
+assertEq(Object.getOwnPropertySymbols(new Proxy(Object.create(obj), {})).length, 0);
+
+// Primitives are coerced to objects; but there are never any symbol-keyed
+// properties on the resulting wrapper objects.
+assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(), TypeError);
+assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(undefined), TypeError);
+assertThrowsInstanceOf(() => Object.getOwnPropertySymbols(null), TypeError);
+for (var primitive of [true, 1, 3.14, "hello", Symbol()])
+ assertEq(Object.getOwnPropertySymbols(primitive).length, 0);
+
+assertEq(Object.getOwnPropertySymbols.length, 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/getPrototypeOf-array.js b/js/src/tests/non262/object/getPrototypeOf-array.js
new file mode 100644
index 0000000000..e482f89be7
--- /dev/null
+++ b/js/src/tests/non262/object/getPrototypeOf-array.js
@@ -0,0 +1,32 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'getPrototypeOf-array.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(Object.getPrototypeOf(objWithArrPrototype), arr);
+var objWithArrGrandPrototype = Object.create(objWithArrPrototype);
+assertEq(!Array.isArray(objWithArrGrandPrototype), true);
+assertEq(Object.getPrototypeOf(objWithArrGrandPrototype), objWithArrPrototype);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/non262/object/getPrototypeOf.js b/js/src/tests/non262/object/getPrototypeOf.js
new file mode 100644
index 0000000000..71cd30c62c
--- /dev/null
+++ b/js/src/tests/non262/object/getPrototypeOf.js
@@ -0,0 +1,22 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1079090;
+var summary = "Coerce the argument passed to Object.getPrototypeOf using ToObject";
+print(BUGNUMBER + ": " + summary);
+
+assertThrowsInstanceOf(() => Object.getPrototypeOf(), TypeError);
+assertThrowsInstanceOf(() => Object.getPrototypeOf(undefined), TypeError);
+assertThrowsInstanceOf(() => Object.getPrototypeOf(null), TypeError);
+
+assertEq(Object.getPrototypeOf(1), Number.prototype);
+assertEq(Object.getPrototypeOf(true), Boolean.prototype);
+assertEq(Object.getPrototypeOf("foo"), String.prototype);
+if (typeof Symbol === "function") {
+ assertEq(Object.getPrototypeOf(Symbol("foo")), Symbol.prototype);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/getter-name.js b/js/src/tests/non262/object/getter-name.js
new file mode 100644
index 0000000000..601d6b4778
--- /dev/null
+++ b/js/src/tests/non262/object/getter-name.js
@@ -0,0 +1,10 @@
+var BUGNUMBER = 1180290;
+var summary = 'Object accessors should have get prefix';
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").get.name, "get __proto__");
+assertEq(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set.name, "set __proto__");
+
+if (typeof reportCompare === 'function')
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/hasOwn.js b/js/src/tests/non262/object/hasOwn.js
new file mode 100644
index 0000000000..cb9ebda5db
--- /dev/null
+++ b/js/src/tests/non262/object/hasOwn.js
@@ -0,0 +1,18 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+assertEq(Object.hasOwn({}, "any"), false);
+assertThrowsInstanceOf(() => Object.hasOwn(null, "any"), TypeError);
+
+var x = { test: 'test value'}
+var y = {}
+var z = Object.create(x);
+
+assertEq(Object.hasOwn(x, "test"), true);
+assertEq(Object.hasOwn(y, "test"), false);
+assertEq(Object.hasOwn(z, "test"), false);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/isExtensible.js b/js/src/tests/non262/object/isExtensible.js
new file mode 100644
index 0000000000..f1fa008782
--- /dev/null
+++ b/js/src/tests/non262/object/isExtensible.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 1060873;
+var summary = "Object.isExtensible() should return false when given primitive values as input";
+
+print(BUGNUMBER + ": " + summary);
+assertEq(Object.isExtensible(), false);
+assertEq(Object.isExtensible(undefined), false);
+assertEq(Object.isExtensible(null), false);
+assertEq(Object.isExtensible(1), false);
+assertEq(Object.isExtensible("foo"), false);
+assertEq(Object.isExtensible(true), false);
+if (typeof Symbol === "function") {
+ assertEq(Object.isExtensible(Symbol()), false);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/isFrozen.js b/js/src/tests/non262/object/isFrozen.js
new file mode 100644
index 0000000000..02056802d7
--- /dev/null
+++ b/js/src/tests/non262/object/isFrozen.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1071464;
+var summary = "Object.isFrozen() should return true when given primitive values as input";
+
+print(BUGNUMBER + ": " + summary);
+assertEq(Object.isFrozen(), true);
+assertEq(Object.isFrozen(undefined), true);
+assertEq(Object.isFrozen(null), true);
+assertEq(Object.isFrozen(1), true);
+assertEq(Object.isFrozen("foo"), true);
+assertEq(Object.isFrozen(true), true);
+if (typeof Symbol === "function") {
+ assertEq(Object.isFrozen(Symbol()), true);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/isPrototypeOf.js b/js/src/tests/non262/object/isPrototypeOf.js
new file mode 100644
index 0000000000..a2d78f6507
--- /dev/null
+++ b/js/src/tests/non262/object/isPrototypeOf.js
@@ -0,0 +1,86 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'isPrototypeOf.js';
+var BUGNUMBER = 619283;
+var summary = "Object.prototype.isPrototypeOf";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function expectThrowTypeError(fun)
+{
+ try
+ {
+ var r = fun();
+ throw new Error("didn't throw TypeError, returned " + r);
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "didn't throw TypeError, got: " + e);
+ }
+}
+
+var isPrototypeOf = Object.prototype.isPrototypeOf;
+
+/*
+ * 1. If V is not an Object, return false.
+ */
+assertEq(isPrototypeOf(), false);
+assertEq(isPrototypeOf(1), false);
+assertEq(isPrototypeOf(Number.MAX_VALUE), false);
+assertEq(isPrototypeOf(NaN), false);
+assertEq(isPrototypeOf(""), false);
+assertEq(isPrototypeOf("sesquicentennial"), false);
+assertEq(isPrototypeOf(true), false);
+assertEq(isPrototypeOf(false), false);
+assertEq(isPrototypeOf(0.72), false);
+assertEq(isPrototypeOf(undefined), false);
+assertEq(isPrototypeOf(null), false);
+
+
+/*
+ * 2. Let O be the result of calling ToObject passing the this value as the
+ * argument.
+ */
+var protoGlobal = Object.create(this);
+expectThrowTypeError(function() { isPrototypeOf.call(null, {}); });
+expectThrowTypeError(function() { isPrototypeOf.call(undefined, {}); });
+expectThrowTypeError(function() { isPrototypeOf({}); });
+expectThrowTypeError(function() { isPrototypeOf.call(null, protoGlobal); });
+expectThrowTypeError(function() { isPrototypeOf.call(undefined, protoGlobal); });
+expectThrowTypeError(function() { isPrototypeOf(protoGlobal); });
+
+
+/*
+ * 3. Repeat
+ */
+
+/*
+ * 3a. Let V be the value of the [[Prototype]] internal property of V.
+ * 3b. If V is null, return false.
+ */
+assertEq(Object.prototype.isPrototypeOf(Object.prototype), false);
+assertEq(String.prototype.isPrototypeOf({}), false);
+assertEq(Object.prototype.isPrototypeOf(Object.create(null)), false);
+
+/* 3c. If O and V refer to the same object, return true. */
+assertEq(Object.prototype.isPrototypeOf({}), true);
+assertEq(this.isPrototypeOf(protoGlobal), true);
+assertEq(Object.prototype.isPrototypeOf({}), true);
+assertEq(Object.prototype.isPrototypeOf(new Number(17)), true);
+assertEq(Object.prototype.isPrototypeOf(function(){}), true);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/isSealed.js b/js/src/tests/non262/object/isSealed.js
new file mode 100644
index 0000000000..cd363a87e1
--- /dev/null
+++ b/js/src/tests/non262/object/isSealed.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1062860;
+var summary = "Object.isSealed() should return true when given primitive values as input";
+
+print(BUGNUMBER + ": " + summary);
+assertEq(Object.isSealed(), true);
+assertEq(Object.isSealed(undefined), true);
+assertEq(Object.isSealed(null), true);
+assertEq(Object.isSealed(1), true);
+assertEq(Object.isSealed("foo"), true);
+assertEq(Object.isSealed(true), true);
+if (typeof Symbol === "function") {
+ assertEq(Object.isSealed(Symbol()), true);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/keys.js b/js/src/tests/non262/object/keys.js
new file mode 100644
index 0000000000..5766f16d11
--- /dev/null
+++ b/js/src/tests/non262/object/keys.js
@@ -0,0 +1,23 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1038545;
+var summary = "Coerce the argument passed to Object.keys using ToObject";
+print(BUGNUMBER + ": " + summary);
+
+assertThrowsInstanceOf(() => Object.keys(), TypeError);
+assertThrowsInstanceOf(() => Object.keys(undefined), TypeError);
+assertThrowsInstanceOf(() => Object.keys(null), TypeError);
+
+assertDeepEq(Object.keys(1), []);
+assertDeepEq(Object.keys(true), []);
+if (typeof Symbol === "function") {
+ assertDeepEq(Object.keys(Symbol("foo")), []);
+}
+
+assertDeepEq(Object.keys("foo"), ["0", "1", "2"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/method-non-constructor.js b/js/src/tests/non262/object/method-non-constructor.js
new file mode 100644
index 0000000000..fd1d589b97
--- /dev/null
+++ b/js/src/tests/non262/object/method-non-constructor.js
@@ -0,0 +1,12 @@
+var obj = { method() { } };
+assertThrowsInstanceOf(() => {
+ new obj.method;
+}, TypeError);
+
+obj = { constructor() { } };
+assertThrowsInstanceOf(() => {
+ new obj.constructor;
+}, TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/mutation-prevention-methods.js b/js/src/tests/non262/object/mutation-prevention-methods.js
new file mode 100644
index 0000000000..01b4c19cbe
--- /dev/null
+++ b/js/src/tests/non262/object/mutation-prevention-methods.js
@@ -0,0 +1,124 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+var gTestfile = 'mutation-prevention-methods.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 492849;
+var summary = 'Object.is{Sealed,Frozen}, Object.{seal,freeze}';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// Empty object
+
+var o1 = {};
+
+assertEq(Object.isExtensible(o1), true);
+assertEq(Object.isSealed(o1), false);
+assertEq(Object.isFrozen(o1), false);
+
+Object.preventExtensions(o1);
+
+// An non-extensible empty object has no properties, so it is vacuously sealed
+// and frozen.
+assertEq(Object.isExtensible(o1), false);
+assertEq(Object.isSealed(o1), true);
+assertEq(Object.isFrozen(o1), true);
+
+
+// Object with a data property
+
+var o2 = { 1: 2 };
+
+assertEq(Object.isExtensible(o2), true);
+assertEq(Object.isSealed(o2), false);
+assertEq(Object.isFrozen(o2), false);
+
+Object.preventExtensions(o2);
+
+assertEq(Object.isExtensible(o2), false);
+assertEq(Object.isSealed(o2), false);
+assertEq(Object.isFrozen(o2), false);
+
+Object.seal(o2);
+
+assertEq(Object.isExtensible(o2), false);
+assertEq(Object.isSealed(o2), true);
+assertEq(Object.isFrozen(o2), false);
+
+assertEq(o2[1], 2);
+
+var desc;
+
+desc = Object.getOwnPropertyDescriptor(o2, "1");
+assertEq(typeof desc, "object");
+assertEq(desc.enumerable, true);
+assertEq(desc.configurable, false);
+assertEq(desc.value, 2);
+assertEq(desc.writable, true);
+
+o2[1] = 17;
+
+assertEq(o2[1], 17);
+
+desc = Object.getOwnPropertyDescriptor(o2, "1");
+assertEq(typeof desc, "object");
+assertEq(desc.enumerable, true);
+assertEq(desc.configurable, false);
+assertEq(desc.value, 17);
+assertEq(desc.writable, true);
+
+Object.freeze(o2);
+
+assertEq(o2[1], 17);
+
+desc = Object.getOwnPropertyDescriptor(o2, "1");
+assertEq(typeof desc, "object");
+assertEq(desc.enumerable, true);
+assertEq(desc.configurable, false);
+assertEq(desc.value, 17);
+assertEq(desc.writable, false);
+
+
+// Object with an accessor property
+
+var o3 = { get foo() { return 17; } };
+
+assertEq(Object.isExtensible(o3), true);
+assertEq(Object.isSealed(o3), false);
+assertEq(Object.isFrozen(o3), false);
+
+Object.preventExtensions(o3);
+
+assertEq(Object.isExtensible(o3), false);
+assertEq(Object.isSealed(o3), false);
+assertEq(Object.isFrozen(o3), false);
+
+Object.seal(o3);
+
+// An accessor property in a sealed object is unchanged if that object is
+// frozen, so a sealed object containing only accessor properties is also
+// vacuously frozen.
+assertEq(Object.isExtensible(o3), false);
+assertEq(Object.isSealed(o3), true);
+assertEq(Object.isFrozen(o3), true);
+
+Object.freeze(o3);
+
+assertEq(Object.isExtensible(o3), false);
+assertEq(Object.isSealed(o3), true);
+assertEq(Object.isFrozen(o3), true);
+
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/object-create-with-primitive-second-arg.js b/js/src/tests/non262/object/object-create-with-primitive-second-arg.js
new file mode 100644
index 0000000000..44afd53c25
--- /dev/null
+++ b/js/src/tests/non262/object/object-create-with-primitive-second-arg.js
@@ -0,0 +1,8 @@
+[1, "", true, Symbol(), undefined].forEach(props => {
+ assertEq(Object.getPrototypeOf(Object.create(null, props)), null);
+});
+
+assertThrowsInstanceOf(() => Object.create(null, null), TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/object-toString-01.js b/js/src/tests/non262/object/object-toString-01.js
new file mode 100644
index 0000000000..6a8c4e86a9
--- /dev/null
+++ b/js/src/tests/non262/object/object-toString-01.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 gTestfile = 'object-toString-01.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 575522;
+var summary = '({}).toString.call(null) == "[object Null]", ' +
+ '({}).toString.call(undefined) == "[object Undefined]", ';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var toString = Object.prototype.toString;
+
+assertEq(toString.call(null), "[object Null]");
+assertEq(toString.call(undefined), "[object Undefined]");
+
+assertEq(toString.call(true), "[object Boolean]");
+assertEq(toString.call(false), "[object Boolean]");
+
+assertEq(toString.call(0), "[object Number]");
+assertEq(toString.call(-0), "[object Number]");
+assertEq(toString.call(1), "[object Number]");
+assertEq(toString.call(-1), "[object Number]");
+assertEq(toString.call(NaN), "[object Number]");
+assertEq(toString.call(Infinity), "[object Number]");
+assertEq(toString.call(-Infinity), "[object Number]");
+
+assertEq(toString.call("foopy"), "[object String]");
+
+assertEq(toString.call({}), "[object Object]");
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/preventExtensions-idempotent.js b/js/src/tests/non262/object/preventExtensions-idempotent.js
new file mode 100644
index 0000000000..c0b16d890f
--- /dev/null
+++ b/js/src/tests/non262/object/preventExtensions-idempotent.js
@@ -0,0 +1,30 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor:
+ * Jeff Walden <jwalden+code@mit.edu>
+ */
+
+var gTestfile = 'preventExtensions-idempotent.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 599459;
+var summary = 'Object.preventExtensions should be idempotent';
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var obj = {};
+assertEq(Object.preventExtensions(obj), obj);
+assertEq(Object.isExtensible(obj), false);
+assertEq(Object.preventExtensions(obj), obj);
+assertEq(Object.isExtensible(obj), false);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/preventExtensions-proxy.js b/js/src/tests/non262/object/preventExtensions-proxy.js
new file mode 100644
index 0000000000..347a63bc3a
--- /dev/null
+++ b/js/src/tests/non262/object/preventExtensions-proxy.js
@@ -0,0 +1,23 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function logProxy(object = {}, handler = {}) {
+ var log = [];
+ var proxy = new Proxy(object, new Proxy(handler, {
+ get(target, propertyKey, receiver) {
+ log.push(propertyKey);
+ return target[propertyKey];
+ }
+ }));
+ return {proxy, log};
+}
+
+var {proxy, log} = logProxy();
+Object.preventExtensions(proxy);
+assertDeepEq(log, ["preventExtensions"]);
+
+var {proxy, log} = logProxy();
+Object.preventExtensions(Object.preventExtensions(proxy));
+assertDeepEq(log, ["preventExtensions", "preventExtensions"]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/preventExtensions.js b/js/src/tests/non262/object/preventExtensions.js
new file mode 100644
index 0000000000..75c8ed3db5
--- /dev/null
+++ b/js/src/tests/non262/object/preventExtensions.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1073446;
+var summary = "Object.preventExtensions() should return its argument with no conversion when the argument is a primitive value";
+
+print(BUGNUMBER + ": " + summary);
+assertEq(Object.preventExtensions(), undefined);
+assertEq(Object.preventExtensions(undefined), undefined);
+assertEq(Object.preventExtensions(null), null);
+assertEq(Object.preventExtensions(1), 1);
+assertEq(Object.preventExtensions("foo"), "foo");
+assertEq(Object.preventExtensions(true), true);
+if (typeof Symbol === "function") {
+ assertEq(Object.preventExtensions(Symbol.for("foo")), Symbol.for("foo"));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/property-descriptor-order.js b/js/src/tests/non262/object/property-descriptor-order.js
new file mode 100644
index 0000000000..337d247dae
--- /dev/null
+++ b/js/src/tests/non262/object/property-descriptor-order.js
@@ -0,0 +1,17 @@
+var names = Object.getOwnPropertyNames(Object.getOwnPropertyDescriptor({foo: 0}, "foo"));
+assertDeepEq(names, ["value", "writable", "enumerable", "configurable"]);
+
+names = Object.getOwnPropertyNames(Object.getOwnPropertyDescriptor({get foo(){}}, "foo"));
+assertDeepEq(names, ["get", "set", "enumerable", "configurable"]);
+
+var proxy = new Proxy({}, {
+ defineProperty(target, key, desc) {
+ var names = Object.getOwnPropertyNames(desc);
+ assertDeepEq(names, ["set", "configurable"]);
+ return true;
+ }
+});
+
+Object.defineProperty(proxy, "foo", {configurable: true, set: function() {}});
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/object/propertyIsEnumerable-proxy.js b/js/src/tests/non262/object/propertyIsEnumerable-proxy.js
new file mode 100644
index 0000000000..a1dda90e0a
--- /dev/null
+++ b/js/src/tests/non262/object/propertyIsEnumerable-proxy.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function logProxy(object) {
+ var log = [];
+ var handler = {
+ getOwnPropertyDescriptor(target, propertyKey) {
+ log.push(propertyKey);
+ return Object.getOwnPropertyDescriptor(target, propertyKey);
+ }
+ };
+ var proxy = new Proxy(object, new Proxy(handler, {
+ get(target, propertyKey, receiver) {
+ if (!(propertyKey in target)) {
+ throw new Error(`Unexpected call to trap: "${propertyKey}"`);
+ }
+ return target[propertyKey];
+ }
+ }));
+ return {proxy, log};
+}
+
+var properties = ["string-property"];
+if (typeof Symbol === 'function')
+ properties.push(Symbol("symbol-property"));
+
+for (var property of properties) {
+ // Test 1: property is not present on object
+ var {proxy, log} = logProxy({});
+ var result = Object.prototype.propertyIsEnumerable.call(proxy, property);
+ assertEq(result, false);
+ assertDeepEq(log, [property]);
+
+ // Test 2: property is present on object and enumerable
+ var {proxy, log} = logProxy({[property]: 0});
+ var result = Object.prototype.propertyIsEnumerable.call(proxy, property);
+ assertEq(result, true);
+ assertDeepEq(log, [property]);
+
+ // Test 3: property is present on object, but not enumerable
+ var {proxy, log} = logProxy(Object.defineProperty({[property]: 0}, property, {enumerable: false}));
+ var result = Object.prototype.propertyIsEnumerable.call(proxy, property);
+ assertEq(result, false);
+ assertDeepEq(log, [property]);
+
+ // Test 4: property is present on prototype object
+ var {proxy, log} = logProxy(Object.create({[property]: 0}));
+ var result = Object.prototype.propertyIsEnumerable.call(proxy, property);
+ assertEq(result, false);
+ assertDeepEq(log, [property]);
+
+ // Test 5: property is present on prototype object, prototype is proxy object
+ var {proxy, log} = logProxy({[property]: 0});
+ var result = Object.prototype.propertyIsEnumerable.call(Object.create(proxy), property);
+ assertEq(result, false);
+ assertDeepEq(log, []);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/propertyIsEnumerable.js b/js/src/tests/non262/object/propertyIsEnumerable.js
new file mode 100644
index 0000000000..e9b09d0bfb
--- /dev/null
+++ b/js/src/tests/non262/object/propertyIsEnumerable.js
@@ -0,0 +1,199 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'propertyIsEnumerable.js';
+var BUGNUMBER = 619283;
+var summary = "Object.prototype.propertyIsEnumerable";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function expectThrowError(errorCtor, fun)
+{
+ try
+ {
+ var r = fun();
+ throw "didn't throw TypeError, returned " + r;
+ }
+ catch (e)
+ {
+ assertEq(e instanceof errorCtor, true,
+ "didn't throw " + errorCtor.prototype.name + ", got: " + e);
+ }
+}
+
+function expectThrowTypeError(fun)
+{
+ expectThrowError(TypeError, fun);
+}
+
+function withToString(fun)
+{
+ return { toString: fun };
+}
+
+function withValueOf(fun)
+{
+ return { toString: null, valueOf: fun };
+}
+
+var propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
+
+/*
+ * 1. Let P be ToString(V).
+ */
+expectThrowError(ReferenceError, function()
+{
+ propertyIsEnumerable(withToString(function() { fahslkjdfhlkjdsl; }));
+});
+expectThrowError(ReferenceError, function()
+{
+ propertyIsEnumerable.call(null, withToString(function() { fahslkjdfhlkjdsl; }));
+});
+expectThrowError(ReferenceError, function()
+{
+ propertyIsEnumerable.call(undefined, withToString(function() { fahslkjdfhlkjdsl; }));
+});
+
+expectThrowError(ReferenceError, function()
+{
+ propertyIsEnumerable(withValueOf(function() { fahslkjdfhlkjdsl; }));
+});
+expectThrowError(ReferenceError, function()
+{
+ propertyIsEnumerable.call(null, withValueOf(function() { fahslkjdfhlkjdsl; }));
+});
+expectThrowError(ReferenceError, function()
+{
+ propertyIsEnumerable.call(undefined, withValueOf(function() { fahslkjdfhlkjdsl; }));
+});
+
+expectThrowError(SyntaxError, function()
+{
+ propertyIsEnumerable(withToString(function() { eval("}"); }));
+});
+expectThrowError(SyntaxError, function()
+{
+ propertyIsEnumerable.call(null, withToString(function() { eval("}"); }));
+});
+expectThrowError(SyntaxError, function()
+{
+ propertyIsEnumerable.call(undefined, withToString(function() { eval("}"); }));
+});
+
+expectThrowError(SyntaxError, function()
+{
+ propertyIsEnumerable(withValueOf(function() { eval("}"); }));
+});
+expectThrowError(SyntaxError, function()
+{
+ propertyIsEnumerable.call(null, withValueOf(function() { eval("}"); }));
+});
+expectThrowError(SyntaxError, function()
+{
+ propertyIsEnumerable.call(undefined, withValueOf(function() { eval("}"); }));
+});
+
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable(withToString(function() { [].length = -1; }));
+});
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable.call(null, withToString(function() { [].length = -1; }));
+});
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable.call(undefined, withToString(function() { [].length = -1; }));
+});
+
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable(withValueOf(function() { [].length = -1; }));
+});
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable.call(null, withValueOf(function() { [].length = -1; }));
+});
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable.call(undefined, withValueOf(function() { [].length = -1; }));
+});
+
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable(withToString(function() { [].length = 0.7; }));
+});
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable.call(null, withToString(function() { [].length = 0.7; }));
+});
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable.call(undefined, withToString(function() { [].length = 0.7; }));
+});
+
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable(withValueOf(function() { [].length = 0.7; }));
+});
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable.call(null, withValueOf(function() { [].length = 0.7; }));
+});
+expectThrowError(RangeError, function()
+{
+ propertyIsEnumerable.call(undefined, withValueOf(function() { [].length = 0.7; }));
+});
+
+/*
+ * 2. Let O be the result of calling ToObject passing the this value as the
+ * argument.
+ */
+expectThrowTypeError(function() { propertyIsEnumerable("s"); });
+expectThrowTypeError(function() { propertyIsEnumerable.call(null, "s"); });
+expectThrowTypeError(function() { propertyIsEnumerable.call(undefined, "s"); });
+expectThrowTypeError(function() { propertyIsEnumerable(true); });
+expectThrowTypeError(function() { propertyIsEnumerable.call(null, true); });
+expectThrowTypeError(function() { propertyIsEnumerable.call(undefined, true); });
+expectThrowTypeError(function() { propertyIsEnumerable(NaN); });
+expectThrowTypeError(function() { propertyIsEnumerable.call(null, NaN); });
+expectThrowTypeError(function() { propertyIsEnumerable.call(undefined, NaN); });
+
+expectThrowTypeError(function() { propertyIsEnumerable({}); });
+expectThrowTypeError(function() { propertyIsEnumerable.call(null, {}); });
+expectThrowTypeError(function() { propertyIsEnumerable.call(undefined, {}); });
+
+/*
+ * 3. Let desc be the result of calling the [[GetOwnProperty]] internal method
+ * of O passing P as the argument.
+ * 4. If desc is undefined, return false.
+ */
+assertEq(propertyIsEnumerable.call({}, "valueOf"), false);
+assertEq(propertyIsEnumerable.call({}, "toString"), false);
+assertEq(propertyIsEnumerable.call("s", 1), false);
+assertEq(propertyIsEnumerable.call({}, "dsfiodjfs"), false);
+assertEq(propertyIsEnumerable.call(true, "toString"), false);
+assertEq(propertyIsEnumerable.call({}, "__proto__"), false);
+
+assertEq(propertyIsEnumerable.call(Object, "getOwnPropertyDescriptor"), false);
+assertEq(propertyIsEnumerable.call(this, "expectThrowTypeError"), true);
+assertEq(propertyIsEnumerable.call("s", "length"), false);
+assertEq(propertyIsEnumerable.call("s", 0), true);
+assertEq(propertyIsEnumerable.call(Number, "MAX_VALUE"), false);
+assertEq(propertyIsEnumerable.call({ x: 9 }, "x"), true);
+assertEq(propertyIsEnumerable.call(function() { }, "prototype"), false);
+assertEq(propertyIsEnumerable.call(function() { }, "length"), false);
+assertEq(propertyIsEnumerable.call(function() { "use strict"; }, "caller"), false);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/proto-property-change-writability-set.js b/js/src/tests/non262/object/proto-property-change-writability-set.js
new file mode 100644
index 0000000000..d81f844e93
--- /dev/null
+++ b/js/src/tests/non262/object/proto-property-change-writability-set.js
@@ -0,0 +1,56 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributors:
+ * Gary Kwong
+ * Jeff Walden
+ * Jason Orendorff
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 713944;
+var summary =
+ "Don't assert anything about a shape from the property cache until it's " +
+ "known the cache entry matches";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var accDesc = { set: function() {} };
+var dataDesc = { value: 3 };
+
+function f()
+{
+ propertyIsEnumerable = {};
+}
+function g()
+{
+ propertyIsEnumerable = {};
+}
+
+Object.defineProperty(Object.prototype, "propertyIsEnumerable", accDesc);
+f();
+Object.defineProperty(Object.prototype, "propertyIsEnumerable", dataDesc);
+assertEq(propertyIsEnumerable, 3);
+f();
+assertEq(propertyIsEnumerable, 3);
+g();
+assertEq(propertyIsEnumerable, 3);
+
+
+
+var a = { p1: 1, p2: 2 };
+var b = Object.create(a);
+Object.defineProperty(a, "p1", {set: function () {}});
+for (var i = 0; i < 2; i++)
+{
+ b.p1 = {};
+ Object.defineProperty(a, "p1", {value: 3});
+}
+assertEq(b.p1, 3);
+assertEq(a.p1, 3);
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/object/regress-137000.js b/js/src/tests/non262/object/regress-137000.js
new file mode 100644
index 0000000000..7e4ce268dd
--- /dev/null
+++ b/js/src/tests/non262/object/regress-137000.js
@@ -0,0 +1,203 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ *
+ * Date: 03 June 2002
+ * SUMMARY: Function param or local var with same name as a function property
+ *
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=137000
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=138708
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=150032
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=150859
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 137000;
+var summary = 'Function param or local var with same name as a function prop';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+
+/*
+ * Note use of 'x' both for the parameter to f,
+ * and as a property name for |f| as an object
+ */
+function f(x)
+{
+}
+
+status = inSection(1);
+f.x = 12;
+actual = f.x;
+expect = 12;
+addThis();
+
+
+
+/*
+ * A more elaborate example, using the call() method
+ * to chain constructors from child to parent.
+ *
+ * The key point is the use of the same name 'p' for both
+ * the parameter to the constructor, and as a property name
+ */
+function parentObject(p)
+{
+ this.p = 1;
+}
+
+function childObject()
+{
+ parentObject.call(this);
+}
+childObject.prototype = parentObject;
+
+status = inSection(2);
+var objParent = new parentObject();
+actual = objParent.p;
+expect = 1;
+addThis();
+
+status = inSection(3);
+var objChild = new childObject();
+actual = objChild.p;
+expect = 1;
+addThis();
+
+
+
+/*
+ * A similar set-up. Here the same name is being used for
+ * the parameter to both the Base and Child constructors,
+ */
+function Base(id)
+{
+}
+
+function Child(id)
+{
+ this.prop = id;
+}
+Child.prototype=Base;
+
+status = inSection(4);
+var c1 = new Child('child1');
+actual = c1.prop;
+expect = 'child1';
+addThis();
+
+
+
+/*
+ * Use same identifier as a property name, too -
+ */
+function BaseX(id)
+{
+}
+
+function ChildX(id)
+{
+ this.id = id;
+}
+ChildX.prototype=BaseX;
+
+status = inSection(5);
+c1 = new ChildX('child1');
+actual = c1.id;
+expect = 'child1';
+addThis();
+
+
+
+/*
+ * From http://bugzilla.mozilla.org/show_bug.cgi?id=150032
+ *
+ * Here the same name is being used both for a local variable
+ * declared in g(), and as a property name for |g| as an object
+ */
+function g()
+{
+ var propA = g.propA;
+ var propB = g.propC;
+
+ this.getVarA = function() {return propA;}
+ this.getVarB = function() {return propB;}
+}
+g.propA = 'A';
+g.propB = 'B';
+g.propC = 'C';
+var obj = new g();
+
+status = inSection(6);
+actual = obj.getVarA(); // this one was returning 'undefined'
+expect = 'A';
+addThis();
+
+status = inSection(7);
+actual = obj.getVarB(); // this one is easy; it never failed
+expect = 'C';
+addThis();
+
+
+
+/*
+ * By martin.honnen@gmx.de
+ * From http://bugzilla.mozilla.org/show_bug.cgi?id=150859
+ *
+ * Here the same name is being used for a local var in F
+ * and as a property name for |F| as an object
+ *
+ * Twist: the property is added via another function.
+ */
+function setFProperty(val)
+{
+ F.propA = val;
+}
+
+function F()
+{
+ var propA = 'Local variable in F';
+}
+
+status = inSection(8);
+setFProperty('Hello');
+actual = F.propA; // this was returning 'undefined'
+expect = 'Hello';
+addThis();
+
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/object/regress-192105.js b/js/src/tests/non262/object/regress-192105.js
new file mode 100644
index 0000000000..d29c2d7565
--- /dev/null
+++ b/js/src/tests/non262/object/regress-192105.js
@@ -0,0 +1,146 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ *
+ * Date: 06 February 2003
+ * SUMMARY: Using |instanceof| to check if function is called as a constructor
+ *
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=192105
+ *
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 192105;
+var summary = 'Using |instanceof| to check if f() is called as constructor';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+
+
+/*
+ * This function is the heart of the test. It sets the result
+ * variable |actual|, which we will compare against |expect|.
+ *
+ * Note |actual| will be set to |true| or |false| according
+ * to whether or not this function is called as a constructor;
+ * i.e. whether it is called via the |new| keyword or not -
+ */
+function f()
+{
+ actual = (this instanceof f);
+}
+
+
+/*
+ * Call f as a constructor from global scope
+ */
+status = inSection(1);
+new f(); // sets |actual|
+expect = true;
+addThis();
+
+/*
+ * Now, not as a constructor
+ */
+status = inSection(2);
+f(); // sets |actual|
+expect = false;
+addThis();
+
+
+/*
+ * Call f as a constructor from function scope
+ */
+function F()
+{
+ new f();
+}
+status = inSection(3);
+F(); // sets |actual|
+expect = true;
+addThis();
+
+/*
+ * Now, not as a constructor
+ */
+function G()
+{
+ f();
+}
+status = inSection(4);
+G(); // sets |actual|
+expect = false;
+addThis();
+
+
+/*
+ * Now make F() and G() methods of an object
+ */
+var obj = {F:F, G:G};
+status = inSection(5);
+obj.F(); // sets |actual|
+expect = true;
+addThis();
+
+status = inSection(6);
+obj.G(); // sets |actual|
+expect = false;
+addThis();
+
+
+/*
+ * Now call F() and G() from yet other functions, and use eval()
+ */
+function A()
+{
+ eval('F();');
+}
+status = inSection(7);
+A(); // sets |actual|
+expect = true;
+addThis();
+
+
+function B()
+{
+ eval('G();');
+}
+status = inSection(8);
+B(); // sets |actual|
+expect = false;
+addThis();
+
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = actual;
+ expectedvalues[UBound] = expect;
+ UBound++;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/object/regress-308806-01.js b/js/src/tests/non262/object/regress-308806-01.js
new file mode 100644
index 0000000000..8e0a66839c
--- /dev/null
+++ b/js/src/tests/non262/object/regress-308806-01.js
@@ -0,0 +1,20 @@
+/* -*- 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 = 308806;
+var summary = 'Object.prototype.toLocaleString() should track Object.prototype.toString() ';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+var o = {toString: function() { return 'foo'; }};
+
+expect = o.toString();
+actual = o.toLocaleString();
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/object/regress-338709.js b/js/src/tests/non262/object/regress-338709.js
new file mode 100644
index 0000000000..ca82e7fbcb
--- /dev/null
+++ b/js/src/tests/non262/object/regress-338709.js
@@ -0,0 +1,74 @@
+/* -*- 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 = 338709;
+var summary = 'ReadOnly properties should not be overwritten by using ' +
+ 'Object and try..throw..catch';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+Object = function () { return Math };
+expect = Math.LN2;
+try
+{
+ throw 1990;
+}
+catch (LN2)
+{
+}
+actual = Math.LN2;
+print("Math.LN2 = " + Math.LN2)
+ reportCompare(expect, actual, summary);
+
+var s = new String("abc");
+Object = function () { return s };
+expect = s.length;
+try
+{
+ throw -8
+ }
+catch (length)
+{
+}
+actual = s.length;
+print("length of '" + s + "' = " + s.length)
+ reportCompare(expect, actual, summary);
+
+var re = /xy/m;
+Object = function () { return re };
+expect = re.multiline;
+try
+{
+ throw false
+ }
+catch (multiline)
+{
+}
+actual = re.multiline;
+print("re.multiline = " + re.multiline)
+ reportCompare(expect, actual, summary);
+
+if ("document" in this) {
+ // Let the document be its own documentElement.
+ Object = function () { return document }
+ expect = document.documentElement + '';
+ try
+ {
+ throw document;
+ }
+ catch (documentElement)
+ {
+ }
+ actual = document.documentElement + '';
+ print("document.documentElement = " + document.documentElement)
+ }
+else
+ Object = this.constructor
+
+ reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/object/regress-361274.js b/js/src/tests/non262/object/regress-361274.js
new file mode 100644
index 0000000000..dd3d15f328
--- /dev/null
+++ b/js/src/tests/non262/object/regress-361274.js
@@ -0,0 +1,30 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 361274;
+var summary = 'Embedded nulls in property names';
+var actual = '';
+var expect = '';
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ var x='123'+'\0'+'456';
+ var y='123'+'\0'+'789';
+ var a={};
+ a[x]=1;
+ a[y]=2;
+
+ reportCompare(1, a[x], summary + ': 123\\0456');
+ reportCompare(2, a[y], summary + ': 123\\0789');
+}
diff --git a/js/src/tests/non262/object/regress-382503.js b/js/src/tests/non262/object/regress-382503.js
new file mode 100644
index 0000000000..373b45f6e2
--- /dev/null
+++ b/js/src/tests/non262/object/regress-382503.js
@@ -0,0 +1,29 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 382503;
+var summary = 'Do not assert: with prototype=regexp';
+var actual = '';
+var expect = '';
+
+printBugNumber(BUGNUMBER);
+printStatus (summary);
+
+function f(x)
+{
+ prototype = /a/;
+
+ if (x) {
+ return /b/;
+ return /c/;
+ } else {
+ return /d/;
+ }
+}
+
+void f(false);
+
+reportCompare(expect, actual, summary);
diff --git a/js/src/tests/non262/object/regress-382532.js b/js/src/tests/non262/object/regress-382532.js
new file mode 100644
index 0000000000..a65651a1c6
--- /dev/null
+++ b/js/src/tests/non262/object/regress-382532.js
@@ -0,0 +1,33 @@
+/* -*- 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 = 382532;
+var summary = 'instanceof,... broken by use of |prototype| in heavyweight constructor';
+var actual = '';
+var expect = '';
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ var prototype;
+
+ function Bug() {
+ var func = function () { x; };
+ prototype;
+ }
+
+ expect = true;
+ actual = (new Bug instanceof Bug);
+
+ reportCompare(expect, actual, summary);
+}
diff --git a/js/src/tests/non262/object/regress-385393-07.js b/js/src/tests/non262/object/regress-385393-07.js
new file mode 100644
index 0000000000..eea506aba2
--- /dev/null
+++ b/js/src/tests/non262/object/regress-385393-07.js
@@ -0,0 +1,31 @@
+/* -*- 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 = 385393;
+var summary = 'Regression test for bug 385393';
+var actual = 'No Crash';
+var expect = 'No Crash';
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ try
+ {
+ (2).eval();
+ }
+ catch(ex)
+ {
+ }
+
+ reportCompare(expect, actual, summary);
+}
diff --git a/js/src/tests/non262/object/regress-444787.js b/js/src/tests/non262/object/regress-444787.js
new file mode 100644
index 0000000000..08e1496860
--- /dev/null
+++ b/js/src/tests/non262/object/regress-444787.js
@@ -0,0 +1,101 @@
+/* -*- 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 = 444787;
+var summary = 'Object.getPrototypeOf';
+var actual = '';
+var expect = '';
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ var i;
+ var type;
+ var instance;
+ var types = [
+ Array,
+ Boolean,
+ Date,
+ Error,
+ Function,
+ Math,
+ Number,
+ Object,
+ RegExp,
+ String,
+ ];
+
+ for (i = 0; i < types.length; i++)
+ {
+ type = types[i];
+
+ if (typeof type.__proto__ != 'undefined')
+ {
+ expect = type.__proto__;
+ actual = Object.getPrototypeOf(type);
+ reportCompare(expect, actual, summary + ': ' + type.name);
+ }
+
+ try
+ {
+ eval('instance = new ' + type.name);
+ expect = type.prototype;
+ actual = Object.getPrototypeOf(instance);
+ reportCompare(expect, actual, summary + ': new ' + type.name);
+ }
+ catch(ex) {
+ if (ex instanceof TypeError) {
+ print('Ignore ' + ex);
+ } else {
+ actual = ex + '';
+ reportCompare(expect, actual, summary + ': new ' + type.name);
+ }
+ }
+
+ }
+
+ types = [null, undefined];
+
+ for (i = 0; i < types.length; i++)
+ {
+ type = types[i];
+ expect = 'TypeError: Object.getPrototype is not a function';
+ try
+ {
+ actual = Object.getPrototype(null);
+ }
+ catch(ex)
+ {
+ actual = ex + '';
+ }
+ reportCompare(expect, actual, summary + ': ' + type);
+ }
+
+ var objects = [
+ {instance: [0], type: Array},
+ {instance: (function () {}), type: Function},
+ {instance: eval, type: Function},
+ {instance: parseInt, type: Function},
+ {instance: {a: ''}, type: Object},
+ {instance: /foo/, type: RegExp}
+ ];
+
+ for (i = 0; i < objects.length; i++)
+ {
+ instance = objects[i].instance;
+ type = objects[i].type;
+ expect = type.prototype;
+ actual = Object.getPrototypeOf(instance);
+ reportCompare(expect, actual, summary + ' instance: ' + instance + ', type: ' + type.name);
+ }
+}
diff --git a/js/src/tests/non262/object/regress-459405.js b/js/src/tests/non262/object/regress-459405.js
new file mode 100644
index 0000000000..524bc6a092
--- /dev/null
+++ b/js/src/tests/non262/object/regress-459405.js
@@ -0,0 +1,37 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributor: Robert Sayre
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 459405;
+var summary = 'Math is not ReadOnly';
+var actual = '';
+var expect = '';
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ expect = 'foo';
+
+ try
+ {
+ var Math = 'foo';
+ actual = Math;
+ }
+ catch(ex)
+ {
+ actual = ex + '';
+ }
+
+ reportCompare(expect, actual, summary);
+}
diff --git a/js/src/tests/non262/object/regress-465476.js b/js/src/tests/non262/object/regress-465476.js
new file mode 100644
index 0000000000..1d998f1e71
--- /dev/null
+++ b/js/src/tests/non262/object/regress-465476.js
@@ -0,0 +1,60 @@
+/* -*- 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 = 465476;
+var summary = '"-0" and "0" are distinct properties.';
+var actual = '';
+var expect = '';
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ var x = { "0": 3, "-0": 7 };
+
+ expect = actual = 'No Exception';
+
+ try
+ {
+ if (!("0" in x))
+ throw "0 not in x";
+ if (!("-0" in x))
+ throw "-0 not in x";
+ delete x[0];
+ if ("0" in x)
+ throw "0 in x after delete";
+ if (!("-0" in x))
+ throw "-0 removed from x after unassociated delete";
+ delete x["-0"];
+ if ("-0" in x)
+ throw "-0 in x after delete";
+ x[0] = 3;
+ if (!("0" in x))
+ throw "0 not in x after insertion of 0 property";
+ if ("-0" in x)
+ throw "-0 in x after insertion of 0 property";
+ x["-0"] = 7;
+ if (!("-0" in x))
+ throw "-0 not in x after reinsertion";
+
+ var props = [];
+ for (var i in x)
+ props.push(i);
+ if (props.length !== 2)
+ throw "not all props found!";
+ }
+ catch(ex)
+ {
+ actual = ex + '';
+ }
+ reportCompare(expect, actual, summary);
+}
diff --git a/js/src/tests/non262/object/regress-72773.js b/js/src/tests/non262/object/regress-72773.js
new file mode 100644
index 0000000000..77f75c3dc0
--- /dev/null
+++ b/js/src/tests/non262/object/regress-72773.js
@@ -0,0 +1,60 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Date: 09 May 2001
+ *
+ * SUMMARY: Regression test: we shouldn't crash on this code
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=72773
+ *
+ * See ECMA-262 Edition 3 13-Oct-1999, Section 8.6.2 re [[Class]] property.
+ *
+ * Same as class-001.js - but testing user-defined types here, not
+ * native types. Therefore we expect the [[Class]] property to equal
+ * 'Object' in each case -
+ *
+ * The getJSClass() function we use is in a utility file, e.g. "shell.js"
+ */
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 72773;
+var summary = "Regression test: we shouldn't crash on this code";
+var status = '';
+var actual = '';
+var expect = '';
+var sToEval = '';
+
+/*
+ * This code should produce an error, but not a crash.
+ * 'TypeError: Function.prototype.toString called on incompatible object'
+ */
+sToEval += 'function Cow(name){this.name = name;}'
+sToEval += 'function Calf(str){this.name = str;}'
+sToEval += 'Calf.prototype = Cow;'
+sToEval += 'new Calf().toString();'
+
+status = 'Trying to catch an expected error';
+try
+{
+ eval(sToEval);
+}
+catch(e)
+{
+ actual = getJSClass(e);
+ expect = 'Error';
+}
+
+
+//----------------------------------------------------------------------------------------------
+test();
+//----------------------------------------------------------------------------------------------
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ reportCompare(expect, actual, status);
+}
diff --git a/js/src/tests/non262/object/regress-79129-001.js b/js/src/tests/non262/object/regress-79129-001.js
new file mode 100644
index 0000000000..b9689429ee
--- /dev/null
+++ b/js/src/tests/non262/object/regress-79129-001.js
@@ -0,0 +1,44 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Date: 06 May 2001
+ *
+ * SUMMARY: Regression test: we shouldn't crash on this code
+ *
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=79129
+ */
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 79129;
+var summary = "Regression test: we shouldn't crash on this code";
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+ tryThis();
+ reportCompare('No Crash', 'No Crash', 'Should not crash');
+}
+
+
+function tryThis()
+{
+ obj={};
+ obj.a = obj.b = obj.c = 1;
+ delete obj.a;
+ delete obj.b;
+ delete obj.c;
+ obj.d = obj.e = 1;
+ obj.a=1;
+ obj.b=1;
+ obj.c=1;
+ obj.d=1;
+ obj.e=1;
+}
diff --git a/js/src/tests/non262/object/regress-90596-003.js b/js/src/tests/non262/object/regress-90596-003.js
new file mode 100644
index 0000000000..ea0c161592
--- /dev/null
+++ b/js/src/tests/non262/object/regress-90596-003.js
@@ -0,0 +1,275 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Date: 28 August 2001
+ *
+ * SUMMARY: A [DontEnum] prop, if overridden, should appear in for-in loops.
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=90596
+ *
+ * NOTE: some inefficiencies in the test are made for the sake of readability.
+ * For example, we quote string values like "Hi" in lines like this:
+ *
+ * actual = enumerateThis(obj);
+ * expect = '{prop:"Hi"}';
+ *
+ * But enumerateThis(obj) gets literal value Hi for obj.prop, not
+ * literal "Hi". We take care of all these details in the
+ * compactThis(), sortThis() functions. Sorting properties
+ * alphabetically is necessary for the test to work in Rhino.
+ */
+//-----------------------------------------------------------------------------
+var UBound = 0;
+var BUGNUMBER = 90596;
+var summary = '[DontEnum] props (if overridden) should appear in for-in loops';
+var cnCOMMA = ',';
+var cnCOLON = ':';
+var cnLBRACE = '{';
+var cnRBRACE = '}';
+var status = '';
+var statusitems = [];
+var actual = '';
+var actualvalues = [];
+var expect= '';
+var expectedvalues = [];
+var obj = {};
+
+
+status = inSection(1);
+obj = {toString:9};
+actual = enumerateThis(obj);
+expect = '{toString:9}';
+addThis();
+
+status = inSection(2);
+obj = {hasOwnProperty:"Hi"};
+actual = enumerateThis(obj);
+expect = '{hasOwnProperty:"Hi"}';
+addThis();
+
+status = inSection(3);
+obj = {toString:9, hasOwnProperty:"Hi"};
+actual = enumerateThis(obj);
+expect = '{toString:9, hasOwnProperty:"Hi"}';
+addThis();
+
+status = inSection(4);
+obj = {prop1:1, toString:9, hasOwnProperty:"Hi"};
+actual = enumerateThis(obj);
+expect = '{prop1:1, toString:9, hasOwnProperty:"Hi"}';
+addThis();
+
+
+// TRY THE SAME THING IN EVAL CODE
+var s = '';
+
+status = inSection(5);
+s = 'obj = {toString:9}';
+eval(s);
+actual = enumerateThis(obj);
+expect = '{toString:9}';
+addThis();
+
+status = inSection(6);
+s = 'obj = {hasOwnProperty:"Hi"}';
+eval(s);
+actual = enumerateThis(obj);
+expect = '{hasOwnProperty:"Hi"}';
+addThis();
+
+status = inSection(7);
+s = 'obj = {toString:9, hasOwnProperty:"Hi"}';
+eval(s);
+actual = enumerateThis(obj);
+expect = '{toString:9, hasOwnProperty:"Hi"}';
+addThis();
+
+status = inSection(8);
+s = 'obj = {prop1:1, toString:9, hasOwnProperty:"Hi"}';
+eval(s);
+actual = enumerateThis(obj);
+expect = '{prop1:1, toString:9, hasOwnProperty:"Hi"}';
+addThis();
+
+
+// TRY THE SAME THING IN FUNCTION CODE
+function A()
+{
+ status = inSection(9);
+ var s = 'obj = {toString:9}';
+ eval(s);
+ actual = enumerateThis(obj);
+ expect = '{toString:9}';
+ addThis();
+}
+A();
+
+function B()
+{
+ status = inSection(10);
+ var s = 'obj = {hasOwnProperty:"Hi"}';
+ eval(s);
+ actual = enumerateThis(obj);
+ expect = '{hasOwnProperty:"Hi"}';
+ addThis();
+}
+B();
+
+function C()
+{
+ status = inSection(11);
+ var s = 'obj = {toString:9, hasOwnProperty:"Hi"}';
+ eval(s);
+ actual = enumerateThis(obj);
+ expect = '{toString:9, hasOwnProperty:"Hi"}';
+ addThis();
+}
+C();
+
+function D()
+{
+ status = inSection(12);
+ var s = 'obj = {prop1:1, toString:9, hasOwnProperty:"Hi"}';
+ eval(s);
+ actual = enumerateThis(obj);
+ expect = '{prop1:1, toString:9, hasOwnProperty:"Hi"}';
+ addThis();
+}
+D();
+
+
+
+//-----------------------------------------------------------------------------
+test();
+//-----------------------------------------------------------------------------
+
+
+
+function enumerateThis(obj)
+{
+ var arr = new Array();
+
+ for (var prop in obj)
+ {
+ arr.push(prop + cnCOLON + obj[prop]);
+ }
+
+ var ret = addBraces(String(arr));
+ return ret;
+}
+
+
+function addBraces(text)
+{
+ return cnLBRACE + text + cnRBRACE;
+}
+
+
+/*
+ * Sort properties alphabetically so the test will work in Rhino
+ */
+function addThis()
+{
+ statusitems[UBound] = status;
+ actualvalues[UBound] = sortThis(actual);
+ expectedvalues[UBound] = sortThis(expect);
+ UBound++;
+}
+
+
+/*
+ * Takes a string of the form '{"c", "b", "a", 2}' and returns '{2,a,b,c}'
+ */
+function sortThis(sList)
+{
+ sList = compactThis(sList);
+ sList = stripBraces(sList);
+ var arr = sList.split(cnCOMMA);
+ arr = arr.sort();
+ var ret = String(arr);
+ ret = addBraces(ret);
+ return ret;
+}
+
+
+/*
+ * Strips out any whitespace or quotes from the text -
+ */
+function compactThis(text)
+{
+ var charCode = 0;
+ var ret = '';
+
+ for (var i=0; i<text.length; i++)
+ {
+ charCode = text.charCodeAt(i);
+
+ if (!isWhiteSpace(charCode) && !isQuote(charCode))
+ ret += text.charAt(i);
+ }
+
+ return ret;
+}
+
+
+function isWhiteSpace(charCode)
+{
+ switch (charCode)
+ {
+ case (0x0009):
+ case (0x000B):
+ case (0x000C):
+ case (0x0020):
+ case (0x000A): // '\n'
+ case (0x000D): // '\r'
+ return true;
+ break;
+
+ default:
+ return false;
+ }
+}
+
+
+function isQuote(charCode)
+{
+ switch (charCode)
+ {
+ case (0x0027): // single quote
+ case (0x0022): // double quote
+ return true;
+ break;
+
+ default:
+ return false;
+ }
+}
+
+
+/*
+ * strips off braces at beginning and end of text -
+ */
+function stripBraces(text)
+{
+ // remember to escape the braces...
+ var arr = text.match(/^\{(.*)\}$/);
+
+ // defend against a null match...
+ if (arr != null && arr[1] != null)
+ return arr[1];
+ return text;
+}
+
+
+function test()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus (summary);
+
+ for (var i=0; i<UBound; i++)
+ {
+ reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
+ }
+}
diff --git a/js/src/tests/non262/object/seal-proxy.js b/js/src/tests/non262/object/seal-proxy.js
new file mode 100644
index 0000000000..44bb685c87
--- /dev/null
+++ b/js/src/tests/non262/object/seal-proxy.js
@@ -0,0 +1,27 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function logProxy(object = {}, handler = {}) {
+ var log = [];
+ var proxy = new Proxy(object, new Proxy(handler, {
+ get(target, propertyKey, receiver) {
+ log.push(propertyKey);
+ return target[propertyKey];
+ }
+ }));
+ return {proxy, log};
+}
+
+// The order of operations is backwards when compared to ES6 draft rev 27
+// (2014 August 24), but see https://bugs.ecmascript.org/show_bug.cgi?id=3215
+// for an explanation on why the spec version is clearly wrong.
+
+var {proxy, log} = logProxy();
+Object.seal(proxy);
+assertDeepEq(log, ["preventExtensions", "ownKeys"]);
+
+var {proxy, log} = logProxy();
+Object.seal(Object.seal(proxy));
+assertDeepEq(log, ["preventExtensions", "ownKeys", "preventExtensions", "ownKeys"]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/seal.js b/js/src/tests/non262/object/seal.js
new file mode 100644
index 0000000000..e325c80d9d
--- /dev/null
+++ b/js/src/tests/non262/object/seal.js
@@ -0,0 +1,21 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1075294;
+var summary = "Object.seal() should return its argument with no conversion when the argument is a primitive value";
+
+print(BUGNUMBER + ": " + summary);
+assertEq(Object.seal(), undefined);
+assertEq(Object.seal(undefined), undefined);
+assertEq(Object.seal(null), null);
+assertEq(Object.seal(1), 1);
+assertEq(Object.seal("foo"), "foo");
+assertEq(Object.seal(true), true);
+if (typeof Symbol === "function") {
+ assertEq(Object.seal(Symbol.for("foo")), Symbol.for("foo"));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/setPrototypeOf-cross-realm-cycle.js b/js/src/tests/non262/object/setPrototypeOf-cross-realm-cycle.js
new file mode 100644
index 0000000000..e2efe010eb
--- /dev/null
+++ b/js/src/tests/non262/object/setPrototypeOf-cross-realm-cycle.js
@@ -0,0 +1,11 @@
+// The cycle check in 9.1.2 [[SetPrototypeOf]] prevents cross-realm cycles
+// involving only ordinary objects.
+
+var gw = newGlobal();
+
+var obj = {};
+var w = gw.Object.create(obj);
+assertThrowsInstanceOf(() => Object.setPrototypeOf(obj, w), TypeError);
+assertThrowsInstanceOf(() => gw.Object.setPrototypeOf(obj, w), gw.TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/setPrototypeOf-cycle.js b/js/src/tests/non262/object/setPrototypeOf-cycle.js
new file mode 100644
index 0000000000..a8b5aa75cd
--- /dev/null
+++ b/js/src/tests/non262/object/setPrototypeOf-cycle.js
@@ -0,0 +1,16 @@
+// The cycle check in 9.1.2 [[SetPrototypeOf]] does not walk proxies.
+// Therefore it's very easy to create prototype chain cycles involving proxies,
+// and the spec requires us to accept this.
+
+var t = {};
+var p = new Proxy(t, {});
+Object.setPrototypeOf(t, p); // 🙈
+
+// Actually doing anything that searches this object's prototype chain
+// technically should not terminate. We instead throw "too much recursion".
+for (var obj of [t, p]) {
+ assertThrowsInstanceOf(() => "x" in obj, InternalError);
+ assertThrowsInstanceOf(() => obj.x, InternalError);
+ assertThrowsInstanceOf(() => { obj.x = 1; }, InternalError);
+}
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/setPrototypeOf-same-value.js b/js/src/tests/non262/object/setPrototypeOf-same-value.js
new file mode 100644
index 0000000000..3375509462
--- /dev/null
+++ b/js/src/tests/non262/object/setPrototypeOf-same-value.js
@@ -0,0 +1,11 @@
+// Setting a "new" prototype to the current [[Prototype]] value should never fail
+
+var x = {}, t = Object.create(x);
+Object.preventExtensions(t);
+// Should not fail, because it is the same [[Prototype]] value
+Object.setPrototypeOf(t, x);
+
+// Object.prototype's [[Prototype]] is immutable, make sure we can still set null
+Object.setPrototypeOf(Object.prototype, null);
+
+reportCompare(true, true);
diff --git a/js/src/tests/non262/object/shell.js b/js/src/tests/non262/object/shell.js
new file mode 100644
index 0000000000..49d875f264
--- /dev/null
+++ b/js/src/tests/non262/object/shell.js
@@ -0,0 +1,62 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Date: 14 Mar 2001
+ *
+ * SUMMARY: Utility functions for testing objects -
+ *
+ * Suppose obj is an instance of a native type, e.g. Number.
+ * Then obj.toString() invokes Number.prototype.toString().
+ * We would also like to access Object.prototype.toString().
+ *
+ * The difference is this: suppose obj = new Number(7).
+ * Invoking Number.prototype.toString() on this just returns 7.
+ * Object.prototype.toString() on this returns '[object Number]'.
+ *
+ * The getJSClass() function returns 'Number', the [[Class]] property of obj.
+ * See ECMA-262 Edition 3, 13-Oct-1999, Section 8.6.2
+ */
+//-----------------------------------------------------------------------------
+
+
+var cnNoObject = 'Unexpected Error!!! Parameter to this function must be an object';
+var cnNoClass = 'Unexpected Error!!! Cannot find Class property';
+var cnObjectToString = Object.prototype.toString;
+var GLOBAL = 'global';
+
+
+// checks that it's safe to call findType()
+function getJSClass(obj)
+{
+ if (isObject(obj))
+ return findClass(findType(obj));
+ return cnNoObject;
+}
+
+
+function findType(obj)
+{
+ return cnObjectToString.apply(obj);
+}
+
+
+// given '[object Number]', return 'Number'
+function findClass(sType)
+{
+ var re = /^\[.*\s+(\w+)\s*\]$/;
+ var a = sType.match(re);
+
+ if (a && a[1])
+ return a[1];
+ return cnNoClass;
+}
+
+
+function isObject(obj)
+{
+ return obj instanceof Object;
+}
+
diff --git a/js/src/tests/non262/object/toLocaleString-01.js b/js/src/tests/non262/object/toLocaleString-01.js
new file mode 100644
index 0000000000..3fa2acc746
--- /dev/null
+++ b/js/src/tests/non262/object/toLocaleString-01.js
@@ -0,0 +1,13 @@
+"use strict";
+
+Object.defineProperty(String.prototype, "toString", {
+ get() {
+ assertEq(typeof this, "string");
+
+ return function() { return typeof this; };
+ }
+})
+assertEq(Object.prototype.toLocaleString.call("test"), "string");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/toLocaleString.js b/js/src/tests/non262/object/toLocaleString.js
new file mode 100644
index 0000000000..e42c4a09e5
--- /dev/null
+++ b/js/src/tests/non262/object/toLocaleString.js
@@ -0,0 +1,102 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'toLocaleString.js';
+var BUGNUMBER = 653789;
+var summary = "Object.prototype.toLocaleString";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+function expectThrowTypeError(fun)
+{
+ try
+ {
+ var r = fun();
+ throw "didn't throw TypeError, returned " + r;
+ }
+ catch (e)
+ {
+ assertEq(e instanceof TypeError, true,
+ "didn't throw TypeError, got: " + e);
+ }
+}
+
+var toLocaleString = Object.prototype.toLocaleString;
+
+/*
+ * 1. Let O be the result of calling ToObject passing the this value as the
+ * argument.
+ */
+expectThrowTypeError(function() { toLocaleString.call(null); });
+expectThrowTypeError(function() { toLocaleString.call(undefined); });
+expectThrowTypeError(function() { toLocaleString.apply(null); });
+expectThrowTypeError(function() { toLocaleString.apply(undefined); });
+
+
+/*
+ * 2. Let toString be the result of calling the [[Get]] internal method of O
+ * passing "toString" as the argument.
+ */
+try
+{
+ toLocaleString.call({ get toString() { throw 17; } });
+ throw new Error("didn't throw");
+}
+catch (e)
+{
+ assertEq(e, 17);
+}
+
+
+/* 3. If IsCallable(toString) is false, throw a TypeError exception. */
+expectThrowTypeError(function() { toLocaleString.call({ toString: 12 }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: 0.3423423452352e9 }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: undefined }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: false }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: [] }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: {} }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: new String }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: new Number(7.7) }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: new Boolean(true) }); });
+expectThrowTypeError(function() { toLocaleString.call({ toString: JSON }); });
+
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: 12 }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: 0.3423423452352e9 }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: undefined }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: false }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: [] }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: {} }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: new String }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: new Number(7.7) }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: new Boolean(true) }); });
+expectThrowTypeError(function() { toLocaleString.call({ valueOf: 0, toString: JSON }); });
+
+
+/*
+ * 4. Return the result of calling the [[Call]] internal method of toString
+ * passing O as the this value and no arguments.
+ */
+assertEq(toLocaleString.call({ get toString() { return function() { return "foo"; } } }),
+ "foo");
+
+var obj = { toString: function() { assertEq(this, obj); assertEq(arguments.length, 0); return 5; } };
+assertEq(toLocaleString.call(obj), 5);
+
+assertEq(toLocaleString.call({ toString: function() { return obj; } }), obj);
+
+assertEq(toLocaleString.call({ toString: function() { return obj; },
+ valueOf: function() { return "abc"; } }),
+ obj);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/toPrimitive-callers.js b/js/src/tests/non262/object/toPrimitive-callers.js
new file mode 100644
index 0000000000..ffeef2225c
--- /dev/null
+++ b/js/src/tests/non262/object/toPrimitive-callers.js
@@ -0,0 +1,57 @@
+// Check all the algorithms that call ToPrimitive. Confirm that they're passing
+// the correct hint, per spec.
+
+var STRING = "xyzzy";
+var NUMBER = 42;
+
+function assertCallsToPrimitive(f, expectedHint, expectedResult) {
+ var hint = undefined;
+ var testObj = {
+ [Symbol.toPrimitive](h) {
+ assertEq(hint, undefined);
+ hint = h;
+ return h === "number" ? NUMBER : STRING;
+ }
+ };
+ var result = f(testObj);
+ assertEq(hint, expectedHint, String(f));
+ assertEq(result, expectedResult, String(f));
+}
+
+// ToNumber
+assertCallsToPrimitive(Number, "number", NUMBER);
+
+// ToString
+assertCallsToPrimitive(String, "string", STRING);
+
+// ToPropertyKey
+var obj = {[STRING]: "pass"};
+assertCallsToPrimitive(key => obj[key], "string", "pass");
+
+// Abstract Relational Comparison
+assertCallsToPrimitive(x => x >= 42, "number", true);
+assertCallsToPrimitive(x => x > "42", "number", false);
+
+// Abstract Equality Comparison
+assertCallsToPrimitive(x => x != STRING, "default", false);
+assertCallsToPrimitive(x => STRING == x, "default", true);
+assertCallsToPrimitive(x => x == NUMBER, "default", false);
+assertCallsToPrimitive(x => NUMBER != x, "default", true);
+
+// Addition
+assertCallsToPrimitive(x => 1 + x, "default", "1" + STRING);
+assertCallsToPrimitive(x => "" + x, "default", STRING);
+
+// Date constructor
+assertCallsToPrimitive(x => (new Date(x)).valueOf(), "default", Number(STRING));
+
+// Date.prototype.toJSON
+var expected = "a suffusion of yellow";
+function testJSON(x) {
+ x.toJSON = Date.prototype.toJSON;
+ x.toISOString = function () { return expected; };
+ return JSON.stringify(x);
+}
+assertCallsToPrimitive(testJSON, "number", JSON.stringify(expected));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/toPrimitive.js b/js/src/tests/non262/object/toPrimitive.js
new file mode 100644
index 0000000000..59ed6ac475
--- /dev/null
+++ b/js/src/tests/non262/object/toPrimitive.js
@@ -0,0 +1,101 @@
+// ES6 7.1.1 ToPrimitive(input [, PreferredType]) specifies a new extension
+// point in the language. Objects can override the behavior of ToPrimitive
+// somewhat by supporting the method obj[@@toPrimitive](hint).
+//
+// (Rationale: ES5 had a [[DefaultValue]] internal method, overridden only by
+// Date objects. The change in ES6 is to make [[DefaultValue]] a plain old
+// method. This allowed ES6 to eliminate the [[DefaultValue]] internal method,
+// simplifying the meta-object protocol and thus proxies.)
+
+// obj[Symbol.toPrimitive]() is called whenever the ToPrimitive algorithm is invoked.
+var expectedThis, expectedHint;
+var obj = {
+ [Symbol.toPrimitive](hint, ...rest) {
+ assertEq(this, expectedThis);
+ assertEq(hint, expectedHint);
+ assertEq(rest.length, 0);
+ return 2015;
+ }
+};
+expectedThis = obj;
+expectedHint = "string";
+assertEq(String(obj), "2015");
+expectedHint = "number";
+assertEq(Number(obj), 2015);
+
+// It is called even through proxies.
+var proxy = new Proxy(obj, {});
+expectedThis = proxy;
+expectedHint = "default";
+assertEq("ES" + proxy, "ES2015");
+
+// It is called even through additional proxies and the prototype chain.
+proxy = new Proxy(Object.create(proxy), {});
+expectedThis = proxy;
+expectedHint = "default";
+assertEq("ES" + (proxy + 1), "ES2016");
+
+// It is not called if the operand is already a primitive.
+var ok = true;
+for (var constructor of [Boolean, Number, String, Symbol]) {
+ constructor.prototype[Symbol.toPrimitive] = function () {
+ ok = false;
+ throw "FAIL";
+ };
+}
+assertEq(Number(true), 1);
+assertEq(Number(77.7), 77.7);
+assertEq(Number("123"), 123);
+assertThrowsInstanceOf(() => Number(Symbol.iterator), TypeError);
+assertEq(String(true), "true");
+assertEq(String(77.7), "77.7");
+assertEq(String("123"), "123");
+assertEq(String(Symbol.iterator), "Symbol(Symbol.iterator)");
+assertEq(ok, true);
+
+// Converting a primitive symbol to another primitive type throws even if you
+// delete the @@toPrimitive method from Symbol.prototype.
+delete Symbol.prototype[Symbol.toPrimitive];
+var sym = Symbol("ok");
+assertThrowsInstanceOf(() => `${sym}`, TypeError);
+assertThrowsInstanceOf(() => Number(sym), TypeError);
+assertThrowsInstanceOf(() => "" + sym, TypeError);
+
+// However, having deleted that method, converting a Symbol wrapper object does
+// work: it calls Symbol.prototype.toString().
+obj = Object(sym);
+assertEq(String(obj), "Symbol(ok)");
+assertEq(`${obj}`, "Symbol(ok)");
+
+// Deleting valueOf as well makes numeric conversion also call toString().
+delete Symbol.prototype.valueOf;
+delete Object.prototype.valueOf;
+assertEq(Number(obj), NaN);
+Symbol.prototype.toString = function () { return "2060"; };
+assertEq(Number(obj), 2060);
+
+// Deleting Date.prototype[Symbol.toPrimitive] changes the result of addition
+// involving Date objects.
+var d = new Date;
+assertEq(0 + d, 0 + d.toString());
+delete Date.prototype[Symbol.toPrimitive];
+assertEq(0 + d, 0 + d.valueOf());
+
+// If @@toPrimitive, .toString, and .valueOf are all missing, we get a
+// particular sequence of property accesses, followed by a TypeError exception.
+var log = [];
+function doGet(target, propertyName, receiver) {
+ log.push(propertyName);
+}
+var handler = new Proxy({}, {
+ get(target, trapName, receiver) {
+ if (trapName !== "get")
+ throw `FAIL: system tried to access handler method: ${String(trapName)}`;
+ return doGet;
+ }
+});
+proxy = new Proxy(Object.create(null), handler);
+assertThrowsInstanceOf(() => proxy == 0, TypeError);
+assertDeepEq(log, [Symbol.toPrimitive, "valueOf", "toString"]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/non262/object/vacuous-accessor-unqualified-name.js b/js/src/tests/non262/object/vacuous-accessor-unqualified-name.js
new file mode 100644
index 0000000000..768b1050b9
--- /dev/null
+++ b/js/src/tests/non262/object/vacuous-accessor-unqualified-name.js
@@ -0,0 +1,26 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'vacuous-accessor-unqualified-name.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 560216;
+var summary =
+ "Using a name referring to a { get: undefined, set: undefined } descriptor " +
+ "shouldn't assert";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+Object.defineProperty(this, "x", { set: undefined, configurable: true });
+x;
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("All tests passed!");
diff --git a/js/src/tests/non262/object/values-entries-indexed.js b/js/src/tests/non262/object/values-entries-indexed.js
new file mode 100644
index 0000000000..f4d801c272
--- /dev/null
+++ b/js/src/tests/non262/object/values-entries-indexed.js
@@ -0,0 +1,71 @@
+function assertSameEntries(actual, expected) {
+ assertEq(actual.length, expected.length);
+ for (let i = 0; i < expected.length; ++i)
+ assertEqArray(actual[i], expected[i]);
+}
+
+// Test Object.keys/values/entries on objects with indexed properties.
+
+// Empty dense elements, test with array and plain object.
+{
+ let array = [];
+ assertEqArray(Object.keys(array), []);
+ assertEqArray(Object.values(array), []);
+ assertSameEntries(Object.entries(array), []);
+
+ let object = {};
+ assertEqArray(Object.keys(object), []);
+ assertEqArray(Object.values(object), []);
+ assertSameEntries(Object.entries(object), []);
+}
+
+// Dense elements only, test with array and plain object.
+{
+ let array = [1, 2, 3];
+ assertEqArray(Object.keys(array), ["0", "1", "2"]);
+ assertEqArray(Object.values(array), [1, 2, 3]);
+ assertSameEntries(Object.entries(array), [["0", 1], ["1", 2], ["2", 3]]);
+
+ let object = {0: 4, 1: 5, 2: 6};
+ assertEqArray(Object.keys(object), ["0", "1", "2"]);
+ assertEqArray(Object.values(object), [4, 5, 6]);
+ assertSameEntries(Object.entries(object), [["0", 4], ["1", 5], ["2", 6]]);
+}
+
+// Extra indexed properties only, test with array and plain object.
+{
+ let array = [];
+ Object.defineProperty(array, 0, {configurable: true, enumerable: true, value: 123});
+
+ assertEqArray(Object.keys(array), ["0"]);
+ assertEqArray(Object.values(array), [123]);
+ assertSameEntries(Object.entries(array), [["0", 123]]);
+
+ let object = [];
+ Object.defineProperty(object, 0, {configurable: true, enumerable: true, value: 123});
+
+ assertEqArray(Object.keys(object), ["0"]);
+ assertEqArray(Object.values(object), [123]);
+ assertSameEntries(Object.entries(object), [["0", 123]]);
+}
+
+// Dense and extra indexed properties, test with array and plain object.
+{
+ let array = [1, 2, 3];
+ Object.defineProperty(array, 0, {writable: false});
+
+ assertEqArray(Object.keys(array), ["0", "1", "2"]);
+ assertEqArray(Object.values(array), [1, 2, 3]);
+ assertSameEntries(Object.entries(array), [["0", 1], ["1", 2], ["2", 3]]);
+
+ let object = {0: 4, 1: 5, 2: 6};
+ Object.defineProperty(object, 0, {writable: false});
+
+ assertEqArray(Object.keys(object), ["0", "1", "2"]);
+ assertEqArray(Object.values(object), [4, 5, 6]);
+ assertSameEntries(Object.entries(object), [["0", 4], ["1", 5], ["2", 6]]);
+}
+
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/values-entries-lazy-props.js b/js/src/tests/non262/object/values-entries-lazy-props.js
new file mode 100644
index 0000000000..0631c048af
--- /dev/null
+++ b/js/src/tests/non262/object/values-entries-lazy-props.js
@@ -0,0 +1,93 @@
+// Return new objects for each test case.
+function makeTestCases() {
+ // Call the resolve hook for arguments/string objects.
+ const resolveIndex = object => 0 in object;
+
+ // Calls the resolve hook for functions.
+ const resolveFunction = object => "length" in object;
+
+ const expected = array => ({
+ keys: Object.keys(array),
+ values: Object.values(array),
+ entries: Object.entries(array),
+ });
+
+ return [
+ // Mapped arguments objects.
+ {
+ object: function(){ return arguments; }(),
+ resolve: resolveIndex,
+ ...expected([]),
+ },
+ {
+ object: function(x){ return arguments; }(1),
+ resolve: resolveIndex,
+ ...expected([1]),
+ },
+ {
+ object: function(x, y, z){ return arguments; }(1, 2, 3),
+ resolve: resolveIndex,
+ ...expected([1, 2, 3]),
+ },
+
+ // Unmapped arguments objects.
+ {
+ object: function(){ "use strict"; return arguments; }(),
+ resolve: resolveIndex,
+ ...expected([]),
+ },
+ {
+ object: function(x){ "use strict"; return arguments; }(1),
+ resolve: resolveIndex,
+ ...expected([1]),
+ },
+ {
+ object: function(x, y, z){ "use strict"; return arguments; }(1, 2, 3),
+ resolve: resolveIndex,
+ ...expected([1, 2, 3]),
+ },
+
+ // String objects.
+ { object: new String(""), resolve: resolveIndex, ...expected([]), },
+ { object: new String("a"), resolve: resolveIndex, ...expected(["a"]), },
+ { object: new String("abc"), resolve: resolveIndex, ...expected(["a","b","c"]), },
+
+ // Function objects.
+ { object: function(){}, resolve: resolveFunction, ...expected([]), },
+ ];
+}
+
+var assertWith = {
+ keys: assertEqArray,
+ values: assertEqArray,
+ entries(actual, expected) {
+ assertEq(actual.length, expected.length);
+ for (let i = 0; i < expected.length; ++i)
+ assertEqArray(actual[i], expected[i]);
+ }
+};
+
+// Test Object.keys/values/entries on objects with enumerate/resolve hooks.
+
+for (let method of ["keys", "values", "entries"]) {
+ let assert = assertWith[method];
+
+ // Call each method twice to test the case when
+ // - the enumerate hook wasn't yet called,
+ // - the enumerate hook was already called.
+ for (let {object, [method]: expected} of makeTestCases()) {
+ assert(Object[method](object), expected);
+ assert(Object[method](object), expected);
+ }
+
+ // Test the case when enumerate wasn't yet called, but a property was already resolved.
+ for (let {object, resolve, [method]: expected} of makeTestCases()) {
+ resolve(object); // Call the resolve hook.
+
+ assert(Object[method](object), expected);
+ assert(Object[method](object), expected);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/values-entries-typedarray.js b/js/src/tests/non262/object/values-entries-typedarray.js
new file mode 100644
index 0000000000..b0ac5a51bb
--- /dev/null
+++ b/js/src/tests/non262/object/values-entries-typedarray.js
@@ -0,0 +1,53 @@
+function assertSameEntries(actual, expected) {
+ assertEq(actual.length, expected.length);
+ for (let i = 0; i < expected.length; ++i)
+ assertEqArray(actual[i], expected[i]);
+}
+
+function throwsTypeError(fn) {
+ try {
+ fn();
+ } catch (e) {
+ assertEq(e instanceof TypeError, true);
+ return true;
+ }
+ return false;
+}
+
+// Non-standard: Accessing elements of detached array buffers should throw, but
+// this is currently not implemented.
+const ACCESS_ON_DETACHED_ARRAY_BUFFER_THROWS = (() => {
+ let ta = new Int32Array(10);
+ detachArrayBuffer(ta.buffer);
+ let throws = throwsTypeError(() => ta[0]);
+ // Ensure [[Get]] and [[GetOwnProperty]] return consistent results.
+ assertEq(throwsTypeError(() => Object.getOwnPropertyDescriptor(ta, 0)), throws);
+ return throws;
+})();
+
+function maybeThrowOnDetached(fn, returnValue) {
+ if (ACCESS_ON_DETACHED_ARRAY_BUFFER_THROWS) {
+ assertThrowsInstanceOf(fn, TypeError);
+ return returnValue;
+ }
+ return fn();
+}
+
+// Ensure Object.keys/values/entries work correctly on typed arrays.
+for (let len of [0, 1, 10]) {
+ let array = new Array(len).fill(1);
+ let ta = new Int32Array(array);
+
+ assertEqArray(Object.keys(ta), Object.keys(array));
+ assertEqArray(Object.values(ta), Object.values(array));
+ assertSameEntries(Object.entries(ta), Object.entries(array));
+
+ detachArrayBuffer(ta.buffer);
+
+ assertEqArray(maybeThrowOnDetached(() => Object.keys(ta), []), []);
+ assertEqArray(maybeThrowOnDetached(() => Object.values(ta), []), []);
+ assertSameEntries(maybeThrowOnDetached(() => Object.entries(ta), []), []);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/non262/object/values.js b/js/src/tests/non262/object/values.js
new file mode 100644
index 0000000000..189bea7605
--- /dev/null
+++ b/js/src/tests/non262/object/values.js
@@ -0,0 +1,94 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+if ("values" in Object) {
+ assertEq(Object.values.length, 1);
+
+ var o, values;
+
+ o = { a: 3, b: 2 };
+ values = Object.values(o);
+ assertDeepEq(values, [3, 2]);
+
+ o = { get a() { return 17; }, b: 2 };
+ values = Object.values(o),
+ assertDeepEq(values, [17, 2]);
+
+ o = { __iterator__: function() { throw new Error("non-standard __iterator__ called?"); } };
+ values = Object.values(o);
+ assertDeepEq(values, [o.__iterator__]);
+
+ o = { a: 1, b: 2 };
+ delete o.a;
+ o.a = 3;
+ values = Object.values(o);
+ assertDeepEq(values, [2, 3]);
+
+ o = [0, 1, 2];
+ values = Object.values(o);
+ assertDeepEq(values, [0, 1, 2]);
+
+ o = /./.exec("abc");
+ values = Object.values(o);
+ assertDeepEq(values, ["a", 0, "abc", undefined]);
+
+ o = { a: 1, b: 2, c: 3 };
+ delete o.b;
+ o.b = 5;
+ values = Object.values(o);
+ assertDeepEq(values, [1, 3, 5]);
+
+ function f() { }
+ f.prototype.p = 1;
+ o = new f();
+ o.g = 1;
+ values = Object.values(o);
+ assertDeepEq(values, [1]);
+
+ var o = {get a() {delete this.b; return 1}, b: 2, c: 3};
+ values = Object.values(o);
+ assertDeepEq(values, [1, 3]);
+
+ assertThrowsInstanceOf(() => Object.values(), TypeError);
+ assertThrowsInstanceOf(() => Object.values(undefined), TypeError);
+ assertThrowsInstanceOf(() => Object.values(null), TypeError);
+
+ assertDeepEq(Object.values(1), []);
+ assertDeepEq(Object.values(true), []);
+ if (typeof Symbol === "function")
+ assertDeepEq(Object.values(Symbol("foo")), []);
+
+ assertDeepEq(Object.values("foo"), ["f", "o", "o"]);
+
+ values = Object.values({
+ get a(){
+ Object.defineProperty(this, "b", {enumerable: false});
+ return "A";
+ },
+ b: "B"
+ });
+ assertDeepEq(values, ["A"]);
+
+ let ownKeysCallCount = 0;
+ let getOwnPropertyDescriptorCalls = [];
+ let target = { a: 1, b: 2, c: 3 };
+ o = new Proxy(target, {
+ ownKeys() {
+ ownKeysCallCount++;
+ return ["c", "a"];
+ },
+ getOwnPropertyDescriptor(target, key) {
+ getOwnPropertyDescriptorCalls.push(key);
+ return Object.getOwnPropertyDescriptor(target, key);
+ }
+ });
+ values = Object.values(o);
+ assertEq(ownKeysCallCount, 1);
+ assertDeepEq(values, [3, 1]);
+ assertDeepEq(getOwnPropertyDescriptorCalls, ["c", "a"]);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);