I am building a Webassembly runtime and am currently implementing the WASI APIs. I'm wondering how the ABI looks like, according to this document: https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md
To test, I have compiled this C application with emscripten to a standalone WASM module.
#include <stdio.h>
int main() {
    printf("Hello, World!\n");
    return 0;
}
After checking with wasm-objdump, I can see the following function imports:
Import[2]:
 - func[0] sig=2 <__wasi_proc_exit> <- wasi_snapshot_preview1.proc_exit
 - func[1] sig=11 <__wasi_fd_write> <- wasi_snapshot_preview1.fd_write
with the type signatures:
 - type[2] (i32) -> nil
 - type[11] (i32, i32, i32, i32) -> i32
According to the spec, the fd_write function has the signature  fd_write(fd: fd, iovs: ciovec_array) -> Result<size, errno>, which maps to the POSIX system call ssize_t writev(int fd, const struct iovec *iov, int iovcnt);.
But what is the fourth argument in the WASM file? It receives some pointer to a memory address. So I thought I would have to write Result<size, errno> to that address, but if I do that and return 0 (for success), the fd_write gets called just over and over again (presumably because the printf function assumes that nothing was written). If I return the written bytes, the program terminates correctly, but what is then the fourth argument?
Also, how can I return more complex Results, which do not fit into an i32?
 
                        
In wasi-libc, the function signature of
__wasi_fd_readis:According to some implementations of
fd_write, the last argument is a pointer to return the number of bytes written, and the return value is always 0 (like what you did).So I guess you should also set the number of bytes that have been read to where
retptr0points to.