@@ -503,7 +503,8 @@ fn type_of_fn_full(@crate_ctxt cx,
503
503
ast. proto proto ,
504
504
option. t[ TypeRef ] obj_self ,
505
505
vec[ ty. arg] inputs ,
506
- @ty. t output ) -> TypeRef {
506
+ @ty. t output ,
507
+ uint ty_param_count ) -> TypeRef {
507
508
let vec[ TypeRef ] atys = vec ( ) ;
508
509
509
510
// Arg 0: Output pointer.
@@ -529,10 +530,6 @@ fn type_of_fn_full(@crate_ctxt cx,
529
530
530
531
// Args >3: ty params, if not acquired via capture...
531
532
if ( obj_self == none[ TypeRef ] ) {
532
- auto ty_param_count =
533
- ty. count_ty_params ( plain_ty ( ty. ty_fn ( proto,
534
- inputs,
535
- output) ) ) ;
536
533
auto i = 0 u;
537
534
while ( i < ty_param_count) {
538
535
atys += T_ptr ( T_tydesc ( cx. tn ) ) ;
@@ -547,7 +544,7 @@ fn type_of_fn_full(@crate_ctxt cx,
547
544
atys += T_fn_pair ( cx. tn ,
548
545
type_of_fn_full ( cx, ast. proto_fn , none[ TypeRef ] ,
549
546
vec ( rec ( mode=ast. val , ty=output) ) ,
550
- plain_ty ( ty. ty_nil ) ) ) ;
547
+ plain_ty ( ty. ty_nil ) , 0 u ) ) ;
551
548
}
552
549
553
550
// ... then explicit args.
@@ -558,8 +555,11 @@ fn type_of_fn_full(@crate_ctxt cx,
558
555
559
556
fn type_of_fn ( @crate_ctxt cx ,
560
557
ast. proto proto ,
561
- vec[ ty. arg] inputs , @ty. t output ) -> TypeRef {
562
- ret type_of_fn_full ( cx, proto, none[ TypeRef ] , inputs, output) ;
558
+ vec[ ty. arg] inputs ,
559
+ @ty. t output ,
560
+ uint ty_param_count ) -> TypeRef {
561
+ ret type_of_fn_full ( cx, proto, none[ TypeRef ] , inputs, output,
562
+ ty_param_count) ;
563
563
}
564
564
565
565
fn type_of_native_fn ( @crate_ctxt cx , ast. native_abi abi ,
@@ -634,7 +634,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
634
634
llty = T_struct ( tys) ;
635
635
}
636
636
case ( ty. ty_fn ( ?proto, ?args, ?out) ) {
637
- llty = T_fn_pair ( cx. tn , type_of_fn ( cx, proto, args, out) ) ;
637
+ llty = T_fn_pair ( cx. tn , type_of_fn ( cx, proto, args, out, 0 u ) ) ;
638
638
}
639
639
case ( ty. ty_native_fn ( ?abi, ?args, ?out) ) {
640
640
llty = T_fn_pair ( cx. tn , type_of_native_fn ( cx, abi, args, out) ) ;
@@ -648,7 +648,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
648
648
let TypeRef mty =
649
649
type_of_fn_full ( cx, m. proto ,
650
650
some[ TypeRef ] ( self_ty) ,
651
- m. inputs , m. output ) ;
651
+ m. inputs , m. output , 0 u ) ;
652
652
mtys += T_ptr ( mty) ;
653
653
}
654
654
let TypeRef vtbl = T_struct ( mtys) ;
@@ -2820,7 +2820,7 @@ fn trans_for_each(@block_ctxt cx,
2820
2820
auto iter_body_llty = type_of_fn_full( cx. fcx. ccx, ast. proto_fn,
2821
2821
none[ TypeRef ] ,
2822
2822
vec( rec( mode=ast. val, ty=decl_ty) ) ,
2823
- plain_ty( ty. ty_nil) ) ;
2823
+ plain_ty( ty. ty_nil) , 0 u ) ;
2824
2824
2825
2825
let ValueRef lliterbody = decl_fastcall_fn( cx. fcx. ccx. llmod,
2826
2826
s, iter_body_llty) ;
@@ -3447,6 +3447,16 @@ fn trans_bind_thunk(@crate_ctxt cx,
3447
3447
auto lltargetfn = bcx. build. GEP ( lltarget. val,
3448
3448
vec( C_int ( 0 ) ,
3449
3449
C_int ( abi. fn_field_code) ) ) ;
3450
+
3451
+ // Cast the outgoing function to the appropriate type (see the comments in
3452
+ // trans_bind below for why this is necessary).
3453
+ auto lltargetty = type_of_fn( bcx. fcx. ccx,
3454
+ ty. ty_fn_proto( outgoing_fty) ,
3455
+ outgoing_args,
3456
+ outgoing_ret_ty,
3457
+ ty_param_count) ;
3458
+ lltargetfn = bcx. build. PointerCast ( lltargetfn, T_ptr ( T_ptr ( lltargetty) ) ) ;
3459
+
3450
3460
lltargetfn = bcx. build. Load ( lltargetfn) ;
3451
3461
3452
3462
auto r = bcx. build. FastCall ( lltargetfn, llargs) ;
@@ -3551,12 +3561,26 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
3551
3561
bcx = bindings_tydesc. bcx;
3552
3562
bcx. build. Store ( bindings_tydesc. val, bound_tydesc) ;
3553
3563
3564
+ // Determine the LLVM type for the outgoing function type. This
3565
+ // may be different from the type returned by trans_malloc_boxed()
3566
+ // since we have more information than that function does;
3567
+ // specifically, we know how many type descriptors the outgoing
3568
+ // function has, which type_of() doesn't, as only we know which
3569
+ // item the function refers to.
3570
+ auto llfnty = type_of_fn( bcx. fcx. ccx,
3571
+ ty. ty_fn_proto( outgoing_fty) ,
3572
+ ty. ty_fn_args( outgoing_fty) ,
3573
+ ty. ty_fn_ret( outgoing_fty) ,
3574
+ ty_param_count) ;
3575
+ auto llclosurety = T_ptr ( T_fn_pair ( bcx. fcx. ccx. tn, llfnty) ) ;
3576
+
3554
3577
// Store thunk-target.
3555
3578
auto bound_target =
3556
3579
bcx. build. GEP ( closure,
3557
3580
vec( C_int ( 0 ) ,
3558
3581
C_int ( abi. closure_elt_target) ) ) ;
3559
3582
auto src = bcx. build. Load ( f_res. res. val) ;
3583
+ bound_target = bcx. build. PointerCast ( bound_target, llclosurety) ;
3560
3584
bcx. build. Store ( src, bound_target) ;
3561
3585
3562
3586
// Copy expr values into boxed bindings.
@@ -4691,7 +4715,8 @@ fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
4691
4715
case ( ty. ty_fn( ?proto, ?inputs, ?output) ) {
4692
4716
llfnty = type_of_fn_full( cx, proto,
4693
4717
some[ TypeRef ] ( self_ty) ,
4694
- inputs, output) ;
4718
+ inputs, output,
4719
+ _vec. len[ ast. ty_param] ( ty_params) ) ;
4695
4720
}
4696
4721
}
4697
4722
@@ -4990,11 +5015,23 @@ fn get_pair_fn_ty(TypeRef llpairty) -> TypeRef {
4990
5015
fn decl_fn_and_pair( @crate_ctxt cx,
4991
5016
str kind,
4992
5017
str name,
5018
+ vec[ ast. ty_param] ty_params,
4993
5019
& ast. ann ann,
4994
5020
ast. def_id id) {
4995
5021
4996
- auto llpairty = node_type( cx, ann) ;
4997
- auto llfty = get_pair_fn_ty( llpairty) ;
5022
+ auto llfty;
5023
+ auto llpairty;
5024
+ alt ( node_ann_type( cx, ann) . struct ) {
5025
+ case ( ty. ty_fn( ?proto, ?inputs, ?output) ) {
5026
+ llfty = type_of_fn( cx, proto, inputs, output,
5027
+ _vec. len[ ast. ty_param] ( ty_params) ) ;
5028
+ llpairty = T_fn_pair ( cx. tn, llfty) ;
5029
+ }
5030
+ case ( _) {
5031
+ cx. sess. bug( "decl_fn_and_pair(): fn item doesn't have fn type?!" ) ;
5032
+ fail;
5033
+ }
5034
+ }
4998
5035
4999
5036
// Declare the function itself.
5000
5037
let str s = cx. names. next( "_rust_" + kind) + sep( ) + name;
@@ -5023,11 +5060,29 @@ fn register_fn_pair(@crate_ctxt cx, str ps, TypeRef llpairty, ValueRef llfn,
5023
5060
cx. fn_pairs. insert( id, gvar) ;
5024
5061
}
5025
5062
5026
- fn native_fn_wrapper_type( @crate_ctxt cx, & ast. ann ann) -> TypeRef {
5063
+ // Returns the number of type parameters that the given native function has.
5064
+ fn native_fn_ty_param_count( @crate_ctxt cx, & ast. def_id id) -> uint {
5065
+ auto count;
5066
+ auto native_item = cx. native_items. get( id) ;
5067
+ alt ( native_item. node) {
5068
+ case ( ast. native_item_ty( _, _) ) {
5069
+ cx. sess. bug( "decl_native_fn_and_pair(): native fn isn't " +
5070
+ "actually a fn?!" ) ;
5071
+ fail;
5072
+ }
5073
+ case ( ast. native_item_fn( _, _, ?tps, _, _) ) {
5074
+ count = _vec. len[ ast. ty_param] ( tps) ;
5075
+ }
5076
+ }
5077
+ ret count;
5078
+ }
5079
+
5080
+ fn native_fn_wrapper_type( @crate_ctxt cx, uint ty_param_count, & ast. ann ann)
5081
+ -> TypeRef {
5027
5082
auto x = node_ann_type( cx, ann) ;
5028
5083
alt ( x. struct ) {
5029
5084
case ( ty. ty_native_fn( ?abi, ?args, ?out) ) {
5030
- ret type_of_fn( cx, ast. proto_fn, args, out) ;
5085
+ ret type_of_fn( cx, ast. proto_fn, args, out, ty_param_count ) ;
5031
5086
}
5032
5087
}
5033
5088
fail;
@@ -5037,8 +5092,10 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
5037
5092
str name,
5038
5093
& ast. ann ann,
5039
5094
ast. def_id id) {
5095
+ auto num_ty_param = native_fn_ty_param_count( cx, id) ;
5096
+
5040
5097
// Declare the wrapper.
5041
- auto wrapper_type = native_fn_wrapper_type( cx, ann) ;
5098
+ auto wrapper_type = native_fn_wrapper_type( cx, num_ty_param , ann) ;
5042
5099
let str s = cx. names. next( "_rust_wrapper" ) + sep( ) + name;
5043
5100
let ValueRef wrapper_fn = decl_fastcall_fn( cx. llmod, s, wrapper_type) ;
5044
5101
@@ -5063,7 +5120,6 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
5063
5120
alt ( abi) {
5064
5121
case ( ast. native_abi_rust) {
5065
5122
call_args += vec( fcx. lltaskptr) ;
5066
- auto num_ty_param = ty. count_ty_params( plain_ty( fn_type. struct ) ) ;
5067
5123
for each ( uint i in _uint. range( 0 u, num_ty_param) ) {
5068
5124
auto llarg = llvm. LLVMGetParam ( fcx. llfn, arg_n) ;
5069
5125
check ( llarg as int != 0 ) ;
@@ -5081,6 +5137,7 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
5081
5137
call_args += vec( llarg) ;
5082
5138
arg_n += 1 u;
5083
5139
}
5140
+
5084
5141
auto r = bcx. build. Call ( function, call_args) ;
5085
5142
bcx. build. Store ( r, fcx. llretptr) ;
5086
5143
bcx. build. RetVoid ( ) ;
@@ -5102,16 +5159,16 @@ fn collect_native_item(&@crate_ctxt cx, @ast.native_item i) -> @crate_ctxt {
5102
5159
fn collect_item( & @crate_ctxt cx, @ast. item i) -> @crate_ctxt {
5103
5160
5104
5161
alt ( i. node) {
5105
- case ( ast. item_fn( ?name, ?f, _ , ?fid, ?ann) ) {
5162
+ case ( ast. item_fn( ?name, ?f, ?tps , ?fid, ?ann) ) {
5106
5163
cx. items. insert( fid, i) ;
5107
5164
if ( ! cx. obj_methods. contains_key( fid) ) {
5108
- decl_fn_and_pair( cx, "fn ", name, ann, fid) ;
5165
+ decl_fn_and_pair( cx, "fn ", name, tps , ann, fid) ;
5109
5166
}
5110
5167
}
5111
5168
5112
- case ( ast. item_obj( ?name, ?ob, _ , ?oid, ?ann) ) {
5169
+ case ( ast. item_obj( ?name, ?ob, ?tps , ?oid, ?ann) ) {
5113
5170
cx. items. insert( oid, i) ;
5114
- decl_fn_and_pair( cx, "obj_ctor" , name, ann, oid) ;
5171
+ decl_fn_and_pair( cx, "obj_ctor" , name, tps , ann, oid) ;
5115
5172
for ( @ast. method m in ob. methods) {
5116
5173
cx. obj_methods. insert( m. node. id, ( ) ) ;
5117
5174
}
@@ -5151,11 +5208,11 @@ fn collect_tag_ctor(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
5151
5208
5152
5209
alt ( i. node) {
5153
5210
5154
- case ( ast. item_tag( _, ?variants, _ , _) ) {
5211
+ case ( ast. item_tag( _, ?variants, ?tps , _) ) {
5155
5212
for ( ast. variant variant in variants) {
5156
5213
if ( _vec. len[ ast. variant_arg] ( variant. args) != 0 u) {
5157
5214
decl_fn_and_pair( cx, "tag", variant. name,
5158
- variant. ann, variant. id) ;
5215
+ tps , variant. ann, variant. id) ;
5159
5216
}
5160
5217
}
5161
5218
}
0 commit comments