Chromium Code Reviews| 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 |