diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 28935b21b253..d47e69528e68 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -6001,7 +6001,8 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout, nsresult rv; { nsJSUtils::ExecutionContext exec(aes.cx(), global); - rv = exec.CompileAndExec(options, script); + exec.Compile(options, script); + rv = exec.ExecScript(); } if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE) { diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp index 2d2691e9156e..df92b54a60a1 100644 --- a/dom/base/nsJSUtils.cpp +++ b/dom/base/nsJSUtils.cpp @@ -124,6 +124,7 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx, mRealm(aCx, aGlobal), mRetValue(aCx), mScopeChain(aCx), + mScript(aCx), mRv(NS_OK), mSkip(false), mCoerceToString(false), @@ -131,7 +132,8 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx, #ifdef DEBUG , mWantsReturnValue(false), - mExpectScopeChain(false) + mExpectScopeChain(false), + mScriptUsed(false) #endif { MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext()); @@ -174,30 +176,24 @@ void nsJSUtils::ExecutionContext::SetScopeChain( } } -nsresult nsJSUtils::ExecutionContext::JoinAndExec( - JS::OffThreadToken** aOffThreadToken, - JS::MutableHandle aScript) { +nsresult nsJSUtils::ExecutionContext::JoinCompile( + JS::OffThreadToken** aOffThreadToken) { if (mSkip) { return mRv; } MOZ_ASSERT(!mWantsReturnValue); MOZ_ASSERT(!mExpectScopeChain); - aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken)); + MOZ_ASSERT(!mScript); + mScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken)); *aOffThreadToken = nullptr; // Mark the token as having been finished. - if (!aScript) { + if (!mScript) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; } - if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) { - mSkip = true; - mRv = EvaluationExceptionToNSResult(mCx); - return mRv; - } - - if (!JS_ExecuteScript(mCx, mScopeChain, aScript)) { + if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; @@ -206,9 +202,8 @@ nsresult nsJSUtils::ExecutionContext::JoinAndExec( return NS_OK; } -nsresult nsJSUtils::ExecutionContext::CompileAndExec( - JS::CompileOptions& aCompileOptions, JS::SourceText& aSrcBuf, - JS::MutableHandle aScript) { +nsresult nsJSUtils::ExecutionContext::Compile( + JS::CompileOptions& aCompileOptions, JS::SourceText& aSrcBuf) { if (mSkip) { return mRv; } @@ -219,29 +214,23 @@ nsresult nsJSUtils::ExecutionContext::CompileAndExec( mWantsReturnValue = !aCompileOptions.noScriptRval; #endif + MOZ_ASSERT(!mScript); bool compiled = true; if (mScopeChain.length() == 0) { - compiled = JS::Compile(mCx, aCompileOptions, aSrcBuf, aScript); + compiled = JS::Compile(mCx, aCompileOptions, aSrcBuf, &mScript); } else { - compiled = - JS::CompileForNonSyntacticScope(mCx, aCompileOptions, aSrcBuf, aScript); + compiled = JS::CompileForNonSyntacticScope(mCx, aCompileOptions, aSrcBuf, + &mScript); } - MOZ_ASSERT_IF(compiled, aScript); + MOZ_ASSERT_IF(compiled, mScript); if (!compiled) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; } - if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) { - mSkip = true; - mRv = EvaluationExceptionToNSResult(mCx); - return mRv; - } - - MOZ_ASSERT(!mCoerceToString || mWantsReturnValue); - if (!JS_ExecuteScript(mCx, mScopeChain, aScript, &mRetValue)) { + if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; @@ -250,10 +239,8 @@ nsresult nsJSUtils::ExecutionContext::CompileAndExec( return NS_OK; } -nsresult nsJSUtils::ExecutionContext::CompileAndExec( +nsresult nsJSUtils::ExecutionContext::Compile( JS::CompileOptions& aCompileOptions, const nsAString& aScript) { - MOZ_ASSERT(!mEncodeBytecode, - "A JSScript is needed for calling FinishIncrementalEncoding"); if (mSkip) { return mRv; } @@ -267,23 +254,19 @@ nsresult nsJSUtils::ExecutionContext::CompileAndExec( return mRv; } - JS::Rooted script(mCx); - return CompileAndExec(aCompileOptions, srcBuf, &script); + return Compile(aCompileOptions, srcBuf); } -nsresult nsJSUtils::ExecutionContext::DecodeAndExec( +nsresult nsJSUtils::ExecutionContext::Decode( JS::CompileOptions& aCompileOptions, mozilla::Vector& aBytecodeBuf, size_t aBytecodeIndex) { - MOZ_ASSERT(!mEncodeBytecode, - "A JSScript is needed for calling FinishIncrementalEncoding"); if (mSkip) { return mRv; } MOZ_ASSERT(!mWantsReturnValue); - JS::Rooted script(mCx); JS::TranscodeResult tr = - JS::DecodeScript(mCx, aBytecodeBuf, &script, aBytecodeIndex); + JS::DecodeScript(mCx, aBytecodeBuf, &mScript, aBytecodeIndex); // These errors are external parameters which should be handled before the // decoding phase, and which are the only reasons why you might want to // fallback on decoding failures. @@ -295,16 +278,10 @@ nsresult nsJSUtils::ExecutionContext::DecodeAndExec( return mRv; } - if (!JS_ExecuteScript(mCx, mScopeChain, script)) { - mSkip = true; - mRv = EvaluationExceptionToNSResult(mCx); - return mRv; - } - return mRv; } -nsresult nsJSUtils::ExecutionContext::DecodeJoinAndExec( +nsresult nsJSUtils::ExecutionContext::JoinDecode( JS::OffThreadToken** aOffThreadToken) { if (mSkip) { return mRv; @@ -312,10 +289,9 @@ nsresult nsJSUtils::ExecutionContext::DecodeJoinAndExec( MOZ_ASSERT(!mWantsReturnValue); MOZ_ASSERT(!mExpectScopeChain); - JS::Rooted script(mCx); - script.set(JS::FinishOffThreadScriptDecoder(mCx, *aOffThreadToken)); + mScript.set(JS::FinishOffThreadScriptDecoder(mCx, *aOffThreadToken)); *aOffThreadToken = nullptr; // Mark the token as having been finished. - if (!script || !JS_ExecuteScript(mCx, mScopeChain, script)) { + if (!mScript) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; @@ -324,9 +300,8 @@ nsresult nsJSUtils::ExecutionContext::DecodeJoinAndExec( return NS_OK; } -nsresult nsJSUtils::ExecutionContext::DecodeBinASTJoinAndExec( - JS::OffThreadToken** aOffThreadToken, - JS::MutableHandle aScript) { +nsresult nsJSUtils::ExecutionContext::JoinDecodeBinAST( + JS::OffThreadToken** aOffThreadToken) { #ifdef JS_BUILD_BINAST if (mSkip) { return mRv; @@ -335,22 +310,16 @@ nsresult nsJSUtils::ExecutionContext::DecodeBinASTJoinAndExec( MOZ_ASSERT(!mWantsReturnValue); MOZ_ASSERT(!mExpectScopeChain); - aScript.set(JS::FinishOffThreadBinASTDecode(mCx, *aOffThreadToken)); + mScript.set(JS::FinishOffThreadBinASTDecode(mCx, *aOffThreadToken)); *aOffThreadToken = nullptr; // Mark the token as having been finished. - if (!aScript) { + if (!mScript) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; } - if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) { - mSkip = true; - mRv = EvaluationExceptionToNSResult(mCx); - return mRv; - } - - if (!JS_ExecuteScript(mCx, mScopeChain, aScript)) { + if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; @@ -362,9 +331,8 @@ nsresult nsJSUtils::ExecutionContext::DecodeBinASTJoinAndExec( #endif } -nsresult nsJSUtils::ExecutionContext::DecodeBinASTAndExec( - JS::CompileOptions& aCompileOptions, const uint8_t* aBuf, size_t aLength, - JS::MutableHandle aScript) { +nsresult nsJSUtils::ExecutionContext::DecodeBinAST( + JS::CompileOptions& aCompileOptions, const uint8_t* aBuf, size_t aLength) { #ifdef JS_BUILD_BINAST MOZ_ASSERT(mScopeChain.length() == 0, "BinAST decoding is not supported in non-syntactic scopes"); @@ -379,22 +347,15 @@ nsresult nsJSUtils::ExecutionContext::DecodeBinASTAndExec( mWantsReturnValue = !aCompileOptions.noScriptRval; #endif - aScript.set(JS::DecodeBinAST(mCx, aCompileOptions, aBuf, aLength)); + mScript.set(JS::DecodeBinAST(mCx, aCompileOptions, aBuf, aLength)); - if (!aScript) { + if (!mScript) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; } - if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) { - mSkip = true; - mRv = EvaluationExceptionToNSResult(mCx); - return mRv; - } - - MOZ_ASSERT(!mCoerceToString || mWantsReturnValue); - if (!JS_ExecuteScript(mCx, mScopeChain, aScript, &mRetValue)) { + if (mEncodeBytecode && !StartIncrementalEncoding(mCx, mScript)) { mSkip = true; mRv = EvaluationExceptionToNSResult(mCx); return mRv; @@ -406,6 +367,32 @@ nsresult nsJSUtils::ExecutionContext::DecodeBinASTAndExec( #endif } +JSScript* nsJSUtils::ExecutionContext::GetScript() { +#ifdef DEBUG + MOZ_ASSERT(!mSkip); + MOZ_ASSERT(mScript); + mScriptUsed = true; +#endif + + return mScript; +} + +nsresult nsJSUtils::ExecutionContext::ExecScript() { + if (mSkip) { + return mRv; + } + + MOZ_ASSERT(mScript); + + if (!JS_ExecuteScript(mCx, mScopeChain, mScript)) { + mSkip = true; + mRv = EvaluationExceptionToNSResult(mCx); + return mRv; + } + + return NS_OK; +} + static bool IsPromiseValue(JSContext* aCx, JS::Handle aValue) { if (!aValue.isObject()) { return false; @@ -419,43 +406,45 @@ static bool IsPromiseValue(JSContext* aCx, JS::Handle aValue) { return JS::IsPromiseObject(obj); } -nsresult nsJSUtils::ExecutionContext::ExtractReturnValue( +nsresult nsJSUtils::ExecutionContext::ExecScript( JS::MutableHandle aRetValue) { - MOZ_ASSERT(aRetValue.isUndefined()); if (mSkip) { - // Repeat earlier result, as NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW are not - // failures cases. -#ifdef DEBUG - mWantsReturnValue = false; -#endif + aRetValue.setUndefined(); return mRv; } + MOZ_ASSERT(mScript); MOZ_ASSERT(mWantsReturnValue); + + if (!JS_ExecuteScript(mCx, mScopeChain, mScript, aRetValue)) { + mSkip = true; + mRv = EvaluationExceptionToNSResult(mCx); + return mRv; + } + #ifdef DEBUG mWantsReturnValue = false; #endif - if (mCoerceToString && IsPromiseValue(mCx, mRetValue)) { + if (mCoerceToString && IsPromiseValue(mCx, aRetValue)) { // We're a javascript: url and we should treat Promise return values as // undefined. // // Once bug 1477821 is fixed this code might be able to go away, or will // become enshrined in the spec, depending. - mRetValue.setUndefined(); + aRetValue.setUndefined(); } - if (mCoerceToString && !mRetValue.isUndefined()) { - JSString* str = JS::ToString(mCx, mRetValue); + if (mCoerceToString && !aRetValue.isUndefined()) { + JSString* str = JS::ToString(mCx, aRetValue); if (!str) { // ToString can be a function call, so an exception can be raised while // executing the function. mSkip = true; return EvaluationExceptionToNSResult(mCx); } - mRetValue.set(JS::StringValue(str)); + aRetValue.set(JS::StringValue(str)); } - aRetValue.set(mRetValue); return NS_OK; } @@ -465,7 +454,6 @@ nsresult nsJSUtils::CompileModule(JSContext* aCx, JS::CompileOptions& aCompileOptions, JS::MutableHandle aModule) { AUTO_PROFILER_LABEL("nsJSUtils::CompileModule", JS); - MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext()); MOZ_ASSERT(aSrcBuf.get()); MOZ_ASSERT(JS_IsGlobalObject(aEvaluationGlobal)); diff --git a/dom/base/nsJSUtils.h b/dom/base/nsJSUtils.h index f2042e46aec4..f15ea9f335f1 100644 --- a/dom/base/nsJSUtils.h +++ b/dom/base/nsJSUtils.h @@ -81,6 +81,9 @@ class nsJSUtils { // Scope chain in which the execution takes place. JS::AutoObjectVector mScopeChain; + // The compiled script. + JS::Rooted mScript; + // returned value forwarded when we have to interupt the execution eagerly // with mSkip. nsresult mRv; @@ -100,6 +103,8 @@ class nsJSUtils { bool mWantsReturnValue; bool mExpectScopeChain; + + bool mScriptUsed; #endif public: @@ -111,8 +116,12 @@ class nsJSUtils { ExecutionContext(ExecutionContext&&) = delete; ~ExecutionContext() { - // This flag is resetted, when the returned value is extracted. - MOZ_ASSERT(!mWantsReturnValue); + // This flag is reset when the returned value is extracted. + MOZ_ASSERT_IF(!mSkip, !mWantsReturnValue); + + // If encoding was started we expect the script to have been + // used when ending the encoding. + MOZ_ASSERT_IF(mEncodeBytecode && mScript && mRv == NS_OK, mScriptUsed); } // The returned value would be converted to a string if the @@ -134,54 +143,53 @@ class nsJSUtils { // Set the scope chain in which the code should be executed. void SetScopeChain(const JS::AutoObjectVector& aScopeChain); - // Copy the returned value in the mutable handle argument, in case of a + // After getting a notification that an off-thread compilation terminated, + // this function will take the result of the parser and move it to the main + // thread. + MOZ_MUST_USE nsresult JoinCompile(JS::OffThreadToken** aOffThreadToken); + + // Compile a script contained in a SourceText. + nsresult Compile(JS::CompileOptions& aCompileOptions, + JS::SourceText& aSrcBuf); + + // Compile a script contained in a string. + nsresult Compile(JS::CompileOptions& aCompileOptions, + const nsAString& aScript); + + // Decode a script contained in a buffer. + nsresult Decode(JS::CompileOptions& aCompileOptions, + mozilla::Vector& aBytecodeBuf, + size_t aBytecodeIndex); + + // After getting a notification that an off-thread decoding terminated, this + // function will get the result of the decoder and move it to the main + // thread. + nsresult JoinDecode(JS::OffThreadToken** aOffThreadToken); + + nsresult JoinDecodeBinAST(JS::OffThreadToken** aOffThreadToken); + + // Decode a BinAST encoded script contained in a buffer. + nsresult DecodeBinAST(JS::CompileOptions& aCompileOptions, + const uint8_t* aBuf, size_t aLength); + + // Get a successfully compiled script. + JSScript* GetScript(); + + // Execute the compiled script and ignore the return value. + MOZ_MUST_USE nsresult ExecScript(); + + // Execute the compiled script a get the return value. + // + // Copy the returned value into the mutable handle argument. In case of a // evaluation failure either during the execution or the conversion of the - // result to a string, the nsresult would be set to the corresponding result - // code, and the mutable handle argument would remain unchanged. + // result to a string, the nsresult is be set to the corresponding result + // code and the mutable handle argument remains unchanged. // // The value returned in the mutable handle argument is part of the // compartment given as argument to the ExecutionContext constructor. If the // caller is in a different compartment, then the out-param value should be // wrapped by calling |JS_WrapValue|. - MOZ_MUST_USE nsresult - ExtractReturnValue(JS::MutableHandle aRetValue); - - // After getting a notification that an off-thread compilation terminated, - // this function will take the result of the parser by moving it to the main - // thread before starting the execution of the script. - // - // The compiled script would be returned in the |aScript| out-param. - MOZ_MUST_USE nsresult JoinAndExec(JS::OffThreadToken** aOffThreadToken, - JS::MutableHandle aScript); - - // Compile a script contained in a SourceText, and execute it. - nsresult CompileAndExec(JS::CompileOptions& aCompileOptions, - JS::SourceText& aSrcBuf, - JS::MutableHandle aScript); - - // Compile a script contained in a string, and execute it. - nsresult CompileAndExec(JS::CompileOptions& aCompileOptions, - const nsAString& aScript); - - // Decode a script contained in a buffer, and execute it. - MOZ_MUST_USE nsresult DecodeAndExec(JS::CompileOptions& aCompileOptions, - mozilla::Vector& aBytecodeBuf, - size_t aBytecodeIndex); - - // After getting a notification that an off-thread decoding terminated, this - // function will get the result of the decoder by moving it to the main - // thread before starting the execution of the script. - MOZ_MUST_USE nsresult - DecodeJoinAndExec(JS::OffThreadToken** aOffThreadToken); - - MOZ_MUST_USE nsresult - DecodeBinASTJoinAndExec(JS::OffThreadToken** aOffThreadToken, - JS::MutableHandle aScript); - - // Decode a BinAST encoded script contained in a buffer, and execute it. - nsresult DecodeBinASTAndExec(JS::CompileOptions& aCompileOptions, - const uint8_t* aBuf, size_t aLength, - JS::MutableHandle aScript); + MOZ_MUST_USE nsresult ExecScript(JS::MutableHandle aRetValue); }; static nsresult CompileModule(JSContext* aCx, diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp index 7c68bfd723a7..c4f5bfecf1e7 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -254,8 +254,8 @@ nsresult nsJSThunk::EvaluateScript( { nsJSUtils::ExecutionContext exec(cx, globalJSObject); exec.SetCoerceToString(true); - exec.CompileAndExec(options, NS_ConvertUTF8toUTF16(script)); - rv = exec.ExtractReturnValue(&v); + exec.Compile(options, NS_ConvertUTF8toUTF16(script)); + rv = exec.ExecScript(&v); } js::AssertSameCompartment(cx, v); diff --git a/dom/plugins/base/nsNPAPIPlugin.cpp b/dom/plugins/base/nsNPAPIPlugin.cpp index 53112b584ac9..a5a765def89e 100644 --- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -998,8 +998,8 @@ bool _evaluate(NPP npp, NPObject *npobj, NPString *script, NPVariant *result) { { nsJSUtils::ExecutionContext exec(cx, obj); exec.SetScopeChain(scopeChain); - exec.CompileAndExec(options, utf16script); - rv = exec.ExtractReturnValue(&rval); + exec.Compile(options, utf16script); + rv = exec.ExecScript(&rval); } if (!JS_WrapValue(cx, &rval)) { diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index c7749958c338..0a51a01231a5 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -8,8 +8,8 @@ #include "ScriptLoadHandler.h" #include "ScriptLoadRequest.h" #include "ScriptTrace.h" -#include "ModuleLoadRequest.h" #include "LoadedScript.h" +#include "ModuleLoadRequest.h" #include "prsystem.h" #include "jsapi.h" @@ -2470,13 +2470,14 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) { if (aRequest->mOffThreadToken) { LOG(("ScriptLoadRequest (%p): Decode Bytecode & Join and Execute", aRequest)); - rv = exec.DecodeJoinAndExec(&aRequest->mOffThreadToken); + exec.JoinDecode(&aRequest->mOffThreadToken); } else { LOG(("ScriptLoadRequest (%p): Decode Bytecode and Execute", aRequest)); - rv = exec.DecodeAndExec(options, aRequest->mScriptBytecode, - aRequest->mBytecodeOffset); + exec.Decode(options, aRequest->mScriptBytecode, + aRequest->mBytecodeOffset); } + rv = exec.ExecScript(); // We do not expect to be saving anything when we already have some // bytecode. MOZ_ASSERT(!aRequest->mCacheInfo); @@ -2496,30 +2497,34 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) { "Execute", aRequest)); if (aRequest->IsBinASTSource()) { - rv = exec.DecodeBinASTJoinAndExec(&aRequest->mOffThreadToken, - &script); + rv = exec.JoinDecodeBinAST(&aRequest->mOffThreadToken); } else { MOZ_ASSERT(aRequest->IsTextSource()); - rv = exec.JoinAndExec(&aRequest->mOffThreadToken, &script); + rv = exec.JoinCompile(&aRequest->mOffThreadToken); } } else { // Main thread parsing (inline and small scripts) LOG(("ScriptLoadRequest (%p): Compile And Exec", aRequest)); if (aRequest->IsBinASTSource()) { - rv = exec.DecodeBinASTAndExec( - options, aRequest->ScriptBinASTData().begin(), - aRequest->ScriptBinASTData().length(), &script); + rv = exec.DecodeBinAST(options, + aRequest->ScriptBinASTData().begin(), + aRequest->ScriptBinASTData().length()); } else { MOZ_ASSERT(aRequest->IsTextSource()); auto srcBuf = GetScriptSource(cx, aRequest); if (srcBuf) { - rv = exec.CompileAndExec(options, *srcBuf, &script); + rv = exec.Compile(options, *srcBuf); } else { rv = NS_ERROR_OUT_OF_MEMORY; } } } + + if (rv == NS_OK) { + script = exec.GetScript(); + rv = exec.ExecScript(); + } } // Queue the current script load request to later save the bytecode. diff --git a/dom/xbl/nsXBLProtoImplField.cpp b/dom/xbl/nsXBLProtoImplField.cpp index 4fe17ed602d8..9be3c27df3b0 100644 --- a/dom/xbl/nsXBLProtoImplField.cpp +++ b/dom/xbl/nsXBLProtoImplField.cpp @@ -415,9 +415,8 @@ nsresult nsXBLProtoImplField::InstallField( { nsJSUtils::ExecutionContext exec(cx, scopeObject); exec.SetScopeChain(scopeChain); - exec.CompileAndExec(options, - nsDependentString(mFieldText, mFieldTextLength)); - rv = exec.ExtractReturnValue(&result); + exec.Compile(options, nsDependentString(mFieldText, mFieldTextLength)); + rv = exec.ExecScript(&result); } if (NS_FAILED(rv)) {