@@ -62,7 +62,9 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
62
62
// FIXME: would be nice to have a constraint on arg
63
63
// that would obviate the need for this check
64
64
check non_ty_var( cx, arg_ty) ;
65
- atys += [ T_ptr ( type_of_inner ( cx, sp, arg_ty) ) ] ;
65
+ let llty = type_of_inner ( cx, sp, arg_ty) ;
66
+ if arg. mode == ast:: by_val { atys += [ llty] ; }
67
+ else { atys += [ T_ptr ( llty) ] ; }
66
68
}
67
69
ret atys;
68
70
}
@@ -3424,15 +3426,15 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
3424
3426
env_ty : ty:: t , ty_param_count : uint ,
3425
3427
target_fn : option:: t < ValueRef > )
3426
3428
-> { val : ValueRef , ty: TypeRef } {
3427
- // If we supported constraints on record fields, we could make the
3428
- // constraints for this function:
3429
- /*
3429
+ // If we supported constraints on record fields, we could make the
3430
+ // constraints for this function:
3431
+ /*
3430
3432
: returns_non_ty_var(ccx, outgoing_fty),
3431
3433
type_has_static_size(ccx, incoming_fty) ->
3432
- */
3433
- // but since we don't, we have to do the checks at the beginning.
3434
- let ccx = cx. ccx ;
3435
- check type_has_static_size ( ccx, incoming_fty) ;
3434
+ */
3435
+ // but since we don't, we have to do the checks at the beginning.
3436
+ let ccx = cx. ccx ;
3437
+ check type_has_static_size ( ccx, incoming_fty) ;
3436
3438
3437
3439
// Here we're not necessarily constructing a thunk in the sense of
3438
3440
// "function with no arguments". The result of compiling 'bind f(foo,
@@ -3566,6 +3568,7 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
3566
3568
abi : : closure_elt_bindings, b] ) ;
3567
3569
bcx = bound_arg. bcx;
3568
3570
let val = bound_arg. val;
3571
+ if out_arg. mode == ast : : by_val { val = Load ( bcx, val) ; }
3569
3572
// If the type is parameterized, then we need to cast the
3570
3573
// type we actually have to the parameterized out type.
3571
3574
if ty:: type_contains_params( cx. ccx. tcx, out_arg. ty) {
@@ -3700,21 +3703,24 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
3700
3703
// to have type lldestty0 (the callee's expected type).
3701
3704
val = llvm:: LLVMGetUndef ( lldestty0) ;
3702
3705
} else if arg. mode == ast:: by_ref || arg. mode == ast:: by_val {
3703
- let copied = false ;
3704
- if !lv. is_mem && type_is_immediate ( ccx , e_ty ) {
3706
+ let copied = false , imm = type_is_immediate ( ccx , e_ty ) ;
3707
+ if arg . mode == ast :: by_ref && !lv. is_mem && imm {
3705
3708
val = do_spill_noroot ( bcx, val) ;
3706
3709
copied = true ;
3707
3710
}
3708
3711
if ccx. copy_map . contains_key ( e. id ) && lv. is_mem {
3712
+ assert lv. is_mem ;
3709
3713
if !copied {
3710
3714
let alloc = alloc_ty ( bcx, e_ty) ;
3711
- bcx =
3712
- copy_val ( alloc. bcx , INIT , alloc. val ,
3713
- load_if_immediate ( alloc. bcx , val, e_ty) , e_ty) ;
3715
+ bcx = copy_val ( alloc. bcx , INIT , alloc. val ,
3716
+ load_if_immediate ( alloc. bcx , val, e_ty) , e_ty) ;
3714
3717
val = alloc. val ;
3715
3718
} else { bcx = take_ty ( bcx, val, e_ty) ; }
3716
3719
add_clean ( bcx, val, e_ty) ;
3717
3720
}
3721
+ if arg. mode == ast:: by_val && ( lv. is_mem || !imm) {
3722
+ val = Load ( bcx, val) ;
3723
+ }
3718
3724
} else if type_is_immediate ( ccx, e_ty) && !lv. is_mem {
3719
3725
let r = do_spill ( bcx, val, e_ty) ;
3720
3726
val = r. val ;
@@ -3960,7 +3966,8 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr,
3960
3966
3961
3967
let r = trans_arg_expr ( bcx, ty_arg, llargty, to_zero, to_revoke, arg) ;
3962
3968
let llargval = r. val ; bcx = r. bcx ;
3963
- { llval: llargval, llty: llargty, static : static }
3969
+ { llval: llargval, llty: llargty, static : static ,
3970
+ by_val: ty_arg. mode == ast:: by_val }
3964
3971
} , fn_arg_tys, args) ;
3965
3972
3966
3973
// Allocate the argument bundle.
@@ -3976,7 +3983,7 @@ fn trans_c_stack_native_call(bcx: @block_ctxt, f: @ast::expr,
3976
3983
if llarg. static {
3977
3984
// FIXME: This load is unfortunate. It won't be necessary once we
3978
3985
// have reference types again.
3979
- llargval = Load ( bcx, llarg. llval ) ;
3986
+ llargval = llarg . by_val ? llarg . llval : Load ( bcx, llarg. llval ) ;
3980
3987
} else {
3981
3988
llargval = llarg. llval ;
3982
3989
}
@@ -5141,27 +5148,38 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
5141
5148
arg_tys : [ ty:: arg ] , ignore_mut : bool )
5142
5149
-> @block_ctxt {
5143
5150
let arg_n: uint = 0 u;
5144
- for aarg: ast:: arg in args {
5145
- let arg_ty = arg_tys[ arg_n] . ty ;
5146
- alt aarg. mode {
5151
+ for arg in arg_tys {
5152
+ let id = args[ arg_n] . id ;
5153
+ let mutated = !ignore_mut && fcx. lcx . ccx . mut_map . contains_key ( id) ;
5154
+ alt arg. mode {
5155
+ ast:: mode_infer. {
5156
+ bcx_ccx ( bcx) . sess . span_fatal ( fcx. sp , "this" ) ;
5157
+ }
5147
5158
ast:: by_move. {
5148
- add_clean ( bcx, fcx. llargs . get ( aarg . id ) , arg_ty ) ;
5159
+ add_clean ( bcx, fcx. llargs . get ( id) , arg . ty ) ;
5149
5160
}
5150
5161
ast:: by_mut_ref. { }
5151
- _ {
5152
- let mutated =
5153
- !ignore_mut && fcx. lcx . ccx . mut_map . contains_key ( aarg. id ) ;
5154
-
5162
+ ast:: by_val. {
5163
+ let aval = fcx. llargs . get ( id) ;
5164
+ let { bcx: cx , val : alloc } = alloc_ty ( bcx, arg. ty ) ;
5165
+ bcx = cx;
5166
+ Store ( bcx, aval, alloc) ;
5167
+ if mutated {
5168
+ bcx = take_ty ( bcx, alloc, arg. ty ) ;
5169
+ add_clean ( bcx, alloc, arg. ty ) ;
5170
+ }
5171
+ fcx. llargs . insert ( id, alloc) ;
5172
+ }
5173
+ ast:: by_ref. {
5155
5174
// Overwrite the llargs entry for locally mutated params
5156
5175
// with a local alloca.
5157
5176
if mutated {
5158
- let aptr = fcx. llargs . get ( aarg. id ) ;
5159
- let { bcx: bcx , val : alloc } = alloc_ty ( bcx, arg_ty) ;
5160
- bcx =
5161
- copy_val ( bcx, INIT , alloc,
5162
- load_if_immediate ( bcx, aptr, arg_ty) , arg_ty) ;
5163
- fcx. llargs . insert ( aarg. id , alloc) ;
5164
- add_clean ( bcx, alloc, arg_ty) ;
5177
+ let aptr = fcx. llargs . get ( id) ;
5178
+ let { bcx: cx , val : alloc } = alloc_ty ( bcx, arg. ty ) ;
5179
+ bcx = copy_val ( cx, INIT , alloc,
5180
+ load_if_immediate ( cx, aptr, arg. ty ) , arg. ty ) ;
5181
+ fcx. llargs . insert ( id, alloc) ;
5182
+ add_clean ( bcx, alloc, arg. ty ) ;
5165
5183
}
5166
5184
}
5167
5185
}
@@ -5845,7 +5863,7 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
5845
5863
let i = arg_n;
5846
5864
for arg: ty:: arg in args {
5847
5865
let llarg = llvm:: LLVMGetParam ( fcx. llfn , i) ;
5848
- if arg. mode == ast:: by_ref || arg . mode == ast :: by_val {
5866
+ if arg. mode == ast:: by_ref {
5849
5867
llarg = load_if_immediate ( bcx, llarg, arg. ty ) ;
5850
5868
}
5851
5869
assert ( llarg as int != 0 ) ;
0 commit comments