emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.91k stars 3.32k forks source link

A question about how EMCC implements WASI #12341

Open wustwn opened 4 years ago

wustwn commented 4 years ago

Hi,

There is a question about how emcc implements WASI. I think that under normal circumstances, it should invoke the WASI APIs’ implementation and import the corresponding wasi function in the target wasm file like wasi-sdk, but after testing case using system API like file system api fopen, I found that it is different with EMCC. I notice that someone has submitted similar test case here #12094 so I do not attach mine.

In the meanwhile, I also notice that there are tutorials about using files in emscripten.org , so does it mean that emcc's implementation about WASI relys on browser or nodejs Api, which is different from the traditional wasi-sdk by invoking wasi api? Is there any possible way to compile wasm module of standard wasi with emcc?

Looking forward to your reply.

Thanks

sbc100 commented 4 years ago

Emscripten's current approach is to use WASI APIs where it makes sense and where they are efficient in terms of code size and performance.

As of today we only use WASI APIs for a very small number of things. If you try to do anything other than the most basic I/O you will most likely end up with program that requires emscripten-specific APIs and the result will not run on WASI runtimes.

We do hope to increase our use of WASI over time, but if you want to be sure that your program depends only on the WASI APIs your best bet is to use the wasi-sdk.

sbc100 commented 4 years ago

We could add an ONLY_WASI option to emscripten, which would severely limit the number of programs you could compile, but perhaps it would be useful?

kripken commented 4 years ago

We could add an ONLY_WASI option to emscripten, which would severely limit the number of programs you could compile, but perhaps it would be useful?

I think it would be useful together with an implementation to use WASI syscalls as much as possible.

See previous discussion in https://github.com/emscripten-core/emscripten/issues/12073 . @mejedi perhaps you'll have time for a PR as discussed there?

sunfishcode commented 4 years ago

If there are ways wasi-sdk could be more useful, please report them!

mejedi commented 4 years ago

@kripken

See previous discussion in #12073 . @mejedi perhaps you'll have time for a PR as discussed there?

I need more time. WASI is not feature complete to implement even the basic POSIX-y filesystem support (ex: lacks the notion of current working directory). Furthermore, at least some of the WASI runtimes do not normalise mapped directories: you might end up with /foo/../bar/. or . in pre-opened directories. Should libc normalise them internally or not? The workarounds I have make sense in the context of the project I'm involved in but aren't universally useful.

A side note. I'm excited about WASI because in theory it enables shipping a single binary. The alternative being shipping separate packages for countless Linux distributions, OS X, Windows and what else. WASI variant should behave exactly as the native variant does. This is not possible in general since WASI feature set is limited. Quite surprisingly, even the basic filesystem support is crippled. I'm not even talking about permissions.

There are different ways to reference a file: by absolute path, or by a relative path with and without leading ./. Relative paths need current directory, the only way to infer it is via PWD environment variable, which is not robust. Emulating chdir and getcwd is not straightforward either. For instance, getcwd should return up to date path even if the directory was renamed in meantime. Also, getcwd must yield a path with symbolic links expanded. Any emulation will suffer from TOCTOU problem. I will be opening an issue in WASI tracker. https://github.com/WebAssembly/WASI/issues/303

Finally, Windows path syntax is different. WASI doesn't tell us what the host OS is. Python might be able to switch filesystem flavour dynamically. Cross-platform C/C++ projects typically have separate implementation for Posix and Windows, and switching the flavour dynamically is not possible. As a short term solution one can build separate binaries for Posix and Windows.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant.