5 #include <unordered_map> 6 #include <unordered_set> 8 #include "src/objects/module.h" 10 #include "src/accessors.h" 11 #include "src/api-inl.h" 12 #include "src/ast/modules.h" 13 #include "src/objects-inl.h" 14 #include "src/objects/hash-table-inl.h" 15 #include "src/objects/js-generator-inl.h" 16 #include "src/objects/module-inl.h" 23 return module->hash();
35 return string->Hash();
41 return lhs->Equals(*rhs);
46 :
public std::unordered_set<Handle<String>, StringHandleHash,
48 ZoneAllocator<Handle<String>>> {
58 :
public std::unordered_set<Handle<Module>, ModuleHandleHash,
60 ZoneAllocator<Handle<Module>>> {
70 :
public std::unordered_map<
71 Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual,
72 ZoneAllocator<std::pair<const Handle<String>, Handle<Object>>>> {
84 :
public std::unordered_map<
85 Handle<Module>, UnorderedStringSet*, ModuleHandleHash,
87 ZoneAllocator<std::pair<const Handle<Module>, UnorderedStringSet*>>> {
99 Zone* zone()
const {
return zone_; }
105 int Module::ExportIndex(
int cell_index) {
106 DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
107 ModuleDescriptor::kExport);
108 return cell_index - 1;
111 int Module::ImportIndex(
int cell_index) {
112 DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
113 ModuleDescriptor::kImport);
114 return -cell_index - 1;
117 void Module::CreateIndirectExport(Isolate* isolate,
Handle<Module> module,
121 DCHECK(exports->Lookup(name)->IsTheHole(isolate));
122 exports = ObjectHashTable::Put(exports, name, entry);
123 module->set_exports(*exports);
126 void Module::CreateExport(Isolate* isolate, Handle<Module> module,
127 int cell_index, Handle<FixedArray> names) {
128 DCHECK_LT(0, names->length());
130 isolate->factory()->NewCell(isolate->factory()->undefined_value());
131 module->regular_exports()->set(ExportIndex(cell_index), *cell);
133 Handle<ObjectHashTable> exports(module->exports(), isolate);
134 for (
int i = 0, n = names->length();
i < n; ++
i) {
135 Handle<String> name(String::cast(names->get(
i)), isolate);
136 DCHECK(exports->Lookup(name)->IsTheHole(isolate));
137 exports = ObjectHashTable::Put(exports, name, cell);
139 module->set_exports(*exports);
142 Cell* Module::GetCell(
int cell_index) {
143 DisallowHeapAllocation no_gc;
145 switch (ModuleDescriptor::GetCellIndexKind(cell_index)) {
146 case ModuleDescriptor::kImport:
147 cell = regular_imports()->get(ImportIndex(cell_index));
149 case ModuleDescriptor::kExport:
150 cell = regular_exports()->get(ExportIndex(cell_index));
152 case ModuleDescriptor::kInvalid:
156 return Cell::cast(cell);
159 Handle<Object> Module::LoadVariable(Isolate* isolate, Handle<Module> module,
161 return handle(module->GetCell(cell_index)->value(), isolate);
164 void Module::StoreVariable(Handle<Module> module,
int cell_index,
165 Handle<Object> value) {
166 DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
167 ModuleDescriptor::kExport);
168 module->GetCell(cell_index)->set_value(*value);
172 void Module::PrintStatusTransition(Status new_status) {
173 if (FLAG_trace_module_status) {
175 os <<
"Changing module status from " << status() <<
" to " << new_status
177 script()->GetNameOrSourceURL()->Print(os);
180 #endif // OBJECT_PRINT 185 void Module::SetStatus(Status new_status) {
186 DisallowHeapAllocation no_alloc;
187 DCHECK_LE(status(), new_status);
188 DCHECK_NE(new_status, Module::kErrored);
190 PrintStatusTransition(new_status);
192 set_status(new_status);
195 void Module::ResetGraph(Isolate* isolate, Handle<Module> module) {
196 DCHECK_NE(module->status(), kInstantiating);
197 DCHECK_NE(module->status(), kEvaluating);
198 if (module->status() != kPreInstantiating)
return;
199 Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
200 Reset(isolate, module);
201 for (
int i = 0;
i < requested_modules->length(); ++
i) {
202 Handle<Object> descendant(requested_modules->get(
i), isolate);
203 if (descendant->IsModule()) {
204 ResetGraph(isolate, Handle<Module>::cast(descendant));
206 DCHECK(descendant->IsUndefined(isolate));
211 void Module::Reset(Isolate* isolate, Handle<Module> module) {
212 Factory* factory = isolate->factory();
214 DCHECK(module->status() == kPreInstantiating ||
215 module->status() == kInstantiating);
216 DCHECK(module->exception()->IsTheHole(isolate));
217 DCHECK(module->import_meta()->IsTheHole(isolate));
221 DCHECK(!module->module_namespace()->IsJSModuleNamespace());
223 Handle<ObjectHashTable> exports =
224 ObjectHashTable::New(isolate, module->info()->RegularExportCount());
225 Handle<FixedArray> regular_exports =
226 factory->NewFixedArray(module->regular_exports()->length());
227 Handle<FixedArray> regular_imports =
228 factory->NewFixedArray(module->regular_imports()->length());
229 Handle<FixedArray> requested_modules =
230 factory->NewFixedArray(module->requested_modules()->length());
232 if (module->status() == kInstantiating) {
233 module->set_code(JSFunction::cast(module->code())->shared());
236 module->PrintStatusTransition(kUninstantiated);
238 module->set_status(kUninstantiated);
239 module->set_exports(*exports);
240 module->set_regular_exports(*regular_exports);
241 module->set_regular_imports(*regular_imports);
242 module->set_requested_modules(*requested_modules);
243 module->set_dfs_index(-1);
244 module->set_dfs_ancestor_index(-1);
247 void Module::RecordError(Isolate* isolate) {
248 DisallowHeapAllocation no_alloc;
249 DCHECK(exception()->IsTheHole(isolate));
250 Object* the_exception = isolate->pending_exception();
251 DCHECK(!the_exception->IsTheHole(isolate));
255 PrintStatusTransition(Module::kErrored);
257 set_status(Module::kErrored);
258 set_exception(the_exception);
261 Object* Module::GetException() {
262 DisallowHeapAllocation no_alloc;
263 DCHECK_EQ(status(), Module::kErrored);
264 DCHECK(!exception()->IsTheHole());
268 SharedFunctionInfo* Module::GetSharedFunctionInfo()
const {
269 DisallowHeapAllocation no_alloc;
270 DCHECK_NE(status(), Module::kEvaluating);
271 DCHECK_NE(status(), Module::kEvaluated);
273 case kUninstantiated:
274 case kPreInstantiating:
275 DCHECK(code()->IsSharedFunctionInfo());
276 return SharedFunctionInfo::cast(code());
278 DCHECK(code()->IsJSFunction());
279 return JSFunction::cast(code())->shared();
281 DCHECK(code()->IsJSGeneratorObject());
282 return JSGeneratorObject::cast(code())->function()->shared();
292 MaybeHandle<Cell> Module::ResolveImport(Isolate* isolate, Handle<Module> module,
293 Handle<String> name,
int module_request,
294 MessageLocation loc,
bool must_resolve,
295 Module::ResolveSet* resolve_set) {
296 Handle<Module> requested_module(
297 Module::cast(module->requested_modules()->get(module_request)), isolate);
298 Handle<String> specifier(
299 String::cast(module->info()->module_requests()->get(module_request)),
301 MaybeHandle<Cell> result =
302 Module::ResolveExport(isolate, requested_module, specifier, name, loc,
303 must_resolve, resolve_set);
304 DCHECK_IMPLIES(isolate->has_pending_exception(), result.is_null());
308 MaybeHandle<Cell> Module::ResolveExport(Isolate* isolate, Handle<Module> module,
309 Handle<String> module_specifier,
310 Handle<String> export_name,
311 MessageLocation loc,
bool must_resolve,
312 Module::ResolveSet* resolve_set) {
313 DCHECK_GE(module->status(), kPreInstantiating);
314 DCHECK_NE(module->status(), kEvaluating);
315 Handle<Object> object(module->exports()->Lookup(export_name), isolate);
316 if (object->IsCell()) {
318 return Handle<Cell>::cast(
object);
324 auto result = resolve_set->insert({module,
nullptr});
325 UnorderedStringSet*& name_set = result.first->second;
328 Zone* zone = resolve_set->zone();
330 new (zone->New(
sizeof(UnorderedStringSet))) UnorderedStringSet(zone);
331 }
else if (name_set->count(export_name)) {
334 return isolate->Throw<Cell>(
335 isolate->factory()->NewSyntaxError(
336 MessageTemplate::kCyclicModuleDependency, export_name,
340 return MaybeHandle<Cell>();
342 name_set->insert(export_name);
345 if (object->IsModuleInfoEntry()) {
347 Handle<ModuleInfoEntry> entry = Handle<ModuleInfoEntry>::cast(
object);
348 Handle<String> import_name(String::cast(entry->import_name()), isolate);
349 Handle<Script> script(module->script(), isolate);
350 MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
353 if (!ResolveImport(isolate, module, import_name, entry->module_request(),
354 new_loc,
true, resolve_set)
356 DCHECK(isolate->has_pending_exception());
357 return MaybeHandle<Cell>();
362 Handle<ObjectHashTable> exports(module->exports(), isolate);
363 DCHECK(exports->Lookup(export_name)->IsModuleInfoEntry());
365 exports = ObjectHashTable::Put(exports, export_name, cell);
366 module->set_exports(*exports);
370 DCHECK(object->IsTheHole(isolate));
371 return Module::ResolveExportUsingStarExports(isolate, module,
372 module_specifier, export_name,
373 loc, must_resolve, resolve_set);
376 MaybeHandle<Cell> Module::ResolveExportUsingStarExports(
377 Isolate* isolate, Handle<Module> module, Handle<String> module_specifier,
378 Handle<String> export_name, MessageLocation loc,
bool must_resolve,
379 Module::ResolveSet* resolve_set) {
380 if (!export_name->Equals(ReadOnlyRoots(isolate).default_string())) {
383 Handle<Cell> unique_cell;
384 Handle<FixedArray> special_exports(module->info()->special_exports(),
386 for (
int i = 0, n = special_exports->length();
i < n; ++
i) {
388 i::ModuleInfoEntry::cast(special_exports->get(
i)), isolate);
389 if (!entry->export_name()->IsUndefined(isolate)) {
393 Handle<Script> script(module->script(), isolate);
394 MessageLocation new_loc(script, entry->beg_pos(), entry->end_pos());
397 if (ResolveImport(isolate, module, export_name, entry->module_request(),
398 new_loc,
false, resolve_set)
400 if (unique_cell.is_null()) unique_cell = cell;
401 if (*unique_cell != *cell) {
402 return isolate->Throw<Cell>(isolate->factory()->NewSyntaxError(
403 MessageTemplate::kAmbiguousExport,
404 module_specifier, export_name),
407 }
else if (isolate->has_pending_exception()) {
408 return MaybeHandle<Cell>();
412 if (!unique_cell.is_null()) {
414 Handle<ObjectHashTable> exports(module->exports(), isolate);
415 DCHECK(exports->Lookup(export_name)->IsTheHole(isolate));
416 exports = ObjectHashTable::Put(exports, export_name, unique_cell);
417 module->set_exports(*exports);
424 return isolate->Throw<Cell>(
425 isolate->factory()->NewSyntaxError(MessageTemplate::kUnresolvableExport,
426 module_specifier, export_name),
429 return MaybeHandle<Cell>();
432 bool Module::Instantiate(Isolate* isolate, Handle<Module> module,
434 v8::Module::ResolveCallback callback) {
436 if (FLAG_trace_module_status) {
438 os <<
"Instantiating module ";
439 module->script()->GetNameOrSourceURL()->Print(os);
442 #endif // OBJECT_PRINT 446 if (!PrepareInstantiate(isolate, module, context, callback)) {
447 ResetGraph(isolate, module);
450 Zone zone(isolate->allocator(), ZONE_NAME);
451 ZoneForwardList<Handle<Module>> stack(&zone);
452 unsigned dfs_index = 0;
453 if (!FinishInstantiate(isolate, module, &stack, &dfs_index, &zone)) {
454 for (
auto& descendant : stack) {
455 Reset(isolate, descendant);
457 DCHECK_EQ(module->status(), kUninstantiated);
460 DCHECK(module->status() == kInstantiated || module->status() == kEvaluated ||
461 module->status() == kErrored);
462 DCHECK(stack.empty());
466 bool Module::PrepareInstantiate(Isolate* isolate, Handle<Module> module,
468 v8::Module::ResolveCallback callback) {
469 DCHECK_NE(module->status(), kEvaluating);
470 DCHECK_NE(module->status(), kInstantiating);
471 if (module->status() >= kPreInstantiating)
return true;
472 module->SetStatus(kPreInstantiating);
473 STACK_CHECK(isolate,
false);
476 Handle<ModuleInfo> module_info(module->info(), isolate);
477 Handle<FixedArray> module_requests(module_info->module_requests(), isolate);
478 Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
479 for (
int i = 0, length = module_requests->length();
i < length; ++
i) {
480 Handle<String> specifier(String::cast(module_requests->get(
i)), isolate);
482 if (!callback(context, v8::Utils::ToLocal(specifier),
483 v8::Utils::ToLocal(module))
484 .ToLocal(&api_requested_module)) {
485 isolate->PromoteScheduledException();
488 Handle<Module> requested_module = Utils::OpenHandle(*api_requested_module);
489 requested_modules->set(
i, *requested_module);
493 for (
int i = 0, length = requested_modules->length();
i < length; ++
i) {
494 Handle<Module> requested_module(Module::cast(requested_modules->get(
i)),
496 if (!PrepareInstantiate(isolate, requested_module, context, callback)) {
503 for (
int i = 0, n = module_info->RegularExportCount();
i < n; ++
i) {
504 int cell_index = module_info->RegularExportCellIndex(
i);
505 Handle<FixedArray> export_names(module_info->RegularExportExportNames(
i),
507 CreateExport(isolate, module, cell_index, export_names);
515 Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
516 for (
int i = 0, n = special_exports->length();
i < n; ++
i) {
517 Handle<ModuleInfoEntry> entry(
518 ModuleInfoEntry::cast(special_exports->get(
i)), isolate);
519 Handle<Object> export_name(entry->export_name(), isolate);
520 if (export_name->IsUndefined(isolate))
continue;
521 CreateIndirectExport(isolate, module, Handle<String>::cast(export_name),
525 DCHECK_EQ(module->status(), kPreInstantiating);
529 bool Module::RunInitializationCode(Isolate* isolate, Handle<Module> module) {
530 DCHECK_EQ(module->status(), kInstantiating);
531 Handle<JSFunction>
function(JSFunction::cast(module->code()), isolate);
532 DCHECK_EQ(MODULE_SCOPE, function->shared()->scope_info()->scope_type());
533 Handle<Object> receiver = isolate->factory()->undefined_value();
534 Handle<Object> argv[] = {module};
535 MaybeHandle<Object> maybe_generator =
536 Execution::Call(isolate,
function, receiver, arraysize(argv), argv);
537 Handle<Object> generator;
538 if (!maybe_generator.ToHandle(&generator)) {
539 DCHECK(isolate->has_pending_exception());
542 DCHECK_EQ(*
function, Handle<JSGeneratorObject>::cast(generator)->
function());
543 module->set_code(*generator);
547 bool Module::MaybeTransitionComponent(Isolate* isolate, Handle<Module> module,
548 ZoneForwardList<Handle<Module>>* stack,
550 DCHECK(new_status == kInstantiated || new_status == kEvaluated);
553 std::count_if(stack->begin(), stack->end(),
554 [&](Handle<Module> m) {
return *m == *module; }) == 1);
555 DCHECK_LE(module->dfs_ancestor_index(), module->dfs_index());
556 if (module->dfs_ancestor_index() == module->dfs_index()) {
558 Handle<Module> ancestor;
560 ancestor = stack->front();
562 DCHECK_EQ(ancestor->status(),
563 new_status == kInstantiated ? kInstantiating : kEvaluating);
564 if (new_status == kInstantiated) {
565 if (!RunInitializationCode(isolate, ancestor))
return false;
567 ancestor->SetStatus(new_status);
568 }
while (*ancestor != *module);
573 bool Module::FinishInstantiate(Isolate* isolate, Handle<Module> module,
574 ZoneForwardList<Handle<Module>>* stack,
575 unsigned* dfs_index, Zone* zone) {
576 DCHECK_NE(module->status(), kEvaluating);
577 if (module->status() >= kInstantiating)
return true;
578 DCHECK_EQ(module->status(), kPreInstantiating);
579 STACK_CHECK(isolate,
false);
583 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(module->code()),
585 Handle<JSFunction>
function =
586 isolate->factory()->NewFunctionFromSharedFunctionInfo(
587 shared, isolate->native_context());
588 module->set_code(*
function);
589 module->SetStatus(kInstantiating);
590 module->set_dfs_index(*dfs_index);
591 module->set_dfs_ancestor_index(*dfs_index);
592 stack->push_front(module);
596 Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
597 for (
int i = 0, length = requested_modules->length();
i < length; ++
i) {
598 Handle<Module> requested_module(Module::cast(requested_modules->get(
i)),
600 if (!FinishInstantiate(isolate, requested_module, stack, dfs_index, zone)) {
604 DCHECK_NE(requested_module->status(), kEvaluating);
605 DCHECK_GE(requested_module->status(), kInstantiating);
608 (requested_module->status() == kInstantiating) ==
609 std::count_if(stack->begin(), stack->end(), [&](Handle<Module> m) {
610 return *m == *requested_module;
613 if (requested_module->status() == kInstantiating) {
614 module->set_dfs_ancestor_index(
615 std::min(module->dfs_ancestor_index(),
616 requested_module->dfs_ancestor_index()));
620 Handle<Script> script(module->script(), isolate);
621 Handle<ModuleInfo> module_info(module->info(), isolate);
624 Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
625 for (
int i = 0, n = regular_imports->length();
i < n; ++
i) {
626 Handle<ModuleInfoEntry> entry(
627 ModuleInfoEntry::cast(regular_imports->get(
i)), isolate);
628 Handle<String> name(String::cast(entry->import_name()), isolate);
629 MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
630 ResolveSet resolve_set(zone);
632 if (!ResolveImport(isolate, module, name, entry->module_request(), loc,
637 module->regular_imports()->set(ImportIndex(entry->cell_index()), *cell);
641 Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
642 for (
int i = 0, n = special_exports->length();
i < n; ++
i) {
643 Handle<ModuleInfoEntry> entry(
644 ModuleInfoEntry::cast(special_exports->get(
i)), isolate);
645 Handle<Object> name(entry->export_name(), isolate);
646 if (name->IsUndefined(isolate))
continue;
647 MessageLocation loc(script, entry->beg_pos(), entry->end_pos());
648 ResolveSet resolve_set(zone);
649 if (ResolveExport(isolate, module, Handle<String>(),
650 Handle<String>::cast(name), loc,
true, &resolve_set)
656 return MaybeTransitionComponent(isolate, module, stack, kInstantiated);
659 MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module) {
661 if (FLAG_trace_module_status) {
663 os <<
"Evaluating module ";
664 module->script()->GetNameOrSourceURL()->Print(os);
667 #endif // OBJECT_PRINT 670 if (module->status() == kErrored) {
671 isolate->Throw(module->GetException());
672 return MaybeHandle<Object>();
674 DCHECK_NE(module->status(), kEvaluating);
675 DCHECK_GE(module->status(), kInstantiated);
676 Zone zone(isolate->allocator(), ZONE_NAME);
678 ZoneForwardList<Handle<Module>> stack(&zone);
679 unsigned dfs_index = 0;
680 Handle<Object> result;
681 if (!Evaluate(isolate, module, &stack, &dfs_index).ToHandle(&result)) {
682 for (
auto& descendant : stack) {
683 DCHECK_EQ(descendant->status(), kEvaluating);
684 descendant->RecordError(isolate);
686 DCHECK_EQ(module->GetException(), isolate->pending_exception());
687 return MaybeHandle<Object>();
689 DCHECK_EQ(module->status(), kEvaluated);
690 DCHECK(stack.empty());
694 MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module,
695 ZoneForwardList<Handle<Module>>* stack,
696 unsigned* dfs_index) {
697 if (module->status() == kErrored) {
698 isolate->Throw(module->GetException());
699 return MaybeHandle<Object>();
701 if (module->status() >= kEvaluating) {
702 return isolate->factory()->undefined_value();
704 DCHECK_EQ(module->status(), kInstantiated);
705 STACK_CHECK(isolate, MaybeHandle<Object>());
707 Handle<JSGeneratorObject> generator(JSGeneratorObject::cast(module->code()),
710 generator->function()->shared()->scope_info()->ModuleDescriptorInfo());
711 module->SetStatus(kEvaluating);
712 module->set_dfs_index(*dfs_index);
713 module->set_dfs_ancestor_index(*dfs_index);
714 stack->push_front(module);
718 Handle<FixedArray> requested_modules(module->requested_modules(), isolate);
719 for (
int i = 0, length = requested_modules->length();
i < length; ++
i) {
720 Handle<Module> requested_module(Module::cast(requested_modules->get(
i)),
723 isolate, Evaluate(isolate, requested_module, stack, dfs_index), Object);
725 DCHECK_GE(requested_module->status(), kEvaluating);
726 DCHECK_NE(requested_module->status(), kErrored);
729 (requested_module->status() == kEvaluating) ==
730 std::count_if(stack->begin(), stack->end(), [&](Handle<Module> m) {
731 return *m == *requested_module;
734 if (requested_module->status() == kEvaluating) {
735 module->set_dfs_ancestor_index(
736 std::min(module->dfs_ancestor_index(),
737 requested_module->dfs_ancestor_index()));
742 Handle<JSFunction> resume(
743 isolate->native_context()->generator_next_internal(), isolate);
744 Handle<Object> result;
745 ASSIGN_RETURN_ON_EXCEPTION(
746 isolate, result, Execution::Call(isolate, resume, generator, 0,
nullptr),
748 DCHECK(static_cast<JSIteratorResult*>(JSObject::cast(*result))
750 ->BooleanValue(isolate));
752 CHECK(MaybeTransitionComponent(isolate, module, stack, kEvaluated));
754 static_cast<JSIteratorResult*>(JSObject::cast(*result))->value(),
760 void FetchStarExports(Isolate* isolate, Handle<Module> module, Zone* zone,
761 UnorderedModuleSet* visited) {
762 DCHECK_GE(module->status(), Module::kInstantiating);
764 if (module->module_namespace()->IsJSModuleNamespace())
return;
766 bool cycle = !visited->insert(module).second;
768 Handle<ObjectHashTable> exports(module->exports(), isolate);
769 UnorderedStringMap more_exports(zone);
774 ReadOnlyRoots roots(isolate);
775 Handle<FixedArray> special_exports(module->info()->special_exports(),
777 for (
int i = 0, n = special_exports->length();
i < n; ++
i) {
778 Handle<ModuleInfoEntry> entry(
779 ModuleInfoEntry::cast(special_exports->get(
i)), isolate);
780 if (!entry->export_name()->IsUndefined(roots)) {
784 Handle<Module> requested_module(
785 Module::cast(module->requested_modules()->get(entry->module_request())),
789 FetchStarExports(isolate, requested_module, zone, visited);
795 Handle<ObjectHashTable> requested_exports(requested_module->exports(),
797 for (
int i = 0, n = requested_exports->Capacity();
i < n; ++
i) {
799 if (!requested_exports->ToKey(roots,
i, &key))
continue;
800 Handle<String> name(String::cast(key), isolate);
802 if (name->Equals(roots.default_string()))
continue;
803 if (!exports->Lookup(name)->IsTheHole(roots))
continue;
805 Handle<Cell> cell(Cell::cast(requested_exports->ValueAt(
i)), isolate);
806 auto insert_result = more_exports.insert(std::make_pair(name, cell));
807 if (!insert_result.second) {
808 auto it = insert_result.first;
809 if (*it->second == *cell || it->second->IsUndefined(roots)) {
813 DCHECK(it->second->IsCell());
816 it->second = roots.undefined_value_handle();
823 for (
const auto& elem : more_exports) {
824 if (elem.second->IsUndefined(isolate))
continue;
825 DCHECK(!elem.first->Equals(ReadOnlyRoots(isolate).default_string()));
826 DCHECK(elem.second->IsCell());
827 exports = ObjectHashTable::Put(exports, elem.first, elem.second);
829 module->set_exports(*exports);
834 Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
835 Handle<Module> module,
836 int module_request) {
837 Handle<Module> requested_module(
838 Module::cast(module->requested_modules()->get(module_request)), isolate);
839 return Module::GetModuleNamespace(isolate, requested_module);
842 Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
843 Handle<Module> module) {
844 Handle<HeapObject> object(module->module_namespace(), isolate);
845 ReadOnlyRoots roots(isolate);
846 if (!object->IsUndefined(roots)) {
848 return Handle<JSModuleNamespace>::cast(
object);
852 Zone zone(isolate->allocator(), ZONE_NAME);
853 UnorderedModuleSet visited(&zone);
854 FetchStarExports(isolate, module, &zone, &visited);
855 Handle<ObjectHashTable> exports(module->exports(), isolate);
856 ZoneVector<Handle<String>> names(&zone);
857 names.reserve(exports->NumberOfElements());
858 for (
int i = 0, n = exports->Capacity();
i < n; ++
i) {
860 if (!exports->ToKey(roots,
i, &key))
continue;
861 names.push_back(handle(String::cast(key), isolate));
863 DCHECK_EQ(static_cast<int>(names.size()), exports->NumberOfElements());
866 std::sort(names.begin(), names.end(),
867 [&isolate](Handle<String> a, Handle<String> b) {
868 return String::Compare(isolate, a, b) ==
869 ComparisonResult::kLessThan;
873 Handle<JSModuleNamespace> ns = isolate->factory()->NewJSModuleNamespace();
874 ns->set_module(*module);
875 module->set_module_namespace(*ns);
879 PropertyAttributes attr = DONT_DELETE;
880 JSObject::NormalizeProperties(ns, CLEAR_INOBJECT_PROPERTIES,
881 static_cast<int>(names.size()),
882 "JSModuleNamespace");
883 for (
const auto& name : names) {
884 JSObject::SetNormalizedProperty(
885 ns, name, Accessors::MakeModuleNamespaceEntryInfo(isolate, name),
886 PropertyDetails(kAccessor, attr, PropertyCellType::kMutable));
888 JSObject::PreventExtensions(ns, kThrowOnError).ToChecked();
894 JSObject::OptimizeAsPrototype(ns);
896 Handle<PrototypeInfo> proto_info =
897 Map::GetOrCreatePrototypeInfo(Handle<JSObject>::cast(ns), isolate);
898 proto_info->set_module_namespace(*ns);
902 MaybeHandle<Object> JSModuleNamespace::GetExport(Isolate* isolate,
903 Handle<String> name) {
904 Handle<Object> object(module()->exports()->Lookup(name), isolate);
905 if (object->IsTheHole(isolate)) {
906 return isolate->factory()->undefined_value();
909 Handle<Object> value(Handle<Cell>::cast(
object)->value(), isolate);
910 if (value->IsTheHole(isolate)) {
912 isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object);
918 Maybe<PropertyAttributes> JSModuleNamespace::GetPropertyAttributes(
919 LookupIterator* it) {
920 Handle<JSModuleNamespace>
object = it->GetHolder<JSModuleNamespace>();
921 Handle<String> name = Handle<String>::cast(it->GetName());
922 DCHECK_EQ(it->state(), LookupIterator::ACCESSOR);
924 Isolate* isolate = it->isolate();
926 Handle<Object> lookup(object->module()->exports()->Lookup(name), isolate);
927 if (lookup->IsTheHole(isolate)) {
931 Handle<Object> value(Handle<Cell>::cast(lookup)->value(), isolate);
932 if (value->IsTheHole(isolate)) {
933 isolate->Throw(*isolate->factory()->NewReferenceError(
934 MessageTemplate::kNotDefined, name));
935 return Nothing<PropertyAttributes>();
938 return Just(it->property_attributes());