Bug 781035 - Use the C++ JS compile API in more places. r=jorendorff sr=jst
authorBenjamin Peterson <benjamin@python.org>
Mon, 27 Aug 2012 08:04:37 -0400
changeset 105592 4bb09a1e8c1592feedd94b1aea70dbc8b5e10df5
parent 105591 c203425c094d439877b2faf2c48e56051e605ce5
child 105593 d985281cad1377334f72e5d3c85f6c42a38bc85e
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersjorendorff, jst
bugs781035
milestone17.0a1
Bug 781035 - Use the C++ JS compile API in more places. r=jorendorff sr=jst
content/base/src/nsFrameMessageManager.cpp
dom/base/nsJSEnvironment.cpp
dom/workers/ScriptLoader.cpp
dom/workers/WorkerPrivate.cpp
extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
js/xpconnect/src/XPCComponents.cpp
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -822,27 +822,23 @@ nsFrameScriptExecutor::LoadFrameScriptIn
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
       JSObject* global = nullptr;
       mGlobal->GetJSObject(&global);
       if (global) {
         JSAutoCompartment ac(mCx, global);
-        uint32_t oldopts = JS_GetOptions(mCx);
-        JS_SetOptions(mCx, oldopts | JSOPTION_NO_SCRIPT_RVAL);
-
-        JSScript* script =
-          JS_CompileUCScriptForPrincipals(mCx, nullptr,
-                                          nsJSPrincipals::get(mPrincipal),
-                                          static_cast<const jschar*>(dataString.get()),
-                                          dataString.Length(),
-                                          url.get(), 1);
-
-        JS_SetOptions(mCx, oldopts);
+        JS::CompileOptions options(mCx);
+        options.setNoScriptRval(true)
+               .setFileAndLine(url.get(), 1)
+               .setPrincipals(nsJSPrincipals::get(mPrincipal));
+        JS::RootedObject empty(mCx, NULL);
+        JSScript* script = JS::Compile(mCx, empty, options,
+                                       dataString.get(), dataString.Length());
 
         if (script) {
           nsCAutoString scheme;
           uri->GetScheme(scheme);
           // We don't cache data: scripts!
           if (!scheme.EqualsLiteral("data")) {
             nsFrameJSScriptExecutorHolder* holder =
               new nsFrameJSScriptExecutorHolder(script);
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1288,25 +1288,23 @@ nsJSContext::EvaluateStringWithValue(con
   // check it isn't JSVERSION_UNKNOWN.
   if (ok && ((JSVersion)aVersion) != JSVERSION_UNKNOWN) {
 
     XPCAutoRequest ar(mContext);
     JSAutoCompartment ac(mContext, aScopeObject);
 
     ++mExecuteDepth;
 
-    ok = ::JS_EvaluateUCScriptForPrincipalsVersion(mContext,
-                                                   aScopeObject,
-                                                   nsJSPrincipals::get(principal),
-                                                   static_cast<const jschar*>(PromiseFlatString(aScript).get()),
-                                                   aScript.Length(),
-                                                   aURL,
-                                                   aLineNo,
-                                                   &val,
-                                                   JSVersion(aVersion));
+    JS::CompileOptions options(mContext);
+    options.setFileAndLine(aURL, aLineNo)
+           .setVersion(JSVersion(aVersion))
+           .setPrincipals(nsJSPrincipals::get(principal));
+    JS::RootedObject rootedScope(mContext, aScopeObject);
+    ok = JS::Evaluate(mContext, rootedScope, options, PromiseFlatString(aScript).get(),
+                      aScript.Length(), &val);
 
     --mExecuteDepth;
 
     if (!ok) {
       // Tell XPConnect about any pending exceptions. This is needed
       // to avoid dropping JS exceptions in case we got here through
       // nested calls through XPConnect.
 
@@ -1485,21 +1483,25 @@ nsJSContext::EvaluateString(const nsAStr
 
   // SecurityManager said "ok", but 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 (ok && JSVersion(aVersion) != JSVERSION_UNKNOWN) {
     XPCAutoRequest ar(mContext);
     JSAutoCompartment ac(mContext, aScopeObject);
 
-    ok = JS_EvaluateUCScriptForPrincipalsVersionOrigin(
-      mContext, aScopeObject,
-      nsJSPrincipals::get(principal), nsJSPrincipals::get(aOriginPrincipal),
-      static_cast<const jschar*>(PromiseFlatString(aScript).get()),
-      aScript.Length(), aURL, aLineNo, vp, JSVersion(aVersion));
+    JS::RootedObject rootedScope(mContext, aScopeObject);
+    JS::CompileOptions options(mContext);
+    options.setFileAndLine(aURL, aLineNo)
+           .setPrincipals(nsJSPrincipals::get(principal))
+           .setOriginPrincipals(nsJSPrincipals::get(aOriginPrincipal))
+           .setVersion(JSVersion(aVersion));
+    ok = JS::Evaluate(mContext, rootedScope, options,
+                      PromiseFlatString(aScript).get(),
+                      aScript.Length(), vp);
 
     if (!ok) {
       // Tell XPConnect about any pending exceptions. This is needed
       // to avoid dropping JS exceptions in case we got here through
       // nested calls through XPConnect.
 
       ReportPendingException();
     }
@@ -1746,27 +1748,26 @@ nsJSContext::CompileEventHandler(nsIAtom
   }
 
 #ifdef DEBUG
   JSContext* top = nsContentUtils::GetCurrentJSContext();
   NS_ASSERTION(mContext == top, "Context not properly pushed!");
 #endif
 
   // Event handlers are always shared, and must be bound before use.
-  // Therefore we never bother compiling with principals.
-  // (that probably means we should avoid JS_CompileUCFunctionForPrincipals!)
+  // Therefore we don't bother compiling with principals.
   XPCAutoRequest ar(mContext);
 
-  JSFunction* fun =
-      ::JS_CompileUCFunctionForPrincipalsVersion(mContext,
-                                                 nullptr, nullptr,
-                                                 nsAtomCString(aName).get(), aArgCount, aArgNames,
-                                                 (jschar*)PromiseFlatString(aBody).get(),
-                                                 aBody.Length(),
-                                                 aURL, aLineNo, JSVersion(aVersion));
+  JS::CompileOptions options(mContext);
+  options.setVersion(JSVersion(aVersion))
+         .setFileAndLine(aURL, aLineNo);
+  JS::RootedObject empty(mContext, NULL);
+  JSFunction* fun = JS::CompileFunction(mContext, empty, options, nsAtomCString(aName).get(),
+                                        aArgCount, aArgNames,
+                                        PromiseFlatString(aBody).get(), aBody.Length());
 
   if (!fun) {
     ReportPendingException();
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   JSObject *handler = ::JS_GetFunctionObject(fun);
   return aHandler.set(handler);
@@ -1809,30 +1810,28 @@ nsJSContext::CompileFunction(JSObject* a
     nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(global);
     if (globalData) {
       principal = globalData->GetPrincipal();
       if (!principal)
         return NS_ERROR_FAILURE;
     }
   }
 
-  JSObject *target = aTarget;
+  JS::RootedObject target(mContext, aShared ? NULL : aTarget);
 
   XPCAutoRequest ar(mContext);
 
-  JSFunction* fun =
-      ::JS_CompileUCFunctionForPrincipalsVersion(mContext,
-                                                 aShared ? nullptr : target,
-                                                 nsJSPrincipals::get(principal),
-                                                 PromiseFlatCString(aName).get(),
-                                                 aArgCount, aArgArray,
-                                                 static_cast<const jschar*>(PromiseFlatString(aBody).get()),
-                                                 aBody.Length(),
-                                                 aURL, aLineNo,
-                                                 JSVersion(aVersion));
+  JS::CompileOptions options(mContext);
+  options.setPrincipals(nsJSPrincipals::get(principal))
+         .setVersion(JSVersion(aVersion))
+         .setFileAndLine(aURL, aLineNo);
+  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;
 }
 
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -571,17 +571,17 @@ ScriptExecutorRunnable::WorkerRun(JSCont
     NS_ASSERTION(!loadInfo.mChannel, "Should no longer have a channel!");
     NS_ASSERTION(loadInfo.mExecutionScheduled, "Should be scheduled!");
 
     if (!loadInfo.mExecutionResult) {
       return true;
     }
   }
 
-  JSObject* global = JS_GetGlobalObject(aCx);
+  JS::RootedObject global(aCx, JS_GetGlobalObject(aCx));
   NS_ASSERTION(global, "Must have a global by now!");
 
   JSPrincipals* principal = GetWorkerPrincipal();
   NS_ASSERTION(principal, "This should never be null!");
 
   for (uint32_t index = mFirstIndex; index <= mLastIndex; index++) {
     ScriptLoadInfo& loadInfo = loadInfos.ElementAt(index);
 
@@ -610,20 +610,21 @@ ScriptExecutorRunnable::WorkerRun(JSCont
           JS_ReportError(aCx, "Failed to load script: %s (nsresult = 0x%x)",
                          url.get(), loadInfo.mLoadResult);
       }
       return true;
     }
 
     NS_ConvertUTF16toUTF8 filename(loadInfo.mURL);
 
-    if (!JS_EvaluateUCScriptForPrincipals(aCx, global, principal,
-                                          loadInfo.mScriptText.get(),
-                                          loadInfo.mScriptText.Length(),
-                                          filename.get(), 1, nullptr)) {
+    JS::CompileOptions options(aCx);
+    options.setPrincipals(principal)
+           .setFileAndLine(filename.get(), 1);
+    if (!JS::Evaluate(aCx, global, options, loadInfo.mScriptText.get(),
+                      loadInfo.mScriptText.Length(), nullptr)) {
       return true;
     }
 
     loadInfo.mExecutionResult = true;
   }
 
   return true;
 }
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3755,17 +3755,17 @@ WorkerPrivate::RunExpiredTimeouts(JSCont
   }
 
   NS_ASSERTION(mTimer, "Must have a timer!");
   NS_ASSERTION(!mTimeouts.IsEmpty(), "Should have some work to do!");
 
   bool retval = true;
 
   AutoPtrComparator<TimeoutInfo> comparator = GetAutoPtrComparator(mTimeouts);
-  JSObject* global = JS_GetGlobalObject(aCx);
+  JS::RootedObject global(aCx, JS_GetGlobalObject(aCx));
   JSPrincipals* principal = GetWorkerPrincipal();
 
   // We want to make sure to run *something*, even if the timer fired a little
   // early. Fudge the value of now to at least include the first timeout.
   const TimeStamp now = NS_MAX(TimeStamp::Now(), mTimeouts[0]->mTargetTime);
 
   nsAutoTArray<TimeoutInfo*, 10> expiredTimeouts;
   for (uint32_t index = 0; index < mTimeouts.Length(); index++) {
@@ -3789,28 +3789,27 @@ WorkerPrivate::RunExpiredTimeouts(JSCont
 
     // Always call JS_ReportPendingException if something fails, and if
     // JS_ReportPendingException returns false (i.e. uncatchable exception) then
     // break out of the loop.
 
     if (info->mTimeoutVal.isString()) {
       JSString* expression = info->mTimeoutVal.toString();
 
+      JS::CompileOptions options(aCx);
+      options.setPrincipals(principal)
+        .setFileAndLine(info->mFilename.get(), info->mLineNumber);
+
       size_t stringLength;
       const jschar* string = JS_GetStringCharsAndLength(aCx, expression,
                                                         &stringLength);
-
-      if ((!string ||
-           !JS_EvaluateUCScriptForPrincipals(aCx, global, principal, string,
-                                             stringLength,
-                                             info->mFilename.get(),
-                                             info->mLineNumber, nullptr)) &&
+      if ((!string || !JS::Evaluate(aCx, global, options, string, stringLength, nullptr)) &&
           !JS_ReportPendingException(aCx)) {
-        retval = false;
-        break;
+          retval = false;
+          break;
       }
     }
     else {
       jsval rval;
       if (!JS_CallFunctionValue(aCx, global, info->mTimeoutVal,
                                 info->mExtraArgVals.Length(),
                                 info->mExtraArgVals.Elements(), &rval) &&
           !JS_ReportPendingException(aCx)) {
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -190,19 +190,21 @@ nsresult EvaluateAdminConfigScript(const
     if (NS_FAILED(rv)) {
         NS_ERROR("coudn't push the context on the stack");
         return rv;
     }
 
     JS_BeginRequest(autoconfig_cx);
     nsCOMPtr<nsIPrincipal> principal;
     nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(principal));
-    ok = JS_EvaluateScriptForPrincipals(autoconfig_cx, autoconfig_glob, 
-                                        nsJSPrincipals::get(principal),
-                                        js_buffer, length, filename, 0, nullptr);
+    JS::CompileOptions options(autoconfig_cx);
+    options.setPrincipals(nsJSPrincipals::get(principal))
+           .setFileAndLine(filename, 1);
+    JS::RootedObject glob(autoconfig_cx, autoconfig_glob);
+    ok = JS::Evaluate(autoconfig_cx, glob, options, js_buffer, length, nullptr);
     JS_EndRequest(autoconfig_cx);
 
     JS_MaybeGC(autoconfig_cx);
 
     JSContext *cx;
     cxstack->Pop(&cx);
     NS_ASSERTION(cx == autoconfig_cx, "AutoConfig JS contexts didn't match");
 
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3910,23 +3910,22 @@ xpc_EvalInSandbox(JSContext *cx, JSObjec
     nsresult rv = NS_OK;
 
     {
         JSAutoRequest req(sandcx->GetJSContext());
         JSAutoCompartment ac(sandcx->GetJSContext(), sandbox);
 
         jsval v;
         JSString *str = nullptr;
-        JSBool ok =
-            JS_EvaluateUCScriptForPrincipals(sandcx->GetJSContext(), sandbox,
-                                             nsJSPrincipals::get(prin),
-                                             reinterpret_cast<const jschar *>
-                                                             (PromiseFlatString(source).get()),
-                                             source.Length(), filename, lineNo,
-                                             &v);
+        JS::CompileOptions options(sandcx->GetJSContext());
+        options.setPrincipals(nsJSPrincipals::get(prin))
+               .setFileAndLine(filename, lineNo);
+        JS::RootedObject rootedSandbox(sandcx->GetJSContext(), sandbox);
+        bool ok = JS::Evaluate(sandcx->GetJSContext(), rootedSandbox, options,
+                               PromiseFlatString(source).get(), source.Length(), &v);
         if (ok && returnStringOnly && !(JSVAL_IS_VOID(v))) {
             ok = !!(str = JS_ValueToString(sandcx->GetJSContext(), v));
         }
 
         if (!ok) {
             // The sandbox threw an exception, convert it to a string (if
             // asked) or convert it to a SJOW.