-
Notifications
You must be signed in to change notification settings - Fork 694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multi-module 1-step Instantiate with dependencies #997
Comments
Just repeating my usual observation that allowing cycles is much more than a mere API addition. It would introduce full-fletched recursive modules into Wasm, which is a tricky design space with numerous potential implications on present and future versions of the language. (FWIW, recursive modules for typed languages are still an active and rather involved research topic.) We should be very careful not to do something hasty there. So for a Milestone 2 feature it would be much safer to separate the problem of bulk instantiation from recursive linking and only allow DAGs. One other nit: |
Agreed on starting with DAGs, just as a practical first step. On the So the original reason I thought it was simple to keep them in the same namespace: let's say I'm instantiating some module in the DAG of some call |
@flagxor - this would be a helper API, correct? I worry we would enter composition engine territory with this API. Questions of policy arise. Besides cycles, as @rossberg-chromium illustrates, there's also: how do you match imports and exports; what if there are 2 imports you want satisfied with the same export. I would prefer we let third parties come up with such policies, and us just provide the basic building blocks, API-wise. |
@mtrofin this is an offshoot of #991. The main goal is to allow multiple ongoing streams to make forward progress, reducing the time to play on a wasm site that uses dynamic linking. You bring up important design points, but I don't think third parties can do what you propose. The JS API have to do this. Unless I'm wrong :) So, let's consider what you say, but I think we have to do so in the JS API. |
Let's also take a step back. What's the motivating user story for this API? The proposal frames this in the context of dynamic linking. The motivations for that feature are, afaik:
In all of these cases, bindings happen at different times - first we instantiate one module; later, and, importantly, because of some user event, we want to instantiate another one and relate imports/exports. The instantiateGroup API doesn't accommodate for that "some user event". Which places the API square in the field of composition (a'la dependency injection frameworks and composition engines). Why do we want (what motivates) that? @jfbastien - I am not sure how #991 blocks a third party composition engine from working when using the response-based APIs. Specifically:
|
@mtrofin You're thinking about runtime dynamic linking. What we're talking about here is load-time dynamic linking. The use cases for that are:
|
@lukewagner - I agree, this is about load-time linking. I think I went about my point in too convoluted of a way. Let me try this:
|
@mtrofin The problem with that snippet is it uses |
Also, since we've punted out all the fetching/memoization logic, I don't think remaining logic for matching imports/exports is too complex here. |
How about this: let's first prototype an implementation for instantiateGroup. |
Sounds reasonable :) |
@mtrofin what @lukewagner said, as well as: you have to write an example with |
An alternative for this might be to extend instantiate + compile to allow Promises throughout the options parameter. This would allow you to state things up front like having the memory, but defer things like having the imports from something not yet compiled. |
That's a pretty cool idea. Is there any precedent for module systems doing this in the past that anyone has heard of? |
Yeah I think @rossberg-chromium proposed this? I like it 😁 |
@lukewagner, the dynamic module system I developed in my thesis (a long time ago...) defined its semantics for lazy linking in a similar manner, based on proper futures. :) |
Who's willing to champion this? |
@rossberg-chromium Cool. And so iiuc, this would be able to support DAGs but not (cyclic) graphs, yes? |
There is a similar precedent in production, too - .NET's MEF allows import satisfaction with Lazy objects. Similar to this proposal here, in that the object providing the service required by the importer is resolved after binding time. A more closer correspondent in JS would be a function returning the import - but probably Promise is more composable and easier to document. |
@lukewagner, yes, it's just a way to be able to "provide" the dependencies before you "have" them, so that e.g. compilation can proceed and parallelism can be maximised. The actual instantiation step for each module would still have to wait for its import promises, so you cannot construct cycles with this alone. @mtrofin, actually, lazy objects and futures/promises are very closely related (so close that in the system I mentioned they where one and the same thing). So mapping dot-net's mechanism to promises is most natural. |
We should support a version of instantiate that will continue to allow us to recommend it as the preferred instantiation method one dynamic linking / multiple modules become more popular.
WebAssembly.instantiateGroup({a:Promise<Response>, b:Promise<Response>, otherImports:importObject})
With this, the module at urlA could import the foo export of the module at urlB by importing from "b" "foo".
Questions:
The text was updated successfully, but these errors were encountered: