@@ -92,12 +92,14 @@ fn type_of_explicit_args(cx: &@crate_ctxt, sp: &span, inputs: &[ty::arg]) ->
92
92
let atys: [ TypeRef ] = [ ] ;
93
93
for arg: ty:: arg in inputs {
94
94
let t: TypeRef = type_of_inner ( cx, sp, arg. ty ) ;
95
- t =
96
- alt arg. mode {
97
- ty:: mo_alias ( _) { T_ptr ( t) }
98
- ty:: mo_move. { T_ptr ( t) }
99
- _ { t }
100
- } ;
95
+ t = alt arg. mode {
96
+ ty:: mo_alias ( _) { T_ptr ( t) }
97
+ ty:: mo_move. { T_ptr ( t) }
98
+ _ {
99
+ if ty:: type_is_structural ( cx. tcx , arg. ty ) { T_ptr ( t) }
100
+ else { t }
101
+ }
102
+ } ;
101
103
atys += [ t] ;
102
104
}
103
105
ret atys;
@@ -4327,7 +4329,9 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
4327
4329
bcx = copy_ty ( bcx, val, e_ty) . bcx ;
4328
4330
} else {
4329
4331
bcx = copy_ty ( bcx, val, e_ty) . bcx ;
4330
- val = bcx. build . Load ( val) ;
4332
+ if !ty:: type_is_structural ( cx. ccx . tcx , e_ty) {
4333
+ val = bcx. build . Load ( val) ;
4334
+ }
4331
4335
}
4332
4336
}
4333
4337
llargs += [ val] ;
@@ -4494,16 +4498,8 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
4494
4498
4495
4499
if !is_bot && ty:: type_contains_params ( ccx. tcx , arg. ty ) {
4496
4500
let lldestty = lldestty0;
4497
- if arg. mode == ty:: mo_val && ty:: type_is_structural ( ccx. tcx , e_ty) {
4498
- lldestty = T_ptr ( lldestty) ;
4499
- }
4500
4501
val = bcx. build . PointerCast ( val, lldestty) ;
4501
4502
}
4502
- if arg. mode == ty:: mo_val && ty:: type_is_structural ( ccx. tcx , e_ty) {
4503
- // Until here we've been treating structures by pointer;
4504
- // we are now passing it as an arg, so need to load it.
4505
- val = bcx. build . Load ( val) ;
4506
- }
4507
4503
4508
4504
// Collect arg for later if it happens to be one we've moving out.
4509
4505
if arg. mode == ty:: mo_move {
@@ -5821,12 +5817,13 @@ fn create_llargs_for_fn_args(cx: &@fn_ctxt, proto: ast::proto,
5821
5817
}
5822
5818
}
5823
5819
5824
- fn copy_args_to_allocas ( fcx : @fn_ctxt , args : & [ ast:: arg ] ) {
5820
+ fn copy_args_to_allocas ( fcx : @fn_ctxt , args : & [ ast:: arg ] ,
5821
+ arg_tys : & [ ty:: arg ] ) {
5825
5822
let bcx = new_raw_block_ctxt ( fcx, fcx. llcopyargs ) ;
5826
5823
let arg_n: uint = 0 u;
5827
5824
for aarg: ast:: arg in args {
5828
5825
if aarg. mode == ast:: val {
5829
- let argval;
5826
+ let argval, arg_ty = arg_tys . ( arg_n ) . ty ;
5830
5827
alt bcx. fcx . llargs . find ( aarg. id ) {
5831
5828
some ( x) { argval = x; }
5832
5829
_ {
@@ -5835,13 +5832,20 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, args: &[ast::arg]) {
5835
5832
"unbound arg ID in copy_args_to_allocas" ) ;
5836
5833
}
5837
5834
}
5838
- let a = do_spill ( bcx, argval) ;
5835
+ let a;
5836
+ if ty:: type_is_structural ( fcx_tcx ( fcx) , arg_ty) {
5837
+ a = alloca ( bcx, llvm:: LLVMGetElementType ( val_ty ( argval) ) ) ;
5838
+ bcx = memmove_ty ( bcx, a, argval, arg_ty) . bcx ;
5839
+ } else {
5840
+ a = do_spill ( bcx, argval) ;
5841
+ }
5839
5842
5840
5843
// Overwrite the llargs entry for this arg with its alloca.
5841
5844
bcx. fcx . llargs . insert ( aarg. id , a) ;
5842
5845
}
5843
5846
arg_n += 1 u;
5844
5847
}
5848
+ fcx. llcopyargs = bcx. llbb ;
5845
5849
}
5846
5850
5847
5851
fn add_cleanups_for_args ( bcx : & @block_ctxt , args : & [ ast:: arg ] ,
@@ -5961,7 +5965,7 @@ fn trans_closure(bcx_maybe: &option::t<@block_ctxt>,
5961
5965
_ { }
5962
5966
}
5963
5967
let arg_tys = arg_tys_of_fn ( fcx. lcx . ccx , id) ;
5964
- copy_args_to_allocas ( fcx, f. decl . inputs ) ;
5968
+ copy_args_to_allocas ( fcx, f. decl . inputs , arg_tys ) ;
5965
5969
5966
5970
// Figure out if we need to build a closure and act accordingly
5967
5971
let res =
@@ -6115,7 +6119,7 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
6115
6119
i += 1 u;
6116
6120
}
6117
6121
let arg_tys = arg_tys_of_fn ( cx. ccx , variant. node . id ) ;
6118
- copy_args_to_allocas ( fcx, fn_args) ;
6122
+ copy_args_to_allocas ( fcx, fn_args, arg_tys ) ;
6119
6123
let bcx = new_top_block_ctxt ( fcx) ;
6120
6124
let lltop = bcx. llbb ;
6121
6125
@@ -6325,30 +6329,20 @@ fn create_main_wrapper(ccx: &@crate_ctxt, sp: &span, main_llfn: ValueRef,
6325
6329
let bcx = new_top_block_ctxt ( fcx) ;
6326
6330
let lltop = bcx. llbb ;
6327
6331
6328
- if takes_ivec {
6329
- let lloutputarg = llvm:: LLVMGetParam ( llfdecl, 0 u) ;
6330
- let lltaskarg = llvm:: LLVMGetParam ( llfdecl, 1 u) ;
6331
- let llenvarg = llvm:: LLVMGetParam ( llfdecl, 2 u) ;
6332
- let llargvarg = llvm:: LLVMGetParam ( llfdecl, 3 u) ;
6333
- let args = [ lloutputarg, lltaskarg, llenvarg, llargvarg] ;
6334
- bcx. build . FastCall ( main_llfn, args) ;
6332
+ let lloutputarg = llvm:: LLVMGetParam ( llfdecl, 0 u) ;
6333
+ let lltaskarg = llvm:: LLVMGetParam ( llfdecl, 1 u) ;
6334
+ let llenvarg = llvm:: LLVMGetParam ( llfdecl, 2 u) ;
6335
+ let llargvarg = llvm:: LLVMGetParam ( llfdecl, 3 u) ;
6336
+ let args = if takes_ivec {
6337
+ ~[ lloutputarg, lltaskarg, llenvarg, llargvarg]
6335
6338
} else {
6336
- let lloutputarg = llvm:: LLVMGetParam ( llfdecl, 0 u) ;
6337
- let lltaskarg = llvm:: LLVMGetParam ( llfdecl, 1 u) ;
6338
- let llenvarg = llvm:: LLVMGetParam ( llfdecl, 2 u) ;
6339
- let llargvarg = llvm:: LLVMGetParam ( llfdecl, 3 u) ;
6340
-
6341
6339
// If the crate's main function doesn't take the args vector then
6342
6340
// we're responsible for freeing it
6343
- let llivecptr = alloca ( bcx, val_ty ( llargvarg) ) ;
6344
- bcx. build . Store ( llargvarg, llivecptr) ;
6345
- bcx =
6346
- maybe_free_ivec_heap_part ( bcx, llivecptr,
6347
- ty:: mk_str ( ccx. tcx ) ) . bcx ;
6348
-
6349
- let args = [ lloutputarg, lltaskarg, llenvarg] ;
6350
- bcx. build . FastCall ( main_llfn, args) ;
6351
- }
6341
+ bcx = maybe_free_ivec_heap_part ( bcx, llargvarg,
6342
+ ty:: mk_str ( ccx. tcx ) ) . bcx ;
6343
+ ~[ lloutputarg, lltaskarg, llenvarg]
6344
+ } ;
6345
+ bcx. build . FastCall ( main_llfn, args) ;
6352
6346
build_return ( bcx) ;
6353
6347
6354
6348
finish_fn ( fcx, lltop) ;
0 commit comments