@@ -185,30 +185,6 @@ Local<Context> ModuleWrap::context() const {
185185 return obj.As <Object>()->GetCreationContextChecked ();
186186}
187187
188- ModuleWrap* ModuleWrap::GetLinkedRequest (uint32_t index) {
189- DCHECK (IsLinked ());
190- Isolate* isolate = env ()->isolate ();
191- EscapableHandleScope scope (isolate);
192- Local<Data> linked_requests_data =
193- object ()->GetInternalField (kLinkedRequestsSlot );
194- DCHECK (linked_requests_data->IsValue () &&
195- linked_requests_data.As <Value>()->IsArray ());
196- Local<Array> requests = linked_requests_data.As <Array>();
197-
198- CHECK_LT (index, requests->Length ());
199-
200- Local<Value> module_value;
201- if (!requests->Get (context (), index).ToLocal (&module_value)) {
202- return nullptr ;
203- }
204- CHECK (module_value->IsObject ());
205- Local<Object> module_object = module_value.As <Object>();
206-
207- ModuleWrap* module_wrap;
208- ASSIGN_OR_RETURN_UNWRAP (&module_wrap, module_object, nullptr );
209- return module_wrap;
210- }
211-
212188ModuleWrap* ModuleWrap::GetFromModule (Environment* env,
213189 Local<Module> module ) {
214190 auto range = env->hash_to_module_map .equal_range (module ->GetIdentityHash ());
@@ -644,6 +620,7 @@ void ModuleWrap::GetModuleRequests(const FunctionCallbackInfo<Value>& args) {
644620// moduleWrap.link(moduleWraps)
645621void ModuleWrap::Link (const FunctionCallbackInfo<Value>& args) {
646622 Isolate* isolate = args.GetIsolate ();
623+ HandleScope handle_scope (isolate);
647624 Realm* realm = Realm::GetCurrent (args);
648625 Local<Context> context = realm->context ();
649626
@@ -655,8 +632,13 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
655632 Local<FixedArray> requests =
656633 dependent->module_ .Get (isolate)->GetModuleRequests ();
657634 Local<Array> modules = args[0 ].As <Array>();
658- int request_count = requests->Length ();
659- CHECK_EQ (modules->Length (), static_cast <uint32_t >(request_count));
635+ std::vector<Global<Value>> modules_vector;
636+ if (FromV8Array (context, modules, &modules_vector).IsEmpty ()) {
637+ return ;
638+ }
639+ size_t request_count = static_cast <size_t >(requests->Length ());
640+ CHECK_EQ (modules_vector.size (), request_count);
641+ std::vector<ModuleWrap*> linked_module_wraps (request_count);
660642
661643 // Track the duplicated module requests. For example if a modulelooks like
662644 // this:
@@ -670,13 +652,13 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
670652 // module request 1 would be mapped to mod_key and both should resolve to the
671653 // module identified by module request 0 (the first one with this identity),
672654 // and module request 2 should resolve the module identified by index 2.
673- std::unordered_map<ModuleCacheKey, int , ModuleCacheKey::Hash>
655+ std::unordered_map<ModuleCacheKey, size_t , ModuleCacheKey::Hash>
674656 module_request_map;
675- Local<Value> current_module;
676- Local<Value> first_seen_module;
677- for (int i = 0 ; i < request_count; i++) {
657+
658+ for (size_t i = 0 ; i < request_count; i++) {
678659 // TODO(joyeecheung): merge this with the serializeKey() in module_map.js.
679660 // This currently doesn't sort the import attributes.
661+ Local<Value> module_value = modules_vector[i].Get (isolate);
680662 ModuleCacheKey module_cache_key = ModuleCacheKey::From (
681663 context, requests->Get (context, i).As <ModuleRequest>());
682664 auto it = module_request_map.find (module_cache_key);
@@ -686,13 +668,12 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
686668 // check here.
687669 module_request_map[module_cache_key] = i;
688670 } else { // This identity has been seen before, check for mismatch.
689- int first_seen_index = it->second ;
671+ size_t first_seen_index = it->second ;
690672 // Check that the module is the same as the one resolved by the first
691673 // request with this identity.
692- if (!modules->Get (context, i).ToLocal (¤t_module) ||
693- !modules->Get (context, first_seen_index)
694- .ToLocal (&first_seen_module) ||
695- !current_module->StrictEquals (first_seen_module)) {
674+ Local<Value> first_seen_value =
675+ modules_vector[first_seen_index].Get (isolate);
676+ if (!module_value->StrictEquals (first_seen_value)) {
696677 // If the module is different from the one of the same request, throw an
697678 // error.
698679 THROW_ERR_MODULE_LINK_MISMATCH (
@@ -705,9 +686,16 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
705686 return ;
706687 }
707688 }
689+
690+ CHECK (module_value->IsObject ()); // Guaranteed by link methods in JS land.
691+ ModuleWrap* resolved =
692+ BaseObject::Unwrap<ModuleWrap>(module_value.As <Object>());
693+ CHECK_NOT_NULL (resolved); // Guaranteed by link methods in JS land.
694+ linked_module_wraps[i] = resolved;
708695 }
709696
710697 args.This ()->SetInternalField (kLinkedRequestsSlot , modules);
698+ std::swap (dependent->linked_module_wraps_ , linked_module_wraps);
711699 dependent->linked_ = true ;
712700}
713701
@@ -1109,10 +1097,15 @@ Maybe<ModuleWrap*> ModuleWrap::ResolveModule(Local<Context> context,
11091097 return Nothing<ModuleWrap*>();
11101098 }
11111099
1112- ModuleWrap* module_wrap =
1113- dependent->GetLinkedRequest (static_cast <uint32_t >(module_request_index));
1114- CHECK_NOT_NULL (module_wrap);
1115- return Just (module_wrap);
1100+ size_t linked_module_count = dependent->linked_module_wraps_ .size ();
1101+ if (linked_module_count > 0 ) {
1102+ CHECK_LT (module_request_index, linked_module_count);
1103+ } else {
1104+ UNREACHABLE (" Module resolution callback invoked for a module"
1105+ " without linked requests" );
1106+ }
1107+
1108+ return Just (dependent->linked_module_wraps_ [module_request_index]);
11161109}
11171110
11181111static MaybeLocal<Promise> ImportModuleDynamicallyWithPhase (
0 commit comments