Skip to content

Commit 0b9b7bd

Browse files
authored
Fix swapped arguments in ThreadNewIndirect trampoline (#13054)
* Fix swapped arguments in `ThreadNewIndirect` trampoline * Add reference types declaration
1 parent 87ffaa3 commit 0b9b7bd

2 files changed

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

0 commit comments

Comments
 (0)