@@ -1292,20 +1292,27 @@ fn emit_tydescs(ccx: @crate_ctxt) {
1292
1292
1293
1293
fn make_take_glue ( cx : @block_ctxt , v : ValueRef , t : ty:: t ) {
1294
1294
let bcx = cx;
1295
+ let tcx = bcx_tcx ( cx) ;
1295
1296
// NB: v is an *alias* of type t here, not a direct value.
1296
- if ty:: type_is_boxed ( bcx_tcx ( bcx) , t) {
1297
+ alt ty:: struct ( tcx, t) {
1298
+ ty:: ty_box ( _) {
1297
1299
bcx = incr_refcnt_of_boxed ( bcx, Load ( bcx, v) ) ;
1298
- } else if ty:: type_is_unique_box ( bcx_tcx ( bcx) , t) {
1300
+ }
1301
+ ty:: ty_uniq ( _) {
1299
1302
check trans_uniq:: type_is_unique_box ( bcx, t) ;
1300
1303
let { bcx: cx , val } = trans_uniq:: duplicate ( bcx, Load ( bcx, v) , t) ;
1301
1304
bcx = cx;
1302
1305
Store ( bcx, val, v) ;
1303
- } else if ty:: type_is_structural ( bcx_tcx ( bcx) , t) {
1304
- bcx = iter_structural_ty ( bcx, v, t, take_ty) ;
1305
- } else if ty:: type_is_vec ( bcx_tcx ( bcx) , t) {
1306
+ }
1307
+ ty:: ty_vec ( _) | ty:: ty_str. {
1306
1308
let { bcx: cx , val } = tvec:: duplicate ( bcx, Load ( bcx, v) , t) ;
1307
1309
bcx = cx;
1308
1310
Store ( bcx, val, v) ;
1311
+ }
1312
+ _ when ty:: type_is_structural ( bcx_tcx ( bcx) , t) {
1313
+ bcx = iter_structural_ty ( bcx, v, t, take_ty) ;
1314
+ }
1315
+ _ { /* fallthrough */ }
1309
1316
}
1310
1317
1311
1318
build_return ( bcx) ;
@@ -1321,6 +1328,19 @@ fn incr_refcnt_of_boxed(cx: @block_ctxt, box_ptr: ValueRef) -> @block_ctxt {
1321
1328
ret cx;
1322
1329
}
1323
1330
1331
+ fn call_bound_data_glue_for_closure ( bcx : @block_ctxt ,
1332
+ v : ValueRef ,
1333
+ field : int ) {
1334
+ // Call through the closure's own fields-drop glue.
1335
+ let ccx = bcx_ccx ( bcx) ;
1336
+ let v = PointerCast ( bcx, v, T_opaque_closure_ptr ( ccx) ) ;
1337
+ let body = GEPi ( bcx, v, [ 0 , abi:: box_rc_field_body] ) ;
1338
+ let bindings = GEPi ( bcx, body, [ 0 , abi:: closure_elt_bindings] ) ;
1339
+ let tydescptr = GEPi ( bcx, body, [ 0 , abi:: closure_elt_tydesc] ) ;
1340
+ let ti = none;
1341
+ call_tydesc_glue_full ( bcx, bindings, Load ( bcx, tydescptr) , field, ti) ;
1342
+ }
1343
+
1324
1344
fn make_free_glue ( bcx : @block_ctxt , v : ValueRef , t : ty:: t ) {
1325
1345
// v is a pointer to the actual box component of the type here. The
1326
1346
// ValueRef will have the wrong type here (make_generic_glue is casting
@@ -1359,19 +1379,22 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) {
1359
1379
trans_non_gc_free ( bcx, b)
1360
1380
} else { bcx }
1361
1381
}
1362
- ty:: ty_fn ( _, _, _, _, _) {
1363
- // Call through the closure's own fields-drop glue first.
1364
- // Then free the body.
1365
- let ccx = bcx_ccx ( bcx) ;
1366
- let v = PointerCast ( bcx, v, T_opaque_closure_ptr ( ccx) ) ;
1367
- let body = GEPi ( bcx, v, [ 0 , abi:: box_rc_field_body] ) ;
1368
- let bindings =
1369
- GEPi ( bcx, body, [ 0 , abi:: closure_elt_bindings] ) ;
1370
- let tydescptr =
1371
- GEPi ( bcx, body, [ 0 , abi:: closure_elt_tydesc] ) ;
1372
- let ti = none;
1373
- call_tydesc_glue_full ( bcx, bindings, Load ( bcx, tydescptr) ,
1374
- abi:: tydesc_field_drop_glue, ti) ;
1382
+ ty:: ty_fn ( ast:: proto_bare. , _, _, _, _) {
1383
+ bcx
1384
+ }
1385
+ ty:: ty_fn ( ast:: proto_block. , _, _, _, _) {
1386
+ bcx
1387
+ }
1388
+ ty:: ty_fn ( ast:: proto_send. , _, _, _, _) {
1389
+ // n.b.: When we drop a function, we actually invoke the
1390
+ // free glue only on the environment part.
1391
+ call_bound_data_glue_for_closure ( bcx, v, abi:: tydesc_field_drop_glue) ;
1392
+ trans_shared_free ( bcx, v)
1393
+ }
1394
+ ty:: ty_fn ( ast:: proto_shared ( _) , _, _, _, _) {
1395
+ // n.b.: When we drop a function, we actually invoke the
1396
+ // free glue only on the environment part.
1397
+ call_bound_data_glue_for_closure ( bcx, v, abi:: tydesc_field_drop_glue) ;
1375
1398
if !bcx_ccx ( bcx) . sess . get_opts ( ) . do_gc {
1376
1399
trans_non_gc_free ( bcx, v)
1377
1400
} else { bcx }
@@ -1398,7 +1421,18 @@ fn make_drop_glue(bcx: @block_ctxt, v0: ValueRef, t: ty::t) {
1398
1421
ty:: ty_res ( did, inner, tps) {
1399
1422
trans_res_drop ( bcx, v0, did, inner, tps)
1400
1423
}
1401
- ty:: ty_fn ( _, _, _, _, _) {
1424
+ ty:: ty_fn ( ast:: proto_bare. , _, _, _, _) {
1425
+ bcx // No environment to free.
1426
+ }
1427
+ ty:: ty_fn ( ast:: proto_block. , _, _, _, _) {
1428
+ bcx // Environment is stack allocated and needs no free.
1429
+ }
1430
+ ty:: ty_fn ( ast:: proto_send. , _, _, _, _) {
1431
+ // Environment is a unique pointer.
1432
+ let box_cell = GEPi ( bcx, v0, [ 0 , abi:: fn_field_box] ) ;
1433
+ free_ty ( bcx, Load ( bcx, box_cell) , t)
1434
+ }
1435
+ ty:: ty_fn ( ast:: proto_shared ( _) , _, _, _, _) {
1402
1436
let box_cell = GEPi ( bcx, v0, [ 0 , abi:: fn_field_box] ) ;
1403
1437
decr_refcnt_maybe_free ( bcx, Load ( bcx, box_cell) , t)
1404
1438
}
0 commit comments