Bug 959787 - Handlify JS_ExecuteScript and JS::Evaluate APIs r=terrence r=bz
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 01 Apr 2014 11:34:39 +0100
changeset 176420 833ff3a90b83d66dd56a1def7807e21e338fe0ab
parent 176419 92f8f685d9400d4624811d63be4974b9d38fa69d
child 176421 56b6b23b7eb2a8b0b2627e71c3fa8ff45a177f4e
push id41756
push userjcoppeard@mozilla.com
push dateTue, 01 Apr 2014 10:40:43 +0000
treeherdermozilla-inbound@56b6b23b7eb2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence, bz
bugs959787
milestone31.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 959787 - Handlify JS_ExecuteScript and JS::Evaluate APIs r=terrence r=bz
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsScriptLoader.cpp
content/xul/document/src/XULDocument.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSUtils.cpp
dom/base/nsJSUtils.h
dom/plugins/base/nsNPAPIPlugin.cpp
dom/src/jsurl/nsJSProtocolHandler.cpp
dom/workers/ScriptLoader.cpp
dom/workers/WorkerPrivate.cpp
dom/xbl/nsXBLProtoImplField.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/src/jsapi-tests/testDebugger.cpp
js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
js/src/jsapi-tests/testGCOutOfMemory.cpp
js/src/jsapi-tests/testJSEvaluateScript.cpp
js/src/jsapi-tests/testOriginPrincipals.cpp
js/src/jsapi-tests/testScriptObject.cpp
js/src/jsapi-tests/testSourcePolicy.cpp
js/src/jsapi-tests/testTrap.cpp
js/src/jsapi-tests/testXDR.cpp
js/src/jsapi-tests/tests.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/shell/js.cpp
js/src/vm/SelfHosting.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCShellImpl.cpp
netwerk/base/src/ProxyAutoConfig.cpp
security/manager/ssl/src/nsCrypto.cpp
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -1428,17 +1428,17 @@ nsFrameScriptExecutor::LoadFrameScriptIn
       if (!method) {
         return;
       }
       JS::Rooted<JS::Value> rval(cx);
       JS::Rooted<JS::Value> methodVal(cx, JS::ObjectValue(*method));
       ok = JS_CallFunctionValue(cx, global, methodVal,
                                 JS::HandleValueArray::empty(), &rval);
     } else if (script) {
-      ok = JS_ExecuteScript(cx, global, script, nullptr);
+      ok = JS_ExecuteScript(cx, global, script);
     }
 
     if (!ok) {
       nsJSUtils::ReportPendingException(cx);
     }
   }
 }
 
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -1083,19 +1083,17 @@ nsScriptLoader::EvaluateScript(nsScriptL
   context->SetProcessingScriptTag(true);
 
   // Update our current script.
   nsCOMPtr<nsIScriptElement> oldCurrent = mCurrentScript;
   mCurrentScript = aRequest->mElement;
 
   JS::CompileOptions options(entryScript.cx());
   FillCompileOptionsForRequest(aRequest, global, &options);
-  nsJSUtils::EvaluateOptions evalOptions;
-  nsresult rv = nsJSUtils::EvaluateString(entryScript.cx(), aScript, global,
-                                          options, evalOptions, nullptr,
+  nsresult rv = nsJSUtils::EvaluateString(entryScript.cx(), aScript, global, options,
                                           aOffThreadToken);
 
   // Put the old script back in case it wants to do anything else.
   mCurrentScript = oldCurrent;
 
   context->SetProcessingScriptTag(oldProcessingScriptTag);
   return rv;
 }
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -3674,18 +3674,17 @@ XULDocument::ExecuteScript(nsIScriptCont
     JSContext *cx = aContext->GetNativeContext();
     AutoCxPusher pusher(cx);
     JS::Rooted<JSObject*> global(cx, mScriptGlobalObject->GetGlobalJSObject());
     NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
     NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(global), NS_OK);
     JS::ExposeObjectToActiveJS(global);
     xpc_UnmarkGrayScript(aScriptObject);
     JSAutoCompartment ac(cx, global);
-    JS::Rooted<JS::Value> unused(cx);
-    if (!JS_ExecuteScript(cx, global, aScriptObject, unused.address()))
+    if (!JS_ExecuteScript(cx, global, aScriptObject))
         nsJSUtils::ReportPendingException(cx);
     return NS_OK;
 }
 
 nsresult
 XULDocument::ExecuteScript(nsXULPrototypeScript *aScript)
 {
     NS_PRECONDITION(aScript != nullptr, "null ptr");
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -11849,19 +11849,18 @@ nsGlobalWindow::RunTimeoutHandler(nsTime
 
     // New script entry point required, due to the "Create a script" sub-step of
     // http://www.whatwg.org/specs/web-apps/current-work/#timer-initialization-steps
     AutoEntryScript entryScript(this, true, aScx->GetNativeContext());
     JS::CompileOptions options(entryScript.cx());
     options.setFileAndLine(filename, lineNo)
            .setVersion(JSVERSION_DEFAULT);
     JS::Rooted<JSObject*> global(entryScript.cx(), FastGetGlobalJSObject());
-    nsJSUtils::EvaluateOptions evalOptions;
     nsJSUtils::EvaluateString(entryScript.cx(), nsDependentString(script),
-                              global, options, evalOptions, nullptr);
+                              global, options);
   } else {
     // Hold strong ref to ourselves while we call the callback.
     nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
     ErrorResult ignored;
     callback->Call(me, handler->GetArgs(), ignored);
   }
 
   // We ignore any failures from calling EvaluateString() on the context or
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -171,34 +171,34 @@ nsJSUtils::CompileFunction(JSContext* aC
   return NS_OK;
 }
 
 nsresult
 nsJSUtils::EvaluateString(JSContext* aCx,
                           const nsAString& aScript,
                           JS::Handle<JSObject*> aScopeObject,
                           JS::CompileOptions& aCompileOptions,
-                          EvaluateOptions& aEvaluateOptions,
-                          JS::Value* aRetValue,
+                          const EvaluateOptions& aEvaluateOptions,
+                          JS::MutableHandle<JS::Value> aRetValue,
                           void **aOffThreadToken)
 {
   PROFILER_LABEL("JS", "EvaluateString");
   MOZ_ASSERT_IF(aCompileOptions.versionSet,
                 aCompileOptions.version != JSVERSION_UNKNOWN);
-  MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, aRetValue);
-  MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, aRetValue);
+  MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, aEvaluateOptions.needResult);
+  MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, aEvaluateOptions.needResult);
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
 
   // Unfortunately, the JS engine actually compiles scripts with a return value
   // in a different, less efficient way.  Furthermore, it can't JIT them in many
   // cases.  So we need to be explicitly told whether the caller cares about the
-  // return value.  Callers use null to indicate they don't care.
-  if (aRetValue) {
-    *aRetValue = JSVAL_VOID;
-  }
+  // return value.  Callers can do this by calling the other overload of
+  // EvaluateString() which calls this function with aEvaluateOptions.needResult
+  // set to false.
+  aRetValue.setUndefined();
 
   JS::ExposeObjectToActiveJS(aScopeObject);
   nsAutoMicroTask mt;
   nsresult rv = NS_OK;
 
   bool ok = false;
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   NS_ENSURE_TRUE(ssm->ScriptAllowed(js::GetGlobalForObjectCrossCompartment(aScopeObject)), NS_OK);
@@ -216,63 +216,87 @@ nsJSUtils::EvaluateString(JSContext* aCx
     JSAutoCompartment ac(aCx, aScopeObject);
 
     JS::Rooted<JSObject*> rootedScope(aCx, aScopeObject);
     if (aOffThreadToken) {
       JS::Rooted<JSScript*>
         script(aCx, JS::FinishOffThreadScript(aCx, JS_GetRuntime(aCx), *aOffThreadToken));
       *aOffThreadToken = nullptr; // Mark the token as having been finished.
       if (script) {
-        ok = JS_ExecuteScript(aCx, rootedScope, script, aRetValue);
+        if (aEvaluateOptions.needResult) {
+          ok = JS_ExecuteScript(aCx, rootedScope, script, aRetValue);
+        } else {
+          ok = JS_ExecuteScript(aCx, rootedScope, script);
+        }
       } else {
         ok = false;
       }
     } else {
-      ok = JS::Evaluate(aCx, rootedScope, aCompileOptions,
-                        PromiseFlatString(aScript).get(),
-                        aScript.Length(), aRetValue);
+      if (aEvaluateOptions.needResult) {
+        ok = JS::Evaluate(aCx, rootedScope, aCompileOptions,
+                          PromiseFlatString(aScript).get(),
+                          aScript.Length(), aRetValue);
+      } else {
+        ok = JS::Evaluate(aCx, rootedScope, aCompileOptions,
+                          PromiseFlatString(aScript).get(),
+                          aScript.Length());
+      }
     }
 
-    if (ok && aEvaluateOptions.coerceToString && !aRetValue->isUndefined()) {
-      JS::Rooted<JS::Value> value(aCx, *aRetValue);
+    if (ok && aEvaluateOptions.coerceToString && !aRetValue.isUndefined()) {
+      JS::Rooted<JS::Value> value(aCx, aRetValue);
       JSString* str = JS::ToString(aCx, value);
       ok = !!str;
-      *aRetValue = ok ? JS::StringValue(str) : JS::UndefinedValue();
+      aRetValue.set(ok ? JS::StringValue(str) : JS::UndefinedValue());
     }
   }
 
   if (!ok) {
     if (aEvaluateOptions.reportUncaught) {
       ReportPendingException(aCx);
-      if (aRetValue) {
-        *aRetValue = JS::UndefinedValue();
+      if (aEvaluateOptions.needResult) {
+        aRetValue.setUndefined();
       }
     } else {
       rv = JS_IsExceptionPending(aCx) ? NS_ERROR_FAILURE
                                       : NS_ERROR_OUT_OF_MEMORY;
       JS::Rooted<JS::Value> exn(aCx);
       JS_GetPendingException(aCx, &exn);
-      if (aRetValue) {
-        *aRetValue = exn;
+      if (aEvaluateOptions.needResult) {
+        aRetValue.set(exn);
       }
       JS_ClearPendingException(aCx);
     }
   }
 
   // Wrap the return value into whatever compartment aCx was in.
-  if (aRetValue) {
-    JS::Rooted<JS::Value> v(aCx, *aRetValue);
+  if (aEvaluateOptions.needResult) {
+    JS::Rooted<JS::Value> v(aCx, aRetValue);
     if (!JS_WrapValue(aCx, &v)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
-    *aRetValue = v;
+    aRetValue.set(v);
   }
   return rv;
 }
 
+nsresult
+nsJSUtils::EvaluateString(JSContext* aCx,
+                          const nsAString& aScript,
+                          JS::Handle<JSObject*> aScopeObject,
+                          JS::CompileOptions& aCompileOptions,
+                          void **aOffThreadToken)
+{
+  EvaluateOptions options;
+  options.setNeedResult(false);
+  JS::RootedValue unused(aCx);
+  return EvaluateString(aCx, aScript, aScopeObject, aCompileOptions,
+                        options, &unused, aOffThreadToken);
+}
+
 //
 // nsDOMJSUtils.h
 //
 
 JSObject* GetDefaultScopeFromJSContext(JSContext *cx)
 {
   // DOM JSContexts don't store their default compartment object on
   // the cx, so in those cases we need to fetch it via the scx
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -59,38 +59,52 @@ public:
                                   uint32_t aArgCount,
                                   const char** aArgArray,
                                   const nsAString& aBody,
                                   JSObject** aFunctionObject);
 
   struct EvaluateOptions {
     bool coerceToString;
     bool reportUncaught;
+    bool needResult;
 
     explicit EvaluateOptions() : coerceToString(false)
                                , reportUncaught(true)
+                               , needResult(true)
     {}
 
     EvaluateOptions& setCoerceToString(bool aCoerce) {
       coerceToString = aCoerce;
       return *this;
     }
 
     EvaluateOptions& setReportUncaught(bool aReport) {
       reportUncaught = aReport;
       return *this;
     }
+
+    EvaluateOptions& setNeedResult(bool aNeedResult) {
+      needResult = aNeedResult;
+      return *this;
+    }
   };
 
   static nsresult EvaluateString(JSContext* aCx,
                                  const nsAString& aScript,
                                  JS::Handle<JSObject*> aScopeObject,
                                  JS::CompileOptions &aCompileOptions,
-                                 EvaluateOptions& aEvaluateOptions,
-                                 JS::Value* aRetValue,
+                                 const EvaluateOptions& aEvaluateOptions,
+                                 JS::MutableHandle<JS::Value> aRetValue,
+                                 void **aOffThreadToken = nullptr);
+
+
+  static nsresult EvaluateString(JSContext* aCx,
+                                 const nsAString& aScript,
+                                 JS::Handle<JSObject*> aScopeObject,
+                                 JS::CompileOptions &aCompileOptions,
                                  void **aOffThreadToken = nullptr);
 
 };
 
 class MOZ_STACK_CLASS AutoDontReportUncaught {
   JSContext* mContext;
   bool mWasSet;
 
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -1553,17 +1553,17 @@ bool
                   npp, npobj, script->UTF8Characters));
 
   JS::CompileOptions options(cx);
   options.setFileAndLine(spec, 0)
          .setVersion(JSVERSION_DEFAULT);
   JS::Rooted<JS::Value> rval(cx);
   nsJSUtils::EvaluateOptions evalOptions;
   nsresult rv = nsJSUtils::EvaluateString(cx, utf16script, obj, options,
-                                          evalOptions, rval.address());
+                                          evalOptions, &rval);
 
   return NS_SUCCEEDED(rv) &&
          (!result || JSValToNPVariant(npp, cx, rval, result));
 }
 
 bool
 _getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
              NPVariant *result)
--- a/dom/src/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/src/jsurl/nsJSProtocolHandler.cpp
@@ -310,18 +310,17 @@ nsresult nsJSThunk::EvaluateScript(nsICh
         // No need to use the sandbox, evaluate the script directly in
         // the given scope.
         JS::CompileOptions options(cx);
         options.setFileAndLine(mURL.get(), 1)
                .setVersion(JSVERSION_DEFAULT);
         nsJSUtils::EvaluateOptions evalOptions;
         evalOptions.setCoerceToString(true);
         rv = nsJSUtils::EvaluateString(cx, NS_ConvertUTF8toUTF16(script),
-                                       globalJSObject, options, evalOptions,
-                                       v.address());
+                                       globalJSObject, options, evalOptions, &v);
 
         // If there's an error on cx as a result of that call, report
         // it now -- either we're just running under the event loop,
         // so we shouldn't propagate JS exceptions out of here, or we
         // can't be sure that our caller is JS (and if it's not we'll
         // lose the error), or it might be JS that then proceeds to
         // cause an error of its own (which will also make us lose
         // this error).
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -712,17 +712,17 @@ ScriptExecutorRunnable::WorkerRun(JSCont
       return true;
     }
 
     NS_ConvertUTF16toUTF8 filename(loadInfo.mURL);
 
     JS::CompileOptions options(aCx);
     options.setFileAndLine(filename.get(), 1);
     if (!JS::Evaluate(aCx, global, options, loadInfo.mScriptText.get(),
-                      loadInfo.mScriptText.Length(), nullptr)) {
+                      loadInfo.mScriptText.Length())) {
       return true;
     }
 
     loadInfo.mExecutionResult = true;
   }
 
   return true;
 }
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -5423,18 +5423,17 @@ WorkerPrivate::RunExpiredTimeouts(JSCont
     }
     else {
       nsString expression = info->mTimeoutString;
 
       JS::CompileOptions options(aCx);
       options.setFileAndLine(info->mFilename.get(), info->mLineNumber);
 
       if ((expression.IsEmpty() ||
-           !JS::Evaluate(aCx, global, options, expression.get(),
-                         expression.Length(), nullptr)) &&
+           !JS::Evaluate(aCx, global, options, expression.get(), expression.Length())) &&
           !JS_ReportPendingException(aCx)) {
         retval = false;
         break;
       }
     }
 
     NS_ASSERTION(mRunningExpiredTimeouts, "Someone changed this!");
   }
--- a/dom/xbl/nsXBLProtoImplField.cpp
+++ b/dom/xbl/nsXBLProtoImplField.cpp
@@ -426,17 +426,17 @@ nsXBLProtoImplField::InstallField(JS::Ha
   JS::Rooted<JS::Value> result(cx);
   JS::CompileOptions options(cx);
   options.setFileAndLine(uriSpec.get(), mLineNumber)
          .setVersion(JSVERSION_LATEST);
   nsJSUtils::EvaluateOptions evalOptions;
   rv = nsJSUtils::EvaluateString(cx, nsDependentString(mFieldText,
                                                        mFieldTextLength),
                                  wrappedNode, options, evalOptions,
-                                 result.address());
+                                 &result);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
 
   // Now, enter the node's compartment, wrap the eval result, and define it on
   // the bound node.
   JSAutoCompartment ac2(cx, aBoundNode);
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -165,18 +165,17 @@ Load(JSContext *cx,
         JS::CompileOptions options(cx);
         options.setUTF8(true)
                .setFileAndLine(filename.ptr(), 1);
         JS::Rooted<JSScript*> script(cx, JS::Compile(cx, obj, options, file));
         fclose(file);
         if (!script)
             return false;
 
-        JS::Rooted<JS::Value> result(cx);
-        if (!JS_ExecuteScript(cx, obj, script, result.address())) {
+        if (!JS_ExecuteScript(cx, obj, script)) {
             return false;
         }
     }
     args.rval().setUndefined();
     return true;
 }
 
 static bool
@@ -332,17 +331,17 @@ XPCShellEnvironment::ProcessFile(JSConte
         JSAutoRequest ar(cx);
         JSAutoCompartment ac(cx, obj);
 
         JS::CompileOptions options(cx);
         options.setUTF8(true)
                .setFileAndLine(filename, 1);
         JS::Rooted<JSScript*> script(cx, JS::Compile(cx, obj, options, file));
         if (script)
-            (void)JS_ExecuteScript(cx, obj, script, result.address());
+            (void)JS_ExecuteScript(cx, obj, script, &result);
 
         return;
     }
 
     /* It's an interactive filehandle; drop into read-eval-print loop. */
     lineno = 1;
     hitEOF = false;
     do {
@@ -372,17 +371,17 @@ XPCShellEnvironment::ProcessFile(JSConte
         JS_ClearPendingException(cx);
         JS::CompileOptions options(cx);
         options.setFileAndLine("typein", startline);
         JS::Rooted<JSScript*> script(cx,
                                      JS_CompileScript(cx, obj, buffer, strlen(buffer), options));
         if (script) {
             JSErrorReporter older;
 
-            ok = JS_ExecuteScript(cx, obj, script, result.address());
+            ok = JS_ExecuteScript(cx, obj, script, &result);
             if (ok && result != JSVAL_VOID) {
                 /* Suppress error reports from JS::ToString(). */
                 older = JS_SetErrorReporter(cx, nullptr);
                 str = JS::ToString(cx, result);
                 JSAutoByteString bytes;
                 if (str)
                     bytes.encodeLatin1(cx, str);
                 JS_SetErrorReporter(cx, older);
@@ -587,17 +586,17 @@ XPCShellEnvironment::EvaluateString(cons
      return false;
   }
 
   if (aResult) {
       aResult->Truncate();
   }
 
   JS::Rooted<JS::Value> result(cx);
-  bool ok = JS_ExecuteScript(cx, global, script, result.address());
+  bool ok = JS_ExecuteScript(cx, global, script, &result);
   if (ok && result != JSVAL_VOID) {
       JSErrorReporter old = JS_SetErrorReporter(cx, nullptr);
       JSString* str = JS::ToString(cx, result);
       nsDependentJSString depStr;
       if (str)
           depStr.init(cx, str);
       JS_SetErrorReporter(cx, old);
 
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -121,17 +121,17 @@ ThrowHook(JSContext *cx, JSScript *, jsb
 {
     JS_ASSERT(!closure);
     calledThrowHook = true;
 
     JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
 
     char text[] = "new Error()";
     JS::RootedValue _(cx);
-    JS_EvaluateScript(cx, global, text, strlen(text), "", 0, _.address());
+    JS_EvaluateScript(cx, global, text, strlen(text), "", 0, &_);
 
     return JSTRAP_CONTINUE;
 }
 
 BEGIN_TEST(testDebugger_throwHook)
 {
     CHECK(JS_SetDebugMode(cx, true));
     CHECK(JS_SetThrowHook(rt, ThrowHook, nullptr));
--- a/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
+++ b/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
@@ -35,13 +35,13 @@ BEGIN_TEST(testRedefineGlobalEval)
     if (!g)
         return false;
 
     JSAutoCompartment ac(cx, g);
     JS::Rooted<JS::Value> v(cx);
     CHECK(JS_GetProperty(cx, g, "Object", &v));
 
     static const char data[] = "Object.defineProperty(this, 'eval', { configurable: false });";
-    CHECK(JS_EvaluateScript(cx, g, data, mozilla::ArrayLength(data) - 1, __FILE__, __LINE__, v.address()));
+    CHECK(JS_EvaluateScript(cx, g, data, mozilla::ArrayLength(data) - 1, __FILE__, __LINE__, &v));
 
     return true;
 }
 END_TEST(testRedefineGlobalEval)
--- a/js/src/jsapi-tests/testGCOutOfMemory.cpp
+++ b/js/src/jsapi-tests/testGCOutOfMemory.cpp
@@ -24,18 +24,17 @@ BEGIN_TEST(testGCOutOfMemory)
 
     static const char source[] =
         "var max = 0; (function() {"
         "    var array = [];"
         "    for (; ; ++max)"
         "        array.push({});"
         "    array = []; array.push(0);"
         "})();";
-    bool ok = JS_EvaluateScript(cx, global, source, strlen(source), "", 1,
-                                  root.address());
+    bool ok = JS_EvaluateScript(cx, global, source, strlen(source), "", 1, &root);
 
     /* Check that we get OOM. */
     CHECK(!ok);
     CHECK(!JS_IsExceptionPending(cx));
     CHECK_EQUAL(errorCount, 1);
     JS_GC(rt);
 
     // Temporarily disabled to reopen the tree. Bug 847579.
--- a/js/src/jsapi-tests/testJSEvaluateScript.cpp
+++ b/js/src/jsapi-tests/testJSEvaluateScript.cpp
@@ -9,34 +9,32 @@ BEGIN_TEST(testJSEvaluateScript)
     JS::RootedObject obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), global));
     CHECK(obj);
 
     CHECK(JS::ContextOptionsRef(cx).varObjFix());
 
     static const char src[] = "var x = 5;";
 
     JS::RootedValue retval(cx);
-    CHECK(JS_EvaluateScript(cx, obj, src, sizeof(src) - 1, __FILE__, __LINE__,
-                            retval.address()));
+    CHECK(JS_EvaluateScript(cx, obj, src, sizeof(src) - 1, __FILE__, __LINE__, &retval));
 
     bool hasProp = true;
     CHECK(JS_AlreadyHasOwnProperty(cx, obj, "x", &hasProp));
     CHECK(!hasProp);
 
     hasProp = false;
     CHECK(JS_HasProperty(cx, global, "x", &hasProp));
     CHECK(hasProp);
 
     // Now do the same thing, but without JSOPTION_VAROBJFIX
     JS::ContextOptionsRef(cx).setVarObjFix(false);
 
     static const char src2[] = "var y = 5;";
 
-    CHECK(JS_EvaluateScript(cx, obj, src2, sizeof(src2) - 1, __FILE__, __LINE__,
-                            retval.address()));
+    CHECK(JS_EvaluateScript(cx, obj, src2, sizeof(src2) - 1, __FILE__, __LINE__, &retval));
 
     hasProp = false;
     CHECK(JS_AlreadyHasOwnProperty(cx, obj, "y", &hasProp));
     CHECK(hasProp);
 
     hasProp = true;
     CHECK(JS_AlreadyHasOwnProperty(cx, global, "y", &hasProp));
     CHECK(!hasProp);
--- a/js/src/jsapi-tests/testOriginPrincipals.cpp
+++ b/js/src/jsapi-tests/testOriginPrincipals.cpp
@@ -64,17 +64,17 @@ eval(const char *asciiChars, JSPrincipal
     JSAutoCompartment ac(cx, global);
     CHECK(JS_InitStandardClasses(cx, global));
 
 
     JS::CompileOptions options(cx);
     options.setOriginPrincipals(originPrincipals)
            .setFileAndLine("", 0);
 
-    bool ok = JS::Evaluate(cx, global, options, chars, len, rval.address());
+    bool ok = JS::Evaluate(cx, global, options, chars, len, rval);
 
     delete[] chars;
     return ok;
 }
 
 bool
 testOuter(const char *asciiChars)
 {
--- a/js/src/jsapi-tests/testScriptObject.cpp
+++ b/js/src/jsapi-tests/testScriptObject.cpp
@@ -22,17 +22,17 @@ struct ScriptObjectFixture : public JSAP
     {
         JS::RootedScript script(cx, scriptArg);
         CHECK(script);
 
         JS_GC(rt);
 
         /* After a garbage collection, the script should still work. */
         JS::RootedValue result(cx);
-        CHECK(JS_ExecuteScript(cx, global, script, result.address()));
+        CHECK(JS_ExecuteScript(cx, global, script, &result));
 
         return true;
     }
 };
 
 const char ScriptObjectFixture::code[] =
     "(function(a, b){return a+' '+b;}('hello', 'world'))";
 const int ScriptObjectFixture::code_size = sizeof(ScriptObjectFixture::code) - 1;
--- a/js/src/jsapi-tests/testSourcePolicy.cpp
+++ b/js/src/jsapi-tests/testSourcePolicy.cpp
@@ -11,32 +11,32 @@ BEGIN_TEST(testBug795104)
     JS::CompileOptions opts(cx);
     opts.setSourcePolicy(JS::CompileOptions::NO_SOURCE);
     const size_t strLen = 60002;
     char *s = static_cast<char *>(JS_malloc(cx, strLen));
     CHECK(s);
     s[0] = '"';
     memset(s + 1, 'x', strLen - 2);
     s[strLen - 1] = '"';
-    CHECK(JS::Evaluate(cx, global, opts, s, strLen, nullptr));
+    CHECK(JS::Evaluate(cx, global, opts, s, strLen));
     CHECK(JS::CompileFunction(cx, global, opts, "f", 0, nullptr, s, strLen));
     JS_free(cx, s);
 
     return true;
 }
 END_TEST(testBug795104)
 
 static const char *const simpleSource = "var x = 4;";
 
 BEGIN_TEST(testScriptSourceReentrant)
 {
     JS::CompileOptions opts(cx);
     bool match = false;
     JS_SetNewScriptHook(rt, NewScriptHook, &match);
-    CHECK(JS::Evaluate(cx, global, opts, simpleSource, strlen(simpleSource), nullptr));
+    CHECK(JS::Evaluate(cx, global, opts, simpleSource, strlen(simpleSource)));
     CHECK(match);
     JS_SetNewScriptHook(rt, nullptr, nullptr);
 
     return true;
 }
 
 static void
 NewScriptHook(JSContext *cx, const char *fn, unsigned lineno,
--- a/js/src/jsapi-tests/testTrap.cpp
+++ b/js/src/jsapi-tests/testTrap.cpp
@@ -37,17 +37,17 @@ BEGIN_TEST(testTrap_gc)
     JS::CompileOptions options(cx);
     options.setFileAndLine(__FILE__, 1);
     JS::RootedScript script(cx, JS_CompileScript(cx, global, source,
                                                  strlen(source), options));
     CHECK(script);
 
     // execute
     JS::RootedValue v2(cx);
-    CHECK(JS_ExecuteScript(cx, global, script, v2.address()));
+    CHECK(JS_ExecuteScript(cx, global, script, &v2));
     CHECK(v2.isObject());
     CHECK_EQUAL(emptyTrapCallCount, 0);
 
     // Enable debug mode
     CHECK(JS_SetDebugMode(cx, true));
 
     static const char trapClosureText[] = "some trap closure";
 
@@ -68,17 +68,17 @@ BEGIN_TEST(testTrap_gc)
         JS_SetTrap(cx, script, line6, EmptyTrapHandler, closureValue);
 
         JS_GC(rt);
 
         CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
     }
 
     // execute
-    CHECK(JS_ExecuteScript(cx, global, script, v2.address()));
+    CHECK(JS_ExecuteScript(cx, global, script, &v2));
     CHECK_EQUAL(emptyTrapCallCount, 11);
 
     JS_GC(rt);
 
     CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
 
     return true;
 }
--- a/js/src/jsapi-tests/testXDR.cpp
+++ b/js/src/jsapi-tests/testXDR.cpp
@@ -131,17 +131,17 @@ JSScript *createScriptViaXDR(JSPrincipal
         script = FreezeThaw(cx, script);
         if (!script)
             return nullptr;
         if (testCase == TEST_SCRIPT)
             return script;
     }
 
     JS::RootedValue v(cx);
-    bool ok = JS_ExecuteScript(cx, global, script, v.address());
+    bool ok = JS_ExecuteScript(cx, global, script, &v);
     if (!ok || !v.isObject())
         return nullptr;
     JS::RootedObject funobj(cx, &v.toObject());
     if (testCase == TEST_FUNCTION) {
         funobj = FreezeThaw(cx, funobj);
         if (!funobj)
             return nullptr;
     }
@@ -167,17 +167,17 @@ BEGIN_TEST(testXDR_bug506491)
                                                  options));
     CHECK(script);
 
     script = FreezeThaw(cx, script);
     CHECK(script);
 
     // execute
     JS::RootedValue v2(cx);
-    CHECK(JS_ExecuteScript(cx, global, script, v2.address()));
+    CHECK(JS_ExecuteScript(cx, global, script, &v2));
 
     // try to break the Block object that is the parent of f
     JS_GC(rt);
 
     // confirm
     EVAL("f() === 'ok';\n", &v2);
     JS::RootedValue trueval(cx, JSVAL_TRUE);
     CHECK_SAME(v2, trueval);
@@ -192,17 +192,17 @@ BEGIN_TEST(testXDR_bug516827)
     options.setFileAndLine(__FILE__, __LINE__);
     JS::RootedScript script(cx, JS_CompileScript(cx, global, "", 0, options));
     CHECK(script);
 
     script = FreezeThaw(cx, script);
     CHECK(script);
 
     // execute with null result meaning no result wanted
-    CHECK(JS_ExecuteScript(cx, global, script, nullptr));
+    CHECK(JS_ExecuteScript(cx, global, script));
     return true;
 }
 END_TEST(testXDR_bug516827)
 
 BEGIN_TEST(testXDR_source)
 {
     const char *samples[] = {
         // This can't possibly fail to compress well, can it?
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -27,25 +27,25 @@ bool JSAPITest::init()
     JS_EnterCompartment(cx, global);
     return true;
 }
 
 bool JSAPITest::exec(const char *bytes, const char *filename, int lineno)
 {
     JS::RootedValue v(cx);
     JS::HandleObject global = JS::HandleObject::fromMarkedLocation(&this->global);
-    return JS_EvaluateScript(cx, global, bytes, strlen(bytes), filename, lineno, v.address()) ||
+    return JS_EvaluateScript(cx, global, bytes, strlen(bytes), filename, lineno, &v) ||
         fail(bytes, filename, lineno);
 }
 
 bool JSAPITest::evaluate(const char *bytes, const char *filename, int lineno,
                          JS::MutableHandleValue vp)
 {
     JS::HandleObject global = JS::HandleObject::fromMarkedLocation(&this->global);
-    return JS_EvaluateScript(cx, global, bytes, strlen(bytes), filename, lineno, vp.address()) ||
+    return JS_EvaluateScript(cx, global, bytes, strlen(bytes), filename, lineno, vp) ||
         fail(bytes, filename, lineno);
 }
 
 bool JSAPITest::definePrint()
 {
     JS::HandleObject global = JS::HandleObject::fromMarkedLocation(&this->global);
     return JS_DefineFunction(cx, global, "print", (JSNative) print, 0, 0);
 }
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4707,18 +4707,18 @@ JS_DecompileFunctionBody(JSContext *cx, 
 {
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, fun);
     return FunctionToString(cx, fun, true, !(indent & JS_DONT_PRETTY_PRINT));
 }
 
-MOZ_NEVER_INLINE JS_PUBLIC_API(bool)
-JS_ExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptArg, jsval *rval)
+MOZ_NEVER_INLINE static bool
+ExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptArg, jsval *rval)
 {
     RootedScript script(cx, scriptArg);
 
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     if (cx->compartment() != obj->compartment())
@@ -4739,28 +4739,46 @@ JS_ExecuteScript(JSContext *cx, HandleOb
             return false;
     } else {
         script = scriptArg;
     }
 
     return Execute(cx, script, *obj, rval);
 }
 
+MOZ_NEVER_INLINE JS_PUBLIC_API(bool)
+JS_ExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptArg, MutableHandleValue rval)
+{
+    return ExecuteScript(cx, obj, scriptArg, rval.address());
+}
+
+MOZ_NEVER_INLINE JS_PUBLIC_API(bool)
+JS_ExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptArg)
+{
+    return ExecuteScript(cx, obj, scriptArg, nullptr);
+}
+
 JS_PUBLIC_API(bool)
-JS_ExecuteScriptVersion(JSContext *cx, HandleObject obj, HandleScript script, jsval *rval,
-                        JSVersion version)
-{
-    return JS_ExecuteScript(cx, obj, script, rval);
+JS_ExecuteScriptVersion(JSContext *cx, HandleObject obj, HandleScript script,
+                        MutableHandleValue rval, JSVersion version)
+{
+    return ExecuteScript(cx, obj, script, rval.address());
+}
+
+JS_PUBLIC_API(bool)
+JS_ExecuteScriptVersion(JSContext *cx, HandleObject obj, HandleScript script, JSVersion version)
+{
+    return ExecuteScript(cx, obj, script, nullptr);
 }
 
 static const unsigned LARGE_SCRIPT_LENGTH = 500*1024;
 
-extern JS_PUBLIC_API(bool)
-JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
-             const jschar *chars, size_t length, jsval *rval)
+static bool
+Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+         const jschar *chars, size_t length, JS::Value *rval)
 {
     CompileOptions options(cx, optionsArg);
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     AutoLastFrameCheck lfc(cx);
@@ -4783,73 +4801,125 @@ JS::Evaluate(JSContext *cx, HandleObject
     // After evaluation, the compiled script will not be run again.
     // script->ensureRanAnalysis allocated 1 analyze::Bytecode for every opcode
     // which for large scripts means significant memory. Perform a GC eagerly
     // to clear out this analysis data before anything happens to inhibit the
     // flushing of this memory (such as setting requestAnimationFrame).
     if (script->length() > LARGE_SCRIPT_LENGTH) {
         script = nullptr;
         PrepareZoneForGC(cx->zone());
-        GC(cx->runtime(), GC_NORMAL, gcreason::FINISH_LARGE_EVALUTE);
+        GC(cx->runtime(), GC_NORMAL, JS::gcreason::FINISH_LARGE_EVALUTE);
     }
 
     return result;
 }
 
-extern JS_PUBLIC_API(bool)
-JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
-             const char *bytes, size_t length, jsval *rval)
+static bool
+Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
+         const char *bytes, size_t length, JS::Value *rval)
 {
     jschar *chars;
     if (options.utf8)
-        chars = UTF8CharsToNewTwoByteCharsZ(cx, UTF8Chars(bytes, length), &length).get();
+        chars = UTF8CharsToNewTwoByteCharsZ(cx, JS::UTF8Chars(bytes, length), &length).get();
     else
         chars = InflateString(cx, bytes, &length);
     if (!chars)
         return false;
 
-    bool ok = Evaluate(cx, obj, options, chars, length, rval);
+    bool ok = ::Evaluate(cx, obj, options, chars, length, rval);
     js_free(chars);
     return ok;
 }
 
-extern JS_PUBLIC_API(bool)
-JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
-             const char *filename, jsval *rval)
+static bool
+Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+         const char *filename, JS::Value *rval)
 {
     FileContents buffer(cx);
     {
         AutoFile file;
         if (!file.open(cx, filename) || !file.readAll(cx, buffer))
             return false;
     }
 
     CompileOptions options(cx, optionsArg);
     options.setFileAndLine(filename, 1);
     return Evaluate(cx, obj, options, buffer.begin(), buffer.length(), rval);
 }
 
+extern JS_PUBLIC_API(bool)
+JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+             const jschar *chars, size_t length, MutableHandleValue rval)
+{
+    return ::Evaluate(cx, obj, optionsArg, chars, length, rval.address());
+}
+
+extern JS_PUBLIC_API(bool)
+JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
+             const char *bytes, size_t length, MutableHandleValue rval)
+{
+    return ::Evaluate(cx, obj, options, bytes, length, rval.address());
+}
+
+extern JS_PUBLIC_API(bool)
+JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+             const char *filename, MutableHandleValue rval)
+{
+    return ::Evaluate(cx, obj, optionsArg, filename, rval.address());
+}
+
+extern JS_PUBLIC_API(bool)
+JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+             const jschar *chars, size_t length)
+{
+    return ::Evaluate(cx, obj, optionsArg, chars, length, nullptr);
+}
+
+extern JS_PUBLIC_API(bool)
+JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
+             const char *bytes, size_t length)
+{
+    return ::Evaluate(cx, obj, options, bytes, length, nullptr);
+}
+
+extern JS_PUBLIC_API(bool)
+JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+             const char *filename)
+{
+    return ::Evaluate(cx, obj, optionsArg, filename, nullptr);
+}
+
 JS_PUBLIC_API(bool)
 JS_EvaluateUCScript(JSContext *cx, HandleObject obj, const jschar *chars, unsigned length,
                     const char *filename, unsigned lineno, MutableHandleValue rval)
 {
     CompileOptions options(cx);
     options.setFileAndLine(filename, lineno);
 
-    return Evaluate(cx, obj, options, chars, length, rval.address());
+    return ::Evaluate(cx, obj, options, chars, length, rval.address());
 }
 
 JS_PUBLIC_API(bool)
 JS_EvaluateScript(JSContext *cx, HandleObject obj, const char *bytes, unsigned nbytes,
-                  const char *filename, unsigned lineno, jsval *rval)
+                  const char *filename, unsigned lineno, MutableHandleValue rval)
 {
     CompileOptions options(cx);
     options.setFileAndLine(filename, lineno);
 
-    return Evaluate(cx, obj, options, bytes, nbytes, rval);
+    return ::Evaluate(cx, obj, options, bytes, nbytes, rval.address());
+}
+
+JS_PUBLIC_API(bool)
+JS_EvaluateScript(JSContext *cx, HandleObject obj, const char *bytes, unsigned nbytes,
+                  const char *filename, unsigned lineno)
+{
+    CompileOptions options(cx);
+    options.setFileAndLine(filename, lineno);
+
+    return ::Evaluate(cx, obj, options, bytes, nbytes, nullptr);
 }
 
 JS_PUBLIC_API(bool)
 JS_CallFunction(JSContext *cx, HandleObject obj, HandleFunction fun, const HandleValueArray& args,
                 MutableHandleValue rval)
 {
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3697,47 +3697,71 @@ JS_DecompileFunctionBody(JSContext *cx, 
  * points with signatures matching the following six, and that doesn't seem
  * worth the code bloat cost.  Such new entry points would probably have less
  * obvious names, too, so would not tend to be used.  The JS_SetOption call,
  * OTOH, can be more easily hacked into existing code that does not depend on
  * the bug; such code can continue to use the familiar JS_EvaluateScript,
  * etc., entry points.
  */
 extern JS_PUBLIC_API(bool)
-JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script, jsval *rval);
+JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script, JS::MutableHandleValue rval);
+
+extern JS_PUBLIC_API(bool)
+JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script);
 
 extern JS_PUBLIC_API(bool)
-JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script, jsval *rval,
+JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script,
+                        JS::MutableHandleValue rval, JSVersion version);
+
+extern JS_PUBLIC_API(bool)
+JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script,
                         JSVersion version);
 
 extern JS_PUBLIC_API(bool)
 JS_EvaluateScript(JSContext *cx, JS::HandleObject obj,
                   const char *bytes, unsigned length,
                   const char *filename, unsigned lineno,
-                  jsval *rval);
+                  JS::MutableHandleValue rval);
+
+extern JS_PUBLIC_API(bool)
+JS_EvaluateScript(JSContext *cx, JS::HandleObject obj,
+                  const char *bytes, unsigned length,
+                  const char *filename, unsigned lineno);
 
 extern JS_PUBLIC_API(bool)
 JS_EvaluateUCScript(JSContext *cx, JS::Handle<JSObject*> obj,
                     const jschar *chars, unsigned length,
                     const char *filename, unsigned lineno,
                     JS::MutableHandle<JS::Value> rval);
 
 namespace JS {
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-         const jschar *chars, size_t length, jsval *rval);
+         const jschar *chars, size_t length, JS::MutableHandleValue rval);
+
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
+         const char *bytes, size_t length, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-         const char *bytes, size_t length, jsval *rval);
+         const char *filename, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-         const char *filename, jsval *rval);
+         const jschar *chars, size_t length);
+
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
+         const char *bytes, size_t length);
+
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
+         const char *filename);
 
 } /* namespace JS */
 
 extern JS_PUBLIC_API(bool)
 JS_CallFunction(JSContext *cx, JS::HandleObject obj, JS::HandleFunction fun,
                 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -448,17 +448,17 @@ RunFile(JSContext *cx, Handle<JSObject*>
         JS_ASSERT_IF(!script, gGotError);
     }
 
     #ifdef DEBUG
         if (dumpEntrainedVariables)
             AnalyzeEntrainedVariables(cx, script);
     #endif
     if (script && !compileOnly) {
-        if (!JS_ExecuteScript(cx, obj, script, nullptr)) {
+        if (!JS_ExecuteScript(cx, obj, script)) {
             if (!gQuitting && !gTimedOut)
                 gExitCode = EXITCODE_RUNTIME_ERROR;
         }
         int64_t t2 = PRMJ_Now() - t1;
         if (printTiming)
             printf("runtime = %.3f ms\n", double(t2) / PRMJ_USEC_PER_MSEC);
     }
 }
@@ -475,17 +475,17 @@ EvalAndPrint(JSContext *cx, Handle<JSObj
            .setFileAndLine("typein", lineno);
     RootedScript script(cx);
     script = JS::Compile(cx, global, options, bytes, length);
     if (!script)
         return false;
     if (compileOnly)
         return true;
     RootedValue result(cx);
-    if (!JS_ExecuteScript(cx, global, script, result.address()))
+    if (!JS_ExecuteScript(cx, global, script, &result))
         return false;
 
     if (!result.isUndefined()) {
         // Print.
         RootedString str(cx);
         str = JS_ValueToSource(cx, result);
         if (!str)
             return false;
@@ -785,17 +785,17 @@ LoadScript(JSContext *cx, unsigned argc,
             return false;
         errno = 0;
         CompileOptions opts(cx);
         opts.setIntroductionType("js shell load")
             .setUTF8(true)
             .setCompileAndGo(true)
             .setNoScriptRval(true);
         if ((compileOnly && !Compile(cx, thisobj, opts, filename.ptr())) ||
-            !Evaluate(cx, thisobj, opts, filename.ptr(), nullptr))
+            !Evaluate(cx, thisobj, opts, filename.ptr()))
         {
             return false;
         }
     }
 
     args.rval().setUndefined();
     return true;
 }
@@ -1237,17 +1237,17 @@ Evaluate(JSContext *cx, unsigned argc, j
         }
         if (sourceMapURL && !script->scriptSource()->hasSourceMapURL()) {
             const jschar *smurl = JS_GetStringCharsZ(cx, sourceMapURL);
             if (!smurl)
                 return false;
             if (!script->scriptSource()->setSourceMapURL(cx, smurl))
                 return false;
         }
-        if (!JS_ExecuteScript(cx, global, script, vp)) {
+        if (!JS_ExecuteScript(cx, global, script, args.rval())) {
             if (catchTermination && !JS_IsExceptionPending(cx)) {
                 JSAutoCompartment ac1(cx, callerGlobal);
                 JSString *str = JS_NewStringCopyZ(cx, "terminated");
                 if (!str)
                     return false;
                 args.rval().setString(str);
                 return true;
             }
@@ -1409,17 +1409,17 @@ Run(JSContext *cx, unsigned argc, jsval 
         options.setIntroductionType("js shell run")
                .setFileAndLine(filename.ptr(), 1)
                .setCompileAndGo(true);
         script = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, options);
         if (!script)
             return false;
     }
 
-    if (!JS_ExecuteScript(cx, thisobj, script, nullptr))
+    if (!JS_ExecuteScript(cx, thisobj, script))
         return false;
 
     int64_t endClock = PRMJ_Now();
 
     args.rval().setDouble((endClock - startClock) / double(PRMJ_USEC_PER_MSEC));
     return true;
 }
 
@@ -2876,17 +2876,17 @@ WorkerMain(void *arg)
         options.setFileAndLine("<string>", 1)
                .setCompileAndGo(true);
 
         RootedScript script(cx, JS::Compile(cx, global, options,
                                             input->chars, input->length));
         if (!script)
             break;
         RootedValue result(cx);
-        JS_ExecuteScript(cx, global, script, result.address());
+        JS_ExecuteScript(cx, global, script, &result);
     } while (0);
 
     DestroyContext(cx, false);
     JS_DestroyRuntime(rt);
 
     js_delete(input);
 }
 
@@ -3690,17 +3690,17 @@ runOffThreadScript(JSContext *cx, unsign
         JS_ReportError(cx, "called runOffThreadScript when no compilation is pending");
         return false;
     }
 
     RootedScript script(cx, JS::FinishOffThreadScript(cx, cx->runtime(), token));
     if (!script)
         return false;
 
-    return JS_ExecuteScript(cx, cx->global(), script, args.rval().address());
+    return JS_ExecuteScript(cx, cx->global(), script, args.rval());
 }
 
 #endif // JS_THREADSAFE
 
 struct FreeOnReturn
 {
     JSContext *cx;
     const char *ptr;
@@ -5717,17 +5717,17 @@ ProcessArgs(JSContext *cx, JSObject *obj
             char *path = filePaths.front();
             Process(cx, obj, path, false);
             if (gExitCode)
                 return gExitCode;
             filePaths.popFront();
         } else {
             const char *code = codeChunks.front();
             RootedValue rval(cx);
-            if (!JS_EvaluateScript(cx, obj, code, strlen(code), "-e", 1, rval.address()))
+            if (!JS_EvaluateScript(cx, obj, code, strlen(code), "-e", 1, &rval))
                 return gExitCode ? gExitCode : EXITCODE_RUNTIME_ERROR;
             codeChunks.popFront();
         }
     }
 
     /* The |script| argument is processed after all options. */
     if (const char *path = op->getStringArg("script")) {
         Process(cx, obj, path, false);
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -938,17 +938,17 @@ JSRuntime::initSelfHosting(JSContext *cx
                                       reinterpret_cast<unsigned char *>(src.get()), srcLen))
         {
             return false;
         }
 #else
         const char *src = rawSources;
 #endif
 
-        ok = Evaluate(cx, shg, options, src, srcLen, rv.address());
+        ok = Evaluate(cx, shg, options, src, srcLen, &rv);
     }
     JS_SetErrorReporter(cx, oldReporter);
     if (receivesDefaultObject)
         js::SetDefaultObjectForContext(cx, savedGlobal);
     return ok;
 }
 
 void
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -1018,17 +1018,17 @@ mozJSComponentLoader::ObjectForLocation(
     mThisObjects.Put(tableScript, obj);
     bool ok = false;
 
     {
         AutoSaveContextOptions asco(cx);
         if (aPropagateExceptions)
             ContextOptionsRef(cx).setDontReportUncaught(true);
         if (script) {
-            ok = JS_ExecuteScriptVersion(cx, obj, script, nullptr, JSVERSION_LATEST);
+            ok = JS_ExecuteScriptVersion(cx, obj, script, JSVERSION_LATEST);
         } else {
             RootedValue rval(cx);
             ok = JS_CallFunction(cx, obj, function, JS::HandleValueArray::empty(), &rval);
         }
      }
 
     if (!ok) {
         if (aPropagateExceptions) {
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -345,17 +345,17 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
     loader->NoteSubScript(script, targetObj);
 
 
     bool ok = false;
     if (function) {
         ok = JS_CallFunction(cx, targetObj, function, JS::HandleValueArray::empty(),
                              retval);
     } else {
-        ok = JS_ExecuteScriptVersion(cx, targetObj, script, retval.address(), version);
+        ok = JS_ExecuteScriptVersion(cx, targetObj, script, retval, version);
     }
 
     if (ok) {
         JSAutoCompartment rac(cx, result_obj);
         if (!JS_WrapValue(cx, retval))
             return NS_ERROR_UNEXPECTED;
     }
 
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -531,17 +531,17 @@ EvalInWindow(JSContext *cx, const nsAStr
         nsJSUtils::EvaluateOptions evaluateOptions;
         evaluateOptions.setReportUncaught(false);
 
         nsresult rv = nsJSUtils::EvaluateString(wndCx,
                                                 source,
                                                 targetScope,
                                                 compileOptions,
                                                 evaluateOptions,
-                                                rval.address());
+                                                rval);
 
         if (NS_FAILED(rv)) {
             // If there was an exception we get it as a return value, if
             // the evaluation failed for some other reason, then a default
             // exception is raised.
             MOZ_ASSERT(!JS_IsExceptionPending(wndCx),
                        "Exception should be delivered as return value.");
             if (rval.isUndefined()) {
@@ -1716,18 +1716,17 @@ xpc::EvalInSandbox(JSContext *cx, Handle
         JSAutoCompartment ac(sandcx, sandbox);
 
         JS::CompileOptions options(sandcx);
         options.setFileAndLine(filenameBuf.get(), lineNo);
         if (jsVersion != JSVERSION_DEFAULT)
                options.setVersion(jsVersion);
         JS::RootedObject rootedSandbox(sandcx, sandbox);
         ok = JS::Evaluate(sandcx, rootedSandbox, options,
-                          PromiseFlatString(source).get(), source.Length(),
-                          v.address());
+                          PromiseFlatString(source).get(), source.Length(), &v);
         if (ok && returnStringOnly && !v.isUndefined()) {
             JSString *str = ToString(sandcx, v);
             ok = !!str;
             v = ok ? JS::StringValue(str) : JS::UndefinedValue();
         }
 
         // If the sandbox threw an exception, grab it off the context.
         if (JS_GetPendingException(sandcx, &exn)) {
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -339,18 +339,17 @@ Load(JSContext *cx, unsigned argc, jsval
         JS::CompileOptions options(cx);
         options.setUTF8(true)
                .setFileAndLine(filename.ptr(), 1);
         JS::Rooted<JSScript*> script(cx, JS::Compile(cx, obj, options, file));
         fclose(file);
         if (!script)
             return false;
 
-        JS::Rooted<JS::Value> result(cx);
-        if (!compileOnly && !JS_ExecuteScript(cx, obj, script, result.address()))
+        if (!compileOnly && !JS_ExecuteScript(cx, obj, script))
             return false;
     }
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 Version(JSContext *cx, unsigned argc, jsval *vp)
@@ -923,17 +922,17 @@ ProcessFile(JSContext *cx, JS::Handle<JS
         ungetc(ch, file);
         DoBeginRequest(cx);
 
         JS::CompileOptions options(cx);
         options.setUTF8(true)
                .setFileAndLine(filename, 1);
         script = JS::Compile(cx, obj, options, file);
         if (script && !compileOnly)
-            (void)JS_ExecuteScript(cx, obj, script, result.address());
+            (void)JS_ExecuteScript(cx, obj, script, &result);
         DoEndRequest(cx);
 
         return;
     }
 
     /* It's an interactive filehandle; drop into read-eval-print loop. */
     lineno = 1;
     hitEOF = false;
@@ -962,17 +961,17 @@ ProcessFile(JSContext *cx, JS::Handle<JS
         JS_ClearPendingException(cx);
         JS::CompileOptions options(cx);
         options.setFileAndLine("typein", startline);
         script = JS_CompileScript(cx, obj, buffer, strlen(buffer), options);
         if (script) {
             JSErrorReporter older;
 
             if (!compileOnly) {
-                ok = JS_ExecuteScript(cx, obj, script, result.address());
+                ok = JS_ExecuteScript(cx, obj, script, &result);
                 if (ok && result != JSVAL_VOID) {
                     /* Suppress error reports from JS::ToString(). */
                     older = JS_SetErrorReporter(cx, nullptr);
                     str = ToString(cx, result);
                     JS_SetErrorReporter(cx, older);
                     JSAutoByteString bytes;
                     if (str && bytes.encodeLatin1(cx, str))
                         fprintf(gOutFile, "%s\n", bytes.ptr());
@@ -1149,18 +1148,17 @@ ProcessArgs(JSContext *cx, JS::Handle<JS
         case 'e':
         {
             RootedValue rval(cx);
 
             if (++i == argc) {
                 return usage();
             }
 
-            JS_EvaluateScript(cx, obj, argv[i], strlen(argv[i]), "-e", 1,
-                              rval.address());
+            JS_EvaluateScript(cx, obj, argv[i], strlen(argv[i]), "-e", 1, &rval);
 
             isInteractive = false;
             break;
         }
         case 'C':
             compileOnly = true;
             isInteractive = false;
             break;
--- a/netwerk/base/src/ProxyAutoConfig.cpp
+++ b/netwerk/base/src/ProxyAutoConfig.cpp
@@ -629,17 +629,17 @@ ProxyAutoConfig::SetupJS()
   bool isDataURI = nsDependentCSubstring(mPACURI, 0, 5).LowerCaseEqualsASCII("data:", 5);
 
   sRunning = this;
   JS::Rooted<JSObject*> global(cx, mJSRuntime->Global());
   JS::CompileOptions options(cx);
   options.setFileAndLine(mPACURI.get(), 1);
   JS::Rooted<JSScript*> script(cx, JS_CompileScript(cx, global, mPACScript.get(),
                                                     mPACScript.Length(), options));
-  if (!script || !JS_ExecuteScript(cx, global, script, nullptr)) {
+  if (!script || !JS_ExecuteScript(cx, global, script)) {
     nsString alertMessage(NS_LITERAL_STRING("PAC file failed to install from "));
     if (isDataURI) {
       alertMessage += NS_LITERAL_STRING("data: URI");
     }
     else {
       alertMessage += NS_ConvertUTF8toUTF16(mPACURI);
     }
     PACLogToConsole(alertMessage);
--- a/security/manager/ssl/src/nsCrypto.cpp
+++ b/security/manager/ssl/src/nsCrypto.cpp
@@ -2195,17 +2195,17 @@ nsCryptoRunnable::Run()
   nsNSSShutDownPreventionLock locker;
   AutoPushJSContext cx(m_args->m_cx);
   JSAutoRequest ar(cx);
   JS::Rooted<JSObject*> scope(cx, m_args->m_scope);
   JSAutoCompartment ac(cx, scope);
 
   bool ok =
     JS_EvaluateScript(cx, scope, m_args->m_jsCallback,
-                      strlen(m_args->m_jsCallback), nullptr, 0, nullptr);
+                      strlen(m_args->m_jsCallback), nullptr, 0);
   return ok ? NS_OK : NS_ERROR_FAILURE;
 }
 
 //Quick helper function to check if a newly issued cert
 //already exists in the user's database.
 static bool
 nsCertAlreadyExists(SECItem *derCert)
 {