rustc: Move duplicate_heap_parts to copy glue; add a test case

This commit is contained in:
Patrick Walton 2011-06-28 17:58:45 -07:00
parent db478ed4de
commit 74f8eb51ae
3 changed files with 27 additions and 13 deletions

View file

@ -1933,6 +1933,9 @@ fn make_copy_glue(&@block_ctxt cx, ValueRef v, &ty::t t) {
bcx = incr_refcnt_of_boxed(cx, cx.build.Load(v)).bcx;
} else if (ty::type_is_structural(cx.fcx.lcx.ccx.tcx, t)) {
bcx = iter_structural_ty(cx, v, t, bind copy_ty(_, _, _)).bcx;
if (ty::type_owns_heap_mem(cx.fcx.lcx.ccx.tcx, t)) {
bcx = duplicate_heap_parts(bcx, v, t).bcx;
}
} else { bcx = cx; }
bcx.build.RetVoid();
}
@ -3054,7 +3057,8 @@ fn compare(&@block_ctxt cx, ValueRef lhs, ValueRef rhs, &ty::t t,
}
fn copy_ty(&@block_ctxt cx, ValueRef v, ty::t t) -> result {
if (ty::type_has_pointers(cx.fcx.lcx.ccx.tcx, t)) {
if (ty::type_has_pointers(cx.fcx.lcx.ccx.tcx, t) ||
ty::type_owns_heap_mem(cx.fcx.lcx.ccx.tcx, t)) {
ret call_tydesc_glue(cx, v, t, abi::tydesc_field_copy_glue);
}
ret rslt(cx, C_nil());
@ -3168,20 +3172,24 @@ fn copy_val(&@block_ctxt cx, copy_action action, ValueRef dst, ValueRef src,
ty::type_is_bot(ccx.tcx, t)) {
ret rslt(cx, C_nil());
} else if (ty::type_is_boxed(ccx.tcx, t)) {
auto r = copy_ty(cx, src, t);
auto bcx;
if (action == DROP_EXISTING) {
r = drop_ty(r.bcx, r.bcx.build.Load(dst), t);
bcx = drop_ty(cx, cx.build.Load(dst), t).bcx;
} else {
bcx = cx;
}
ret rslt(r.bcx, r.bcx.build.Store(src, dst));
bcx = copy_ty(bcx, src, t).bcx;
ret rslt(bcx, bcx.build.Store(src, dst));
} else if (ty::type_is_structural(ccx.tcx, t) ||
ty::type_has_dynamic_size(ccx.tcx, t)) {
auto r = copy_ty(cx, src, t);
if (action == DROP_EXISTING) { r = drop_ty(r.bcx, dst, t); }
r = memmove_ty(r.bcx, dst, src, t);
if (ty::type_owns_heap_mem(ccx.tcx, t)) {
r = duplicate_heap_parts(cx, dst, t);
auto bcx;
if (action == DROP_EXISTING) {
bcx = drop_ty(cx, dst, t).bcx;
} else {
bcx = cx;
}
ret r;
bcx = memmove_ty(bcx, dst, src, t).bcx;
ret copy_ty(bcx, dst, t);
}
ccx.sess.bug("unexpected type in trans::copy_val: " +
ty_to_str(ccx.tcx, t));

View file

@ -452,18 +452,17 @@ copy_elements(rust_task *task, type_desc *elem_t,
void *pdst, void *psrc, size_t n)
{
char *dst = (char *)pdst, *src = (char *)psrc;
memmove(dst, src, n);
// FIXME: Copy glue doesn't work this way.
// increment the refcount of each element of the vector
if (elem_t->copy_glue) {
glue_fn *copy_glue = elem_t->copy_glue;
size_t elem_size = elem_t->size;
const type_desc **tydescs = elem_t->first_param;
for (char *p = src; p < src+n; p += elem_size) {
for (char *p = dst; p < dst+n; p += elem_size) {
copy_glue(NULL, task, NULL, tydescs, p);
}
}
memmove(dst, src, n);
}
extern "C" CDECL void

View file

@ -0,0 +1,7 @@
// xfail-stage0
fn f[T](@T v) {}
fn main() {
f(@~[ 1, 2, 3, 4, 5 ]);
}