Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/internal/modules/esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ class ModuleLoader {
if (!job.module) {
assert.fail(getRaceMessage(filename, parentFilename));
}
if (job.module.async) {
if (job.module.hasAsyncGraph) {
throw new ERR_REQUIRE_ASYNC_MODULE(filename, parentFilename);
}
const status = job.module.getStatus();
Expand Down
15 changes: 8 additions & 7 deletions lib/internal/modules/esm/module_job.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,13 @@ class ModuleJob extends ModuleJobBase {
// FIXME(joyeecheung): this cannot fully handle < kInstantiated. Make the linking
// fully synchronous instead.
if (status === kUninstantiated) {
this.module.async = this.module.instantiateSync();
this.module.hasAsyncGraph = this.module.instantiateSync();
status = this.module.getStatus();
}
if (status === kInstantiated || status === kErrored) {
const filename = urlToFilename(this.url);
const parentFilename = urlToFilename(parent?.filename);
this.module.async ??= this.module.isGraphAsync();
this.module.hasAsyncGraph ??= this.module.isGraphAsync();

if (this.module.async && !getOptionValue('--experimental-print-required-tla')) {
throw new ERR_REQUIRE_ASYNC_MODULE(filename, parentFilename);
Expand Down Expand Up @@ -370,7 +370,7 @@ class ModuleJob extends ModuleJobBase {
try {
await this.module.evaluate(timeout, breakOnSigint);
} catch (e) {
explainCommonJSGlobalLikeNotDefinedError(e, this.module.url, this.module.hasTopLevelAwait());
explainCommonJSGlobalLikeNotDefinedError(e, this.module.url, this.module.hasTopLevelAwait);
throw e;
}
return { __proto__: null, module: this.module };
Expand Down Expand Up @@ -490,24 +490,25 @@ class ModuleJobSync extends ModuleJobBase {
debug('ModuleJobSync.runSync()', this.module);
assert(this.phase === kEvaluationPhase);
// TODO(joyeecheung): add the error decoration logic from the async instantiate.
this.module.async = this.module.instantiateSync();
this.module.hasAsyncGraph = this.module.instantiateSync();
// If --experimental-print-required-tla is true, proceeds to evaluation even
// if it's async because we want to search for the TLA and help users locate
// them.
// TODO(joyeecheung): track the asynchroniticy using v8::Module::HasTopLevelAwait()
// and we'll be able to throw right after compilation of the modules, using acron
// to find and print the TLA.
// to find and print the TLA. This requires the linking to be synchronous in case
// it runs into cached asynchronous modules that are not yet fetched.
const parentFilename = urlToFilename(parent?.filename);
const filename = urlToFilename(this.url);
if (this.module.async && !getOptionValue('--experimental-print-required-tla')) {
if (this.module.hasAsyncGraph && !getOptionValue('--experimental-print-required-tla')) {
throw new ERR_REQUIRE_ASYNC_MODULE(filename, parentFilename);
}
setHasStartedUserESMExecution();
try {
const namespace = this.module.evaluateSync(filename, parentFilename);
return { __proto__: null, module: this.module, namespace };
} catch (e) {
explainCommonJSGlobalLikeNotDefinedError(e, this.module.url, this.module.hasTopLevelAwait());
explainCommonJSGlobalLikeNotDefinedError(e, this.module.url, this.module.hasTopLevelAwait);
throw e;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/env_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
V(gid_string, "gid") \
V(groups_string, "groups") \
V(has_regexp_groups_string, "hasRegExpGroups") \
V(has_top_level_await_string, "hasTopLevelAwait") \
V(hash_string, "hash") \
V(h2_string, "h2") \
V(handle_string, "handle") \
Expand Down
32 changes: 8 additions & 24 deletions src/module_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ using errors::TryCatchScope;
using node::contextify::ContextifyContext;
using v8::Array;
using v8::ArrayBufferView;
using v8::Boolean;
using v8::Context;
using v8::Data;
using v8::EscapableHandleScope;
Expand Down Expand Up @@ -395,6 +396,13 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
return;
}

if (that->Set(context,
realm->env()->has_top_level_await_string(),
Boolean::New(isolate, module->HasTopLevelAwait()))
.IsNothing()) {
return;
}

if (that->Set(context,
realm->env()->source_url_string(),
module->GetUnboundModuleScript()->GetSourceURL())
Expand Down Expand Up @@ -948,27 +956,6 @@ void ModuleWrap::IsGraphAsync(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(module->IsGraphAsync());
}

void ModuleWrap::HasTopLevelAwait(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
ModuleWrap* obj;
ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());

Local<Module> module = obj->module_.Get(isolate);

// Check if module is valid
if (module.IsEmpty()) {
args.GetReturnValue().Set(false);
return;
}

// For source text modules, check if the graph is async
// For synthetic modules, it's always false
bool has_top_level_await =
module->IsSourceTextModule() && module->IsGraphAsync();

args.GetReturnValue().Set(has_top_level_await);
}

void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
ModuleWrap* obj;
Expand Down Expand Up @@ -1392,8 +1379,6 @@ void ModuleWrap::CreatePerIsolateProperties(IsolateData* isolate_data,
SetProtoMethodNoSideEffect(isolate, tpl, "getNamespace", GetNamespace);
SetProtoMethodNoSideEffect(isolate, tpl, "getStatus", GetStatus);
SetProtoMethodNoSideEffect(isolate, tpl, "isGraphAsync", IsGraphAsync);
SetProtoMethodNoSideEffect(
isolate, tpl, "hasTopLevelAwait", HasTopLevelAwait);
SetProtoMethodNoSideEffect(isolate, tpl, "getError", GetError);
SetConstructorFunction(isolate, target, "ModuleWrap", tpl);
isolate_data->set_module_wrap_constructor_template(tpl);
Expand Down Expand Up @@ -1456,7 +1441,6 @@ void ModuleWrap::RegisterExternalReferences(
registry->Register(GetStatus);
registry->Register(GetError);
registry->Register(IsGraphAsync);
registry->Register(HasTopLevelAwait);

registry->Register(CreateRequiredModuleFacade);

Expand Down
2 changes: 0 additions & 2 deletions src/module_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ class ModuleWrap : public BaseObject {
v8::Local<v8::Module> module,
v8::Local<v8::Object> meta);

static void HasTopLevelAwait(const v8::FunctionCallbackInfo<v8::Value>& args);

v8::Local<v8::Context> context() const;
v8::Maybe<bool> CheckUnsettledTopLevelAwait();

Expand Down
Loading