Cranelift: Introduce the return_call and return_call_indirect instructions (#5679)

* Cranelift: Introduce the `tail` calling convention

This is an unstable-ABI calling convention that we will eventually use to
support Wasm tail calls.

Co-Authored-By: Jamey Sharp <jsharp@fastly.com>

* Cranelift: Introduce the `return_call` and `return_call_indirect` instructions

These will be used to implement tail calls for Wasm and any other language
targeting CLIF. The `return_call_indirect` instruction differs from the Wasm
instruction of the same name by taking a native address callee rather than a
Wasm function index.

Co-Authored-By: Jamey Sharp <jsharp@fastly.com>

* Cranelift: Implement verification rules for `return_call[_indirect]`

They must:

* have the same return types between the caller and callee,
* have the same calling convention between caller and callee,
* and that calling convention must support tail calls.

Co-Authored-By: Jamey Sharp <jsharp@fastly.com>

* cargo fmt

---------

Co-authored-by: Jamey Sharp <jsharp@fastly.com>
This commit is contained in:
Nick Fitzgerald
2023-02-01 13:20:35 -08:00
committed by GitHub
parent ffbbfbffce
commit bdfb746548
8 changed files with 298 additions and 101 deletions

View File

@@ -0,0 +1,50 @@
test verifier
function %test_1(i32) -> i32 tail { ; Ok
fn0 = %wow(i32) -> i32 tail
block0(v0: i32):
return_call fn0(v0)
}
function %test_2(i32) -> i32 fast {
fn0 = %wow(i32) -> i32 tail
block0(v0: i32):
return_call fn0(v0) ; error: callee's calling convention must match caller
}
function %test_3(i32) -> i32 tail {
fn0 = %wow(i32) -> i32 fast
block0(v0: i32):
return_call fn0(v0) ; error: calling convention `fast` does not support tail calls
; error: callee's calling convention must match caller
}
function %test_4(i32) -> i32 system_v {
fn0 = %wow(i32) -> i32 system_v
block0(v0: i32):
return_call fn0(v0) ; error: calling convention `system_v` does not support tail calls
}
function %test_5(i32) tail {
fn0 = %wow(i32) -> i32 tail
block0(v0: i32):
return_call fn0(v0) ; error: results of callee must match caller
}
function %test_6(i32) -> i32 tail {
fn0 = %wow(i32) tail
block0(v0: i32):
return_call fn0(v0) ; error: results of callee must match caller
}
function %test_7(i32) -> i32 tail {
fn0 = %wow(i32) -> i64 tail
block0(v0: i32):
return_call fn0(v0) ; error: result 0 has type i64, must match function signature of i32
}
function %test_8(i32) -> i32 tail {
fn0 = %wow(i32) -> i32 tail
block0(v0: i32):
return_call fn0() ; error: mismatched argument count for `return_call fn0()`: got 0, expected 1
}

View File

@@ -19,7 +19,7 @@ function %incorrect_arg_type(i32, i8) -> i32 {
function %incorrect_return_type() -> f32 {
block0:
v0 = iconst.i32 1
return v0 ; error: arg 0 (v0) has type i32, must match function signature of f32
return v0 ; error: result 0 has type i32, must match function signature of f32
}
function %too_many_return_values() {
@@ -82,7 +82,7 @@ function %jump_args() {
v0 = iconst.i16 10
v3 = iconst.i64 20
jump block1(v0, v3) ; error: arg 0 (v0) has type i16, expected i64
; error: arg 1 (v3) has type i64, expected i16
; error: arg 1 (v3) has type i64, expected i16
block1(v10: i64, v11: i16):
return
}