@@ -2090,15 +2090,7 @@ fn make_drop_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) {
2090
2090
decr_refcnt_maybe_free( cx, box_cell, v0, t)
2091
2091
}
2092
2092
case ( ty:: ty_res( ?did, ?inner) ) {
2093
- ( alt ( ccx. ast_map. get( did. _1) ) {
2094
- case ( ast_map:: node_item( ?i) ) {
2095
- alt ( i. node) {
2096
- case ( ast:: item_res( ?dtor, _, _, _) ) {
2097
- drop_res( cx, v0, inner, dtor)
2098
- }
2099
- }
2100
- }
2101
- } )
2093
+ trans_res_drop( cx, v0, did, inner)
2102
2094
}
2103
2095
case ( ty:: ty_fn( _, _, _, _, _) ) {
2104
2096
auto box_cell =
@@ -2115,8 +2107,8 @@ fn make_drop_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) {
2115
2107
rs. bcx. build. RetVoid ( ) ;
2116
2108
}
2117
2109
2118
- fn drop_res ( @block_ctxt cx, ValueRef rs, ty :: t inner_t , & ast:: _fn dtor )
2119
- -> result {
2110
+ fn trans_res_drop ( @block_ctxt cx, ValueRef rs, & ast:: def_id did ,
2111
+ ty :: t inner_t ) -> result {
2120
2112
auto ccx = cx. fcx. lcx. ccx;
2121
2113
auto tup_ty = ty:: mk_imm_tup( ccx. tcx, [ ty:: mk_int( ccx. tcx) , inner_t] ) ;
2122
2114
auto drop_cx = new_sub_block_ctxt( cx, "drop res") ;
@@ -2126,12 +2118,29 @@ fn drop_res(@block_ctxt cx, ValueRef rs, ty::t inner_t, &ast::_fn dtor)
2126
2118
cx = drop_flag. bcx;
2127
2119
auto null_test = cx. build. IsNull ( cx. build. Load ( drop_flag. val) ) ;
2128
2120
cx. build. CondBr ( null_test, next_cx. llbb, drop_cx. llbb) ;
2129
-
2130
2121
cx = drop_cx;
2131
- auto val = GEP_tup_like ( cx, tup_ty, rs, [ 0 , 1 ] ) ;
2122
+
2123
+ // Find and call the actual destructor.
2124
+ auto dtor_pair = if ( did. _0 == ast:: local_crate) {
2125
+ ccx. fn_pairs. get( did. _1)
2126
+ } else {
2127
+ auto params = decoder:: get_type_param_count( ccx. tcx, did) ;
2128
+ auto f_t = type_of_fn( ccx, cx. sp, ast:: proto_fn,
2129
+ [ rec( mode=ty:: mo_alias( false) , ty=inner_t) ] ,
2130
+ ty:: mk_nil( ccx. tcx) , params) ;
2131
+ get_extern_const( ccx. externs, ccx. llmod,
2132
+ decoder:: get_symbol( ccx. sess, did) ,
2133
+ T_fn_pair ( ccx. tn, f_t) )
2134
+ } ;
2135
+ auto dtor_addr = cx. build. Load
2136
+ ( cx. build. GEP ( dtor_pair, [ C_int ( 0 ) , C_int ( abi:: fn_field_code) ] ) ) ;
2137
+ auto dtor_env = cx. build. Load
2138
+ ( cx. build. GEP ( dtor_pair, [ C_int ( 0 ) , C_int ( abi:: fn_field_box) ] ) ) ;
2139
+ auto val = GEP_tup_like ( cx, tup_ty, rs, [ 0 , 1 ] ) ;
2132
2140
cx = val. bcx;
2133
- cx. fcx. llargs. insert( dtor. decl. inputs. ( 0 ) . id, val. val) ;
2134
- cx = trans_block( cx, dtor. body, return ) . bcx;
2141
+ cx. build. FastCall ( dtor_addr, [ cx. fcx. llretptr, cx. fcx. lltaskptr, dtor_env]
2142
+ + cx. fcx. lltydescs + [ val. val] ) ;
2143
+
2135
2144
cx = drop_slot( cx, val. val, inner_t) . bcx;
2136
2145
cx. build. Store ( C_int ( 0 ) , drop_flag. val) ;
2137
2146
cx. build. Br ( next_cx. llbb) ;
@@ -7827,19 +7836,20 @@ fn trans_obj(@local_ctxt cx, &span sp, &ast::_obj ob, ast::node_id ctor_id,
7827
7836
finish_fn( fcx, lltop) ;
7828
7837
}
7829
7838
7830
- fn trans_res( @local_ctxt cx, & span sp, & ast:: _fn f, ast:: node_id ctor_id,
7831
- & vec[ ast:: ty_param] ty_params) {
7839
+ fn trans_res_ctor( @local_ctxt cx, & span sp, & ast:: _fn dtor,
7840
+ ast:: node_id ctor_id, & vec[ ast:: ty_param] ty_params) {
7841
+ // Create a function for the constructor
7832
7842
auto llctor_decl = cx. ccx. item_ids. get( ctor_id) ;
7833
7843
auto fcx = new_fn_ctxt( cx, sp, llctor_decl) ;
7834
7844
auto ret_t = ty:: ret_ty_of_fn( cx. ccx. tcx, ctor_id) ;
7835
7845
create_llargs_for_fn_args( fcx, ast:: proto_fn, none[ ty_self_pair] ,
7836
- ret_t, f . decl. inputs, ty_params) ;
7846
+ ret_t, dtor . decl. inputs, ty_params) ;
7837
7847
auto bcx = new_top_block_ctxt( fcx) ;
7838
7848
auto lltop = bcx. llbb;
7839
7849
auto arg_t = arg_tys_of_fn( cx. ccx, ctor_id) . ( 0 ) . ty;
7840
7850
auto tup_t = ty:: mk_imm_tup( cx. ccx. tcx, [ ty:: mk_int( cx. ccx. tcx) , arg_t] ) ;
7841
7851
auto arg = load_if_immediate
7842
- ( bcx, fcx. llargs. get( f . decl. inputs. ( 0 ) . id) , arg_t) ;
7852
+ ( bcx, fcx. llargs. get( dtor . decl. inputs. ( 0 ) . id) , arg_t) ;
7843
7853
auto dst = GEP_tup_like ( bcx, tup_t, fcx. llretptr, [ 0 , 1 ] ) ;
7844
7854
bcx = dst. bcx;
7845
7855
bcx = copy_val( bcx, INIT , dst. val, arg, arg_t) . bcx;
@@ -7959,8 +7969,11 @@ fn trans_item(@local_ctxt cx, &ast::item item) {
7959
7969
with * extend_path( cx, item. ident) ) ;
7960
7970
trans_obj( sub_cx, item. span, ob, ctor_id, tps) ;
7961
7971
}
7962
- case ( ast:: item_res( ?decl, _, ?tps, ?ctor_id) ) {
7963
- trans_res( cx, item. span, decl, ctor_id, tps) ;
7972
+ case ( ast:: item_res( ?dtor, ?dtor_id, ?tps, ?ctor_id) ) {
7973
+ trans_res_ctor( cx, item. span, dtor, ctor_id, tps) ;
7974
+ // Create a function for the destructor
7975
+ auto lldtor_decl = cx. ccx. item_ids. get( item. id) ;
7976
+ trans_fn( cx, item. span, dtor, lldtor_decl, none, tps, dtor_id) ;
7964
7977
}
7965
7978
case ( ast:: item_mod( ?m) ) {
7966
7979
auto sub_cx =
@@ -7999,10 +8012,17 @@ fn get_pair_fn_ty(TypeRef llpairty) -> TypeRef {
7999
8012
ret struct_elt( llpairty, 0 u) ;
8000
8013
}
8001
8014
8002
- fn decl_fn_and_pair( & @crate_ctxt ccx, & span sp, vec[ str ] path, str flav,
8015
+ fn decl_fn_and_pair( & @crate_ctxt ccx, & span sp, & vec[ str ] path, str flav,
8003
8016
vec[ ast:: ty_param] ty_params, ast:: node_id node_id) {
8017
+ decl_fn_and_pair_full( ccx, sp, path, flav, ty_params, node_id,
8018
+ node_id_type( ccx, node_id) ) ;
8019
+ }
8020
+
8021
+ fn decl_fn_and_pair_full( & @crate_ctxt ccx, & span sp, & vec[ str ] path, str flav,
8022
+ vec[ ast:: ty_param] ty_params, ast:: node_id node_id,
8023
+ ty:: t node_type) {
8004
8024
auto llfty;
8005
- alt ( ty:: struct ( ccx. tcx, node_id_type ( ccx , node_id ) ) ) {
8025
+ alt ( ty:: struct ( ccx. tcx, node_type ) ) {
8006
8026
case ( ty:: ty_fn( ?proto, ?inputs, ?output, _, _) ) {
8007
8027
llfty =
8008
8028
type_of_fn( ccx, sp, proto, inputs, output,
@@ -8023,7 +8043,7 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp, vec[str] path, str flav,
8023
8043
let ValueRef llfn = decl_internal_fastcall_fn( ccx. llmod, s, llfty) ;
8024
8044
// Declare the global constant pair that points to it.
8025
8045
8026
- let str ps = mangle_exported_name( ccx, path, node_id_type ( ccx , node_id ) ) ;
8046
+ let str ps = mangle_exported_name( ccx, path, node_type ) ;
8027
8047
register_fn_pair( ccx, ps, llfty, llfn, node_id) ;
8028
8048
if ( is_main) {
8029
8049
if ( ccx. main_fn != none[ ValueRef ] ) {
@@ -8295,8 +8315,14 @@ fn collect_item_2(&@crate_ctxt ccx, &@ast::item i, &vec[str] pt,
8295
8315
ccx. obj_methods. insert( m. node. id, ( ) ) ;
8296
8316
}
8297
8317
}
8298
- case ( ast:: item_res( ?decl , _ , ?tps, ?ctor_id) ) {
8318
+ case ( ast:: item_res( _ , ?dtor_id , ?tps, ?ctor_id) ) {
8299
8319
decl_fn_and_pair( ccx, i. span, new_pt, "res_ctor", tps, ctor_id) ;
8320
+ // Note that the destructor is associated with the item's id, not
8321
+ // the dtor_id. This is a bit counter-intuitive, but simplifies
8322
+ // ty_res, which would have to carry around two def_ids otherwise
8323
+ // -- one to identify the type, and one to find the dtor symbol.
8324
+ decl_fn_and_pair_full( ccx, i. span, new_pt, "res_dtor", tps, i. id,
8325
+ node_id_type( ccx, dtor_id) ) ;
8300
8326
}
8301
8327
case ( _) { }
8302
8328
}
0 commit comments