Simplify argument forwarding in the various shim generators

This commit is contained in:
Björn Steinbrink 2015-06-18 20:07:36 +02:00
parent f862da5bb8
commit dea5a9608c
4 changed files with 28 additions and 62 deletions

View File

@ -2252,6 +2252,18 @@ pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef {
}
}
pub fn get_params(llfn: ValueRef) -> Vec<ValueRef> {
unsafe {
let num_params = LLVMCountParams(llfn);
let mut params = Vec::with_capacity(num_params as usize);
for idx in 0..num_params {
params.push(LLVMGetParam(llfn, idx));
}
params
}
}
#[allow(missing_copy_implementations)]
pub enum RustString_opaque {}
pub type RustStringRef = *mut RustString_opaque;

View File

@ -21,9 +21,7 @@ pub use self::CallArgs::*;
use arena::TypedArena;
use back::link;
use session;
use llvm::ValueRef;
use llvm::get_param;
use llvm;
use llvm::{self, ValueRef, get_params};
use metadata::csearch;
use middle::def;
use middle::subst;
@ -343,19 +341,15 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
&block_arena);
let mut bcx = init_function(&fcx, false, sig.output);
let llargs = get_params(fcx.llfn);
// the first argument (`self`) will be ptr to the the fn pointer
let llfnpointer = if is_by_ref {
Load(bcx, get_param(fcx.llfn, fcx.arg_pos(0) as u32))
Load(bcx, llargs[fcx.arg_pos(0)])
} else {
get_param(fcx.llfn, fcx.arg_pos(0) as u32)
llargs[fcx.arg_pos(0)]
};
// the remaining arguments will be the untupled values
let llargs: Vec<_> =
sig.inputs.iter()
.enumerate()
.map(|(i, _)| get_param(fcx.llfn, fcx.arg_pos(i+1) as u32))
.collect();
assert!(!fcx.needs_ret_allocas);
let dest = fcx.llretslotptr.get().map(|_|
@ -366,7 +360,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
DebugLoc::None,
bare_fn_ty,
|bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) },
ArgVals(&llargs[..]),
ArgVals(&llargs[fcx.arg_pos(1)..]),
dest).bcx;
finish_fn(&fcx, bcx, sig.output, DebugLoc::None);

View File

@ -10,7 +10,7 @@
use arena::TypedArena;
use back::link::{self, mangle_internal_name_by_path_and_seq};
use llvm::{ValueRef, get_param};
use llvm::{ValueRef, get_params};
use middle::mem_categorization::Typer;
use trans::adt;
use trans::attributes;
@ -405,11 +405,13 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
&block_arena);
let mut bcx = init_function(&fcx, false, sig.output);
let llargs = get_params(fcx.llfn);
// the first argument (`self`) will be the (by value) closure env.
let self_scope = fcx.push_custom_cleanup_scope();
let self_scope_id = CustomScope(self_scope);
let rvalue_mode = datum::appropriate_rvalue_mode(ccx, closure_ty);
let llself = get_param(lloncefn, fcx.arg_pos(0) as u32);
let llself = llargs[fcx.arg_pos(0)];
let env_datum = Datum::new(llself, closure_ty, Rvalue::new(rvalue_mode));
let env_datum = unpack_datum!(bcx,
env_datum.to_lvalue_datum_in_scope(bcx, "self",
@ -418,19 +420,6 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
debug!("trans_fn_once_adapter_shim: env_datum={}",
bcx.val_to_string(env_datum.val));
// the remaining arguments will be packed up in a tuple.
let input_tys = match sig.inputs[1].sty {
ty::TyTuple(ref tys) => &**tys,
_ => bcx.sess().bug(&format!("trans_fn_once_adapter_shim: not rust-call! \
closure_def_id={:?}",
closure_def_id))
};
let llargs: Vec<_> =
input_tys.iter()
.enumerate()
.map(|(i, _)| get_param(lloncefn, fcx.arg_pos(i+1) as u32))
.collect();
let dest =
fcx.llretslotptr.get().map(
|_| expr::SaveIn(fcx.get_ret_slot(bcx, sig.output, "ret_slot")));
@ -442,7 +431,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
DebugLoc::None,
llref_fn_ty,
|bcx, _| Callee { bcx: bcx, data: callee_data },
ArgVals(&llargs),
ArgVals(&llargs[fcx.arg_pos(1)..]),
dest).bcx;
fcx.pop_custom_cleanup_scope(self_scope);

View File

@ -11,7 +11,7 @@
use arena::TypedArena;
use back::abi;
use back::link;
use llvm::{ValueRef, get_param};
use llvm::{ValueRef, get_params};
use metadata::csearch;
use middle::subst::{Subst, Substs};
use middle::subst::VecPerParamSpace;
@ -611,43 +611,14 @@ pub fn trans_object_shim<'a, 'tcx>(
&block_arena);
let mut bcx = init_function(&fcx, false, sig.output);
let llargs = get_params(fcx.llfn);
// the first argument (`self`) will be a trait object
let llobject = get_param(fcx.llfn, fcx.arg_pos(0) as u32);
let llobject = llargs[fcx.arg_pos(0)];
debug!("trans_object_shim: llobject={}",
bcx.val_to_string(llobject));
// the remaining arguments will be, well, whatever they are
let input_tys =
match fty.abi {
RustCall => {
// unpack the tuple to extract the input type arguments:
match sig.inputs[1].sty {
ty::TyTuple(ref tys) => &**tys,
_ => {
bcx.sess().bug(
&format!("rust-call expects a tuple not {:?}",
sig.inputs[1]));
}
}
}
_ => {
// skip the self parameter:
&sig.inputs[1..]
}
};
let llargs: Vec<_> =
input_tys.iter()
.enumerate()
.map(|(i, _)| {
let llarg = get_param(fcx.llfn, fcx.arg_pos(i+1) as u32);
debug!("trans_object_shim: input #{} == {}",
i, bcx.val_to_string(llarg));
llarg
})
.collect();
assert!(!fcx.needs_ret_allocas);
let dest =
@ -669,7 +640,7 @@ pub fn trans_object_shim<'a, 'tcx>(
method_bare_fn_ty,
method_offset_in_vtable,
llobject),
ArgVals(&llargs),
ArgVals(&llargs[fcx.arg_pos(1)..]),
dest).bcx;
finish_fn(&fcx, bcx, sig.output, DebugLoc::None);