Bug 824864 - Hoist the guts of CompileFunction into nsJSUtils. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Wed, 16 Jan 2013 18:50:25 -0800
changeset 119104 33d6b596f5d23b9cad2c960a4e97616310d8d4f9
parent 119103 e51150a044d7fdac4d1c7cb686927ad804609b13
child 119105 533bc8e4981b770978ded6e800af27e8a9724108
push id24189
push useremorley@mozilla.com
push dateThu, 17 Jan 2013 10:42:06 +0000
treeherdermozilla-central@712eca11a04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs824864
milestone21.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 824864 - Hoist the guts of CompileFunction into nsJSUtils. r=bz
dom/base/nsJSEnvironment.cpp
dom/base/nsJSUtils.cpp
dom/base/nsJSUtils.h
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1806,49 +1806,27 @@ nsJSContext::CompileFunction(JSObject* a
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   // Don't compile if aVersion is unknown.  Since the caller is responsible for
   // parsing the version strings, we just check it isn't JSVERSION_UNKNOWN.
   if ((JSVersion)aVersion == JSVERSION_UNKNOWN) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
-  xpc_UnmarkGrayObject(aTarget);
-
-  nsIScriptGlobalObject *global = GetGlobalObject();
-  nsCOMPtr<nsIPrincipal> principal;
-  if (global) {
-    // XXXbe why the two-step QI? speed up via a new GetGlobalObjectData func?
-    nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(global);
-    if (globalData) {
-      principal = globalData->GetPrincipal();
-      if (!principal)
-        return NS_ERROR_FAILURE;
-    }
-  }
-
+  JSAutoRequest ar(mContext);
+  JSAutoCompartment ac(mContext, aTarget);
   js::RootedObject target(mContext, aShared ? NULL : aTarget);
 
-  XPCAutoRequest ar(mContext);
-
   JS::CompileOptions options(mContext);
-  options.setPrincipals(nsJSPrincipals::get(principal))
-         .setVersion(JSVersion(aVersion))
+  options.setVersion(JSVersion(aVersion))
          .setFileAndLine(aURL, aLineNo)
          .setUserBit(aIsXBL);
-  JSFunction* fun = JS::CompileFunction(mContext, target,
-                                        options, PromiseFlatCString(aName).get(),
-                                        aArgCount, aArgArray,
-                                        PromiseFlatString(aBody).get(), aBody.Length());
-
-  if (!fun)
-    return NS_ERROR_FAILURE;
-
-  *aFunctionObject = JS_GetFunctionObject(fun);
-  return NS_OK;
+
+  return nsJSUtils::CompileFunction(mContext, target, options, aName, aArgCount,
+                                    aArgArray, aBody, aFunctionObject);
 }
 
 nsresult
 nsJSContext::CallEventHandler(nsISupports* aTarget, JSObject* aScope,
                               JSObject* aHandler, nsIArray* aargv,
                               nsIVariant** arv)
 {
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -20,16 +20,19 @@
 #include "nsIServiceManager.h"
 #include "nsIXPConnect.h"
 #include "nsCOMPtr.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsPIDOMWindow.h"
 
 #include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
 
+#include "nsContentUtils.h"
+#include "nsJSPrincipals.h"
+
 #include "mozilla/dom/BindingUtils.h"
 
 JSBool
 nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
                               uint32_t* aLineno)
 {
   JSScript* script = nullptr;
   unsigned lineno = 0;
@@ -139,8 +142,44 @@ nsJSUtils::ReportPendingException(JSCont
   if (JS_IsExceptionPending(aContext)) {
     bool saved = JS_SaveFrameChain(aContext);
     JS_ReportPendingException(aContext);
     if (saved) {
       JS_RestoreFrameChain(aContext);
     }
   }
 }
+
+nsresult
+nsJSUtils::CompileFunction(JSContext* aCx,
+                           JS::HandleObject aTarget,
+                           JS::CompileOptions& aOptions,
+                           const nsACString& aName,
+                           uint32_t aArgCount,
+                           const char** aArgArray,
+                           const nsAString& aBody,
+                           JSObject** aFunctionObject)
+{
+  MOZ_ASSERT(js::GetEnterCompartmentDepth(aCx) > 0);
+  MOZ_ASSERT(!aTarget || js::IsObjectInContextCompartment(aTarget, aCx));
+  MOZ_ASSERT_IF(aOptions.versionSet, aOptions.version != JSVERSION_UNKNOWN);
+
+  // Since aTarget and aCx are same-compartment, there should be no distinction
+  // between the object principal and the cx principal.
+  // However, aTarget may be null in the wacky aShared case. So use the cx.
+  JSPrincipals *p = JS_GetCompartmentPrincipals(js::GetContextCompartment(aCx));
+  aOptions.setPrincipals(p);
+
+  // Do the junk Gecko is supposed to do before calling into JSAPI.
+  xpc_UnmarkGrayObject(aTarget);
+
+  // Compile.
+  JSFunction* fun = JS::CompileFunction(aCx, aTarget, aOptions,
+                                        PromiseFlatCString(aName).get(),
+                                        aArgCount, aArgArray,
+                                        PromiseFlatString(aBody).get(),
+                                        aBody.Length());
+  if (!fun)
+    return NS_ERROR_FAILURE;
+
+  *aFunctionObject = JS_GetFunctionObject(fun);
+  return NS_OK;
+}
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -49,16 +49,26 @@ public:
   static uint64_t GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext);
 
   /**
    * Report a pending exception on aContext, if any.  Note that this
    * can be called when the context has a JS stack.  If that's the
    * case, the stack will be set aside before reporting the exception.
    */
   static void ReportPendingException(JSContext *aContext);
+
+  static nsresult CompileFunction(JSContext* aCx,
+                                  JS::HandleObject aTarget,
+                                  JS::CompileOptions& aOptions,
+                                  const nsACString& aName,
+                                  uint32_t aArgCount,
+                                  const char** aArgArray,
+                                  const nsAString& aBody,
+                                  JSObject** aFunctionObject);
+
 };
 
 
 class nsDependentJSString : public nsDependentString
 {
 public:
   /**
    * In the case of string ids, getting the string's chars is infallible, so