Skip to content

Commit 7034366

Browse files
sunfishcodedschuff
andauthored
Add a toolchain-independent ABI document, and propose _initialize (#203)
* Add a toolchain-independent ABI document, and propose `_initialize` The Wasm ecosystem is currently not consistent in how "constructors" such as C++ static initializers and similar features in other languages are implemented, and the result is users reporting constructs running multiple times, and other users reporting constructors not getting run when they should. WASI has [defined a convention] using an exported function named `_initialize`, however not all users are using WASI conventions. In particular, users of what is sometimes called "wasm32-unknown-unknown" are not expecting to follow WASI conventions. However, they still have a need for constructors working in a reliable way. To address this, I propose moving this out of WASI and defining this as a toolchain-independent ABI, here in tool-conventions. This would recognize the `_initialize` function as the toolchain-independent way to ensure that constructors are properly called before other exports are accessed. Related activities ------------------ In the component model, there is a proposal to add a [second initialization phase]. If that's done, then component-model toolchains could arrange for this `_initialize` function to be called automatically by this second initialization mechanism. Considered alternatives ----------------------- It is tempting to use the [Wasm start function] for C++ constructors; this has been [extensively discussed], and the short answer is, the Wasm start function is often called at a time when the outside environment can't access the module's exports, and C++ constructors can run arbitrary user code which may generate calls to things that need to access the module's exports. It's also tempting to propose defining a second initialization phase in core Wasm. I'm not opposed to this, but it is more complex at the core Wasm level than at the component-model level. For example, in Emscripten, Wasm modules depend on JS code being able to run after the exports are available but before the initialization function is called, which wouldn't be possible if we simply call the initilaization function as part of the linking step. Wasm-ld has a [`__wasm_call_ctors` function], and in theory we could use that name instead of `_initialize`, but wasm-ld already does insert some initialization in addition to just constructors, so I think it makes sense to use `_initialize` as the exported function, which may call `__wasm_call_ctors` in its body. Process ------- We don't have a formal process defined for tool-convention proposals, but because this is proposal has potentially wide-ranging impacts, I propose to follow the following process: - I'm starting by posting this PR here, and people can comment on it. If a better alternative emerges, I'll close this PR. - After discussion here settles, if a better alternative hasn't emerged, I plan to request a CG meeting agenda item to present this topic to the CG, and seek feedback there, to ensure that it has CG-level visibility. - If the CG is in favor of it, then I'd propose we merge this PR. [defined a convention]: https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md [second initialization phase]: WebAssembly/component-model#146 [Wasm start function]: https://webassembly.github.io/spec/core/syntax/modules.html#syntax-start [extensively discussed]: WebAssembly/design#1160 [`__wasm_call_ctors` function]: https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md#start-section * Rename to "Basic Module ABI". * Update BasicModuleABI.md Co-authored-by: Derek Schuff <[email protected]> * Explain when we can and can't use the wasm start function. --------- Co-authored-by: Derek Schuff <[email protected]>
1 parent ab2a9d6 commit 7034366

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

BasicModuleABI.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Basic Module ABI
2+
================
3+
4+
There are many different ways to use Wasm modules, and many different
5+
conventions, language-specific ABIs, and toolchain-specific ABIs. This
6+
document describes ABI features intended to be common across all ABIs.
7+
8+
## The `_initialize` function
9+
10+
If a module exports a function named `_initialize` with no arguments and no
11+
return values, and does not export a function named `_start`, the toolchain
12+
that produced my assume that on any instance of the module, this `_initialize`
13+
function is called before any other exports are accessed.
14+
15+
This is intended to support language features such as C++ static constructors,
16+
as well as "top-level scripts" in many scripting languages, which can't use
17+
the [wasm start function] because they may call imports that need to access
18+
the module's exports. In use cases that don't need this, the wasm start
19+
function should be used.
20+
21+
[wasm start section]: https://webassembly.github.io/spec/core/syntax/modules.html#syntax-start

0 commit comments

Comments
 (0)