mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-06 20:58:28 +00:00
83 lines
3.0 KiB
Rust
83 lines
3.0 KiB
Rust
// LLVM implements part of the ABI lowering internally, but also requires that
|
|
// the user pack and unpack values themselves sometimes. This can help the LLVM
|
|
// optimizer by exposing operations to the optimizer, but it requires that the
|
|
// frontend know exactly what IR to produce in order to get the right ABI.
|
|
|
|
#![deny(dead_code, missing_docs)]
|
|
|
|
use crate::translator::intrinsics::Intrinsics;
|
|
use inkwell::{
|
|
attributes::{Attribute, AttributeLoc},
|
|
builder::Builder,
|
|
context::Context,
|
|
targets::TargetMachine,
|
|
types::FunctionType,
|
|
values::{BasicValueEnum, CallSiteValue, FunctionValue, PointerValue},
|
|
};
|
|
use wasmer_compiler::CompileError;
|
|
use wasmer_types::FunctionType as FuncSig;
|
|
use wasmer_vm::VMOffsets;
|
|
|
|
mod aarch64_systemv;
|
|
mod x86_64_systemv;
|
|
|
|
use aarch64_systemv::Aarch64SystemV;
|
|
use x86_64_systemv::X86_64SystemV;
|
|
|
|
pub fn get_abi(target_machine: &TargetMachine) -> Box<dyn Abi> {
|
|
if target_machine.get_triple().as_str().to_string_lossy().starts_with("aarch64") {
|
|
Box::new(Aarch64SystemV {})
|
|
} else {
|
|
Box::new(X86_64SystemV {})
|
|
}
|
|
}
|
|
|
|
/// We need to produce different LLVM IR for different platforms. (Contrary to
|
|
/// popular knowledge LLVM IR is not intended to be portable in that way.) This
|
|
/// trait deals with differences between function signatures on different
|
|
/// targets.
|
|
pub trait Abi {
|
|
/// Given a function definition, retrieve the parameter that is the vmctx pointer.
|
|
fn get_vmctx_ptr_param<'ctx>(&self, func_value: &FunctionValue<'ctx>) -> PointerValue<'ctx>;
|
|
|
|
/// Given a wasm function type, produce an llvm function declaration.
|
|
fn func_type_to_llvm<'ctx>(
|
|
&self,
|
|
context: &'ctx Context,
|
|
intrinsics: &Intrinsics<'ctx>,
|
|
offsets: Option<&VMOffsets>,
|
|
sig: &FuncSig,
|
|
) -> Result<(FunctionType<'ctx>, Vec<(Attribute, AttributeLoc)>), CompileError>;
|
|
|
|
/// Marshall wasm stack values into function parameters.
|
|
fn args_to_call<'ctx>(
|
|
&self,
|
|
alloca_builder: &Builder<'ctx>,
|
|
func_sig: &FuncSig,
|
|
ctx_ptr: PointerValue<'ctx>,
|
|
llvm_fn_ty: &FunctionType<'ctx>,
|
|
values: &[BasicValueEnum<'ctx>],
|
|
) -> Vec<BasicValueEnum<'ctx>>;
|
|
|
|
/// Given a CallSite, extract the returned values and return them in a Vec.
|
|
fn rets_from_call<'ctx>(
|
|
&self,
|
|
builder: &Builder<'ctx>,
|
|
intrinsics: &Intrinsics<'ctx>,
|
|
call_site: CallSiteValue<'ctx>,
|
|
func_sig: &FuncSig,
|
|
) -> Vec<BasicValueEnum<'ctx>>;
|
|
|
|
/// Whether the llvm equivalent of this wasm function has an `sret` attribute.
|
|
fn is_sret(&self, func_sig: &FuncSig) -> Result<bool, CompileError>;
|
|
|
|
/// Pack LLVM IR values representing individual wasm values into the return type for the function.
|
|
fn pack_values_for_register_return<'ctx>(
|
|
&self,
|
|
intrinsics: &Intrinsics<'ctx>,
|
|
builder: &Builder<'ctx>,
|
|
values: &[BasicValueEnum<'ctx>],
|
|
func_type: &FunctionType<'ctx>,
|
|
) -> Result<BasicValueEnum<'ctx>, CompileError>;
|
|
}
|