[llvm] [WebAssembly] Implement lowering calls through funcref to call_ref when available (PR #162227)
Demetrius Kanios via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 14 16:42:23 PDT 2025
QuantumSegfault wrote:
...it works?
It compiles just fine `bin/llvm-mc -filetype=obj -mattr=+reference-types call_ref_test.s`
If I run that through `wasm-ld --allow-undefined --no-entry --export-dynamic` I get:
```wat
(module $-
(type (;0;) (func (param i32)))
(type (;1;) (func (param funcref)))
(import "env" "__funcref_call_table" (table (;0;) 0 funcref))
(memory (;0;) 2)
(global $__stack_pointer (;0;) (mut i32) (i32.const 66560))
(export "memory" (memory 0))
(export "__stack_pointer" (global $__stack_pointer))
(export "test_func" (func $test_func))
(func $test_func (;0;) (type 1) (param funcref)
(table.set 0
(i32.const 0)
(local.get 0))
(call_indirect (type 0)
(i32.const 32)
(i32.const 0))
(table.set 0
(i32.const 0)
(ref.null func))
)
(@producers
(processed-by "clang" "20.1.8")
)
(@custom "target_features" (after code) "\08+\0bbulk-memory+\0fbulk-memory-opt+\16call-indirect-overlong+\0amultivalue+\0fmutable-globals+\13nontrapping-fptoint+\0freference-types+\08sign-ext")
)
```
The one thing that sticks out is that `__funcref_call_table` is not defined. Here is the output of obj2yaml after `llvm-mc`
```yaml
--- !WASM
FileHeader:
Version: 0x1
Sections:
- Type: TYPE
Signatures:
- Index: 0
ParamTypes:
- FUNCREF
ReturnTypes: []
- Index: 1
ParamTypes:
- I32
ReturnTypes: []
- Type: IMPORT
Imports:
- Module: env
Field: __linear_memory
Kind: MEMORY
Memory:
Minimum: 0x0
- Module: env
Field: __funcref_call_table
Kind: TABLE
Table:
Index: 0
ElemType: FUNCREF
Limits:
Minimum: 0x0
- Type: FUNCTION
FunctionTypes: [ 0 ]
- Type: CODE
Relocations:
- Type: R_WASM_TABLE_NUMBER_LEB
Index: 1
Offset: 0x8
- Type: R_WASM_TYPE_INDEX_LEB
Index: 1
Offset: 0x12
- Type: R_WASM_TABLE_NUMBER_LEB
Index: 1
Offset: 0x17
- Type: R_WASM_TABLE_NUMBER_LEB
Index: 1
Offset: 0x21
Functions:
- Index: 0
Locals: []
Body: 410020002680808080004120410011818080800080808080004100D0702680808080000B
- Type: CUSTOM
Name: linking
Version: 2
SymbolTable:
- Index: 0
Kind: FUNCTION
Name: test_func
Flags: [ ]
Function: 0
- Index: 1
Kind: TABLE
Name: __funcref_call_table
Flags: [ UNDEFINED ]
Table: 0
- Type: CUSTOM
Name: producers
Tools:
- Name: clang
Version: 20.1.8
- Type: CUSTOM
Name: target_features
Features:
- Prefix: USED
Name: bulk-memory
- Prefix: USED
Name: bulk-memory-opt
- Prefix: USED
Name: call-indirect-overlong
- Prefix: USED
Name: multivalue
- Prefix: USED
Name: mutable-globals
- Prefix: USED
Name: nontrapping-fptoint
- Prefix: USED
Name: reference-types
- Prefix: USED
Name: sign-ext
```
---
The symbol is created weak, just like the `__indirect_function_table`, but unlike that other table, it is never provided default contents. So maybe we just need to initialize the table somewhere? I'll look into it. I'm guessing that should be a separate PR?
https://github.com/llvm/llvm-project/pull/162227
More information about the llvm-commits
mailing list