Implementing suggestions from @nikomatsakis
This commit is contained in:
parent
a85993ff69
commit
b7f71e1ee6
6 changed files with 101 additions and 100 deletions
|
|
@ -1593,7 +1593,7 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
|
|||
impl_id: Option<ast::def_id>,
|
||||
param_substs: Option<@param_substs>,
|
||||
sp: Option<span>)
|
||||
-> (fn_ctxt, bool) {
|
||||
-> fn_ctxt {
|
||||
for param_substs.each |p| { p.validate(); }
|
||||
|
||||
debug!("new_fn_ctxt_w_id(path=%s, id=%?, impl_id=%?, \
|
||||
|
|
@ -1611,12 +1611,11 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
|
|||
ty::subst_tps(ccx.tcx, substs.tys, substs.self_ty, output_type)
|
||||
}
|
||||
};
|
||||
let imm = ty::type_is_immediate(substd_output_type);
|
||||
|
||||
let is_immediate = ty::type_is_immediate(substd_output_type);
|
||||
let fcx = @mut fn_ctxt_ {
|
||||
llfn: llfndecl,
|
||||
llenv: unsafe {
|
||||
llvm::LLVMGetParam(llfndecl, arg_env(imm) as c_uint)
|
||||
llvm::LLVMGetUndef(T_ptr(T_i8()))
|
||||
},
|
||||
llretptr: None,
|
||||
llstaticallocas: llbbs.sa,
|
||||
|
|
@ -1625,7 +1624,7 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
|
|||
llself: None,
|
||||
personality: None,
|
||||
loop_ret: None,
|
||||
has_immediate_return_value: imm,
|
||||
has_immediate_return_value: is_immediate,
|
||||
llargs: @mut HashMap::new(),
|
||||
lllocals: @mut HashMap::new(),
|
||||
llupvars: @mut HashMap::new(),
|
||||
|
|
@ -1636,9 +1635,11 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
|
|||
path: path,
|
||||
ccx: @ccx
|
||||
};
|
||||
|
||||
fcx.llenv = unsafe {
|
||||
llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
|
||||
};
|
||||
fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
|
||||
(fcx, imm)
|
||||
fcx
|
||||
}
|
||||
|
||||
pub fn new_fn_ctxt(ccx: @CrateContext,
|
||||
|
|
@ -1646,7 +1647,7 @@ pub fn new_fn_ctxt(ccx: @CrateContext,
|
|||
llfndecl: ValueRef,
|
||||
output_type: ty::t,
|
||||
sp: Option<span>)
|
||||
-> (fn_ctxt, bool) {
|
||||
-> fn_ctxt {
|
||||
new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, None, None, sp)
|
||||
}
|
||||
|
||||
|
|
@ -1666,8 +1667,7 @@ pub fn new_fn_ctxt(ccx: @CrateContext,
|
|||
// field of the fn_ctxt with
|
||||
pub fn create_llargs_for_fn_args(cx: fn_ctxt,
|
||||
self_arg: self_arg,
|
||||
args: &[ast::arg],
|
||||
ret_imm: bool)
|
||||
args: &[ast::arg])
|
||||
-> ~[ValueRef] {
|
||||
let _icx = cx.insn_ctxt("create_llargs_for_fn_args");
|
||||
|
||||
|
|
@ -1693,7 +1693,7 @@ pub fn create_llargs_for_fn_args(cx: fn_ctxt,
|
|||
// llvm::LLVMGetParam for each argument.
|
||||
vec::from_fn(args.len(), |i| {
|
||||
unsafe {
|
||||
let arg_n = arg_pos(ret_imm, i);
|
||||
let arg_n = cx.arg_pos(i);
|
||||
let arg = &args[i];
|
||||
let llarg = llvm::LLVMGetParam(cx.llfn, arg_n as c_uint);
|
||||
|
||||
|
|
@ -1832,15 +1832,15 @@ pub fn trans_closure(ccx: @CrateContext,
|
|||
param_substs.repr(ccx.tcx));
|
||||
|
||||
// Set up arguments to the function.
|
||||
let (fcx, imm) = new_fn_ctxt_w_id(ccx,
|
||||
path,
|
||||
llfndecl,
|
||||
id,
|
||||
output_type,
|
||||
impl_id,
|
||||
param_substs,
|
||||
Some(body.span));
|
||||
let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs, imm);
|
||||
let fcx = new_fn_ctxt_w_id(ccx,
|
||||
path,
|
||||
llfndecl,
|
||||
id,
|
||||
output_type,
|
||||
impl_id,
|
||||
param_substs,
|
||||
Some(body.span));
|
||||
let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs);
|
||||
|
||||
// Set the fixed stack segment flag if necessary.
|
||||
if attr::attrs_contains_name(attributes, "fixed_stack_segment") {
|
||||
|
|
@ -1965,16 +1965,16 @@ pub fn trans_enum_variant(ccx: @CrateContext,
|
|||
ty_param_substs,
|
||||
None,
|
||||
ty::node_id_to_type(ccx.tcx, enum_id));
|
||||
let (fcx, imm) = new_fn_ctxt_w_id(ccx,
|
||||
~[],
|
||||
llfndecl,
|
||||
variant.node.id,
|
||||
enum_ty,
|
||||
None,
|
||||
param_substs,
|
||||
None);
|
||||
let fcx = new_fn_ctxt_w_id(ccx,
|
||||
~[],
|
||||
llfndecl,
|
||||
variant.node.id,
|
||||
enum_ty,
|
||||
None,
|
||||
param_substs,
|
||||
None);
|
||||
|
||||
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args, imm);
|
||||
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
|
||||
let bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
|
||||
let arg_tys = ty::ty_fn_args(node_id_type(bcx, variant.node.id));
|
||||
let bcx = copy_args_to_allocas(fcx, bcx, fn_args, raw_llargs, arg_tys);
|
||||
|
|
@ -2044,16 +2044,16 @@ pub fn trans_tuple_struct(ccx: @CrateContext,
|
|||
ty_to_str(ccx.tcx, ctor_ty)))
|
||||
};
|
||||
|
||||
let (fcx, imm) = new_fn_ctxt_w_id(ccx,
|
||||
~[],
|
||||
llfndecl,
|
||||
ctor_id,
|
||||
tup_ty,
|
||||
None,
|
||||
param_substs,
|
||||
None);
|
||||
let fcx = new_fn_ctxt_w_id(ccx,
|
||||
~[],
|
||||
llfndecl,
|
||||
ctor_id,
|
||||
tup_ty,
|
||||
None,
|
||||
param_substs,
|
||||
None);
|
||||
|
||||
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args, imm);
|
||||
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
|
||||
|
||||
let bcx = top_scope_block(fcx, None);
|
||||
let lltop = bcx.llbb;
|
||||
|
|
@ -2301,14 +2301,19 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
|
|||
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
|
||||
lib::llvm::CCallConv, llfty);
|
||||
|
||||
let (fcx, _) = new_fn_ctxt(ccx, ~[], llfdecl, nt, None);
|
||||
let fcx = new_fn_ctxt(ccx, ~[], llfdecl, nt, None);
|
||||
|
||||
// the args vector built in create_entry_fn will need
|
||||
// be updated if this assertion starts to fail.
|
||||
assert!(fcx.has_immediate_return_value);
|
||||
|
||||
let bcx = top_scope_block(fcx, None);
|
||||
let lltop = bcx.llbb;
|
||||
|
||||
// Call main.
|
||||
let llenvarg = unsafe {
|
||||
llvm::LLVMGetParam(llfdecl, arg_env(true) as c_uint)
|
||||
let env_arg = fcx.env_arg_pos();
|
||||
llvm::LLVMGetParam(llfdecl, env_arg as c_uint)
|
||||
};
|
||||
let args = ~[llenvarg];
|
||||
let llresult = Call(bcx, main_llfn, args);
|
||||
|
|
|
|||
|
|
@ -132,8 +132,7 @@ pub impl FnType {
|
|||
bcx: block,
|
||||
ret_ty: TypeRef,
|
||||
llwrapfn: ValueRef,
|
||||
llargbundle: ValueRef,
|
||||
ret_imm: bool) {
|
||||
llargbundle: ValueRef) {
|
||||
let mut atys = /*bad*/copy self.arg_tys;
|
||||
let mut attrs = /*bad*/copy self.attrs;
|
||||
let mut j = 0u;
|
||||
|
|
|
|||
|
|
@ -351,6 +351,30 @@ pub struct fn_ctxt_ {
|
|||
ccx: @@CrateContext
|
||||
}
|
||||
|
||||
pub impl fn_ctxt_ {
|
||||
pub fn arg_pos(&self, arg: uint) -> uint {
|
||||
if self.has_immediate_return_value {
|
||||
arg + 1u
|
||||
} else {
|
||||
arg + 2u
|
||||
}
|
||||
}
|
||||
|
||||
pub fn out_arg_pos(&self) -> uint {
|
||||
assert!(self.has_immediate_return_value);
|
||||
0u
|
||||
}
|
||||
|
||||
pub fn env_arg_pos(&self) -> uint {
|
||||
if !self.has_immediate_return_value {
|
||||
1u
|
||||
} else {
|
||||
0u
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub type fn_ctxt = @mut fn_ctxt_;
|
||||
|
||||
pub fn warn_not_to_commit(ccx: @CrateContext, msg: &str) {
|
||||
|
|
@ -660,27 +684,6 @@ pub fn mk_block(llbb: BasicBlockRef, parent: Option<block>, kind: block_kind,
|
|||
@mut block_(llbb, parent, kind, is_lpad, node_info, fcx)
|
||||
}
|
||||
|
||||
pub fn arg_pos(ret_imm: bool, arg: uint) -> uint {
|
||||
if ret_imm {
|
||||
arg + 1u
|
||||
} else {
|
||||
arg + 2u
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arg_out(ret_imm: bool) -> uint {
|
||||
assert!(ret_imm);
|
||||
0u
|
||||
}
|
||||
|
||||
pub fn arg_env(ret_imm: bool) -> uint {
|
||||
if !ret_imm {
|
||||
1u
|
||||
} else {
|
||||
0u
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Result {
|
||||
bcx: block,
|
||||
val: ValueRef
|
||||
|
|
|
|||
|
|
@ -150,14 +150,10 @@ fn build_shim_fn_(ccx: @CrateContext,
|
|||
ccx.llmod, shim_name, tys.shim_fn_ty);
|
||||
|
||||
// Declare the body of the shim function:
|
||||
let (fcx, imm) = new_fn_ctxt(ccx, ~[], llshimfn, tys.fn_sig.output, None);
|
||||
let fcx = new_fn_ctxt(ccx, ~[], llshimfn, tys.fn_sig.output, None);
|
||||
let bcx = top_scope_block(fcx, None);
|
||||
let lltop = bcx.llbb;
|
||||
|
||||
//
|
||||
// FIXME [#6575] this seems to be making the assumption that the first
|
||||
// implicit argument is always available?
|
||||
//
|
||||
let llargbundle = get_param(llshimfn, 0u);
|
||||
let llargvals = arg_builder(bcx, tys, llargbundle);
|
||||
|
||||
|
|
@ -179,8 +175,7 @@ fn build_shim_fn_(ccx: @CrateContext,
|
|||
type wrap_arg_builder<'self> = &'self fn(bcx: block,
|
||||
tys: &ShimTypes,
|
||||
llwrapfn: ValueRef,
|
||||
llargbundle: ValueRef,
|
||||
ret_imm: bool);
|
||||
llargbundle: ValueRef);
|
||||
|
||||
type wrap_ret_builder<'self> = &'self fn(bcx: block,
|
||||
tys: &ShimTypes,
|
||||
|
|
@ -195,7 +190,7 @@ fn build_wrap_fn_(ccx: @CrateContext,
|
|||
arg_builder: wrap_arg_builder,
|
||||
ret_builder: wrap_ret_builder) {
|
||||
let _icx = ccx.insn_ctxt("foreign::build_wrap_fn_");
|
||||
let (fcx, imm) = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None);
|
||||
let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None);
|
||||
|
||||
// Patch up the return type if it's not immediate and we're returning via
|
||||
// the C ABI.
|
||||
|
|
@ -210,7 +205,7 @@ fn build_wrap_fn_(ccx: @CrateContext,
|
|||
|
||||
// Allocate the struct and write the arguments into it.
|
||||
let llargbundle = alloca(bcx, tys.bundle_ty);
|
||||
arg_builder(bcx, tys, llwrapfn, llargbundle, imm);
|
||||
arg_builder(bcx, tys, llwrapfn, llargbundle);
|
||||
|
||||
// Create call itself.
|
||||
let llshimfnptr = PointerCast(bcx, llshimfn, T_ptr(T_i8()));
|
||||
|
|
@ -438,14 +433,14 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
|
|||
cc: lib::llvm::CallConv) {
|
||||
debug!("build_direct_fn(%s)", *link_name(ccx, item));
|
||||
|
||||
let (fcx, imm) = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
|
||||
let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
|
||||
let bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
|
||||
let llbasefn = base_fn(ccx, *link_name(ccx, item), tys, cc);
|
||||
let ty = ty::lookup_item_type(ccx.tcx,
|
||||
ast_util::local_def(item.id)).ty;
|
||||
let ret_ty = ty::ty_fn_ret(ty);
|
||||
let args = vec::from_fn(ty::ty_fn_args(ty).len(), |i| {
|
||||
get_param(decl, arg_pos(imm, i))
|
||||
get_param(decl, fcx.arg_pos(i))
|
||||
});
|
||||
let retval = Call(bcx, llbasefn, args);
|
||||
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
|
||||
|
|
@ -464,7 +459,7 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
|
|||
cc: lib::llvm::CallConv) {
|
||||
debug!("build_fast_ffi_fn(%s)", *link_name(ccx, item));
|
||||
|
||||
let (fcx, imm) = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
|
||||
let fcx = new_fn_ctxt(ccx, ~[], decl, tys.fn_sig.output, None);
|
||||
let bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
|
||||
let llbasefn = base_fn(ccx, *link_name(ccx, item), tys, cc);
|
||||
set_no_inline(fcx.llfn);
|
||||
|
|
@ -473,7 +468,7 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
|
|||
ast_util::local_def(item.id)).ty;
|
||||
let ret_ty = ty::ty_fn_ret(ty);
|
||||
let args = vec::from_fn(ty::ty_fn_args(ty).len(), |i| {
|
||||
get_param(decl, arg_pos(imm, i))
|
||||
get_param(decl, fcx.arg_pos(i))
|
||||
});
|
||||
let retval = Call(bcx, llbasefn, args);
|
||||
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
|
||||
|
|
@ -514,13 +509,13 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
|
|||
fn build_args(bcx: block,
|
||||
tys: &ShimTypes,
|
||||
llwrapfn: ValueRef,
|
||||
llargbundle: ValueRef,
|
||||
ret_imm: bool) {
|
||||
llargbundle: ValueRef) {
|
||||
let _icx = bcx.insn_ctxt("foreign::wrap::build_args");
|
||||
let ccx = bcx.ccx();
|
||||
let n = tys.llsig.llarg_tys.len();
|
||||
for uint::range(0, n) |i| {
|
||||
let mut llargval = get_param(llwrapfn, arg_pos(ret_imm, i));
|
||||
let arg_i = bcx.fcx.arg_pos(i);
|
||||
let mut llargval = get_param(llwrapfn, arg_i);
|
||||
|
||||
// In some cases, Rust will pass a pointer which the
|
||||
// native C type doesn't have. In that case, just
|
||||
|
|
@ -558,14 +553,14 @@ pub fn trans_intrinsic(ccx: @CrateContext,
|
|||
|
||||
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id));
|
||||
|
||||
let (fcx, imm) = new_fn_ctxt_w_id(ccx,
|
||||
path,
|
||||
decl,
|
||||
item.id,
|
||||
output_type,
|
||||
None,
|
||||
Some(substs),
|
||||
Some(item.span));
|
||||
let fcx = new_fn_ctxt_w_id(ccx,
|
||||
path,
|
||||
decl,
|
||||
item.id,
|
||||
output_type,
|
||||
None,
|
||||
Some(substs),
|
||||
Some(item.span));
|
||||
|
||||
// Set the fixed stack segment flag if necessary.
|
||||
if attr::attrs_contains_name(attributes, "fixed_stack_segment") {
|
||||
|
|
@ -574,7 +569,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
|
|||
|
||||
let mut bcx = top_scope_block(fcx, None);
|
||||
let lltop = bcx.llbb;
|
||||
let first_real_arg = arg_pos(imm, 0u);
|
||||
let first_real_arg = fcx.arg_pos(0u);
|
||||
match *ccx.sess.str_of(item.ident) {
|
||||
~"atomic_cxchg" => {
|
||||
let old = AtomicCmpXchg(bcx,
|
||||
|
|
@ -1356,14 +1351,12 @@ pub fn trans_foreign_fn(ccx: @CrateContext,
|
|||
fn build_args(bcx: block,
|
||||
tys: &ShimTypes,
|
||||
llwrapfn: ValueRef,
|
||||
llargbundle: ValueRef,
|
||||
ret_imm: bool) {
|
||||
llargbundle: ValueRef) {
|
||||
let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_args");
|
||||
tys.fn_ty.build_wrap_args(bcx,
|
||||
tys.llsig.llret_ty,
|
||||
llwrapfn,
|
||||
llargbundle,
|
||||
ret_imm);
|
||||
llargbundle);
|
||||
}
|
||||
|
||||
fn build_ret(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) {
|
||||
|
|
|
|||
|
|
@ -727,7 +727,7 @@ pub fn make_generic_glue_inner(ccx: @CrateContext,
|
|||
helper: glue_helper)
|
||||
-> ValueRef {
|
||||
let _icx = ccx.insn_ctxt("make_generic_glue_inner");
|
||||
let (fcx, imm) = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None);
|
||||
let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None);
|
||||
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
|
||||
ccx.stats.n_glues_created += 1u;
|
||||
// All glue functions take values passed *by alias*; this is a
|
||||
|
|
@ -740,7 +740,8 @@ pub fn make_generic_glue_inner(ccx: @CrateContext,
|
|||
|
||||
let bcx = top_scope_block(fcx, None);
|
||||
let lltop = bcx.llbb;
|
||||
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, arg_pos(true, 1u) as c_uint) };
|
||||
let rawptr0_arg = fcx.arg_pos(1u);
|
||||
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
|
||||
helper(bcx, llrawptr0, t);
|
||||
finish_fn(fcx, lltop);
|
||||
return llfn;
|
||||
|
|
|
|||
|
|
@ -286,19 +286,19 @@ pub impl Reflector {
|
|||
|
||||
let llfty = type_of_fn(ccx, [opaqueptrty], ty::mk_int());
|
||||
let llfdecl = decl_internal_cdecl_fn(ccx.llmod, sym, llfty);
|
||||
let fcx = new_fn_ctxt(ccx,
|
||||
~[],
|
||||
llfdecl,
|
||||
ty::mk_uint(),
|
||||
None);
|
||||
let arg = unsafe {
|
||||
//
|
||||
// we know the return type of llfdecl is an int here, so
|
||||
// no need for a special check to see if the return type
|
||||
// is immediate.
|
||||
//
|
||||
llvm::LLVMGetParam(llfdecl, arg_pos(true, 0u) as c_uint)
|
||||
llvm::LLVMGetParam(llfdecl, fcx.arg_pos(0u) as c_uint)
|
||||
};
|
||||
let (fcx, _) = new_fn_ctxt(ccx,
|
||||
~[],
|
||||
llfdecl,
|
||||
ty::mk_uint(),
|
||||
None);
|
||||
let bcx = top_scope_block(fcx, None);
|
||||
let arg = BitCast(bcx, arg, llptrty);
|
||||
let ret = adt::trans_get_discr(bcx, repr, arg);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue