Skip to content

Commit

Permalink
support _initialize export as well as __wasm_call_ctors
Browse files Browse the repository at this point in the history
Per WebAssembly/tool-conventions#203 and recent LLVM and
wasi-libc changes, libraries may export an `_initialize` function instead of
`__wasm_call_ctors`, and we should call whichever one we find.  Note that we
expect to find at most one of the two, and will return an error if both are
found.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
  • Loading branch information
dicej committed Oct 3, 2023
1 parent c950866 commit e84c299
Show file tree
Hide file tree
Showing 15 changed files with 503 additions and 0 deletions.
17 changes: 17 additions & 0 deletions crates/wit-component/src/linking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,14 @@ fn make_init_module(
)));
}

if metadata.has_ctors && metadata.has_initialize {
bail!(
"library {} exports both `__wasm_call_ctors` and `_initialize`; \
expected at most one of the two",
metadata.name
);
}

if metadata.has_ctors {
ctor_calls.push(Ins::Call(add_function_import(
&mut imports,
Expand All @@ -613,6 +621,15 @@ fn make_init_module(
)));
}

if metadata.has_initialize {
ctor_calls.push(Ins::Call(add_function_import(
&mut imports,
metadata.name,
"_initialize",
thunk_ty,
)));
}

if metadata.has_set_libraries {
ctor_calls.push(Ins::I32Const(
i32::try_from(dl_openables.libraries_address).unwrap(),
Expand Down
5 changes: 5 additions & 0 deletions crates/wit-component/src/linking/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ pub struct Metadata<'a> {
/// Whether this module exports `__wasm_call_ctors`
pub has_ctors: bool,

/// Whether this module exports `_initialize`
pub has_initialize: bool,

/// Whether this module exports `__wasm_set_libraries`
pub has_set_libraries: bool,

Expand Down Expand Up @@ -303,6 +306,7 @@ impl<'a> Metadata<'a> {
needed_libs: Vec::new(),
has_data_relocs: false,
has_ctors: false,
has_initialize: false,
has_set_libraries: false,
has_component_exports,
env_imports: BTreeSet::new(),
Expand Down Expand Up @@ -491,6 +495,7 @@ impl<'a> Metadata<'a> {
match export.name {
"__wasm_apply_data_relocs" => result.has_data_relocs = true,
"__wasm_call_ctors" => result.has_ctors = true,
"_initialize" => result.has_initialize = true,
"__wasm_set_libraries" => result.has_set_libraries = true,
_ => {
let ty = match export.kind {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
library foo exports both `__wasm_call_ctors` and `_initialize`; expected at most one of the two
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(module
(@dylink.0
(mem-info (memory 0 4))
(needed "foo")
)
(type (func (param i32) (result i32)))
(import "env" "foo" (func $import_foo (type 0)))
(func $bar (type 0) (param i32) (result i32)
unreachable
)
(export "bar" (func $bar))
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package test:test;

world lib-bar { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(module
(@dylink.0
(mem-info (memory 0 4))
(needed "bar")
)
(type (func (param i32) (result i32)))
(type (func))
(import "test:test/test" "foo" (func $import_foo (type 0)))
(import "env" "foo" (func $import_foo2 (type 0)))
(import "env" "bar" (func $import_bar (type 0)))
(func $foo (type 0) (param i32) (result i32)
unreachable
)
(func $_initialize (type 1)
unreachable
)
(export "test:test/test#foo" (func $foo))
(export "foo" (func $foo))
(export "_initialize" (func $_initialize))
(export "__wasm_call_ctors" (func $_initialize))
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package test:test;

interface test {
foo: func(v: s32) -> s32;
}

world lib-foo {
import test;
export test;
}
Loading

0 comments on commit e84c299

Please sign in to comment.