Backed out 2 changesets (bug 1488417, bug 1259822) for web compat issues. a=backout
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 10 Dec 2018 10:47:47 -0600
changeset 508927 5cfb828cce2d196e41f4ba603870525c32206dd8
parent 508926 d90c4df44d452d090a938ccff62b5351fc1f5c85
child 508928 8e281b518980ba27ba25faab66d248eb2272d3f1
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1488417, 1259822
milestone65.0
backs outb58b7cd29a0b3e43a3644e4c88c04740124870b4
f0c6e521429cfaff0585ec6eaf734e9fcf873f8a
Backed out 2 changesets (bug 1488417, bug 1259822) for web compat issues. a=backout Backed out changeset b58b7cd29a0b (bug 1488417) Backed out changeset f0c6e521429c (bug 1259822)
dom/u2f/tests/frame_appid_facet_insecure.html
js/src/jit-test/tests/basic/bug827104.js
js/src/jit-test/tests/basic/expression-autopsy.js
js/src/jit-test/tests/basic/iterable-error-messages.js
js/src/jit-test/tests/basic/testBug604210.js
js/src/jit-test/tests/debug/bug1275001.js
js/src/jit-test/tests/ion/bug913749.js
js/src/jit/BaselineIC.cpp
js/src/js.msg
js/src/jsapi-tests/testErrorInterceptor.cpp
js/src/tests/non262/extensions/regress-353116.js
js/src/tests/non262/regress/regress-469625-03.js
js/src/tests/non262/regress/regress-469758.js
js/src/vm/Interpreter-inl.h
js/src/vm/Interpreter.cpp
js/src/vm/JSContext.cpp
js/src/vm/JSContext.h
js/src/vm/JSObject.cpp
js/src/vm/JSObject.h
services/settings/test/unit/test_remote_settings_worker.js
toolkit/components/extensions/test/xpcshell/test_ext_contentscript_create_iframe.js
--- a/dom/u2f/tests/frame_appid_facet_insecure.html
+++ b/dom/u2f/tests/frame_appid_facet_insecure.html
@@ -28,17 +28,17 @@ async function doTests() {
     local_ok(err == "ReferenceError: u2f is not defined", "calling u2f should have thrown from an insecure origin");
   }
 
   try {
     window.u2f.register(null, [], [], function(res) {
       local_ok(false, "Callbacks should not be called.");
     });
   } catch (err) {
-    local_ok(err.toString().includes("TypeError: window.u2f is undefined"), "accessing window.u2f should have thrown from an insecure origin");
+    local_ok(err == "TypeError: window.u2f is undefined", "accessing window.u2f should have thrown from an insecure origin");
   }
 
   try {
     await promiseU2FRegister(null, [{
       version: version,
       challenge: bytesToBase64UrlSafe(challenge),
     }], [], function(res){
       local_ok(false, "Shouldn't have gotten here on an insecure origin");
--- a/js/src/jit-test/tests/basic/bug827104.js
+++ b/js/src/jit-test/tests/basic/bug827104.js
@@ -5,9 +5,9 @@ function f() {
     }
     a[i][0] = 0;
 }
 
 var e;
 try {
     f();
 } catch (error) {e = error;}
-assertEq(e.toString(), `TypeError: a[i] is undefined; can't access element at index 0`);
+assertEq(e.toString(), 'TypeError: a[i] is undefined');
\ No newline at end of file
--- a/js/src/jit-test/tests/basic/expression-autopsy.js
+++ b/js/src/jit-test/tests/basic/expression-autopsy.js
@@ -13,17 +13,17 @@ function check_one(expected, f, err) {
         assertEq(s.slice(11, -err.length), expected);
     }
     if (!failed)
         throw new Error("didn't fail");
 }
 ieval = eval;
 function check(expr, expected=expr, testStrict=true) {
     var end, err;
-    for ([end, err] of [[".random_prop", ` is undefined; can't access its "random_prop" property`], ["()", " is not a function"]]) {
+    for ([end, err] of [[".random_prop", " is undefined"], ["()", " is not a function"]]) {
         var statement = "o = {};" + expr + end, f;
         var cases = [
             // Global scope
             function () {
                 ieval("var o, undef;\n" + statement);
             },
             // Function scope
             Function("o", "undef", statement),
@@ -97,17 +97,17 @@ check("o[(~(o + 1))]");
 check("o[(+ (o + 1))]");
 check("o[(- (o + 1))]");
 
 // A few one off tests
 check_one("6", (function () { 6() }), " is not a function");
 check_one("4", (function() { (4||eval)(); }), " is not a function");
 check_one("0", (function () { Array.prototype.reverse.call('123'); }), " is read-only");
 check_one("[...][Symbol.iterator](...).next(...).value",
-          function () { ieval("{ let x; var [a, b, [c0, c1]] = [x, x, x]; }") }, " is undefined; can't access its Symbol.iterator property");
+          function () { ieval("{ let x; var [a, b, [c0, c1]] = [x, x, x]; }") }, " is undefined");
 check_one("(void 1)", function() { (void 1)(); }, " is not a function");
 check_one("(void o[1])", function() { var o = []; (void o[1])() }, " is not a function");
 
 check_one("(typeof 1)", function() { (typeof 1)(); }, " is not a function");
 check_one("(typeof o[1])", function() { var o = []; (typeof o[1])() }, " is not a function");
 
 check_one("(delete foo)",
           function() { (delete foo)(); },
--- a/js/src/jit-test/tests/basic/iterable-error-messages.js
+++ b/js/src/jit-test/tests/basic/iterable-error-messages.js
@@ -10,30 +10,30 @@ function assertThrowsMsg(f, msg) {
 
 // For-of
 function testForOf(val) {
     for (var x of val) {}
 }
 for (v of [{}, Math, new Proxy({}, {})]) {
     assertThrowsMsg(() => testForOf(v), "val is not iterable");
 }
-assertThrowsMsg(() => testForOf(null), "val is null; can't access its Symbol.iterator property");
+assertThrowsMsg(() => testForOf(null), "val is null");
 assertThrowsMsg(() => { for (var x of () => 1) {}}, "() => 1 is not iterable");
 
 // Destructuring
 function testDestr(val) {
     var [a, b] = val;
 }
 for (v of [{}, Math, new Proxy({}, {})]) {
     assertThrowsMsg(() => testDestr(v), "val is not iterable");
 }
-assertThrowsMsg(() => testDestr(null), "val is null; can't access its Symbol.iterator property");
+assertThrowsMsg(() => testDestr(null), "val is null");
 assertThrowsMsg(() => { [a, b] = () => 1; }, "() => 1 is not iterable");
 
 // Spread
 function testSpread(val) {
     [...val];
 }
 for (v of [{}, Math, new Proxy({}, {})]) {
     assertThrowsMsg(() => testSpread(v), "val is not iterable");
 }
-assertThrowsMsg(() => testSpread(null), "val is null; can't access its Symbol.iterator property");
+assertThrowsMsg(() => testSpread(null), "val is null");
 assertThrowsMsg(() => { [...() => 1]; }, "() => 1 is not iterable");
--- a/js/src/jit-test/tests/basic/testBug604210.js
+++ b/js/src/jit-test/tests/basic/testBug604210.js
@@ -1,11 +1,11 @@
 function f() {
     var msg = '';
     try {
         var x = undefined;
         print(x.foo);
     } catch (e) {
         msg = '' + e;
     }
-    assertEq(msg, `TypeError: x is undefined; can't access its "foo" property`);
+    assertEq(msg, "TypeError: x is undefined");
 }
 f();
--- a/js/src/jit-test/tests/debug/bug1275001.js
+++ b/js/src/jit-test/tests/debug/bug1275001.js
@@ -12,19 +12,19 @@ function check_one(expected, f, err) {
     } catch (ex) {
         s = ex.toString()
         assertEq(s.slice(11, -err.length), expected)
     }
 }
 ieval = eval
 function check(expr, expected = expr) {
     var end, err
-    for ([end, err] of [[".random_prop", ` is undefined, can't access its "random_prop" property`]])
+    for ([end, err] of[[".random_prop", " is undefined" ]]) 
          statement = "o = {};" + expr + end;
          cases = [
             function() { return ieval("var undef;" + statement); },
             Function(statement)
         ]
-        for (f of cases)
+        for (f of cases) 
             check_one(expected, f, err)
 }
 check("undef");
 check("o.b");
--- a/js/src/jit-test/tests/ion/bug913749.js
+++ b/js/src/jit-test/tests/ion/bug913749.js
@@ -8,18 +8,18 @@ Object.defineProperty(x, 18, {
 });
 this.toSource();
 
 y = undefined;
 
 // The exact error message varies nondeterministically. Accept several
 // variations on the theme.
 var variations = [
-    `y is undefined; can't access its "length" property`,
-    `can't access property "length" of undefined` ,
+    `y is undefined`,
+    `can't access property "length" of undefined`,
     `undefined has no properties`,
 ];
 
 var hits = 0;
 for (var i = 0; i < 3; i++) {
     try {
         x.toString();
     } catch (e) {
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -2214,17 +2214,17 @@ static bool DoSetElemFallback(JSContext*
   jsbytecode* pc = stub->icEntry()->pc(script);
   JSOp op = JSOp(*pc);
   FallbackICSpew(cx, stub, "SetElem(%s)", CodeName[JSOp(*pc)]);
 
   MOZ_ASSERT(op == JSOP_SETELEM || op == JSOP_STRICTSETELEM ||
              op == JSOP_INITELEM || op == JSOP_INITHIDDENELEM ||
              op == JSOP_INITELEM_ARRAY || op == JSOP_INITELEM_INC);
 
-  RootedObject obj(cx, ToObjectFromStackForPropertyAccess(cx, objv, index));
+  RootedObject obj(cx, ToObjectFromStack(cx, objv));
   if (!obj) {
     return false;
   }
 
   RootedShape oldShape(cx, obj->maybeShape());
   RootedObjectGroup oldGroup(cx, JSObject::getGroup(cx, obj));
   if (!oldGroup) {
     return false;
@@ -3003,17 +3003,17 @@ static bool DoSetPropFallback(JSContext*
   if (op == JSOP_SETALIASEDVAR || op == JSOP_INITALIASEDLEXICAL) {
     name = EnvironmentCoordinateName(cx->caches().envCoordinateNameCache,
                                      script, pc);
   } else {
     name = script->getName(pc);
   }
   RootedId id(cx, NameToId(name));
 
-  RootedObject obj(cx, ToObjectFromStackForPropertyAccess(cx, lhs, id));
+  RootedObject obj(cx, ToObjectFromStack(cx, lhs));
   if (!obj) {
     return false;
   }
   RootedShape oldShape(cx, obj->maybeShape());
   RootedObjectGroup oldGroup(cx, JSObject::getGroup(cx, obj));
   if (!oldGroup) {
     return false;
   }
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -4,32 +4,31 @@
  * 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/. */
 
 /*
  * This is the JavaScript error message file.
  *
  * The format for each JS error message is:
  *
- *     MSG_DEF(<SYMBOLIC_NAME>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
- *             <FORMAT_STRING>)
+ * MSG_DEF(<SYMBOLIC_NAME>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
+ *         <FORMAT_STRING>)
  *
- * where:
- *
- *     <SYMBOLIC_NAME> is a legal C identifer that will be used in the
- *     JS engine source.
+ * where ;
+ * <SYMBOLIC_NAME> is a legal C identifer that will be used in the
+ * JS engine source.
  *
- *     <ARGUMENT_COUNT> is an integer literal specifying the total number of
- *     replaceable arguments in the following format string.
+ * <ARGUMENT_COUNT> is an integer literal specifying the total number of
+ * replaceable arguments in the following format string.
  *
- *     <EXCEPTION_NAME> is an enum JSExnType value, defined in jsapi.h.
+ * <EXCEPTION_NAME> is an enum JSExnType value, defined in jsapi.h.
  *
- *     <FORMAT_STRING> is a string literal, optionally containing sequences
- *     {X} where X  is an integer representing the argument number that will
- *     be replaced with a string value when the error is reported.
+ * <FORMAT_STRING> is a string literal, optionally containing sequences
+ * {X} where X  is an integer representing the argument number that will
+ * be replaced with a string value when the error is reported.
  *
  * e.g.
  *
  * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 2, JSEXN_TYPEERROR,
  *         "{0} is not a member of the {1} family")
  *
  * can be used:
  *
@@ -51,19 +50,16 @@ MSG_DEF(JSMSG_CANT_DELETE,             1
 MSG_DEF(JSMSG_CANT_TRUNCATE_ARRAY,     0, JSEXN_TYPEERR, "can't delete non-configurable array element")
 MSG_DEF(JSMSG_NOT_FUNCTION,            1, JSEXN_TYPEERR, "{0} is not a function")
 MSG_DEF(JSMSG_NOT_CONSTRUCTOR,         1, JSEXN_TYPEERR, "{0} is not a constructor")
 MSG_DEF(JSMSG_BOGUS_CONSTRUCTOR,       1, JSEXN_TYPEERR, "{0} constructor can't be used directly")
 MSG_DEF(JSMSG_CANT_CONVERT_TO,         2, JSEXN_TYPEERR, "can't convert {0} to {1}")
 MSG_DEF(JSMSG_TOPRIMITIVE_NOT_CALLABLE, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] property is not a function")
 MSG_DEF(JSMSG_TOPRIMITIVE_RETURNED_OBJECT, 2, JSEXN_TYPEERR, "can't convert {0} to {1}: its [Symbol.toPrimitive] method returned an object")
 MSG_DEF(JSMSG_NO_PROPERTIES,           1, JSEXN_TYPEERR, "{0} has no properties")
-MSG_DEF(JSMSG_PROPERTY_FAIL,           2, JSEXN_TYPEERR, "can't access property {0} of {1}")
-MSG_DEF(JSMSG_PROPERTY_FAIL_EXPR,      3, JSEXN_TYPEERR, "{0} is {1}; can't access its {2} property")
-MSG_DEF(JSMSG_ELEMENT_FAIL_EXPR,       3, JSEXN_TYPEERR, "{0} is {1}; can't access element at index {2}")
 MSG_DEF(JSMSG_BAD_REGEXP_FLAG,         1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
 MSG_DEF(JSMSG_INVALID_DATA_VIEW_LENGTH, 0, JSEXN_RANGEERR, "invalid data view length")
 MSG_DEF(JSMSG_OFFSET_LARGER_THAN_FILESIZE, 0, JSEXN_RANGEERR, "offset is larger than filesize")
 MSG_DEF(JSMSG_OFFSET_OUT_OF_BUFFER,    0, JSEXN_RANGEERR, "start offset is outside the bounds of the buffer")
 MSG_DEF(JSMSG_OFFSET_OUT_OF_DATAVIEW,  0, JSEXN_RANGEERR, "offset is outside the bounds of the DataView")
 MSG_DEF(JSMSG_SPREAD_TOO_LARGE,        0, JSEXN_RANGEERR, "array too large due to spread operand(s)")
 MSG_DEF(JSMSG_BAD_WEAKMAP_KEY,         0, JSEXN_TYPEERR, "cannot use the given object as a weak map key")
 MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER,    1, JSEXN_TYPEERR, "invalid {0} usage")
--- a/js/src/jsapi-tests/testErrorInterceptor.cpp
+++ b/js/src/jsapi-tests/testErrorInterceptor.cpp
@@ -30,35 +30,35 @@ bool equalStrings(JSContext* cx, JSStrin
   }
   return result == 0;
 }
 }  // namespace
 
 BEGIN_TEST(testErrorInterceptor) {
   // Run the following snippets.
   const char* SAMPLES[] = {
-      "throw new Error('I am an Error')",
-      "throw new TypeError('I am a TypeError')",
-      "throw new ReferenceError('I am a ReferenceError')",
-      "throw new SyntaxError('I am a SyntaxError')",
-      "throw 5",
-      "undefined[0]",
-      "foo[0]",
-      "b[",
+      "throw new Error('I am an Error')\0",
+      "throw new TypeError('I am a TypeError')\0",
+      "throw new ReferenceError('I am a ReferenceError')\0",
+      "throw new SyntaxError('I am a SyntaxError')\0",
+      "throw 5\0",
+      "undefined[0]\0",
+      "foo[0]\0",
+      "b[\0",
   };
   // With the simpleInterceptor, we should end up with the following error:
   const char* TO_STRING[] = {
-      "Error: I am an Error",
-      "TypeError: I am a TypeError",
-      "ReferenceError: I am a ReferenceError",
-      "SyntaxError: I am a SyntaxError",
-      "5",
-      "TypeError: can't access property 0 of undefined",
-      "ReferenceError: foo is not defined",
-      "SyntaxError: expected expression, got end of script",
+      "Error: I am an Error\0",
+      "TypeError: I am a TypeError\0",
+      "ReferenceError: I am a ReferenceError\0",
+      "SyntaxError: I am a SyntaxError\0",
+      "5\0",
+      "TypeError: undefined has no properties\0",
+      "ReferenceError: foo is not defined\0",
+      "SyntaxError: expected expression, got end of script\0",
   };
   MOZ_ASSERT(mozilla::ArrayLength(SAMPLES) == mozilla::ArrayLength(TO_STRING));
 
   // Save original callback.
   JSErrorInterceptor* original = JS_GetErrorInterceptorCallback(cx->runtime());
   gLatestMessage.init(cx);
 
   // Test without callback.
--- a/js/src/tests/non262/extensions/regress-353116.js
+++ b/js/src/tests/non262/extensions/regress-353116.js
@@ -14,57 +14,57 @@ var expect = '';
 test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   printBugNumber(BUGNUMBER);
   printStatus (summary);
 
-  expect = `TypeError: can't access property "y" of undefined`;
+  expect = 'TypeError: undefined has no properties';
   actual = 'No Error';
 
   try
   {
     undefined.y;
   }
   catch(ex)
   {
     actual = ex + '';
   }
   reportCompare(expect, actual, summary);
 
-  expect = `TypeError: can't access property "y" of null`;
+  expect = 'TypeError: null has no properties';
   actual = 'No Error';
 
   try
   {
     null.y;
   }
   catch(ex)
   {
     actual = ex + '';
   }
   reportCompare(expect, actual, summary);
 
-  expect = `TypeError: x is undefined; can't access its "y" property`;
+  expect = 'TypeError: x is undefined';
   actual = 'No Error';
 
   try
   {
     x = undefined; 
     x.y;
   }
   catch(ex)
   {
     actual = ex + '';
   }
   reportCompare(expect, actual, summary);
 
-  expect = `TypeError: x is null; can't access its "y" property`;
+  expect = 'TypeError: x is null';
   actual = 'No Error';
 
   try
   {
     x = null; 
     x.y;
   }
   catch(ex)
--- a/js/src/tests/non262/regress/regress-469625-03.js
+++ b/js/src/tests/non262/regress/regress-469625-03.js
@@ -20,17 +20,17 @@ function test()
 {
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
   function f(x) {
     var [a, b, [c0, c1]] = [x, x, x];
   }
 
-  expect = `TypeError: [...][Symbol.iterator](...).next(...).value is null; can't access its Symbol.iterator property`;
+  expect = `TypeError: [...][Symbol.iterator](...).next(...).value is null`;
   actual = 'No Error';
   try
   {
     f(null);
   }
   catch(ex)
   {
     actual = ex + '';
--- a/js/src/tests/non262/regress/regress-469758.js
+++ b/js/src/tests/non262/regress/regress-469758.js
@@ -4,11 +4,11 @@
 var err;
 try {
     {let i=1}
     {let j=1; [][j][2]}
 } catch (e) {
     err = e;
 }
 assertEq(err instanceof TypeError, true);
-assertEq(err.message, "[][j] is undefined; can't access element at index 2");
+assertEq(err.message, "[][j] is undefined");
 
 reportCompare(0, 0, 'ok');
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -543,17 +543,17 @@ static MOZ_ALWAYS_INLINE bool GetObjectE
 }
 
 static MOZ_ALWAYS_INLINE bool GetPrimitiveElementOperation(
     JSContext* cx, JSOp op, JS::HandleValue receiver, HandleValue key,
     MutableHandleValue res) {
   MOZ_ASSERT(op == JSOP_GETELEM || op == JSOP_CALLELEM);
 
   // FIXME: Bug 1234324 We shouldn't be boxing here.
-  RootedObject boxed(cx, ToObjectFromStackForPropertyAccess(cx, receiver, key));
+  RootedObject boxed(cx, ToObjectFromStack(cx, receiver));
   if (!boxed) {
     return false;
   }
 
   do {
     uint32_t index;
     if (IsDefinitelyIndex(key, &index)) {
       if (GetElementNoGC(cx, boxed, receiver, index, res.address())) {
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -252,17 +252,17 @@ static inline bool GetImportOperation(JS
   MOZ_ASSERT(env->as<ModuleEnvironmentObject>().hasImportBinding(name));
   return FetchName<GetNameMode::Normal>(cx, env, pobj, name, prop, vp);
 }
 
 static bool SetPropertyOperation(JSContext* cx, JSOp op, HandleValue lval,
                                  HandleId id, HandleValue rval) {
   MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
 
-  RootedObject obj(cx, ToObjectFromStackForPropertyAccess(cx, lval, id));
+  RootedObject obj(cx, ToObjectFromStack(cx, lval));
   if (!obj) {
     return false;
   }
 
   ObjectOpResult result;
   return SetProperty(cx, obj, id, rval, lval, result) &&
          result.checkStrictErrorOrWarning(cx, obj, id,
                                           op == JSOP_STRICTSETPROP);
@@ -1578,21 +1578,21 @@ again:
   do {                               \
     REGS.sp++->setObjectOrNull(obj); \
     cx->debugOnlyCheck(REGS.sp[-1]); \
   } while (0)
 #define PUSH_MAGIC(magic) REGS.sp++->setMagic(magic)
 #define POP_COPY_TO(v) (v) = *--REGS.sp
 #define POP_RETURN_VALUE() REGS.fp()->setReturnValue(*--REGS.sp)
 
-#define FETCH_OBJECT(cx, n, obj, key)                             \
-  JS_BEGIN_MACRO                                                  \
-    HandleValue val = REGS.stackHandleAt(n);                      \
-    obj = ToObjectFromStackForPropertyAccess((cx), (val), (key)); \
-    if (!obj) goto error;                                         \
+#define FETCH_OBJECT(cx, n, obj)             \
+  JS_BEGIN_MACRO                             \
+    HandleValue val = REGS.stackHandleAt(n); \
+    obj = ToObjectFromStack((cx), (val));    \
+    if (!obj) goto error;                    \
   JS_END_MACRO
 
 /*
  * Same for JSOP_SETNAME and JSOP_SETPROP, which differ only slightly but
  * remain distinct for the decompiler.
  */
 JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
 
@@ -2881,17 +2881,17 @@ static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_
     END_CASE(JSOP_DELNAME)
 
     CASE(JSOP_DELPROP)
     CASE(JSOP_STRICTDELPROP) {
       static_assert(JSOP_DELPROP_LENGTH == JSOP_STRICTDELPROP_LENGTH,
                     "delprop and strictdelprop must be the same size");
       ReservedRooted<jsid> id(&rootId0, NameToId(script->getName(REGS.pc)));
       ReservedRooted<JSObject*> obj(&rootObject0);
-      FETCH_OBJECT(cx, -1, obj, id);
+      FETCH_OBJECT(cx, -1, obj);
 
       ObjectOpResult result;
       if (!DeleteProperty(cx, obj, id, result)) {
         goto error;
       }
       if (!result && JSOp(*REGS.pc) == JSOP_STRICTDELPROP) {
         result.reportError(cx, obj, id);
         goto error;
@@ -2902,18 +2902,19 @@ static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_
     END_CASE(JSOP_DELPROP)
 
     CASE(JSOP_DELELEM)
     CASE(JSOP_STRICTDELELEM) {
       static_assert(JSOP_DELELEM_LENGTH == JSOP_STRICTDELELEM_LENGTH,
                     "delelem and strictdelelem must be the same size");
       /* Fetch the left part and resolve it to a non-null object. */
       ReservedRooted<JSObject*> obj(&rootObject0);
+      FETCH_OBJECT(cx, -2, obj);
+
       ReservedRooted<Value> propval(&rootValue0, REGS.sp[-1]);
-      FETCH_OBJECT(cx, -2, obj, propval);
 
       ObjectOpResult result;
       ReservedRooted<jsid> id(&rootId0);
       if (!ToPropertyKey(cx, propval, &id)) {
         goto error;
       }
       if (!DeleteProperty(cx, obj, id, result)) {
         goto error;
@@ -3169,18 +3170,17 @@ static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_
     END_CASE(JSOP_GETELEM_SUPER)
 
     CASE(JSOP_SETELEM)
     CASE(JSOP_STRICTSETELEM) {
       static_assert(JSOP_SETELEM_LENGTH == JSOP_STRICTSETELEM_LENGTH,
                     "setelem and strictsetelem must be the same size");
       HandleValue receiver = REGS.stackHandleAt(-3);
       ReservedRooted<JSObject*> obj(&rootObject0);
-      obj = ToObjectFromStackForPropertyAccess(cx, receiver,
-                                               REGS.stackHandleAt(-2));
+      obj = ToObjectFromStack(cx, receiver);
       if (!obj) {
         goto error;
       }
       ReservedRooted<jsid> id(&rootId0);
       FETCH_ELEMENT_ID(-2, id);
       HandleValue value = REGS.stackHandleAt(-1);
       if (!SetObjectElementOperation(cx, obj, id, value, receiver,
                                      *REGS.pc == JSOP_STRICTSETELEM)) {
@@ -4726,17 +4726,17 @@ bool js::GetProperty(JSContext* cx, Hand
     }
 
     if (GetPropertyPure(cx, proto, NameToId(name), vp.address())) {
       return true;
     }
   }
 
   RootedValue receiver(cx, v);
-  RootedObject obj(cx, ToObjectFromStackForPropertyAccess(cx, v, name));
+  RootedObject obj(cx, ToObjectFromStack(cx, v));
   if (!obj) {
     return false;
   }
 
   return GetProperty(cx, obj, receiver, name, vp);
 }
 
 JSObject* js::Lambda(JSContext* cx, HandleFunction fun, HandleObject parent) {
@@ -4870,17 +4870,17 @@ bool js::GetAndClearException(JSContext*
 
   // Allow interrupting deeply nested exception handling.
   return CheckForInterrupt(cx);
 }
 
 template <bool strict>
 bool js::DeletePropertyJit(JSContext* cx, HandleValue v,
                            HandlePropertyName name, bool* bp) {
-  RootedObject obj(cx, ToObjectFromStackForPropertyAccess(cx, v, name));
+  RootedObject obj(cx, ToObjectFromStack(cx, v));
   if (!obj) {
     return false;
   }
 
   RootedId id(cx, NameToId(name));
   ObjectOpResult result;
   if (!DeleteProperty(cx, obj, id, result)) {
     return false;
@@ -4900,17 +4900,17 @@ bool js::DeletePropertyJit(JSContext* cx
 template bool js::DeletePropertyJit<true>(JSContext* cx, HandleValue val,
                                           HandlePropertyName name, bool* bp);
 template bool js::DeletePropertyJit<false>(JSContext* cx, HandleValue val,
                                            HandlePropertyName name, bool* bp);
 
 template <bool strict>
 bool js::DeleteElementJit(JSContext* cx, HandleValue val, HandleValue index,
                           bool* bp) {
-  RootedObject obj(cx, ToObjectFromStackForPropertyAccess(cx, val, index));
+  RootedObject obj(cx, ToObjectFromStack(cx, val));
   if (!obj) {
     return false;
   }
 
   RootedId id(cx);
   if (!ToPropertyKey(cx, index, &id)) {
     return false;
   }
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -877,29 +877,20 @@ void js::ReportIsNotDefined(JSContext* c
   }
 }
 
 void js::ReportIsNotDefined(JSContext* cx, HandlePropertyName name) {
   RootedId id(cx, NameToId(name));
   ReportIsNotDefined(cx, id);
 }
 
-void js::ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx, HandleValue v,
-                                                  bool reportScanStack) {
+void js::ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v) {
   MOZ_ASSERT(v.isNullOrUndefined());
 
-  if (!reportScanStack) {
-    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
-                              JSMSG_CANT_CONVERT_TO,
-                              v.isNull() ? "null" : "undefined", "object");
-    return;
-  }
-
-  UniqueChars bytes =
-      DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, nullptr);
+  UniqueChars bytes = DecompileValueGenerator(cx, spindex, v, nullptr);
   if (!bytes) {
     return;
   }
 
   if (strcmp(bytes.get(), js_undefined_str) == 0 ||
       strcmp(bytes.get(), js_null_str) == 0) {
     JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NO_PROPERTIES,
                              bytes.get());
@@ -909,58 +900,16 @@ void js::ReportIsNullOrUndefinedForPrope
                              js_undefined_str);
   } else {
     MOZ_ASSERT(v.isNull());
     JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
                              JSMSG_UNEXPECTED_TYPE, bytes.get(), js_null_str);
   }
 }
 
-void js::ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx, HandleValue v,
-                                                  HandleId key,
-                                                  bool reportScanStack) {
-  MOZ_ASSERT(v.isNullOrUndefined());
-
-  UniqueChars keyBytes =
-      IdToPrintableUTF8(cx, key, IdToPrintableBehavior::IdIsPropertyKey);
-  if (!keyBytes) {
-    return;
-  }
-
-  if (!reportScanStack) {
-    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL,
-                             keyBytes.get(),
-                             v.isUndefined() ? js_undefined_str : js_null_str);
-    return;
-  }
-
-  UniqueChars bytes =
-      DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, nullptr);
-  if (!bytes) {
-    return;
-  }
-
-  if (strcmp(bytes.get(), js_undefined_str) == 0 ||
-      strcmp(bytes.get(), js_null_str) == 0) {
-    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL,
-                             keyBytes.get(), bytes.get());
-  } else {
-    const char* actual = v.isUndefined() ? js_undefined_str : js_null_str;
-    if (JSID_IS_INT(key)) {
-      JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
-                               JSMSG_ELEMENT_FAIL_EXPR, bytes.get(), actual,
-                               keyBytes.get());
-    } else {
-      JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
-                               JSMSG_PROPERTY_FAIL_EXPR, bytes.get(), actual,
-                               keyBytes.get());
-    }
-  }
-}
-
 void js::ReportMissingArg(JSContext* cx, HandleValue v, unsigned arg) {
   char argbuf[11];
   UniqueChars bytes;
 
   SprintfLiteral(argbuf, "%u", arg);
   if (IsFunctionObject(v)) {
     RootedAtom name(cx, v.toObject().as<JSFunction>().explicitName());
     bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, name);
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -1057,23 +1057,17 @@ extern bool PrintError(JSContext* cx, FI
 
 extern void ReportIsNotDefined(JSContext* cx, HandlePropertyName name);
 
 extern void ReportIsNotDefined(JSContext* cx, HandleId id);
 
 /*
  * Report an attempt to access the property of a null or undefined value (v).
  */
-extern void ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx,
-                                                     HandleValue v,
-                                                     bool reportScanStack);
-extern void ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx,
-                                                     HandleValue v,
-                                                     HandleId key,
-                                                     bool reportScanStack);
+extern void ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v);
 
 extern void ReportMissingArg(JSContext* cx, js::HandleValue v, unsigned arg);
 
 /*
  * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
  * the first argument for the error message. If the error message has less
  * then 3 arguments, use null for arg1 or arg2.
  */
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -3414,67 +3414,22 @@ JSObject* js::PrimitiveToObject(JSContex
  * Callers must handle the already-object case.
  */
 JSObject* js::ToObjectSlow(JSContext* cx, JS::HandleValue val,
                            bool reportScanStack) {
   MOZ_ASSERT(!val.isMagic());
   MOZ_ASSERT(!val.isObject());
 
   if (val.isNullOrUndefined()) {
-    ReportIsNullOrUndefinedForPropertyAccess(cx, val, reportScanStack);
-    return nullptr;
-  }
-
-  return PrimitiveToObject(cx, val);
-}
-
-JSObject* js::ToObjectSlowForPropertyAccess(JSContext* cx, JS::HandleValue val,
-                                            HandleId key,
-                                            bool reportScanStack) {
-  MOZ_ASSERT(!val.isMagic());
-  MOZ_ASSERT(!val.isObject());
-
-  if (val.isNullOrUndefined()) {
-    ReportIsNullOrUndefinedForPropertyAccess(cx, val, key, reportScanStack);
-    return nullptr;
-  }
-
-  return PrimitiveToObject(cx, val);
-}
-
-JSObject* js::ToObjectSlowForPropertyAccess(JSContext* cx, JS::HandleValue val,
-                                            HandlePropertyName key,
-                                            bool reportScanStack) {
-  MOZ_ASSERT(!val.isMagic());
-  MOZ_ASSERT(!val.isObject());
-
-  if (val.isNullOrUndefined()) {
-    RootedId keyId(cx, NameToId(key));
-    ReportIsNullOrUndefinedForPropertyAccess(cx, val, keyId, reportScanStack);
-    return nullptr;
-  }
-
-  return PrimitiveToObject(cx, val);
-}
-
-JSObject* js::ToObjectSlowForPropertyAccess(JSContext* cx, JS::HandleValue val,
-                                            HandleValue keyValue,
-                                            bool reportScanStack) {
-  MOZ_ASSERT(!val.isMagic());
-  MOZ_ASSERT(!val.isObject());
-
-  if (val.isNullOrUndefined()) {
-    RootedId key(cx);
-    if (keyValue.isPrimitive()) {
-      if (!ValueToId<CanGC>(cx, keyValue, &key)) {
-        return nullptr;
-      }
-      ReportIsNullOrUndefinedForPropertyAccess(cx, val, key, reportScanStack);
+    if (reportScanStack) {
+      ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val);
     } else {
-      ReportIsNullOrUndefinedForPropertyAccess(cx, val, reportScanStack);
+      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                                JSMSG_CANT_CONVERT_TO,
+                                val.isNull() ? "null" : "undefined", "object");
     }
     return nullptr;
   }
 
   return PrimitiveToObject(cx, val);
 }
 
 Value js::GetThisValue(JSObject* obj) {
--- a/js/src/vm/JSObject.h
+++ b/js/src/vm/JSObject.h
@@ -949,48 +949,16 @@ namespace js {
 /* For converting stack values to objects. */
 MOZ_ALWAYS_INLINE JSObject* ToObjectFromStack(JSContext* cx, HandleValue vp) {
   if (vp.isObject()) {
     return &vp.toObject();
   }
   return js::ToObjectSlow(cx, vp, true);
 }
 
-JSObject* ToObjectSlowForPropertyAccess(JSContext* cx, JS::HandleValue val,
-                                        HandleId key, bool reportScanStack);
-JSObject* ToObjectSlowForPropertyAccess(JSContext* cx, JS::HandleValue val,
-                                        HandlePropertyName key,
-                                        bool reportScanStack);
-JSObject* ToObjectSlowForPropertyAccess(JSContext* cx, JS::HandleValue val,
-                                        HandleValue keyValue,
-                                        bool reportScanStack);
-
-MOZ_ALWAYS_INLINE JSObject* ToObjectFromStackForPropertyAccess(JSContext* cx,
-                                                               HandleValue vp,
-                                                               HandleId key) {
-  if (vp.isObject()) {
-    return &vp.toObject();
-  }
-  return js::ToObjectSlowForPropertyAccess(cx, vp, key, true);
-}
-MOZ_ALWAYS_INLINE JSObject* ToObjectFromStackForPropertyAccess(
-    JSContext* cx, HandleValue vp, HandlePropertyName key) {
-  if (vp.isObject()) {
-    return &vp.toObject();
-  }
-  return js::ToObjectSlowForPropertyAccess(cx, vp, key, true);
-}
-MOZ_ALWAYS_INLINE JSObject* ToObjectFromStackForPropertyAccess(
-    JSContext* cx, HandleValue vp, HandleValue key) {
-  if (vp.isObject()) {
-    return &vp.toObject();
-  }
-  return js::ToObjectSlowForPropertyAccess(cx, vp, key, true);
-}
-
 template <XDRMode mode>
 XDRResult XDRObjectLiteral(XDRState<mode>* xdr, MutableHandleObject obj);
 
 /*
  * Report a TypeError: "so-and-so is not an object".
  * Using NotNullObject is usually less code.
  */
 extern void ReportNotObject(JSContext* cx, HandleValue v);
--- a/services/settings/test/unit/test_remote_settings_worker.js
+++ b/services/settings/test/unit/test_remote_settings_worker.js
@@ -41,10 +41,10 @@ add_task(async function test_import_json
 
 add_task(async function test_throws_error_if_worker_fails() {
   let error;
   try {
     await RemoteSettingsWorker.canonicalStringify(null, [], 42);
   } catch (e) {
     error = e;
   }
-  Assert.equal("TypeError: localRecords is null; can't access its \"concat\" property", error.message);
+  Assert.equal("TypeError: localRecords is null", error.message);
 });
--- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_create_iframe.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_create_iframe.js
@@ -119,18 +119,17 @@ add_task(async function test_contentscri
     try {
       manifest = win.browser.runtime.getManifest();
     } catch (e) {
       manifestException = e;
     }
 
     Assert.ok(!manifest, "manifest should be undefined");
 
-    Assert.equal(String(manifestException),
-                 `TypeError: win.browser.runtime is undefined; can't access its "getManifest" property`,
+    Assert.equal(String(manifestException), "TypeError: win.browser.runtime is undefined",
                  "expected exception received");
 
     let getManifestException = win.testGetManifestException();
 
     Assert.equal(getManifestException, "TypeError: can't access dead object",
                  "expected exception received");
   });