Skip to content

Commit 57fa30b

Browse files
committed
Bug 2023835: Align errored module handling with tc39/ecma262#3583. r=jonco
Implement tc39/ecma262#3583 Diff: implement https://arai-a.github.io/ecma262-compare/?rev=939b9934b57543df47e2ab5d81a6fdf61f2dd2aa An error evaluated module can be reset to null if it is evaluated again. Differential Revision: https://phabricator.services.mozilla.com/D288147
1 parent 5a709d4 commit 57fa30b

File tree

4 files changed

+22
-24
lines changed

4 files changed

+22
-24
lines changed

js/src/builtin/ModuleObject.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,10 @@ ModuleObject* ModuleObject::getCycleRoot() const {
12801280
return cyclicModuleFields()->cycleRoot;
12811281
}
12821282

1283+
bool ModuleObject::hasCycleRoot() const {
1284+
return bool(cyclicModuleFields()->cycleRoot);
1285+
}
1286+
12831287
LoadedModuleMap& ModuleObject::loadedModules() {
12841288
return cyclicModuleFields()->loadedModules;
12851289
}

js/src/builtin/ModuleObject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ class ModuleObject : public NativeObject {
470470
AsyncEvaluationOrder const& asyncEvaluationOrder() const;
471471
void setCycleRoot(ModuleObject* cycleRoot);
472472
ModuleObject* getCycleRoot() const;
473+
bool hasCycleRoot() const;
473474
bool hasCyclicModuleFields() const;
474475
bool hasSyntheticModuleFields() const;
475476
LoadedModuleMap& loadedModules();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
let module1 = registerModule('module1', parseModule(
2+
`throw 1;`));
3+
moduleLink(module1);
4+
moduleEvaluate(module1).catch(() => 0);
5+
moduleEvaluate(module1).catch(() => 0);
6+
drainJobQueue();

js/src/vm/Modules.cpp

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,34 +1912,21 @@ static bool ModuleEvaluate(JSContext* cx, Handle<ModuleObject*> moduleArg,
19121912
return false;
19131913
}
19141914

1915-
// Note: we return early in the error case, as the spec assumes we can get the
1916-
// cycle root of |module| which may not be available.
1917-
if (module->hadEvaluationError()) {
1918-
Rooted<PromiseObject*> capability(cx);
1919-
if (!module->hasTopLevelCapability()) {
1920-
capability = ModuleObject::createTopLevelCapability(cx, module);
1921-
if (!capability) {
1922-
return false;
1923-
}
1924-
1925-
Rooted<Value> error(cx, module->evaluationError());
1926-
if (!ModuleObject::topLevelCapabilityReject(cx, module, error)) {
1927-
return false;
1928-
}
1929-
}
1930-
1931-
capability = module->topLevelCapability();
1932-
MOZ_ASSERT(JS::GetPromiseState(capability) == JS::PromiseState::Rejected);
1933-
MOZ_ASSERT(JS::GetPromiseResult(capability) == module->evaluationError());
1934-
result.set(ObjectValue(*capability));
1935-
return true;
1936-
}
1937-
19381915
// Step 3. If module.[[Status]] is evaluating-async or evaluated, set module
19391916
// to module.[[CycleRoot]].
19401917
if (module->status() == ModuleStatus::EvaluatingAsync ||
19411918
module->status() == ModuleStatus::Evaluated) {
1942-
module = module->getCycleRoot();
1919+
// a. If module.[[CycleRoot]] is not empty, then
1920+
if (module->hasCycleRoot()) {
1921+
// i. Set module to module.[[CycleRoot]].
1922+
module = module->getCycleRoot();
1923+
} else {
1924+
// b. Else
1925+
// i. Assert: module.[[Status]] is evaluated and
1926+
// module.[[EvaluationError]] is a throw completion.
1927+
MOZ_ASSERT((module->status() == ModuleStatus::Evaluated) &&
1928+
module->hadEvaluationError());
1929+
}
19431930
}
19441931

19451932
// Step 4. If module.[[TopLevelCapability]] is not empty, then:

0 commit comments

Comments
 (0)