Skip to content

Commit f7cce6b

Browse files
committed
pull out the code from iter_structural_ty for handling functions,
as we will have to do very careful and non-generic things
1 parent 7c7cb26 commit f7cce6b

File tree

2 files changed

+55
-29
lines changed

2 files changed

+55
-29
lines changed

src/comp/middle/trans.rs

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,13 @@ fn trans_native_call(cx: @block_ctxt, externs: hashmap<str, ValueRef>,
349349
ret Call(cx, llnative, call_args);
350350
}
351351

352-
fn trans_non_gc_free(cx: @block_ctxt, v: ValueRef) -> @block_ctxt {
353-
Call(cx, bcx_ccx(cx).upcalls.free,
354-
[PointerCast(cx, v, T_ptr(T_i8())),
355-
C_int(bcx_ccx(cx), 0)]);
352+
fn trans_free_if_not_gc(cx: @block_ctxt, v: ValueRef) -> @block_ctxt {
353+
let ccx = bcx_ccx(cx);
354+
if !ccx.sess.get_opts().do_gc {
355+
Call(cx, ccx.upcalls.free,
356+
[PointerCast(cx, v, T_ptr(T_i8())),
357+
C_int(bcx_ccx(cx), 0)]);
358+
}
356359
ret cx;
357360
}
358361

@@ -1291,29 +1294,62 @@ fn emit_tydescs(ccx: @crate_ctxt) {
12911294
}
12921295

12931296
fn make_take_glue(cx: @block_ctxt, v: ValueRef, t: ty::t) {
1297+
1298+
fn take_fn_env(cx: @block_ctxt,
1299+
v: ValueRef,
1300+
blk: block(@block_ctxt, ValueRef) -> @block_ctxt)
1301+
-> @block_ctxt {
1302+
let box_cell_v = GEPi(cx, v, [0, abi::fn_field_box]);
1303+
let box_ptr_v = Load(cx, box_cell_v);
1304+
let inner_cx = new_sub_block_ctxt(cx, "iter box");
1305+
let next_cx = new_sub_block_ctxt(cx, "next");
1306+
let null_test = IsNull(cx, box_ptr_v);
1307+
CondBr(cx, null_test, next_cx.llbb, inner_cx.llbb);
1308+
inner_cx = blk(inner_cx, box_ptr_v);
1309+
Br(inner_cx, next_cx.llbb);
1310+
ret next_cx;
1311+
}
1312+
1313+
12941314
let bcx = cx;
12951315
let tcx = bcx_tcx(cx);
12961316
// NB: v is an *alias* of type t here, not a direct value.
1297-
alt ty::struct(tcx, t) {
1317+
bcx = alt ty::struct(tcx, t) {
12981318
ty::ty_box(_) {
1299-
bcx = incr_refcnt_of_boxed(bcx, Load(bcx, v));
1319+
incr_refcnt_of_boxed(bcx, Load(bcx, v))
13001320
}
13011321
ty::ty_uniq(_) {
13021322
check trans_uniq::type_is_unique_box(bcx, t);
1303-
let {bcx: cx, val} = trans_uniq::duplicate(bcx, Load(bcx, v), t);
1304-
bcx = cx;
1305-
Store(bcx, val, v);
1323+
let r = trans_uniq::duplicate(bcx, Load(bcx, v), t);
1324+
Store(r.bcx, r.val, v);
1325+
r.bcx
13061326
}
13071327
ty::ty_vec(_) | ty::ty_str. {
1308-
let {bcx: cx, val} = tvec::duplicate(bcx, Load(bcx, v), t);
1309-
bcx = cx;
1310-
Store(bcx, val, v);
1328+
let r = tvec::duplicate(bcx, Load(bcx, v), t);
1329+
Store(r.bcx, r.val, v);
1330+
r.bcx
1331+
}
1332+
ty::ty_fn(ast::proto_bare., _, _, _, _) {
1333+
bcx
1334+
}
1335+
ty::ty_fn(ast::proto_block., _, _, _, _) {
1336+
bcx
1337+
}
1338+
ty::ty_fn(ast::proto_send., _, _, _, _) {
1339+
take_fn_env(bcx, v, { |bcx, _box_ptr_v|
1340+
bcx // NDM
1341+
})
1342+
}
1343+
ty::ty_fn(ast::proto_shared(_), _, _, _, _) {
1344+
take_fn_env(bcx, v, { |bcx, box_ptr_v|
1345+
incr_refcnt_of_boxed(bcx, box_ptr_v)
1346+
})
13111347
}
13121348
_ when ty::type_is_structural(bcx_tcx(bcx), t) {
1313-
bcx = iter_structural_ty(bcx, v, t, take_ty);
1349+
iter_structural_ty(bcx, v, t, take_ty)
13141350
}
1315-
_ { /* fallthrough */ }
1316-
}
1351+
_ { bcx }
1352+
};
13171353

13181354
build_return(bcx);
13191355
}
@@ -1350,9 +1386,7 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) {
13501386
let v = PointerCast(bcx, v, type_of_1(bcx, t));
13511387
let body = GEPi(bcx, v, [0, abi::box_rc_field_body]);
13521388
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 }
1389+
trans_free_if_not_gc(bcx, v)
13561390
}
13571391
ty::ty_uniq(content_mt) {
13581392
check trans_uniq::type_is_unique_box(bcx, t);
@@ -1375,9 +1409,7 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) {
13751409
let ti = none;
13761410
call_tydesc_glue_full(bcx, body, tydesc,
13771411
abi::tydesc_field_drop_glue, ti);
1378-
if !bcx_ccx(bcx).sess.get_opts().do_gc {
1379-
trans_non_gc_free(bcx, b)
1380-
} else { bcx }
1412+
trans_free_if_not_gc(bcx, b)
13811413
}
13821414
ty::ty_fn(ast::proto_bare., _, _, _, _) {
13831415
bcx
@@ -1395,9 +1427,7 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) {
13951427
// n.b.: When we drop a function, we actually invoke the
13961428
// free glue only on the environment part.
13971429
call_bound_data_glue_for_closure(bcx, v, abi::tydesc_field_drop_glue);
1398-
if !bcx_ccx(bcx).sess.get_opts().do_gc {
1399-
trans_non_gc_free(bcx, v)
1400-
} else { bcx }
1430+
trans_free_if_not_gc(bcx, v)
14011431
}
14021432
_ { bcx }
14031433
};
@@ -1728,10 +1758,6 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t,
17281758
}
17291759
ret next_cx;
17301760
}
1731-
ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _) {
1732-
let box_cell_a = GEPi(cx, av, [0, abi::fn_field_box]);
1733-
ret iter_boxpp(cx, box_cell_a, f);
1734-
}
17351761
ty::ty_obj(_) {
17361762
let box_cell_a = GEPi(cx, av, [0, abi::obj_field_box]);
17371763
ret iter_boxpp(cx, box_cell_a, f);

src/comp/middle/trans_common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ fn add_clean_temp_mem(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
275275
fn add_clean_free(cx: @block_ctxt, ptr: ValueRef, shared: bool) {
276276
let scope_cx = find_scope_cx(cx);
277277
let free_fn = if shared { bind trans::trans_shared_free(_, ptr) }
278-
else { bind trans::trans_non_gc_free(_, ptr) };
278+
else { bind trans::trans_free_if_not_gc(_, ptr) };
279279
scope_cx.cleanups += [clean_temp(ptr, free_fn)];
280280
scope_cx.lpad_dirty = true;
281281
}

0 commit comments

Comments
 (0)