-
Notifications
You must be signed in to change notification settings - Fork 693
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
JS API; asynchronous imports #720
Comments
In the MVP, I agree there isn't any direct support; wasm can really only take and receive numbers. However, one could generate or hand-write a JS glue layer that supports interfacing async JS. E.g., the glue layer could create a JS function closure that contained an exported wasm function and wasm closure state (probably an integer; i.e., the classic C-API-style Post-MVP, with GC and WebIDL integration, I think we will be able to support more direct integration with async JS (and also a new breed of async Web APIs). In particular, I think we should provide the building blocks for wasm to directly construct callback functions (ultimately just code-pointer + data-pointer) which would then allow wasm to directly call, e.g., a Promise's |
This won't work if you also use |
Oh, are you talking specifically about the in-progress (or maybe it has advanced?) |
@lukewagner looking to have a wasm module perform some async network I/O mediated by JS - any way of doing this with the current api? |
@lukewagner we are thinking about this again now in our prototype. One of the import method we define needs to do a async look up (if in node.js from the disk or from the network if in the browser).
Yes, this is possible but we can't rely on the wasm code to export its closure state. So I don't think it will work for us. We don't have any control the wasm code being run. (apart from adding metering via a transform). |
@kumavis I might be misunderstanding what you mean, but I think there should be no problem; the implementation of emscripten_async_wget does this. Is there a specific issue you're having you could describe? |
@lukewagner I don't think that will work, we don't control the code is running in the wasm instance. We want to be able to give the wasn instance an import that has to do some async work `(import $async_stuff_may_happen 'ethereum' 'getStorage')' which third parties will use. |
@wanderer What do you mean by "has to do some async work"? In your example import, is |
@lukewagner would there be a way to refer to WebAssembly exports with an index? That could simplify this. |
getStorage need to pull load from value from either the network or disk. Both of which are not nice to make synchronous in JS.
I'm not sure I understand this. Here is an example of what I was thinking. In this example the imported function returns a value via a callback instead of a return. This pattern can be implemented in pure JS if example
This is an option, but it would only apply to clients running in the browser. Non-browser clients will have full control of the VM so they don't have to worry about this. This mean we have to transform the code on the fly in the browser by looking for But it seem to me that async lookups would be common usecase and it might make sense to have that optionality in the JS api. |
@axic Yes, you could either put all the exports into a JS array or you could put them into an exported
Ok, so you're talking about designing a single host-environment that can run modules in either a browser or non-browser wasm VMs. (Sounds cool!) I still think passing the pair of (func-ptr, closure) indices would be suitable since they could have the same meaning in a non-browser VM: func-ptr would index into either the exported functions or an exported table; closure into exported linear memory. |
Thanks @lukewagner found Runtime.dynCall('vi', callback, [allocate(intArrayFromString(_file), 'i8', ALLOC_STACK)]);
return Module['dynCall_' + sig].apply(null, args); result is calling Module.dynCall_vi(callback, allocate(intArrayFromString(_file), 'i8', ALLOC_STACK))
@lukewagner That clarified things for me a bit but I think the next step would be to find some wasm example code that uses |
@kumavis FWIW, much of that |
Is someone interested in championing a concrete proposal here? |
@jfbastien so far we have managed work around this limitatio by adding callback to all the c interface. Another option to run the wasm instance in a webworker use a SAB and Atomic.wait to "pause", then do the async work in a the main thread. But it might be less "hacky" if the imported function returned a promise wasm instance would resume after the promised resolved. Are there any immediate problems with this? |
I'd need to see more concrete code to understand clearly. |
@jfbastien here's a minimal example to demonstrate the issue https://gist.github.com/cdetrio/7f5486004b0054b5c08e0496cf3ab21f |
Currently it doesn't look like there is a way for imports written in JS to return asynchronously. If this is true, would there be interest in adding a way?
I think the easiest way would be to return a promise
The text was updated successfully, but these errors were encountered: