mirror of
https://github.com/roytam1/basilisk55.git
synced 2026-05-26 15:02:46 +00:00
import from UXP: Issue #2229 Followup - Handle re-entrant module instantiation/evaluation during async module loads (6c67c6f6)
This commit is contained in:
@@ -1170,8 +1170,20 @@ public:
|
||||
};
|
||||
|
||||
void ScriptLoader::RunScriptWhenSafe(ScriptLoadRequest* aRequest) {
|
||||
auto runnable = new ScriptRequestProcessor(this, aRequest);
|
||||
nsContentUtils::AddScriptRunner(runnable);
|
||||
// Queue for processing through the normal script execution pipeline so that
|
||||
// dynamic imports are blocked during sync XHR just like async scripts.
|
||||
if (!aRequest->IsModuleRequest() ||
|
||||
!aRequest->AsModuleRequest()->IsDynamicImport()) {
|
||||
auto runnable = new ScriptRequestProcessor(this, aRequest);
|
||||
nsContentUtils::AddScriptRunner(runnable);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
MOZ_ASSERT(!aRequest->mInAsyncList);
|
||||
aRequest->mInAsyncList = true;
|
||||
mLoadedAsyncRequests.AppendElement(aRequest);
|
||||
ProcessPendingRequests();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2481,7 +2493,11 @@ ScriptLoader::ProcessPendingRequests()
|
||||
while (ReadyToExecuteScripts() && !mLoadedAsyncRequests.isEmpty()) {
|
||||
request = mLoadedAsyncRequests.StealFirst();
|
||||
if (request->IsModuleRequest()) {
|
||||
ProcessRequest(request);
|
||||
if (request->AsModuleRequest()->IsDynamicImport()) {
|
||||
ProcessDynamicImport(request->AsModuleRequest());
|
||||
} else {
|
||||
ProcessRequest(request);
|
||||
}
|
||||
} else {
|
||||
CompileOffThreadOrProcessRequest(request);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,23 @@
|
||||
function CallModuleResolveHook(module, specifier, expectedMinimumStatus)
|
||||
{
|
||||
let requestedModule = HostResolveImportedModule(module, specifier);
|
||||
if (requestedModule.state < expectedMinimumStatus)
|
||||
ThrowInternalError(JSMSG_BAD_MODULE_STATUS);
|
||||
if (requestedModule.state < expectedMinimumStatus) {
|
||||
ThrowBadModuleStatus("CallModuleResolveHook", requestedModule,
|
||||
"specifier=" + specifier + " expected>=" + expectedMinimumStatus);
|
||||
}
|
||||
|
||||
return requestedModule;
|
||||
}
|
||||
|
||||
function ThrowBadModuleStatus(where, module, details = "")
|
||||
{
|
||||
let status = module && module.status;
|
||||
let msg = "module record has unexpected status " + status + " at " + where;
|
||||
if (details)
|
||||
msg += " " + details;
|
||||
ThrowInternalError(msg);
|
||||
}
|
||||
|
||||
// 15.2.1.16.2 GetExportedNames(exportStarSet)
|
||||
function ModuleGetExportedNames(exportStarSet = [])
|
||||
{
|
||||
@@ -318,7 +329,10 @@ function ModuleInstantiate()
|
||||
if (module.status === MODULE_STATUS_INSTANTIATING ||
|
||||
module.status === MODULE_STATUS_EVALUATING)
|
||||
{
|
||||
ThrowInternalError(JSMSG_BAD_MODULE_STATUS);
|
||||
// Re-entrant instantiation can happen when a module is already
|
||||
// instantiating/evaluating (e.g., dynamic import while evaluating).
|
||||
// Treat this as a no-op, since the module graph is already in progress.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Step 3
|
||||
@@ -545,11 +559,19 @@ function ModuleEvaluate()
|
||||
let module = this;
|
||||
|
||||
// Step 2
|
||||
if (module.status === MODULE_STATUS_EVALUATING) {
|
||||
// Re-entrant evaluation should return the existing async evaluation
|
||||
// promise instead of throwing.
|
||||
return GetModuleEvaluationPromise(module);
|
||||
}
|
||||
|
||||
if (module.status !== MODULE_STATUS_INSTANTIATED &&
|
||||
module.status !== MODULE_STATUS_EVALUATED &&
|
||||
module.status !== MODULE_STATUS_EVALUATED_ERROR)
|
||||
{
|
||||
ThrowInternalError(JSMSG_BAD_MODULE_STATUS);
|
||||
// Avoid crashing on unexpected re-entrancy; callers will observe
|
||||
// completion via the existing evaluation flow.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Step 3
|
||||
|
||||
Reference in New Issue
Block a user