OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <memory> | 9 #include <memory> |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 19595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19606 void Module::StoreExport(Handle<Module> module, Handle<String> name, | 19606 void Module::StoreExport(Handle<Module> module, Handle<String> name, |
19607 Handle<Object> value) { | 19607 Handle<Object> value) { |
19608 Handle<Cell> cell(Cell::cast(module->exports()->Lookup(name))); | 19608 Handle<Cell> cell(Cell::cast(module->exports()->Lookup(name))); |
19609 cell->set_value(*value); | 19609 cell->set_value(*value); |
19610 } | 19610 } |
19611 | 19611 |
19612 Handle<Object> Module::LoadExport(Handle<Module> module, Handle<String> name) { | 19612 Handle<Object> Module::LoadExport(Handle<Module> module, Handle<String> name) { |
19613 Isolate* isolate = module->GetIsolate(); | 19613 Isolate* isolate = module->GetIsolate(); |
19614 Handle<Object> object(module->exports()->Lookup(name), isolate); | 19614 Handle<Object> object(module->exports()->Lookup(name), isolate); |
19615 | 19615 |
19616 // TODO(neis): Star exports and namespace imports are not yet implemented. | 19616 // TODO(neis): Namespace imports are not yet implemented. Trying to use this |
19617 // Trying to use these features may crash here. | 19617 // feature may crash here. |
19618 if (!object->IsCell()) UNIMPLEMENTED(); | 19618 if (!object->IsCell()) UNIMPLEMENTED(); |
19619 | 19619 |
19620 return handle(Handle<Cell>::cast(object)->value(), isolate); | 19620 return handle(Handle<Cell>::cast(object)->value(), isolate); |
19621 } | 19621 } |
19622 | 19622 |
19623 Handle<Object> Module::LoadImport(Handle<Module> module, Handle<String> name, | 19623 Handle<Object> Module::LoadImport(Handle<Module> module, Handle<String> name, |
19624 int module_request) { | 19624 int module_request) { |
19625 Isolate* isolate = module->GetIsolate(); | 19625 Isolate* isolate = module->GetIsolate(); |
19626 Handle<Module> requested_module( | 19626 Handle<Module> requested_module( |
19627 Module::cast(module->requested_modules()->get(module_request)), isolate); | 19627 Module::cast(module->requested_modules()->get(module_request)), isolate); |
19628 return Module::LoadExport(requested_module, name); | 19628 return Module::LoadExport(requested_module, name); |
19629 } | 19629 } |
19630 | 19630 |
19631 MaybeHandle<Cell> Module::ResolveImport(Handle<Module> module, | 19631 MaybeHandle<Cell> Module::ResolveImport(Handle<Module> module, |
19632 Handle<String> name, | 19632 Handle<String> name, int module_request, |
19633 int module_request) { | 19633 bool must_resolve) { |
19634 Isolate* isolate = module->GetIsolate(); | 19634 Isolate* isolate = module->GetIsolate(); |
19635 Handle<Module> requested_module( | 19635 Handle<Module> requested_module( |
19636 Module::cast(module->requested_modules()->get(module_request)), isolate); | 19636 Module::cast(module->requested_modules()->get(module_request)), isolate); |
19637 return Module::ResolveExport(requested_module, name); | 19637 return Module::ResolveExport(requested_module, name, must_resolve); |
19638 } | 19638 } |
19639 | 19639 |
19640 MaybeHandle<Cell> Module::ResolveExport(Handle<Module> module, | 19640 MaybeHandle<Cell> Module::ResolveExport(Handle<Module> module, |
19641 Handle<String> name) { | 19641 Handle<String> name, |
| 19642 bool must_resolve) { |
19642 // TODO(neis): Detect cycles. | 19643 // TODO(neis): Detect cycles. |
19643 | 19644 |
19644 Isolate* isolate = module->GetIsolate(); | 19645 Isolate* isolate = module->GetIsolate(); |
19645 Handle<Object> object(module->exports()->Lookup(name), isolate); | 19646 Handle<Object> object(module->exports()->Lookup(name), isolate); |
19646 | 19647 |
19647 if (object->IsCell()) { | 19648 if (object->IsCell()) { |
19648 // Already resolved (e.g. because it's a local export). | 19649 // Already resolved (e.g. because it's a local export). |
19649 return Handle<Cell>::cast(object); | 19650 return Handle<Cell>::cast(object); |
19650 } | 19651 } |
19651 | 19652 |
19652 if (object->IsModuleInfoEntry()) { | 19653 if (object->IsModuleInfoEntry()) { |
19653 // Not yet resolved indirect export. | 19654 // Not yet resolved indirect export. |
19654 Handle<ModuleInfoEntry> entry = Handle<ModuleInfoEntry>::cast(object); | 19655 Handle<ModuleInfoEntry> entry = Handle<ModuleInfoEntry>::cast(object); |
19655 int module_request = Smi::cast(entry->module_request())->value(); | 19656 int module_request = Smi::cast(entry->module_request())->value(); |
19656 Handle<String> import_name(String::cast(entry->import_name()), isolate); | 19657 Handle<String> import_name(String::cast(entry->import_name()), isolate); |
19657 | 19658 |
19658 Handle<Cell> cell; | 19659 Handle<Cell> cell; |
19659 if (!ResolveImport(module, import_name, module_request).ToHandle(&cell)) { | 19660 if (!ResolveImport(module, import_name, module_request, true) |
| 19661 .ToHandle(&cell)) { |
| 19662 DCHECK(isolate->has_pending_exception()); |
19660 return MaybeHandle<Cell>(); | 19663 return MaybeHandle<Cell>(); |
19661 } | 19664 } |
19662 | 19665 |
19663 // The export table may have changed but the entry in question should be | 19666 // The export table may have changed but the entry in question should be |
19664 // unchanged. | 19667 // unchanged. |
19665 Handle<ObjectHashTable> exports(module->exports(), isolate); | 19668 Handle<ObjectHashTable> exports(module->exports(), isolate); |
19666 DCHECK(exports->Lookup(name)->IsModuleInfoEntry()); | 19669 DCHECK(exports->Lookup(name)->IsModuleInfoEntry()); |
19667 | 19670 |
19668 exports = ObjectHashTable::Put(exports, name, cell); | 19671 exports = ObjectHashTable::Put(exports, name, cell); |
19669 module->set_exports(*exports); | 19672 module->set_exports(*exports); |
19670 return cell; | 19673 return cell; |
19671 } | 19674 } |
19672 | 19675 |
19673 DCHECK(object->IsTheHole(isolate)); | 19676 DCHECK(object->IsTheHole(isolate)); |
19674 // TODO(neis): Implement star exports. | 19677 return Module::ResolveExportUsingStarExports(module, name, must_resolve); |
| 19678 } |
| 19679 |
| 19680 MaybeHandle<Cell> Module::ResolveExportUsingStarExports(Handle<Module> module, |
| 19681 Handle<String> name, |
| 19682 bool must_resolve) { |
| 19683 Isolate* isolate = module->GetIsolate(); |
| 19684 if (!name->Equals(isolate->heap()->default_string())) { |
| 19685 // Go through all star exports looking for the given name. If multiple star |
| 19686 // exports provide the name, make sure they all map it to the same cell. |
| 19687 Handle<Cell> unique_cell; |
| 19688 Handle<FixedArray> special_exports(module->info()->special_exports(), |
| 19689 isolate); |
| 19690 for (int i = 0, n = special_exports->length(); i < n; ++i) { |
| 19691 i::Handle<i::ModuleInfoEntry> entry( |
| 19692 i::ModuleInfoEntry::cast(special_exports->get(i)), isolate); |
| 19693 if (!entry->export_name()->IsUndefined(isolate)) { |
| 19694 continue; // Indirect export. |
| 19695 } |
| 19696 int module_request = Smi::cast(entry->module_request())->value(); |
| 19697 |
| 19698 Handle<Cell> cell; |
| 19699 if (ResolveImport(module, name, module_request, false).ToHandle(&cell)) { |
| 19700 if (unique_cell.is_null()) unique_cell = cell; |
| 19701 if (*unique_cell != *cell) { |
| 19702 THROW_NEW_ERROR( |
| 19703 isolate, NewSyntaxError(MessageTemplate::kAmbiguousExport, name), |
| 19704 Cell); |
| 19705 } |
| 19706 } else if (isolate->has_pending_exception()) { |
| 19707 return MaybeHandle<Cell>(); |
| 19708 } |
| 19709 } |
| 19710 |
| 19711 if (!unique_cell.is_null()) { |
| 19712 // Found a unique star export for this name. |
| 19713 Handle<ObjectHashTable> exports(module->exports(), isolate); |
| 19714 DCHECK(exports->Lookup(name)->IsTheHole(isolate)); |
| 19715 exports = ObjectHashTable::Put(exports, name, unique_cell); |
| 19716 module->set_exports(*exports); |
| 19717 return unique_cell; |
| 19718 } |
| 19719 } |
19675 | 19720 |
19676 // Unresolvable. | 19721 // Unresolvable. |
19677 THROW_NEW_ERROR(isolate, | 19722 if (must_resolve) { |
19678 NewSyntaxError(MessageTemplate::kUnresolvableExport, name), | 19723 THROW_NEW_ERROR(isolate, |
19679 Cell); | 19724 NewSyntaxError(MessageTemplate::kUnresolvableExport, name), |
| 19725 Cell); |
| 19726 } |
| 19727 return MaybeHandle<Cell>(); |
19680 } | 19728 } |
19681 | 19729 |
19682 } // namespace internal | 19730 } // namespace internal |
19683 } // namespace v8 | 19731 } // namespace v8 |
OLD | NEW |