Bug 1481793 part 4 - Use the CCW's realm for Debugger.Object referents. r=jimb
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 09 Aug 2018 13:34:40 +0200
changeset 485927 f95e8da173618fddb155faf7df34576857027b14
parent 485926 b1bfefd4495f785edec66dcec131f498f234ba95
child 485928 4c826b3937d8a1ca06658d4a9403bbb7509345f8
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb
bugs1481793
milestone63.0a1
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
Bug 1481793 part 4 - Use the CCW's realm for Debugger.Object referents. r=jimb
js/src/vm/Debugger.cpp
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2279,18 +2279,20 @@ Debugger::appendAllocationSite(JSContext
 {
     MOZ_ASSERT(trackingAllocationSites && enabled);
 
     AutoRealm ar(cx, object);
     RootedObject wrappedFrame(cx, frame);
     if (!cx->compartment()->wrap(cx, &wrappedFrame))
         return false;
 
+    // Try to get the constructor name from the ObjectGroup's TypeNewScript.
+    // This is only relevant for native objects.
     RootedAtom ctorName(cx);
-    {
+    if (obj->is<NativeObject>()) {
         AutoRealm ar(cx, obj);
         if (!JSObject::constructorDisplayAtom(cx, obj, &ctorName))
             return false;
     }
     if (ctorName)
         cx->markAtom(ctorName);
 
     auto className = obj->getClass()->name;
@@ -9765,16 +9767,25 @@ DebuggerObject::applyMethod(JSContext* c
 
         if (!args.growBy(argc) || !GetElements(cx, argsobj, argc, args.begin()))
             return false;
     }
 
     return object->call(cx, object, thisv, args, callArgs.rval());
 }
 
+static void
+EnterDebuggeeObjectRealm(JSContext* cx, Maybe<AutoRealm>& ar, JSObject* referent)
+{
+    // |referent| may be a cross-compartment wrapper and CCWs normally
+    // shouldn't be used with AutoRealm, but here we use an arbitrary realm for
+    // now because we don't really have another option.
+    ar.emplace(cx, referent->maybeCCWRealm()->maybeGlobal());
+}
+
 /* static */ bool
 DebuggerObject::asEnvironmentMethod(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "asEnvironment", args, dbg, referent);
     if (!RequireGlobalObject(cx, args.thisv(), referent))
         return false;
 
     Rooted<Env*> env(cx);
@@ -10094,17 +10105,18 @@ DebuggerObject::isPromise() const
 /* static */ bool
 DebuggerObject::getClassName(JSContext* cx, HandleDebuggerObject object,
                              MutableHandleString result)
 {
     RootedObject referent(cx, object->referent());
 
     const char* className;
     {
-        AutoRealm ar(cx, referent);
+        Maybe<AutoRealm> ar;
+        EnterDebuggeeObjectRealm(cx, ar, referent);
         className = GetObjectClassName(cx, referent);
     }
 
     JSAtom* str = Atomize(cx, className, strlen(className));
     if (!str)
         return false;
 
     result.set(str);
@@ -10391,55 +10403,57 @@ DebuggerObject::getPromiseReason(JSConte
 }
 
 /* static */ bool
 DebuggerObject::isExtensible(JSContext* cx, HandleDebuggerObject object, bool& result)
 {
     RootedObject referent(cx, object->referent());
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
+
     ErrorCopier ec(ar);
     return IsExtensible(cx, referent, &result);
 }
 
 /* static */ bool
 DebuggerObject::isSealed(JSContext* cx, HandleDebuggerObject object, bool& result)
 {
     RootedObject referent(cx, object->referent());
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
 
     ErrorCopier ec(ar);
     return TestIntegrityLevel(cx, referent, IntegrityLevel::Sealed, &result);
 }
 
 /* static */ bool
 DebuggerObject::isFrozen(JSContext* cx, HandleDebuggerObject object, bool& result)
 {
     RootedObject referent(cx, object->referent());
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
 
     ErrorCopier ec(ar);
     return TestIntegrityLevel(cx, referent, IntegrityLevel::Frozen, &result);
 }
 
 /* static */ bool
 DebuggerObject::getPrototypeOf(JSContext* cx, HandleDebuggerObject object,
                                MutableHandleDebuggerObject result)
 {
     RootedObject referent(cx, object->referent());
     Debugger* dbg = object->owner();
 
     RootedObject proto(cx);
     {
-        AutoRealm ar(cx, referent);
+        Maybe<AutoRealm> ar;
+        EnterDebuggeeObjectRealm(cx, ar, referent);
         if (!GetPrototype(cx, referent, &proto))
             return false;
     }
 
     if (!proto) {
         result.set(nullptr);
         return true;
     }
@@ -10451,17 +10465,17 @@ DebuggerObject::getPrototypeOf(JSContext
 DebuggerObject::getOwnPropertyNames(JSContext* cx, HandleDebuggerObject object,
                                     MutableHandle<IdVector> result)
 {
     RootedObject referent(cx, object->referent());
 
     AutoIdVector ids(cx);
     {
         Maybe<AutoRealm> ar;
-        ar.emplace(cx, referent);
+        EnterDebuggeeObjectRealm(cx, ar, referent);
 
         ErrorCopier ec(ar);
         if (!GetPropertyKeys(cx, referent, JSITER_OWNONLY | JSITER_HIDDEN, &ids))
             return false;
     }
 
     for (size_t i = 0; i < ids.length(); i++)
         cx->markId(ids[i]);
@@ -10473,17 +10487,17 @@ DebuggerObject::getOwnPropertyNames(JSCo
 DebuggerObject::getOwnPropertySymbols(JSContext* cx, HandleDebuggerObject object,
                                       MutableHandle<IdVector> result)
 {
     RootedObject referent(cx, object->referent());
 
     AutoIdVector ids(cx);
     {
         Maybe<AutoRealm> ar;
-        ar.emplace(cx, referent);
+        EnterDebuggeeObjectRealm(cx, ar, referent);
 
         ErrorCopier ec(ar);
         if (!GetPropertyKeys(cx, referent,
                              JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS | JSITER_SYMBOLSONLY,
                              &ids))
             return false;
     }
 
@@ -10498,17 +10512,18 @@ DebuggerObject::getOwnPropertyDescriptor
                                          HandleId id, MutableHandle<PropertyDescriptor> desc)
 {
     RootedObject referent(cx, object->referent());
     Debugger* dbg = object->owner();
 
     // Bug: This can cause the debuggee to run!
     {
         Maybe<AutoRealm> ar;
-        ar.emplace(cx, referent);
+        EnterDebuggeeObjectRealm(cx, ar, referent);
+
         cx->markId(id);
 
         ErrorCopier ec(ar);
         if (!GetOwnPropertyDescriptor(cx, referent, id, desc))
             return false;
     }
 
     if (desc.object()) {
@@ -10537,41 +10552,41 @@ DebuggerObject::getOwnPropertyDescriptor
 }
 
 /* static */ bool
 DebuggerObject::preventExtensions(JSContext* cx, HandleDebuggerObject object)
 {
     RootedObject referent(cx, object->referent());
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
 
     ErrorCopier ec(ar);
     return PreventExtensions(cx, referent);
 }
 
 /* static */ bool
 DebuggerObject::seal(JSContext* cx, HandleDebuggerObject object)
 {
     RootedObject referent(cx, object->referent());
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
 
     ErrorCopier ec(ar);
     return SetIntegrityLevel(cx, referent, IntegrityLevel::Sealed);
 }
 
 /* static */ bool
 DebuggerObject::freeze(JSContext* cx, HandleDebuggerObject object)
 {
     RootedObject referent(cx, object->referent());
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
 
     ErrorCopier ec(ar);
     return SetIntegrityLevel(cx, referent, IntegrityLevel::Frozen);
 }
 
 /* static */ bool
 DebuggerObject::defineProperty(JSContext* cx, HandleDebuggerObject object, HandleId id,
                                Handle<PropertyDescriptor> desc_)
@@ -10580,17 +10595,18 @@ DebuggerObject::defineProperty(JSContext
     Debugger* dbg = object->owner();
 
     Rooted<PropertyDescriptor> desc(cx, desc_);
     if (!dbg->unwrapPropertyDescriptor(cx, referent, &desc))
         return false;
     JS_TRY_OR_RETURN_FALSE(cx, CheckPropertyDescriptorAccessors(cx, desc));
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
+
     if (!cx->compartment()->wrap(cx, &desc))
         return false;
     cx->markId(id);
 
     ErrorCopier ec(ar);
     if (!DefineProperty(cx, referent, id, desc))
         return false;
 
@@ -10610,17 +10626,18 @@ DebuggerObject::defineProperties(JSConte
         return false;
     for (size_t i = 0; i < descs.length(); i++) {
         if (!dbg->unwrapPropertyDescriptor(cx, referent, descs[i]))
             return false;
         JS_TRY_OR_RETURN_FALSE(cx, CheckPropertyDescriptorAccessors(cx, descs[i]));
     }
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
+
     for (size_t i = 0; i < descs.length(); i++) {
         if (!cx->compartment()->wrap(cx, descs[i]))
             return false;
         cx->markId(ids[i]);
     }
 
     ErrorCopier ec(ar);
     for (size_t i = 0; i < descs.length(); i++) {
@@ -10633,17 +10650,17 @@ DebuggerObject::defineProperties(JSConte
 
 /* static */ bool
 DebuggerObject::deleteProperty(JSContext* cx, HandleDebuggerObject object, HandleId id,
                                ObjectOpResult& result)
 {
     RootedObject referent(cx, object->referent());
 
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
 
     cx->markId(id);
 
     ErrorCopier ec(ar);
     return DeleteProperty(cx, referent, id, result);
 }
 
 /* static */ bool
@@ -10673,17 +10690,17 @@ DebuggerObject::call(JSContext* cx, Hand
         if (!dbg->unwrapDebuggeeValue(cx, args2[i]))
             return false;
     }
 
     // Enter the debuggee compartment and rewrap all input value for that
     // compartment. (Rewrapping always takes place in the destination
     // compartment.)
     Maybe<AutoRealm> ar;
-    ar.emplace(cx, referent);
+    EnterDebuggeeObjectRealm(cx, ar, referent);
     if (!cx->compartment()->wrap(cx, &calleev) || !cx->compartment()->wrap(cx, &thisv))
         return false;
     for (unsigned i = 0; i < args2.length(); ++i) {
         if (!cx->compartment()->wrap(cx, args2[i]))
             return false;
     }
 
     // Call the function. Use receiveCompletionValue to return to the debugger
@@ -10766,17 +10783,18 @@ DebuggerObject::makeDebuggeeValue(JSCont
 
     RootedValue value(cx, value_);
 
     // Non-objects are already debuggee values.
     if (value.isObject()) {
         // Enter this Debugger.Object's referent's compartment, and wrap the
         // argument as appropriate for references from there.
         {
-            AutoRealm ar(cx, referent);
+            Maybe<AutoRealm> ar;
+            EnterDebuggeeObjectRealm(cx, ar, referent);
             if (!cx->compartment()->wrap(cx, &value))
                 return false;
         }
 
         // Back in the debugger's compartment, produce a new Debugger.Object
         // instance referring to the wrapped argument.
         if (!dbg->wrapDebuggeeValue(cx, &value))
             return false;