Skip to content

Commit 9f16293

Browse files
committed
fixup! fixup! esm: use index-based resolution callbacks
1 parent 8d3012c commit 9f16293

File tree

2 files changed

+37
-41
lines changed

2 files changed

+37
-41
lines changed

src/module_wrap.cc

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
212188
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
213189
Local<Module> module) {
214190
auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
@@ -655,8 +631,13 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
655631
Local<FixedArray> requests =
656632
dependent->module_.Get(isolate)->GetModuleRequests();
657633
Local<Array> modules = args[0].As<Array>();
658-
int request_count = requests->Length();
659-
CHECK_EQ(modules->Length(), static_cast<uint32_t>(request_count));
634+
std::vector<Global<Value>> modules_vector;
635+
if (FromV8Array(context, modules, &modules_vector).IsEmpty()) {
636+
return;
637+
}
638+
size_t request_count = static_cast<size_t>(requests->Length());
639+
CHECK_EQ(modules_vector.size(), request_count);
640+
std::vector<ModuleWrap*> linked_module_wraps(request_count);
660641

661642
// Track the duplicated module requests. For example if a modulelooks like
662643
// this:
@@ -670,13 +651,13 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
670651
// module request 1 would be mapped to mod_key and both should resolve to the
671652
// module identified by module request 0 (the first one with this identity),
672653
// and module request 2 should resolve the module identified by index 2.
673-
std::unordered_map<ModuleCacheKey, int, ModuleCacheKey::Hash>
654+
std::unordered_map<ModuleCacheKey, size_t, ModuleCacheKey::Hash>
674655
module_request_map;
675-
Local<Value> current_module;
676-
Local<Value> first_seen_module;
677-
for (int i = 0; i < request_count; i++) {
656+
657+
for (size_t i = 0; i < request_count; i++) {
678658
// TODO(joyeecheung): merge this with the serializeKey() in module_map.js.
679659
// This currently doesn't sort the import attributes.
660+
Local<Value> module_value = modules_vector[i].Get(isolate);
680661
ModuleCacheKey module_cache_key = ModuleCacheKey::From(
681662
context, requests->Get(context, i).As<ModuleRequest>());
682663
auto it = module_request_map.find(module_cache_key);
@@ -689,10 +670,9 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
689670
int first_seen_index = it->second;
690671
// Check that the module is the same as the one resolved by the first
691672
// request with this identity.
692-
if (!modules->Get(context, i).ToLocal(&current_module) ||
693-
!modules->Get(context, first_seen_index)
694-
.ToLocal(&first_seen_module) ||
695-
!current_module->StrictEquals(first_seen_module)) {
673+
Local<Value> first_seen_value =
674+
modules_vector[first_seen_index].Get(isolate);
675+
if (!module_value->StrictEquals(first_seen_value)) {
696676
// If the module is different from the one of the same request, throw an
697677
// error.
698678
THROW_ERR_MODULE_LINK_MISMATCH(
@@ -705,9 +685,16 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
705685
return;
706686
}
707687
}
688+
689+
CHECK(module_value->IsObject()); // Guaranteed by link methods in JS land.
690+
ModuleWrap* resolved =
691+
BaseObject::Unwrap<ModuleWrap>(module_value.As<Object>());
692+
CHECK_NOT_NULL(resolved); // Guaranteed by link methods in JS land.
693+
linked_module_wraps[i] = resolved;
708694
}
709695

710696
args.This()->SetInternalField(kLinkedRequestsSlot, modules);
697+
std::swap(dependent->linked_module_wraps_, linked_module_wraps);
711698
dependent->linked_ = true;
712699
}
713700

@@ -1109,10 +1096,15 @@ Maybe<ModuleWrap*> ModuleWrap::ResolveModule(Local<Context> context,
11091096
return Nothing<ModuleWrap*>();
11101097
}
11111098

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);
1099+
size_t linked_module_count = dependent->linked_module_wraps_.size();
1100+
if (linked_module_count > 0) {
1101+
CHECK_LT(module_request_index, linked_module_count);
1102+
} else {
1103+
UNREACHABLE("Module resolution callback invoked for a module"
1104+
" without linked requests");
1105+
}
1106+
1107+
return Just(dependent->linked_module_wraps_[module_request_index]);
11161108
}
11171109

11181110
static MaybeLocal<Promise> ImportModuleDynamicallyWithPhase(

src/module_wrap.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class ModuleWrap : public BaseObject {
100100
kModuleSourceObjectSlot,
101101
kSyntheticEvaluationStepsSlot,
102102
kContextObjectSlot, // Object whose creation context is the target Context
103-
kLinkedRequestsSlot, // Array of linked requests
103+
kLinkedRequestsSlot, // Array of linked requests, each is a ModuleWrap JS
104+
// wrapper object.
104105
kInternalFieldCount
105106
};
106107

@@ -132,8 +133,6 @@ class ModuleWrap : public BaseObject {
132133

133134
bool IsLinked() const { return linked_; }
134135

135-
ModuleWrap* GetLinkedRequest(uint32_t index);
136-
137136
static v8::Local<v8::PrimitiveArray> GetHostDefinedOptions(
138137
v8::Isolate* isolate, v8::Local<v8::Symbol> symbol);
139138

@@ -216,6 +215,11 @@ class ModuleWrap : public BaseObject {
216215
// nullopt value.
217216
std::optional<bool> has_async_graph_ = std::nullopt;
218217
int module_hash_;
218+
// Corresponds to the ModuleWrap* of the wrappers in kLinkedRequestsSlot.
219+
// These are populated during Link(), and are only valid after that as
220+
// convenient shortcuts, but do not hold the ModuleWraps alive. The actual
221+
// strong references come from the array in kLinkedRequestsSlot.
222+
std::vector<ModuleWrap*> linked_module_wraps_;
219223
};
220224

221225
} // namespace loader

0 commit comments

Comments
 (0)