-
Notifications
You must be signed in to change notification settings - Fork 33
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
Multiple imports of the same wasm file: same instance or different instances? #60
Comments
You might be interested in #44 |
I believe this will actually depend on the host environment, due to how the ES spec specifies how modules are resolved. In particular, see HostResolveImportedModule. But for running on the web, the HTML spec should give the same module record. Here's an excerpt from HostResolveImportedModule's spec text:
The last paragraph says the mapping is host-defined. In the case of loading in HTML and the Web, it's defined here in the HTML spec. As far as I know, this algorithm and HTML's module map will ensure that for modules with the same base URL and specifier (should be the case for (Module records should also only get evaluated once, and module record evaluation is when the Wasm module gets instantiated) |
Ok, maybe this could be added somewhere to the description / examples in some form, since it's a quirk that may be non-obvious. Then I have a concern that basically this gives observability / non-determinism if the graph imports is something different than a tree. Think of a utility wasm file, that is included twice by two different components, they will then share the state. Think of some interface like "setMyData" "getMyData", it will not be OK in general to share the same instance. This is similar to the JavaScript case, but there at least there are ways to write files that are impossible to misuse (eg. exporting a factory to an actual instance) while Wasm modules have no clear way of add the constrain: this should not be a shared instance. |
Yeah, I see what you're saying in terms of sharing state, but that's also generally how JS modules behave in a JS module graph as far as I know. I think there is no obvious way to change this behavior while having Wasm modules be the usual module records in the ECMA spec. I think it's a good idea to note that it works similarly to JS somewhere though. Other people have been asking for a way to have ESM integration provide a Wasm module instead of an instance (see #14). In that situation, you could do I don't think that will be included in this initial proposal though, as it depends on the import reflection proposal. |
Yes and no, as in this is similar to JS, but JS have clear way to expose interface where state in non-global, while in WebAssembly it's far-from-obvious. Even the example counter.wasm expose functionality to get or increment the counter, and I find it puzzling that adding unrelated code (that somehow also uses counter.wasm) lead to 'breaking' existing code assumptions. My concern is that ESM integration would mostly work out of the box, only for that do be broken in surprising ways as more code gets added to a given project. |
fwiw I don't think that the esm proposal has to solve every use case wrt loading wasm modules. If you have specialized requirements, you can always manually use |
While thinking about #63, I sort of came to better understand the problem I was seeing here. Another way of looking at this is that a module/instance interface is not entirely "public" as in safe to use for anyone on the outside, since there are a few exports that are meant to be tied to a specific JS behavior, and is not safe (neither from the user, nor from anyone who was relying on the instance). Think to an export like __terminate(), it would not be OK for __terminate, on a currently live Instance, to be reachable via ESM integration by a third party. This is also somehow tied implicitly share state-full instances, basically a way out would be having a new module instantiated every time (since then you can't do harm if you misuse the implied usage), but this somehow shifts the purpose of the proposal. |
As per the title, the basic case is like:
While instantiating c.js, there will be a single wasm module whose export 'someFunc' has been called twice OR two different instance of the same module, each called once?
Then depending on the answer, there might be possible problems (or at least some need of disambiguation / explanation) how to avoid some common problems.
With separate instances, the fact that memory might become an issue, with same instance the fact that different components might (without knowledge) share the same internal state.
I implemented ES6 module's support in Cheerp (C++ to JS/Wasm compiler), and we ended up with modules exporting a default initialization function that when called returns (asynchronously) a new instance of the module.
Here the explanation of the approach: https://docs.leaningtech.com/cheerp/ES6-Modules
The text was updated successfully, but these errors were encountered: