mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-25 13:24:22 +00:00
parent
fa1295343f
commit
a35dbf3fd5
@ -1321,7 +1321,9 @@ fn make_take_glue(cx: @block_ctxt, v: ValueRef, t: ty::t) {
|
||||
bcx = incr_refcnt_of_boxed(bcx, Load(bcx, v));
|
||||
} else if ty::type_is_unique_box(bcx_tcx(bcx), t) {
|
||||
check trans_uniq::type_is_unique_box(bcx, t);
|
||||
bcx = trans_uniq::duplicate(bcx, v, t);
|
||||
let {bcx: cx, val} = trans_uniq::duplicate(bcx, Load(bcx, v), t);
|
||||
bcx = cx;
|
||||
Store(bcx, val, v);
|
||||
} else if ty::type_is_structural(bcx_tcx(bcx), t) {
|
||||
bcx = iter_structural_ty(bcx, v, t, take_ty);
|
||||
} else if ty::type_is_vec(bcx_tcx(bcx), t) {
|
||||
@ -1954,6 +1956,27 @@ fn drop_ty(cx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
|
||||
ret cx;
|
||||
}
|
||||
|
||||
fn drop_ty_immediate(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
|
||||
alt ty::struct(bcx_tcx(bcx), t) {
|
||||
ty::ty_box(_) { ret decr_refcnt_maybe_free(bcx, v, t); }
|
||||
ty::ty_uniq(_) { ret free_ty(bcx, v, t); }
|
||||
// FIXME A ty_ptr pointing at something that needs drop glue is somehow
|
||||
// marked as needing drop glue. This is probably a mistake.
|
||||
ty::ty_ptr(_) { ret bcx; }
|
||||
}
|
||||
}
|
||||
|
||||
fn take_ty_immediate(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> result {
|
||||
alt ty::struct(bcx_tcx(bcx), t) {
|
||||
ty::ty_box(_) { ret rslt(incr_refcnt_of_boxed(bcx, v), v); }
|
||||
ty::ty_uniq(_) {
|
||||
check trans_uniq::type_is_unique_box(bcx, t);
|
||||
ret trans_uniq::duplicate(bcx, v, t);
|
||||
}
|
||||
_ { ret rslt(bcx, v); }
|
||||
}
|
||||
}
|
||||
|
||||
fn free_ty(cx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
|
||||
if ty::type_has_pointers(bcx_tcx(cx), t) {
|
||||
ret call_tydesc_glue(cx, v, t, abi::tydesc_field_free_glue);
|
||||
@ -4059,8 +4082,8 @@ fn get_landing_pad(bcx: @block_ctxt,
|
||||
let scope_bcx = find_scope_for_lpad(bcx, have_zero_or_revoke);
|
||||
if scope_bcx.lpad_dirty || have_zero_or_revoke {
|
||||
let unwind_bcx = new_sub_block_ctxt(bcx, "unwind");
|
||||
let lpadbb = trans_landing_pad(unwind_bcx, to_zero, to_revoke);
|
||||
scope_bcx.lpad = some(lpadbb);
|
||||
trans_landing_pad(unwind_bcx, to_zero, to_revoke);
|
||||
scope_bcx.lpad = some(unwind_bcx.llbb);
|
||||
scope_bcx.lpad_dirty = have_zero_or_revoke;
|
||||
}
|
||||
assert option::is_some(scope_bcx.lpad);
|
||||
@ -4418,10 +4441,15 @@ fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
||||
let ty = ty::expr_ty(bcx_tcx(bcx), e);
|
||||
alt dest {
|
||||
by_val(cell) {
|
||||
if kind != owned {
|
||||
if kind == temporary {
|
||||
revoke_clean(bcx, val);
|
||||
*cell = val;
|
||||
} else if kind == owned_imm {
|
||||
let {bcx: cx, val} = take_ty_immediate(bcx, val, ty);
|
||||
*cell = val;
|
||||
bcx = cx;
|
||||
} else if ty::type_is_unique(bcx_tcx(bcx), ty) {
|
||||
// FIXME make vectors immediate again, lose this hack
|
||||
// Do a song and a dance to work around the fact that take_ty
|
||||
// for unique boxes overwrites the pointer.
|
||||
let oldval = Load(bcx, val);
|
||||
@ -4723,9 +4751,15 @@ fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt {
|
||||
// This is a local that is kept immediate
|
||||
none. {
|
||||
let initexpr = alt local.node.init { some({expr, _}) { expr } };
|
||||
let val = trans_temp_expr(bcx, initexpr);
|
||||
bcx.fcx.lllocals.insert(local.node.pat.id, local_imm(val.val));
|
||||
ret val.bcx;
|
||||
let {bcx, val, kind} = trans_temp_lval(bcx, initexpr);
|
||||
if kind != temporary {
|
||||
if kind == owned { val = Load(bcx, val); }
|
||||
let rs = take_ty_immediate(bcx, val, ty);
|
||||
bcx = rs.bcx; val = rs.val;
|
||||
add_clean_temp(bcx, val, ty);
|
||||
}
|
||||
bcx.fcx.lllocals.insert(local.node.pat.id, local_imm(val));
|
||||
ret bcx;
|
||||
}
|
||||
};
|
||||
|
||||
@ -4984,8 +5018,7 @@ fn alloc_local(cx: @block_ctxt, local: @ast::local) -> @block_ctxt {
|
||||
};
|
||||
// Do not allocate space for locals that can be kept immediate.
|
||||
if is_simple && !bcx_ccx(cx).mut_map.contains_key(local.node.pat.id) &&
|
||||
ty::type_is_immediate(bcx_tcx(cx), t) &&
|
||||
!ty::type_needs_drop(bcx_tcx(cx), t) {
|
||||
ty::type_is_immediate(bcx_tcx(cx), t) {
|
||||
alt local.node.init {
|
||||
some({op: ast::init_assign., _}) { ret cx; }
|
||||
_ {}
|
||||
|
@ -271,17 +271,17 @@ fn add_clean(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
|
||||
}
|
||||
fn add_clean_temp(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
|
||||
if !ty::type_needs_drop(bcx_tcx(cx), ty) { ret; }
|
||||
fn spill_and_drop(cx: @block_ctxt, val: ValueRef, ty: ty::t) ->
|
||||
fn do_drop(bcx: @block_ctxt, val: ValueRef, ty: ty::t) ->
|
||||
@block_ctxt {
|
||||
let bcx = cx;
|
||||
let r = trans::spill_if_immediate(bcx, val, ty);
|
||||
let spilled = r.val;
|
||||
bcx = r.bcx;
|
||||
ret drop_ty(bcx, spilled, ty);
|
||||
if ty::type_is_immediate(bcx_tcx(bcx), ty) {
|
||||
ret trans::drop_ty_immediate(bcx, val, ty);
|
||||
} else {
|
||||
ret drop_ty(bcx, val, ty);
|
||||
}
|
||||
}
|
||||
let scope_cx = find_scope_cx(cx);
|
||||
scope_cx.cleanups +=
|
||||
[clean_temp(val, bind spill_and_drop(_, val, ty))];
|
||||
[clean_temp(val, bind do_drop(_, val, ty))];
|
||||
scope_cx.lpad_dirty = true;
|
||||
}
|
||||
fn add_clean_temp_mem(cx: @block_ctxt, val: ValueRef, ty: ty::t) {
|
||||
|
@ -98,15 +98,13 @@ fn autoderef(bcx: @block_ctxt, v: ValueRef, t: ty::t)
|
||||
}
|
||||
|
||||
fn duplicate(bcx: @block_ctxt, v: ValueRef, t: ty::t)
|
||||
: type_is_unique_box(bcx, t) -> @block_ctxt {
|
||||
: type_is_unique_box(bcx, t) -> result {
|
||||
|
||||
let content_ty = content_ty(bcx, t);
|
||||
let {bcx, val: llptr} = alloc_uniq(bcx, t);
|
||||
|
||||
let src = Load(bcx, v);
|
||||
let src = load_if_immediate(bcx, src, content_ty);
|
||||
let src = load_if_immediate(bcx, v, content_ty);
|
||||
let dst = llptr;
|
||||
let bcx = trans::copy_val(bcx, INIT, dst, src, content_ty);
|
||||
Store(bcx, dst, v);
|
||||
ret bcx;
|
||||
ret rslt(bcx, dst);
|
||||
}
|
Loading…
Reference in New Issue
Block a user