Bug 1689499 - Replace GetAsyncCycleRoot with [[CycleRoot]] field;r=jorendorff

Differential Revision: https://phabricator.services.mozilla.com/D103808
This commit is contained in:
yulia 2021-02-24 15:10:18 +00:00
parent f926953cfd
commit 28ccc23dd7
4 changed files with 41 additions and 52 deletions

View File

@ -594,7 +594,7 @@ function ModuleEvaluate()
if (isTopLevelAwaitEnabled) {
// Top-level Await Step 4
if (module.status === MODULE_STATUS_EVALUATED) {
module = GetAsyncCycleRoot(module);
module = GetCycleRoot(module);
}
// Top-level Await Step 5
@ -713,7 +713,7 @@ function InnerModuleEvaluation(module, stack, index)
requiredModule.dfsAncestorIndex));
} else {
if (isTopLevelAwaitEnabled) {
requiredModule = GetAsyncCycleRoot(requiredModule);
requiredModule = GetCycleRoot(requiredModule);
assert(requiredModule.status >= MODULE_STATUS_EVALUATED,
`Bad module status in InnerModuleEvaluation: ${requiredModule.status}`);
if (requiredModule.evaluationError) {
@ -757,10 +757,12 @@ function InnerModuleEvaluation(module, stack, index)
// Step 14
if (module.dfsAncestorIndex === module.dfsIndex) {
let cycleRoot = module;
let requiredModule;
do {
requiredModule = callFunction(std_Array_pop, stack);
ModuleSetStatus(requiredModule, MODULE_STATUS_EVALUATED);
SetCycleRoot(requiredModule, cycleRoot);
} while (requiredModule !== module);
}

View File

@ -994,7 +994,9 @@ uint32_t ModuleObject::dfsAncestorIndex() const {
}
JSObject* ModuleObject::topLevelCapability() const {
return &getReservedSlot(TopLevelCapabilitySlot).toObject();
Value capability = getReservedSlot(TopLevelCapabilitySlot);
MOZ_RELEASE_ASSERT(capability.isObject());
return &capability.toObject();
}
PromiseObject* ModuleObject::createTopLevelCapability(
@ -1031,6 +1033,16 @@ void ModuleObject::setPendingAsyncDependencies(uint32_t newValue) {
return setReservedSlot(PendingAsyncDependenciesSlot, NumberValue(newValue));
}
void ModuleObject::setCycleRoot(ModuleObject* cycleRoot) {
return setReservedSlot(CycleRootSlot, ObjectValue(*cycleRoot));
}
ModuleObject* ModuleObject::getCycleRoot() const {
Value cycleRoot = getReservedSlot(CycleRootSlot);
MOZ_RELEASE_ASSERT(cycleRoot.isObject());
return &cycleRoot.toObject().as<ModuleObject>();
}
bool ModuleObject::hasTopLevelCapability() const {
return !getReservedSlot(TopLevelCapabilitySlot).isUndefined();
}
@ -1960,36 +1972,6 @@ JSObject* js::CallModuleResolveHook(JSContext* cx,
return result;
}
// https://tc39.es/proposal-top-level-await/#sec-getasynccycleroot
ModuleObject* js::GetAsyncCycleRoot(ModuleObject* module) {
// Step 1.
MOZ_ASSERT(module->status() == MODULE_STATUS_EVALUATED);
// Step 2.
if (module->asyncParentModules()->empty()) {
return module;
}
// Step 3.
ModuleObject* currentModule = module;
while (currentModule->dfsIndex() > currentModule->dfsAncestorIndex()) {
MOZ_ASSERT(!currentModule->asyncParentModules()->empty());
ModuleObject* nextCycleModule = &currentModule->asyncParentModules()
->get(0)
.toObject()
.as<ModuleObject>();
MOZ_ASSERT(nextCycleModule->dfsAncestorIndex() <=
currentModule->dfsAncestorIndex());
currentModule = nextCycleModule;
}
// Step 4.
MOZ_ASSERT(currentModule->dfsIndex() == currentModule->dfsAncestorIndex());
// Step 5.
return currentModule;
}
bool js::AsyncModuleExecutionFulfilledHandler(JSContext* cx, unsigned argc,
Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
@ -2044,16 +2026,12 @@ void js::AsyncModuleExecutionFulfilled(JSContext* cx,
for (uint32_t i = 0; i < length; i++) {
m = &module->asyncParentModules()->get(i).toObject().as<ModuleObject>();
if (module->dfsIndex() != module->dfsAncestorIndex()) {
MOZ_ASSERT(m->dfsAncestorIndex() <= module->dfsAncestorIndex());
}
m->setPendingAsyncDependencies(m->pendingAsyncDependencies() - 1);
if (m->pendingAsyncDependencies() == 0 && !m->hadEvaluationError()) {
MOZ_ASSERT(m->isAsyncEvaluating());
cycleRoot = GetAsyncCycleRoot(m);
cycleRoot = m->getCycleRoot();
if (cycleRoot->hadEvaluationError()) {
return;
@ -2078,7 +2056,7 @@ void js::AsyncModuleExecutionFulfilled(JSContext* cx,
// Step 6.
if (module->hasTopLevelCapability()) {
MOZ_ASSERT(module->dfsIndex() == module->dfsAncestorIndex());
MOZ_ASSERT(module->getCycleRoot() == module);
ModuleObject::topLevelCapabilityResolve(cx, module);
}
@ -2113,15 +2091,12 @@ void js::AsyncModuleExecutionRejected(JSContext* cx, HandleModuleObject module,
for (uint32_t i = 0; i < length; i++) {
parent =
&module->asyncParentModules()->get(i).toObject().as<ModuleObject>();
if (module->dfsIndex() != module->dfsAncestorIndex()) {
MOZ_ASSERT(parent->dfsAncestorIndex() == module->dfsAncestorIndex());
}
AsyncModuleExecutionRejected(cx, parent, error);
}
// Step 7.
if (module->hasTopLevelCapability()) {
MOZ_ASSERT(module->dfsIndex() == module->dfsAncestorIndex());
MOZ_ASSERT(module->getCycleRoot() == module);
ModuleObject::topLevelCapabilityReject(cx, module, error);
}
@ -2259,8 +2234,10 @@ static bool OnResolvedDynamicModule(JSContext* cx, unsigned argc, Value* vp) {
return RejectPromiseWithPendingError(cx, promise);
}
MOZ_ASSERT(module->topLevelCapability()->as<PromiseObject>().state() ==
JS::PromiseState::Fulfilled);
MOZ_ASSERT(module->getCycleRoot()
->topLevelCapability()
->as<PromiseObject>()
.state() == JS::PromiseState::Fulfilled);
RootedObject ns(cx, ModuleObject::GetOrCreateModuleNamespace(cx, module));
if (!ns) {

View File

@ -277,6 +277,7 @@ class ModuleObject : public NativeObject {
TopLevelCapabilitySlot,
AsyncParentModulesSlot,
PendingAsyncDependenciesSlot,
CycleRootSlot,
SlotCount
};
@ -356,6 +357,8 @@ class ModuleObject : public NativeObject {
JSObject* topLevelCapability() const;
ListObject* asyncParentModules() const;
uint32_t pendingAsyncDependencies() const;
void setCycleRoot(ModuleObject* cycleRoot);
ModuleObject* getCycleRoot() const;
static bool appendAsyncParentModule(JSContext* cx, HandleModuleObject self,
HandleModuleObject parent);
@ -411,9 +414,6 @@ JSObject* GetOrCreateModuleMetaObject(JSContext* cx, HandleObject module);
JSObject* CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate,
HandleString specifier);
// https://tc39.es/proposal-top-level-await/#sec-getasynccycleroot
ModuleObject* GetAsyncCycleRoot(ModuleObject* module);
// https://tc39.es/proposal-top-level-await/#sec-asyncmodulexecutionfulfilled
void AsyncModuleExecutionFulfilled(JSContext* cx, HandleModuleObject module);

View File

@ -1951,12 +1951,21 @@ static bool intrinsic_IsTopLevelAwaitEnabled(JSContext* cx, unsigned argc,
return true;
}
static bool intrinsic_GetAsyncCycleRoot(JSContext* cx, unsigned argc,
Value* vp) {
static bool intrinsic_SetCycleRoot(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 2);
RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
RootedModuleObject cycleRoot(cx, &args[1].toObject().as<ModuleObject>());
module->setCycleRoot(cycleRoot);
args.rval().setUndefined();
return true;
}
static bool intrinsic_GetCycleRoot(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 1);
RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
JSObject* result = js::GetAsyncCycleRoot(module);
JSObject* result = module->getCycleRoot();
if (!result) {
return false;
}
@ -2597,7 +2606,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
intrinsic_InstantiateModuleFunctionDeclarations, 1, 0),
JS_FN("ExecuteModule", intrinsic_ExecuteModule, 1, 0),
JS_FN("IsTopLevelAwaitEnabled", intrinsic_IsTopLevelAwaitEnabled, 0, 0),
JS_FN("GetAsyncCycleRoot", intrinsic_GetAsyncCycleRoot, 1, 0),
JS_FN("SetCycleRoot", intrinsic_SetCycleRoot, 2, 0),
JS_FN("GetCycleRoot", intrinsic_GetCycleRoot, 1, 0),
JS_FN("AppendAsyncParentModule", intrinsic_AppendAsyncParentModule, 2, 0),
JS_FN("CreateTopLevelCapability", intrinsic_CreateTopLevelCapability, 1, 0),
JS_FN("ModuleTopLevelCapabilityResolve",