Skip to content

Commit a0ed842

Browse files
committed
rustc: compute FnAbi's for virtual calls through FnAbi::of_instance.
1 parent b30866f commit a0ed842

File tree

5 files changed

+36
-36
lines changed

5 files changed

+36
-36
lines changed

src/librustc/ty/layout.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -2495,9 +2495,8 @@ where
24952495
+ HasTyCtxt<'tcx>
24962496
+ HasParamEnv<'tcx>,
24972497
{
2498-
fn of_instance(cx: &C, instance: ty::Instance<'tcx>) -> Self;
24992498
fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
2500-
fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
2499+
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self;
25012500
fn new_internal(
25022501
cx: &C,
25032502
sig: ty::FnSig<'tcx>,
@@ -2515,25 +2514,22 @@ where
25152514
+ HasTyCtxt<'tcx>
25162515
+ HasParamEnv<'tcx>,
25172516
{
2518-
fn of_instance(cx: &C, instance: ty::Instance<'tcx>) -> Self {
2517+
fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
2518+
call::FnAbi::new_internal(cx, sig, extra_args, |ty, _| ArgAbi::new(cx.layout_of(ty)))
2519+
}
2520+
2521+
fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
25192522
let sig = instance.fn_sig(cx.tcx());
25202523
let sig = cx
25212524
.tcx()
25222525
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
2523-
call::FnAbi::new(cx, sig, &[])
2524-
}
2525-
2526-
fn new(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
2527-
call::FnAbi::new_internal(cx, sig, extra_args, |ty, _| ArgAbi::new(cx.layout_of(ty)))
2528-
}
25292526

2530-
fn new_vtable(cx: &C, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
2531-
FnAbiExt::new_internal(cx, sig, extra_args, |ty, arg_idx| {
2527+
call::FnAbi::new_internal(cx, sig, extra_args, |ty, arg_idx| {
25322528
let mut layout = cx.layout_of(ty);
25332529
// Don't pass the vtable, it's not an argument of the virtual fn.
25342530
// Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
25352531
// or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen
2536-
if arg_idx == Some(0) {
2532+
if let (ty::InstanceDef::Virtual(..), Some(0)) = (&instance.def, arg_idx) {
25372533
let fat_pointer_ty = if layout.is_unsized() {
25382534
// unsized `self` is passed as a pointer to `self`
25392535
// FIXME (mikeyhew) change this to use &own if it is ever added to the language

src/librustc_codegen_llvm/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn get_fn(
7777
llfn
7878
}
7979
} else {
80-
let fn_abi = FnAbi::of_instance(cx, instance);
80+
let fn_abi = FnAbi::of_instance(cx, instance, &[]);
8181
let llfn = cx.declare_fn(&sym, &fn_abi);
8282
debug!("get_fn: not casting pointer!");
8383

src/librustc_codegen_llvm/mono_item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
4343
assert!(!instance.substs.needs_infer() &&
4444
!instance.substs.has_param_types());
4545

46-
let fn_abi = FnAbi::of_instance(self, instance);
46+
let fn_abi = FnAbi::of_instance(self, instance, &[]);
4747
let lldecl = self.declare_fn(symbol_name, &fn_abi);
4848
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
4949
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());

src/librustc_codegen_ssa/mir/block.rs

+25-21
Original file line numberDiff line numberDiff line change
@@ -345,20 +345,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
345345
&args1[..]
346346
};
347347
let (drop_fn, fn_abi) = match ty.kind {
348+
// FIXME(eddyb) perhaps move some of this logic into
349+
// `Instance::resolve_drop_in_place`?
348350
ty::Dynamic(..) => {
349-
let sig = drop_fn.fn_sig(self.cx.tcx());
350-
let sig = self.cx.tcx().normalize_erasing_late_bound_regions(
351-
ty::ParamEnv::reveal_all(),
352-
&sig,
353-
);
354-
let fn_abi = FnAbi::new_vtable(&bx, sig, &[]);
351+
let virtual_drop = Instance {
352+
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
353+
substs: drop_fn.substs,
354+
};
355+
let fn_abi = FnAbi::of_instance(&bx, virtual_drop, &[]);
355356
let vtable = args[1];
356357
args = &args[..1];
357358
(meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_abi), fn_abi)
358359
}
359360
_ => {
360361
(bx.get_fn_addr(drop_fn),
361-
FnAbi::of_instance(&bx, drop_fn))
362+
FnAbi::of_instance(&bx, drop_fn, &[]))
362363
}
363364
};
364365
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
@@ -439,7 +440,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
439440
// Obtain the panic entry point.
440441
let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
441442
let instance = ty::Instance::mono(bx.tcx(), def_id);
442-
let fn_abi = FnAbi::of_instance(&bx, instance);
443+
let fn_abi = FnAbi::of_instance(&bx, instance, &[]);
443444
let llfn = bx.get_fn_addr(instance);
444445

445446
// Codegen the actual panic invoke/call.
@@ -474,6 +475,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
474475
_ => bug!("{} is not callable", callee.layout.ty),
475476
};
476477
let def = instance.map(|i| i.def);
478+
479+
if let Some(ty::InstanceDef::DropGlue(_, None)) = def {
480+
// Empty drop glue; a no-op.
481+
let &(_, target) = destination.as_ref().unwrap();
482+
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
483+
helper.funclet_br(self, &mut bx, target);
484+
return;
485+
}
486+
487+
// FIXME(eddyb) avoid computing this if possible, when `instance` is
488+
// available - right now `sig` is only needed for getthing the `abi`
489+
// and figuring out how many extra args were passed to a C-variadic `fn`.
477490
let sig = callee.layout.ty.fn_sig(bx.tcx());
478491
let sig = bx.tcx().normalize_erasing_late_bound_regions(
479492
ty::ParamEnv::reveal_all(),
@@ -514,18 +527,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
514527
self.monomorphize(&op_ty)
515528
}).collect::<Vec<_>>();
516529

517-
let fn_abi = match def {
518-
Some(ty::InstanceDef::Virtual(..)) => {
519-
FnAbi::new_vtable(&bx, sig, &extra_args)
520-
}
521-
Some(ty::InstanceDef::DropGlue(_, None)) => {
522-
// Empty drop glue; a no-op.
523-
let &(_, target) = destination.as_ref().unwrap();
524-
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
525-
helper.funclet_br(self, &mut bx, target);
526-
return;
527-
}
528-
_ => FnAbi::new(&bx, sig, &extra_args)
530+
let fn_abi = match instance {
531+
Some(instance) => FnAbi::of_instance(&bx, instance, &extra_args),
532+
None => FnAbi::new(&bx, sig, &extra_args)
529533
};
530534

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

547551
if let Some((_, target)) = destination.as_ref() {

src/librustc_codegen_ssa/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
127127

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

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

133133
let debug_context = {

0 commit comments

Comments
 (0)