Backed out 2 changesets (bug 1488417, bug 1259822) for web compat issues.
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 10 Dec 2018 10:47:47 -0600
changeset 449703 8fc0458ea017
parent 449702 6915aee134cb
child 449704 cc5f0fb59ada
push id110422
push userjorendorff@mozilla.com
push dateMon, 10 Dec 2018 20:08:47 +0000
treeherdermozilla-inbound@8fc0458ea017 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1488417, 1259822
milestone65.0a1
backs outb58b7cd29a0b
f0c6e521429c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 2 changesets (bug 1488417, bug 1259822) for web compat issues. 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
@@ -3412,67 +3412,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");
   });