Home > Enterprise >  Why is an object's constructor being called in every exported WASM function?
Why is an object's constructor being called in every exported WASM function?

Time:06-10

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.

  • Related