lib,src: cache ModuleWrap.hasAsyncGraph · nodejs/node@ff13d1d
@@ -56,6 +56,7 @@ using v8::ObjectTemplate;
5656using v8::PrimitiveArray;
5757using v8::Promise;
5858using v8::PromiseRejectEvent;
59+using v8::PropertyCallbackInfo;
5960using v8::ScriptCompiler;
6061using v8::ScriptOrigin;
6162using v8::String;
@@ -158,6 +159,8 @@ ModuleWrap::ModuleWrap(Realm* realm,
158159159160if (!synthetic_evaluation_step->IsUndefined()) {
160161 synthetic_ = true;
162+// Synthetic modules have no dependencies.
163+ linked_ = true;
161164 }
162165MakeWeak();
163166 module_.SetWeak();
@@ -240,7 +243,7 @@ Maybe<bool> ModuleWrap::CheckUnsettledTopLevelAwait() {
240243return Just(true);
241244 }
242245243-if (!module->IsGraphAsync()) { // There is no TLA, no need to check.
246+if (!HasAsyncGraph()) { // There is no TLA, no need to check.
244247return Just(true);
245248 }
246249@@ -263,6 +266,16 @@ Maybe<bool> ModuleWrap::CheckUnsettledTopLevelAwait() {
263266return Just(false);
264267}
265268269+bool ModuleWrap::HasAsyncGraph() {
270+if (!has_async_graph_.has_value()) {
271+ Isolate* isolate = env()->isolate();
272+ HandleScope scope(isolate);
273+274+ has_async_graph_ = module_.Get(isolate)->IsGraphAsync();
275+ }
276+return has_async_graph_.value();
277+}
278+266279Local<PrimitiveArray> ModuleWrap::GetHostDefinedOptions(
267280 Isolate* isolate, Local<Symbol> id_symbol) {
268281 Local<PrimitiveArray> host_defined_options =
@@ -687,25 +700,28 @@ void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
687700ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
688701 Local<Context> context = obj->context();
689702 Local<Module> module = obj->module_.Get(isolate);
703+ Environment* env = realm->env();
690704691705if (!obj->IsLinked()) {
692-THROW_ERR_VM_MODULE_LINK_FAILURE(realm->env(), "module is not linked");
706+THROW_ERR_VM_MODULE_LINK_FAILURE(env, "module is not linked");
693707return;
694708 }
695709696- TryCatchScope try_catch(realm->env());
697-USE(module->InstantiateModule(
698- context, ResolveModuleCallback, ResolveSourceCallback));
710+ {
711+ TryCatchScope try_catch(env);
712+USE(module->InstantiateModule(
713+ context, ResolveModuleCallback, ResolveSourceCallback));
699714700-if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
701-CHECK(!try_catch.Message().IsEmpty());
702-CHECK(!try_catch.Exception().IsEmpty());
703-AppendExceptionLine(realm->env(),
704- try_catch.Exception(),
705- try_catch.Message(),
706- ErrorHandlingMode::MODULE_ERROR);
707- try_catch.ReThrow();
708-return;
715+if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
716+CHECK(!try_catch.Message().IsEmpty());
717+CHECK(!try_catch.Exception().IsEmpty());
718+AppendExceptionLine(env,
719+ try_catch.Exception(),
720+ try_catch.Message(),
721+ ErrorHandlingMode::MODULE_ERROR);
722+ try_catch.ReThrow();
723+return;
724+ }
709725 }
710726}
711727@@ -790,37 +806,6 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
790806 }
791807}
792808793-void ModuleWrap::InstantiateSync(const FunctionCallbackInfo<Value>& args) {
794- Realm* realm = Realm::GetCurrent(args);
795- Isolate* isolate = args.GetIsolate();
796- ModuleWrap* obj;
797-ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
798- Local<Context> context = obj->context();
799- Local<Module> module = obj->module_.Get(isolate);
800- Environment* env = realm->env();
801-802- {
803- TryCatchScope try_catch(env);
804-USE(module->InstantiateModule(
805- context, ResolveModuleCallback, ResolveSourceCallback));
806-807-if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
808-CHECK(!try_catch.Message().IsEmpty());
809-CHECK(!try_catch.Exception().IsEmpty());
810-AppendExceptionLine(env,
811- try_catch.Exception(),
812- try_catch.Message(),
813- ErrorHandlingMode::MODULE_ERROR);
814- try_catch.ReThrow();
815-return;
816- }
817- }
818-819-// TODO(joyeecheung): record Module::HasTopLevelAwait() in every ModuleWrap
820-// and infer the asynchronicity from a module's children during linking.
821- args.GetReturnValue().Set(module->IsGraphAsync());
822-}
823-824809Maybe<void> ThrowIfPromiseRejected(Realm* realm, Local<Promise> promise) {
825810 Isolate* isolate = realm->isolate();
826811 Local<Context> context = realm->context();
@@ -886,7 +871,7 @@ void ModuleWrap::EvaluateSync(const FunctionCallbackInfo<Value>& args) {
886871return;
887872 }
888873889-if (module->IsGraphAsync()) {
874+if (obj->HasAsyncGraph()) {
890875CHECK(env->options()->print_required_tla);
891876auto stalled_messages =
892877 std::get<1>(module->GetStalledTopLevelAwaitMessages(isolate));
@@ -908,52 +893,15 @@ void ModuleWrap::EvaluateSync(const FunctionCallbackInfo<Value>& args) {
908893 args.GetReturnValue().Set(module->GetModuleNamespace());
909894}
910895911-void ModuleWrap::GetNamespaceSync(const FunctionCallbackInfo<Value>& args) {
912- Realm* realm = Realm::GetCurrent(args);
913- Isolate* isolate = args.GetIsolate();
914- ModuleWrap* obj;
915-ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
916- Local<Module> module = obj->module_.Get(isolate);
917-918-switch (module->GetStatus()) {
919-case Module::Status::kUninstantiated:
920-case Module::Status::kInstantiating:
921-return realm->env()->ThrowError(
922-"Cannot get namespace, module has not been instantiated");
923-case Module::Status::kInstantiated:
924-case Module::Status::kEvaluating:
925-case Module::Status::kEvaluated:
926-case Module::Status::kErrored:
927-break;
928- }
929-930-if (module->IsGraphAsync()) {
931-return THROW_ERR_REQUIRE_ASYNC_MODULE(realm->env(), args[0], args[1]);
932- }
933- Local<Value> result = module->GetModuleNamespace();
934- args.GetReturnValue().Set(result);
935-}
936-937896void ModuleWrap::GetNamespace(const FunctionCallbackInfo<Value>& args) {
938897 Realm* realm = Realm::GetCurrent(args);
939898 Isolate* isolate = args.GetIsolate();
940899 ModuleWrap* obj;
941900ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
942901943902 Local<Module> module = obj->module_.Get(isolate);
944-945-switch (module->GetStatus()) {
946-case Module::Status::kUninstantiated:
947-case Module::Status::kInstantiating:
948-return realm->env()->ThrowError(
949-"cannot get namespace, module has not been instantiated");
950-case Module::Status::kInstantiated:
951-case Module::Status::kEvaluating:
952-case Module::Status::kEvaluated:
953-case Module::Status::kErrored:
954-break;
955-default:
956-UNREACHABLE();
903+if (module->GetStatus() < Module::kInstantiated) {
904+return THROW_ERR_MODULE_NOT_INSTANTIATED(realm->env());
957905 }
958906959907 Local<Value> result = module->GetModuleNamespace();
@@ -1004,23 +952,28 @@ void ModuleWrap::GetStatus(const FunctionCallbackInfo<Value>& args) {
1004952 args.GetReturnValue().Set(module->GetStatus());
1005953}
10069541007-void ModuleWrap::IsGraphAsync(const FunctionCallbackInfo<Value>& args) {
955+void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
1008956 Isolate* isolate = args.GetIsolate();
1009957 ModuleWrap* obj;
1010958ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
10119591012960 Local<Module> module = obj->module_.Get(isolate);
1013-1014- args.GetReturnValue().Set(module->IsGraphAsync());
961+ args.GetReturnValue().Set(module->GetException());
1015962}
10169631017-void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
964+void ModuleWrap::HasAsyncGraph(Local<Name> property,
965+const PropertyCallbackInfo<Value>& args) {
1018966 Isolate* isolate = args.GetIsolate();
967+ Environment* env = Environment::GetCurrent(isolate);
1019968 ModuleWrap* obj;
1020969ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
10219701022971 Local<Module> module = obj->module_.Get(isolate);
1023- args.GetReturnValue().Set(module->GetException());
972+if (module->GetStatus() < Module::kInstantiated) {
973+return THROW_ERR_MODULE_NOT_INSTANTIATED(env);
974+ }
975+976+ args.GetReturnValue().Set(obj->HasAsyncGraph());
1024977}
10259781026979// static
@@ -1424,10 +1377,8 @@ void ModuleWrap::CreatePerIsolateProperties(IsolateData* isolate_data,
1424137714251378SetProtoMethod(isolate, tpl, "link", Link);
14261379SetProtoMethod(isolate, tpl, "getModuleRequests", GetModuleRequests);
1427-SetProtoMethod(isolate, tpl, "instantiateSync", InstantiateSync);
1428-SetProtoMethod(isolate, tpl, "evaluateSync", EvaluateSync);
1429-SetProtoMethod(isolate, tpl, "getNamespaceSync", GetNamespaceSync);
14301380SetProtoMethod(isolate, tpl, "instantiate", Instantiate);
1381+SetProtoMethod(isolate, tpl, "evaluateSync", EvaluateSync);
14311382SetProtoMethod(isolate, tpl, "evaluate", Evaluate);
14321383SetProtoMethod(isolate, tpl, "setExport", SetSyntheticExport);
14331384SetProtoMethod(isolate, tpl, "setModuleSourceObject", SetModuleSourceObject);
@@ -1436,9 +1387,12 @@ void ModuleWrap::CreatePerIsolateProperties(IsolateData* isolate_data,
14361387 isolate, tpl, "createCachedData", CreateCachedData);
14371388SetProtoMethodNoSideEffect(isolate, tpl, "getNamespace", GetNamespace);
14381389SetProtoMethodNoSideEffect(isolate, tpl, "getStatus", GetStatus);
1439-SetProtoMethodNoSideEffect(isolate, tpl, "isGraphAsync", IsGraphAsync);
14401390SetProtoMethodNoSideEffect(isolate, tpl, "getError", GetError);
14411391SetConstructorFunction(isolate, target, "ModuleWrap", tpl);
1392+1393+ tpl->InstanceTemplate()->SetLazyDataProperty(
1394+FIXED_ONE_BYTE_STRING(isolate, "hasAsyncGraph"), HasAsyncGraph);
1395+14421396 isolate_data->set_module_wrap_constructor_template(tpl);
1443139714441398SetMethod(isolate,
@@ -1486,9 +1440,7 @@ void ModuleWrap::RegisterExternalReferences(
1486144014871441 registry->Register(Link);
14881442 registry->Register(GetModuleRequests);
1489- registry->Register(InstantiateSync);
14901443 registry->Register(EvaluateSync);
1491- registry->Register(GetNamespaceSync);
14921444 registry->Register(Instantiate);
14931445 registry->Register(Evaluate);
14941446 registry->Register(SetSyntheticExport);
@@ -1498,7 +1450,7 @@ void ModuleWrap::RegisterExternalReferences(
14981450 registry->Register(GetNamespace);
14991451 registry->Register(GetStatus);
15001452 registry->Register(GetError);
1501- registry->Register(IsGraphAsync);
1453+ registry->Register(HasAsyncGraph);
1502145415031455 registry->Register(CreateRequiredModuleFacade);
15041456