cranelift-interpreter: Implement call_indirect and return_call_indirect (#5877)

* cranelift-interpreter: Implement `call_indirect`

* cranelift: Fix typo

* riscv64: Enable `call_indirect` tests
This commit is contained in:
Afonso Bordado
2023-02-25 13:16:59 +00:00
committed by GitHub
parent 36e92add6f
commit e9095050be
6 changed files with 321 additions and 69 deletions

View File

@@ -3,7 +3,10 @@
use crate::address::{Address, AddressSize};
use crate::interpreter::LibCallHandler;
use cranelift_codegen::data_value::DataValue;
use cranelift_codegen::ir::{FuncRef, Function, GlobalValue, StackSlot, Type, Value};
use cranelift_codegen::ir::{
ExternalName, FuncRef, Function, GlobalValue, LibCall, Signature, StackSlot, Type, Value,
};
use cranelift_codegen::isa::CallConv;
use cranelift_entity::PrimaryMap;
use smallvec::SmallVec;
use thiserror::Error;
@@ -64,6 +67,16 @@ pub trait State<'a, V> {
/// stack or to one of the heaps; the number of bytes stored corresponds to the specified [Type].
fn checked_store(&mut self, address: Address, v: V) -> Result<(), MemoryError>;
/// Compute the address of a function given its name.
fn function_address(
&self,
size: AddressSize,
name: &ExternalName,
) -> Result<Address, MemoryError>;
/// Retrieve a reference to a [Function] given its address.
fn get_function_from_address(&self, address: Address) -> Option<InterpreterFunctionRef<'a>>;
/// Given a global value, compute the final value for that global value, applying all operations
/// in intermediate global values.
fn resolve_global_value(&self, gv: GlobalValue) -> Result<V, MemoryError>;
@@ -77,6 +90,33 @@ pub trait State<'a, V> {
fn set_pinned_reg(&mut self, v: V);
}
pub enum InterpreterFunctionRef<'a> {
Function(&'a Function),
LibCall(LibCall),
}
impl<'a> InterpreterFunctionRef<'a> {
pub fn signature(&self) -> Signature {
match self {
InterpreterFunctionRef::Function(f) => f.stencil.signature.clone(),
// CallConv here is sort of irrelevant, since we don't use it for anything
InterpreterFunctionRef::LibCall(lc) => lc.signature(CallConv::SystemV),
}
}
}
impl<'a> From<&'a Function> for InterpreterFunctionRef<'a> {
fn from(f: &'a Function) -> Self {
InterpreterFunctionRef::Function(f)
}
}
impl From<LibCall> for InterpreterFunctionRef<'_> {
fn from(lc: LibCall) -> Self {
InterpreterFunctionRef::LibCall(lc)
}
}
#[derive(Error, Debug)]
pub enum MemoryError {
#[error("Invalid DataValue passed as an address: {0}")]
@@ -150,6 +190,18 @@ where
unimplemented!()
}
fn function_address(
&self,
_size: AddressSize,
_name: &ExternalName,
) -> Result<Address, MemoryError> {
unimplemented!()
}
fn get_function_from_address(&self, _address: Address) -> Option<InterpreterFunctionRef<'a>> {
unimplemented!()
}
fn resolve_global_value(&self, _gv: GlobalValue) -> Result<V, MemoryError> {
unimplemented!()
}