OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/ast/modules.h" | 5 #include "src/ast/modules.h" |
6 #include "src/ast/ast-value-factory.h" | 6 #include "src/ast/ast-value-factory.h" |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
11 | 11 |
12 void ModuleDescriptor::AddImport( | 12 void ModuleDescriptor::AddImport( |
13 const AstRawString* import_name, const AstRawString* local_name, | 13 const AstRawString* import_name, const AstRawString* local_name, |
14 const AstRawString* module_request, Scanner::Location loc, Zone* zone) { | 14 const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
15 Entry* entry = new (zone) Entry(loc); | 15 Entry* entry = new (zone) Entry(loc); |
16 entry->local_name = local_name; | 16 entry->local_name = local_name; |
17 entry->import_name = import_name; | 17 entry->import_name = import_name; |
18 entry->module_request = module_request; | 18 entry->module_request = AddModuleRequest(module_request); |
19 AddRegularImport(entry); | 19 AddRegularImport(entry); |
20 } | 20 } |
21 | 21 |
22 | 22 |
23 void ModuleDescriptor::AddStarImport( | 23 void ModuleDescriptor::AddStarImport( |
24 const AstRawString* local_name, const AstRawString* module_request, | 24 const AstRawString* local_name, const AstRawString* module_request, |
25 Scanner::Location loc, Zone* zone) { | 25 Scanner::Location loc, Zone* zone) { |
26 DCHECK_NOT_NULL(local_name); | 26 DCHECK_NOT_NULL(local_name); |
27 DCHECK_NOT_NULL(module_request); | |
28 Entry* entry = new (zone) Entry(loc); | 27 Entry* entry = new (zone) Entry(loc); |
29 entry->local_name = local_name; | 28 entry->local_name = local_name; |
30 entry->module_request = module_request; | 29 entry->module_request = AddModuleRequest(module_request); |
31 AddSpecialImport(entry, zone); | 30 AddSpecialImport(entry, zone); |
32 } | 31 } |
33 | 32 |
34 | 33 |
35 void ModuleDescriptor::AddEmptyImport( | 34 void ModuleDescriptor::AddEmptyImport( |
36 const AstRawString* module_request, Scanner::Location loc, Zone* zone) { | 35 const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
37 Entry* entry = new (zone) Entry(loc); | 36 Entry* entry = new (zone) Entry(loc); |
38 entry->module_request = module_request; | 37 entry->module_request = AddModuleRequest(module_request); |
39 AddSpecialImport(entry, zone); | 38 AddSpecialImport(entry, zone); |
40 } | 39 } |
41 | 40 |
42 | 41 |
43 void ModuleDescriptor::AddExport( | 42 void ModuleDescriptor::AddExport( |
44 const AstRawString* local_name, const AstRawString* export_name, | 43 const AstRawString* local_name, const AstRawString* export_name, |
45 Scanner::Location loc, Zone* zone) { | 44 Scanner::Location loc, Zone* zone) { |
46 Entry* entry = new (zone) Entry(loc); | 45 Entry* entry = new (zone) Entry(loc); |
47 entry->export_name = export_name; | 46 entry->export_name = export_name; |
48 entry->local_name = local_name; | 47 entry->local_name = local_name; |
49 AddRegularExport(entry); | 48 AddRegularExport(entry); |
50 } | 49 } |
51 | 50 |
52 | 51 |
53 void ModuleDescriptor::AddExport( | 52 void ModuleDescriptor::AddExport( |
54 const AstRawString* import_name, const AstRawString* export_name, | 53 const AstRawString* import_name, const AstRawString* export_name, |
55 const AstRawString* module_request, Scanner::Location loc, Zone* zone) { | 54 const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
56 DCHECK_NOT_NULL(import_name); | 55 DCHECK_NOT_NULL(import_name); |
57 DCHECK_NOT_NULL(export_name); | 56 DCHECK_NOT_NULL(export_name); |
58 Entry* entry = new (zone) Entry(loc); | 57 Entry* entry = new (zone) Entry(loc); |
59 entry->export_name = export_name; | 58 entry->export_name = export_name; |
60 entry->import_name = import_name; | 59 entry->import_name = import_name; |
61 entry->module_request = module_request; | 60 entry->module_request = AddModuleRequest(module_request); |
62 AddSpecialExport(entry, zone); | 61 AddSpecialExport(entry, zone); |
63 } | 62 } |
64 | 63 |
65 | 64 |
66 void ModuleDescriptor::AddStarExport( | 65 void ModuleDescriptor::AddStarExport( |
67 const AstRawString* module_request, Scanner::Location loc, Zone* zone) { | 66 const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
68 Entry* entry = new (zone) Entry(loc); | 67 Entry* entry = new (zone) Entry(loc); |
69 entry->module_request = module_request; | 68 entry->module_request = AddModuleRequest(module_request); |
70 AddSpecialExport(entry, zone); | 69 AddSpecialExport(entry, zone); |
71 } | 70 } |
72 | 71 |
73 namespace { | 72 namespace { |
74 | 73 |
75 Handle<Object> ToStringOrUndefined(Isolate* isolate, const AstRawString* s) { | 74 Handle<Object> ToStringOrUndefined(Isolate* isolate, const AstRawString* s) { |
76 return (s == nullptr) | 75 return (s == nullptr) |
77 ? Handle<Object>::cast(isolate->factory()->undefined_value()) | 76 ? Handle<Object>::cast(isolate->factory()->undefined_value()) |
78 : Handle<Object>::cast(s->string()); | 77 : Handle<Object>::cast(s->string()); |
79 } | 78 } |
80 | 79 |
81 const AstRawString* FromStringOrUndefined(Isolate* isolate, | 80 const AstRawString* FromStringOrUndefined(Isolate* isolate, |
82 AstValueFactory* avfactory, | 81 AstValueFactory* avfactory, |
83 Handle<Object> object) { | 82 Handle<Object> object) { |
84 if (object->IsUndefined(isolate)) return nullptr; | 83 if (object->IsUndefined(isolate)) return nullptr; |
85 return avfactory->GetString(Handle<String>::cast(object)); | 84 return avfactory->GetString(Handle<String>::cast(object)); |
86 } | 85 } |
87 | 86 |
88 } // namespace | 87 } // namespace |
89 | 88 |
90 Handle<ModuleInfoEntry> ModuleDescriptor::Entry::Serialize( | 89 Handle<ModuleInfoEntry> ModuleDescriptor::Entry::Serialize( |
91 Isolate* isolate) const { | 90 Isolate* isolate) const { |
92 return ModuleInfoEntry::New(isolate, | 91 CHECK(Smi::IsValid(module_request)); // TODO(neis): Check earlier? |
93 ToStringOrUndefined(isolate, export_name), | 92 return ModuleInfoEntry::New( |
94 ToStringOrUndefined(isolate, local_name), | 93 isolate, ToStringOrUndefined(isolate, export_name), |
95 ToStringOrUndefined(isolate, import_name), | 94 ToStringOrUndefined(isolate, local_name), |
96 ToStringOrUndefined(isolate, module_request)); | 95 ToStringOrUndefined(isolate, import_name), |
| 96 Handle<Object>(Smi::FromInt(module_request), isolate)); |
97 } | 97 } |
98 | 98 |
99 ModuleDescriptor::Entry* ModuleDescriptor::Entry::Deserialize( | 99 ModuleDescriptor::Entry* ModuleDescriptor::Entry::Deserialize( |
100 Isolate* isolate, AstValueFactory* avfactory, | 100 Isolate* isolate, AstValueFactory* avfactory, |
101 Handle<ModuleInfoEntry> entry) { | 101 Handle<ModuleInfoEntry> entry) { |
102 Entry* result = new (avfactory->zone()) Entry(Scanner::Location::invalid()); | 102 Entry* result = new (avfactory->zone()) Entry(Scanner::Location::invalid()); |
103 result->export_name = FromStringOrUndefined( | 103 result->export_name = FromStringOrUndefined( |
104 isolate, avfactory, handle(entry->export_name(), isolate)); | 104 isolate, avfactory, handle(entry->export_name(), isolate)); |
105 result->local_name = FromStringOrUndefined( | 105 result->local_name = FromStringOrUndefined( |
106 isolate, avfactory, handle(entry->local_name(), isolate)); | 106 isolate, avfactory, handle(entry->local_name(), isolate)); |
107 result->import_name = FromStringOrUndefined( | 107 result->import_name = FromStringOrUndefined( |
108 isolate, avfactory, handle(entry->import_name(), isolate)); | 108 isolate, avfactory, handle(entry->import_name(), isolate)); |
109 result->module_request = FromStringOrUndefined( | 109 result->module_request = Smi::cast(entry->module_request())->value(); |
110 isolate, avfactory, handle(entry->module_request(), isolate)); | |
111 return result; | 110 return result; |
112 } | 111 } |
113 | 112 |
114 void ModuleDescriptor::MakeIndirectExportsExplicit(Zone* zone) { | 113 void ModuleDescriptor::MakeIndirectExportsExplicit(Zone* zone) { |
115 for (auto it = regular_exports_.begin(); it != regular_exports_.end();) { | 114 for (auto it = regular_exports_.begin(); it != regular_exports_.end();) { |
116 Entry* entry = it->second; | 115 Entry* entry = it->second; |
117 DCHECK_NOT_NULL(entry->local_name); | 116 DCHECK_NOT_NULL(entry->local_name); |
118 auto import = regular_imports_.find(entry->local_name); | 117 auto import = regular_imports_.find(entry->local_name); |
119 if (import != regular_imports_.end()) { | 118 if (import != regular_imports_.end()) { |
120 // Found an indirect export. Patch export entry and move it from regular | 119 // Found an indirect export. Patch export entry and move it from regular |
121 // to special. | 120 // to special. |
122 DCHECK_NULL(entry->import_name); | 121 DCHECK_NULL(entry->import_name); |
123 DCHECK_NULL(entry->module_request); | 122 DCHECK_LT(entry->module_request, 0); |
124 DCHECK_NOT_NULL(import->second->import_name); | 123 DCHECK_NOT_NULL(import->second->import_name); |
125 DCHECK_NOT_NULL(import->second->module_request); | 124 DCHECK_LE(0, import->second->module_request); |
| 125 DCHECK_LT(import->second->module_request, |
| 126 static_cast<int>(module_requests_.size())); |
126 entry->import_name = import->second->import_name; | 127 entry->import_name = import->second->import_name; |
127 entry->module_request = import->second->module_request; | 128 entry->module_request = import->second->module_request; |
128 entry->local_name = nullptr; | 129 entry->local_name = nullptr; |
129 special_exports_.Add(entry, zone); | 130 special_exports_.Add(entry, zone); |
130 it = regular_exports_.erase(it); | 131 it = regular_exports_.erase(it); |
131 } else { | 132 } else { |
132 it++; | 133 it++; |
133 } | 134 } |
134 } | 135 } |
135 } | 136 } |
(...skipping 17 matching lines...) Expand all Loading... |
153 : current_duplicate; | 154 : current_duplicate; |
154 } | 155 } |
155 | 156 |
156 } // namespace | 157 } // namespace |
157 | 158 |
158 const ModuleDescriptor::Entry* ModuleDescriptor::FindDuplicateExport( | 159 const ModuleDescriptor::Entry* ModuleDescriptor::FindDuplicateExport( |
159 Zone* zone) const { | 160 Zone* zone) const { |
160 const ModuleDescriptor::Entry* duplicate = nullptr; | 161 const ModuleDescriptor::Entry* duplicate = nullptr; |
161 ZoneMap<const AstRawString*, const ModuleDescriptor::Entry*> export_names( | 162 ZoneMap<const AstRawString*, const ModuleDescriptor::Entry*> export_names( |
162 zone); | 163 zone); |
163 for (const auto& it : regular_exports_) { | 164 for (const auto& elem : regular_exports_) { |
164 duplicate = BetterDuplicate(it.second, export_names, duplicate); | 165 duplicate = BetterDuplicate(elem.second, export_names, duplicate); |
165 } | 166 } |
166 for (auto entry : special_exports_) { | 167 for (auto entry : special_exports_) { |
167 if (entry->export_name == nullptr) continue; // Star export. | 168 if (entry->export_name == nullptr) continue; // Star export. |
168 duplicate = BetterDuplicate(entry, export_names, duplicate); | 169 duplicate = BetterDuplicate(entry, export_names, duplicate); |
169 } | 170 } |
170 return duplicate; | 171 return duplicate; |
171 } | 172 } |
172 | 173 |
173 bool ModuleDescriptor::Validate(ModuleScope* module_scope, | 174 bool ModuleDescriptor::Validate(ModuleScope* module_scope, |
174 PendingCompilationErrorHandler* error_handler, | 175 PendingCompilationErrorHandler* error_handler, |
175 Zone* zone) { | 176 Zone* zone) { |
176 DCHECK_EQ(this, module_scope->module()); | 177 DCHECK_EQ(this, module_scope->module()); |
177 DCHECK_NOT_NULL(error_handler); | 178 DCHECK_NOT_NULL(error_handler); |
178 | 179 |
179 // Report error iff there are duplicate exports. | 180 // Report error iff there are duplicate exports. |
180 { | 181 { |
181 const Entry* entry = FindDuplicateExport(zone); | 182 const Entry* entry = FindDuplicateExport(zone); |
182 if (entry != nullptr) { | 183 if (entry != nullptr) { |
183 error_handler->ReportMessageAt( | 184 error_handler->ReportMessageAt( |
184 entry->location.beg_pos, entry->location.end_pos, | 185 entry->location.beg_pos, entry->location.end_pos, |
185 MessageTemplate::kDuplicateExport, entry->export_name); | 186 MessageTemplate::kDuplicateExport, entry->export_name); |
186 return false; | 187 return false; |
187 } | 188 } |
188 } | 189 } |
189 | 190 |
190 // Report error iff there are exports of non-existent local names. | 191 // Report error iff there are exports of non-existent local names. |
191 for (const auto& it : regular_exports_) { | 192 for (const auto& elem : regular_exports_) { |
192 const Entry* entry = it.second; | 193 const Entry* entry = elem.second; |
193 DCHECK_NOT_NULL(entry->local_name); | 194 DCHECK_NOT_NULL(entry->local_name); |
194 if (module_scope->LookupLocal(entry->local_name) == nullptr) { | 195 if (module_scope->LookupLocal(entry->local_name) == nullptr) { |
195 error_handler->ReportMessageAt( | 196 error_handler->ReportMessageAt( |
196 entry->location.beg_pos, entry->location.end_pos, | 197 entry->location.beg_pos, entry->location.end_pos, |
197 MessageTemplate::kModuleExportUndefined, entry->local_name); | 198 MessageTemplate::kModuleExportUndefined, entry->local_name); |
198 return false; | 199 return false; |
199 } | 200 } |
200 } | 201 } |
201 | 202 |
202 MakeIndirectExportsExplicit(zone); | 203 MakeIndirectExportsExplicit(zone); |
203 return true; | 204 return true; |
204 } | 205 } |
205 | 206 |
206 } // namespace internal | 207 } // namespace internal |
207 } // namespace v8 | 208 } // namespace v8 |
OLD | NEW |