Add method to get FnAbi
of function pointer
This commit is contained in:
parent
4e6de37349
commit
225796a2df
@ -533,6 +533,13 @@ fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error> {
|
|||||||
Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables))
|
Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error> {
|
||||||
|
let mut tables = self.0.borrow_mut();
|
||||||
|
let tcx = tables.tcx;
|
||||||
|
let sig = fn_ptr.internal(&mut *tables, tcx);
|
||||||
|
Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?.stable(&mut *tables))
|
||||||
|
}
|
||||||
|
|
||||||
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
|
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
|
||||||
let mut tables = self.0.borrow_mut();
|
let mut tables = self.0.borrow_mut();
|
||||||
let def_id = tables.instances[def].def_id();
|
let def_id = tables.instances[def].def_id();
|
||||||
|
@ -215,6 +215,9 @@ fn resolve_closure(
|
|||||||
/// Get an instance ABI.
|
/// Get an instance ABI.
|
||||||
fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error>;
|
fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error>;
|
||||||
|
|
||||||
|
/// Get the ABI of a function pointer.
|
||||||
|
fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error>;
|
||||||
|
|
||||||
/// Get the layout of a type.
|
/// Get the layout of a type.
|
||||||
fn ty_layout(&self, ty: Ty) -> Result<Layout, Error>;
|
fn ty_layout(&self, ty: Ty) -> Result<Layout, Error>;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
mir::{Body, Mutability, Safety},
|
mir::{Body, Mutability, Safety},
|
||||||
with, DefId, Error, Symbol,
|
with, DefId, Error, Symbol,
|
||||||
};
|
};
|
||||||
use crate::abi::Layout;
|
use crate::abi::{FnAbi, Layout};
|
||||||
use crate::crate_def::{CrateDef, CrateDefType};
|
use crate::crate_def::{CrateDef, CrateDefType};
|
||||||
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
||||||
use crate::mir::mono::StaticDef;
|
use crate::mir::mono::StaticDef;
|
||||||
@ -996,6 +996,16 @@ pub struct AliasTerm {
|
|||||||
|
|
||||||
pub type PolyFnSig = Binder<FnSig>;
|
pub type PolyFnSig = Binder<FnSig>;
|
||||||
|
|
||||||
|
impl PolyFnSig {
|
||||||
|
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
|
||||||
|
///
|
||||||
|
/// NB: this doesn't handle virtual calls - those should use `Instance::fn_abi`
|
||||||
|
/// instead, where the instance is an `InstanceKind::Virtual`.
|
||||||
|
pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
|
||||||
|
with(|cx| cx.fn_ptr_abi(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct FnSig {
|
pub struct FnSig {
|
||||||
pub inputs_and_output: Vec<Ty>,
|
pub inputs_and_output: Vec<Ty>,
|
||||||
|
@ -54,6 +54,21 @@ fn test_stable_mir() -> ControlFlow<()> {
|
|||||||
let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap();
|
let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap();
|
||||||
check_variadic(variadic_fn);
|
check_variadic(variadic_fn);
|
||||||
|
|
||||||
|
// Extract function pointers.
|
||||||
|
let fn_ptr_holder = *get_item(&items, (ItemKind::Fn, "fn_ptr_holder")).unwrap();
|
||||||
|
let fn_ptr_holder_instance = Instance::try_from(fn_ptr_holder).unwrap();
|
||||||
|
let body = fn_ptr_holder_instance.body().unwrap();
|
||||||
|
let args = body.arg_locals();
|
||||||
|
|
||||||
|
// Test fn_abi of function pointer version.
|
||||||
|
let ptr_fn_abi = args[0].ty.kind().fn_sig().unwrap().fn_ptr_abi().unwrap();
|
||||||
|
assert_eq!(ptr_fn_abi, fn_abi);
|
||||||
|
|
||||||
|
// Test variadic_fn of function pointer version.
|
||||||
|
let ptr_variadic_fn_abi = args[1].ty.kind().fn_sig().unwrap().fn_ptr_abi().unwrap();
|
||||||
|
assert!(ptr_variadic_fn_abi.c_variadic);
|
||||||
|
assert_eq!(ptr_variadic_fn_abi.args.len(), 1);
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +179,14 @@ pub fn fn_abi(
|
|||||||
pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{
|
pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{
|
||||||
0
|
0
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
pub type ComplexFn = fn([u8; 0], char, NonZero<u8>) -> Result<usize, &'static str>;
|
||||||
|
pub type VariadicFn = unsafe extern "C" fn(usize, ...) -> usize;
|
||||||
|
|
||||||
|
pub fn fn_ptr_holder(complex_fn: ComplexFn, variadic_fn: VariadicFn) {{
|
||||||
|
// We only care about the signature.
|
||||||
|
todo!()
|
||||||
|
}}
|
||||||
"#
|
"#
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user