OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium 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 "core/loader/modulescript/ModuleTreeLinker.h" | 5 #include "core/loader/modulescript/ModuleTreeLinker.h" |
6 | 6 |
7 #include "bindings/core/v8/ScriptModule.h" | 7 #include "bindings/core/v8/ScriptModule.h" |
8 #include "core/dom/AncestorList.h" | 8 #include "core/dom/AncestorList.h" |
9 #include "core/dom/ModuleScript.h" | 9 #include "core/dom/ModuleScript.h" |
10 #include "core/loader/modulescript/ModuleScriptFetchRequest.h" | 10 #include "core/loader/modulescript/ModuleScriptFetchRequest.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 NOTREACHED(); | 105 NOTREACHED(); |
106 break; | 106 break; |
107 } | 107 } |
108 | 108 |
109 state_ = new_state; | 109 state_ = new_state; |
110 | 110 |
111 if (state_ == State::kFinished) { | 111 if (state_ == State::kFinished) { |
112 registry_->ReleaseFinishedFetcher(this); | 112 registry_->ReleaseFinishedFetcher(this); |
113 | 113 |
114 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-sc ript-graph-fetching-procedure | 114 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-sc ript-graph-fetching-procedure |
115 // Step 8. Asynchronously complete this algorithm with descendants result. | 115 // Step 9. Asynchronously complete this algorithm with descendants result. |
116 client_->NotifyModuleTreeLoadFinished(descendants_module_script_); | 116 client_->NotifyModuleTreeLoadFinished(descendants_module_script_); |
117 } | 117 } |
118 } | 118 } |
119 | 119 |
120 void ModuleTreeLinker::FetchSelf(const ModuleScriptFetchRequest& request, | 120 void ModuleTreeLinker::FetchSelf(const ModuleScriptFetchRequest& request, |
121 ModuleGraphLevel level) { | 121 ModuleGraphLevel level) { |
122 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-scri pt-graph-fetching-procedure | 122 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-scri pt-graph-fetching-procedure |
123 | 123 |
124 // Step 1. Fetch a single module script given url, fetch client settings | 124 // Step 1. Fetch a single module script given url, fetch client settings |
125 // object, destination, cryptographic nonce, parser state, credentials mode, | 125 // object, destination, cryptographic nonce, parser state, credentials mode, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 | 197 |
198 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-the-descendant s-of-a-module-script | 198 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-the-descendant s-of-a-module-script |
199 | 199 |
200 // Step 1. Let record be module script's module record. | 200 // Step 1. Let record be module script's module record. |
201 ScriptModule record = module_script_->Record(); | 201 ScriptModule record = module_script_->Record(); |
202 | 202 |
203 // Step 2. If record.[[RequestedModules]] is empty, asynchronously complete | 203 // Step 2. If record.[[RequestedModules]] is empty, asynchronously complete |
204 // this algorithm with module script. | 204 // this algorithm with module script. |
205 Vector<String> module_requests = | 205 Vector<String> module_requests = |
206 modulator_->ModuleRequestsFromScriptModule(record); | 206 modulator_->ModuleRequestsFromScriptModule(record); |
207 if (module_requests.IsEmpty()) { | |
208 // Continue to Instantiate() to process "internal module script graph | |
209 // fetching procedure" Step 5-. | |
210 descendants_module_script_ = module_script_; | |
211 Instantiate(); | |
212 return; | |
213 } | |
214 | 207 |
215 // Step 3. Let urls be a new empty list. | 208 // Step 3. Let urls be a new empty list. |
216 Vector<KURL> urls; | 209 Vector<KURL> urls; |
217 | 210 |
218 // Step 4. For each string requested of record.[[RequestedModules]], | 211 // Step 4. For each string requested of record.[[RequestedModules]], |
219 for (const auto& module_request : module_requests) { | 212 for (const auto& module_request : module_requests) { |
220 // Step 4.1. Let url be the result of resolving a module specifier given | 213 // Step 4.1. Let url be the result of resolving a module specifier given |
221 // module script and requested. | 214 // module script and requested. |
222 KURL url = Modulator::ResolveModuleSpecifier(module_request, | 215 KURL url = Modulator::ResolveModuleSpecifier(module_request, |
223 module_script_->BaseURL()); | 216 module_script_->BaseURL()); |
224 | 217 |
225 // Step 4.2. If the result is error: ... | 218 // Step 4.2. If the result is error: ... |
226 if (url.IsNull()) { | 219 if (url.IsNull()) { |
227 // Let error be a new TypeError exception. | 220 // Let error be a new TypeError exception. |
228 // Report the exception error for module script. | 221 // Report the exception error for module script. |
229 // TODO(kouhei): Implement the exception. | 222 // TODO(kouhei): Implement the exception. |
230 | 223 |
231 // Abort this algorithm, and asynchronously complete it with null. | 224 // Abort this algorithm, and asynchronously complete it with null. |
232 // Note: The return variable for "internal module script graph fetching | 225 // Note: The return variable for "internal module script graph fetching |
233 // procedure" is descendants_module_script_ per Step 8. | 226 // procedure" is descendants_module_script_ per Step 9. |
234 DCHECK(!descendants_module_script_); | 227 DCHECK(!descendants_module_script_); |
235 // Note: while we complete "fetch the descendants of a module script" | 228 // Note: while we complete "fetch the descendants of a module script" |
236 // algorithm here, we still need to continue to the rest of the | 229 // algorithm here, we still need to continue to the rest of the |
237 // steps in "internal module script graph fetching procedure" | 230 // steps in "internal module script graph fetching procedure" |
238 Instantiate(); | 231 Instantiate(); |
239 return; | 232 return; |
240 } | 233 } |
241 | 234 |
242 // Step 4.3. Otherwise, if ancestor list does not contain url, append url to | 235 // Step 4.3. Otherwise, if ancestor list does not contain url, append url to |
243 // urls. | 236 // urls. |
244 | 237 |
245 // Modulator::resolveModuleSpecifier() impl must return either a valid url | 238 // Modulator::resolveModuleSpecifier() impl must return either a valid url |
246 // or null. | 239 // or null. |
247 CHECK(url.IsValid()); | 240 CHECK(url.IsValid()); |
248 if (!ancestor_list_with_url_.Contains(url)) | 241 if (!ancestor_list_with_url_.Contains(url)) |
249 urls.push_back(url); | 242 urls.push_back(url); |
250 } | 243 } |
251 | 244 |
252 // Step 5. For each url in urls, perform the internal module script graph | 245 // Step 5. For each url in urls, perform the internal module script graph |
253 // fetching procedure given url, module script's credentials mode, module | 246 // fetching procedure given url, module script's credentials mode, module |
254 // script's cryptographic nonce, module script's parser state, destination, | 247 // script's cryptographic nonce, module script's parser state, destination, |
255 // module script's settings object, module script's settings object, ancestor | 248 // module script's settings object, module script's settings object, ancestor |
256 // list, module script's base URL, and with the top-level module fetch flag | 249 // list, module script's base URL, and with the top-level module fetch flag |
257 // unset. If the caller of this algorithm specified custom perform the fetch | 250 // unset. If the caller of this algorithm specified custom perform the fetch |
258 // steps, pass those along while performing the internal module script graph | 251 // steps, pass those along while performing the internal module script graph |
259 // fetching procedure. | 252 // fetching procedure. |
260 // TODO(kouhei): handle "destination". | 253 // TODO(kouhei): handle "destination". |
261 DCHECK(!urls.IsEmpty()); | 254 if (urls.IsEmpty()) { |
kouhei (in TOK)
2017/04/26 13:03:44
DCHECK doesn't always hold. The requests may be al
hiroshige
2017/04/28 01:15:35
Memo: This causes crash in imports.html wpt test.
| |
255 // Continue to Instantiate() to process "internal module script graph | |
256 // fetching procedure" Step 5-. | |
257 descendants_module_script_ = module_script_; | |
258 Instantiate(); | |
259 | |
260 RESOURCE_LOADING_DVLOG(1) << "maybe cycles? " << module_script_->BaseURL().G etString(); | |
261 return; | |
262 } | |
262 CHECK_EQ(num_incomplete_descendants_, 0u); | 263 CHECK_EQ(num_incomplete_descendants_, 0u); |
263 num_incomplete_descendants_ = urls.size(); | 264 num_incomplete_descendants_ = urls.size(); |
264 for (const KURL& url : urls) { | 265 for (const KURL& url : urls) { |
265 DependencyModuleClient* dependency_client = | 266 DependencyModuleClient* dependency_client = |
266 DependencyModuleClient::Create(this); | 267 DependencyModuleClient::Create(this); |
267 dependency_clients_.insert(dependency_client); | 268 dependency_clients_.insert(dependency_client); |
268 | 269 |
269 ModuleScriptFetchRequest request(url, module_script_->Nonce(), | 270 ModuleScriptFetchRequest request(url, module_script_->Nonce(), |
270 module_script_->ParserState(), | 271 module_script_->ParserState(), |
271 module_script_->CredentialsMode(), | 272 module_script_->CredentialsMode(), |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 Instantiate(); | 330 Instantiate(); |
330 } | 331 } |
331 } | 332 } |
332 | 333 |
333 void ModuleTreeLinker::Instantiate() { | 334 void ModuleTreeLinker::Instantiate() { |
334 CHECK(module_script_); | 335 CHECK(module_script_); |
335 AdvanceState(State::kInstantiating); | 336 AdvanceState(State::kInstantiating); |
336 | 337 |
337 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-scri pt-graph-fetching-procedure | 338 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-scri pt-graph-fetching-procedure |
338 | 339 |
339 // Step 5. Let record be result's module record. | 340 // Step 5. Let instantiationStatus be null. |
340 ScriptModule record = module_script_->Record(); | |
341 | |
342 // Step 6. Let instantiationStatus be record.ModuleDeclarationInstantiation(). | |
343 // Note: The |error| variable corresponds to spec variable | 341 // Note: The |error| variable corresponds to spec variable |
344 // "instantiationStatus". If |error| is empty, it indicates successful | 342 // "instantiationStatus". If |error| is empty, it indicates successful |
345 // completion. | 343 // completion. |
346 ScriptValue error = modulator_->InstantiateModule(record); | 344 ScriptValue error; |
347 | 345 |
348 // Step 7. For each module script script in result's uninstantiated inclusive | 346 // Step 6. If result's instantiation state is "errored",... |
347 if (module_script_->InstantiationState() == | |
348 ModuleInstantiationState::kErrored) { | |
349 // ... Set instantiationStatus to record.ModuleDeclarationInstantiation(). | |
350 error = modulator_->GetInstantiationError(module_script_); | |
351 } else { | |
352 // Step 7. Otherwise: | |
353 // Step 7.1. Let record be result's module record. | |
354 ScriptModule record = module_script_->Record(); | |
355 // Step 7.2. Set instantiationStatus to | |
356 // record.ModuleDeclarationInstantiation(). | |
357 error = modulator_->InstantiateModule(record); | |
358 } | |
359 | |
360 // Step 8. For each module script script in result's uninstantiated inclusive | |
349 // descendant module scripts, perform the following steps: | 361 // descendant module scripts, perform the following steps: |
350 HeapHashSet<Member<ModuleScript>> uninstantiated_set = | 362 HeapHashSet<Member<ModuleScript>> uninstantiated_set = |
351 UninstantiatedInclusiveDescendants(); | 363 UninstantiatedInclusiveDescendants(); |
352 for (const auto& descendant : uninstantiated_set) { | 364 for (const auto& descendant : uninstantiated_set) { |
353 if (!error.IsEmpty()) { | 365 if (!error.IsEmpty()) { |
354 // Step 7.1. If instantiationStatus is an abrupt completion, then set | 366 // Step 8.1. If instantiationStatus is an abrupt completion, then |
355 // script's instantiation state to "errored", its instantiation error to | 367 // Step 8.1.1. Set script module record's [[HostDefined]] field to |
356 // instantiationStatus.[[Value]], and its module record to null. | 368 // undefined. |
369 // TODO(kouhei): Implement this. | |
370 | |
371 // Step 8.1.2. Set script's module record to null. | |
372 // Step 8.1.3. Set script's instantiation state to "errored". | |
373 // Step 8.1.4. Set script's instantiation error to | |
374 // instantiationStatus.[[Value]]. | |
357 descendant->SetInstantiationErrorAndClearRecord(error); | 375 descendant->SetInstantiationErrorAndClearRecord(error); |
358 } else { | 376 } else { |
359 // Step 7.2. Otherwise, set script's instantiation state to | 377 // Step 8.2. Otherwise, set script's instantiation state to |
360 // "instantiated". | 378 // "instantiated". |
361 descendant->SetInstantiationSuccess(); | 379 descendant->SetInstantiationSuccess(); |
362 } | 380 } |
363 } | 381 } |
364 | 382 |
365 // Step 8. Asynchronously complete this algorithm with descendants result. | 383 // Step 9. Asynchronously complete this algorithm with descendants result. |
366 AdvanceState(State::kFinished); | 384 AdvanceState(State::kFinished); |
367 } | 385 } |
368 | 386 |
369 HeapHashSet<Member<ModuleScript>> | 387 HeapHashSet<Member<ModuleScript>> |
370 ModuleTreeLinker::UninstantiatedInclusiveDescendants() { | 388 ModuleTreeLinker::UninstantiatedInclusiveDescendants() { |
371 // https://html.spec.whatwg.org/multipage/webappapis.html#uninstantiated-inclu sive-descendant-module-scripts | 389 // https://html.spec.whatwg.org/multipage/webappapis.html#uninstantiated-inclu sive-descendant-module-scripts |
372 // Step 1. Let moduleMap be script's settings object's module map. | 390 // Step 1. Let moduleMap be script's settings object's module map. |
373 // Note: Modulator is our "settings object". | 391 // Note: Modulator is our "settings object". |
374 // Note: We won't reference the ModuleMap directly here to aid testing. | 392 // Note: We won't reference the ModuleMap directly here to aid testing. |
375 | 393 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 HeapHashSet<Member<ModuleScript>> uninstantiated_set; | 472 HeapHashSet<Member<ModuleScript>> uninstantiated_set; |
455 for (const auto& script : inclusive_descendants) { | 473 for (const auto& script : inclusive_descendants) { |
456 if (script->InstantiationState() == | 474 if (script->InstantiationState() == |
457 ModuleInstantiationState::kUninstantiated) | 475 ModuleInstantiationState::kUninstantiated) |
458 uninstantiated_set.insert(script); | 476 uninstantiated_set.insert(script); |
459 } | 477 } |
460 return uninstantiated_set; | 478 return uninstantiated_set; |
461 } | 479 } |
462 | 480 |
463 } // namespace blink | 481 } // namespace blink |
OLD | NEW |