Repository navigation
Return value from wasm module via WASI #32093
Description
Activity
- addedwasiIssues and PRs related to the WebAssembly System Interface.Issues and PRs related to the WebAssembly System Interface.
on Mar 4, 2020 those functions don't have a return value.
Oh, I somehow thought they did. Could there be an alternative way?
what are you trying to achieve?
I'm trying to use this simple C program that detects if a number is even:
#include <stdlib.h> #define WASM_EXPORT __attribute__((visibility("default"))) WASM_EXPORT int main(int argc, char *argv[]) { char *rest; long i = strtol(argv[1], &rest, 10); return i % 2; }
I compiled it with wasi-sdk. It works fine when running with wasmtime and I get the intended return value. I expected it to be usable with node. Or have I misunderstood something?
also this is basically what _start does:
void _start(void) { int r = main(); if (r != 0) { __wasi_proc_exit(r); } }Yeah this definitely seems odd - can start just not return the code directly?
_start is doing the correct thing. The odd thing is that we don't scope __wasi_proc_exit to the WASI instance.
__wasi_proc_exit()terminates the process unconditionally because if it doesn't, the result will be a failed assertion in the wasm runtime (__wasi_proc_exit()is not allowed to return).Right, but there is no reason
wasi.start()can't return the exit code that__wasi_proc_exit()stores as a side effect.I agree, and that would be preferable. But that's not currently in our control.
Can you clarify why that is the case?
wasi.start()is very much a Node.js-specific API?@cjihrig indeed... i'm just saying it should not exit the node process. for the moment we can throw an exception, since wasm can't catch them yet.
@guybedford __wasi_proc_exit can happen at any point, we should probably represent it as some sort of event, not a return value.
@guybedford
wasi.start()just calls into wasm here. Once inside of wasm, there is an eventual call to__wasi_proc_exit()(implemented asuvwasi_proc_exit()in node). That exits the process in C code. If__wasi_proc_exit()returns, there will be a failed assertion, that is also out of our control.I think the proper fix would need to happen in the wasi-libc. We could also try @devsnek's suggestion of throwing an exception (by overwriting the
__wasi_proc_exit()with JavaScript) in the short term.There is no need for a return value from
__wasi_proc_exit()- from a VM perspective, one can consider there should be a "process state" which represents the state of the process (in progress, completed, code, etc).__wasi_proc_exitcan manipulate this state andwasi.start()can return this state. That way there can also be assertions that it can only run once etc etc.Thinking of these WASI apps as nanoprocesses (I think that's what the WASI folks are calling them), I think having an exit code would be useful for the same reasons real processes have exit codes. I think that could be discussed separately from this issue though. IMO, the real problem here is that
__wasi_proc_exit()terminates the process unconditionally, which means that you can't use Node to orchestrate multiple WASI applications without using a child process.Reacted by Guy BedfordIt's worth noting, __wasi_proc_exit is in an odd place atm, and how it works will likely change in the future (or it will be removed). For the moment, just making it not exit the entire process is enough.
@devsnek I'll look into this tonight.
Reacted by snek- added a commit that references this issue
on Mar 9, 2020 - added 2 commits that reference this issue
on Apr 25, 2020

Is your feature request related to a problem? Please describe.
I have a WebAssembly file compiled from a simple C++ program. I would like to get the return value from main. I am calling the function via
wasm.start()Describe the solution you'd like
start()should return the value from_start()and/or__wasi_unstable_reactor_start.Describe alternatives you've considered
The WASI object could also store the return value and make it available via a getter function, but I think the solution via the return value cleaner.