@@ -46,6 +46,12 @@ import trans_build::*;
46
46
import trans_objects:: { trans_anon_obj, trans_obj} ;
47
47
import tvec = trans_vec;
48
48
49
+ fn type_of_1 ( bcx : @block_ctxt , t : ty:: t ) -> TypeRef {
50
+ let cx = bcx_ccx ( bcx) ;
51
+ check type_has_static_size ( cx, t) ;
52
+ type_of ( cx, bcx. sp , t)
53
+ }
54
+
49
55
fn type_of( cx : @crate_ctxt , sp : span , t : ty:: t ) : type_has_static_size ( cx , t )
50
56
-> TypeRef {
51
57
// Should follow from type_has_static_size -- argh.
@@ -1335,62 +1341,59 @@ fn incr_refcnt_of_boxed(cx: @block_ctxt, box_ptr: ValueRef) -> @block_ctxt {
1335
1341
ret cx;
1336
1342
}
1337
1343
1338
- fn make_free_glue ( bcx : @block_ctxt , v0 : ValueRef , t : ty:: t ) {
1339
- // NB: v is an *alias* of type t here, not a direct value.
1340
- let bcx =
1341
- alt ty:: struct ( bcx_tcx ( bcx) , t) {
1342
- ty:: ty_box ( body_mt) {
1343
- let v = Load ( bcx, v0) ;
1344
- let body = GEP ( bcx, v, [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ] ) ;
1345
- let bcx = drop_ty ( bcx, body, body_mt. ty ) ;
1346
- if !bcx_ccx ( bcx) . sess . get_opts ( ) . do_gc {
1347
- trans_non_gc_free ( bcx, v)
1348
- } else { bcx }
1349
- }
1350
- ty:: ty_uniq ( content_mt) {
1351
- check trans_uniq:: type_is_unique_box ( bcx, t) ;
1352
- trans_uniq:: make_free_glue ( bcx, v0, t)
1353
- }
1354
- ty:: ty_obj ( _) {
1355
- // Call through the obj's own fields-drop glue first.
1356
- // Then free the body.
1357
- let box_cell =
1358
- GEP ( bcx, v0, [ C_int ( 0 ) , C_int ( abi:: obj_field_box) ] ) ;
1359
- let b = Load ( bcx, box_cell) ;
1360
- let ccx = bcx_ccx ( bcx) ;
1361
- let llbox_ty = T_opaque_obj_ptr ( * ccx) ;
1362
- b = PointerCast ( bcx, b, llbox_ty) ;
1363
- let body = GEP ( bcx, b, [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ] ) ;
1364
- let tydescptr =
1365
- GEP ( bcx, body, [ C_int ( 0 ) , C_int ( abi:: obj_body_elt_tydesc) ] ) ;
1366
- let tydesc = Load ( bcx, tydescptr) ;
1367
- let ti = none;
1368
- call_tydesc_glue_full ( bcx, body, tydesc,
1369
- abi:: tydesc_field_drop_glue, ti) ;
1370
- if !bcx_ccx ( bcx) . sess . get_opts ( ) . do_gc {
1371
- trans_non_gc_free ( bcx, b)
1372
- } else { bcx }
1373
- }
1374
- ty:: ty_fn ( _, _, _, _, _) {
1375
- // Call through the closure's own fields-drop glue first.
1376
- // Then free the body.
1377
- let box_cell = GEP ( bcx, v0, [ C_int ( 0 ) , C_int ( abi:: fn_field_box) ] ) ;
1378
- let v = Load ( bcx, box_cell) ;
1379
- let body = GEP ( bcx, v, [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ] ) ;
1380
- let bindings =
1381
- GEP ( bcx, body, [ C_int ( 0 ) , C_int ( abi:: closure_elt_bindings) ] ) ;
1382
- let tydescptr =
1383
- GEP ( bcx, body, [ C_int ( 0 ) , C_int ( abi:: closure_elt_tydesc) ] ) ;
1384
- let ti = none;
1385
- call_tydesc_glue_full ( bcx, bindings, Load ( bcx, tydescptr) ,
1386
- abi:: tydesc_field_drop_glue, ti) ;
1387
- if !bcx_ccx ( bcx) . sess . get_opts ( ) . do_gc {
1388
- trans_non_gc_free ( bcx, v)
1389
- } else { bcx }
1390
- }
1391
- _ { bcx }
1392
- } ;
1393
-
1344
+ fn make_free_glue ( bcx : @block_ctxt , v : ValueRef , t : ty:: t ) {
1345
+ // v is a pointer to the actual box component of the type here. The
1346
+ // ValueRef will have the wrong type here (make_generic_glue is casting
1347
+ // everything to a pointer to the type that the glue acts on).
1348
+ let bcx = alt ty:: struct ( bcx_tcx ( bcx) , t) {
1349
+ ty:: ty_box ( body_mt) {
1350
+ v = PointerCast ( bcx, v, type_of_1 ( bcx, t) ) ;
1351
+ let body = GEP ( bcx, v, [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ] ) ;
1352
+ let bcx = drop_ty ( bcx, body, body_mt. ty ) ;
1353
+ if !bcx_ccx ( bcx) . sess . get_opts ( ) . do_gc {
1354
+ trans_non_gc_free ( bcx, v)
1355
+ } else { bcx }
1356
+ }
1357
+ ty:: ty_uniq ( content_mt) {
1358
+ check trans_uniq:: type_is_unique_box ( bcx, t) ;
1359
+ v = PointerCast ( bcx, v, type_of_1 ( bcx, t) ) ;
1360
+ trans_uniq:: make_free_glue ( bcx, v, t)
1361
+ }
1362
+ ty:: ty_obj ( _) {
1363
+ // Call through the obj's own fields-drop glue first.
1364
+ // Then free the body.
1365
+ let ccx = bcx_ccx ( bcx) ;
1366
+ let llbox_ty = T_opaque_obj_ptr ( * ccx) ;
1367
+ let b = PointerCast ( bcx, v, llbox_ty) ;
1368
+ let body = GEP ( bcx, b, [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ] ) ;
1369
+ let tydescptr =
1370
+ GEP ( bcx, body, [ C_int ( 0 ) , C_int ( abi:: obj_body_elt_tydesc) ] ) ;
1371
+ let tydesc = Load ( bcx, tydescptr) ;
1372
+ let ti = none;
1373
+ call_tydesc_glue_full ( bcx, body, tydesc,
1374
+ abi:: tydesc_field_drop_glue, ti) ;
1375
+ if !bcx_ccx ( bcx) . sess . get_opts ( ) . do_gc {
1376
+ trans_non_gc_free ( bcx, b)
1377
+ } else { bcx }
1378
+ }
1379
+ ty:: ty_fn ( _, _, _, _, _) {
1380
+ // Call through the closure's own fields-drop glue first.
1381
+ // Then free the body.
1382
+ v = PointerCast ( bcx, v, T_opaque_closure_ptr ( * bcx_ccx ( bcx) ) ) ;
1383
+ let body = GEP ( bcx, v, [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ] ) ;
1384
+ let bindings =
1385
+ GEP ( bcx, body, [ C_int ( 0 ) , C_int ( abi:: closure_elt_bindings) ] ) ;
1386
+ let tydescptr =
1387
+ GEP ( bcx, body, [ C_int ( 0 ) , C_int ( abi:: closure_elt_tydesc) ] ) ;
1388
+ let ti = none;
1389
+ call_tydesc_glue_full ( bcx, bindings, Load ( bcx, tydescptr) ,
1390
+ abi:: tydesc_field_drop_glue, ti) ;
1391
+ if !bcx_ccx ( bcx) . sess . get_opts ( ) . do_gc {
1392
+ trans_non_gc_free ( bcx, v)
1393
+ } else { bcx }
1394
+ }
1395
+ _ { bcx }
1396
+ } ;
1394
1397
build_return ( bcx) ;
1395
1398
}
1396
1399
@@ -1401,21 +1404,19 @@ fn make_drop_glue(bcx: @block_ctxt, v0: ValueRef, t: ty::t) {
1401
1404
alt ty:: struct ( ccx. tcx , t) {
1402
1405
ty:: ty_vec ( _) { tvec:: make_drop_glue ( bcx, v0, t) }
1403
1406
ty:: ty_str. { tvec:: make_drop_glue ( bcx, v0, t) }
1404
- ty:: ty_box ( _) { decr_refcnt_maybe_free ( bcx, v0, v0, t) }
1405
- ty:: ty_uniq ( _) {
1406
- free_ty ( bcx, v0, t)
1407
- }
1407
+ ty:: ty_box ( _) { decr_refcnt_maybe_free ( bcx, Load ( bcx, v0) , t) }
1408
+ ty:: ty_uniq ( _) { free_ty ( bcx, Load ( bcx, v0) , t) }
1408
1409
ty:: ty_obj ( _) {
1409
1410
let box_cell =
1410
1411
GEP ( bcx, v0, [ C_int ( 0 ) , C_int ( abi:: obj_field_box) ] ) ;
1411
- decr_refcnt_maybe_free ( bcx, box_cell , v0 , t)
1412
+ decr_refcnt_maybe_free ( bcx, Load ( bcx , box_cell ) , t)
1412
1413
}
1413
1414
ty:: ty_res ( did, inner, tps) {
1414
1415
trans_res_drop ( bcx, v0, did, inner, tps)
1415
1416
}
1416
1417
ty:: ty_fn ( _, _, _, _, _) {
1417
1418
let box_cell = GEP ( bcx, v0, [ C_int ( 0 ) , C_int ( abi:: fn_field_box) ] ) ;
1418
- decr_refcnt_maybe_free ( bcx, box_cell , v0 , t)
1419
+ decr_refcnt_maybe_free ( bcx, Load ( bcx , box_cell ) , t)
1419
1420
}
1420
1421
_ {
1421
1422
if ty:: type_has_pointers ( ccx. tcx , t) &&
@@ -1470,13 +1471,12 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id,
1470
1471
ret next_cx;
1471
1472
}
1472
1473
1473
- fn decr_refcnt_maybe_free ( cx : @block_ctxt , box_ptr_alias : ValueRef ,
1474
- full_alias : ValueRef , t : ty :: t ) -> @block_ctxt {
1474
+ fn decr_refcnt_maybe_free ( cx : @block_ctxt , box_ptr : ValueRef , t : ty :: t )
1475
+ -> @block_ctxt {
1475
1476
let ccx = bcx_ccx ( cx) ;
1476
1477
let rc_adj_cx = new_sub_block_ctxt ( cx, "rc--" ) ;
1477
1478
let free_cx = new_sub_block_ctxt ( cx, "free" ) ;
1478
1479
let next_cx = new_sub_block_ctxt ( cx, "next" ) ;
1479
- let box_ptr = Load ( cx, box_ptr_alias) ;
1480
1480
let llbox_ty = T_opaque_obj_ptr ( * ccx) ;
1481
1481
box_ptr = PointerCast ( cx, box_ptr, llbox_ty) ;
1482
1482
let null_test = IsNull ( cx, box_ptr) ;
@@ -1488,7 +1488,7 @@ fn decr_refcnt_maybe_free(cx: @block_ctxt, box_ptr_alias: ValueRef,
1488
1488
Store ( rc_adj_cx, rc, rc_ptr) ;
1489
1489
let zero_test = ICmp ( rc_adj_cx, lib:: llvm:: LLVMIntEQ , C_int ( 0 ) , rc) ;
1490
1490
CondBr ( rc_adj_cx, zero_test, free_cx. llbb , next_cx. llbb ) ;
1491
- let free_cx = free_ty ( free_cx, full_alias , t) ;
1491
+ let free_cx = free_ty ( free_cx, box_ptr , t) ;
1492
1492
Br ( free_cx, next_cx. llbb ) ;
1493
1493
ret next_cx;
1494
1494
}
0 commit comments