{"action":"created","issue":{"url":"https://api.github.com/repos/whatwg/loader/issues/68","labels_url":"https://api.github.com/repos/whatwg/loader/issues/68/labels{/name}","comments_url":"https://api.github.com/repos/whatwg/loader/issues/68/comments","events_url":"https://api.github.com/repos/whatwg/loader/issues/68/events","html_url":"https://github.com/whatwg/loader/issues/68","id":101151688,"number":68,"title":"Introducing the new state, \"ResolveDependencies\"","user":{"login":"Constellation","id":9023,"avatar_url":"https://avatars.githubusercontent.com/u/9023?v=3","gravatar_id":"","url":"https://api.github.com/users/Constellation","html_url":"https://github.com/Constellation","followers_url":"https://api.github.com/users/Constellation/followers","following_url":"https://api.github.com/users/Constellation/following{/other_user}","gists_url":"https://api.github.com/users/Constellation/gists{/gist_id}","starred_url":"https://api.github.com/users/Constellation/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Constellation/subscriptions","organizations_url":"https://api.github.com/users/Constellation/orgs","repos_url":"https://api.github.com/users/Constellation/repos","events_url":"https://api.github.com/users/Constellation/events{/privacy}","received_events_url":"https://api.github.com/users/Constellation/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/whatwg/loader/labels/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/whatwg/loader/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":{"login":"caridy","id":38969,"avatar_url":"https://avatars.githubusercontent.com/u/38969?v=3","gravatar_id":"","url":"https://api.github.com/users/caridy","html_url":"https://github.com/caridy","followers_url":"https://api.github.com/users/caridy/followers","following_url":"https://api.github.com/users/caridy/following{/other_user}","gists_url":"https://api.github.com/users/caridy/gists{/gist_id}","starred_url":"https://api.github.com/users/caridy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caridy/subscriptions","organizations_url":"https://api.github.com/users/caridy/orgs","repos_url":"https://api.github.com/users/caridy/repos","events_url":"https://api.github.com/users/caridy/events{/privacy}","received_events_url":"https://api.github.com/users/caridy/received_events","type":"User","site_admin":false},"milestone":null,"comments":8,"created_at":"2015-08-15T08:24:57Z","updated_at":"2015-09-26T08:25:49Z","closed_at":null,"body":"I think that the current draft spec incurs infinite recursion when there is the circular dependencies.\r\nThe situation is the following,\r\n\r\nThere are several modules,\r\n\r\n__A__: This is the entry point.\r\n```js\r\nimport \"B\"\r\n```\r\n\r\n__B__\r\n```js\r\nimport \"C\"\r\n```\r\n\r\n__C__\r\n```js\r\nimport \"B\"\r\n```\r\n\r\n1. At that time, before linking the modules, we call `RequestInstantiateAll(A)`.\r\n2. In `RequestInstantiateAll(A)`, step 1-b-i-1, we extract the B dependency.\r\n3. So, step 1-b-i-3, we perform `RequestInstantiateAll(B)`.\r\n4. Later, it will extract the C dependency. So, step 1-b-i-3 in `RequestInstantiateAll(B)`, we call `RequestInstantiateAll(C)`.\r\n5. Since C has the B dependency, in `RequestInstantiateAll(C)` step 1-b-i-3, we again call `RequestInstantiateAll(B)`.\r\n6. Here, now, since once `RequestInstantiate(B)` is called inside `RequestInstantiateAll(B)`, it immediately returns the promise `B.[[Instantiate]]`. But, Now, __we stored the status of instantiation in [[Instantiate]], but we didn't store the status of collecting the dependencies__.\r\n7. So, in `RequestInstantiateAll(B)`, `RequestInstantiate(B)` returns the stored promise, but __it performs the dependency resolution again in 1-a or later__. So it will call `RequestInstantiateAll(C)` at step 1-b-i-3 again.\r\n8. `RequestInstantiateAll(B)` and `RequestInstantiateAll(C)` are called repeatedly.\r\n\r\nThis problem comes from that the current algorithm does not store the status of \"resolving the dependencies\".\r\n\r\nTo solve this, I would like to propose introducing the new state `ResolveDependencies`. That means, \"Now, the instantiation is done, so the  entry is ready to resolve the dependencies. And if there's entry.[[ResolveDependencies]] promise and the state is `ResolveDependencies`, we're resolving the dependency of the module just now\".\r\n\r\nThe algorithm becomes the following,\r\n\r\n### CommitInstantiated(loader, key)\r\n1. Let _instance_ be Instantiation(_loader_, _optionalInstance_, _source_).\r\n1. ReturnIfAbrupt(_instance_).\r\n1. // TODO: edge case: what if _instance_ is a thenable function?\r\n1. Fulfill _entry_.[[Instantiate]] with _instance_.\r\n1. Let _deps_ be a new empty List.\r\n1. If _instance_ is a Module Record, then:\r\n  1. Assert: _instance_ is a Source Text Module Record.\r\n  1. Set _instance_.[[RegistryEntry]] to _entry_.\r\n  1. For each _dep_ in _instance_.[[RequestedModules]], do:\r\n    1. Append the record { [[key]]: _dep_, [[value]]: *undefined* } to _deps_.\r\n1. Set _entry_.[[Dependencies]] to _deps_.\r\n1. Set _entry_.[[Module]] to _instance_.\r\n1. SetStateToMax(_entry_, __\"resolveDependencies\"__).\r\n\r\n### RequestResolveDependencies(loader, key)\r\n\r\n1. Let _entry_ be EnsureRegistered(_loader_, _key_).\r\n2. Let _linkStateValue_ be GetStateValue(\"link\").\r\n3. If _stateValue_ is greater than _linkStateValue_, return a new error promise.\r\n3. If _entry_.[[ResolveDependencies]] is not *undefined*, return _entry_.[[ResolveDependencies]].\r\n4. Return the result of transforming RequestInstantiate(_loader_, _key_) with a fulfillment handler that, when called with argument _entry_, runs the following steps:\r\n    1. Let _depLoads_ be a new empty List.\r\n    2. For each _pair_ in _entry_.[[Dependencies]], do:\r\n        1. Let _p_ be the result of transforming Resolve(_loader_, _pair_.[[key]], _key_) with a fulfillment handler that, when called with value _depKey_, runs the following steps:\r\n            1. Let _depEntry_ be EnsureRegistered(_loader_, _depKey_).\r\n            1. If _depEntry_.[[ResolveDependencies]] is not *undefined*\r\n                1. Return the result of transforming _depEntry_.[[Instantiate]] with a fulfillment handler that, when called with value _depEntry_, runs the following steps:\r\n                    1. Let _dep_ be _depEntry_.[[Module]].\r\n                    1. Set _pair_.[[value]] to _dep_.\r\n                    1. Return _depEntry_.\r\n            1.  Return the result of transforming RequestCollect(_loader_, _depKey_) with a fulfillment handler that, when called with value _depEntry_, runs the following steps:\r\n                1. Let _dep_ be _depEntry_.[[Module]].\r\n                1. Set _pair_.[[value]] to _dep_.\r\n                1. Return _depEntry_.\r\n        1. Append _p_ to _depLoads_.\r\n    1. Let _p_ be the result of waiting for all _depLoads_.\r\n    1. Return the result of transforming _p_ with a fulfillment handler that, when called, runs the following steps:\r\n        1. SetStateToMax(_entry_, \"link\").\r\n        1. Return _entry_."},"comment":{"url":"https://api.github.com/repos/whatwg/loader/issues/comments/143409694","html_url":"https://github.com/whatwg/loader/issues/68#issuecomment-143409694","issue_url":"https://api.github.com/repos/whatwg/loader/issues/68","id":143409694,"user":{"login":"Constellation","id":9023,"avatar_url":"https://avatars.githubusercontent.com/u/9023?v=3","gravatar_id":"","url":"https://api.github.com/users/Constellation","html_url":"https://github.com/Constellation","followers_url":"https://api.github.com/users/Constellation/followers","following_url":"https://api.github.com/users/Constellation/following{/other_user}","gists_url":"https://api.github.com/users/Constellation/gists{/gist_id}","starred_url":"https://api.github.com/users/Constellation/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Constellation/subscriptions","organizations_url":"https://api.github.com/users/Constellation/orgs","repos_url":"https://api.github.com/users/Constellation/repos","events_url":"https://api.github.com/users/Constellation/events{/privacy}","received_events_url":"https://api.github.com/users/Constellation/received_events","type":"User","site_admin":false},"created_at":"2015-09-26T08:25:49Z","updated_at":"2015-09-26T08:25:49Z","body":"How about this? @caridy @domenic "}}