@@ -1240,14 +1240,13 @@ fn drop_ty(@block_ctxt cx,
1240
1240
fn build_memcpy( @block_ctxt cx,
1241
1241
ValueRef dst,
1242
1242
ValueRef src,
1243
- TypeRef llty ) -> result {
1243
+ ValueRef n_bytes ) -> result {
1244
1244
// FIXME: switch to the 64-bit variant when on such a platform.
1245
1245
check ( cx. fcx. ccx. intrinsics. contains_key( "llvm.memcpy.p0i8.p0i8.i32" ) ) ;
1246
1246
auto memcpy = cx. fcx. ccx. intrinsics. get( "llvm.memcpy.p0i8.p0i8.i32" ) ;
1247
1247
auto src_ptr = cx. build. PointerCast ( src, T_ptr ( T_i8 ( ) ) ) ;
1248
1248
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 ( ) ) ;
1251
1250
auto align = cx. build. IntCast ( C_int ( 1 ) , T_i32 ( ) ) ;
1252
1251
1253
1252
// FIXME: align seems like it should be
@@ -1260,6 +1259,20 @@ fn build_memcpy(@block_ctxt cx,
1260
1259
size, align, volatile) ) ) ;
1261
1260
}
1262
1261
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
+
1263
1276
fn copy_ty( @block_ctxt cx,
1264
1277
bool is_init,
1265
1278
ValueRef dst,
@@ -1278,15 +1291,13 @@ fn copy_ty(@block_ctxt cx,
1278
1291
}
1279
1292
ret res( r. bcx, r. bcx. build. Store ( src, dst) ) ;
1280
1293
1281
- } else if ( ty. type_is_structural( t) ) {
1294
+ } else if ( ty. type_is_structural( t) ||
1295
+ ty. type_has_dynamic_size( t) ) {
1282
1296
auto r = incr_all_refcnts( cx, src, t) ;
1283
1297
if ( ! is_init) {
1284
1298
r = drop_ty( r. bcx, dst, t) ;
1285
1299
}
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) ;
1290
1301
}
1291
1302
1292
1303
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 {
2598
2609
2599
2610
alt ( e) {
2600
2611
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) ) {
2602
2615
r. bcx. build. RetVoid ( ) ;
2603
2616
r. val = C_nil ( ) ;
2604
2617
ret r; // FIXME: early return needed due to typestate bug
2605
2618
}
2606
2619
2607
2620
alt ( cx. fcx. llretptr) {
2608
2621
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 ) ;
2611
2624
r. bcx. build. RetVoid ( ) ;
2612
2625
}
2613
2626
case ( none[ ValueRef ] ) {
0 commit comments