Backed out changeset f0c6e521429c (bug 1259822) as requested by jorendorff. a=backout
authorCosmin Sabou <csabou@mozilla.com>
Tue, 16 Oct 2018 17:20:33 +0300
changeset 492931 ea4b5c999c575532506dfe6c702f59c5a268983b
parent 492930 e822fa107a8ea5c4d80e4a829ba45a9b6bd5bc14
child 492932 ec06a13284f18e6b1841c0f58095a3535c50e99d
push id1821
push usercsabou@mozilla.com
push dateTue, 16 Oct 2018 14:21:42 +0000
treeherdermozilla-release@ea4b5c999c57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1259822
milestone63.0
backs outf0c6e521429cfaff0585ec6eaf734e9fcf873f8a
Backed out changeset f0c6e521429c (bug 1259822) as requested by jorendorff. a=backout
dom/browser-element/mochitest/browserElement_ExecuteScript.js
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
toolkit/components/extensions/test/xpcshell/test_ext_contentscript_create_iframe.js
--- a/dom/browser-element/mochitest/browserElement_ExecuteScript.js
+++ b/dom/browser-element/mochitest/browserElement_ExecuteScript.js
@@ -86,17 +86,17 @@ function runTest() {
       `, {url});
     }).then(bail, (error) => {
       is(error.message, 'Value returned (resolve) by promise is not a valid JSON object', `scriptId: ${scriptId++}`);
       return iframe.executeScript('window.btoa("a")', {url})
     }, bail).then(rv => {
       ok(c(rv, 'YQ=='), `scriptId: ${scriptId++}`);
       return iframe.executeScript('window.wrappedJSObject.btoa("a")', {url})
     }, bail).then(bail, (error) => {
-      is(error.message, `TypeError: window.wrappedJSObject is undefined, can't access property "btoa" of it`, `scriptId: ${scriptId++}`);
+      is(error.message, 'TypeError: window.wrappedJSObject is undefined', `scriptId: ${scriptId++}`);
       return iframe.executeScript('42', {})
     }).then(bail, error => {
       is(error.name, 'InvalidAccessError', `scriptId: ${scriptId++}`);
       return iframe.executeScript('42');
     }).then(bail, error => {
       is(error.name, 'InvalidAccessError', `scriptId: ${scriptId++}`);
       return iframe.executeScript('43', { url: 'http://foo.com' });
     }).then(bail, (error) => {
--- 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 property 0 of it`);
+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 property \"random_prop" of it`], ["()", " 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 property Symbol.iterator of it");
+          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 property Symbol.iterator of it");
+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 property Symbol.iterator of it");
+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 property Symbol.iterator of it");
+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 property "foo" of it`);
+    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,17 +12,17 @@ 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 property \"random_prop" of it` ]]) 
+    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) 
             check_one(expected, f, err)
 }
--- a/js/src/jit-test/tests/ion/bug913749.js
+++ b/js/src/jit-test/tests/ion/bug913749.js
@@ -10,12 +10,12 @@ this.toSource();
 
 y = undefined;
 
 for (var i = 0; i < 3; i++) {
     try {
 	x.toString();
 	assertEq(0, 1);
     } catch (e) {
-	assertEq(e.message === `y is undefined, can't access property "length" of it` ||
+	assertEq(e.message === "y is undefined" ||
 		 e.message === "undefined has no properties", true);
     }
 }
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -1877,17 +1877,17 @@ DoSetElemFallback(JSContext* cx, Baselin
 
     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;
 
@@ -2766,17 +2766,17 @@ DoSetPropFallback(JSContext* cx, Baselin
 
     RootedPropertyName name(cx);
     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;
 
     if (obj->is<UnboxedPlainObject>()) {
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -49,18 +49,16 @@ MSG_DEF(JSMSG_READ_ONLY,               1
 MSG_DEF(JSMSG_CANT_DELETE,             1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted")
 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_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 property {2} of it")
 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
@@ -45,17 +45,17 @@ BEGIN_TEST(testErrorInterceptor)
     };
     // With the simpleInterceptor, we should end up with the following error:
     const char* TO_STRING[] = {
         "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: can't access property 0 of undefined\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());
--- 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 property "y" of it`;
+  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 property "y" of it`;
+  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 property Symbol.iterator of it`;
+  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 property 2 of it");
+assertEq(err.message, "[][j] is undefined");
 
 reportCompare(0, 0, 'ok');
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -533,17 +533,17 @@ GetObjectElementOperation(JSContext* cx,
 
 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()))
                 break;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -258,17 +258,17 @@ GetImportOperation(JSContext* cx, Interp
     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);
 }
 
@@ -1537,20 +1537,20 @@ HandleError(JSContext* cx, InterpreterRe
 #define PUSH_SYMBOL(s)           REGS.sp++->setSymbol(s)
 #define PUSH_STRING(s)           do { REGS.sp++->setString(s); cx->debugOnlyCheck(REGS.sp[-1]); } while (0)
 #define PUSH_OBJECT(obj)         do { REGS.sp++->setObject(obj); cx->debugOnlyCheck(REGS.sp[-1]); } while (0)
 #define PUSH_OBJECT_OR_NULL(obj) 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)                                         \
+#define FETCH_OBJECT(cx, n, obj)                                              \
     JS_BEGIN_MACRO                                                            \
         HandleValue val = REGS.stackHandleAt(n);                              \
-        obj = ToObjectFromStackForPropertyAccess((cx), (val), (key));         \
+        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.
  */
@@ -2843,17 +2843,17 @@ 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;
     }
@@ -2864,18 +2864,19 @@ 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;
     if (!result && JSOp(*REGS.pc) == JSOP_STRICTDELELEM) {
@@ -3129,17 +3130,17 @@ 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))
         goto error;
     REGS.sp[-3] = value;
@@ -4632,17 +4633,17 @@ js::GetProperty(JSContext* cx, HandleVal
         if (!proto)
             return false;
 
         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)
@@ -4777,17 +4778,17 @@ js::GetAndClearException(JSContext* cx, 
     // 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;
 
@@ -4805,17 +4806,17 @@ template bool js::DeletePropertyJit<true
                                            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;
     ObjectOpResult result;
     if (!DeleteProperty(cx, obj, id, result))
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -905,88 +905,37 @@ js::ReportIsNotDefined(JSContext* cx, Ha
 void
 js::ReportIsNotDefined(JSContext* cx, HandlePropertyName name)
 {
     RootedId id(cx, NameToId(name));
     ReportIsNotDefined(cx, id);
 }
 
 void
-js::ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx, HandleValue v, bool reportScanStack)
+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_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NO_PROPERTIES,
                                    bytes.get());
     } else if (v.isUndefined()) {
         JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
                                    bytes.get(), js_undefined_str);
     } else {
         MOZ_ASSERT(v.isNull());
         JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
                                    bytes.get(), js_null_str);
     }
 }
 
-char*
-EncodeIdAsLatin1(JSContext* cx, HandleId id, JSAutoByteString& bytes)
-{
-    RootedValue idVal(cx, IdToValue(id));
-    RootedString idStr(cx, ValueToSource(cx, idVal));
-    if (!idStr)
-        return nullptr;
-
-    return bytes.encodeLatin1(cx, idStr);
-}
-
-void
-js::ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx, HandleValue v, HandleId key,
-                                             bool reportScanStack)
-{
-    MOZ_ASSERT(v.isNullOrUndefined());
-
-    JSAutoByteString keyBytes;
-    if (!EncodeIdAsLatin1(cx, key, keyBytes))
-        return;
-
-    if (!reportScanStack) {
-        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL,
-                                   keyBytes.ptr(),
-                                   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_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL,
-                                   keyBytes.ptr(), bytes.get());
-    } else if (v.isUndefined()) {
-        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL_EXPR,
-                                   bytes.get(), js_undefined_str, keyBytes.ptr());
-    } else {
-        MOZ_ASSERT(v.isNull());
-        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL_EXPR,
-                                   bytes.get(), js_null_str, keyBytes.ptr());
-    }
-}
-
 void
 js::ReportMissingArg(JSContext* cx, HandleValue v, unsigned arg)
 {
     char argbuf[11];
     UniqueChars bytes;
 
     SprintfLiteral(argbuf, "%u", arg);
     if (IsFunctionObject(v)) {
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -1102,20 +1102,17 @@ ReportIsNotDefined(JSContext* cx, Handle
 
 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);
+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
@@ -3234,69 +3234,21 @@ js::PrimitiveToObject(JSContext* cx, con
  */
 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
--- a/js/src/vm/JSObject.h
+++ b/js/src/vm/JSObject.h
@@ -1195,48 +1195,16 @@ namespace js {
 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.
  */
--- 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 property "getManifest" of it`,
+    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");
   });