Skip to content

Commit

Permalink
rustc: compute FnAbi's for virtual calls through FnAbi::of_instance.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Nov 3, 2019
1 parent b30866f commit a0ed842
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 36 deletions.
20 changes: 8 additions & 12 deletions src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2495,9 +2495,8 @@ where
+ HasTyCtxt<'tcx>
+ HasParamEnv<'tcx>,
{
fn of_instance(cx: &C, instance: ty::Instance<'tcx>) -> Self;
fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
fn new_internal(
cx: &C,
sig: ty::FnSig<'tcx>,
Expand All @@ -2515,25 +2514,22 @@ where
+ HasTyCtxt<'tcx>
+ HasParamEnv<'tcx>,
{
fn of_instance(cx: &C, instance: ty::Instance<'tcx>) -> Self {
fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
call::FnAbi::new_internal(cx, sig, extra_args, |ty, _| ArgAbi::new(cx.layout_of(ty)))
}

fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
let sig = instance.fn_sig(cx.tcx());
let sig = cx
.tcx()
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
call::FnAbi::new(cx, sig, &[])
}

fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
call::FnAbi::new_internal(cx, sig, extra_args, |ty, _| ArgAbi::new(cx.layout_of(ty)))
}

fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
FnAbiExt::new_internal(cx, sig, extra_args, |ty, arg_idx| {
call::FnAbi::new_internal(cx, sig, extra_args, |ty, arg_idx| {
let mut layout = cx.layout_of(ty);
// Don't pass the vtable, it's not an argument of the virtual fn.
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
// or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
if arg_idx == Some(0) {
if let (ty::InstanceDef::Virtual(..), Some(0)) = (&instance.def, arg_idx) {
let fat_pointer_ty = if layout.is_unsized() {
// unsized `self` is passed as a pointer to `self`
// FIXME (mikeyhew) change this to use &own if it is ever added to the language
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub fn get_fn(
llfn
}
} else {
let fn_abi = FnAbi::of_instance(cx, instance);
let fn_abi = FnAbi::of_instance(cx, instance, &[]);
let llfn = cx.declare_fn(&sym, &fn_abi);
debug!("get_fn: not casting pointer!");

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
assert!(!instance.substs.needs_infer() &&
!instance.substs.has_param_types());

let fn_abi = FnAbi::of_instance(self, instance);
let fn_abi = FnAbi::of_instance(self, instance, &[]);
let lldecl = self.declare_fn(symbol_name, &fn_abi);
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
Expand Down
46 changes: 25 additions & 21 deletions src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,20 +345,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&args1[..]
};
let (drop_fn, fn_abi) = match ty.kind {
// FIXME(eddyb) perhaps move some of this logic into
// `Instance::resolve_drop_in_place`?
ty::Dynamic(..) => {
let sig = drop_fn.fn_sig(self.cx.tcx());
let sig = self.cx.tcx().normalize_erasing_late_bound_regions(
ty::ParamEnv::reveal_all(),
&sig,
);
let fn_abi = FnAbi::new_vtable(&bx, sig, &[]);
let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
substs: drop_fn.substs,
};
let fn_abi = FnAbi::of_instance(&bx, virtual_drop, &[]);
let vtable = args[1];
args = &args[..1];
(meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_abi), fn_abi)
}
_ => {
(bx.get_fn_addr(drop_fn),
FnAbi::of_instance(&bx, drop_fn))
FnAbi::of_instance(&bx, drop_fn, &[]))
}
};
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
Expand Down Expand Up @@ -439,7 +440,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Obtain the panic entry point.
let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
let instance = ty::Instance::mono(bx.tcx(), def_id);
let fn_abi = FnAbi::of_instance(&bx, instance);
let fn_abi = FnAbi::of_instance(&bx, instance, &[]);
let llfn = bx.get_fn_addr(instance);

// Codegen the actual panic invoke/call.
Expand Down Expand Up @@ -474,6 +475,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
_ => bug!("{} is not callable", callee.layout.ty),
};
let def = instance.map(|i| i.def);

if let Some(ty::InstanceDef::DropGlue(_, None)) = def {
// Empty drop glue; a no-op.
let &(_, target) = destination.as_ref().unwrap();
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
helper.funclet_br(self, &mut bx, target);
return;
}

// FIXME(eddyb) avoid computing this if possible, when `instance` is
// available - right now `sig` is only needed for getthing the `abi`
// and figuring out how many extra args were passed to a C-variadic `fn`.
let sig = callee.layout.ty.fn_sig(bx.tcx());
let sig = bx.tcx().normalize_erasing_late_bound_regions(
ty::ParamEnv::reveal_all(),
Expand Down Expand Up @@ -514,18 +527,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.monomorphize(&op_ty)
}).collect::<Vec<_>>();

let fn_abi = match def {
Some(ty::InstanceDef::Virtual(..)) => {
FnAbi::new_vtable(&bx, sig, &extra_args)
}
Some(ty::InstanceDef::DropGlue(_, None)) => {
// Empty drop glue; a no-op.
let &(_, target) = destination.as_ref().unwrap();
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
helper.funclet_br(self, &mut bx, target);
return;
}
_ => FnAbi::new(&bx, sig, &extra_args)
let fn_abi = match instance {
Some(instance) => FnAbi::of_instance(&bx, instance, &extra_args),
None => FnAbi::new(&bx, sig, &extra_args)
};

// Emit a panic or a no-op for `panic_if_uninhabited`.
Expand All @@ -541,7 +545,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let def_id =
common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem);
let instance = ty::Instance::mono(bx.tcx(), def_id);
let fn_abi = FnAbi::of_instance(&bx, instance);
let fn_abi = FnAbi::of_instance(&bx, instance, &[]);
let llfn = bx.get_fn_addr(instance);

if let Some((_, target)) = destination.as_ref() {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(

let mir = cx.tcx().instance_mir(instance.def);

let fn_abi = FnAbi::of_instance(cx, instance);
let fn_abi = FnAbi::of_instance(cx, instance, &[]);
debug!("fn_abi: {:?}", fn_abi);

let debug_context = {
Expand Down

0 comments on commit a0ed842

Please sign in to comment.