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 { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 } | 80 } |
81 | 81 |
82 } // namespace | 82 } // namespace |
83 | 83 |
84 Handle<ModuleInfoEntry> ModuleDescriptor::Entry::Serialize( | 84 Handle<ModuleInfoEntry> ModuleDescriptor::Entry::Serialize( |
85 Isolate* isolate) const { | 85 Isolate* isolate) const { |
86 CHECK(Smi::IsValid(module_request)); // TODO(neis): Check earlier? | 86 CHECK(Smi::IsValid(module_request)); // TODO(neis): Check earlier? |
87 return ModuleInfoEntry::New( | 87 return ModuleInfoEntry::New( |
88 isolate, ToStringOrUndefined(isolate, export_name), | 88 isolate, ToStringOrUndefined(isolate, export_name), |
89 ToStringOrUndefined(isolate, local_name), | 89 ToStringOrUndefined(isolate, local_name), |
90 ToStringOrUndefined(isolate, import_name), | 90 ToStringOrUndefined(isolate, import_name), module_request, cell_index, |
91 Handle<Object>(Smi::FromInt(module_request), isolate), location.beg_pos, | 91 location.beg_pos, location.end_pos); |
92 location.end_pos); | |
93 } | 92 } |
94 | 93 |
95 ModuleDescriptor::Entry* ModuleDescriptor::Entry::Deserialize( | 94 ModuleDescriptor::Entry* ModuleDescriptor::Entry::Deserialize( |
96 Isolate* isolate, AstValueFactory* avfactory, | 95 Isolate* isolate, AstValueFactory* avfactory, |
97 Handle<ModuleInfoEntry> entry) { | 96 Handle<ModuleInfoEntry> entry) { |
98 Entry* result = new (avfactory->zone()) Entry(Scanner::Location::invalid()); | 97 Entry* result = new (avfactory->zone()) Entry(Scanner::Location::invalid()); |
99 result->export_name = FromStringOrUndefined( | 98 result->export_name = FromStringOrUndefined( |
100 isolate, avfactory, handle(entry->export_name(), isolate)); | 99 isolate, avfactory, handle(entry->export_name(), isolate)); |
101 result->local_name = FromStringOrUndefined( | 100 result->local_name = FromStringOrUndefined( |
102 isolate, avfactory, handle(entry->local_name(), isolate)); | 101 isolate, avfactory, handle(entry->local_name(), isolate)); |
103 result->import_name = FromStringOrUndefined( | 102 result->import_name = FromStringOrUndefined( |
104 isolate, avfactory, handle(entry->import_name(), isolate)); | 103 isolate, avfactory, handle(entry->import_name(), isolate)); |
105 result->module_request = Smi::cast(entry->module_request())->value(); | 104 result->module_request = entry->module_request(); |
| 105 result->cell_index = entry->cell_index(); |
106 return result; | 106 return result; |
107 } | 107 } |
108 | 108 |
109 Handle<FixedArray> ModuleDescriptor::SerializeRegularExports(Isolate* isolate, | 109 Handle<FixedArray> ModuleDescriptor::SerializeRegularExports(Isolate* isolate, |
110 Zone* zone) const { | 110 Zone* zone) const { |
111 // We serialize regular exports in a way that lets us later iterate over their | 111 // We serialize regular exports in a way that lets us later iterate over their |
112 // local names and for each local name immediately access all its export | 112 // local names and for each local name immediately access all its export |
113 // names. (Regular exports have neither import name nor module request.) | 113 // names. (Regular exports have neither import name nor module request.) |
114 | 114 |
115 ZoneVector<Handle<Object>> data(zone); | 115 ZoneVector<Handle<Object>> data(zone); |
116 data.reserve(2 * regular_exports_.size()); | 116 data.reserve(3 * regular_exports_.size()); |
117 | 117 |
118 for (auto it = regular_exports_.begin(); it != regular_exports_.end();) { | 118 for (auto it = regular_exports_.begin(); it != regular_exports_.end();) { |
119 // Find out how many export names this local name has. | 119 // Find out how many export names this local name has. |
120 auto next = it; | 120 auto next = it; |
121 int size = 0; | 121 int size = 0; |
122 do { | 122 do { |
| 123 DCHECK_EQ(it->second->local_name, next->second->local_name); |
| 124 DCHECK_EQ(it->second->cell_index, next->second->cell_index); |
123 ++next; | 125 ++next; |
124 ++size; | 126 ++size; |
125 } while (next != regular_exports_.end() && next->first == it->first); | 127 } while (next != regular_exports_.end() && next->first == it->first); |
126 | 128 |
127 Handle<FixedArray> export_names = isolate->factory()->NewFixedArray(size); | 129 Handle<FixedArray> export_names = isolate->factory()->NewFixedArray(size); |
128 data.push_back(it->second->local_name->string()); | 130 data.push_back(it->second->local_name->string()); |
| 131 data.push_back(handle(Smi::FromInt(it->second->cell_index), isolate)); |
129 data.push_back(export_names); | 132 data.push_back(export_names); |
130 | 133 |
131 // Collect the export names. | 134 // Collect the export names. |
132 int i = 0; | 135 int i = 0; |
133 for (; it != next; ++it) { | 136 for (; it != next; ++it) { |
134 export_names->set(i++, *it->second->export_name->string()); | 137 export_names->set(i++, *it->second->export_name->string()); |
135 } | 138 } |
136 DCHECK_EQ(i, size); | 139 DCHECK_EQ(i, size); |
137 | 140 |
138 // Continue with the next distinct key. | 141 // Continue with the next distinct key. |
139 DCHECK(it == next); | 142 DCHECK(it == next); |
140 } | 143 } |
141 | 144 |
142 // We cannot create the FixedArray earlier because we only now know the | 145 // We cannot create the FixedArray earlier because we only now know the |
143 // precise size (the number of unique keys in regular_exports). | 146 // precise size (the number of unique keys in regular_exports). |
144 int size = static_cast<int>(data.size()); | 147 int size = static_cast<int>(data.size()); |
145 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); | 148 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); |
146 for (int i = 0; i < size; ++i) { | 149 for (int i = 0; i < size; ++i) { |
147 result->set(i, *data[i]); | 150 result->set(i, *data[i]); |
148 } | 151 } |
149 return result; | 152 return result; |
150 } | 153 } |
151 | 154 |
152 void ModuleDescriptor::DeserializeRegularExports(Isolate* isolate, | 155 void ModuleDescriptor::DeserializeRegularExports(Isolate* isolate, |
153 AstValueFactory* avfactory, | 156 AstValueFactory* avfactory, |
154 Handle<FixedArray> data) { | 157 Handle<FixedArray> data) { |
155 for (int i = 0, length_i = data->length(); i < length_i;) { | 158 for (int i = 0, length_i = data->length(); i < length_i;) { |
156 Handle<String> local_name(String::cast(data->get(i++)), isolate); | 159 Handle<String> local_name(String::cast(data->get(i++)), isolate); |
| 160 int cell_index = Smi::cast(data->get(i++))->value(); |
157 Handle<FixedArray> export_names(FixedArray::cast(data->get(i++)), isolate); | 161 Handle<FixedArray> export_names(FixedArray::cast(data->get(i++)), isolate); |
158 | 162 |
159 for (int j = 0, length_j = export_names->length(); j < length_j; ++j) { | 163 for (int j = 0, length_j = export_names->length(); j < length_j; ++j) { |
160 Handle<String> export_name(String::cast(export_names->get(j)), isolate); | 164 Handle<String> export_name(String::cast(export_names->get(j)), isolate); |
161 | 165 |
162 Entry* entry = | 166 Entry* entry = |
163 new (avfactory->zone()) Entry(Scanner::Location::invalid()); | 167 new (avfactory->zone()) Entry(Scanner::Location::invalid()); |
164 entry->local_name = avfactory->GetString(local_name); | 168 entry->local_name = avfactory->GetString(local_name); |
165 entry->export_name = avfactory->GetString(export_name); | 169 entry->export_name = avfactory->GetString(export_name); |
| 170 entry->cell_index = cell_index; |
166 | 171 |
167 AddRegularExport(entry); | 172 AddRegularExport(entry); |
168 } | 173 } |
169 } | 174 } |
170 } | 175 } |
171 | 176 |
172 void ModuleDescriptor::MakeIndirectExportsExplicit(Zone* zone) { | 177 void ModuleDescriptor::MakeIndirectExportsExplicit(Zone* zone) { |
173 for (auto it = regular_exports_.begin(); it != regular_exports_.end();) { | 178 for (auto it = regular_exports_.begin(); it != regular_exports_.end();) { |
174 Entry* entry = it->second; | 179 Entry* entry = it->second; |
175 DCHECK_NOT_NULL(entry->local_name); | 180 DCHECK_NOT_NULL(entry->local_name); |
(...skipping 18 matching lines...) Expand all Loading... |
194 entry->location = import->second->location; | 199 entry->location = import->second->location; |
195 entry->local_name = nullptr; | 200 entry->local_name = nullptr; |
196 AddSpecialExport(entry, zone); | 201 AddSpecialExport(entry, zone); |
197 it = regular_exports_.erase(it); | 202 it = regular_exports_.erase(it); |
198 } else { | 203 } else { |
199 it++; | 204 it++; |
200 } | 205 } |
201 } | 206 } |
202 } | 207 } |
203 | 208 |
| 209 void ModuleDescriptor::AssignCellIndices() { |
| 210 int export_index = 1; |
| 211 for (auto it = regular_exports_.begin(); it != regular_exports_.end();) { |
| 212 auto current_key = it->first; |
| 213 // This local name may be exported under multiple export names. Assign the |
| 214 // same index to each such entry. |
| 215 do { |
| 216 Entry* entry = it->second; |
| 217 DCHECK_NOT_NULL(entry->local_name); |
| 218 DCHECK_NULL(entry->import_name); |
| 219 DCHECK_LT(entry->module_request, 0); |
| 220 DCHECK_EQ(entry->cell_index, 0); |
| 221 entry->cell_index = export_index; |
| 222 it++; |
| 223 } while (it != regular_exports_.end() && it->first == current_key); |
| 224 export_index++; |
| 225 } |
| 226 |
| 227 int import_index = -1; |
| 228 for (const auto& elem : regular_imports_) { |
| 229 Entry* entry = elem.second; |
| 230 DCHECK_NOT_NULL(entry->local_name); |
| 231 DCHECK_NOT_NULL(entry->import_name); |
| 232 DCHECK_LE(0, entry->module_request); |
| 233 DCHECK_EQ(entry->cell_index, 0); |
| 234 entry->cell_index = import_index; |
| 235 import_index--; |
| 236 } |
| 237 } |
| 238 |
204 namespace { | 239 namespace { |
205 | 240 |
206 const ModuleDescriptor::Entry* BetterDuplicate( | 241 const ModuleDescriptor::Entry* BetterDuplicate( |
207 const ModuleDescriptor::Entry* candidate, | 242 const ModuleDescriptor::Entry* candidate, |
208 ZoneMap<const AstRawString*, const ModuleDescriptor::Entry*>& export_names, | 243 ZoneMap<const AstRawString*, const ModuleDescriptor::Entry*>& export_names, |
209 const ModuleDescriptor::Entry* current_duplicate) { | 244 const ModuleDescriptor::Entry* current_duplicate) { |
210 DCHECK_NOT_NULL(candidate->export_name); | 245 DCHECK_NOT_NULL(candidate->export_name); |
211 DCHECK(candidate->location.IsValid()); | 246 DCHECK(candidate->location.IsValid()); |
212 auto insert_result = | 247 auto insert_result = |
213 export_names.insert(std::make_pair(candidate->export_name, candidate)); | 248 export_names.insert(std::make_pair(candidate->export_name, candidate)); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 DCHECK_NOT_NULL(entry->local_name); | 295 DCHECK_NOT_NULL(entry->local_name); |
261 if (module_scope->LookupLocal(entry->local_name) == nullptr) { | 296 if (module_scope->LookupLocal(entry->local_name) == nullptr) { |
262 error_handler->ReportMessageAt( | 297 error_handler->ReportMessageAt( |
263 entry->location.beg_pos, entry->location.end_pos, | 298 entry->location.beg_pos, entry->location.end_pos, |
264 MessageTemplate::kModuleExportUndefined, entry->local_name); | 299 MessageTemplate::kModuleExportUndefined, entry->local_name); |
265 return false; | 300 return false; |
266 } | 301 } |
267 } | 302 } |
268 | 303 |
269 MakeIndirectExportsExplicit(zone); | 304 MakeIndirectExportsExplicit(zone); |
| 305 AssignCellIndices(); |
270 return true; | 306 return true; |
271 } | 307 } |
272 | 308 |
273 } // namespace internal | 309 } // namespace internal |
274 } // namespace v8 | 310 } // namespace v8 |
OLD | NEW |