emscripten-core / emsdk

Emscripten SDK
http://emscripten.org
Other
3k stars 682 forks source link

Uncaught (in promise) TypeError: import object field 'wasi_snapshot_preview1' is not an Object #1321

Closed vault-thirteen closed 10 months ago

vault-thirteen commented 10 months ago

I have built a *.wasm file as a stand-alone WASM without an entry function. The --no-entry argument is passed to the tool. But for some reason, when I try to load this WASM file into a web browser, I have an error: Uncaught (in promise) TypeError: import object field 'wasi_snapshot_preview1' is not an Object

How I compiled the file.

emcmake cmake . -B "_BUILD_" -G "MinGW Makefiles"
emmake cmake --build _BUILD_
cd _BUILD_
emcc libargon2.a -o argon2.wasm --no-entry -s EXPORTED_FUNCTIONS=["_argon2_ctx","_argon2_encodedlen","_argon2_error_message","_argon2_hash","_argon2_type2string","_argon2_verify","_argon2_verify_ctx","_argon2d_ctx","_argon2d_hash_encoded","_argon2d_hash_raw","_argon2d_verify","_argon2d_verify_ctx","_argon2i_ctx","_argon2i_hash_encoded","_argon2i_hash_raw","_argon2i_verify","_argon2i_verify_ctx","_argon2id_ctx","_argon2id_hash_encoded","_argon2id_hash_raw","_argon2id_verify","_argon2id_verify_ctx"]

The source code is here: https://github.com/vault-thirteen/argon2 The JS loader is located here: https://github.com/vault-thirteen/argon2/tree/main/wasm It is super simple, just a loader and nothing else.

It looks like the WASM file was compiled for a WASI runtime environment according to the error. But I compiled it for a web browser. What is wrong ? Thank you.

sbc100 commented 10 months ago

When building in standalone wasm mode emscripten tries to use system calls that a likely to be available on embedded platforms.

If you want to build for the web I would advice using -o argon2.js and then emscripten will generate the JavaScript for in order to satisfy the wasm imports. Otherwise it would be incumbent upon your to provide all the imports which can be a huge amount of work.

sbc100 commented 10 months ago

If you want to see which imports your progam needs you can inspect the imports section using a tools such as wasm-dis (from binaryen) or wasm2wat (from wabt). The fact that wasi_snapshot_preview1 is being imported means you program depends on at least one WASI system call.

vault-thirteen commented 10 months ago

But why does it work for a single C file then ? I tried to compile a stand-alone wasm file from a single C file, I used the --no-entry key, there was no JS output and it worked in a web browser. What is the reason ? Was this function too simple to trigger the WASI ? emcc sum.c -o sum.wasm --no-entry -s EXPORTED_FUNCTIONS=["_sum"]

int sum(int a, int b) {
    return a+b;
}
sbc100 commented 10 months ago

The more complex a program, and the more part of libc it depends on the more likely it is to end up depending on import from the outside world.

vault-thirteen commented 10 months ago

Thank you.