Skip to content

Commit

Permalink
librustc: Mark unboxed closure calls and definitions with appropriate…
Browse files Browse the repository at this point in the history
… llvm return/argument attributes.
  • Loading branch information
luqmana committed Aug 21, 2014
1 parent 4444aec commit 171c542
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2240,26 +2240,44 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
ty::ty_bare_fn(ref f) => (f.sig.clone(), f.abi, false),
ty::ty_unboxed_closure(closure_did, _) => {
let unboxed_closures = ccx.tcx.unboxed_closures.borrow();
let function_type = unboxed_closures.get(&closure_did)
.closure_type
.clone();
let ref function_type = unboxed_closures.get(&closure_did)
.closure_type;

(function_type.sig.clone(), RustCall, true)
}
_ => fail!("expected closure or function.")
_ => ccx.sess().bug("expected closure or function.")
};


// Since index 0 is the return value of the llvm func, we start
// at either 1 or 2 depending on whether there's an env slot or not
let mut first_arg_offset = if has_env { 2 } else { 1 };
let mut attrs = llvm::AttrBuilder::new();
let ret_ty = fn_sig.output;

// These have an odd calling convention, so we skip them for now.
//
// FIXME(pcwalton): We don't have to skip them; just untuple the result.
if abi == RustCall {
return attrs;
}
// These have an odd calling convention, so we need to manually
// unpack the input ty's
let input_tys = match ty::get(fn_ty).sty {
ty::ty_unboxed_closure(_, _) => {
assert!(abi == RustCall);

match ty::get(fn_sig.inputs[0]).sty {
ty::ty_nil => Vec::new(),
ty::ty_tup(ref inputs) => inputs.clone(),
_ => ccx.sess().bug("expected tuple'd inputs")
}
},
ty::ty_bare_fn(_) if abi == RustCall => {
let inputs = vec![fn_sig.inputs[0]];

match ty::get(fn_sig.inputs[1]).sty {
ty::ty_nil => inputs,
ty::ty_tup(ref t_in) => inputs.append(t_in.as_slice()),
_ => ccx.sess().bug("expected tuple'd inputs")
}
}
_ => fn_sig.inputs.clone()
};

// A function pointer is called without the declaration
// available, so we have to apply any attributes with ABI
Expand Down Expand Up @@ -2315,7 +2333,7 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
}
}

for (idx, &t) in fn_sig.inputs.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
for (idx, &t) in input_tys.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
match ty::get(t).sty {
// this needs to be first to prevent fat pointers from falling through
_ if !type_is_immediate(ccx, t) => {
Expand Down

0 comments on commit 171c542

Please sign in to comment.