Bug 792036 - Factor out glue code to get the JS Components object for a scope. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Mon, 24 Sep 2012 14:46:27 +0200
changeset 108012 65e5f5c48ffcb1b2b7f191c16eec3276bd8e554d
parent 108011 9f0be04eee5fb57e4ab7334e00d0006086f3dbcc
child 108013 1460d44ec8def5ee7d1d4ebb9534dcce652a0966
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersmrbkap
bugs792036
milestone18.0a1
Bug 792036 - Factor out glue code to get the JS Components object for a scope. r=mrbkap
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -4759,51 +4759,28 @@ nsXPCComponents::SetProperty(nsIXPConnec
 }
 
 // static
 JSBool
 nsXPCComponents::AttachComponentsObject(XPCCallContext& ccx,
                                         XPCWrappedNativeScope* aScope,
                                         JSObject* aTarget)
 {
+    JSObject *components = aScope->GetComponentsJSObject(ccx);
+    if (!components)
+        return false;
+
     JSObject *global = aScope->GetGlobalJSObject();
     MOZ_ASSERT(js::IsObjectInContextCompartment(global, ccx));
     if (!aTarget)
         aTarget = global;
 
-    nsXPCComponents* components = aScope->GetComponents();
-    if (!components) {
-        components = new nsXPCComponents(aScope);
-        if (!components)
-            return false;
-        aScope->SetComponents(components);
-    }
-
-    nsCOMPtr<nsIXPCComponents> cholder(components);
-
-    AutoMarkingNativeInterfacePtr iface(ccx);
-    iface = XPCNativeInterface::GetNewOrUsed(ccx, &NS_GET_IID(nsIXPCComponents));
-
-    if (!iface)
-        return false;
-
-    nsCOMPtr<XPCWrappedNative> wrapper;
-    xpcObjectHelper helper(cholder);
-    XPCWrappedNative::GetNewOrUsed(ccx, helper, aScope, iface, getter_AddRefs(wrapper));
-    if (!wrapper)
-        return false;
-
-    // The call to wrap() here is necessary even though the object is same-
-    // compartment, because it applies our security wrapper.
-    js::Value v = ObjectValue(*wrapper->GetFlatJSObject());
-    if (!JS_WrapValue(ccx, &v))
-        return false;
-
     jsid id = ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_COMPONENTS);
-    return JS_DefinePropertyById(ccx, aTarget, id, v, nullptr, nullptr,
+    return JS_DefinePropertyById(ccx, aTarget, id, js::ObjectValue(*components),
+                                 nullptr, nullptr,
                                  JSPROP_PERMANENT | JSPROP_READONLY);
 }
 
 /* void lookupMethod (); */
 NS_IMETHODIMP
 nsXPCComponents::LookupMethod(const JS::Value& object,
                               const JS::Value& name,
                               JSContext *cx,
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -148,26 +148,40 @@ XPCWrappedNativeScope::IsDyingScope(XPCW
 {
     for (XPCWrappedNativeScope *cur = gDyingScopes; cur; cur = cur->mNext) {
         if (scope == cur)
             return true;
     }
     return false;
 }
 
-void
-XPCWrappedNativeScope::SetComponents(nsXPCComponents* aComponents)
+JSObject*
+XPCWrappedNativeScope::GetComponentsJSObject(XPCCallContext& ccx)
 {
-    mComponents = aComponents;
-}
+    if (!mComponents)
+        mComponents = new nsXPCComponents(this);
+
+    AutoMarkingNativeInterfacePtr iface(ccx);
+    iface = XPCNativeInterface::GetNewOrUsed(ccx, &NS_GET_IID(nsIXPCComponents));
+    if (!iface)
+        return nullptr;
 
-nsXPCComponents*
-XPCWrappedNativeScope::GetComponents()
-{
-    return mComponents;
+    nsCOMPtr<nsIXPCComponents> cholder(mComponents);
+    xpcObjectHelper helper(cholder);
+    nsCOMPtr<XPCWrappedNative> wrapper;
+    XPCWrappedNative::GetNewOrUsed(ccx, helper, this, iface, getter_AddRefs(wrapper));
+    if (!wrapper)
+        return nullptr;
+
+    // The call to wrap() here is necessary even though the object is same-
+    // compartment, because it applies our security wrapper.
+    JSObject *obj = wrapper->GetFlatJSObject();
+    if (!JS_WrapObject(ccx, &obj))
+        return nullptr;
+    return obj;
 }
 
 // Dummy JS class to let wrappers w/o an xpc prototype share
 // scopes. By doing this we avoid allocating a new scope for every
 // wrapper on creation of the wrapper, and most wrappers won't need
 // their own scope at all for the lifetime of the wrapper.
 // WRAPPER_SLOTS is key here (even though there's never anything
 // in the private data slot in these prototypes), as the number of
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1581,16 +1581,20 @@ public:
     GetWrappedNativeProtoMap(JSBool aMainThreadOnly) const
         {return aMainThreadOnly ?
                 mMainThreadWrappedNativeProtoMap :
                 mWrappedNativeProtoMap;}
 
     nsXPCComponents*
     GetComponents() const {return mComponents;}
 
+    // Returns the JS object reflection of the Components object.
+    JSObject*
+    GetComponentsJSObject(XPCCallContext& ccx);
+
     JSObject*
     GetGlobalJSObject() const
         {return xpc_UnmarkGrayObject(mGlobalJSObject);}
 
     JSObject*
     GetGlobalJSObjectPreserveColor() const {return mGlobalJSObject;}
 
     JSObject*
@@ -1677,18 +1681,16 @@ public:
     SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf);
 
     JSBool
     IsValid() const {return mRuntime != nullptr;}
 
     static JSBool
     IsDyingScope(XPCWrappedNativeScope *scope);
 
-    void SetComponents(nsXPCComponents* aComponents);
-    nsXPCComponents *GetComponents();
     void SetGlobal(XPCCallContext& ccx, JSObject* aGlobal, nsISupports* aNative);
 
     static void InitStatics() { gScopes = nullptr; gDyingScopes = nullptr; }
 
     XPCContext *GetContext() { return mContext; }
     void ClearContext() { mContext = nullptr; }
 
     nsDataHashtable<nsDepCharHashKey, JSObject*>& GetCachedDOMPrototypes()