Bug 792036 - Refactor AttachComponentsObject API to allow an explicit target. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Mon, 24 Sep 2012 14:46:27 +0200
changeset 108011 9f0be04eee5fb57e4ab7334e00d0006086f3dbcc
parent 108010 6a18b979c82cde17705497467a3dfd456f34cc6d
child 108012 65e5f5c48ffcb1b2b7f191c16eec3276bd8e554d
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersmrbkap
bugs792036
milestone18.0a1
Bug 792036 - Refactor AttachComponentsObject API to allow an explicit target. r=mrbkap The aGlobal API is currently unnecessary, since it should always be equal to the global obtained from the scope. But we'll want to manually specify the target object in subsequent patches, so make it an optional argument that's currently never passed.
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3322,17 +3322,17 @@ xpc_CreateSandboxObject(JSContext *cx, j
           JSAutoCompartment ac(ccx, sandbox);
           XPCWrappedNativeScope* scope =
               XPCWrappedNativeScope::GetNewOrUsed(ccx, sandbox);
 
           if (!scope)
               return NS_ERROR_XPC_UNEXPECTED;
 
           if (options.wantComponents &&
-              !nsXPCComponents::AttachComponentsObject(ccx, scope, sandbox))
+              !nsXPCComponents::AttachComponentsObject(ccx, scope))
               return NS_ERROR_XPC_UNEXPECTED;
 
           if (!XPCNativeWrapper::AttachNewConstructorObject(ccx, sandbox))
               return NS_ERROR_XPC_UNEXPECTED;
         }
 
         if (!JS_DefineFunctions(cx, sandbox, SandboxFunctions))
             return NS_ERROR_XPC_UNEXPECTED;
@@ -4757,20 +4757,22 @@ nsXPCComponents::SetProperty(nsIXPConnec
 
     return NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN;
 }
 
 // static
 JSBool
 nsXPCComponents::AttachComponentsObject(XPCCallContext& ccx,
                                         XPCWrappedNativeScope* aScope,
-                                        JSObject* aGlobal)
-{
-    if (!aGlobal)
-        return false;
+                                        JSObject* aTarget)
+{
+    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);
     }
@@ -4791,17 +4793,17 @@ nsXPCComponents::AttachComponentsObject(
 
     // 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, aGlobal, id, v, nullptr, nullptr,
+    return JS_DefinePropertyById(ccx, aTarget, id, v, 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/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -985,17 +985,17 @@ nsXPConnect::InitClasses(JSContext * aJS
     XPCWrappedNativeScope* scope =
         XPCWrappedNativeScope::GetNewOrUsed(ccx, aGlobalJSObj);
 
     if (!scope)
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     scope->RemoveWrappedNativeProtos();
 
-    if (!nsXPCComponents::AttachComponentsObject(ccx, scope, aGlobalJSObj))
+    if (!nsXPCComponents::AttachComponentsObject(ccx, scope))
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     if (!XPCNativeWrapper::AttachNewConstructorObject(ccx, aGlobalJSObj))
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     return NS_OK;
 }
 
@@ -1167,17 +1167,17 @@ nsXPConnect::InitClassesWithNewWrappedGl
 
     // Grab a copy of the global and enter its compartment.
     JSObject *global = wrappedGlobal->GetFlatJSObject();
     MOZ_ASSERT(!js::GetObjectParent(global));
     JSAutoCompartment ac(ccx, global);
 
     if (!(aFlags & nsIXPConnect::OMIT_COMPONENTS_OBJECT)) {
         // XPCCallContext gives us an active request needed to save/restore.
-        if (!nsXPCComponents::AttachComponentsObject(ccx, wrappedGlobal->GetScope(), global))
+        if (!nsXPCComponents::AttachComponentsObject(ccx, wrappedGlobal->GetScope()))
             return UnexpectedFailure(NS_ERROR_FAILURE);
 
         if (!XPCNativeWrapper::AttachNewConstructorObject(ccx, global))
             return UnexpectedFailure(NS_ERROR_FAILURE);
     }
 
     // Stuff coming through this path always ends up as a DOM global.
     // XXX Someone who knows why we can assert this should re-check
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3742,20 +3742,23 @@ class nsXPCComponents : public nsIXPCCom
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
     NS_DECL_NSISECURITYCHECKEDCOMPONENT
 
 public:
+    // The target is the object upon which |Components| will be defined. If
+    // aTarget is left null, a default object will be computed. This is usually
+    // the right thing to do.
     static JSBool
     AttachComponentsObject(XPCCallContext& ccx,
                            XPCWrappedNativeScope* aScope,
-                           JSObject* aGlobal);
+                           JSObject* aTarget = NULL);
 
     void SystemIsBeingShutDown() {ClearMembers();}
 
     virtual ~nsXPCComponents();
 
 private:
     nsXPCComponents(XPCWrappedNativeScope* aScope);
     void ClearMembers();