@@ -61,17 +61,18 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
61
61
62
62
// NB: must keep 4 fns in sync:
63
63
//
64
- // - type_of_fn_full
64
+ // - type_of_fn
65
65
// - create_llargs_for_fn_args.
66
66
// - new_fn_ctxt
67
67
// - trans_args
68
- fn type_of_fn_full ( cx : @crate_ctxt , sp : span , proto : ast:: proto ,
69
- is_method : bool , inputs : [ ty:: arg ] , output : ty :: t ,
70
- ty_param_count : uint ) -> TypeRef {
68
+ fn type_of_fn ( cx : @crate_ctxt , sp : span , proto : ast:: proto ,
69
+ is_method : bool , ret_ref : bool , inputs : [ ty:: arg ] ,
70
+ output : ty :: t , ty_param_count : uint ) -> TypeRef {
71
71
let atys: [ TypeRef ] = [ ] ;
72
72
73
73
// Arg 0: Output pointer.
74
- atys += [ T_ptr ( type_of_inner ( cx, sp, output) ) ] ;
74
+ let out_ty = T_ptr ( type_of_inner ( cx, sp, output) ) ;
75
+ atys += [ ret_ref ? T_ptr ( out_ty) : out_ty] ;
75
76
76
77
// Arg 1: task pointer.
77
78
atys += [ T_taskptr ( * cx) ] ;
@@ -97,17 +98,13 @@ fn type_of_fn_full(cx: @crate_ctxt, sp: span, proto: ast::proto,
97
98
ret T_fn ( atys, llvm:: LLVMVoidType ( ) ) ;
98
99
}
99
100
100
- fn type_of_fn ( cx : @crate_ctxt , sp : span , proto : ast:: proto , inputs : [ ty:: arg ] ,
101
- output : ty:: t , ty_param_count : uint ) -> TypeRef {
102
- ret type_of_fn_full ( cx, sp, proto, false , inputs, output, ty_param_count) ;
103
- }
104
-
105
101
// Given a function type and a count of ty params, construct an llvm type
106
102
fn type_of_fn_from_ty ( cx : @crate_ctxt , sp : span , fty : ty:: t ,
107
103
ty_param_count : uint ) -> TypeRef {
104
+ let by_ref = ty:: ty_fn_ret_style ( cx. tcx , fty) == ast:: return_ref;
108
105
ret type_of_fn( cx, sp, ty:: ty_fn_proto ( cx. tcx , fty) ,
109
- ty :: ty_fn_args ( cx . tcx , fty ) , ty:: ty_fn_ret ( cx. tcx , fty) ,
110
- ty_param_count) ;
106
+ false , by_ref , ty:: ty_fn_args ( cx. tcx , fty) ,
107
+ ty :: ty_fn_ret ( cx . tcx , fty ) , ty_param_count) ;
111
108
}
112
109
113
110
fn type_of_native_fn ( cx : @crate_ctxt , sp : span , abi : ast:: native_abi ,
@@ -2970,12 +2967,13 @@ fn trans_field(cx: @block_ctxt, sp: span, v: ValueRef, t0: ty::t,
2970
2967
vtbl = PointerCast ( cx, vtbl, vtbl_type) ;
2971
2968
2972
2969
let v = GEP ( r. bcx , vtbl, [ C_int ( 0 ) , C_int ( ix as int ) ] ) ;
2973
- let fn_ty: ty:: t = ty:: method_ty_to_fn_ty ( bcx_tcx ( cx) , methods[ ix] ) ;
2974
2970
let tcx = bcx_tcx ( cx) ;
2971
+ let fn_ty: ty:: t = ty:: method_ty_to_fn_ty ( tcx, methods[ ix] ) ;
2972
+ let ret_ref = ty:: ty_fn_ret_style ( tcx, fn_ty) == ast:: return_ref;
2975
2973
let ll_fn_ty =
2976
- type_of_fn_full ( bcx_ccx ( cx) , sp, ty:: ty_fn_proto ( tcx, fn_ty) ,
2977
- true , ty:: ty_fn_args ( tcx, fn_ty) ,
2978
- ty:: ty_fn_ret ( tcx, fn_ty) , 0 u) ;
2974
+ type_of_fn ( bcx_ccx ( cx) , sp, ty:: ty_fn_proto ( tcx, fn_ty) ,
2975
+ true , ret_ref , ty:: ty_fn_args ( tcx, fn_ty) ,
2976
+ ty:: ty_fn_ret ( tcx, fn_ty) , 0 u) ;
2979
2977
v = PointerCast ( r. bcx , v, T_ptr ( T_ptr ( ll_fn_ty) ) ) ;
2980
2978
let lvo = lval_mem ( r. bcx , v) ;
2981
2979
ret { llobj : some :: < ValueRef > ( r. val ) , method_ty : some :: < ty:: t > ( fn_ty)
@@ -3513,26 +3511,28 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
3513
3511
3514
3512
// NB: must keep 4 fns in sync:
3515
3513
//
3516
- // - type_of_fn_full
3514
+ // - type_of_fn
3517
3515
// - create_llargs_for_fn_args.
3518
3516
// - new_fn_ctxt
3519
3517
// - trans_args
3520
3518
fn trans_args ( cx : @block_ctxt , llenv : ValueRef , gen : option:: t < generic_info > ,
3521
3519
lliterbody : option:: t < ValueRef > , es : [ @ast:: expr ] , fn_ty : ty:: t )
3522
- ->
3523
- { bcx : @ block_ctxt ,
3524
- args : [ ValueRef ] ,
3525
- retslot : ValueRef ,
3526
- to_zero : [ { v : ValueRef , t : ty:: t } ] ,
3527
- to_revoke : [ { v : ValueRef , t : ty :: t } ] } {
3520
+ -> { bcx : @ block_ctxt ,
3521
+ args : [ ValueRef ] ,
3522
+ retslot : ValueRef ,
3523
+ to_zero : [ { v : ValueRef , t : ty :: t } ] ,
3524
+ to_revoke : [ { v : ValueRef , t : ty:: t } ] ,
3525
+ by_ref : bool } {
3528
3526
3529
3527
let args: [ ty:: arg ] = ty:: ty_fn_args ( bcx_tcx ( cx) , fn_ty) ;
3530
3528
let llargs: [ ValueRef ] = [ ] ;
3531
3529
let lltydescs: [ ValueRef ] = [ ] ;
3532
3530
let to_zero = [ ] ;
3533
3531
let to_revoke = [ ] ;
3534
3532
3533
+ let tcx = bcx_tcx ( cx) ;
3535
3534
let bcx: @block_ctxt = cx;
3535
+ let by_ref = ty:: ty_fn_ret_style ( tcx, fn_ty) == ast:: return_ref;
3536
3536
// Arg 0: Output pointer.
3537
3537
3538
3538
// FIXME: test case looks like
@@ -3544,22 +3544,25 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
3544
3544
args : [ ] ,
3545
3545
retslot : C_nil ( ) ,
3546
3546
to_zero : to_zero,
3547
- to_revoke : to_revoke} ;
3547
+ to_revoke : to_revoke,
3548
+ by_ref : by_ref} ;
3548
3549
}
3549
- let retty = ty:: ty_fn_ret ( bcx_tcx ( cx) , fn_ty) ;
3550
- let llretslot_res = alloc_ty ( bcx, retty) ;
3550
+ let retty = ty:: ty_fn_ret ( tcx, fn_ty) ;
3551
+ let llretslot_res = if by_ref {
3552
+ rslt ( cx, alloca ( cx, T_ptr ( type_of_or_i8 ( cx, retty) ) ) )
3553
+ } else { alloc_ty ( bcx, retty) } ;
3551
3554
bcx = llretslot_res. bcx ;
3552
3555
let llretslot = llretslot_res. val ;
3553
3556
alt gen {
3554
3557
some ( g) {
3555
3558
lazily_emit_all_generic_info_tydesc_glues ( cx, g) ;
3556
3559
lltydescs = g. tydescs ;
3557
- args = ty:: ty_fn_args ( bcx_tcx ( cx ) , g. item_type ) ;
3558
- retty = ty:: ty_fn_ret ( bcx_tcx ( cx ) , g. item_type ) ;
3560
+ args = ty:: ty_fn_args ( tcx , g. item_type ) ;
3561
+ retty = ty:: ty_fn_ret ( tcx , g. item_type ) ;
3559
3562
}
3560
3563
_ { }
3561
3564
}
3562
- if ty:: type_contains_params ( bcx_tcx ( cx ) , retty) {
3565
+ if ty:: type_contains_params ( tcx , retty) {
3563
3566
// It's possible that the callee has some generic-ness somewhere in
3564
3567
// its return value -- say a method signature within an obj or a fn
3565
3568
// type deep in a structure -- which the caller has a concrete view
@@ -3583,8 +3586,8 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
3583
3586
none. { }
3584
3587
some( lli) {
3585
3588
let lli =
3586
- if ty:: type_contains_params ( bcx_tcx ( cx ) , retty) {
3587
- let body_ty = ty:: mk_iter_body_fn ( bcx_tcx ( cx ) , retty) ;
3589
+ if ty:: type_contains_params ( tcx , retty) {
3590
+ let body_ty = ty:: mk_iter_body_fn ( tcx , retty) ;
3588
3591
let body_llty = type_of_inner ( bcx_ccx ( cx) , cx. sp , body_ty) ;
3589
3592
PointerCast ( bcx, lli, T_ptr ( body_llty) )
3590
3593
} else { lli } ;
@@ -3615,7 +3618,8 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
3615
3618
args : llargs,
3616
3619
retslot : llretslot,
3617
3620
to_zero : to_zero,
3618
- to_revoke : to_revoke} ;
3621
+ to_revoke : to_revoke,
3622
+ by_ref : by_ref} ;
3619
3623
}
3620
3624
3621
3625
fn trans_call ( in_cx : @block_ctxt , f : @ast:: expr ,
@@ -3686,11 +3690,16 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
3686
3690
alt lliterbody {
3687
3691
none. {
3688
3692
if !ty:: type_is_nil ( bcx_tcx ( cx) , ret_ty) {
3689
- retval = load_if_immediate ( bcx, llretslot, ret_ty) ;
3690
- // Retval doesn't correspond to anything really tangible
3691
- // in the frame, but it's a ref all the same, so we put a
3692
- // note here to drop it when we're done in this scope.
3693
- add_clean_temp ( in_cx, retval, ret_ty) ;
3693
+ if args_res. by_ref {
3694
+ let retptr = Load ( bcx, llretslot) ;
3695
+ retval = load_if_immediate ( bcx, retptr, ret_ty) ;
3696
+ } else {
3697
+ retval = load_if_immediate ( bcx, llretslot, ret_ty) ;
3698
+ // Retval doesn't correspond to anything really tangible
3699
+ // in the frame, but it's a ref all the same, so we put a
3700
+ // note here to drop it when we're done in this scope.
3701
+ add_clean_temp ( in_cx, retval, ret_ty) ;
3702
+ }
3694
3703
}
3695
3704
}
3696
3705
some ( _) {
@@ -4386,7 +4395,7 @@ fn trans_ret(cx: @block_ctxt, e: option::t<@ast::expr>) -> result {
4386
4395
bcx = lv. res . bcx ;
4387
4396
if cx. fcx . ret_style == ast:: return_ref {
4388
4397
assert lv. is_mem ;
4389
- Store ( bcx, cx . fcx . llretptr , lv . res . val ) ;
4398
+ Store ( bcx, lv . res . val , cx . fcx . llretptr ) ;
4390
4399
} else {
4391
4400
let is_local = alt x. node {
4392
4401
ast:: expr_path ( p) {
@@ -4824,7 +4833,7 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
4824
4833
4825
4834
// NB: must keep 4 fns in sync:
4826
4835
//
4827
- // - type_of_fn_full
4836
+ // - type_of_fn
4828
4837
// - create_llargs_for_fn_args.
4829
4838
// - new_fn_ctxt
4830
4839
// - trans_args
@@ -4864,7 +4873,7 @@ fn new_fn_ctxt(cx: @local_ctxt, sp: span, llfndecl: ValueRef) -> @fn_ctxt {
4864
4873
4865
4874
// NB: must keep 4 fns in sync:
4866
4875
//
4867
- // - type_of_fn_full
4876
+ // - type_of_fn
4868
4877
// - create_llargs_for_fn_args.
4869
4878
// - new_fn_ctxt
4870
4879
// - trans_args
@@ -5355,10 +5364,10 @@ fn decl_fn_and_pair_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
5355
5364
let llfty =
5356
5365
type_of_fn_from_ty ( ccx, sp, node_type, std:: vec:: len ( ty_params) ) ;
5357
5366
alt ty:: struct ( ccx. tcx , node_type) {
5358
- ty:: ty_fn ( proto, inputs, output, _ , _) {
5359
- llfty =
5360
- type_of_fn ( ccx , sp , proto , inputs, output,
5361
- std :: vec:: len :: < ast :: ty_param > ( ty_params) ) ;
5367
+ ty:: ty_fn ( proto, inputs, output, rs , _) {
5368
+ llfty = type_of_fn ( ccx , sp , proto , false ,
5369
+ rs == ast :: return_ref , inputs, output,
5370
+ vec:: len ( ty_params) ) ;
5362
5371
}
5363
5372
_ { ccx. sess . bug ( "decl_fn_and_pair(): fn item doesn't have fn type!" ) ; }
5364
5373
}
@@ -5396,9 +5405,8 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
5396
5405
let vecarg_ty: ty:: arg =
5397
5406
{ mode: ast:: by_ref,
5398
5407
ty: ty:: mk_vec ( ccx. tcx , { ty: unit_ty, mut: ast:: imm} ) } ;
5399
- let llfty =
5400
- type_of_fn ( ccx, sp, ast:: proto_fn, [ vecarg_ty] ,
5401
- ty:: mk_nil ( ccx. tcx ) , 0 u) ;
5408
+ let llfty = type_of_fn ( ccx, sp, ast:: proto_fn, false , false ,
5409
+ [ vecarg_ty] , ty:: mk_nil ( ccx. tcx ) , 0 u) ;
5402
5410
let llfdecl = decl_fastcall_fn ( ccx. llmod , "_rust_main" , llfty) ;
5403
5411
5404
5412
let fcx = new_fn_ctxt ( new_local_ctxt ( ccx) , sp, llfdecl) ;
@@ -5499,7 +5507,8 @@ fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, ty_param_count: uint,
5499
5507
x : ty:: t ) -> TypeRef {
5500
5508
alt ty:: struct ( cx. tcx , x) {
5501
5509
ty:: ty_native_fn ( abi, args, out) {
5502
- ret type_of_fn ( cx, sp, ast:: proto_fn, args, out, ty_param_count) ;
5510
+ ret type_of_fn ( cx, sp, ast:: proto_fn, false , false , args, out,
5511
+ ty_param_count) ;
5503
5512
}
5504
5513
}
5505
5514
}
0 commit comments