Skip to content

Commit ffdca06

Browse files
committed
---
yaml --- r: 1249 b: refs/heads/master c: d1fdf0a h: refs/heads/master i: 1247: 4a7b24e v: v3
1 parent 07b008d commit ffdca06

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 57b281533d4bdd93744562cf1d39ebc090621151
2+
refs/heads/master: d1fdf0ab231eb60d4a388944a6a44adb818aa9fc

trunk/src/comp/middle/trans.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,14 +1240,13 @@ fn drop_ty(@block_ctxt cx,
12401240
fn build_memcpy(@block_ctxt cx,
12411241
ValueRef dst,
12421242
ValueRef src,
1243-
TypeRef llty) -> result {
1243+
ValueRef n_bytes) -> result {
12441244
// FIXME: switch to the 64-bit variant when on such a platform.
12451245
check (cx.fcx.ccx.intrinsics.contains_key("llvm.memcpy.p0i8.p0i8.i32"));
12461246
auto memcpy = cx.fcx.ccx.intrinsics.get("llvm.memcpy.p0i8.p0i8.i32");
12471247
auto src_ptr = cx.build.PointerCast(src, T_ptr(T_i8()));
12481248
auto dst_ptr = cx.build.PointerCast(dst, T_ptr(T_i8()));
1249-
auto size = cx.build.IntCast(lib.llvm.llvm.LLVMSizeOf(llty),
1250-
T_i32());
1249+
auto size = cx.build.IntCast(n_bytes, T_i32());
12511250
auto align = cx.build.IntCast(C_int(1), T_i32());
12521251

12531252
// FIXME: align seems like it should be
@@ -1260,6 +1259,20 @@ fn build_memcpy(@block_ctxt cx,
12601259
size, align, volatile)));
12611260
}
12621261

1262+
fn memcpy_ty(@block_ctxt cx,
1263+
ValueRef dst,
1264+
ValueRef src,
1265+
@ty.t t) -> result {
1266+
if (ty.type_has_dynamic_size(t)) {
1267+
auto llszptr = field_of_tydesc(cx, t, abi.tydesc_field_size);
1268+
auto llsz = cx.build.Load(llszptr);
1269+
ret build_memcpy(cx, dst, src, llsz);
1270+
1271+
} else {
1272+
ret res(cx, cx.build.Store(cx.build.Load(src), dst));
1273+
}
1274+
}
1275+
12631276
fn copy_ty(@block_ctxt cx,
12641277
bool is_init,
12651278
ValueRef dst,
@@ -1278,15 +1291,13 @@ fn copy_ty(@block_ctxt cx,
12781291
}
12791292
ret res(r.bcx, r.bcx.build.Store(src, dst));
12801293

1281-
} else if (ty.type_is_structural(t)) {
1294+
} else if (ty.type_is_structural(t) ||
1295+
ty.type_has_dynamic_size(t)) {
12821296
auto r = incr_all_refcnts(cx, src, t);
12831297
if (! is_init) {
12841298
r = drop_ty(r.bcx, dst, t);
12851299
}
1286-
// In this one surprising case, we do a load/store on
1287-
// structure types. This results in a memcpy. Usually
1288-
// we talk about structures by pointers in this file.
1289-
ret res(r.bcx, r.bcx.build.Store(r.bcx.build.Load(src), dst));
1300+
ret memcpy_ty(r.bcx, dst, src, t);
12901301
}
12911302

12921303
cx.fcx.ccx.sess.bug("unexpected type in trans.copy_ty: " +
@@ -2598,16 +2609,18 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
25982609

25992610
alt (e) {
26002611
case (some[@ast.expr](?ex)) {
2601-
if (ty.type_is_nil(ty.expr_ty(ex))) {
2612+
auto t = ty.expr_ty(ex);
2613+
2614+
if (ty.type_is_nil(t)) {
26022615
r.bcx.build.RetVoid();
26032616
r.val = C_nil();
26042617
ret r; // FIXME: early return needed due to typestate bug
26052618
}
26062619

26072620
alt (cx.fcx.llretptr) {
26082621
case (some[ValueRef](?llptr)) {
2609-
// FIXME: Generic return: Needs to use tydesc.
2610-
// r.bcx.build.Store(r.val, llptr);
2622+
// Generic return via tydesc + retptr.
2623+
r = copy_ty(r.bcx, true, llptr, r.val, t);
26112624
r.bcx.build.RetVoid();
26122625
}
26132626
case (none[ValueRef]) {

0 commit comments

Comments
 (0)