зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1777972 - Part 2: Add evaluating-async module status r=yulia
This adds ModuleStatus::EvaluatingAsync, splitting it off from ModuleStatus::Evaluated. This allows us to rewrite parts of the code to be closer to the spec. Depends on D151506 Differential Revision: https://phabricator.services.mozilla.com/D151507
This commit is contained in:
Родитель
066629e396
Коммит
62b2edbd3b
|
@ -45,7 +45,9 @@ using mozilla::Some;
|
|||
|
||||
static_assert(ModuleStatus::Unlinked < ModuleStatus::Linking &&
|
||||
ModuleStatus::Linking < ModuleStatus::Linked &&
|
||||
ModuleStatus::Linked < ModuleStatus::Evaluated &&
|
||||
ModuleStatus::Linked < ModuleStatus::Evaluating &&
|
||||
ModuleStatus::Evaluating < ModuleStatus::EvaluatingAsync &&
|
||||
ModuleStatus::EvaluatingAsync < ModuleStatus::Evaluated &&
|
||||
ModuleStatus::Evaluated < ModuleStatus::Evaluated_Error,
|
||||
"Module statuses are ordered incorrectly");
|
||||
|
||||
|
@ -1213,6 +1215,7 @@ bool ModuleObject::instantiateFunctionDeclarations(JSContext* cx,
|
|||
bool ModuleObject::execute(JSContext* cx, Handle<ModuleObject*> self) {
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(self->status() == ModuleStatus::Evaluating ||
|
||||
self->status() == ModuleStatus::EvaluatingAsync ||
|
||||
self->status() == ModuleStatus::Evaluated);
|
||||
MOZ_ASSERT(!self->hadEvaluationError());
|
||||
if (!AssertFrozen(cx, self)) {
|
||||
|
@ -2391,7 +2394,8 @@ static bool OnResolvedDynamicModule(JSContext* cx, unsigned argc, Value* vp) {
|
|||
}
|
||||
|
||||
Rooted<ModuleObject*> module(cx, &result->as<ModuleObject>());
|
||||
if (module->status() != ModuleStatus::Evaluated) {
|
||||
if (module->status() != ModuleStatus::EvaluatingAsync &&
|
||||
module->status() != ModuleStatus::Evaluated) {
|
||||
JS_ReportErrorASCII(
|
||||
cx, "Unevaluated or errored module returned by module resolve hook");
|
||||
return RejectPromiseWithPendingError(cx, promise);
|
||||
|
|
|
@ -255,6 +255,7 @@ enum class ModuleStatus : int32_t {
|
|||
Linking,
|
||||
Linked,
|
||||
Evaluating,
|
||||
EvaluatingAsync,
|
||||
Evaluated,
|
||||
|
||||
// Sub-state of Evaluated with error value set.
|
||||
|
|
|
@ -33,7 +33,7 @@ testGetter(a, "namespace");
|
|||
// ==== status getter ====
|
||||
const MODULE_STATUS_UNLINKED = 0;
|
||||
const MODULE_STATUS_LINKED = 2;
|
||||
const MODULE_STATUS_EVALUATED = 4;
|
||||
const MODULE_STATUS_EVALUATED = 5;
|
||||
|
||||
const c = registerModule('c', parseModule(`
|
||||
`));
|
||||
|
|
|
@ -1075,6 +1075,7 @@ bool js::ModuleLink(JSContext* cx, Handle<ModuleObject*> module) {
|
|||
// Step 5. Assert: module.[[Status]] is linked, evaluating-async, or
|
||||
// evaluated.
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::Linked ||
|
||||
module->status() == ModuleStatus::EvaluatingAsync ||
|
||||
module->status() == ModuleStatus::Evaluated);
|
||||
|
||||
// Step 6. Assert: stack is empty.
|
||||
|
@ -1093,6 +1094,7 @@ static bool InnerModuleLinking(JSContext* cx, Handle<ModuleObject*> module,
|
|||
// evaluated, then:
|
||||
if (module->status() == ModuleStatus::Linking ||
|
||||
module->status() == ModuleStatus::Linked ||
|
||||
module->status() == ModuleStatus::EvaluatingAsync ||
|
||||
module->status() == ModuleStatus::Evaluated) {
|
||||
// Step 2.a. Return index.
|
||||
*indexOut = index;
|
||||
|
@ -1155,6 +1157,7 @@ static bool InnerModuleLinking(JSContext* cx, Handle<ModuleObject*> module,
|
|||
// evaluating-async, or evaluated.
|
||||
MOZ_ASSERT(requiredModule->status() == ModuleStatus::Linking ||
|
||||
requiredModule->status() == ModuleStatus::Linked ||
|
||||
requiredModule->status() == ModuleStatus::EvaluatingAsync ||
|
||||
requiredModule->status() == ModuleStatus::Evaluated);
|
||||
|
||||
// Step 9.c.ii. Assert: requiredModule.[[Status]] is linking if and only if
|
||||
|
@ -1217,6 +1220,7 @@ bool js::ModuleEvaluate(JSContext* cx, Handle<ModuleObject*> moduleArg,
|
|||
// Step 2. Assert: module.[[Status]] is linked, evaluating-async, or
|
||||
// evaluated.
|
||||
if (module->status() != ModuleStatus::Linked &&
|
||||
module->status() != ModuleStatus::EvaluatingAsync &&
|
||||
module->status() != ModuleStatus::Evaluated) {
|
||||
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_BAD_MODULE_STATUS);
|
||||
|
@ -1228,7 +1232,8 @@ bool js::ModuleEvaluate(JSContext* cx, Handle<ModuleObject*> moduleArg,
|
|||
//
|
||||
// Note: we don't attempt to get the cycle root if there was an error during
|
||||
// evaluation as it may not be set.
|
||||
if (module->status() == ModuleStatus::Evaluated &&
|
||||
if ((module->status() == ModuleStatus::EvaluatingAsync ||
|
||||
module->status() == ModuleStatus::Evaluated) &&
|
||||
!module->hadEvaluationError()) {
|
||||
module = module->getCycleRoot();
|
||||
}
|
||||
|
@ -1297,10 +1302,12 @@ bool js::ModuleEvaluate(JSContext* cx, Handle<ModuleObject*> moduleArg,
|
|||
} else {
|
||||
// Step 10. Else:
|
||||
// Step 10.a. Assert: module.[[Status]] is evaluating-async or evaluated.
|
||||
// Step 10.b. Assert: module.[[EvaluationError]] is empty.
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::Evaluating ||
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::EvaluatingAsync ||
|
||||
module->status() == ModuleStatus::Evaluated);
|
||||
|
||||
// Step 10.b. Assert: module.[[EvaluationError]] is empty.
|
||||
MOZ_ASSERT(!module->hadEvaluationError());
|
||||
|
||||
// Step 10.c. If module.[[AsyncEvaluation]] is false, then:
|
||||
if (!module->isAsyncEvaluating()) {
|
||||
// Step 10.c.i. Assert: module.[[Status]] is evaluated.
|
||||
|
@ -1328,19 +1335,22 @@ static bool InnerModuleEvaluation(JSContext* cx, Handle<ModuleObject*> module,
|
|||
MutableHandle<ModuleVector> stack,
|
||||
size_t index, size_t* indexOut) {
|
||||
// Step 2. If module.[[Status]] is evaluating-async or evaluated, then:
|
||||
// Step 2.a. If module.[[EvaluationError]] is empty, return index.
|
||||
// Step 2.b. Otherwise, return ? module.[[EvaluationError]].
|
||||
// Step 3. If module.[[Status]] is evaluating, return index.
|
||||
if (module->status() == ModuleStatus::EvaluatingAsync ||
|
||||
module->status() == ModuleStatus::Evaluated) {
|
||||
// Step 2.a. If module.[[EvaluationError]] is empty, return index.
|
||||
if (!module->hadEvaluationError()) {
|
||||
*indexOut = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
// This section is rearranged since we don't have an evaluating-async state
|
||||
// but we do have an 'evaluation produced an error' state.
|
||||
if (module->hadEvaluationError()) {
|
||||
// Step 2.b. Otherwise, return ? module.[[EvaluationError]].
|
||||
Rooted<Value> error(cx, module->evaluationError());
|
||||
cx->setPendingException(error, ShouldCaptureStack::Maybe);
|
||||
return false;
|
||||
}
|
||||
if (module->status() == ModuleStatus::Evaluating ||
|
||||
module->status() == ModuleStatus::Evaluated) {
|
||||
|
||||
// Step 3. If module.[[Status]] is evaluating, return index.
|
||||
if (module->status() == ModuleStatus::Evaluating) {
|
||||
*indexOut = index;
|
||||
return true;
|
||||
}
|
||||
|
@ -1401,6 +1411,7 @@ static bool InnerModuleEvaluation(JSContext* cx, Handle<ModuleObject*> module,
|
|||
// Step 11.d.i. Assert: requiredModule.[[Status]] is either evaluating,
|
||||
// evaluating-async, or evaluated.
|
||||
MOZ_ASSERT(requiredModule->status() == ModuleStatus::Evaluating ||
|
||||
requiredModule->status() == ModuleStatus::EvaluatingAsync ||
|
||||
requiredModule->status() == ModuleStatus::Evaluated);
|
||||
|
||||
// Step 11.d.ii. Assert: requiredModule.[[Status]] is evaluating if and only
|
||||
|
@ -1422,7 +1433,8 @@ static bool InnerModuleEvaluation(JSContext* cx, Handle<ModuleObject*> module,
|
|||
|
||||
// Step 11.d.iv.2. Assert: requiredModule.[[Status]] is evaluating-async
|
||||
// or evaluated.
|
||||
MOZ_ASSERT(requiredModule->status() == ModuleStatus::Evaluated);
|
||||
MOZ_ASSERT(requiredModule->status() >= ModuleStatus::EvaluatingAsync ||
|
||||
requiredModule->status() == ModuleStatus::Evaluated);
|
||||
|
||||
// Step 11.d.iv.3. If requiredModule.[[EvaluationError]] is not empty,
|
||||
// return ? requiredModule.[[EvaluationError]].
|
||||
|
@ -1493,11 +1505,13 @@ static bool InnerModuleEvaluation(JSContext* cx, Handle<ModuleObject*> module,
|
|||
|
||||
// Step 16.b.iv. If requiredModule.[[AsyncEvaluation]] is false, set
|
||||
// requiredModule.[[Status]] to evaluated.
|
||||
// Step 16.b.v. Otherwise, set requiredModule.[[Status]] to
|
||||
// evaluating-async.
|
||||
|
||||
// Bug 1777972: We don't have a separate evaluating-async state.
|
||||
requiredModule->setStatus(ModuleStatus::Evaluated);
|
||||
if (!requiredModule->isAsyncEvaluating()) {
|
||||
requiredModule->setStatus(ModuleStatus::Evaluated);
|
||||
} else {
|
||||
// Step 16.b.v. Otherwise, set requiredModule.[[Status]] to
|
||||
// evaluating-async.
|
||||
requiredModule->setStatus(ModuleStatus::EvaluatingAsync);
|
||||
}
|
||||
|
||||
// Step 16.b.vi. If requiredModule and module are the same Module Record,
|
||||
// set done to true.
|
||||
|
@ -1518,7 +1532,7 @@ static bool InnerModuleEvaluation(JSContext* cx, Handle<ModuleObject*> module,
|
|||
static bool ExecuteAsyncModule(JSContext* cx, Handle<ModuleObject*> module) {
|
||||
// Step 1. Assert: module.[[Status]] is evaluating or evaluating-async.
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::Evaluating ||
|
||||
module->status() == ModuleStatus::Evaluated);
|
||||
module->status() == ModuleStatus::EvaluatingAsync);
|
||||
|
||||
// Step 2. Assert: module.[[HasTLA]] is true.
|
||||
MOZ_ASSERT(module->hasTopLevelAwait());
|
||||
|
@ -1539,10 +1553,11 @@ struct EvalOrderComparator {
|
|||
}
|
||||
};
|
||||
|
||||
// 16.2.1.5.2.3 GatherAvailableAncestors
|
||||
bool js::GatherAvailableModuleAncestors(
|
||||
JSContext* cx, Handle<ModuleObject*> module,
|
||||
MutableHandle<ModuleVector> sortedList) {
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::Evaluated);
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::EvaluatingAsync);
|
||||
MOZ_ASSERT(sortedList.empty());
|
||||
|
||||
if (!::GatherAvailableModuleAncestors(cx, module, sortedList)) {
|
||||
|
@ -1583,9 +1598,7 @@ static bool GatherAvailableModuleAncestors(
|
|||
if (!m->getCycleRoot()->hadEvaluationError() &&
|
||||
!ContainsElement(execList, m)) {
|
||||
// Step 1.a.i. Assert: m.[[Status]] is evaluating-async.
|
||||
|
||||
// Bug 1777972: We don't have a separate evaluating-async state.
|
||||
MOZ_ASSERT(m->status() == ModuleStatus::Evaluated);
|
||||
MOZ_ASSERT(m->status() == ModuleStatus::EvaluatingAsync);
|
||||
|
||||
// Step 1.a.ii. Assert: m.[[EvaluationError]] is empty.
|
||||
MOZ_ASSERT(!m->hadEvaluationError());
|
||||
|
@ -1625,7 +1638,7 @@ static bool GatherAvailableModuleAncestors(
|
|||
void js::AsyncModuleExecutionFulfilled(JSContext* cx,
|
||||
Handle<ModuleObject*> module) {
|
||||
// Step 1.
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::Evaluated);
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::EvaluatingAsync);
|
||||
|
||||
// Step 2.
|
||||
MOZ_ASSERT(module->isAsyncEvaluating());
|
||||
|
@ -1704,7 +1717,7 @@ void js::AsyncModuleExecutionRejected(JSContext* cx,
|
|||
Handle<ModuleObject*> module,
|
||||
HandleValue error) {
|
||||
// Step 1.
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::Evaluated);
|
||||
MOZ_ASSERT(module->status() == ModuleStatus::EvaluatingAsync);
|
||||
|
||||
// Step 2.
|
||||
if (!module->isAsyncEvaluating()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче