Skip to content

Commit 6adf3df

Browse files
authored
fix table resolution for thread.new-indirect intrinsic calls (#2585)
Previously, the encoding of `thread.new-indirect` calls looked for an `__indirect_function_table` export in the same module as the one importing that intrinsic. However, when linking shared libraries together, the intrinsic-importing library module will be different from the table-exporting main module. In practice, this means we should always be looking for the table in the main module, regardless of which module is importing the intrinsic. Fixes #2583
1 parent e7a8b2c commit 6adf3df

6 files changed

Lines changed: 116 additions & 12 deletions

File tree

crates/wit-component/src/encoding.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,18 +1474,15 @@ impl<'a> EncodingState<'a> {
14741474
.into_iter(*encoding, self.memory_index, realloc_index)?;
14751475
self.component.task_return(result, options)
14761476
}
1477-
ShimKind::ThreadNewIndirect {
1478-
for_module,
1479-
func_ty,
1480-
} => {
1477+
ShimKind::ThreadNewIndirect { func_ty } => {
14811478
// Encode the function type for the thread start function so we can reference it in the `canon` call.
14821479
let (func_ty_idx, f) = self.component.core_type(Some("thread-start"));
14831480
f.core().func_type(func_ty);
14841481

14851482
// In order for the funcref table referenced by `thread.new-indirect` to be used,
1486-
// it must have been exported by the module.
1487-
let exports = self.info.exports_for(*for_module);
1488-
let instance_index = self.instance_for(*for_module);
1483+
// it must have been exported by the main module.
1484+
let exports = self.info.exports_for(CustomModule::Main);
1485+
let instance_index = self.instance_for(CustomModule::Main);
14891486
let table_idx = exports.indirect_function_table().map(|table| {
14901487
self.core_alias_export(
14911488
Some("indirect-function-table"),
@@ -2005,7 +2002,6 @@ impl<'a> EncodingState<'a> {
20052002
Import::ThreadNewIndirect => Ok(self.materialize_shim_import(
20062003
shims,
20072004
&ShimKind::ThreadNewIndirect {
2008-
for_module,
20092005
// This is fixed for now
20102006
func_ty: FuncType::new([ValType::I32], []),
20112007
},
@@ -2611,8 +2607,6 @@ enum ShimKind<'a> {
26112607
/// A shim used for the `thread.new-indirect` built-in function, which
26122608
/// must refer to the core module instance's indirect function table.
26132609
ThreadNewIndirect {
2614-
/// Which instance to pull the function table from.
2615-
for_module: CustomModule<'a>,
26162610
/// The function type to use when creating the thread.
26172611
func_ty: FuncType,
26182612
},
@@ -2866,7 +2860,6 @@ impl<'a> Shims<'a> {
28662860
debug_name: "thread.new-indirect".to_string(),
28672861
options: RequiredOptions::empty(),
28682862
kind: ShimKind::ThreadNewIndirect {
2869-
for_module,
28702863
// This is fixed for now
28712864
func_ty: FuncType::new([ValType::I32], vec![]),
28722865
},

crates/wit-component/src/linking.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1408,7 +1408,7 @@ pub struct Linker {
14081408
impl Linker {
14091409
/// Add a dynamic library module to this linker.
14101410
///
1411-
/// If `dl_openable` is true, all of the libraries exports will be added to the `dlopen`/`dlsym` lookup table
1411+
/// If `dl_openable` is true, all of the library's exports will be added to the `dlopen`/`dlsym` lookup table
14121412
/// for runtime resolution.
14131413
pub fn library(mut self, name: &str, module: &[u8], dl_openable: bool) -> Result<Self> {
14141414
self.libraries
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
(component
2+
(core module $main (;0;)
3+
(table (;0;) 2 funcref)
4+
(memory (;0;) 17)
5+
(global (;0;) i32 i32.const 1048584)
6+
(global (;1;) i32 i32.const 2)
7+
(export "foo:memory_base" (global 0))
8+
(export "foo:table_base" (global 1))
9+
(export "__indirect_function_table" (table 0))
10+
(export "memory" (memory 0))
11+
(@producers
12+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
13+
)
14+
)
15+
(core module $foo (;1;)
16+
(@dylink.0)
17+
(type (;0;) (func (param i32 i32) (result i32)))
18+
(type (;1;) (func))
19+
(import "$root" "[thread-new-indirect-v0]" (func (;0;) (type 0)))
20+
(export "hi" (func 1))
21+
(func (;1;) (type 1))
22+
)
23+
(core module $__init (;2;)
24+
(type (;0;) (func))
25+
(type (;1;) (func (param i32)))
26+
(import "env" "memory" (memory (;0;) 0))
27+
(import "env" "__indirect_function_table" (table (;0;) 0 funcref))
28+
(start 0)
29+
(elem (;0;) (i32.const 1) func)
30+
(elem (;1;) (i32.const 2) func)
31+
(func (;0;) (type 0))
32+
(data (;0;) (i32.const 1048576) "\00\00\00\00\00\00\10\00")
33+
(@producers
34+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
35+
)
36+
)
37+
(core module $wit-component-shim-module (;3;)
38+
(type (;0;) (func (param i32 i32) (result i32)))
39+
(table (;0;) 1 1 funcref)
40+
(export "0" (func $thread.new-indirect))
41+
(export "$imports" (table 0))
42+
(func $thread.new-indirect (;0;) (type 0) (param i32 i32) (result i32)
43+
local.get 0
44+
local.get 1
45+
i32.const 0
46+
call_indirect (type 0)
47+
)
48+
(@producers
49+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
50+
)
51+
)
52+
(core module $wit-component-fixup (;4;)
53+
(type (;0;) (func (param i32 i32) (result i32)))
54+
(import "" "0" (func (;0;) (type 0)))
55+
(import "" "$imports" (table (;0;) 1 1 funcref))
56+
(elem (;0;) (i32.const 0) func 0)
57+
(@producers
58+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
59+
)
60+
)
61+
(core instance $wit-component-shim-instance (;0;) (instantiate $wit-component-shim-module))
62+
(core instance $main (;1;) (instantiate $main))
63+
(alias core export $main "memory" (core memory $memory (;0;)))
64+
(alias core export $wit-component-shim-instance "0" (core func $thread.new-indirect (;0;)))
65+
(core instance $$root (;2;)
66+
(export "[thread-new-indirect-v0]" (func $thread.new-indirect))
67+
)
68+
(core instance $foo (;3;) (instantiate $foo
69+
(with "$root" (instance $$root))
70+
)
71+
)
72+
(alias core export $wit-component-shim-instance "$imports" (core table $"shim table" (;0;)))
73+
(core type $thread-start (;0;) (func (param i32)))
74+
(alias core export $main "__indirect_function_table" (core table $indirect-function-table (;1;)))
75+
(core func $"#core-func1 thread.new-indirect" (@name "thread.new-indirect") (;1;) (canon thread.new-indirect $thread-start $indirect-function-table))
76+
(core instance $fixup-args (;4;)
77+
(export "$imports" (table $"shim table"))
78+
(export "0" (func $"#core-func1 thread.new-indirect"))
79+
)
80+
(core instance $fixup (;5;) (instantiate $wit-component-fixup
81+
(with "" (instance $fixup-args))
82+
)
83+
)
84+
(core instance $__init (;6;) (instantiate $__init
85+
(with "env" (instance $main))
86+
)
87+
)
88+
(type (;0;) (func))
89+
(alias core export $foo "hi" (core func $hi (;2;)))
90+
(func $hi (;0;) (type 0) (canon lift (core func $hi)))
91+
(export $"#func1 hi" (@name "hi") (;1;) "hi" (func $hi))
92+
(@producers
93+
(processed-by "wit-component" "$CARGO_PKG_VERSION")
94+
)
95+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package root:component;
2+
3+
world root {
4+
export hi: func();
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(module
2+
(@dylink.0)
3+
(import "$root" "[thread-new-indirect-v0]" (func (param i32 i32) (result i32)))
4+
5+
(func (export "hi"))
6+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package test:test;
2+
3+
world lib-foo {
4+
export hi: func();
5+
}

0 commit comments

Comments
 (0)