diff options
author | Moonchild <moonchild@palemoon.org> | 2020-07-04 16:28:30 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2020-07-10 18:30:48 +0000 |
commit | f6a6900a6b14d1d54da46370015b28d4d8a152a7 (patch) | |
tree | 6af248540f32f4427e9a01164804aca505aae379 | |
parent | 40aad1a2209607b973170f4fb64548e5d8103402 (diff) | |
download | UXP-f6a6900a6b14d1d54da46370015b28d4d8a152a7.tar UXP-f6a6900a6b14d1d54da46370015b28d4d8a152a7.tar.gz UXP-f6a6900a6b14d1d54da46370015b28d4d8a152a7.tar.lz UXP-f6a6900a6b14d1d54da46370015b28d4d8a152a7.tar.xz UXP-f6a6900a6b14d1d54da46370015b28d4d8a152a7.zip |
Issue #618 - Further align error handling for module scripts with the spec
Ref: BZ 1388728
-rw-r--r-- | dom/script/ModuleLoadRequest.cpp | 42 | ||||
-rw-r--r-- | dom/script/ModuleLoadRequest.h | 6 | ||||
-rw-r--r-- | dom/script/ModuleScript.cpp | 72 | ||||
-rw-r--r-- | dom/script/ModuleScript.h | 10 | ||||
-rw-r--r-- | dom/script/ScriptLoader.cpp | 237 | ||||
-rw-r--r-- | dom/script/ScriptLoader.h | 2 |
6 files changed, 280 insertions, 89 deletions
diff --git a/dom/script/ModuleLoadRequest.cpp b/dom/script/ModuleLoadRequest.cpp index 8871dcdab..d62214304 100644 --- a/dom/script/ModuleLoadRequest.cpp +++ b/dom/script/ModuleLoadRequest.cpp @@ -43,10 +43,16 @@ void ModuleLoadRequest::Cancel() ScriptLoadRequest::Cancel(); mModuleScript = nullptr; mProgress = ScriptLoadRequest::Progress::Ready; + CancelImports(); + mReady.RejectIfExists(NS_ERROR_DOM_ABORT_ERR, __func__); +} + +void +ModuleLoadRequest::CancelImports() +{ for (size_t i = 0; i < mImports.Length(); i++) { mImports[i]->Cancel(); } - mReady.RejectIfExists(NS_ERROR_FAILURE, __func__); } void @@ -77,25 +83,53 @@ ModuleLoadRequest::ModuleLoaded() // been loaded. mModuleScript = mLoader->GetFetchedModule(mURI); + if (!mModuleScript || mModuleScript->IsErrored()) { + ModuleErrored(); + return; + } + mLoader->StartFetchingModuleDependencies(this); } void +ModuleLoadRequest::ModuleErrored() +{ + mLoader->CheckModuleDependenciesLoaded(this); + MOZ_ASSERT(!mModuleScript || mModuleScript->IsErrored()); + + CancelImports(); + SetReady(); + LoadFinished(); +} + +void ModuleLoadRequest::DependenciesLoaded() { // The module and all of its dependencies have been successfully fetched and // compiled. + MOZ_ASSERT(mModuleScript); + + mLoader->CheckModuleDependenciesLoaded(this); SetReady(); - mLoader->ProcessLoadedModuleTree(this); - mLoader = nullptr; - mParent = nullptr; + LoadFinished(); } void ModuleLoadRequest::LoadFailed() { + // We failed to load the source text or an error occurred unrelated to the + // content of the module (e.g. OOM). + + MOZ_ASSERT(!mModuleScript); + Cancel(); + LoadFinished(); +} + +void +ModuleLoadRequest::LoadFinished() +{ mLoader->ProcessLoadedModuleTree(this); mLoader = nullptr; mParent = nullptr; diff --git a/dom/script/ModuleLoadRequest.h b/dom/script/ModuleLoadRequest.h index 0119fad38..7b06dd2cf 100644 --- a/dom/script/ModuleLoadRequest.h +++ b/dom/script/ModuleLoadRequest.h @@ -45,9 +45,15 @@ public: void Cancel() override; void ModuleLoaded(); + void ModuleErrored(); void DependenciesLoaded(); void LoadFailed(); +private: + void LoadFinished(); + void CancelImports(); + +public: // Is this a request for a top level module script or an import? bool mIsTopLevel; diff --git a/dom/script/ModuleScript.cpp b/dom/script/ModuleScript.cpp index bf02f522d..28b97a3cb 100644 --- a/dom/script/ModuleScript.cpp +++ b/dom/script/ModuleScript.cpp @@ -26,6 +26,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ModuleScript) NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader) NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL) tmp->UnlinkModuleRecord(); + tmp->mError.setUndefined(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ModuleScript) @@ -34,25 +35,20 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ModuleScript) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRecord) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mError) NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTING_ADDREF(ModuleScript) NS_IMPL_CYCLE_COLLECTING_RELEASE(ModuleScript) -ModuleScript::ModuleScript(ScriptLoader *aLoader, nsIURI* aBaseURL, - JS::Handle<JSObject*> aModuleRecord) +ModuleScript::ModuleScript(ScriptLoader *aLoader, nsIURI* aBaseURL) : mLoader(aLoader), - mBaseURL(aBaseURL), - mModuleRecord(aModuleRecord) + mBaseURL(aBaseURL) { MOZ_ASSERT(mLoader); MOZ_ASSERT(mBaseURL); - MOZ_ASSERT(mModuleRecord); - - // Make module's host defined field point to this module script object. - // This is cleared in the UnlinkModuleRecord(). - JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this)); - HoldJSObjects(this); + MOZ_ASSERT(!mModuleRecord); + MOZ_ASSERT(mError.isUndefined()); } void @@ -63,18 +59,64 @@ ModuleScript::UnlinkModuleRecord() MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() == this); JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue()); + mModuleRecord = nullptr; } - mModuleRecord = nullptr; } ModuleScript::~ModuleScript() { - if (mModuleRecord) { - // The object may be destroyed without being unlinked first. - UnlinkModuleRecord(); - } + // The object may be destroyed without being unlinked first. + UnlinkModuleRecord(); DropJSObjects(this); } +void +ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord) +{ + MOZ_ASSERT(!mModuleRecord); + MOZ_ASSERT(mError.isUndefined()); + + mModuleRecord = aModuleRecord; + + // Make module's host defined field point to this module script object. + // This is cleared in the UnlinkModuleRecord(). + JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this)); + HoldJSObjects(this); +} + +void +ModuleScript::SetPreInstantiationError(const JS::Value& aError) +{ + MOZ_ASSERT(!aError.isUndefined()); + + UnlinkModuleRecord(); + mError = aError; + + HoldJSObjects(this); +} + +bool +ModuleScript::IsErrored() const +{ + if (!mModuleRecord) { + MOZ_ASSERT(!mError.isUndefined()); + return true; + } + + return JS::IsModuleErrored(mModuleRecord); +} + +JS::Value +ModuleScript::Error() const +{ + MOZ_ASSERT(IsErrored()); + + if (!mModuleRecord) { + return mError; + } + + return JS::GetModuleError(mModuleRecord); +} + } // dom namespace } // mozilla namespace diff --git a/dom/script/ModuleScript.h b/dom/script/ModuleScript.h index 97fdb8ed1..571359859 100644 --- a/dom/script/ModuleScript.h +++ b/dom/script/ModuleScript.h @@ -23,6 +23,7 @@ class ModuleScript final : public nsISupports RefPtr<ScriptLoader> mLoader; nsCOMPtr<nsIURI> mBaseURL; JS::Heap<JSObject*> mModuleRecord; + JS::Heap<JS::Value> mError; ~ModuleScript(); @@ -31,13 +32,18 @@ public: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ModuleScript) ModuleScript(ScriptLoader* aLoader, - nsIURI* aBaseURL, - JS::Handle<JSObject*> aModuleRecord); + nsIURI* aBaseURL); + + void SetModuleRecord(JS::Handle<JSObject*> aModuleRecord); + void SetPreInstantiationError(const JS::Value& aError); ScriptLoader* Loader() const { return mLoader; } JSObject* ModuleRecord() const { return mModuleRecord; } nsIURI* BaseURL() const { return mBaseURL; } + bool IsErrored() const; + JS::Value Error() const; + void UnlinkModuleRecord(); }; diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index cf7f06e71..a53098974 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -418,25 +418,23 @@ void ScriptLoader::SetModuleFetchFinishedAndResumeWaitingRequests(ModuleLoadRequest *aRequest, nsresult aResult) { - // Update module map with the result of fetching a single module script. The - // module script pointer is nullptr on error. + // Update module map with the result of fetching a single module script. // // If any requests for the same URL are waiting on this one to complete, they // will have ModuleLoaded or LoadFailed on them when the promise is // resolved/rejected. This is set up in StartLoad. - MOZ_ASSERT(!aRequest->IsReadyToRun()); - RefPtr<GenericPromise::Private> promise; MOZ_ALWAYS_TRUE(mFetchingModules.Get(aRequest->mURI, getter_AddRefs(promise))); mFetchingModules.Remove(aRequest->mURI); - RefPtr<ModuleScript> ms(aRequest->mModuleScript); - MOZ_ASSERT(NS_SUCCEEDED(aResult) == (ms != nullptr)); - mFetchedModules.Put(aRequest->mURI, ms); + RefPtr<ModuleScript> moduleScript(aRequest->mModuleScript); + MOZ_ASSERT(NS_FAILED(aResult) == !moduleScript); + + mFetchedModules.Put(aRequest->mURI, moduleScript); if (promise) { - if (ms) { + if (moduleScript) { promise->Resolve(true, __func__); } else { promise->Reject(aResult, __func__); @@ -482,19 +480,29 @@ ScriptLoader::ProcessFetchedModuleSource(ModuleLoadRequest* aRequest) MOZ_ASSERT(!aRequest->mModuleScript); nsresult rv = CreateModuleScript(aRequest); + MOZ_ASSERT(NS_FAILED(rv) == !aRequest->mModuleScript); + SetModuleFetchFinishedAndResumeWaitingRequests(aRequest, rv); free(aRequest->mScriptTextBuf); aRequest->mScriptTextBuf = nullptr; aRequest->mScriptTextLength = 0; - if (NS_SUCCEEDED(rv)) { + if (NS_FAILED(rv)) { + aRequest->LoadFailed(); + return rv; + } + + if (!aRequest->mModuleScript->IsErrored()) { StartFetchingModuleDependencies(aRequest); } - return rv; + return NS_OK; } +static nsresult +ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>& aUrls); + nsresult ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) { @@ -548,9 +556,34 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) } } MOZ_ASSERT(NS_SUCCEEDED(rv) == (module != nullptr)); - if (module) { - aRequest->mModuleScript = - new ModuleScript(this, aRequest->mBaseURL, module); + RefPtr<ModuleScript> moduleScript = new ModuleScript(this, aRequest->mBaseURL); + aRequest->mModuleScript = moduleScript; + + if (!module) { + // Compilation failed + MOZ_ASSERT(aes.HasException()); + JS::Rooted<JS::Value> error(cx); + if (!aes.StealException(&error)) { + aRequest->mModuleScript = nullptr; + return NS_ERROR_FAILURE; + } + + moduleScript->SetPreInstantiationError(error); + aRequest->ModuleErrored(); + return NS_OK; + } + + moduleScript->SetModuleRecord(module); + + // Validate requested modules and treat failure to resolve module specifiers + // the same as a parse error. + nsCOMArray<nsIURI> urls; + rv = ResolveRequestedModules(aRequest, urls); + if (NS_FAILED(rv)) { + // ResolveRequestedModules sets pre-instanitation error on failure. + MOZ_ASSERT(moduleScript->IsErrored()); + aRequest->ModuleErrored(); + return NS_OK; } } @@ -560,8 +593,8 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) } static bool -ThrowTypeError(JSContext* aCx, ModuleScript* aScript, - const nsString& aMessage) +CreateTypeError(JSContext* aCx, ModuleScript* aScript, const nsString& aMessage, + JS::MutableHandle<JS::Value> aError) { JS::Rooted<JSObject*> module(aCx, aScript->ModuleRecord()); JS::Rooted<JSScript*> script(aCx, JS::GetModuleScript(aCx, module)); @@ -576,17 +609,11 @@ ThrowTypeError(JSContext* aCx, ModuleScript* aScript, return false; } - JS::Rooted<JS::Value> error(aCx); - if (!JS::CreateError(aCx, JSEXN_TYPEERR, nullptr, filename, 0, 0, nullptr, - message, &error)) { - return false; - } - - JS_SetPendingException(aCx, error); - return false; + return JS::CreateError(aCx, JSEXN_TYPEERR, nullptr, filename, 0, 0, nullptr, + message, aError); } -static bool +static nsresult HandleResolveFailure(JSContext* aCx, ModuleScript* aScript, const nsAString& aSpecifier) { @@ -595,19 +622,13 @@ HandleResolveFailure(JSContext* aCx, ModuleScript* aScript, nsAutoString message(NS_LITERAL_STRING("Error resolving module specifier: ")); message.Append(aSpecifier); - return ThrowTypeError(aCx, aScript, message); -} - -static bool -HandleModuleNotFound(JSContext* aCx, ModuleScript* aScript, - const nsAString& aSpecifier) -{ - // TODO: How can we get the line number of the failed import? - - nsAutoString message(NS_LITERAL_STRING("Resolved module not found in map: ")); - message.Append(aSpecifier); + JS::Rooted<JS::Value> error(aCx); + if (!CreateTypeError(aCx, aScript, message, &error)) { + return NS_ERROR_OUT_OF_MEMORY; + } - return ThrowTypeError(aCx, aScript, message); + aScript->SetPreInstantiationError(error); + return NS_OK; } static already_AddRefed<nsIURI> @@ -705,7 +726,8 @@ ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI> &aUrls) ModuleScript* ms = aRequest->mModuleScript; nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(ms, specifier); if (!uri) { - HandleResolveFailure(cx, ms, specifier); + nsresult rv = HandleResolveFailure(cx, ms, specifier); + NS_ENSURE_SUCCESS(rv, rv); return NS_ERROR_FAILURE; } @@ -724,6 +746,7 @@ void ScriptLoader::StartFetchingModuleDependencies(ModuleLoadRequest* aRequest) { MOZ_ASSERT(aRequest->mModuleScript); + MOZ_ASSERT(!aRequest->mModuleScript->IsErrored()); MOZ_ASSERT(!aRequest->IsReadyToRun()); aRequest->mProgress = ModuleLoadRequest::Progress::FetchingImports; @@ -731,7 +754,7 @@ ScriptLoader::StartFetchingModuleDependencies(ModuleLoadRequest* aRequest) nsCOMArray<nsIURI> urls; nsresult rv = ResolveRequestedModules(aRequest, urls); if (NS_FAILED(rv)) { - aRequest->LoadFailed(); + aRequest->ModuleErrored(); return; } @@ -755,7 +778,7 @@ ScriptLoader::StartFetchingModuleDependencies(ModuleLoadRequest* aRequest) GenericPromise::All(AbstractThread::GetCurrent(), importsReady); allReady->Then(AbstractThread::GetCurrent(), __func__, aRequest, &ModuleLoadRequest::DependenciesLoaded, - &ModuleLoadRequest::LoadFailed); + &ModuleLoadRequest::ModuleErrored); } RefPtr<GenericPromise> @@ -778,6 +801,7 @@ ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, nsresult rv = StartLoad(childRequest, NS_LITERAL_STRING("module"), false); if (NS_FAILED(rv)) { + MOZ_ASSERT(!childRequest->mModuleScript); childRequest->mReady.Reject(rv, __func__); return ready; } @@ -786,6 +810,7 @@ ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, return ready; } +// 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier) bool HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp) { @@ -800,25 +825,25 @@ HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp) MOZ_ASSERT(script->ModuleRecord() == module); // Let url be the result of resolving a module specifier given referencing - // module script and specifier. If the result is failure, throw a TypeError - // exception and abort these steps. + // module script and specifier. nsAutoJSString string; if (!string.init(aCx, specifier)) { return false; } nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(script, string); - if (!uri) { - return HandleResolveFailure(aCx, script, string); - } - // Let resolved module script be the value of the entry in module map whose - // key is url. If no such entry exists, throw a TypeError exception and abort - // these steps. + // This cannot fail because resolving a module specifier must have been + // previously successful with these same two arguments. + MOZ_ASSERT(uri, "Failed to resolve previously-resolved module specifier"); + + // Let resolved module script be moduleMap[url]. (This entry must exist for us + // to have gotten to this point.) + ModuleScript* ms = script->Loader()->GetFetchedModule(uri); - if (!ms) { - return HandleModuleNotFound(aCx, script, string); - } + MOZ_ASSERT(ms, "Resolved module not found in module map"); + + MOZ_ASSERT(!ms->IsErrored()); *vp = JS::ObjectValue(*ms->ModuleRecord()); return true; @@ -843,9 +868,35 @@ EnsureModuleResolveHook(JSContext* aCx) } void +ScriptLoader::CheckModuleDependenciesLoaded(ModuleLoadRequest* aRequest) +{ + RefPtr<ModuleScript> moduleScript = aRequest->mModuleScript; + if (moduleScript && !moduleScript->IsErrored()) { + for (auto childRequest : aRequest->mImports) { + ModuleScript* childScript = childRequest->mModuleScript; + if (!childScript) { + // Load error + aRequest->mModuleScript = nullptr; + return; + } else if (childScript->IsErrored()) { + // Script error + moduleScript->SetPreInstantiationError(childScript->Error()); + return; + } + } + } +} + +void ScriptLoader::ProcessLoadedModuleTree(ModuleLoadRequest* aRequest) { if (aRequest->IsTopLevel()) { + ModuleScript* moduleScript = aRequest->mModuleScript; + if (moduleScript && !moduleScript->IsErrored()) { + if (!InstantiateModuleTree(aRequest)) { + aRequest->mModuleScript = nullptr; + } + } MaybeMoveToLoadedList(aRequest); ProcessPendingRequests(); } @@ -855,6 +906,43 @@ ScriptLoader::ProcessLoadedModuleTree(ModuleLoadRequest* aRequest) } } +bool +ScriptLoader::InstantiateModuleTree(ModuleLoadRequest* aRequest) +{ + // Instantiate a top-level module and record any error. + + MOZ_ASSERT(aRequest); + MOZ_ASSERT(aRequest->IsTopLevel()); + + ModuleScript* moduleScript = aRequest->mModuleScript; + MOZ_ASSERT(moduleScript); + MOZ_ASSERT(moduleScript->ModuleRecord()); + + nsAutoMicroTask mt; + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.Init(moduleScript->ModuleRecord()))) { + return false; + } + + nsresult rv = EnsureModuleResolveHook(jsapi.cx()); + NS_ENSURE_SUCCESS(rv, false); + + JS::Rooted<JSObject*> module(jsapi.cx(), moduleScript->ModuleRecord()); + bool ok = NS_SUCCEEDED(nsJSUtils::ModuleInstantiate(jsapi.cx(), module)); + + if (!ok) { + MOZ_ASSERT(jsapi.HasException()); + JS::RootedValue exception(jsapi.cx()); + if (!jsapi.StealException(&exception)) { + return false; + } + MOZ_ASSERT(!exception.isUndefined()); + // Ignore the exception. It will be recorded in the module record. + } + + return true; +} + nsresult ScriptLoader::StartLoad(ScriptLoadRequest *aRequest, const nsAString &aType, bool aScriptFromHead) @@ -1364,13 +1452,19 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) ModuleLoadRequest* modReq = request->AsModuleRequest(); modReq->mBaseURL = mDocument->GetDocBaseURI(); rv = CreateModuleScript(modReq); - NS_ENSURE_SUCCESS(rv, false); - StartFetchingModuleDependencies(modReq); + MOZ_ASSERT(NS_FAILED(rv) == !modReq->mModuleScript); + if (NS_FAILED(rv)) { + modReq->LoadFailed(); + return false; + } if (aElement->GetScriptAsync()) { mLoadingAsyncRequests.AppendElement(request); } else { AddDeferRequest(request); } + if (!modReq->mModuleScript->IsErrored()) { + StartFetchingModuleDependencies(modReq); + } return false; } request->mProgress = ScriptLoadRequest::Progress::Ready; @@ -1448,11 +1542,7 @@ ScriptLoader::ProcessOffThreadRequest(ScriptLoadRequest* aRequest) if (aRequest->IsModuleRequest()) { MOZ_ASSERT(aRequest->mOffThreadToken); ModuleLoadRequest* request = aRequest->AsModuleRequest(); - nsresult rv = ProcessFetchedModuleSource(request); - if (NS_FAILED(rv)) { - request->LoadFailed(); - } - return rv; + return ProcessFetchedModuleSource(request); } aRequest->SetReady(); @@ -1624,7 +1714,7 @@ ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) if (aRequest->IsModuleRequest() && !aRequest->AsModuleRequest()->mModuleScript) { - // There was an error parsing a module script. Nothing to do here. + // There was an error fetching a module script. Nothing to do here. FireScriptAvailable(NS_ERROR_FAILURE, aRequest); return NS_OK; } @@ -1846,8 +1936,8 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block nsAutoMicroTask mt; AutoEntryScript aes(globalObject, "<script> element", true); - JS::Rooted<JSObject*> global(aes.cx(), - globalObject->GetGlobalJSObject()); + JSContext* cx = aes.cx(); + JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject()); bool oldProcessingScriptTag = context->GetProcessingScriptTag(); context->SetProcessingScriptTag(true); @@ -1868,27 +1958,38 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) } if (aRequest->IsModuleRequest()) { - rv = EnsureModuleResolveHook(aes.cx()); + rv = EnsureModuleResolveHook(cx); NS_ENSURE_SUCCESS(rv, rv); ModuleLoadRequest* request = aRequest->AsModuleRequest(); MOZ_ASSERT(request->mModuleScript); MOZ_ASSERT(!request->mOffThreadToken); - JS::Rooted<JSObject*> module(aes.cx(), - request->mModuleScript->ModuleRecord()); + + ModuleScript* moduleScript = request->mModuleScript; + if (moduleScript->IsErrored()) { + // Module has an error status + JS::Rooted<JS::Value> error(cx, moduleScript->Error()); + JS_SetPendingException(cx, error); + return NS_OK; // An error is reported by AutoEntryScript. + } + + JS::Rooted<JSObject*> module(cx, moduleScript->ModuleRecord()); MOZ_ASSERT(module); - rv = nsJSUtils::ModuleInstantiate(aes.cx(), module); - if (NS_SUCCEEDED(rv)) { - rv = nsJSUtils::ModuleEvaluate(aes.cx(), module); + + rv = nsJSUtils::ModuleEvaluate(cx, module); + MOZ_ASSERT(NS_FAILED(rv) == aes.HasException()); + if (NS_FAILED(rv)) { + // Evaluation failed + rv = NS_OK; // An error is reported by AutoEntryScript. } } else { - JS::CompileOptions options(aes.cx()); + JS::CompileOptions options(cx); rv = FillCompileOptionsForRequest(aes, aRequest, global, &options); if (NS_SUCCEEDED(rv)) { nsAutoString inlineData; SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData); - rv = nsJSUtils::EvaluateString(aes.cx(), srcBuf, global, options, + rv = nsJSUtils::EvaluateString(cx, srcBuf, global, options, aRequest->OffThreadTokenPtr()); } } diff --git a/dom/script/ScriptLoader.h b/dom/script/ScriptLoader.h index 32401d1b6..e6b75bf3b 100644 --- a/dom/script/ScriptLoader.h +++ b/dom/script/ScriptLoader.h @@ -580,7 +580,9 @@ private: nsresult CreateModuleScript(ModuleLoadRequest* aRequest); nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest); + void CheckModuleDependenciesLoaded(ModuleLoadRequest* aRequest); void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest); + bool InstantiateModuleTree(ModuleLoadRequest* aRequest); void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest); RefPtr<mozilla::GenericPromise> |