Skip to content

Commit 225796a

Browse files
committed
Add method to get FnAbi of function pointer
1 parent 4e6de37 commit 225796a

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

compiler/rustc_smir/src/rustc_smir/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
533533
Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables))
534534
}
535535

536+
fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error> {
537+
let mut tables = self.0.borrow_mut();
538+
let tcx = tables.tcx;
539+
let sig = fn_ptr.internal(&mut *tables, tcx);
540+
Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?.stable(&mut *tables))
541+
}
542+
536543
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
537544
let mut tables = self.0.borrow_mut();
538545
let def_id = tables.instances[def].def_id();

compiler/stable_mir/src/compiler_interface.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ pub trait Context {
215215
/// Get an instance ABI.
216216
fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error>;
217217

218+
/// Get the ABI of a function pointer.
219+
fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error>;
220+
218221
/// Get the layout of a type.
219222
fn ty_layout(&self, ty: Ty) -> Result<Layout, Error>;
220223

compiler/stable_mir/src/ty.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{
22
mir::{Body, Mutability, Safety},
33
with, DefId, Error, Symbol,
44
};
5-
use crate::abi::Layout;
5+
use crate::abi::{FnAbi, Layout};
66
use crate::crate_def::{CrateDef, CrateDefType};
77
use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
88
use crate::mir::mono::StaticDef;
@@ -996,6 +996,16 @@ pub struct AliasTerm {
996996

997997
pub type PolyFnSig = Binder<FnSig>;
998998

999+
impl PolyFnSig {
1000+
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
1001+
///
1002+
/// NB: this doesn't handle virtual calls - those should use `Instance::fn_abi`
1003+
/// instead, where the instance is an `InstanceKind::Virtual`.
1004+
pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
1005+
with(|cx| cx.fn_ptr_abi(self))
1006+
}
1007+
}
1008+
9991009
#[derive(Clone, Debug, Eq, PartialEq)]
10001010
pub struct FnSig {
10011011
pub inputs_and_output: Vec<Ty>,

tests/ui-fulldeps/stable-mir/check_abi.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ fn test_stable_mir() -> ControlFlow<()> {
5454
let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap();
5555
check_variadic(variadic_fn);
5656

57+
// Extract function pointers.
58+
let fn_ptr_holder = *get_item(&items, (ItemKind::Fn, "fn_ptr_holder")).unwrap();
59+
let fn_ptr_holder_instance = Instance::try_from(fn_ptr_holder).unwrap();
60+
let body = fn_ptr_holder_instance.body().unwrap();
61+
let args = body.arg_locals();
62+
63+
// Test fn_abi of function pointer version.
64+
let ptr_fn_abi = args[0].ty.kind().fn_sig().unwrap().fn_ptr_abi().unwrap();
65+
assert_eq!(ptr_fn_abi, fn_abi);
66+
67+
// Test variadic_fn of function pointer version.
68+
let ptr_variadic_fn_abi = args[1].ty.kind().fn_sig().unwrap().fn_ptr_abi().unwrap();
69+
assert!(ptr_variadic_fn_abi.c_variadic);
70+
assert_eq!(ptr_variadic_fn_abi.args.len(), 1);
71+
5772
ControlFlow::Continue(())
5873
}
5974

@@ -164,6 +179,14 @@ fn generate_input(path: &str) -> std::io::Result<()> {
164179
pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{
165180
0
166181
}}
182+
183+
pub type ComplexFn = fn([u8; 0], char, NonZero<u8>) -> Result<usize, &'static str>;
184+
pub type VariadicFn = unsafe extern "C" fn(usize, ...) -> usize;
185+
186+
pub fn fn_ptr_holder(complex_fn: ComplexFn, variadic_fn: VariadicFn) {{
187+
// We only care about the signature.
188+
todo!()
189+
}}
167190
"#
168191
)?;
169192
Ok(())

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy