I'm compiling some c for a WASM module
struct Test{
Test(){
printf("Constructed");
}
};
Test t;
EXPORT void init(){...}
EXPORT void update(){...}
EXPORT void uninit(){...}
I would expect the constructor to only be called once for t, but looking at chrome's debugger shows that the constructor for t is called near the top of every exported function (func18 is the constructor):
...
(func $init (;23;) (export "init")
(local $var0 i32) (local $var1 i32) (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32)
call $func18
...
(func $update (;24;) (export "update")
(local $var1 i32)
call $func18
...
(func $uninit (;25;) (export "uninit")
(local $var0 i32) (local $var1 i32) (local $var2 i32)
call $func18
...
I know that the constructor has to be called somewhere, but how can I control where it's called and stop every function from calling it? Is it possible to control this through the command line arguments for clang ?
This is the command I've been using to compile this:
clang
-Wall
--target=wasm32
-Ofast
-flto
--no-standard-libraries
-Wl,--export=init
-Wl,--export=update
-Wl,--export=uninit
-Wl,--no-entry
-Wl,--lto-O3
-Wl,-allow-undefined-file=wasm.syms
-Wl,--import-memory
-o ./bin/main.wasm
-I./src
./src/lib.cpp
./src/main.cpp
I should note that I'm not using Emscripten or any libraries/frameworks.
CodePudding user response:
See https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md
I think what is happening is that the linker in this case deciding that you using the command abi, and each entry point to your application is a standalone command.
What you are actually trying to build is that is referred to in that document as a reactor.
The easiest way to build a reactor is to include some kind of crt1.c file such as the one that wasi-sdk uses: https://github.com/WebAssembly/wasi-libc/blob/main/libc-bottom-half/crt/crt1-reactor.c
If you export the _iniitialize
function, which in turn references the __wasm_call_ctors
function, that is a signal the linker that you the ctors are to be called just once and you are building a reactor.