Start using copy glue to copy bits that may contain ivecs
This is not currently necessary, but will be, when I land the new ivec representation.
This commit is contained in:
@@ -1272,7 +1272,10 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_copy_glue(cx: &@block_ctxt, dst: ValueRef, src: ValueRef, t: ty::t) {
|
// NOTE this is currently just a complicated way to do memmove. I'm working on
|
||||||
|
// a representation of ivecs that will need pointers into itself, which must
|
||||||
|
// be adjusted when copying. Will flesh this out when the time comes.
|
||||||
|
fn make_copy_glue(cx: &@block_ctxt, src: ValueRef, dst: ValueRef, t: ty::t) {
|
||||||
let bcx = memmove_ty(cx, dst, src, t).bcx;
|
let bcx = memmove_ty(cx, dst, src, t).bcx;
|
||||||
build_return(bcx);
|
build_return(bcx);
|
||||||
}
|
}
|
||||||
@@ -2369,9 +2372,12 @@ fn copy_val_no_check(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
|
|||||||
let bcx = if action == DROP_EXISTING {
|
let bcx = if action == DROP_EXISTING {
|
||||||
drop_ty(cx, dst, t).bcx
|
drop_ty(cx, dst, t).bcx
|
||||||
} else { cx };
|
} else { cx };
|
||||||
bcx = memmove_ty(bcx, dst, src, t).bcx;
|
if ty::type_needs_copy_glue(ccx.tcx, t) {
|
||||||
bcx = take_ty(bcx, dst, t).bcx;
|
ret call_copy_glue(bcx, dst, src, t, true);
|
||||||
ret bcx;
|
} else {
|
||||||
|
bcx = memmove_ty(bcx, dst, src, t).bcx;
|
||||||
|
ret take_ty(bcx, dst, t).bcx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ccx.sess.bug("unexpected type in trans::copy_val_no_check: " +
|
ccx.sess.bug("unexpected type in trans::copy_val_no_check: " +
|
||||||
ty_to_str(ccx.tcx, t));
|
ty_to_str(ccx.tcx, t));
|
||||||
@@ -2386,16 +2392,16 @@ fn copy_val_no_check(cx: &@block_ctxt, action: copy_action, dst: ValueRef,
|
|||||||
fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
||||||
src: &lval_result, t: ty::t) -> @block_ctxt {
|
src: &lval_result, t: ty::t) -> @block_ctxt {
|
||||||
let src_val = src.res.val;
|
let src_val = src.res.val;
|
||||||
if ty::type_is_scalar(bcx_tcx(cx), t) ||
|
let tcx = bcx_tcx(cx);
|
||||||
ty::type_is_native(bcx_tcx(cx), t) {
|
if ty::type_is_scalar(tcx, t) ||
|
||||||
|
ty::type_is_native(tcx, t) {
|
||||||
if src.is_mem { src_val = cx.build.Load(src_val); }
|
if src.is_mem { src_val = cx.build.Load(src_val); }
|
||||||
cx.build.Store(src_val, dst);
|
cx.build.Store(src_val, dst);
|
||||||
ret cx;
|
ret cx;
|
||||||
} else if ty::type_is_nil(bcx_tcx(cx), t) ||
|
} else if ty::type_is_nil(tcx, t) || ty::type_is_bot(tcx, t) {
|
||||||
ty::type_is_bot(bcx_tcx(cx), t) {
|
|
||||||
ret cx;
|
ret cx;
|
||||||
} else if ty::type_is_unique(bcx_tcx(cx), t) ||
|
} else if ty::type_is_unique(tcx, t) ||
|
||||||
ty::type_is_boxed(bcx_tcx(cx), t) {
|
ty::type_is_boxed(tcx, t) {
|
||||||
if src.is_mem { src_val = cx.build.Load(src_val); }
|
if src.is_mem { src_val = cx.build.Load(src_val); }
|
||||||
if action == DROP_EXISTING {
|
if action == DROP_EXISTING {
|
||||||
cx = drop_ty(cx, cx.build.Load(dst), t).bcx;
|
cx = drop_ty(cx, cx.build.Load(dst), t).bcx;
|
||||||
@@ -2406,10 +2412,13 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
|||||||
// If we're here, it must be a temporary.
|
// If we're here, it must be a temporary.
|
||||||
revoke_clean(cx, src_val);
|
revoke_clean(cx, src_val);
|
||||||
ret cx;
|
ret cx;
|
||||||
} else if ty::type_is_structural(bcx_tcx(cx), t) ||
|
} else if type_is_structural_or_param(tcx, t) {
|
||||||
ty::type_has_dynamic_size(bcx_tcx(cx), t) {
|
|
||||||
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t).bcx; }
|
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t).bcx; }
|
||||||
cx = memmove_ty(cx, dst, src_val, t).bcx;
|
if ty::type_needs_copy_glue(tcx, t) {
|
||||||
|
cx = call_copy_glue(cx, dst, src_val, t, false);
|
||||||
|
} else {
|
||||||
|
cx = memmove_ty(cx, dst, src_val, t).bcx;
|
||||||
|
}
|
||||||
if src.is_mem {
|
if src.is_mem {
|
||||||
ret zero_alloca(cx, src_val, t).bcx;
|
ret zero_alloca(cx, src_val, t).bcx;
|
||||||
} else { // Temporary value
|
} else { // Temporary value
|
||||||
@@ -2418,7 +2427,7 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bcx_ccx(cx).sess.bug("unexpected type in trans::move_val: " +
|
bcx_ccx(cx).sess.bug("unexpected type in trans::move_val: " +
|
||||||
ty_to_str(bcx_tcx(cx), t));
|
ty_to_str(tcx, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_val_if_temp(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
fn move_val_if_temp(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
||||||
@@ -5049,16 +5058,14 @@ fn trans_expr_out(cx: &@block_ctxt, e: &@ast::expr, output: out_method) ->
|
|||||||
|
|
||||||
let rhs_res = trans_lval(lhs_res.res.bcx, src);
|
let rhs_res = trans_lval(lhs_res.res.bcx, src);
|
||||||
let t = ty::expr_ty(bcx_tcx(cx), src);
|
let t = ty::expr_ty(bcx_tcx(cx), src);
|
||||||
let tmp_res = alloc_ty(rhs_res.res.bcx, t);
|
let {bcx, val: tmp_alloc} = alloc_ty(rhs_res.res.bcx, t);
|
||||||
// Swap through a temporary.
|
// Swap through a temporary.
|
||||||
|
|
||||||
let move1_res =
|
bcx = move_val(bcx, INIT, tmp_alloc, lhs_res, t);
|
||||||
memmove_ty(tmp_res.bcx, tmp_res.val, lhs_res.res.val, t);
|
bcx = move_val(bcx, INIT, lhs_res.res.val, rhs_res, t);
|
||||||
let move2_res =
|
bcx = move_val(bcx, INIT, rhs_res.res.val,
|
||||||
memmove_ty(move1_res.bcx, lhs_res.res.val, rhs_res.res.val, t);
|
lval_mem(bcx, tmp_alloc), t);
|
||||||
let move3_res =
|
ret rslt(bcx, C_nil());
|
||||||
memmove_ty(move2_res.bcx, rhs_res.res.val, tmp_res.val, t);
|
|
||||||
ret rslt(move3_res.bcx, C_nil());
|
|
||||||
}
|
}
|
||||||
ast::expr_assign_op(op, dst, src) {
|
ast::expr_assign_op(op, dst, src) {
|
||||||
let t = ty::expr_ty(bcx_tcx(cx), src);
|
let t = ty::expr_ty(bcx_tcx(cx), src);
|
||||||
|
|||||||
@@ -526,11 +526,9 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef,
|
|||||||
let ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
|
let ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
|
||||||
let llty = trans::type_of(ccx, pat.span, ty);
|
let llty = trans::type_of(ccx, pat.span, ty);
|
||||||
let alloc = trans::alloca(bcx, llty);
|
let alloc = trans::alloca(bcx, llty);
|
||||||
bcx = trans::memmove_ty(bcx, alloc, val, ty).bcx;
|
bcx = trans::copy_val(bcx, trans::INIT, alloc,
|
||||||
let loaded = trans::load_if_immediate(bcx, alloc, ty);
|
trans::load_if_immediate(bcx, val, ty), ty);
|
||||||
bcx = trans::take_ty(bcx, loaded, ty).bcx;
|
|
||||||
table.insert(pat.id, alloc);
|
table.insert(pat.id, alloc);
|
||||||
trans_common::add_clean(bcx, alloc, ty);
|
|
||||||
} else { table.insert(pat.id, val); }
|
} else { table.insert(pat.id, val); }
|
||||||
}
|
}
|
||||||
ast::pat_tag(_, sub) {
|
ast::pat_tag(_, sub) {
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ export type_kind;
|
|||||||
export type_err;
|
export type_err;
|
||||||
export type_err_to_str;
|
export type_err_to_str;
|
||||||
export type_has_dynamic_size;
|
export type_has_dynamic_size;
|
||||||
|
export type_needs_copy_glue;
|
||||||
export type_has_pointers;
|
export type_has_pointers;
|
||||||
export type_needs_drop;
|
export type_needs_drop;
|
||||||
export type_is_bool;
|
export type_is_bool;
|
||||||
@@ -1175,6 +1176,17 @@ fn type_has_dynamic_size(cx: &ctxt, ty: t) -> bool {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn type_needs_copy_glue(cx: &ctxt, ty: t) -> bool {
|
||||||
|
ret type_structurally_contains(cx, ty, fn(sty: &sty) -> bool {
|
||||||
|
ret alt sty {
|
||||||
|
ty_param(_, _) { true }
|
||||||
|
ty_vec(_) { true }
|
||||||
|
ty_istr. { true }
|
||||||
|
_ { false }
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn type_is_integral(cx: &ctxt, ty: t) -> bool {
|
fn type_is_integral(cx: &ctxt, ty: t) -> bool {
|
||||||
alt struct(cx, ty) {
|
alt struct(cx, ty) {
|
||||||
ty_int. { ret true; }
|
ty_int. { ret true; }
|
||||||
|
|||||||
Reference in New Issue
Block a user