@@ -58,7 +58,7 @@ type glue_fns = rec(ValueRef activate_glue,
58
58
ValueRef no_op_type_glue ,
59
59
ValueRef memcpy_glue ,
60
60
ValueRef bzero_glue ,
61
- ValueRef vec_grow_glue ) ;
61
+ ValueRef vec_append_glue ) ;
62
62
63
63
type tag_info = rec ( type_handle th) ;
64
64
@@ -2296,17 +2296,39 @@ fn trans_integral_compare(@block_ctxt cx, ast.binop op, @ty.t intype,
2296
2296
ret cx. build. ICmp ( cmp, lhs, rhs) ;
2297
2297
}
2298
2298
2299
- fn trans_sequence_append( @block_ctxt cx, @ty. t t,
2300
- ValueRef lhs, ValueRef rhs) -> result {
2301
- cx. fcx. ccx. sess. unimpl( "sequence append") ;
2302
- fail;
2299
+ fn trans_vec_append( @block_ctxt cx, @ty. t t,
2300
+ ValueRef lhs, ValueRef rhs) -> result {
2301
+
2302
+ auto elt_ty = ty. sequence_element_type( t) ;
2303
+
2304
+ auto skip_null = C_bool ( false) ;
2305
+ alt ( t. struct ) {
2306
+ case ( ty. ty_str) { skip_null = C_bool ( true) ; }
2307
+ case ( _) { }
2308
+ }
2309
+
2310
+ auto bcx = cx;
2311
+
2312
+ auto llvec_tydesc = get_tydesc( bcx, t) ;
2313
+ bcx = llvec_tydesc. bcx;
2314
+
2315
+ auto llelt_tydesc = get_tydesc( bcx, elt_ty) ;
2316
+ bcx = llelt_tydesc. bcx;
2317
+
2318
+ ret res( cx, cx. build. FastCall ( cx. fcx. ccx. glues. memcpy_glue,
2319
+ vec( cx. fcx. lltaskptr,
2320
+ llvec_tydesc. val,
2321
+ llelt_tydesc. val,
2322
+ lhs,
2323
+ load_scalar_or_boxed( cx, rhs, t) ,
2324
+ skip_null) ) ) ;
2303
2325
}
2304
2326
2305
- fn trans_sequence_add ( @block_ctxt cx, @ty. t t,
2306
- ValueRef lhs, ValueRef rhs) -> result {
2327
+ fn trans_vec_add ( @block_ctxt cx, @ty. t t,
2328
+ ValueRef lhs, ValueRef rhs) -> result {
2307
2329
auto r = alloc_ty( cx, t) ;
2308
2330
r = copy_ty( r. bcx, INIT , r. val, lhs, t) ;
2309
- ret trans_sequence_append ( r. bcx, t, lhs, rhs) ;
2331
+ ret trans_vec_append ( r. bcx, t, lhs, rhs) ;
2310
2332
}
2311
2333
2312
2334
@@ -2316,7 +2338,7 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, @ty.t intype,
2316
2338
alt ( op) {
2317
2339
case ( ast. add) {
2318
2340
if ( ty. type_is_sequence( intype) ) {
2319
- ret trans_sequence_add ( cx, intype, lhs, rhs) ;
2341
+ ret trans_vec_add ( cx, intype, lhs, rhs) ;
2320
2342
}
2321
2343
ret res( cx, cx. build. Add ( lhs, rhs) ) ;
2322
2344
}
@@ -5296,9 +5318,9 @@ fn make_bzero_glue(ModuleRef llmod) -> ValueRef {
5296
5318
ret fun;
5297
5319
}
5298
5320
5299
- fn make_vec_grow_glue ( ModuleRef llmod, type_names tn) -> ValueRef {
5321
+ fn make_vec_append_glue ( ModuleRef llmod, type_names tn) -> ValueRef {
5300
5322
/*
5301
- * Args to vec_grow_glue :
5323
+ * Args to vec_append_glue :
5302
5324
*
5303
5325
* 0. (Implicit) task ptr
5304
5326
*
@@ -5309,31 +5331,35 @@ fn make_vec_grow_glue(ModuleRef llmod, type_names tn) -> ValueRef {
5309
5331
* elements can be copied to a newly alloc'ed vec if one must be
5310
5332
* created.
5311
5333
*
5312
- * 3. Alias to vec that needs to grow (i.e. ptr to ptr to rust_vec).
5334
+ * 3. Dst vec alias (i.e. ptr to ptr to rust_vec, we will mutate it).
5335
+ *
5336
+ * 4. Src vec (i.e. ptr to rust_vec).
5313
5337
*
5314
- * 4. Number of bytes of growth requested
5338
+ * 5. Flag indicating whether to skip trailing null on dst.
5315
5339
*
5316
5340
*/
5317
5341
5318
5342
auto ty = T_fn ( vec ( T_taskptr ( tn) ,
5319
5343
T_ptr ( T_tydesc ( tn) ) ,
5320
5344
T_ptr ( T_tydesc ( tn) ) ,
5321
5345
T_ptr ( T_ptr ( T_vec ( T_int ( ) ) ) ) , // a lie.
5322
- T_int ( ) ) , T_void ( ) ) ;
5346
+ T_ptr ( T_vec ( T_int ( ) ) ) , // a lie.
5347
+ T_bool ( ) ) , T_void ( ) ) ;
5323
5348
5324
- auto llfn = decl_fastcall_fn ( llmod, abi. vec_grow_glue_name ( ) , ty) ;
5349
+ auto llfn = decl_fastcall_fn ( llmod, abi. vec_append_glue_name ( ) , ty) ;
5325
5350
ret llfn;
5326
5351
}
5327
5352
5328
- fn trans_vec_grow_glue ( @crate_ctxt cx ) {
5353
+ fn trans_vec_append_glue ( @crate_ctxt cx ) {
5329
5354
5330
- auto llfn = cx. glues . vec_grow_glue ;
5355
+ auto llfn = cx. glues . vec_append_glue ;
5331
5356
5332
5357
let ValueRef lltaskptr = llvm. LLVMGetParam ( llfn, 0 u) ;
5333
5358
let ValueRef llvec_tydesc = llvm. LLVMGetParam ( llfn, 1 u) ;
5334
5359
let ValueRef llelt_tydesc = llvm. LLVMGetParam ( llfn, 2 u) ;
5335
- let ValueRef llvec_ptr = llvm. LLVMGetParam ( llfn, 3 u) ;
5336
- let ValueRef llnbytes = llvm. LLVMGetParam ( llfn, 4 u) ;
5360
+ let ValueRef lldst_vec_ptr = llvm. LLVMGetParam ( llfn, 3 u) ;
5361
+ let ValueRef llsrc_vec = llvm. LLVMGetParam ( llfn, 4 u) ;
5362
+ let ValueRef llskipnull = llvm. LLVMGetParam ( llfn, 5 u) ;
5337
5363
5338
5364
auto fcx = @rec ( llfn=llfn,
5339
5365
lltaskptr=lltaskptr,
@@ -5349,12 +5375,23 @@ fn trans_vec_grow_glue(@crate_ctxt cx) {
5349
5375
5350
5376
auto bcx = new_top_block_ctxt ( fcx) ;
5351
5377
5352
- auto llneed_copy_ptr = bcx. build . Alloca ( T_int ( ) ) ;
5378
+ // First the dst vec needs to grow to accommodate the src vec.
5379
+ // To do this we have to figure out how many bytes to add.
5380
+ auto n_bytes =
5381
+ bcx. build . Load ( bcx. build . GEP ( llsrc_vec,
5382
+ vec ( C_int ( 0 ) ,
5383
+ C_int ( abi. vec_elt_fill ) ) ) ) ;
5353
5384
5385
+ n_bytes = bcx. build . Select ( llskipnull,
5386
+ bcx. build . Sub ( n_bytes, C_int ( 1 ) ) ,
5387
+ n_bytes) ;
5388
+
5389
+
5390
+ auto llneed_copy_ptr = bcx. build . Alloca ( T_int ( ) ) ;
5354
5391
auto llnew_vec_res =
5355
5392
trans_upcall ( bcx, "upcall_vec_grow" ,
5356
- vec ( vp2i ( bcx, bcx. build . Load ( llvec_ptr ) ) ,
5357
- llnbytes ,
5393
+ vec ( vp2i ( bcx, bcx. build . Load ( lldst_vec_ptr ) ) ,
5394
+ n_bytes ,
5358
5395
vp2i ( bcx, llneed_copy_ptr) ,
5359
5396
vp2i ( bcx, llvec_tydesc) ) ) ;
5360
5397
@@ -5364,6 +5401,7 @@ fn trans_vec_grow_glue(@crate_ctxt cx) {
5364
5401
T_ptr ( T_vec ( T_int ( ) ) ) // a lie.
5365
5402
) ;
5366
5403
5404
+
5367
5405
// FIXME: complete this.
5368
5406
5369
5407
bcx. build . RetVoid ( ) ;
@@ -5396,7 +5434,7 @@ fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
5396
5434
no_op_type_glue = make_no_op_type_glue ( llmod, tn) ,
5397
5435
memcpy_glue = make_memcpy_glue ( llmod) ,
5398
5436
bzero_glue = make_bzero_glue ( llmod) ,
5399
- vec_grow_glue = make_vec_grow_glue ( llmod, tn) ) ;
5437
+ vec_append_glue = make_vec_append_glue ( llmod, tn) ) ;
5400
5438
}
5401
5439
5402
5440
fn trans_crate ( session . session sess, @ast. crate crate, str output ,
@@ -5456,7 +5494,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
5456
5494
5457
5495
trans_mod ( cx, crate . node . module ) ;
5458
5496
trans_exit_task_glue ( cx) ;
5459
- trans_vec_grow_glue ( cx) ;
5497
+ trans_vec_append_glue ( cx) ;
5460
5498
create_crate_constant ( cx) ;
5461
5499
if ( !shared) {
5462
5500
trans_main_fn ( cx, cx. crate_ptr ) ;
0 commit comments