@@ -67,6 +67,8 @@ state type crate_ctxt = rec(session.session sess,
67
67
hashmap[ ast. def_id , ValueRef ] item_ids,
68
68
hashmap[ ast. def_id , @ast. item ] items,
69
69
hashmap[ ast. def_id , @tag_info] tags,
70
+ hashmap[ ast. def_id , ValueRef ] fn_pairs,
71
+ hashmap[ ast. def_id , ( ) ] obj_methods,
70
72
hashmap[ @ty. t , ValueRef ] tydescs,
71
73
vec[ ast. obj_field ] obj_fields,
72
74
@glue_fns glues,
@@ -193,7 +195,7 @@ fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef {
193
195
False ) ;
194
196
}
195
197
196
- fn T_closure ( TypeRef tfn) -> TypeRef {
198
+ fn T_fn_pair ( TypeRef tfn) -> TypeRef {
197
199
ret T_struct ( vec ( T_ptr ( tfn) ,
198
200
T_ptr ( T_box ( T_nil ( ) ) ) ) ) ;
199
201
}
@@ -389,7 +391,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
389
391
ret T_struct ( tys) ;
390
392
}
391
393
case ( ty. ty_fn ( ?args, ?out) ) {
392
- ret type_of_fn ( cx, args, out) ;
394
+ ret T_fn_pair ( type_of_fn ( cx, args, out) ) ;
393
395
}
394
396
case ( ty. ty_obj ( ?meths) ) {
395
397
auto th = mk_type_handle ( ) ;
@@ -500,6 +502,8 @@ fn C_str(@crate_ctxt cx, str s) -> ValueRef {
500
502
_str. buf ( cx. names . next ( "str" ) ) ) ;
501
503
llvm. LLVMSetInitializer ( g, sc) ;
502
504
llvm. LLVMSetGlobalConstant ( g, True ) ;
505
+ llvm. LLVMSetLinkage ( g, lib. llvm . LLVMPrivateLinkage
506
+ as llvm . Linkage ) ;
503
507
ret g;
504
508
}
505
509
@@ -679,6 +683,8 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t) {
679
683
auto gvar = llvm. LLVMAddGlobal ( cx. llmod , val_ty ( tydesc) , _str. buf ( name) ) ;
680
684
llvm. LLVMSetInitializer ( gvar, tydesc) ;
681
685
llvm. LLVMSetGlobalConstant ( gvar, True ) ;
686
+ llvm. LLVMSetLinkage ( gvar, lib. llvm . LLVMPrivateLinkage
687
+ as llvm . Linkage ) ;
682
688
cx. tydescs . insert ( t, gvar) ;
683
689
}
684
690
@@ -1725,17 +1731,22 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
1725
1731
ret lval_mem( cx, cx. fcx. llobjfields. get( did) ) ;
1726
1732
}
1727
1733
case ( ast. def_fn( ?did) ) {
1728
- check ( cx. fcx. ccx. item_ids . contains_key( did) ) ;
1729
- ret lval_val( cx, cx. fcx. ccx. item_ids . get( did) ) ;
1734
+ check ( cx. fcx. ccx. fn_pairs . contains_key( did) ) ;
1735
+ ret lval_val( cx, cx. fcx. ccx. fn_pairs . get( did) ) ;
1730
1736
}
1731
1737
case ( ast. def_obj( ?did) ) {
1732
- check ( cx. fcx. ccx. item_ids . contains_key( did) ) ;
1733
- ret lval_val( cx, cx. fcx. ccx. item_ids . get( did) ) ;
1738
+ check ( cx. fcx. ccx. fn_pairs . contains_key( did) ) ;
1739
+ ret lval_val( cx, cx. fcx. ccx. fn_pairs . get( did) ) ;
1734
1740
}
1735
1741
case ( ast. def_variant( ?tid, ?vid) ) {
1736
1742
check ( cx. fcx. ccx. tags. contains_key( tid) ) ;
1737
- check ( cx. fcx. ccx. item_ids. contains_key( vid) ) ;
1738
- ret lval_val( cx, cx. fcx. ccx. item_ids. get( vid) ) ;
1743
+ if ( cx. fcx. ccx. fn_pairs. contains_key( vid) ) {
1744
+ ret lval_val( cx, cx. fcx. ccx. fn_pairs. get( vid) ) ;
1745
+ } else {
1746
+ // Nullary variants are just scalar constants.
1747
+ check ( cx. fcx. ccx. item_ids. contains_key( vid) ) ;
1748
+ ret lval_val( cx, cx. fcx. ccx. item_ids. get( vid) ) ;
1749
+ }
1739
1750
}
1740
1751
case ( _) {
1741
1752
cx. fcx. ccx. sess. unimpl( "def variant in trans" ) ;
@@ -1942,7 +1953,7 @@ impure fn trans_bind(@block_ctxt cx, @ast.expr f,
1942
1953
& ast. ann ann) -> result {
1943
1954
auto f_res = trans_lval( cx, f) ;
1944
1955
auto bcx = f_res. res. bcx;
1945
- auto pair_t = T_closure ( node_type( cx. fcx. ccx, ann) ) ;
1956
+ auto pair_t = node_type( cx. fcx. ccx, ann) ;
1946
1957
auto pair_v = bcx. build. Alloca ( pair_t) ;
1947
1958
if ( f_res. is_mem) {
1948
1959
cx. fcx. ccx. sess. unimpl( "re-binding existing function" ) ;
@@ -1959,19 +1970,18 @@ impure fn trans_call(@block_ctxt cx, @ast.expr f,
1959
1970
vec[ @ast. expr] args, & ast. ann ann) -> result {
1960
1971
auto f_res = trans_lval( cx, f) ;
1961
1972
auto faddr = f_res. res. val;
1962
- if ( f_res. is_mem) {
1963
- alt ( f_res. llobj) {
1964
- case ( some[ ValueRef ] ( _) ) {
1965
- // It's a vtbl entry.
1966
- faddr = f_res. res. bcx. build. Load ( faddr) ;
1967
- }
1968
- case ( none[ ValueRef ] ) {
1969
- // It's a closure.
1970
- auto bcx = f_res. res. bcx;
1971
- faddr = bcx. build. GEP ( faddr, vec( C_int ( 0 ) ,
1972
- C_int ( abi. fn_field_code) ) ) ;
1973
- faddr = bcx. build. Load ( faddr) ;
1974
- }
1973
+
1974
+ alt ( f_res. llobj) {
1975
+ case ( some[ ValueRef ] ( _) ) {
1976
+ // It's a vtbl entry.
1977
+ faddr = f_res. res. bcx. build. Load ( faddr) ;
1978
+ }
1979
+ case ( none[ ValueRef ] ) {
1980
+ // It's a closure.
1981
+ auto bcx = f_res. res. bcx;
1982
+ faddr = bcx. build. GEP ( faddr, vec( C_int ( 0 ) ,
1983
+ C_int ( abi. fn_field_code) ) ) ;
1984
+ faddr = bcx. build. Load ( faddr) ;
1975
1985
}
1976
1986
}
1977
1987
auto fn_ty = ty. expr_ty( f) ;
@@ -2701,6 +2711,8 @@ impure fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
2701
2711
_str. buf( "_rust_vtbl" + "." + cx. path) ) ;
2702
2712
llvm. LLVMSetInitializer ( gvar, vtbl) ;
2703
2713
llvm. LLVMSetGlobalConstant ( gvar, True ) ;
2714
+ llvm. LLVMSetLinkage ( gvar, lib. llvm. LLVMPrivateLinkage
2715
+ as llvm. Linkage ) ;
2704
2716
ret gvar;
2705
2717
}
2706
2718
@@ -2818,15 +2830,8 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
2818
2830
id=varg. id) ) ;
2819
2831
}
2820
2832
2821
- auto var_ty = ty. ann_to_type( variant. ann) ;
2822
- auto llfnty = type_of( cx, var_ty) ;
2823
-
2824
- let str s = cx. names. next( "_rust_tag" ) + "." + cx. path;
2825
- let ValueRef llfn = decl_fastcall_fn( cx. llmod, s, llfnty) ;
2826
- cx. item_ids. insert( variant. id, llfn) ;
2827
-
2833
+ check ( cx. item_ids. contains_key( variant. id) ) ;
2828
2834
let ValueRef llfndecl = cx. item_ids. get( variant. id) ;
2829
- cx. item_names. insert( cx. path, llfndecl) ;
2830
2835
2831
2836
auto fcx = new_fn_ctxt( cx, cx. path, llfndecl) ;
2832
2837
create_llargs_for_fn_args( fcx, none[ TypeRef ] , ret_ty_of_fn( variant. ann) ,
@@ -2907,25 +2912,59 @@ impure fn trans_mod(@crate_ctxt cx, &ast._mod m) {
2907
2912
}
2908
2913
}
2909
2914
2915
+ fn decl_fn_and_pair( @crate_ctxt cx,
2916
+ str kind,
2917
+ str name,
2918
+ & ast. ann ann,
2919
+ ast. def_id id) {
2920
+
2921
+ // Bit of a kludge: pick the fn typeref out of the pair.
2922
+ auto llpairty = node_type( cx, ann) ;
2923
+ let vec[ TypeRef ] pair_tys = vec( T_nil ( ) , T_nil ( ) ) ;
2924
+ llvm. LLVMGetStructElementTypes ( llpairty,
2925
+ _vec. buf[ TypeRef ] ( pair_tys) ) ;
2926
+ auto llfty = llvm. LLVMGetElementType ( pair_tys. ( 0 ) ) ;
2927
+
2928
+ // Declare the function itself.
2929
+ let str s = cx. names. next( "_rust_" + kind) + "." + name;
2930
+ let ValueRef llfn = decl_fastcall_fn( cx. llmod, s, llfty) ;
2931
+
2932
+ // Declare the global constant pair that points to it.
2933
+ let str ps = cx. names. next( "_rust_" + kind + "_pair" ) + "." + name;
2934
+ let ValueRef gvar = llvm. LLVMAddGlobal ( cx. llmod, llpairty,
2935
+ _str. buf( ps) ) ;
2936
+ auto pair = C_struct ( vec( llfn,
2937
+ C_null ( T_ptr ( T_box ( T_nil ( ) ) ) ) ) ) ;
2938
+
2939
+ llvm. LLVMSetInitializer ( gvar, pair) ;
2940
+ llvm. LLVMSetGlobalConstant ( gvar, True ) ;
2941
+ llvm. LLVMSetLinkage ( gvar,
2942
+ lib. llvm. LLVMPrivateLinkage
2943
+ as llvm. Linkage ) ;
2944
+
2945
+ cx. item_ids. insert( id, llfn) ;
2946
+ cx. fn_pairs. insert( id, gvar) ;
2947
+ }
2948
+
2910
2949
2911
2950
fn collect_item( & @crate_ctxt cx, @ast. item i) -> @crate_ctxt {
2951
+
2912
2952
alt ( i. node) {
2913
2953
case ( ast. item_fn( ?name, ?f, _, ?fid, ?ann) ) {
2914
2954
// TODO: type-params
2915
2955
cx. items. insert( fid, i) ;
2916
- auto llty = node_type( cx, ann) ;
2917
- let str s = cx. names. next( "_rust_fn") + ". " + name;
2918
- let ValueRef llfn = decl_fastcall_fn( cx. llmod, s, llty) ;
2919
- cx. item_ids. insert( fid, llfn) ;
2956
+ if ( ! cx. obj_methods. contains_key( fid) ) {
2957
+ decl_fn_and_pair( cx, "fn ", name, ann, fid) ;
2958
+ }
2920
2959
}
2921
2960
2922
2961
case ( ast. item_obj( ?name, ?ob, _, ?oid, ?ann) ) {
2923
2962
// TODO: type-params
2924
2963
cx. items. insert( oid, i) ;
2925
- auto llty = node_type ( cx, ann) ;
2926
- let str s = cx . names . next ( "_rust_obj_ctor" ) + "." + name ;
2927
- let ValueRef llfn = decl_fastcall_fn ( cx. llmod , s , llty ) ;
2928
- cx . item_ids . insert ( oid , llfn ) ;
2964
+ decl_fn_and_pair ( cx, "obj_ctor" , name , ann, oid ) ;
2965
+ for ( @ast . method m in ob . methods ) {
2966
+ cx. obj_methods . insert ( m . node . id , ( ) ) ;
2967
+ }
2929
2968
}
2930
2969
2931
2970
case ( ast. item_const( ?name, _, _, ?cid, _) ) {
@@ -2963,6 +3002,36 @@ fn collect_items(@crate_ctxt cx, @ast.crate crate) {
2963
3002
fold. fold_crate[ @crate_ctxt] ( cx, fld, crate ) ;
2964
3003
}
2965
3004
3005
+ fn collect_tag_ctor( & @crate_ctxt cx, @ast. item i) -> @crate_ctxt {
3006
+
3007
+ alt ( i. node) {
3008
+
3009
+ case ( ast. item_tag( _, ?variants, _, _) ) {
3010
+ for ( ast. variant variant in variants) {
3011
+ if ( _vec. len [ ast. variant_arg ] ( variant. args ) != 0 u) {
3012
+ decl_fn_and_pair ( cx, "tag" , variant. name ,
3013
+ variant. ann , variant. id ) ;
3014
+ }
3015
+ }
3016
+ }
3017
+
3018
+ case ( _) { /* fall through */ }
3019
+ }
3020
+ ret cx;
3021
+ }
3022
+
3023
+ fn collect_tag_ctors ( @crate_ctxt cx , @ast. crate crate) {
3024
+
3025
+ let fold. ast_fold[ @crate_ctxt] fld =
3026
+ fold. new_identity_fold [ @crate_ctxt] ( ) ;
3027
+
3028
+ fld = @rec ( update_env_for_item = bind collect_tag_ctor ( _, _)
3029
+ with * fld ) ;
3030
+
3031
+ fold. fold_crate [ @crate_ctxt] ( cx, fld, crate ) ;
3032
+ }
3033
+
3034
+
2966
3035
// The tag type resolution pass, which determines all the LLVM types that
2967
3036
// correspond to each tag type in the crate.
2968
3037
@@ -3048,6 +3117,9 @@ fn trans_constant(&@crate_ctxt cx, @ast.item it) -> @crate_ctxt {
3048
3117
_str. buf ( "tag" ) ) ;
3049
3118
llvm. LLVMSetInitializer ( gvar, val) ;
3050
3119
llvm. LLVMSetGlobalConstant ( gvar, True ) ;
3120
+ llvm. LLVMSetLinkage ( gvar,
3121
+ lib. llvm . LLVMPrivateLinkage
3122
+ as llvm . Linkage ) ;
3051
3123
cx. item_ids . insert ( variant_info. _0 , gvar) ;
3052
3124
}
3053
3125
case ( n_ary) {
@@ -3281,6 +3353,8 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
3281
3353
item_ids = new_def_hash[ ValueRef ] ( ) ,
3282
3354
items = new_def_hash[ @ast. item ] ( ) ,
3283
3355
tags = new_def_hash[ @tag_info] ( ) ,
3356
+ fn_pairs = new_def_hash[ ValueRef ] ( ) ,
3357
+ obj_methods = new_def_hash[ ( ) ] ( ) ,
3284
3358
tydescs = tydescs,
3285
3359
obj_fields = obj_fields,
3286
3360
glues = glues,
@@ -3291,6 +3365,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
3291
3365
3292
3366
collect_items ( cx, crate ) ;
3293
3367
resolve_tag_types ( cx, crate ) ;
3368
+ collect_tag_ctors ( cx, crate ) ;
3294
3369
trans_constants ( cx, crate ) ;
3295
3370
3296
3371
trans_mod ( cx, crate . node. module ) ;
0 commit comments