[top-level-await] Consolidate module Evaluate methods

With the TLA flag removed, EvaluateMaybeAsync is a misleading name. This
CL renamed EvaluateMaybeAsync to Evaluate and consolidate it with the
sync Evaluate method.

Bug: v8:9344
Change-Id: I376ba9b9af0ac9e40a226cc8454f042ab7d9fb50
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3309233
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78282}
This commit is contained in:
Shu-yu Guo 2021-12-07 10:51:51 -08:00 committed by V8 LUCI CQ
parent e155881f24
commit 833eba71b3
4 changed files with 28 additions and 56 deletions

View File

@ -247,11 +247,7 @@ MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module) {
PrintStatusMessage(*module, "Evaluating module ");
#endif // DEBUG
STACK_CHECK(isolate, MaybeHandle<Object>());
return Module::EvaluateMaybeAsync(isolate, module);
}
MaybeHandle<Object> Module::EvaluateMaybeAsync(Isolate* isolate,
Handle<Module> module) {
// In the event of errored evaluation, return a rejected promise.
if (module->status() == kErrored) {
// If we have a top level capability we assume it has already been
@ -288,8 +284,8 @@ MaybeHandle<Object> Module::EvaluateMaybeAsync(Isolate* isolate,
DCHECK(module->top_level_capability().IsUndefined());
if (module->IsSourceTextModule()) {
return SourceTextModule::EvaluateMaybeAsync(
isolate, Handle<SourceTextModule>::cast(module));
return SourceTextModule::Evaluate(isolate,
Handle<SourceTextModule>::cast(module));
} else {
return SyntheticModule::Evaluate(isolate,
Handle<SyntheticModule>::cast(module));

View File

@ -116,9 +116,6 @@ class Module : public TorqueGeneratedModule<Module, HeapObject> {
ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index,
Zone* zone);
static V8_WARN_UNUSED_RESULT MaybeHandle<Object> EvaluateMaybeAsync(
Isolate* isolate, Handle<Module> module);
// Set module's status back to kUnlinked and reset other internal state.
// This is used when instantiation fails.
static void Reset(Isolate* isolate, Handle<Module> module);

View File

@ -683,8 +683,15 @@ MaybeHandle<JSObject> SourceTextModule::GetImportMeta(
return Handle<JSObject>::cast(import_meta);
}
MaybeHandle<Object> SourceTextModule::EvaluateMaybeAsync(
MaybeHandle<Object> SourceTextModule::Evaluate(
Isolate* isolate, Handle<SourceTextModule> module) {
CHECK(module->status() == kLinked || module->status() == kEvaluated);
// 5. Let stack be a new empty List.
Zone zone(isolate->allocator(), ZONE_NAME);
ZoneForwardList<Handle<SourceTextModule>> stack(&zone);
unsigned dfs_index = 0;
// 6. Let capability be ! NewPromiseCapability(%Promise%).
Handle<JSPromise> capability = isolate->factory()->NewJSPromise();
@ -692,18 +699,30 @@ MaybeHandle<Object> SourceTextModule::EvaluateMaybeAsync(
module->set_top_level_capability(*capability);
DCHECK(module->top_level_capability().IsJSPromise());
// 8. Let result be InnerModuleEvaluation(module, stack, 0).
// 9. If result is an abrupt completion, then
Handle<Object> unused_result;
if (!Evaluate(isolate, module).ToHandle(&unused_result)) {
if (!InnerModuleEvaluation(isolate, module, &stack, &dfs_index)
.ToHandle(&unused_result)) {
// a. For each Cyclic Module Record m in stack, do
for (auto& descendant : stack) {
// i. Assert: m.[[Status]] is "evaluating".
CHECK_EQ(descendant->status(), kEvaluating);
// ii. Set m.[[Status]] to "evaluated".
// iii. Set m.[[EvaluationError]] to result.
Module::RecordErrorUsingPendingException(isolate, descendant);
}
// If the exception was a termination exception, rejecting the promise
// would resume execution, and our API contract is to return an empty
// handle. The module's status should be set to kErrored and the
// exception field should be set to `null`.
if (!isolate->is_catchable_by_javascript(isolate->pending_exception())) {
DCHECK_EQ(module->status(), kErrored);
DCHECK_EQ(module->exception(), *isolate->factory()->null_value());
CHECK_EQ(module->status(), kErrored);
CHECK_EQ(module->exception(), *isolate->factory()->null_value());
return {};
}
CHECK_EQ(module->exception(), isolate->pending_exception());
// d. Perform ! Call(capability.[[Reject]], undefined,
// «result.[[Value]]»).
@ -721,51 +740,15 @@ MaybeHandle<Object> SourceTextModule::EvaluateMaybeAsync(
JSPromise::Resolve(capability, isolate->factory()->undefined_value())
.ToHandleChecked();
}
// c. Assert: stack is empty.
DCHECK(stack.empty());
}
// 11. Return capability.[[Promise]].
return capability;
}
MaybeHandle<Object> SourceTextModule::Evaluate(
Isolate* isolate, Handle<SourceTextModule> module) {
// Evaluate () Concrete Method continued from EvaluateMaybeAsync.
CHECK(module->status() == kLinked || module->status() == kEvaluated);
// 5. Let stack be a new empty List.
Zone zone(isolate->allocator(), ZONE_NAME);
ZoneForwardList<Handle<SourceTextModule>> stack(&zone);
unsigned dfs_index = 0;
// 8. Let result be InnerModuleEvaluation(module, stack, 0).
// 9. If result is an abrupt completion, then
Handle<Object> result;
if (!InnerModuleEvaluation(isolate, module, &stack, &dfs_index)
.ToHandle(&result)) {
// a. For each Cyclic Module Record m in stack, do
for (auto& descendant : stack) {
// i. Assert: m.[[Status]] is "evaluating".
CHECK_EQ(descendant->status(), kEvaluating);
// ii. Set m.[[Status]] to "evaluated".
// iii. Set m.[[EvaluationError]] to result.
Module::RecordErrorUsingPendingException(isolate, descendant);
}
#ifdef DEBUG
if (isolate->is_catchable_by_javascript(isolate->pending_exception())) {
CHECK_EQ(module->exception(), isolate->pending_exception());
} else {
CHECK_EQ(module->exception(), *isolate->factory()->null_value());
}
#endif // DEBUG
} else {
// 10. Otherwise,
// c. Assert: stack is empty.
DCHECK(stack.empty());
}
return result;
}
void SourceTextModule::AsyncModuleExecutionFulfilled(
Isolate* isolate, Handle<SourceTextModule> module) {
// 1. If module.[[Status]] is evaluated, then

View File

@ -179,10 +179,6 @@ class SourceTextModule
AsyncParentCompletionSet* exec_list);
// Implementation of spec concrete method Evaluate.
static V8_WARN_UNUSED_RESULT MaybeHandle<Object> EvaluateMaybeAsync(
Isolate* isolate, Handle<SourceTextModule> module);
// Continued implementation of spec concrete method Evaluate.
static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
Isolate* isolate, Handle<SourceTextModule> module);