@@ -359,6 +359,11 @@ fn T_glue_fn(type_names tn) -> TypeRef {
359
359
ret t;
360
360
}
361
361
362
+ fn T_dtor ( @crate_ctxt ccx , TypeRef llself_ty ) -> TypeRef {
363
+ ret type_of_fn_full ( ccx, ast. proto_fn , some[ TypeRef ] ( llself_ty) ,
364
+ _vec. empty [ ty. arg ] ( ) , ty. mk_nil ( ccx. tcx ) , 0 u) ;
365
+ }
366
+
362
367
fn T_cmp_glue_fn ( type_names tn) -> TypeRef {
363
368
auto s = "cmp_glue_fn" ;
364
369
if ( tn. name_has_type ( s) ) {
@@ -763,7 +768,7 @@ fn type_of_inner(@crate_ctxt cx, ty.t t) -> TypeRef {
763
768
auto th = mk_type_handle ( ) ;
764
769
auto self_ty = llvm. LLVMResolveTypeHandle ( th. llth ) ;
765
770
766
- let vec[ TypeRef ] mtys = vec ( ) ;
771
+ let vec[ TypeRef ] mtys = vec ( T_ptr ( T_i8 ( ) ) ) ;
767
772
for ( ty. method m in meths) {
768
773
let TypeRef mty =
769
774
type_of_fn_full ( cx, m. proto ,
@@ -1618,7 +1623,8 @@ fn get_tydesc(&@block_ctxt cx, ty.t t) -> result {
1618
1623
1619
1624
// Otherwise, generate a tydesc if necessary, and return it.
1620
1625
let vec[ uint] tps = vec( ) ;
1621
- ret res( cx, get_static_tydesc( cx, t, tps) . tydesc) ;
1626
+ auto st = get_static_tydesc( cx, t, tps) . tydesc;
1627
+ ret res( cx, st) ;
1622
1628
}
1623
1629
1624
1630
fn get_static_tydesc( & @block_ctxt cx,
@@ -1901,25 +1907,26 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v0, ty.t t) {
1901
1907
}
1902
1908
1903
1909
case ( ty. ty_obj ( _) ) {
1904
- fn hit_zero ( @block_ctxt cx , ValueRef v) -> result {
1905
-
1906
- // Call through the obj's own fields-drop glue first.
1910
+ fn hit_zero ( @block_ctxt cx , ValueRef b, ValueRef o) -> result {
1907
1911
auto body =
1908
- cx. build . GEP ( v ,
1912
+ cx. build . GEP ( b ,
1909
1913
vec ( C_int ( 0 ) ,
1910
1914
C_int ( abi. box_rc_field_body ) ) ) ;
1911
-
1912
1915
auto tydescptr =
1913
1916
cx. build . GEP ( body,
1914
1917
vec ( C_int ( 0 ) ,
1915
1918
C_int ( abi. obj_body_elt_tydesc ) ) ) ;
1919
+ auto tydesc = cx. build . Load ( tydescptr) ;
1916
1920
1917
- call_tydesc_glue_full ( cx, body, cx. build . Load ( tydescptr) ,
1921
+ auto cx_ = maybe_call_dtor ( cx, o) ;
1922
+
1923
+ // Call through the obj's own fields-drop glue first.
1924
+ call_tydesc_glue_full ( cx_, body, tydesc,
1918
1925
abi. tydesc_field_drop_glue ) ;
1919
1926
1920
1927
// Then free the body.
1921
1928
// FIXME: switch gc/non-gc on layer of the type.
1922
- ret trans_non_gc_free ( cx , v ) ;
1929
+ ret trans_non_gc_free ( cx_ , b ) ;
1923
1930
}
1924
1931
auto box_cell =
1925
1932
cx. build . GEP ( v0,
@@ -1929,7 +1936,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v0, ty.t t) {
1929
1936
auto boxptr = cx. build . Load ( box_cell) ;
1930
1937
1931
1938
rslt = decr_refcnt_and_if_zero ( cx, boxptr,
1932
- bind hit_zero ( _, boxptr) ,
1939
+ bind hit_zero ( _, boxptr, v0 ) ,
1933
1940
"free obj" ,
1934
1941
T_int ( ) , C_int ( 0 ) ) ;
1935
1942
}
@@ -2704,6 +2711,27 @@ fn call_tydesc_glue(@block_ctxt cx, ValueRef v,
2704
2711
ret res( td. bcx, C_nil ( ) ) ;
2705
2712
}
2706
2713
2714
+ fn maybe_call_dtor( @block_ctxt cx, ValueRef v) -> @block_ctxt {
2715
+ auto vtbl = cx. build. GEP ( v, vec( C_int ( 0 ) , C_int ( abi. obj_field_vtbl) ) ) ;
2716
+ vtbl = cx. build. Load ( vtbl) ;
2717
+ auto dtor_ptr = cx. build. GEP ( vtbl, vec( C_int ( 0 ) , C_int ( 0 ) ) ) ;
2718
+ dtor_ptr = cx. build. Load ( dtor_ptr) ;
2719
+ dtor_ptr = cx. build. BitCast ( dtor_ptr,
2720
+ T_ptr ( T_dtor ( cx. fcx. lcx. ccx, val_ty( v) ) ) ) ;
2721
+
2722
+ auto dtor_cx = new_sub_block_ctxt( cx, "dtor") ;
2723
+ auto after_cx = new_sub_block_ctxt( cx, "after_dtor") ;
2724
+ auto test = cx. build. ICmp ( lib. llvm. LLVMIntNE , dtor_ptr,
2725
+ C_null ( val_ty( dtor_ptr) ) ) ;
2726
+ cx. build. CondBr ( test, dtor_cx. llbb, after_cx. llbb) ;
2727
+
2728
+ // FIXME need to pass type params (?)
2729
+ dtor_cx. build. FastCall ( dtor_ptr, vec( C_null ( T_ptr ( T_nil ( ) ) ) ,
2730
+ cx. fcx. lltaskptr, v) ) ;
2731
+ dtor_cx. build. Br ( after_cx. llbb) ;
2732
+ ret after_cx;
2733
+ }
2734
+
2707
2735
fn call_cmp_glue( @block_ctxt cx, ValueRef lhs, ValueRef rhs, ty. t t,
2708
2736
ValueRef llop) -> result {
2709
2737
// We can't use call_tydesc_glue_full() and friends here because compare
@@ -4110,12 +4138,13 @@ fn trans_field(@block_ctxt cx, &ast.span sp, ValueRef v, ty.t t0,
4110
4138
vec( C_int ( 0 ) ,
4111
4139
C_int ( abi. obj_field_vtbl) ) ) ;
4112
4140
vtbl = r. bcx. build. Load ( vtbl) ;
4141
+ // +1 because slot #0 contains the destructor
4113
4142
auto v = r. bcx. build. GEP ( vtbl, vec( C_int ( 0 ) ,
4114
- C_int ( ix as int) ) ) ;
4143
+ C_int ( ( ix + 1 u ) as int) ) ) ;
4115
4144
4116
4145
auto lvo = lval_mem( r. bcx, v) ;
4117
4146
let ty. t fn_ty = ty. method_ty_to_fn_ty( cx. fcx. lcx. ccx. tcx,
4118
- methods. ( ix) ) ;
4147
+ methods. ( ix) ) ;
4119
4148
ret rec( llobj = some[ ValueRef ] ( r. val) ,
4120
4149
method_ty = some[ ty. t] ( fn_ty)
4121
4150
with lvo) ;
@@ -6102,7 +6131,6 @@ fn populate_fn_ctxt_from_llself(@fn_ctxt fcx, self_vt llself) {
6102
6131
fn trans_fn( @local_ctxt cx, & ast. _fn f, ast. def_id fid,
6103
6132
option. t[ tup( TypeRef , ty. t) ] ty_self,
6104
6133
& vec[ ast. ty_param] ty_params, & ast. ann ann) {
6105
-
6106
6134
auto llfndecl = cx. ccx. item_ids. get( fid) ;
6107
6135
6108
6136
auto fcx = new_fn_ctxt( cx, llfndecl) ;
@@ -6145,7 +6173,15 @@ fn trans_vtbl(@local_ctxt cx,
6145
6173
ty. t self_ty,
6146
6174
& ast. _obj ob,
6147
6175
& vec[ ast. ty_param] ty_params) -> ValueRef {
6148
- let vec[ ValueRef ] methods = vec( ) ;
6176
+ auto dtor = C_null ( T_ptr ( T_i8 ( ) ) ) ;
6177
+ alt ( ob. dtor) {
6178
+ case ( some[ @ast. method] ( ?d) ) {
6179
+ auto dtor_1 = trans_dtor( cx, llself_ty, self_ty, ty_params, d) ;
6180
+ dtor = llvm. LLVMConstBitCast ( dtor_1, val_ty( dtor) ) ;
6181
+ }
6182
+ case ( none[ @ast. method] ) { }
6183
+ }
6184
+ let vec[ ValueRef ] methods = vec( dtor) ;
6149
6185
6150
6186
fn meth_lteq( & @ast. method a, & @ast. method b) -> bool {
6151
6187
ret _str. lteq( a. node. ident, b. node. ident) ;
@@ -6195,16 +6231,7 @@ fn trans_dtor(@local_ctxt cx,
6195
6231
& vec[ ast. ty_param] ty_params,
6196
6232
& @ast. method dtor) -> ValueRef {
6197
6233
6198
- auto llfnty = T_nil ( ) ;
6199
- alt ( ty. struct ( cx. ccx. tcx, node_ann_type( cx. ccx, dtor. node. ann) ) ) {
6200
- case ( ty. ty_fn( ?proto, ?inputs, ?output) ) {
6201
- llfnty = type_of_fn_full( cx. ccx, proto,
6202
- some[ TypeRef ] ( llself_ty) ,
6203
- inputs, output,
6204
- _vec. len[ ast. ty_param] ( ty_params) ) ;
6205
- }
6206
- }
6207
-
6234
+ auto llfnty = T_dtor ( cx. ccx, llself_ty) ;
6208
6235
let @local_ctxt dcx = extend_path( cx, "drop" ) ;
6209
6236
let str s = mangle_name_by_seq( dcx. ccx, dcx. path, "drop" ) ;
6210
6237
let ValueRef llfn = decl_internal_fastcall_fn( cx. ccx. llmod, s, llfnty) ;
@@ -6235,18 +6262,19 @@ fn trans_obj(@local_ctxt cx, &ast._obj ob, ast.def_id oid,
6235
6262
auto fcx = new_fn_ctxt( cx, llctor_decl) ;
6236
6263
create_llargs_for_fn_args( fcx, ast. proto_fn,
6237
6264
none[ tup( TypeRef , ty. t) ] ,
6238
- ret_ty_of_fn( cx . ccx, ann) ,
6265
+ ret_ty_of_fn( ccx, ann) ,
6239
6266
fn_args, ty_params) ;
6240
6267
6241
- let vec[ ty. arg] arg_tys = arg_tys_of_fn( cx . ccx, ann) ;
6268
+ let vec[ ty. arg] arg_tys = arg_tys_of_fn( ccx, ann) ;
6242
6269
copy_args_to_allocas( fcx, fn_args, arg_tys) ;
6243
6270
6244
6271
auto bcx = new_top_block_ctxt( fcx) ;
6245
6272
auto lltop = bcx. llbb;
6246
6273
6247
- auto self_ty = ret_ty_of_fn( cx . ccx, ann) ;
6274
+ auto self_ty = ret_ty_of_fn( ccx, ann) ;
6248
6275
auto llself_ty = type_of( ccx, self_ty) ;
6249
6276
auto pair = bcx. fcx. llretptr;
6277
+
6250
6278
auto vtbl = trans_vtbl( cx, llself_ty, self_ty, ob, ty_params) ;
6251
6279
auto pair_vtbl = bcx. build. GEP ( pair,
6252
6280
vec( C_int ( 0 ) ,
@@ -6270,19 +6298,19 @@ fn trans_obj(@local_ctxt cx, &ast._obj ob, ast.def_id oid,
6270
6298
}
6271
6299
6272
6300
// Synthesize an obj body type.
6273
- auto tydesc_ty = ty. mk_type( cx . ccx. tcx) ;
6301
+ auto tydesc_ty = ty. mk_type( ccx. tcx) ;
6274
6302
let vec[ ty. t] tps = vec( ) ;
6275
6303
for ( ast. ty_param tp in ty_params) {
6276
6304
_vec. push[ ty. t] ( tps, tydesc_ty) ;
6277
6305
}
6278
6306
6279
- let ty. t typarams_ty = ty. mk_imm_tup( cx . ccx. tcx, tps) ;
6280
- let ty. t fields_ty = ty. mk_imm_tup( cx . ccx. tcx, obj_fields) ;
6281
- let ty. t body_ty = ty. mk_imm_tup( cx . ccx. tcx,
6307
+ let ty. t typarams_ty = ty. mk_imm_tup( ccx. tcx, tps) ;
6308
+ let ty. t fields_ty = ty. mk_imm_tup( ccx. tcx, obj_fields) ;
6309
+ let ty. t body_ty = ty. mk_imm_tup( ccx. tcx,
6282
6310
vec( tydesc_ty,
6283
6311
typarams_ty,
6284
6312
fields_ty) ) ;
6285
- let ty. t boxed_body_ty = ty. mk_imm_box( cx . ccx. tcx, body_ty) ;
6313
+ let ty. t boxed_body_ty = ty. mk_imm_box( ccx. tcx, body_ty) ;
6286
6314
6287
6315
// Malloc a box for the body.
6288
6316
auto box = trans_malloc_boxed( bcx, body_ty) ;
@@ -6301,14 +6329,6 @@ fn trans_obj(@local_ctxt cx, &ast._obj ob, ast.def_id oid,
6301
6329
vec( 0 , abi. obj_body_elt_tydesc) ) ;
6302
6330
bcx = body_tydesc. bcx;
6303
6331
6304
- auto dtor = C_null ( T_ptr ( T_glue_fn ( ccx. tn) ) ) ;
6305
- alt ( ob. dtor) {
6306
- case ( some[ @ast. method] ( ?d) ) {
6307
- dtor = trans_dtor( cx, llself_ty, self_ty, ty_params, d) ;
6308
- }
6309
- case ( none[ @ast. method] ) { }
6310
- }
6311
-
6312
6332
auto body_td = get_tydesc( bcx, body_ty) ;
6313
6333
bcx = body_td. bcx;
6314
6334
bcx. build. Store ( body_td. val, body_tydesc. val) ;
0 commit comments