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" |
| 11 #include "core/loader/modulescript/ModuleTreeLinkerRegistry.h" | 11 #include "core/loader/modulescript/ModuleTreeLinkerRegistry.h" |
| 12 #include "platform/loader/fetch/ResourceLoadingLog.h" | 12 #include "platform/loader/fetch/ResourceLoadingLog.h" |
| 13 #include "platform/wtf/HashSet.h" | 13 #include "platform/wtf/HashSet.h" |
|
nhiroki
2017/04/20 09:06:25
"HashSet.h" may be unused (HeapHashSet is defined
| |
| 14 | 14 |
| 15 namespace blink { | 15 namespace blink { |
| 16 | 16 |
| 17 ModuleTreeLinker* ModuleTreeLinker::Fetch( | 17 ModuleTreeLinker* ModuleTreeLinker::Fetch( |
| 18 const ModuleScriptFetchRequest& request, | 18 const ModuleScriptFetchRequest& request, |
| 19 const AncestorList& ancestor_list, | 19 const AncestorList& ancestor_list, |
| 20 ModuleGraphLevel level, | 20 ModuleGraphLevel level, |
| 21 Modulator* modulator, | 21 Modulator* modulator, |
| 22 ModuleTreeLinkerRegistry* registry, | 22 ModuleTreeLinkerRegistry* registry, |
| 23 ModuleTreeClient* client) { | 23 ModuleTreeClient* client) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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, |
| 126 // module map settings object, referrer, and the top-level module fetch flag. | 126 // module map settings object, referrer, and the top-level module fetch flag. |
| 127 // If the caller of this algorithm specified custom perform the fetch steps, | 127 // If the caller of this algorithm specified custom perform the fetch steps, |
| 128 // pass those along while fetching a single module script. | 128 // pass those along while fetching a single module script. |
| 129 AdvanceState(State::kFetchingSelf); | 129 AdvanceState(State::kFetchingSelf); |
| 130 modulator_->FetchSingle(request, level, this); | 130 modulator_->FetchSingle(request, level, this); |
| 131 | 131 |
| 132 // Step 2. Return from this algorithm, and run the following steps when | 132 // Step 2. Return from this algorithm, and run the following steps when |
| 133 // fetching a single module script asynchronously completes with result. | 133 // fetching a single module script asynchronously completes with result. |
| 134 // Note: Modulator::fetchSingle asynchronously notifies result to | 134 // Note: Modulator::FetchSingle asynchronously notifies result to |
| 135 // ModuleTreeLinker::notifyModuleLoadFinished(). | 135 // ModuleTreeLinker::notifyModuleLoadFinished(). |
| 136 } | 136 } |
| 137 | 137 |
| 138 void ModuleTreeLinker::NotifyModuleLoadFinished(ModuleScript* module_script) { | 138 void ModuleTreeLinker::NotifyModuleLoadFinished(ModuleScript* module_script) { |
| 139 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-scri pt-graph-fetching-procedure | 139 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-scri pt-graph-fetching-procedure |
| 140 | 140 |
| 141 // Step 3. "If result is null, ..." | 141 // Step 3. "If result is null, ..." |
| 142 if (!module_script) { | 142 if (!module_script) { |
| 143 // "asynchronously complete this algorithm with null and abort these steps." | 143 // "asynchronously complete this algorithm with null and abort these steps." |
| 144 // Note: The return variable for "internal module script graph fetching | 144 // Note: We return null by calling AdvanceState(), which calls |
| 145 // procedure" is descendants_module_script_ per Step 8. | 145 // NotifyModuleTreeLoadFinished(descendants_module_script_), and in this |
| 146 // case |descendants_module_script_| is always null) | |
|
hiroshige
2017/04/20 09:38:47
small nit: extra ')' at the end of the line.
| |
| 146 DCHECK(!descendants_module_script_); | 147 DCHECK(!descendants_module_script_); |
| 147 AdvanceState(State::kFinished); | 148 AdvanceState(State::kFinished); |
| 148 return; | 149 return; |
| 149 } | 150 } |
| 150 | 151 |
| 151 // Step 4. Otherwise, result is a module script. Fetch the descendants of | 152 // Step 4. Otherwise, result is a module script. Fetch the descendants of |
| 152 // result given destination and an ancestor list obtained by appending url to | 153 // result given destination and an ancestor list obtained by appending url to |
| 153 // ancestor list. Wait for fetching the descendants of a module script to | 154 // ancestor list. Wait for fetching the descendants of a module script to |
| 154 // asynchronously complete with descendants result before proceeding to the | 155 // asynchronously complete with descendants result before proceeding to the |
| 155 // next step. | 156 // next step. |
| 156 module_script_ = module_script; | 157 module_script_ = module_script; |
| 157 | 158 |
| 158 FetchDescendants(); | 159 FetchDescendants(); |
| 159 | 160 |
| 160 // Note: Step 5- continues in instantiate() method, after | 161 // Note: Step 5- continues in Instantiate() method, after |
| 161 // "fetch the descendants of a module script" procedure completes. | 162 // "fetch the descendants of a module script" procedure completes. |
| 162 } | 163 } |
| 163 | 164 |
| 164 class ModuleTreeLinker::DependencyModuleClient | 165 class ModuleTreeLinker::DependencyModuleClient |
| 165 : public GarbageCollectedFinalized< | 166 : public GarbageCollectedFinalized< |
| 166 ModuleTreeLinker::DependencyModuleClient>, | 167 ModuleTreeLinker::DependencyModuleClient>, |
| 167 public ModuleTreeClient { | 168 public ModuleTreeClient { |
| 168 USING_GARBAGE_COLLECTED_MIXIN(ModuleTreeLinker::DependencyModuleClient); | 169 USING_GARBAGE_COLLECTED_MIXIN(ModuleTreeLinker::DependencyModuleClient); |
| 169 | 170 |
| 170 public: | 171 public: |
| 171 static DependencyModuleClient* Create(ModuleTreeLinker* module_tree_linker) { | 172 static DependencyModuleClient* Create(ModuleTreeLinker* module_tree_linker) { |
| 172 return new DependencyModuleClient(module_tree_linker); | 173 return new DependencyModuleClient(module_tree_linker); |
| 173 } | 174 } |
| 174 virtual ~DependencyModuleClient() = default; | 175 virtual ~DependencyModuleClient() = default; |
| 175 | 176 |
| 176 DEFINE_INLINE_TRACE() { | 177 DEFINE_INLINE_TRACE() { |
| 177 visitor->Trace(module_tree_linker_); | 178 visitor->Trace(module_tree_linker_); |
| 178 ModuleTreeClient::Trace(visitor); | 179 ModuleTreeClient::Trace(visitor); |
| 179 } | 180 } |
| 180 | 181 |
| 181 private: | 182 private: |
| 182 DependencyModuleClient(ModuleTreeLinker* module_tree_linker) | 183 explicit DependencyModuleClient(ModuleTreeLinker* module_tree_linker) |
| 183 : module_tree_linker_(module_tree_linker) { | 184 : module_tree_linker_(module_tree_linker) { |
| 184 CHECK(module_tree_linker); | 185 CHECK(module_tree_linker); |
| 185 } | 186 } |
| 186 | 187 |
| 187 // Implements ModuleTreeClient | 188 // Implements ModuleTreeClient |
| 188 void NotifyModuleTreeLoadFinished(ModuleScript*) override; | 189 void NotifyModuleTreeLoadFinished(ModuleScript*) override; |
| 189 | 190 |
| 190 Member<ModuleTreeLinker> module_tree_linker_; | 191 Member<ModuleTreeLinker> module_tree_linker_; |
| 191 }; | 192 }; |
| 192 | 193 |
| 193 void ModuleTreeLinker::FetchDescendants() { | 194 void ModuleTreeLinker::FetchDescendants() { |
| 194 CHECK(module_script_); | 195 CHECK(module_script_); |
| 195 AdvanceState(State::kFetchingDependencies); | 196 AdvanceState(State::kFetchingDependencies); |
| 196 | 197 |
| 197 // 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 |
| 198 | 199 |
| 199 // Step 1. Let record be module script's module record. | 200 // Step 1. Let record be module script's module record. |
| 200 ScriptModule record = module_script_->Record(); | 201 ScriptModule record = module_script_->Record(); |
| 201 | 202 |
| 202 // Step 2. If record.[[RequestedModules]] is empty, asynchronously complete | 203 // Step 2. If record.[[RequestedModules]] is empty, asynchronously complete |
| 203 // this algorithm with module script. | 204 // this algorithm with module script. |
| 204 Vector<String> module_requests = | 205 Vector<String> module_requests = |
| 205 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 } | |
| 206 | 214 |
| 207 // Step 3. Let urls be a new empty list. | 215 // Step 3. Let urls be a new empty list. |
| 208 HashSet<KURL> urls; | 216 Vector<KURL> urls; |
| 209 | 217 |
| 210 // Step 4. For each string requested of record.[[RequestedModules]], | 218 // Step 4. For each string requested of record.[[RequestedModules]], |
| 211 for (const auto& module_request : module_requests) { | 219 for (const auto& module_request : module_requests) { |
| 212 // Step 4.1. Let url be the result of resolving a module specifier given | 220 // Step 4.1. Let url be the result of resolving a module specifier given |
| 213 // module script and requested. | 221 // module script and requested. |
| 214 KURL url = Modulator::ResolveModuleSpecifier(module_request, | 222 KURL url = Modulator::ResolveModuleSpecifier(module_request, |
| 215 module_script_->BaseURL()); | 223 module_script_->BaseURL()); |
| 216 | 224 |
| 217 // Step 4.2. If the result is error: ... | 225 // Step 4.2. If the result is error: ... |
| 218 if (url.IsNull()) { | 226 if (url.IsNull()) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 231 return; | 239 return; |
| 232 } | 240 } |
| 233 | 241 |
| 234 // Step 4.3. Otherwise, if ancestor list does not contain url, append url to | 242 // Step 4.3. Otherwise, if ancestor list does not contain url, append url to |
| 235 // urls. | 243 // urls. |
| 236 | 244 |
| 237 // Modulator::resolveModuleSpecifier() impl must return either a valid url | 245 // Modulator::resolveModuleSpecifier() impl must return either a valid url |
| 238 // or null. | 246 // or null. |
| 239 CHECK(url.IsValid()); | 247 CHECK(url.IsValid()); |
| 240 if (!ancestor_list_with_url_.Contains(url)) | 248 if (!ancestor_list_with_url_.Contains(url)) |
| 241 urls.insert(url); | 249 urls.push_back(url); |
| 242 } | 250 } |
| 243 | 251 |
| 244 // Step 5. For each url in urls, perform the internal module script graph | 252 // Step 5. For each url in urls, perform the internal module script graph |
| 245 // fetching procedure given url, module script's credentials mode, module | 253 // fetching procedure given url, module script's credentials mode, module |
| 246 // script's cryptographic nonce, module script's parser state, destination, | 254 // script's cryptographic nonce, module script's parser state, destination, |
| 247 // module script's settings object, module script's settings object, ancestor | 255 // module script's settings object, module script's settings object, ancestor |
| 248 // list, module script's base URL, and with the top-level module fetch flag | 256 // list, module script's base URL, and with the top-level module fetch flag |
| 249 // unset. If the caller of this algorithm specified custom perform the fetch | 257 // unset. If the caller of this algorithm specified custom perform the fetch |
| 250 // steps, pass those along while performing the internal module script graph | 258 // steps, pass those along while performing the internal module script graph |
| 251 // fetching procedure. | 259 // fetching procedure. |
| 252 // TODO(kouhei): handle "destination". | 260 // TODO(kouhei): handle "destination". |
| 261 DCHECK(!urls.IsEmpty()); | |
| 253 CHECK_EQ(num_incomplete_descendants_, 0u); | 262 CHECK_EQ(num_incomplete_descendants_, 0u); |
| 254 if (urls.IsEmpty()) { | |
| 255 // Continue to instantiate() to process "internal module script graph | |
| 256 // fetching procedure" Step 5-. | |
| 257 descendants_module_script_ = module_script_; | |
| 258 Instantiate(); | |
| 259 return; | |
| 260 } | |
| 261 num_incomplete_descendants_ = urls.size(); | 263 num_incomplete_descendants_ = urls.size(); |
| 262 for (const KURL& url : urls) { | 264 for (const KURL& url : urls) { |
| 263 DependencyModuleClient* dependency_client = | 265 DependencyModuleClient* dependency_client = |
| 264 DependencyModuleClient::Create(this); | 266 DependencyModuleClient::Create(this); |
| 265 dependency_clients_.insert(dependency_client); | 267 dependency_clients_.insert(dependency_client); |
| 266 | 268 |
| 267 ModuleScriptFetchRequest request(url, module_script_->Nonce(), | 269 ModuleScriptFetchRequest request(url, module_script_->Nonce(), |
| 268 module_script_->ParserState(), | 270 module_script_->ParserState(), |
| 269 module_script_->CredentialsMode(), | 271 module_script_->CredentialsMode(), |
| 270 module_script_->BaseURL().GetString()); | 272 module_script_->BaseURL().GetString()); |
| 271 modulator_->FetchTreeInternal(request, ancestor_list_with_url_, | 273 modulator_->FetchTreeInternal(request, ancestor_list_with_url_, |
| 272 ModuleGraphLevel::kDependentModuleFetch, | 274 ModuleGraphLevel::kDependentModuleFetch, |
| 273 dependency_client); | 275 dependency_client); |
| 274 } | 276 } |
| 275 | 277 |
| 276 // Asynchronously continue processing after notifyOneDescendantFinished() is | 278 // Asynchronously continue processing after notifyOneDescendantFinished() is |
| 277 // called m_numIncompleteDescendants times. | 279 // called m_numIncompleteDescendants times. |
| 278 CHECK_GT(num_incomplete_descendants_, 0u); | 280 CHECK_GT(num_incomplete_descendants_, 0u); |
| 279 } | 281 } |
| 280 | 282 |
| 281 void ModuleTreeLinker::DependencyModuleClient::NotifyModuleTreeLoadFinished( | 283 void ModuleTreeLinker::DependencyModuleClient::NotifyModuleTreeLoadFinished( |
| 282 ModuleScript* module_script) { | 284 ModuleScript* module_script) { |
| 283 DescendantLoad was_success = | 285 DescendantLoad was_success = |
| 284 !!module_script ? DescendantLoad::kSuccess : DescendantLoad::kFailed; | 286 module_script ? DescendantLoad::kSuccess : DescendantLoad::kFailed; |
| 285 module_tree_linker_->NotifyOneDescendantFinished(was_success); | 287 module_tree_linker_->NotifyOneDescendantFinished(was_success); |
| 286 } | 288 } |
| 287 | 289 |
| 288 void ModuleTreeLinker::NotifyOneDescendantFinished(DescendantLoad was_success) { | 290 void ModuleTreeLinker::NotifyOneDescendantFinished(DescendantLoad was_success) { |
| 289 CHECK(!descendants_module_script_); | 291 CHECK(!descendants_module_script_); |
| 290 | 292 |
| 291 if (state_ == State::kFinished) { | 293 if (state_ == State::kFinished) { |
| 292 // We may reach here if one of the descendant failed to load, and the other | 294 // We may reach here if one of the descendant failed to load, and the other |
| 293 // descendants fetches were in flight. | 295 // descendants fetches were in flight. |
| 294 return; | 296 return; |
| 295 } | 297 } |
| 296 CHECK_EQ(state_, State::kFetchingDependencies); | 298 CHECK_EQ(state_, State::kFetchingDependencies); |
| 297 | 299 |
| 298 CHECK_GT(num_incomplete_descendants_, 0u); | 300 CHECK_GT(num_incomplete_descendants_, 0u); |
| 299 --num_incomplete_descendants_; | 301 --num_incomplete_descendants_; |
| 300 | 302 |
| 301 // TODO(kouhei): Potential room for optimization. Cancel inflight descendants | 303 // TODO(kouhei): Potential room for optimization. Cancel inflight descendants |
| 302 // fetch if a descendant load failed. | 304 // fetch if a descendant load failed. |
| 303 | 305 |
| 304 CHECK(module_script_); | 306 CHECK(module_script_); |
| 305 RESOURCE_LOADING_DVLOG(1) | 307 RESOURCE_LOADING_DVLOG(1) |
| 306 << "ModuleTreeLinker[" << this << "]::NotifyOneDescendantFinished with " | 308 << "ModuleTreeLinker[" << this << "]::NotifyOneDescendantFinished with " |
| 307 << (was_success == DescendantLoad::kSuccess ? "success. " : "failure. ") | 309 << (was_success == DescendantLoad::kSuccess ? "success. " : "failure. ") |
| 308 << num_incomplete_descendants_ << " remaining descendants."; | 310 << num_incomplete_descendants_ << " remaining descendants."; |
| 309 | 311 |
| 310 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-the-descendant s-of-a-module-script | 312 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-the-descendant s-of-a-module-script |
| 311 // Step 5. "... If any of them asynchronously complete with null, then | 313 // Step 5. "... If any of them asynchronously complete with null, then |
| 312 // asynchronously complete this algorithm with null" | 314 // asynchronously complete this algorithm with null ..." |
| 313 if (was_success == DescendantLoad::kFailed) { | 315 if (was_success == DescendantLoad::kFailed) { |
| 314 DCHECK(!descendants_module_script_); | 316 DCHECK(!descendants_module_script_); |
| 315 // Note: while we complete "fetch the descendants of a module script" | 317 // Note: while we complete "fetch the descendants of a module script" |
| 316 // algorithm here, we still need to continue to the rest of the steps | 318 // algorithm here, we still need to continue to the rest of the steps |
| 317 // in "internal module script graph fetching procedure" | 319 // in "internal module script graph fetching procedure" |
| 318 Instantiate(); | 320 Instantiate(); |
| 319 return; | 321 return; |
| 320 } | 322 } |
| 321 | 323 |
| 322 // Step 5. "Wait for all of the internal module script graph fetching | 324 // Step 5. "Wait for all of the internal module script graph fetching |
| 323 // procedure invocations to asynchronously complete..." | 325 // procedure invocations to asynchronously complete. ... Otherwise, |
| 326 // asynchronously complete this algorithm with module script." | |
| 324 if (!num_incomplete_descendants_) { | 327 if (!num_incomplete_descendants_) { |
| 325 descendants_module_script_ = module_script_; | 328 descendants_module_script_ = module_script_; |
| 326 Instantiate(); | 329 Instantiate(); |
| 327 return; | |
| 328 } | 330 } |
| 329 } | 331 } |
| 330 | 332 |
| 331 void ModuleTreeLinker::Instantiate() { | 333 void ModuleTreeLinker::Instantiate() { |
| 332 CHECK(module_script_); | 334 CHECK(module_script_); |
| 333 AdvanceState(State::kInstantiating); | 335 AdvanceState(State::kInstantiating); |
| 334 | 336 |
| 335 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-scri pt-graph-fetching-procedure | 337 // https://html.spec.whatwg.org/multipage/webappapis.html#internal-module-scri pt-graph-fetching-procedure |
| 336 | 338 |
| 337 // Step 5. Let record be result's module record. | 339 // Step 5. Let record be result's module record. |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 364 AdvanceState(State::kFinished); | 366 AdvanceState(State::kFinished); |
| 365 } | 367 } |
| 366 | 368 |
| 367 HeapHashSet<Member<ModuleScript>> | 369 HeapHashSet<Member<ModuleScript>> |
| 368 ModuleTreeLinker::UninstantiatedInclusiveDescendants() { | 370 ModuleTreeLinker::UninstantiatedInclusiveDescendants() { |
| 369 // https://html.spec.whatwg.org/multipage/webappapis.html#uninstantiated-inclu sive-descendant-module-scripts | 371 // https://html.spec.whatwg.org/multipage/webappapis.html#uninstantiated-inclu sive-descendant-module-scripts |
| 370 // Step 1. Let moduleMap be script's settings object's module map. | 372 // Step 1. Let moduleMap be script's settings object's module map. |
| 371 // Note: Modulator is our "settings object". | 373 // Note: Modulator is our "settings object". |
| 372 // Note: We won't reference the ModuleMap directly here to aid testing. | 374 // Note: We won't reference the ModuleMap directly here to aid testing. |
| 373 | 375 |
| 374 // Step 2. Let stack be the stack « script ». | 376 // Step 2. Let stack be the stack << script >>. |
| 375 // TODO(kouhei): Make stack a HeapLinkedHashSet for O(1) lookups. | 377 // TODO(kouhei): Make stack a HeapLinkedHashSet for O(1) lookups. |
| 376 HeapDeque<Member<ModuleScript>> stack; | 378 HeapDeque<Member<ModuleScript>> stack; |
| 377 stack.push_front(module_script_); | 379 stack.push_front(module_script_); |
| 378 | 380 |
| 379 // Step 3. Let inclusive descendants be an empty set. | 381 // Step 3. Let inclusive descendants be an empty set. |
| 380 // Note: We use unordered set here as the order is not observable from web | 382 // Note: We use unordered set here as the order is not observable from web |
| 381 // platform. | 383 // platform. |
| 382 // This is allowed per spec: https://infra.spec.whatwg.org/#sets | 384 // This is allowed per spec: https://infra.spec.whatwg.org/#sets |
| 383 HeapHashSet<Member<ModuleScript>> inclusive_descendants; | 385 HeapHashSet<Member<ModuleScript>> inclusive_descendants; |
| 384 | 386 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 for (const auto& child_url : child_urls) { | 426 for (const auto& child_url : child_urls) { |
| 425 ModuleScript* module_script = | 427 ModuleScript* module_script = |
| 426 modulator_->GetFetchedModuleScript(child_url); | 428 modulator_->GetFetchedModuleScript(child_url); |
| 427 | 429 |
| 428 child_modules.push_back(module_script); | 430 child_modules.push_back(module_script); |
| 429 } | 431 } |
| 430 // Step 4.3.5. For each s of child modules: | 432 // Step 4.3.5. For each s of child modules: |
| 431 for (const auto& s : child_modules) { | 433 for (const auto& s : child_modules) { |
| 432 // Step 4.3.5.2. If s is null, continue. | 434 // Step 4.3.5.2. If s is null, continue. |
| 433 // Note: We do null check first, as Blink HashSet can't contain nullptr. | 435 // Note: We do null check first, as Blink HashSet can't contain nullptr. |
| 436 | |
| 434 // Step 4.3.5.3. Assert: s is a module script (i.e., it is not "fetching", | 437 // Step 4.3.5.3. Assert: s is a module script (i.e., it is not "fetching", |
| 435 // since by this point all child modules must have been fetched). Note: | 438 // since by this point all child modules must have been fetched). Note: |
| 436 // GetFetchedModuleScript returns nullptr if "fetching" | 439 // GetFetchedModuleScript returns nullptr if "fetching" |
| 437 if (!s) | 440 if (!s) |
| 438 continue; | 441 continue; |
| 439 | 442 |
| 440 // Step 4.3.5.1. If inclusive descendants already contains s, continue. | 443 // Step 4.3.5.1. If inclusive descendants already contains s, continue. |
| 441 if (inclusive_descendants.Contains(s)) | 444 if (inclusive_descendants.Contains(s)) |
| 442 continue; | 445 continue; |
| 443 | 446 |
| 444 // Step 4.3.5.4. Push s onto satck. | 447 // Step 4.3.5.4. Push s onto stack. |
| 445 stack.push_front(s); | 448 stack.push_front(s); |
| 446 } | 449 } |
| 447 } | 450 } |
| 448 | 451 |
| 449 // Step 5. Return a set containing all items of inclusive descendants whose | 452 // Step 5. Return a set containing all items of inclusive descendants whose |
| 450 // instantiation state is "uninstantiated". | 453 // instantiation state is "uninstantiated". |
| 451 HeapHashSet<Member<ModuleScript>> uninstantiated_set; | 454 HeapHashSet<Member<ModuleScript>> uninstantiated_set; |
| 452 for (const auto& script : inclusive_descendants) { | 455 for (const auto& script : inclusive_descendants) { |
| 453 if (script->InstantiationState() == | 456 if (script->InstantiationState() == |
| 454 ModuleInstantiationState::kUninstantiated) | 457 ModuleInstantiationState::kUninstantiated) |
| 455 uninstantiated_set.insert(script); | 458 uninstantiated_set.insert(script); |
| 456 } | 459 } |
| 457 return uninstantiated_set; | 460 return uninstantiated_set; |
| 458 } | 461 } |
| 459 | 462 |
| 460 } // namespace blink | 463 } // namespace blink |
| OLD | NEW |