镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Return value from wasm module via WASI #32093

Description

@jendrikw

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.

Activity

  1. added
    wasiIssues and PRs related to the WebAssembly System Interface.
    on Mar 4, 2020
  2. devsnek commented on Mar 4, 2020

    @devsnek
    Member

    those functions don't have a return value.

  3. jendrikw commented on Mar 4, 2020

    @jendrikw
    Author

    Oh, I somehow thought they did. Could there be an alternative way?

  4. devsnek commented on Mar 4, 2020

    @devsnek
    Member

    what are you trying to achieve?

  5. jendrikw commented on Mar 4, 2020

    @jendrikw
    Author

    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?

  6. devsnek commented on Mar 4, 2020

    @devsnek
    Member

    @jendrikw if main returns non-zero it will exit the whole node program. kind of a weird design atm.

    also fwiw, you don't need to set the visibility of main (it shouldn't be exported anyway)

    @cjihrig perhaps we should have better behaviour for when __wasi_proc_exit is called?

  7. devsnek commented on Mar 4, 2020

    @devsnek
    Member

    also this is basically what _start does:

    void _start(void) {
      int r = main();
      if (r != 0) { __wasi_proc_exit(r); }
    }
    
  8. guybedford commented on Mar 4, 2020

    @guybedford
    Contributor

    Yeah this definitely seems odd - can start just not return the code directly?

  9. devsnek commented on Mar 4, 2020

    @devsnek
    Member

    _start is doing the correct thing. The odd thing is that we don't scope __wasi_proc_exit to the WASI instance.

  10. cjihrig commented on Mar 4, 2020

    @cjihrig
    Contributor

    __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).

  11. guybedford commented on Mar 4, 2020

    @guybedford
    Contributor

    Right, but there is no reason wasi.start() can't return the exit code that __wasi_proc_exit() stores as a side effect.

  12. cjihrig commented on Mar 4, 2020

    @cjihrig
    Contributor

    I agree, and that would be preferable. But that's not currently in our control.

  13. guybedford commented on Mar 4, 2020

    @guybedford
    Contributor

    Can you clarify why that is the case? wasi.start() is very much a Node.js-specific API?

  14. devsnek commented on Mar 4, 2020

    @devsnek
    Member

    @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.

  15. cjihrig commented on Mar 4, 2020

    @cjihrig
    Contributor

    @guybedford wasi.start() just calls into wasm here. Once inside of wasm, there is an eventual call to __wasi_proc_exit() (implemented as uvwasi_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.

  16. guybedford commented on Mar 4, 2020

    @guybedford
    Contributor

    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_exit can manipulate this state and wasi.start() can return this state. That way there can also be assertions that it can only run once etc etc.

  17. cjihrig commented on Mar 4, 2020

    @cjihrig
    Contributor

    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.

  18. devsnek commented on Mar 4, 2020

    @devsnek
    Member

    It'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.

  19. cjihrig commented on Mar 4, 2020

    @cjihrig
    Contributor

    @devsnek I'll look into this tonight.

  20. added a commit that references this issue on Mar 8, 2020
  21. added a commit that references this issue on Mar 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    wasiIssues and PRs related to the WebAssembly System Interface.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions