Refactor Callee::call to take bcx by-reference.
Also change to not return anything; nothing used the return ValueRef. Inlines with_cond.
This commit is contained in:
parent
9a198534e2
commit
937001a1f8
4 changed files with 46 additions and 75 deletions
|
@ -480,24 +480,6 @@ pub fn to_immediate(bcx: &BlockAndBuilder, val: ValueRef, ty: Ty) -> ValueRef {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn with_cond<'blk, 'tcx, F>(
|
||||
bcx: BlockAndBuilder<'blk, 'tcx>, val: ValueRef, f: F
|
||||
) -> BlockAndBuilder<'blk, 'tcx>
|
||||
where F: FnOnce(BlockAndBuilder<'blk, 'tcx>) -> BlockAndBuilder<'blk, 'tcx>
|
||||
{
|
||||
if common::const_to_opt_uint(val) == Some(0) {
|
||||
return bcx;
|
||||
}
|
||||
|
||||
let fcx = bcx.fcx();
|
||||
let next_cx = fcx.build_new_block("next");
|
||||
let cond_cx = fcx.build_new_block("cond");
|
||||
bcx.cond_br(val, cond_cx.llbb(), next_cx.llbb());
|
||||
let after_cx = f(cond_cx);
|
||||
after_cx.br(next_cx.llbb());
|
||||
next_cx
|
||||
}
|
||||
|
||||
pub enum Lifetime { Start, End }
|
||||
|
||||
impl Lifetime {
|
||||
|
|
|
@ -189,11 +189,10 @@ impl<'tcx> Callee<'tcx> {
|
|||
/// For non-lang items, `dest` is always Some, and hence the result is written
|
||||
/// into memory somewhere. Nonetheless we return the actual return value of the
|
||||
/// function.
|
||||
pub fn call<'a, 'blk>(self, bcx: BlockAndBuilder<'blk, 'tcx>,
|
||||
pub fn call<'a, 'blk>(self, bcx: &BlockAndBuilder<'blk, 'tcx>,
|
||||
args: &[ValueRef],
|
||||
dest: Option<ValueRef>,
|
||||
lpad: Option<&'blk llvm::OperandBundleDef>)
|
||||
-> (BlockAndBuilder<'blk, 'tcx>, ValueRef) {
|
||||
lpad: Option<&'blk llvm::OperandBundleDef>) {
|
||||
trans_call_inner(bcx, self, args, dest, lpad)
|
||||
}
|
||||
|
||||
|
@ -538,7 +537,7 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
|
|||
data: Fn(llfnpointer),
|
||||
ty: bare_fn_ty
|
||||
};
|
||||
let bcx = callee.call(bcx, &llargs[(self_idx + 1)..], fcx.llretslotptr, None).0;
|
||||
callee.call(&bcx, &llargs[(self_idx + 1)..], fcx.llretslotptr, None);
|
||||
fcx.finish(&bcx);
|
||||
|
||||
ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty_maybe_ref, llfn);
|
||||
|
@ -648,12 +647,11 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
// ______________________________________________________________________
|
||||
// Translating calls
|
||||
|
||||
fn trans_call_inner<'a, 'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
|
||||
fn trans_call_inner<'a, 'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
|
||||
callee: Callee<'tcx>,
|
||||
args: &[ValueRef],
|
||||
opt_llretslot: Option<ValueRef>,
|
||||
lpad: Option<&'blk llvm::OperandBundleDef>)
|
||||
-> (BlockAndBuilder<'blk, 'tcx>, ValueRef) {
|
||||
dest: Option<ValueRef>,
|
||||
lpad: Option<&'blk llvm::OperandBundleDef>) {
|
||||
// Introduce a temporary cleanup scope that will contain cleanups
|
||||
// for the arguments while they are being evaluated. The purpose
|
||||
// this cleanup is to ensure that, should a panic occur while
|
||||
|
@ -661,61 +659,52 @@ fn trans_call_inner<'a, 'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
|
|||
// cleaned up. If no panic occurs, the values are handed off to
|
||||
// the callee, and hence none of the cleanups in this temporary
|
||||
// scope will ever execute.
|
||||
let fcx = &bcx.fcx();
|
||||
let ccx = fcx.ccx;
|
||||
|
||||
let ccx = bcx.ccx();
|
||||
let fn_ret = callee.ty.fn_ret();
|
||||
let fn_ty = callee.direct_fn_type(ccx, &[]);
|
||||
|
||||
let mut callee = match callee.data {
|
||||
NamedTupleConstructor(_) | Intrinsic => {
|
||||
bug!("{:?} calls should not go through Callee::call", callee);
|
||||
}
|
||||
f => f
|
||||
};
|
||||
|
||||
// If there no destination, return must be direct, with no cast.
|
||||
if opt_llretslot.is_none() {
|
||||
if dest.is_none() {
|
||||
assert!(!fn_ty.ret.is_indirect() && fn_ty.ret.cast.is_none());
|
||||
}
|
||||
|
||||
let mut llargs = Vec::new();
|
||||
|
||||
if fn_ty.ret.is_indirect() {
|
||||
let mut llretslot = opt_llretslot.unwrap();
|
||||
if let Some(ty) = fn_ty.ret.cast {
|
||||
llretslot = bcx.pointercast(llretslot, ty.ptr_to());
|
||||
}
|
||||
let dest = dest.unwrap();
|
||||
let llretslot = if let Some(ty) = fn_ty.ret.cast {
|
||||
bcx.pointercast(dest, ty.ptr_to())
|
||||
} else {
|
||||
dest
|
||||
};
|
||||
llargs.push(llretslot);
|
||||
}
|
||||
|
||||
match callee {
|
||||
let llfn = match callee.data {
|
||||
NamedTupleConstructor(_) | Intrinsic => {
|
||||
bug!("{:?} calls should not go through Callee::call", callee);
|
||||
}
|
||||
Virtual(idx) => {
|
||||
llargs.push(args[0]);
|
||||
|
||||
let fn_ptr = meth::get_virtual_method(&bcx, args[1], idx);
|
||||
let llty = fn_ty.llvm_type(&bcx.ccx()).ptr_to();
|
||||
callee = Fn(bcx.pointercast(fn_ptr, llty));
|
||||
llargs.extend_from_slice(&args[2..]);
|
||||
bcx.pointercast(fn_ptr, llty)
|
||||
}
|
||||
Fn(f) => {
|
||||
llargs.extend_from_slice(args);
|
||||
f
|
||||
}
|
||||
_ => llargs.extend_from_slice(args)
|
||||
}
|
||||
|
||||
let llfn = match callee {
|
||||
Fn(f) => f,
|
||||
_ => bug!("expected fn pointer callee, found {:?}", callee)
|
||||
};
|
||||
|
||||
let llret = bcx.call(llfn, &llargs[..], lpad);
|
||||
fn_ty.apply_attrs_callsite(llret);
|
||||
|
||||
// If the function we just called does not use an outpointer,
|
||||
// store the result into the rust outpointer. Cast the outpointer
|
||||
// type to match because some ABIs will use a different type than
|
||||
// the Rust type. e.g., a {u32,u32} struct could be returned as
|
||||
// u64.
|
||||
// store the result into the Rust outpointer.
|
||||
if !fn_ty.ret.is_indirect() {
|
||||
if let Some(llretslot) = opt_llretslot {
|
||||
if let Some(llretslot) = dest {
|
||||
fn_ty.ret.store(&bcx, llret, llretslot);
|
||||
}
|
||||
}
|
||||
|
@ -723,6 +712,4 @@ fn trans_call_inner<'a, 'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
|
|||
if fn_ret.0.is_never() {
|
||||
bcx.unreachable();
|
||||
}
|
||||
|
||||
(bcx, llret)
|
||||
}
|
||||
|
|
|
@ -35,21 +35,18 @@ use Disr;
|
|||
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
pub fn trans_exchange_free_dyn<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
|
||||
pub fn trans_exchange_free_dyn<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
|
||||
v: ValueRef,
|
||||
size: ValueRef,
|
||||
align: ValueRef)
|
||||
-> BlockAndBuilder<'blk, 'tcx> {
|
||||
align: ValueRef) {
|
||||
let def_id = langcall(bcx.tcx(), None, "", ExchangeFreeFnLangItem);
|
||||
let args = [bcx.pointercast(v, Type::i8p(bcx.ccx())), size, align];
|
||||
Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[]))
|
||||
.call(bcx, &args, None, None).0
|
||||
Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[])).call(&bcx, &args, None, None)
|
||||
}
|
||||
|
||||
pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
|
||||
pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
|
||||
ptr: ValueRef,
|
||||
content_ty: Ty<'tcx>)
|
||||
-> BlockAndBuilder<'blk, 'tcx> {
|
||||
content_ty: Ty<'tcx>) {
|
||||
assert!(type_is_sized(bcx.ccx().tcx(), content_ty));
|
||||
let sizing_type = sizing_type_of(bcx.ccx(), content_ty);
|
||||
let content_size = llsize_of_alloc(bcx.ccx(), sizing_type);
|
||||
|
@ -58,9 +55,7 @@ pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
|
|||
if content_size != 0 {
|
||||
let content_align = align_of(bcx.ccx(), content_ty);
|
||||
let ccx = bcx.ccx();
|
||||
trans_exchange_free_dyn(bcx, ptr, C_uint(ccx, content_size), C_uint(ccx, content_align))
|
||||
} else {
|
||||
bcx
|
||||
trans_exchange_free_dyn(bcx, ptr, C_uint(ccx, content_size), C_uint(ccx, content_align));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,14 +405,23 @@ fn make_drop_glue<'blk, 'tcx>(bcx: BlockAndBuilder<'blk, 'tcx>,
|
|||
llsize,
|
||||
C_uint(bcx.ccx(), 0u64),
|
||||
);
|
||||
with_cond(bcx, needs_free, |bcx| {
|
||||
trans_exchange_free_dyn(bcx, llbox, llsize, llalign)
|
||||
})
|
||||
if const_to_opt_uint(needs_free) == Some(0) {
|
||||
bcx
|
||||
} else {
|
||||
let fcx = bcx.fcx();
|
||||
let next_cx = fcx.build_new_block("next");
|
||||
let cond_cx = fcx.build_new_block("cond");
|
||||
bcx.cond_br(needs_free, cond_cx.llbb(), next_cx.llbb());
|
||||
trans_exchange_free_dyn(&cond_cx, llbox, llsize, llalign);
|
||||
cond_cx.br(next_cx.llbb());
|
||||
next_cx
|
||||
}
|
||||
} else {
|
||||
let llval = v0;
|
||||
let llbox = bcx.load(llval);
|
||||
drop_ty(&bcx, llbox, content_ty);
|
||||
trans_exchange_free_ty(bcx, llbox, content_ty)
|
||||
trans_exchange_free_ty(&bcx, llbox, content_ty);
|
||||
bcx
|
||||
}
|
||||
}
|
||||
ty::TyDynamic(..) => {
|
||||
|
|
|
@ -82,12 +82,10 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
|
|||
attributes::set_frame_pointer_elimination(ccx, llfn);
|
||||
|
||||
let fcx = FunctionContext::new(ccx, llfn, fn_ty, None, false);
|
||||
let mut bcx = fcx.get_entry_block();
|
||||
let bcx = fcx.get_entry_block();
|
||||
|
||||
let llargs = get_params(fcx.llfn);
|
||||
bcx = callee.call(bcx, &llargs[fcx.fn_ty.ret.is_indirect() as usize..], fcx.llretslotptr,
|
||||
None).0;
|
||||
|
||||
callee.call(&bcx, &llargs[fcx.fn_ty.ret.is_indirect() as usize..], fcx.llretslotptr, None);
|
||||
fcx.finish(&bcx);
|
||||
|
||||
llfn
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue