Teach copy_ty to finish via memcpy of tydesc-provided size.
This commit is contained in:
parent
57b281533d
commit
d1fdf0ab23
1 changed files with 24 additions and 11 deletions
|
@ -1240,14 +1240,13 @@ fn drop_ty(@block_ctxt cx,
|
||||||
fn build_memcpy(@block_ctxt cx,
|
fn build_memcpy(@block_ctxt cx,
|
||||||
ValueRef dst,
|
ValueRef dst,
|
||||||
ValueRef src,
|
ValueRef src,
|
||||||
TypeRef llty) -> result {
|
ValueRef n_bytes) -> result {
|
||||||
// FIXME: switch to the 64-bit variant when on such a platform.
|
// FIXME: switch to the 64-bit variant when on such a platform.
|
||||||
check (cx.fcx.ccx.intrinsics.contains_key("llvm.memcpy.p0i8.p0i8.i32"));
|
check (cx.fcx.ccx.intrinsics.contains_key("llvm.memcpy.p0i8.p0i8.i32"));
|
||||||
auto memcpy = cx.fcx.ccx.intrinsics.get("llvm.memcpy.p0i8.p0i8.i32");
|
auto memcpy = cx.fcx.ccx.intrinsics.get("llvm.memcpy.p0i8.p0i8.i32");
|
||||||
auto src_ptr = cx.build.PointerCast(src, T_ptr(T_i8()));
|
auto src_ptr = cx.build.PointerCast(src, T_ptr(T_i8()));
|
||||||
auto dst_ptr = cx.build.PointerCast(dst, T_ptr(T_i8()));
|
auto dst_ptr = cx.build.PointerCast(dst, T_ptr(T_i8()));
|
||||||
auto size = cx.build.IntCast(lib.llvm.llvm.LLVMSizeOf(llty),
|
auto size = cx.build.IntCast(n_bytes, T_i32());
|
||||||
T_i32());
|
|
||||||
auto align = cx.build.IntCast(C_int(1), T_i32());
|
auto align = cx.build.IntCast(C_int(1), T_i32());
|
||||||
|
|
||||||
// FIXME: align seems like it should be
|
// FIXME: align seems like it should be
|
||||||
|
@ -1260,6 +1259,20 @@ fn build_memcpy(@block_ctxt cx,
|
||||||
size, align, volatile)));
|
size, align, volatile)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn memcpy_ty(@block_ctxt cx,
|
||||||
|
ValueRef dst,
|
||||||
|
ValueRef src,
|
||||||
|
@ty.t t) -> result {
|
||||||
|
if (ty.type_has_dynamic_size(t)) {
|
||||||
|
auto llszptr = field_of_tydesc(cx, t, abi.tydesc_field_size);
|
||||||
|
auto llsz = cx.build.Load(llszptr);
|
||||||
|
ret build_memcpy(cx, dst, src, llsz);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ret res(cx, cx.build.Store(cx.build.Load(src), dst));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn copy_ty(@block_ctxt cx,
|
fn copy_ty(@block_ctxt cx,
|
||||||
bool is_init,
|
bool is_init,
|
||||||
ValueRef dst,
|
ValueRef dst,
|
||||||
|
@ -1278,15 +1291,13 @@ fn copy_ty(@block_ctxt cx,
|
||||||
}
|
}
|
||||||
ret res(r.bcx, r.bcx.build.Store(src, dst));
|
ret res(r.bcx, r.bcx.build.Store(src, dst));
|
||||||
|
|
||||||
} else if (ty.type_is_structural(t)) {
|
} else if (ty.type_is_structural(t) ||
|
||||||
|
ty.type_has_dynamic_size(t)) {
|
||||||
auto r = incr_all_refcnts(cx, src, t);
|
auto r = incr_all_refcnts(cx, src, t);
|
||||||
if (! is_init) {
|
if (! is_init) {
|
||||||
r = drop_ty(r.bcx, dst, t);
|
r = drop_ty(r.bcx, dst, t);
|
||||||
}
|
}
|
||||||
// In this one surprising case, we do a load/store on
|
ret memcpy_ty(r.bcx, dst, src, t);
|
||||||
// structure types. This results in a memcpy. Usually
|
|
||||||
// we talk about structures by pointers in this file.
|
|
||||||
ret res(r.bcx, r.bcx.build.Store(r.bcx.build.Load(src), dst));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.fcx.ccx.sess.bug("unexpected type in trans.copy_ty: " +
|
cx.fcx.ccx.sess.bug("unexpected type in trans.copy_ty: " +
|
||||||
|
@ -2598,7 +2609,9 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
|
||||||
|
|
||||||
alt (e) {
|
alt (e) {
|
||||||
case (some[@ast.expr](?ex)) {
|
case (some[@ast.expr](?ex)) {
|
||||||
if (ty.type_is_nil(ty.expr_ty(ex))) {
|
auto t = ty.expr_ty(ex);
|
||||||
|
|
||||||
|
if (ty.type_is_nil(t)) {
|
||||||
r.bcx.build.RetVoid();
|
r.bcx.build.RetVoid();
|
||||||
r.val = C_nil();
|
r.val = C_nil();
|
||||||
ret r; // FIXME: early return needed due to typestate bug
|
ret r; // FIXME: early return needed due to typestate bug
|
||||||
|
@ -2606,8 +2619,8 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
|
||||||
|
|
||||||
alt (cx.fcx.llretptr) {
|
alt (cx.fcx.llretptr) {
|
||||||
case (some[ValueRef](?llptr)) {
|
case (some[ValueRef](?llptr)) {
|
||||||
// FIXME: Generic return: Needs to use tydesc.
|
// Generic return via tydesc + retptr.
|
||||||
// r.bcx.build.Store(r.val, llptr);
|
r = copy_ty(r.bcx, true, llptr, r.val, t);
|
||||||
r.bcx.build.RetVoid();
|
r.bcx.build.RetVoid();
|
||||||
}
|
}
|
||||||
case (none[ValueRef]) {
|
case (none[ValueRef]) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue