@@ -46,7 +46,6 @@ using v8::Message;
4646using v8::MicrotaskQueue;
4747using v8::Module;
4848using v8::ModuleImportPhase;
49- using v8::ModuleRequest;
5049using v8::Name;
5150using v8::Nothing;
5251using v8::Null;
@@ -63,6 +62,56 @@ using v8::UnboundModuleScript;
6362using v8::Undefined;
6463using v8::Value;
6564
65+ ModulePhase to_phase_constant (ModuleImportPhase phase) {
66+ switch (phase) {
67+ case ModuleImportPhase::kEvaluation :
68+ return kEvaluationPhase ;
69+ case ModuleImportPhase::kSource :
70+ return kSourcePhase ;
71+ }
72+ UNREACHABLE ();
73+ }
74+
75+ void ModuleRequest::MemoryInfo (MemoryTracker* tracker) const {
76+ tracker->TrackField (" specifier" , specifier);
77+ tracker->TrackField (" import_attributes" , import_attributes);
78+ tracker->TrackField (" phase" , static_cast <int >(phase));
79+ }
80+
81+ template <int elements_per_attribute>
82+ ModuleRequest ModuleRequest::From (Local<Context> context,
83+ Local<String> specifier,
84+ Local<FixedArray> import_attributes,
85+ ModulePhase phase) {
86+ CHECK_EQ (import_attributes->Length () % elements_per_attribute, 0 );
87+ Isolate* isolate = context->GetIsolate ();
88+ size_t num_attributes = import_attributes->Length () / elements_per_attribute;
89+ ImportAttributeVector attributes;
90+ attributes.reserve (num_attributes);
91+
92+ for (int i = 0 ; i < import_attributes->Length ();
93+ i += elements_per_attribute) {
94+ Local<String> v8_key = import_attributes->Get (context, i).As <String>();
95+ Local<String> v8_value =
96+ import_attributes->Get (context, i + 1 ).As <String>();
97+ Utf8Value key_utf8 (isolate, v8_key);
98+ Utf8Value value_utf8 (isolate, v8_value);
99+
100+ attributes.emplace_back (key_utf8.ToString (), value_utf8.ToString ());
101+ }
102+
103+ Utf8Value utf8_specifier (isolate, specifier);
104+ return ModuleRequest{utf8_specifier.ToString (), attributes, phase};
105+ }
106+
107+ ModuleRequest ModuleRequest::From (Local<Context> context,
108+ Local<v8::ModuleRequest> v8_request) {
109+ return From (context,
110+ v8_request->GetSpecifier (),
111+ v8_request->GetImportAttributes (),
112+ to_phase_constant (v8_request->GetPhase ()));
113+ }
114+
66115ModuleWrap::ModuleWrap (Realm* realm,
67116 Local<Object> object,
68117 Local<Module> module ,
@@ -422,16 +471,6 @@ MaybeLocal<Module> ModuleWrap::CompileSourceTextModule(
422471 return scope.Escape (module );
423472}
424473
425- ModulePhase to_phase_constant (ModuleImportPhase phase) {
426- switch (phase) {
427- case ModuleImportPhase::kEvaluation :
428- return kEvaluationPhase ;
429- case ModuleImportPhase::kSource :
430- return kSourcePhase ;
431- }
432- UNREACHABLE ();
433- }
434-
435474static Local<Object> createImportAttributesContainer (
436475 Realm* realm,
437476 Isolate* isolate,
@@ -462,8 +501,8 @@ static Local<Array> createModuleRequestsContainer(
462501 LocalVector<Value> requests (isolate, raw_requests->Length ());
463502
464503 for (int i = 0 ; i < raw_requests->Length (); i++) {
465- Local<ModuleRequest> module_request =
466- raw_requests->Get (realm->context (), i).As <ModuleRequest>();
504+ Local<v8:: ModuleRequest> module_request =
505+ raw_requests->Get (realm->context (), i).As <v8:: ModuleRequest>();
467506
468507 Local<String> specifier = module_request->GetSpecifier ();
469508
@@ -509,7 +548,7 @@ void ModuleWrap::GetModuleRequests(const FunctionCallbackInfo<Value>& args) {
509548 realm, isolate, module ->GetModuleRequests ()));
510549}
511550
512- // moduleWrap.link(specifiers, moduleWraps)
551+ // moduleWrap.link(moduleWraps)
513552void ModuleWrap::Link (const FunctionCallbackInfo<Value>& args) {
514553 Realm* realm = Realm::GetCurrent (args);
515554 Isolate* isolate = args.GetIsolate ();
@@ -518,33 +557,28 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
518557 ModuleWrap* dependent;
519558 ASSIGN_OR_RETURN_UNWRAP (&dependent, args.This ());
520559
521- CHECK_EQ (args.Length (), 2 );
560+ CHECK_EQ (args.Length (), 1 );
522561
523- Local<Array> specifiers = args[0 ].As <Array>();
524- Local<Array> modules = args[1 ].As <Array>();
525- CHECK_EQ (specifiers->Length (), modules->Length ());
562+ Local<FixedArray> requests =
563+ dependent->module_ .Get (isolate)->GetModuleRequests ();
564+ Local<Array> modules = args[0 ].As <Array>();
565+ CHECK_EQ (modules->Length (), static_cast <uint32_t >(requests->Length ()));
526566
527- std::vector<Global<Value>> specifiers_buffer;
528- if (FromV8Array (context, specifiers, &specifiers_buffer).IsNothing ()) {
529- return ;
530- }
531567 std::vector<Global<Value>> modules_buffer;
532568 if (FromV8Array (context, modules, &modules_buffer).IsNothing ()) {
533569 return ;
534570 }
535571
536- for (uint32_t i = 0 ; i < specifiers->Length (); i++) {
537- Local<String> specifier_str =
538- specifiers_buffer[i].Get (isolate).As <String>();
572+ for (uint32_t i = 0 ; i < modules_buffer.size (); i++) {
539573 Local<Object> module_object = modules_buffer[i].Get (isolate).As <Object>();
540574
541575 CHECK (
542576 realm->isolate_data ()->module_wrap_constructor_template ()->HasInstance (
543577 module_object));
544578
545- Utf8Value specifier (isolate, specifier_str);
546- dependent-> resolve_cache_ [specifier. ToString ()]. Reset (isolate,
547- module_object);
579+ ModuleRequest module_request = ModuleRequest::From (
580+ context, requests-> Get (context, i). As <v8::ModuleRequest>());
581+ dependent-> resolve_cache_ [module_request]. Reset (isolate, module_object);
548582 }
549583}
550584
@@ -924,27 +958,28 @@ MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
924958 return MaybeLocal<Module>();
925959 }
926960
927- Utf8Value specifier_utf8 (isolate, specifier);
928- std::string specifier_std (*specifier_utf8, specifier_utf8.length ());
961+ // ResolveModuleCallback for kEvaluationPhase only.
962+ const ModulePhase phase = ModulePhase::kEvaluationPhase ;
963+ ModuleRequest request =
964+ ModuleRequest::From (context, specifier, import_attributes, phase);
929965
930966 ModuleWrap* dependent = GetFromModule (env, referrer);
931967 if (dependent == nullptr ) {
932968 THROW_ERR_VM_MODULE_LINK_FAILURE (
933- env, " request for '%s' is from invalid module" , specifier_std );
969+ env, " request for '%s' is from invalid module" , request. specifier );
934970 return MaybeLocal<Module>();
935971 }
936972
937- if (dependent->resolve_cache_ .count (specifier_std ) != 1 ) {
973+ if (dependent->resolve_cache_ .count (request ) != 1 ) {
938974 THROW_ERR_VM_MODULE_LINK_FAILURE (
939- env, " request for '%s' is not in cache" , specifier_std );
975+ env, " request for '%s' is not in cache" , request. specifier );
940976 return MaybeLocal<Module>();
941977 }
942978
943- Local<Object> module_object =
944- dependent->resolve_cache_ [specifier_std].Get (isolate);
979+ Local<Object> module_object = dependent->resolve_cache_ [request].Get (isolate);
945980 if (module_object.IsEmpty () || !module_object->IsObject ()) {
946981 THROW_ERR_VM_MODULE_LINK_FAILURE (
947- env, " request for '%s' did not return an object" , specifier_std );
982+ env, " request for '%s' did not return an object" , request. specifier );
948983 return MaybeLocal<Module>();
949984 }
950985
@@ -965,27 +1000,28 @@ MaybeLocal<Object> ModuleWrap::ResolveSourceCallback(
9651000 return MaybeLocal<Object>();
9661001 }
9671002
968- Utf8Value specifier_utf8 (isolate, specifier);
969- std::string specifier_std (*specifier_utf8, specifier_utf8.length ());
1003+ // ResolveSourceCallback for kSourcePhase only.
1004+ const ModulePhase phase = ModulePhase::kSourcePhase ;
1005+ ModuleRequest request =
1006+ ModuleRequest::From (context, specifier, import_attributes, phase);
9701007
9711008 ModuleWrap* dependent = GetFromModule (env, referrer);
9721009 if (dependent == nullptr ) {
9731010 THROW_ERR_VM_MODULE_LINK_FAILURE (
974- env, " request for '%s' is from invalid module" , specifier_std );
1011+ env, " request for '%s' is from invalid module" , request. specifier );
9751012 return MaybeLocal<Object>();
9761013 }
9771014
978- if (dependent->resolve_cache_ .count (specifier_std ) != 1 ) {
1015+ if (dependent->resolve_cache_ .count (request ) != 1 ) {
9791016 THROW_ERR_VM_MODULE_LINK_FAILURE (
980- env, " request for '%s' is not in cache" , specifier_std );
1017+ env, " request for '%s' is not in cache" , request. specifier );
9811018 return MaybeLocal<Object>();
9821019 }
9831020
984- Local<Object> module_object =
985- dependent->resolve_cache_ [specifier_std].Get (isolate);
1021+ Local<Object> module_object = dependent->resolve_cache_ [request].Get (isolate);
9861022 if (module_object.IsEmpty () || !module_object->IsObject ()) {
9871023 THROW_ERR_VM_MODULE_LINK_FAILURE (
988- env, " request for '%s' did not return an object" , specifier_std );
1024+ env, " request for '%s' did not return an object" , request. specifier );
9891025 return MaybeLocal<Object>();
9901026 }
9911027
0 commit comments