|
| 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