-
Notifications
You must be signed in to change notification settings - Fork 3.5k
A mechanism is needed for handling constructor functions with the LLVM wasm backend. #4218
Description
When using the JSBackend, the backend emits a list of initializers with the metadata, which emscripten reads. For each initializer, it generates a JS function which calls the initializer and pushes it onto the __ATINIT__ variable in the final JS file. A function called before main iterates over that variable and calls each function.
On modern ELF platforms, the compiler emits a pointer to each initializer function into a special section, .init_array. The linker creates symbols __init_array_start and __init_array_end which point to the start and end of this section. Code in the executable (e.g. in the _start() function of a statically-linked executable) can iterate over the array using these symbols to call each initializer, and a dynamic linker can read the section directly.
We need a mechanism to accomplish this purpose for wasm. Wasm has no direct analog to sections, but it does have a mechanism to specify the entry point (a.k.a. start function) for a module (https://github.com/WebAssembly/design/blob/master/Modules.md#module-start-function). This mechanism is sufficient for statically linked binaries to work as they do on native platforms; a function could be defined which iterates over the array and calls the constructors, and linked into the executable (e.g. as part of libc or a crt file). It would be called by the modules entry function. This could be made transparent to emscripten, which could continue to use its existing __ATINIT__ mechanism if there were Javascript functions that also needed to run before the module runs.