Bug 887334 - Miscellaneous JSAutoCompartments. r=luke
☠☠ backed out by b3d0c2498b42 ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>
Fri, 26 Jul 2013 18:56:56 -0700
changeset 148102 af1c512d29787e5bfaaf624ad7e82aaaf7b147cc
parent 148101 35b6d437eb110a9d6f3d7d851adbd8e62f31fcab
child 148103 ff3db04a7caa15a4170955f8c66ee2832fa4606e
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs887334
milestone24.0a2
Bug 887334 - Miscellaneous JSAutoCompartments. r=luke
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
ipc/testshell/TestShellParent.cpp
js/src/shell/js.cpp
netwerk/base/src/ProxyAutoConfig.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2067,16 +2067,18 @@ nsGlobalWindow::CreateOuterObject(nsGlob
   js::SetProxyExtra(outer, 0, js::PrivateValue(ToSupports(this)));
 
   return SetOuterObject(cx, outer);
 }
 
 nsresult
 nsGlobalWindow::SetOuterObject(JSContext* aCx, JS::Handle<JSObject*> aOuterObject)
 {
+  JSAutoCompartment ac(aCx, aOuterObject);
+
   // Force our context's global object to be the outer.
   // NB: JS_SetGlobalObject sets aCx->compartment.
   JS_SetGlobalObject(aCx, aOuterObject);
 
   // Set up the prototype for the outer object.
   JSObject* inner = JS_GetParent(aOuterObject);
   JS::Rooted<JSObject*> proto(aCx);
   if (!JS_GetPrototype(aCx, inner, proto.address())) {
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1328,16 +1328,17 @@ nsJSContext::CompileScript(const PRUnich
   PROFILER_LABEL_PRINTF("JS", "Compile Script", "%s", aURL ? aURL : "");
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   NS_ENSURE_ARG_POINTER(aPrincipal);
 
   AutoPushJSContext cx(mContext);
   JSAutoRequest ar(cx);
   JS::Rooted<JSObject*> scopeObject(mContext, GetNativeGlobal());
+  JSAutoCompartment ac(cx, scopeObject);
   xpc_UnmarkGrayObject(scopeObject);
 
   bool ok = false;
 
   nsresult rv = sSecurityManager->CanExecuteScripts(cx, aPrincipal, &ok);
   if (NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
@@ -2339,17 +2340,20 @@ bool
 nsJSContext::IsContextInitialized()
 {
   return mIsInitialized;
 }
 
 void
 nsJSContext::ScriptEvaluated(bool aTerminated)
 {
-  JS_MaybeGC(mContext);
+  if (GetNativeGlobal()) {
+    JSAutoCompartment ac(mContext, GetNativeGlobal());
+    JS_MaybeGC(mContext);
+  }
 
   if (aTerminated) {
     mOperationCallbackTime = 0;
     mModalStateTime = 0;
     mActive = true;
   }
 }
 
--- a/ipc/testshell/TestShellParent.cpp
+++ b/ipc/testshell/TestShellParent.cpp
@@ -86,21 +86,19 @@ TestShellCommandParent::SetCallback(JSCo
 }
 
 JSBool
 TestShellCommandParent::RunCallback(const nsString& aResponse)
 {
   NS_ENSURE_TRUE(*mCallback.ToJSValPtr() != JSVAL_NULL && mCx, JS_FALSE);
 
   JSAutoRequest ar(mCx);
-
-  JS::Rooted<JSObject*> global(mCx, JS_GetGlobalForObject(mCx, mCallback.ToJSObject()));
-  NS_ENSURE_TRUE(global, JS_FALSE);
-
-  JSAutoCompartment ac(mCx, global);
+  NS_ENSURE_TRUE(mCallback.ToJSObject(), JS_FALSE);
+  JSAutoCompartment ac(mCx, mCallback.ToJSObject());
+  JS::Rooted<JSObject*> global(mCx, JS_GetGlobalForScopeChain(mCx));
 
   JSString* str = JS_NewUCStringCopyN(mCx, aResponse.get(), aResponse.Length());
   NS_ENSURE_TRUE(str, JS_FALSE);
 
   JS::Rooted<JS::Value> strVal(mCx, JS::StringValue(str));
 
   JS::Rooted<JS::Value> rval(mCx);
   JSBool ok = JS_CallFunctionValue(mCx, global, mCallback, 1, strVal.address(),
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -825,43 +825,46 @@ LoadScriptRelativeToScript(JSContext *cx
 }
 
 class AutoNewContext
 {
   private:
     JSContext *oldcx;
     JSContext *newcx;
     Maybe<JSAutoRequest> newRequest;
+    Maybe<AutoCompartment> newCompartment;
 
     AutoNewContext(const AutoNewContext &) MOZ_DELETE;
 
   public:
     AutoNewContext() : oldcx(NULL), newcx(NULL) {}
 
     bool enter(JSContext *cx) {
         JS_ASSERT(!JS_IsExceptionPending(cx));
         oldcx = cx;
         newcx = NewContext(JS_GetRuntime(cx));
         if (!newcx)
             return false;
         JS_SetOptions(newcx, JS_GetOptions(newcx) | JSOPTION_DONT_REPORT_UNCAUGHT);
         JS_SetGlobalObject(newcx, JS_GetGlobalForScopeChain(cx));
 
         newRequest.construct(newcx);
+        newCompartment.construct(newcx, JS_GetGlobalForScopeChain(cx));
         return true;
     }
 
     JSContext *get() { return newcx; }
 
     ~AutoNewContext() {
         if (newcx) {
             RootedValue exc(oldcx);
             bool throwing = JS_IsExceptionPending(newcx);
             if (throwing)
                 JS_GetPendingException(newcx, exc.address());
+            newCompartment.destroy();
             newRequest.destroy();
             if (throwing)
                 JS_SetPendingException(oldcx, exc);
             DestroyContext(newcx, false);
         }
     }
 };
 
@@ -2609,36 +2612,36 @@ EvalInFrame(JSContext *cx, unsigned argc
     ScriptFrameIter fi(cx);
     for (uint32_t i = 0; i < upCount; ++i, ++fi) {
         ScriptFrameIter next(fi);
         ++next;
         if (next.done())
             break;
     }
 
-    bool saved = false;
-    if (saveCurrent)
-        saved = JS_SaveFrameChain(cx);
+    AutoSaveFrameChain sfc(cx);
+    mozilla::Maybe<AutoCompartment> ac;
+    if (saveCurrent) {
+        if (!sfc.save())
+            return false;
+        ac.construct(cx, GetDefaultGlobalForContext(cx));
+    }
 
     size_t length;
     const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
     if (!chars)
         return false;
 
     JSAbstractFramePtr frame(Jsvalify(fi.abstractFramePtr()));
     RootedScript fpscript(cx, frame.script());
     bool ok = !!frame.evaluateUCInStackFrame(cx, chars, length,
                                              fpscript->filename(),
                                              JS_PCToLineNumber(cx, fpscript,
                                                                fi.pc()),
                                              MutableHandleValue::fromMarkedLocation(vp));
-
-    if (saved)
-        JS_RestoreFrameChain(cx);
-
     return ok;
 }
 
 static JSBool
 ShapeOf(JSContext *cx, unsigned argc, JS::Value *vp)
 {
     JS::Value v;
     if (argc < 1 || !((v = JS_ARGV(cx, vp)[0]).isObject())) {
@@ -5125,16 +5128,17 @@ Shell(JSContext *cx, OptionParser *op, c
     if (op->getBoolOption("fuzzing-safe"))
         fuzzingSafe = true;
 
     RootedObject glob(cx);
     glob = NewGlobalObject(cx, NULL);
     if (!glob)
         return 1;
 
+    JSAutoCompartment ac(cx, glob);
     JS_SetGlobalObject(cx, glob);
 
     JSObject *envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0);
     if (!envobj)
         return 1;
     JS_SetPrivate(envobj, envp);
 
     int result = ProcessArgs(cx, glob, op);
--- a/netwerk/base/src/ProxyAutoConfig.cpp
+++ b/netwerk/base/src/ProxyAutoConfig.cpp
@@ -537,16 +537,17 @@ private:
     JSAutoRequest ar(mContext);
 
     JS::CompartmentOptions options;
     options.setZone(JS::SystemZone)
            .setVersion(JSVERSION_LATEST);
     mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr, options);
     NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY);
 
+    JSAutoCompartment ac(mContext, mGlobal);
     JS_SetGlobalObject(mContext, mGlobal);
     JS_InitStandardClasses(mContext, mGlobal);
 
     JS_SetErrorReporter(mContext, PACErrorReporter);
 
     if (!JS_DefineFunctions(mContext, mGlobal, PACGlobalFunctions))
       return NS_ERROR_FAILURE;
 
@@ -588,16 +589,17 @@ ProxyAutoConfig::SetupJS()
   if (mPACScript.IsEmpty())
     return NS_ERROR_FAILURE;
 
   mJSRuntime = JSRuntimeWrapper::Create();
   if (!mJSRuntime)
     return NS_ERROR_FAILURE;
 
   JSAutoRequest ar(mJSRuntime->Context());
+  JSAutoCompartment ac(mJSRuntime->Context(), mJSRuntime->Global());
 
   sRunning = this;
   JSScript *script = JS_CompileScript(mJSRuntime->Context(),
                                       mJSRuntime->Global(),
                                       mPACScript.get(), mPACScript.Length(),
                                       mPACURI.get(), 1);
   if (!script ||
       !JS_ExecuteScript(mJSRuntime->Context(), mJSRuntime->Global(), script, nullptr)) {
@@ -629,16 +631,17 @@ ProxyAutoConfig::GetProxyForURI(const ns
   if (mJSNeedsSetup)
     SetupJS();
 
   if (!mJSRuntime || !mJSRuntime->IsOK())
     return NS_ERROR_NOT_AVAILABLE;
 
   JSContext *cx = mJSRuntime->Context();
   JSAutoRequest ar(cx);
+  JSAutoCompartment ac(cx, mJSRuntime->Global());
 
   // the sRunning flag keeps a new PAC file from being installed
   // while the event loop is spinning on a DNS function. Don't early return.
   sRunning = this;
   mRunningHost = aTestHost;
 
   nsresult rv = NS_ERROR_FAILURE;
   JS::RootedString uriString(cx, JS_NewStringCopyZ(cx, aTestURI.get()));
@@ -668,16 +671,17 @@ ProxyAutoConfig::GetProxyForURI(const ns
 }
 
 void
 ProxyAutoConfig::GC()
 {
   if (!mJSRuntime || !mJSRuntime->IsOK())
     return;
 
+  JSAutoCompartment ac(mJSRuntime->Context(), mJSRuntime->Global());
   JS_MaybeGC(mJSRuntime->Context());
 }
 
 ProxyAutoConfig::~ProxyAutoConfig()
 {
   MOZ_COUNT_DTOR(ProxyAutoConfig);
   NS_ASSERTION(!mJSRuntime,
                "~ProxyAutoConfig leaking JS runtime that "