--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -19,16 +19,17 @@
#include "jsapi.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIComponentManager.h"
#include "mozilla/Module.h"
#include "nsIFile.h"
#include "mozJSComponentLoader.h"
#include "mozJSLoaderUtils.h"
+#include "ScriptPreloader.h"
#include "nsIXPConnect.h"
#include "nsIObserverService.h"
#include "nsIScriptSecurityManager.h"
#include "nsIFileURL.h"
#include "nsIJARURI.h"
#include "nsNetUtil.h"
#include "jsprf.h"
#include "nsJSPrincipals.h"
@@ -680,17 +681,20 @@ mozJSComponentLoader::ObjectForLocation(
StartupCache* cache = StartupCache::GetSingleton();
nsAutoCString cachePath(kJSCachePrefix);
rv = PathifyURI(aInfo.URI(), cachePath);
NS_ENSURE_SUCCESS(rv, rv);
if (cache) {
if (!mReuseLoaderGlobal) {
- rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
+ script = ScriptPreloader::GetSingleton().GetCachedScript(cx, cachePath);
+ if (!script) {
+ rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
+ }
} else {
rv = ReadCachedFunction(cache, cachePath, cx, mSystemPrincipal,
function.address());
}
if (NS_SUCCEEDED(rv)) {
LOG(("Successfully loaded %s from startupcache\n", nativePath.get()));
} else {
@@ -844,16 +848,20 @@ mozJSComponentLoader::ObjectForLocation(
}
// We must have a script or a function (but not both!) here. We have a
// script when we're not reusing the loader global, and a function
// otherwise.
MOZ_ASSERT(!!script != !!function);
MOZ_ASSERT(!!script == JS_IsGlobalObject(obj));
+ if (script) {
+ ScriptPreloader::GetSingleton().NoteScript(nativePath, cachePath, script);
+ }
+
if (writeToCache) {
// We successfully compiled the script, so cache it.
if (script) {
rv = WriteCachedScript(cache, cachePath, cx, mSystemPrincipal,
script);
} else {
rv = WriteCachedFunction(cache, cachePath, cx, mSystemPrincipal,
function);
@@ -886,17 +894,18 @@ mozJSComponentLoader::ObjectForLocation(
// We're going to run script via JS_ExecuteScript or
// JS_CallFunction, so we need an AutoEntryScript.
// This is Gecko-specific and not in any spec.
dom::AutoEntryScript aes(CurrentGlobalOrNull(cx),
"component loader load module");
JSContext* aescx = aes.cx();
bool ok;
if (script) {
- ok = JS_ExecuteScript(aescx, script);
+ JS::RootedValue rval(cx);
+ ok = JS::CloneAndExecuteScript(aescx, script, &rval);
} else {
RootedValue rval(cx);
ok = JS_CallFunction(aescx, obj, function,
JS::HandleValueArray::empty(), &rval);
}
if (!ok) {
if (aPropagateExceptions && aes.HasException()) {
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -2,16 +2,17 @@
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozJSSubScriptLoader.h"
#include "mozJSComponentLoader.h"
#include "mozJSLoaderUtils.h"
+#include "ScriptPreloader.h"
#include "nsIURI.h"
#include "nsIIOService.h"
#include "nsIChannel.h"
#include "nsIInputStream.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsIFileURL.h"
@@ -188,50 +189,51 @@ PrepareScript(nsIURI* uri,
buf, len, function);
}
static bool
EvalScript(JSContext* cx,
HandleObject targetObj,
MutableHandleValue retval,
nsIURI* uri,
- bool cache,
+ bool startupCache,
+ bool preloadCache,
MutableHandleScript script,
HandleFunction function)
{
if (function) {
script.set(JS_GetFunctionScript(cx, function));
}
if (function) {
if (!JS_CallFunction(cx, targetObj, function, JS::HandleValueArray::empty(), retval)) {
return false;
}
} else {
if (JS_IsGlobalObject(targetObj)) {
- if (!JS_ExecuteScript(cx, script, retval)) {
+ if (!JS::CloneAndExecuteScript(cx, script, retval)) {
return false;
}
} else {
JS::AutoObjectVector envChain(cx);
if (!envChain.append(targetObj)) {
return false;
}
- if (!JS_ExecuteScript(cx, envChain, script, retval)) {
+ if (!JS::CloneAndExecuteScript(cx, envChain, script, retval)) {
return false;
}
}
}
JSAutoCompartment rac(cx, targetObj);
if (!JS_WrapValue(cx, retval)) {
return false;
}
- if (cache && !!script) {
+ if (script && (startupCache || preloadCache)) {
nsAutoCString cachePath;
JSVersion version = JS_GetVersion(cx);
cachePath.AppendPrintf("jssubloader/%d", version);
PathifyURI(uri, cachePath);
nsCOMPtr<nsIScriptSecurityManager> secman =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
if (!secman) {
@@ -240,18 +242,27 @@ EvalScript(JSContext* cx,
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = secman->GetSystemPrincipal(getter_AddRefs(principal));
if (NS_FAILED(rv) || !principal) {
ReportError(cx, LOAD_ERROR_NOPRINCIPALS, uri);
return false;
}
- WriteCachedScript(StartupCache::GetSingleton(),
- cachePath, cx, principal, script);
+ nsCString uriStr;
+ if (preloadCache && NS_SUCCEEDED(uri->GetSpec(uriStr))) {
+ ScriptPreloader::GetSingleton().NoteScript(uriStr, cachePath, script);
+ }
+
+ if (startupCache) {
+ JSAutoCompartment ac(cx, script);
+ WriteCachedScript(StartupCache::GetSingleton(),
+ cachePath, cx, principal, script);
+>>>>>>> histedit
+ }
}
return true;
}
class AsyncScriptLoader : public nsIIncrementalStreamLoaderObserver
{
public:
@@ -395,17 +406,19 @@ AsyncScriptLoader::OnStreamComplete(nsII
if (!PrepareScript(uri, cx, targetObj, spec.get(), mCharset,
reinterpret_cast<const char*>(aBuf), aLength,
mReuseGlobal, mWantReturnValue, &script, &function))
{
return NS_OK;
}
JS::Rooted<JS::Value> retval(cx);
- if (EvalScript(cx, targetObj, &retval, uri, mCache, &script, function)) {
+ if (EvalScript(cx, targetObj, &retval, uri, mCache,
+ mCache && !mWantReturnValue,
+ &script, function)) {
autoPromise.ResolvePromise(retval);
}
return NS_OK;
}
nsresult
mozJSSubScriptLoader::ReadScriptAsync(nsIURI* uri,
@@ -626,19 +639,19 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
if (!JS::DescribeScriptedCaller(cx, &filename)) {
// No scripted frame means we don't know who's calling, bail.
return NS_ERROR_FAILURE;
}
JSAutoCompartment ac(cx, targetObj);
// Suppress caching if we're compiling as content.
- StartupCache* cache = (principal == mSystemPrincipal)
- ? StartupCache::GetSingleton()
- : nullptr;
+ bool ignoreCache = options.ignoreCache || principal != mSystemPrincipal;
+ StartupCache* cache = ignoreCache ? nullptr : StartupCache::GetSingleton();
+
nsCOMPtr<nsIIOService> serv = do_GetService(NS_IOSERVICE_CONTRACTID);
if (!serv) {
ReportError(cx, NS_LITERAL_CSTRING(LOAD_ERROR_NOSERVICE));
return NS_OK;
}
// Make sure to explicitly create the URI, since we'll need the
// canonicalized spec.
@@ -681,18 +694,21 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
JSVersion version = JS_GetVersion(cx);
nsAutoCString cachePath;
cachePath.AppendPrintf("jssubloader/%d", version);
PathifyURI(uri, cachePath);
RootedFunction function(cx);
RootedScript script(cx);
if (cache && !options.ignoreCache) {
- rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
- if (NS_FAILED(rv)) {
+ if (!options.wantReturnValue)
+ script = ScriptPreloader::GetSingleton().GetCachedScript(cx, cachePath);
+ if (!script)
+ rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script);
+ if (NS_FAILED(rv) || !script) {
// ReadCachedScript may have set a pending exception.
JS_ClearPendingException(cx);
}
}
// If we are doing an async load, trigger it and bail out.
if (!script && options.async) {
return ReadScriptAsync(uri, targetObj, options.charset, serv,
@@ -707,17 +723,19 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
&function))
{
return NS_OK;
}
} else {
cache = nullptr;
}
- Unused << EvalScript(cx, targetObj, retval, uri, !!cache, &script, function);
+ Unused << EvalScript(cx, targetObj, retval, uri, !!cache,
+ !ignoreCache && !options.wantReturnValue,
+ &script, function);
return NS_OK;
}
/**
* Let us compile scripts from a URI off the main thread.
*/
class ScriptPrecompiler : public nsIIncrementalStreamLoaderObserver