Bug 672893 - Don't #include jscompartment.h in xpconnect. r=cdleary.
authorJason Orendorff <jorendorff@mozilla.com>
Sat, 06 Aug 2011 16:05:25 -0500
changeset 76457 3326454d70f5116055e1f32df8d733524c3ff04a
parent 76456 5b34c14d9f842c1357abe0882cc61ffa8a2de7b5
child 76458 502c33ae0d8115e64f5f661409c371b372debf10
push id1674
push userjorendorff@mozilla.com
push dateFri, 02 Sep 2011 21:53:16 +0000
treeherdermozilla-inbound@7509ecc14e9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscdleary
bugs672893
milestone9.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 672893 - Don't #include jscompartment.h in xpconnect. r=cdleary.
js/jsd/jsd_xpc.cpp
js/src/Makefile.in
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsprvtd.h
js/src/xpconnect/loader/mozJSComponentLoader.cpp
js/src/xpconnect/src/nsXPConnect.cpp
js/src/xpconnect/src/xpcjsruntime.cpp
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcwrappednativescope.cpp
js/src/xpconnect/wrappers/AccessCheck.cpp
js/src/xpconnect/wrappers/AccessCheck.h
js/src/xpconnect/wrappers/CrossOriginWrapper.cpp
js/src/xpconnect/wrappers/WrapperFactory.cpp
js/src/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -55,19 +55,16 @@
 #include "jsdebug.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 
 /* XXX DOM dependency */
 #include "nsIScriptContext.h"
 #include "nsIJSContextStack.h"
 
-/* XXX private JS headers. */
-#include "jscompartment.h"
-
 /*
  * defining CAUTIOUS_SCRIPTHOOK makes jsds disable GC while calling out to the
  * script hook.  This was a hack to avoid some js engine problems that should
  * be fixed now (see Mozilla bug 77636).
  */
 #undef CAUTIOUS_SCRIPTHOOK
 
 #ifdef DEBUG_verbose
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -186,17 +186,16 @@ INSTALLED_HEADERS = \
 		jsdhash.h \
 		jsemit.h \
 		jsfun.h \
 		jsfriendapi.h \
 		jsgc.h \
 		jscell.h \
 		jsgcchunk.h \
 		jsgcstats.h \
-		jscompartment.h \
 		jshash.h \
 		jsinfer.h \
 		jsinferinlines.h \
 		jsinterp.h \
 		jsinttypes.h \
 		jsiter.h \
 		jslock.h \
 		jsobj.h \
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -39,16 +39,17 @@
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 #include "jsfriendapi.h"
 
 #include "jsobjinlines.h"
 
 using namespace js;
+using namespace JS;
 
 JS_FRIEND_API(JSString *)
 JS_GetAnonymousString(JSRuntime *rt)
 {
     JS_ASSERT(rt->state == JSRTS_UP);
     return rt->atomState.anonymousAtom;
 }
 
@@ -107,16 +108,63 @@ JS_NewObjectWithUniqueType(JSContext *cx
 JS_FRIEND_API(uint32)
 JS_ObjectCountDynamicSlots(JSObject *obj)
 {
     if (obj->hasSlotsArray())
         return obj->numDynamicSlots(obj->numSlots());
     return 0;
 }
 
+JS_FRIEND_API(JSPrincipals *)
+JS_GetCompartmentPrincipals(JSCompartment *compartment)
+{
+    return compartment->principals;
+}
+
+JS_FRIEND_API(JSBool)
+JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc)
+{
+    return cx->compartment->wrap(cx, desc);
+}
+
+AutoPreserveCompartment::AutoPreserveCompartment(JSContext *cx
+                                                 JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT)
+  : cx(cx), oldCompartment(cx->compartment)
+{
+    JS_GUARD_OBJECT_NOTIFIER_INIT;
+}
+
+AutoPreserveCompartment::~AutoPreserveCompartment()
+{
+    /* The old compartment may have been destroyed, so we can't use cx->setCompartment. */
+    cx->compartment = oldCompartment;
+}
+
+AutoSwitchCompartment::AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment
+                                             JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT)
+  : cx(cx), oldCompartment(cx->compartment)
+{
+    JS_GUARD_OBJECT_NOTIFIER_INIT;
+    cx->setCompartment(newCompartment);
+}
+
+AutoSwitchCompartment::AutoSwitchCompartment(JSContext *cx, JSObject *target
+                                             JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT)
+  : cx(cx), oldCompartment(cx->compartment)
+{
+    JS_GUARD_OBJECT_NOTIFIER_INIT;
+    cx->setCompartment(target->compartment());
+}
+
+AutoSwitchCompartment::~AutoSwitchCompartment()
+{
+    /* The old compartment may have been destroyed, so we can't use cx->setCompartment. */
+    cx->compartment = oldCompartment;
+}
+
 /*
  * The below code is for temporary telemetry use. It can be removed when
  * sufficient data has been harvested.
  */
 
 extern size_t sE4XObjectsCreated;
 
 JS_FRIEND_API(size_t)
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -88,11 +88,50 @@ typedef struct TypeInferenceMemoryStats
 extern JS_FRIEND_API(void)
 JS_GetTypeInferenceMemoryStats(JSContext *cx, JSCompartment *compartment,
                                TypeInferenceMemoryStats *stats);
 
 extern JS_FRIEND_API(void)
 JS_GetTypeInferenceObjectStats(/*TypeObject*/ void *object,
                                TypeInferenceMemoryStats *stats);
 
+extern JS_FRIEND_API(JSPrincipals *)
+JS_GetCompartmentPrincipals(JSCompartment *compartment);
+
+#ifdef __cplusplus
+
+extern JS_FRIEND_API(JSBool)
+JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc);
+
+#endif
+
 JS_END_EXTERN_C
 
+#ifdef __cplusplus
+
+namespace JS {
+
+class JS_FRIEND_API(AutoPreserveCompartment) {
+  private:
+    JSContext *cx;
+    JSCompartment *oldCompartment;
+  public:
+    AutoPreserveCompartment(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM);
+    ~AutoPreserveCompartment();
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+class JS_FRIEND_API(AutoSwitchCompartment) {
+  private:
+    JSContext *cx;
+    JSCompartment *oldCompartment;
+  public:
+    AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment
+                          JS_GUARD_OBJECT_NOTIFIER_PARAM);
+    AutoSwitchCompartment(JSContext *cx, JSObject *target JS_GUARD_OBJECT_NOTIFIER_PARAM);
+    ~AutoSwitchCompartment();
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+}
+#endif
+
 #endif /* jsfriendapi_h___ */
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -180,16 +180,17 @@ class HashSet;
 
 template <typename K,
           typename V,
           size_t InlineElems>
 class InlineMap;
 
 class PropertyCache;
 struct PropertyCacheEntry;
+struct PropertyDescriptor;
 
 struct Shape;
 struct EmptyShape;
 class Bindings;
 
 class MultiDeclRange;
 class ParseMapPool;
 class DefnOrHeader;
--- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
@@ -69,17 +69,16 @@
 #include "nsString.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIURI.h"
 #include "nsIFileURL.h"
 #include "nsIJARURI.h"
 #include "nsNetUtil.h"
 #include "nsDOMFile.h"
 #include "jsxdrapi.h"
-#include "jscompartment.h"
 #include "jsprf.h"
 // For reporting errors with the console service
 #include "nsIScriptError.h"
 #include "nsIConsoleService.h"
 #include "nsIStorageStream.h"
 #include "nsIStringStream.h"
 #include "prmem.h"
 #if defined(XP_WIN)
@@ -747,18 +746,18 @@ mozJSComponentLoader::GlobalForLocation(
                                         jsval *exception)
 {
     nsresult rv;
 
     JSPrincipals* jsPrincipals = nsnull;
     JSCLContextHelper cx(this);
 
     // preserve caller's compartment
-    js::PreserveCompartment pc(cx);
-    
+    JS::AutoPreserveCompartment pc(cx);
+
     rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals);
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSPrincipalsHolder princHolder(mContext, jsPrincipals);
 
     nsCOMPtr<nsIXPCScriptable> backstagePass;
     rv = mRuntimeService->GetBackstagePass(getter_AddRefs(backstagePass));
     NS_ENSURE_SUCCESS(rv, rv);
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -1058,17 +1058,17 @@ CreateNewCompartment(JSContext *cx, JSCl
         JSPRINCIPALS_DROP(cx, principals);
 
     if(!tempGlobal)
         return false;
 
     *global = tempGlobal;
     *compartment = tempGlobal->compartment();
 
-    js::SwitchToCompartment sc(cx, *compartment);
+    JS::AutoSwitchCompartment sc(cx, *compartment);
     JS_SetCompartmentPrivate(cx, *compartment, priv_holder.forget());
     return true;
 }
 
 nsresult
 xpc_CreateGlobalObject(JSContext *cx, JSClass *clasp,
                        nsIPrincipal *principal, nsISupports *ptr,
                        bool wantXrays, JSObject **global,
@@ -1090,17 +1090,17 @@ xpc_CreateGlobalObject(JSContext *cx, JS
         {
             return UnexpectedFailure(NS_ERROR_FAILURE);
         }
 
         map.Put(&key, *compartment);
     }
     else
     {
-        js::SwitchToCompartment sc(cx, *compartment);
+        JS::AutoSwitchCompartment sc(cx, *compartment);
 
         JSObject *tempGlobal = JS_NewGlobalObject(cx, clasp);
         if(!tempGlobal)
             return UnexpectedFailure(NS_ERROR_FAILURE);
         *global = tempGlobal;
     }
 
     return NS_OK;
@@ -1127,17 +1127,17 @@ xpc_CreateMTGlobalObject(JSContext *cx, 
         {
             return UnexpectedFailure(NS_ERROR_UNEXPECTED);
         }
 
         map.Put(ptr, *compartment);
     }
     else
     {
-        js::SwitchToCompartment sc(cx, *compartment);
+        JS::AutoSwitchCompartment sc(cx, *compartment);
 
         JSObject *tempGlobal = JS_NewGlobalObject(cx, clasp);
         if(!tempGlobal)
             return UnexpectedFailure(NS_ERROR_FAILURE);
         *global = tempGlobal;
     }
 
     return NS_OK;
@@ -2560,17 +2560,17 @@ nsXPConnect::CheckForDebugMode(JSRuntime
             AutoDestroyContext(JSContext *cx) : cx(cx) {}
             ~AutoDestroyContext() { JS_DestroyContext(cx); }
         } adc(cx);
         JSAutoRequest ar(cx);
 
         js::CompartmentVector &vector = rt->compartments;
         for (JSCompartment **p = vector.begin(); p != vector.end(); ++p) {
             JSCompartment *comp = *p;
-            if (!comp->principals) {
+            if (!JS_GetCompartmentPrincipals(comp)) {
                 /* Ignore special compartments (atoms, JSD compartments) */
                 continue;
             }
 
             /* ParticipatesInCycleCollection means "on the main thread" */
             if (xpc::CompartmentParticipatesInCycleCollection(cx, comp)) {
                 if (!JS_SetDebugModeForCompartment(cx, comp, gDesiredDebugMode))
                     goto fail;
--- a/js/src/xpconnect/src/xpcjsruntime.cpp
+++ b/js/src/xpconnect/src/xpcjsruntime.cpp
@@ -100,18 +100,18 @@ WrappedJSDyingJSObjectFinder(JSDHashTabl
     nsXPCWrappedJS* wrapper = ((JSObject2WrappedJSMap::Entry*)hdr)->value;
     NS_ASSERTION(wrapper, "found a null JS wrapper!");
 
     // walk the wrapper chain and find any whose JSObject is to be finalized
     while(wrapper)
     {
         if(wrapper->IsSubjectToFinalization())
         {
-            js::SwitchToCompartment sc(data->cx,
-                                       wrapper->GetJSObjectPreserveColor());
+            JS::AutoSwitchCompartment sc(data->cx,
+                                         wrapper->GetJSObjectPreserveColor());
             if(JS_IsAboutToBeFinalized(data->cx,
                                        wrapper->GetJSObjectPreserveColor()))
                 data->array->AppendElement(wrapper);
         }
         wrapper = wrapper->GetNextWrapper();
     }
     return JS_DHASH_NEXT;
 }
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -53,18 +53,18 @@
 #include "xpcpublic.h"
 #include "jsapi.h"
 #include "jsdhash.h"
 #include "jsprf.h"
 #include "prprf.h"
 #include "jsinterp.h"
 #include "jscntxt.h"
 #include "jsdbgapi.h"
+#include "jsfriendapi.h"
 #include "jsgc.h"
-#include "jscompartment.h"
 #include "nscore.h"
 #include "nsXPCOM.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCycleCollector.h"
 #include "nsDebug.h"
 #include "nsISupports.h"
 #include "nsIServiceManager.h"
--- a/js/src/xpconnect/src/xpcwrappednativescope.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativescope.cpp
@@ -437,17 +437,17 @@ XPCWrappedNativeScope::FinishedMarkPhase
 
     XPCWrappedNativeScope* prev = nsnull;
     XPCWrappedNativeScope* cur = gScopes;
 
     while(cur)
     {
         XPCWrappedNativeScope* next = cur->mNext;
 
-        js::SwitchToCompartment sc(cx, cur->mGlobalJSObject);
+        JS::AutoSwitchCompartment sc(cx, cur->mGlobalJSObject);
 
         if(cur->mGlobalJSObject &&
            JS_IsAboutToBeFinalized(cx, cur->mGlobalJSObject))
         {
             cur->mGlobalJSObject = nsnull;
             cur->mScriptObjectPrincipal = nsnull;
             // Move this scope from the live list to the dying list.
             if(prev)
--- a/js/src/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/src/xpconnect/wrappers/AccessCheck.cpp
@@ -48,20 +48,21 @@
 #include "XrayWrapper.h"
 #include "FilteringWrapper.h"
 #include "WrapperFactory.h"
 
 #include "jsfriendapi.h"
 
 namespace xpc {
 
-static nsIPrincipal *
+nsIPrincipal *
 GetCompartmentPrincipal(JSCompartment *compartment)
 {
-    return compartment->principals ? static_cast<nsJSPrincipals *>(compartment->principals)->nsIPrincipalPtr : 0;
+    JSPrincipals *prin = JS_GetCompartmentPrincipals(compartment);
+    return prin ? static_cast<nsJSPrincipals *>(prin)->nsIPrincipalPtr : nsnull;
 }
 
 bool
 AccessCheck::isSameOrigin(JSCompartment *a, JSCompartment *b)
 {
     nsIPrincipal *aprin = GetCompartmentPrincipal(a);
     nsIPrincipal *bprin = GetCompartmentPrincipal(b);
 
--- a/js/src/xpconnect/wrappers/AccessCheck.h
+++ b/js/src/xpconnect/wrappers/AccessCheck.h
@@ -39,16 +39,19 @@
 
 #include "jsapi.h"
 #include "jswrapper.h"
 
 class nsIPrincipal;
 
 namespace xpc {
 
+nsIPrincipal *
+GetCompartmentPrincipal(JSCompartment *compartment);
+
 class AccessCheck {
   public:
     static bool isSameOrigin(JSCompartment *a, JSCompartment *b);
     static bool isChrome(JSCompartment *compartment);
     static nsIPrincipal *getPrincipal(JSCompartment *compartment);
     static bool isCrossOriginAccessPermitted(JSContext *cx, JSObject *obj, jsid id,
                                              JSWrapper::Action act);
     static bool isSystemOnlyAccessPermitted(JSContext *cx);
--- a/js/src/xpconnect/wrappers/CrossOriginWrapper.cpp
+++ b/js/src/xpconnect/wrappers/CrossOriginWrapper.cpp
@@ -37,16 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsJSPrincipals.h"
 
 #include "XPCWrapper.h"
 
 #include "CrossOriginWrapper.h"
+#include "AccessCheck.h"
 #include "WrapperFactory.h"
 
 namespace xpc {
 
 NoWaiverWrapper::NoWaiverWrapper(uintN flags) : JSCrossCompartmentWrapper(flags)
 {
 }
 
@@ -57,22 +58,16 @@ NoWaiverWrapper::~NoWaiverWrapper()
 CrossOriginWrapper::CrossOriginWrapper(uintN flags) : NoWaiverWrapper(flags)
 {
 }
 
 CrossOriginWrapper::~CrossOriginWrapper()
 {
 }
 
-static nsIPrincipal *
-GetCompartmentPrincipal(JSCompartment *compartment)
-{
-    return static_cast<nsJSPrincipals *>(compartment->principals)->nsIPrincipalPtr;
-}
-
 bool
 CrossOriginWrapper::getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id,
                                           bool set, js::PropertyDescriptor *desc)
 {
     return JSCrossCompartmentWrapper::getPropertyDescriptor(cx, wrapper, id, set, desc) &&
            WrapperFactory::WaiveXrayAndWrap(cx, js::Jsvalify(&desc->value));
 }
 
--- a/js/src/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/src/xpconnect/wrappers/WrapperFactory.cpp
@@ -260,17 +260,18 @@ WrapperFactory::Rewrap(JSContext *cx, JS
                  "wrapped object passed to rewrap");
     NS_ASSERTION(JS_GET_CLASS(cx, obj) != &XrayUtils::HolderClass, "trying to wrap a holder");
 
     JSCompartment *origin = obj->compartment();
     JSCompartment *target = cx->compartment;
     JSObject *xrayHolder = nsnull;
 
     JSWrapper *wrapper;
-    CompartmentPrivate *targetdata = static_cast<CompartmentPrivate *>(target->data);
+    CompartmentPrivate *targetdata =
+        static_cast<CompartmentPrivate *>(JS_GetCompartmentPrivate(cx, target));
     if (AccessCheck::isChrome(target)) {
         if (AccessCheck::isChrome(origin)) {
             wrapper = &JSCrossCompartmentWrapper::singleton;
         } else {
             bool isSystem;
             {
                 JSAutoEnterCompartment ac;
                 if (!ac.enter(cx, obj))
--- a/js/src/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/src/xpconnect/wrappers/XrayWrapper.cpp
@@ -551,17 +551,17 @@ XrayWrapper<Base>::getPropertyDescriptor
             if (!JS_GetPropertyDescriptorById(cx, wnObject, id,
                                               (set ? JSRESOLVE_ASSIGNING : 0) | JSRESOLVE_QUALIFIED,
                                               desc))
                 return false;
         }
 
         if (desc->obj)
             desc->obj = wrapper;
-        return cx->compartment->wrap(cx, desc_in);
+        return JS_WrapPropertyDescriptor(cx, desc_in);
     }
 
     if (!this->resolveOwnProperty(cx, wrapper, id, set, desc_in))
         return false;
 
     if (desc->obj)
         return true;
 
@@ -622,17 +622,17 @@ XrayWrapper<Base>::getOwnPropertyDescrip
             if (!JS_GetPropertyDescriptorById(cx, wnObject, id,
                                               (set ? JSRESOLVE_ASSIGNING : 0) | JSRESOLVE_QUALIFIED,
                                               desc)) {
                 return false;
             }
         }
 
         desc->obj = (desc->obj == wnObject) ? wrapper : nsnull;
-        return cx->compartment->wrap(cx, desc_in);
+        return JS_WrapPropertyDescriptor(cx, desc_in);
     }
 
     return this->resolveOwnProperty(cx, wrapper, id, set, desc_in);
 }
 
 template <typename Base>
 bool
 XrayWrapper<Base>::defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
@@ -644,17 +644,17 @@ XrayWrapper<Base>::defineProperty(JSCont
     // Redirect access straight to the wrapper if we should be transparent.
     if (Transparent(cx, wrapper)) {
         JSObject *wnObject = GetWrappedNativeObjectFromHolder(holder);
 
         JSAutoEnterCompartment ac;
         if (!ac.enter(cx, wnObject))
             return false;
 
-        if (!cx->compartment->wrap(cx, desc))
+        if (!JS_WrapPropertyDescriptor(cx, desc))
             return false;
 
         return JS_DefinePropertyById(cx, wnObject, id, jsdesc->value, jsdesc->getter, jsdesc->setter,
                                      jsdesc->attrs);
     }
 
     PropertyDescriptor existing_desc;
     if (!getOwnPropertyDescriptor(cx, wrapper, id, true, &existing_desc))