--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -45,29 +45,32 @@ class MOZ_STACK_CLASS LoadSubScriptOptio
public:
explicit LoadSubScriptOptions(JSContext* cx = xpc_GetSafeJSContext(),
JSObject* options = nullptr)
: OptionsBase(cx, options)
, target(cx)
, charset(NullString())
, ignoreCache(false)
, async(false)
+ , wantReturnValue(false)
{ }
virtual bool Parse() {
return ParseObject("target", &target) &&
ParseString("charset", charset) &&
ParseBoolean("ignoreCache", &ignoreCache) &&
- ParseBoolean("async", &async);
+ ParseBoolean("async", &async) &&
+ ParseBoolean("wantReturnValue", &wantReturnValue);
}
RootedObject target;
nsString charset;
bool ignoreCache;
bool async;
+ bool wantReturnValue;
};
/* load() error msgs, XXX localize? */
#define LOAD_ERROR_NOSERVICE "Error creating IO Service."
#define LOAD_ERROR_NOURI "Error creating URI (invalid URL scheme?)"
#define LOAD_ERROR_NOSCHEME "Failed to get URI scheme. This is bad."
#define LOAD_ERROR_URI_NOT_LOCAL "Trying to load a non-local URI."
@@ -125,24 +128,26 @@ bool
PrepareScript(nsIURI* uri,
JSContext* cx,
RootedObject& targetObj,
const char* uriStr,
const nsAString& charset,
const char* buf,
int64_t len,
bool reuseGlobal,
+ bool wantReturnValue,
MutableHandleScript script,
MutableHandleFunction function)
{
JS::CompileOptions options(cx);
// Use line 0 to make the function body starts from line 1 when
// |reuseGlobal == true|.
options.setFileAndLine(uriStr, reuseGlobal ? 0 : 1)
- .setVersion(JSVERSION_LATEST);
+ .setVersion(JSVERSION_LATEST)
+ .setNoScriptRval(!wantReturnValue);
if (!charset.IsVoid()) {
char16_t* scriptBuf = nullptr;
size_t scriptLength = 0;
nsresult rv =
nsScriptLoader::ConvertToUTF16(nullptr, reinterpret_cast<const uint8_t*>(buf), len,
charset, nullptr, scriptBuf, scriptLength);
@@ -251,40 +256,42 @@ EvalScript(JSContext* cx,
class AsyncScriptLoader : public nsIIncrementalStreamLoaderObserver
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AsyncScriptLoader)
- AsyncScriptLoader(nsIChannel* aChannel, bool aReuseGlobal,
+ AsyncScriptLoader(nsIChannel* aChannel, bool aReuseGlobal, bool aWantReturnValue,
JSObject* aTargetObj, const nsAString& aCharset,
bool aCache, Promise* aPromise)
: mChannel(aChannel)
, mTargetObj(aTargetObj)
, mPromise(aPromise)
, mCharset(aCharset)
, mReuseGlobal(aReuseGlobal)
+ , mWantReturnValue(aWantReturnValue)
, mCache(aCache)
{
// Needed for the cycle collector to manage mTargetObj.
mozilla::HoldJSObjects(this);
}
private:
virtual ~AsyncScriptLoader() {
mozilla::DropJSObjects(this);
}
RefPtr<nsIChannel> mChannel;
Heap<JSObject*> mTargetObj;
RefPtr<Promise> mPromise;
nsString mCharset;
bool mReuseGlobal;
+ bool mWantReturnValue;
bool mCache;
};
NS_IMPL_CYCLE_COLLECTION_CLASS(AsyncScriptLoader)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AsyncScriptLoader)
NS_INTERFACE_MAP_ENTRY(nsIIncrementalStreamLoaderObserver)
NS_INTERFACE_MAP_END
@@ -383,33 +390,34 @@ AsyncScriptLoader::OnStreamComplete(nsII
nsAutoCString spec;
nsresult rv = uri->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
RootedObject target_obj(cx, mTargetObj);
if (!PrepareScript(uri, cx, target_obj, spec.get(), mCharset,
reinterpret_cast<const char*>(aBuf), aLength,
- mReuseGlobal, &script, &function))
+ mReuseGlobal, mWantReturnValue, &script, &function))
{
return NS_OK;
}
JS::Rooted<JS::Value> retval(cx);
if (EvalScript(cx, target_obj, &retval, uri, mCache, script, function)) {
autoPromise.ResolvePromise(retval);
}
return NS_OK;
}
nsresult
mozJSSubScriptLoader::ReadScriptAsync(nsIURI* uri, JSObject* targetObjArg,
const nsAString& charset,
nsIIOService* serv, bool reuseGlobal,
+ bool wantReturnValue,
bool cache, MutableHandleValue retval)
{
RootedObject target_obj(RootingCx(), targetObjArg);
nsCOMPtr<nsIGlobalObject> globalObject = xpc::NativeGlobal(target_obj);
ErrorResult result;
AutoJSAPI jsapi;
@@ -443,16 +451,17 @@ mozJSSubScriptLoader::ReadScriptAsync(ns
return rv;
}
channel->SetContentType(NS_LITERAL_CSTRING("application/javascript"));
RefPtr<AsyncScriptLoader> loadObserver =
new AsyncScriptLoader(channel,
reuseGlobal,
+ wantReturnValue,
target_obj,
charset,
cache,
promise);
nsCOMPtr<nsIIncrementalStreamLoader> loader;
rv = NS_NewIncrementalStreamLoader(getter_AddRefs(loader), loadObserver);
NS_ENSURE_SUCCESS(rv, rv);
@@ -460,17 +469,18 @@ mozJSSubScriptLoader::ReadScriptAsync(ns
nsCOMPtr<nsIStreamListener> listener = loader.get();
return channel->AsyncOpen2(listener);
}
bool
mozJSSubScriptLoader::ReadScript(nsIURI* uri, JSContext* cx, JSObject* targetObjArg,
const nsAString& charset, const char* uriStr,
nsIIOService* serv, nsIPrincipal* principal,
- bool reuseGlobal, JS::MutableHandleScript script,
+ bool reuseGlobal, bool wantReturnValue,
+ JS::MutableHandleScript script,
JS::MutableHandleFunction function)
{
script.set(nullptr);
function.set(nullptr);
RootedObject target_obj(cx, targetObjArg);
// We create a channel and call SetContentType, to avoid expensive MIME type
@@ -512,17 +522,17 @@ mozJSSubScriptLoader::ReadScript(nsIURI*
}
nsCString buf;
rv = NS_ReadInputStreamToString(instream, buf, len);
NS_ENSURE_SUCCESS(rv, false);
return PrepareScript(uri, cx, target_obj, uriStr, charset,
buf.get(), len,
- reuseGlobal,
+ reuseGlobal, wantReturnValue,
script, function);
}
NS_IMETHODIMP
mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
HandleValue target,
const nsAString& charset,
JSContext* cx,
@@ -679,23 +689,25 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
// 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,
- reusingGlobal, !!cache, retval);
+ reusingGlobal, options.wantReturnValue,
+ !!cache, retval);
}
if (!script) {
if (!ReadScript(uri, cx, targetObj, options.charset,
static_cast<const char*>(uriStr.get()), serv,
- principal, reusingGlobal, &script, &function))
+ principal, reusingGlobal, options.wantReturnValue,
+ &script, &function))
{
return NS_OK;
}
} else {
cache = nullptr;
}
Unused << EvalScript(cx, targetObj, retval, uri, !!cache, script, function);
--- a/js/xpconnect/loader/mozJSSubScriptLoader.h
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.h
@@ -31,23 +31,25 @@ public:
NS_DECL_MOZIJSSUBSCRIPTLOADER
private:
virtual ~mozJSSubScriptLoader();
bool ReadScript(nsIURI* uri, JSContext* cx, JSObject* target_obj,
const nsAString& charset, const char* uriStr,
nsIIOService* serv, nsIPrincipal* principal,
- bool reuseGlobal, JS::MutableHandleScript script,
+ bool reuseGlobal, bool wantReturnValue,
+ JS::MutableHandleScript script,
JS::MutableHandleFunction function);
nsresult ReadScriptAsync(nsIURI* uri, JSObject* target_obj,
const nsAString& charset,
nsIIOService* serv, bool reuseGlobal,
- bool cache, JS::MutableHandleValue retval);
+ bool wantReturnValue, bool cache,
+ JS::MutableHandleValue retval);
nsresult DoLoadSubScriptWithOptions(const nsAString& url,
LoadSubScriptOptions& options,
JSContext* cx,
JS::MutableHandle<JS::Value> retval);
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
};