Skip to content

Commit 4b288ba

Browse files
authored
winch(x64): Call indirect (bytecodealliance#7100)
* winch(x64): Call indirect This change adds support for the `call_indirect` instruction to Winch. Libcalls are a pre-requisite for supporting `call_indirect` in order to lazily initialy funcrefs. This change adds support for libcalls to Winch by introducing a `BuiltinFunctions` struct similar to Cranelift's `BuiltinFunctionSignatures` struct. In general, libcalls are handled like any other function call, with the only difference that given that not all the information to fulfill the function call might be known up-front, control is given to the caller for finalizing the call. The introduction of function references also involves dealing with pointer-sized loads and stores, so this change also adds the required functionality to `FuncEnv` and `MacroAssembler` to be pointer aware, making it straight forward to derive an `OperandSize` or `WasmType` from the target's pointer size. Finally, given the complexity of the call_indirect instrunction, this change bundles an improvement to the register allocator, allowing it to track the allocatable vs non-allocatable registers, this is done to avoid any mistakes when allocating/de-allocating registers that are not alloctable. -- prtest:full * Address review comments * Fix typos * Better documentation for `new_unchecked` * Introduce `max` for `BitSet` * Make allocatable property `u64` * winch(calls): Overhaul `FnCall` This commit simplifies `FnCall`'s interface making its usage more uniform throughout the compiler. In summary, this change: * Avoids side effects in the `FnCall::new` constructor, and also makes it the only constructor. * Exposes `FnCall::save_live_registers` and `FnCall::calculate_call_stack_space` to calculate the stack space consumed by the call and so that the caller can decide which one to use at callsites depending on their use-case. * tests: Fix regset tests
1 parent 11a6608 commit 4b288ba

File tree

30 files changed

+1626
-275
lines changed

30 files changed

+1626
-275
lines changed

build.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,17 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
205205
// We ignore tests that assert for traps on windows, given
206206
// that Winch doesn't encode unwind information for Windows, yet.
207207
if strategy == "Winch" {
208+
if testsuite == "misc_testsuite" {
209+
// The misc/call_indirect is fully supported by Winch.
210+
if testname == "call_indirect" {
211+
return false;
212+
}
213+
}
208214
if testsuite != "winch" {
209215
return true;
210216
}
211217

212-
let assert_trap = ["i32", "i64"].contains(&testname);
218+
let assert_trap = ["i32", "i64", "call_indirect"].contains(&testname);
213219

214220
if assert_trap && env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() == "windows" {
215221
return true;

crates/winch/src/compiler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl wasmtime_environ::Compiler for Compiler {
6868
let mut validator = validator.into_validator(self.take_allocations());
6969
let buffer = self
7070
.isa
71-
.compile_function(ty, &body, &translation, &mut validator)
71+
.compile_function(ty, types, &body, &translation, &mut validator)
7272
.map_err(|e| CompileError::Codegen(format!("{e:?}")));
7373
self.save_allocations(validator.into_allocations());
7474
let buffer = buffer?;

fuzz/fuzz_targets/differential.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,8 @@ fn winch_supports_module(module: &[u8]) -> bool {
374374
| F32Abs { .. }
375375
| F64Abs { .. }
376376
| F32Neg { .. }
377-
| F64Neg { .. } => {}
377+
| F64Neg { .. }
378+
| CallIndirect { .. } => {}
378379
_ => {
379380
supported = false;
380381
break 'main;

0 commit comments

Comments
 (0)