Bug 672893 - Don't #include jscompartment.h in xpconnect. r=cdleary.
☠☠ backed out by 53af4a6b8965 ☠ ☠
authorJason Orendorff <jorendorff@mozilla.com>
Sat, 06 Aug 2011 16:05:25 -0500
changeset 73970 66845f1a3aadc506b7b8d9a54d305b2e53db21c6
parent 73969 f9247cadf32b85830207b6e292b63bdf7a24534d
child 73971 53af4a6b8965f42c3808ac2fabca165804f0f158
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewerscdleary
bugs672893
milestone8.0a1
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/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
@@ -215,17 +215,16 @@ INSTALLED_HEADERS = \
 		jsdhash.h \
 		jsemit.h \
 		jsfun.h \
 		jsfriendapi.h \
 		jsgc.h \
 		jscell.h \
 		jsgcchunk.h \
 		jsgcstats.h \
-		jscompartment.h \
 		jshash.h \
 		jsinterp.h \
 		jsinttypes.h \
 		jsiter.h \
 		jslock.h \
 		jsobj.h \
 		json.h \
 		jsopcode.tbl \
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -37,16 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "jscntxt.h"
 #include "jscompartment.h"
 #include "jsfriendapi.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;
 }
 
@@ -76,16 +77,65 @@ JS_UnwrapObject(JSObject *obj)
 }
 
 JS_FRIEND_API(JSObject *)
 JS_GetFrameScopeChainRaw(JSStackFrame *fp)
 {
     return &Valueify(fp)->scopeChain();
 }
 
+JS_PUBLIC_API(JSPrincipals *)
+JS_GetCompartmentPrincipals(JSCompartment *compartment)
+{
+    return compartment->principals;
+}
+
+JS_PUBLIC_API(void)
+JS_ClearDebugModeForCompartment(JSCompartment *compartment)
+{
+    compartment->debugMode = false;
+}
+
+JS_PUBLIC_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)
+{
+}
+
+AutoPreserveCompartment::~AutoPreserveCompartment()
+{
+    cx->compartment = oldCompartment;
+}
+
+AutoSwitchCompartment::AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment
+                                             JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT)
+  : cx(cx), oldCompartment(cx->compartment)
+{
+    cx->compartment = newCompartment;
+}
+
+AutoSwitchCompartment::AutoSwitchCompartment(JSContext *cx, JSObject *target
+                                             JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT)
+  : cx(cx), oldCompartment(cx->compartment)
+{
+    cx->compartment = target->compartment();
+}
+
+AutoSwitchCompartment::~AutoSwitchCompartment()
+{
+    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
@@ -61,11 +61,53 @@ extern JS_FRIEND_API(size_t)
 JS_GetE4XObjectsCreated(JSContext *cx);
 
 extern JS_FRIEND_API(size_t)
 JS_SetProtoCalled(JSContext *cx);
 
 extern JS_FRIEND_API(size_t)
 JS_GetCustomIteratorCount(JSContext *cx);
 
+extern JS_PUBLIC_API(JSPrincipals *)
+JS_GetCompartmentPrincipals(JSCompartment *compartment);
+
+extern JS_PUBLIC_API(void)
+JS_ClearDebugModeForCompartment(JSCompartment *comp);
+
+#ifdef __cplusplus
+
+extern JS_PUBLIC_API(JSBool)
+JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc);
+
+#endif
+
 JS_END_EXTERN_C
 
+#ifdef __cplusplus
+
+namespace JS {
+
+class JS_PUBLIC_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_PUBLIC_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/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)
@@ -758,18 +757,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
@@ -1054,17 +1054,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,
@@ -1086,17 +1086,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;
@@ -1123,17 +1123,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;
@@ -2554,34 +2554,34 @@ 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 (gDesiredDebugMode) {
                     if (!JS_SetDebugModeForCompartment(cx, comp, JS_TRUE))
                         goto fail;
                 } else {
                     /*
                      * Debugging may be turned off with live scripts, so just
                      * mark future scripts to be compiled into non-debug mode.
                      * Existing scripts will continue to call JSD callbacks,
                      * which will have no effect.
                      */
-                    comp->debugMode = JS_FALSE;
+                    JS_ClearDebugModeForCompartment(comp);
                 }
             }
         }
     }
 
     if (gDesiredDebugMode) {
         rv = jsds->ActivateDebugger(rt);
     }
--- 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))