mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 17:59:34 +00:00

In the following module graph: 0.html +---- 1.mjs +---- 2.mjs (modulepreload) +---- 3.mjs (modulepreload) +---- 4.mjs +---- non_existing.mjs Fetching non_existing.mjs will fail, which will notify its parent module 1.mjs with ModuleErrored(), and then 1.mjs will cancel its imports. The sequence is as follows: 1. 1.mjs cancels 2.mjs, 2.mjs changes to Cancel state 2. 2.mjs cancels 3.mjs, 3.mjs is already preloaded, its state still remains Finished. 3. 2.mjs cancels 4.mjs, 4.mjs changes to Cancel state. Now, 2.mjs will call ChildLoadComplete[1], which will call 1.mjs ModuleErrored()[2] again (The 1st time is called when loading non_existing.mjs failed) Now 1.mjs wants to cancel 2.mjs again, and 2.mjs has been canceled previously, so it will do AssertAllImportsCanceled() check[3]. However, 3.mjs has been fetched by <modulepreload> and is in Finished state, which triggers the assertion failure. To fix this, I add a new state in ScriptLoadRequest::State called CancelingImport, to fix the problem the CancelImport() call is called by non_existing.mjs and 2.mjs. [1]: https://searchfox.org/mozilla-central/rev/f1532761de0b60337e42c6c3f525288a523dabef/js/loader/ModuleLoadRequest.cpp#100 [2]: https://searchfox.org/mozilla-central/rev/f1532761de0b60337e42c6c3f525288a523dabef/js/loader/ModuleLoaderBase.cpp#954 [3]: https://searchfox.org/mozilla-central/rev/f1532761de0b60337e42c6c3f525288a523dabef/js/loader/ModuleLoadRequest.cpp#86 Differential Revision: https://phabricator.services.mozilla.com/D209218