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/Vector.h" |
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 CHECK_EQ(num_incomplete_descendants_, 0u); | 88 CHECK_EQ(num_incomplete_descendants_, 0u); |
89 CHECK(new_state == State::kFetchingDependencies || | 89 CHECK(new_state == State::kFetchingDependencies || |
90 (!descendants_module_script_ && new_state == State::kFinished)); | 90 (!descendants_module_script_ && new_state == State::kFinished)); |
91 break; | 91 break; |
92 case State::kFetchingDependencies: | 92 case State::kFetchingDependencies: |
93 CHECK_EQ(new_state, State::kInstantiating); | 93 CHECK_EQ(new_state, State::kInstantiating); |
94 DCHECK(!num_incomplete_descendants_ || !descendants_module_script_) | 94 DCHECK(!num_incomplete_descendants_ || !descendants_module_script_) |
95 << num_incomplete_descendants_ | 95 << num_incomplete_descendants_ |
96 << " outstanding descendant loads found, but the descendant module " | 96 << " outstanding descendant loads found, but the descendant module " |
97 "script load procedure unexpectedly finished with " | 97 "script load procedure unexpectedly finished with " |
98 << (!!descendants_module_script_ ? "success." : "failure."); | 98 << (descendants_module_script_ ? "success." : "failure."); |
99 break; | 99 break; |
100 case State::kInstantiating: | 100 case State::kInstantiating: |
101 CHECK(num_incomplete_descendants_ == 0u || !descendants_module_script_); | 101 CHECK(num_incomplete_descendants_ == 0u || !descendants_module_script_); |
102 CHECK_EQ(new_state, State::kFinished); | 102 CHECK_EQ(new_state, State::kFinished); |
103 break; | 103 break; |
104 case State::kFinished: | 104 case State::kFinished: |
105 NOTREACHED(); | 105 NOTREACHED(); |
106 break; | 106 break; |
107 } | 107 } |
108 | 108 |
(...skipping 15 matching lines...) Expand all 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. |
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 |