Skip to content

Commit 6162737

Browse files
committed
Fix swapped arguments in ThreadNewIndirect trampoline
1 parent dfe5de4 commit 6162737

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

crates/cranelift/src/compiler/component.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,8 @@ impl<'a> TrampolineCompiler<'a> {
765765
WasmArgs::InRegisters,
766766
|me, params| {
767767
params.push(me.index_value(*instance));
768-
params.push(me.index_value(*start_func_table_idx));
769768
params.push(me.index_value(*start_func_ty_idx));
769+
params.push(me.index_value(*start_func_table_idx));
770770
},
771771
);
772772
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
;;! component_model_async = true
2+
;;! component_model_threading = true
3+
4+
;; Regression test for a bug where the `ThreadNewIndirect` trampoline passed
5+
;; `start_func_table_idx` and `start_func_ty_idx` in the wrong order to the
6+
;; host `thread_new_indirect` libcall. When both indices happened to be 0 (the
7+
;; common single-table case), the swap was invisible. This test uses two tables
8+
;; and two `thread.new-indirect` canonicals so the indices differ, exposing the
9+
;; bug: calling `thread.new-indirect` targeting the empty table should trap with
10+
;; "uninitialized", not silently resolve a function from the wrong table.
11+
12+
(component
13+
(core module $libc
14+
(table (export "__indirect_function_table") 1 funcref)
15+
(table (export "t1") 1 funcref))
16+
(core module $m
17+
(import "" "thread.new-indirect-dummy" (func $thread-new-indirect-dummy (param i32 i32) (result i32)))
18+
(import "" "thread.new-indirect" (func $thread-new-indirect (param i32 i32) (result i32)))
19+
(import "" "thread.index" (func $thread-index (result i32)))
20+
(import "libc" "__indirect_function_table" (table $indirect-function-table 1 funcref))
21+
22+
(func $thread-start (param i32))
23+
(export "thread-start" (func $thread-start))
24+
(elem (table $indirect-function-table) (i32.const 0) func $thread-start)
25+
26+
(func $use-dummy (result i32)
27+
(call $thread-new-indirect-dummy (i32.const 0) (i32.const 0)))
28+
(export "use-dummy" (func $use-dummy))
29+
30+
(func (export "run") (result i32)
31+
(call $thread-new-indirect (i32.const 0) (i32.const 42))))
32+
33+
(core instance $libc (instantiate $libc))
34+
(core type $start-func-ty (func (param i32)))
35+
(alias core export $libc "__indirect_function_table" (core table $t0))
36+
(alias core export $libc "t1" (core table $t1))
37+
38+
(core func $thread-new-indirect-t0
39+
(canon thread.new-indirect $start-func-ty (table $t0)))
40+
(core func $thread-new-indirect-t1
41+
(canon thread.new-indirect $start-func-ty (table $t1)))
42+
(core func $thread-index (canon thread.index))
43+
44+
(core instance $i (instantiate $m
45+
(with "" (instance
46+
(export "thread.new-indirect-dummy" (func $thread-new-indirect-t0))
47+
(export "thread.new-indirect" (func $thread-new-indirect-t1))
48+
(export "thread.index" (func $thread-index))))
49+
(with "libc" (instance $libc))))
50+
51+
(func (export "run") async (result u32) (canon lift (core func $i "run"))))
52+
53+
(assert_trap (invoke "run") "uninitialized")

0 commit comments

Comments
 (0)