@@ -1723,6 +1723,8 @@ fn mk_plain_tag(ast.def_id tid) -> @ty.t {
1723
1723
}
1724
1724
1725
1725
1726
+ type val_fn = fn ( @block_ctxt cx, ValueRef v) -> result;
1727
+
1726
1728
type val_and_ty_fn = fn ( @block_ctxt cx, ValueRef v, @ty. t t) -> result;
1727
1729
1728
1730
type val_pair_and_ty_fn =
@@ -1922,23 +1924,17 @@ fn iter_structural_ty_full(@block_ctxt cx,
1922
1924
ret r;
1923
1925
}
1924
1926
1925
- // Iterates through a pair of sequences, until the src* hits the src_lim*.
1926
- fn iter_sequence_pair_inner( @block_ctxt cx,
1927
- ValueRef dst, // elt*
1928
- ValueRef src, // elt*
1929
- ValueRef src_lim, // elt*
1930
- @ty. t elt_ty,
1931
- val_pair_and_ty_fn f) -> result {
1927
+ // Iterates through a pointer range, until the src* hits the src_lim*.
1928
+ fn iter_sequence_raw( @block_ctxt cx,
1929
+ ValueRef src, // elt*
1930
+ ValueRef src_lim, // elt*
1931
+ ValueRef elt_sz,
1932
+ val_fn f) -> result {
1932
1933
1933
1934
auto bcx = cx;
1934
1935
1935
- auto llunit_ty = type_of( cx. fcx. ccx, elt_ty) ;
1936
- auto unit_sz = size_of( bcx, elt_ty) ;
1937
- bcx = unit_sz. bcx;
1938
-
1939
1936
let ValueRef src_int = vp2i( bcx, src) ;
1940
1937
let ValueRef src_lim_int = vp2i( bcx, src_lim) ;
1941
- let ValueRef dst_int = vp2i( bcx, dst) ;
1942
1938
1943
1939
auto cond_cx = new_scope_block_ctxt( cx, "sequence-iter cond") ;
1944
1940
auto body_cx = new_scope_block_ctxt( cx, "sequence-iter body") ;
@@ -1948,33 +1944,23 @@ fn iter_sequence_pair_inner(@block_ctxt cx,
1948
1944
1949
1945
let ValueRef src_curr = cond_cx. build. Phi ( T_int( ) ,
1950
1946
vec( src_int) , vec( bcx. llbb) ) ;
1951
- let ValueRef dst_curr = cond_cx. build. Phi ( T_int( ) ,
1952
- vec( dst_int) , vec( bcx. llbb) ) ;
1953
1947
1954
- auto end_test = cond_cx. build. ICmp ( lib. llvm. LLVMIntNE ,
1948
+ auto end_test = cond_cx. build. ICmp ( lib. llvm. LLVMIntULT ,
1955
1949
src_curr, src_lim_int) ;
1956
1950
1957
1951
cond_cx. build. CondBr ( end_test, body_cx. llbb, next_cx. llbb) ;
1958
1952
1959
- auto src_curr_ptr = vi2p( body_cx, src_curr, T_ptr ( llunit_ty) ) ;
1960
- auto dst_curr_ptr = vi2p( body_cx, dst_curr, T_ptr ( llunit_ty) ) ;
1953
+ auto src_curr_ptr = vi2p( body_cx, src_curr, T_ptr ( T_i8 ( ) ) ) ;
1961
1954
1962
- auto body_res = f( body_cx,
1963
- dst_curr_ptr,
1964
- load_scalar_or_boxed( body_cx, src_curr_ptr, elt_ty) ,
1965
- elt_ty) ;
1955
+ auto body_res = f( body_cx, src_curr_ptr) ;
1966
1956
body_cx = body_res. bcx;
1967
1957
1968
- auto src_next = body_cx. build. Add ( src_curr, unit_sz. val) ;
1969
- auto dst_next = body_cx. build. Add ( dst_curr, unit_sz. val) ;
1958
+ auto src_next = body_cx. build. Add ( src_curr, elt_sz) ;
1970
1959
body_cx. build. Br ( cond_cx. llbb) ;
1971
1960
1972
1961
cond_cx. build. AddIncomingToPhi ( src_curr, vec( src_next) ,
1973
1962
vec( body_cx. llbb) ) ;
1974
1963
1975
- cond_cx. build. AddIncomingToPhi ( dst_curr, vec( dst_next) ,
1976
- vec( body_cx. llbb) ) ;
1977
-
1978
1964
ret res( next_cx, C_nil( ) ) ;
1979
1965
}
1980
1966
@@ -1985,15 +1971,17 @@ fn iter_sequence_inner(@block_ctxt cx,
1985
1971
@ty. t elt_ty,
1986
1972
val_and_ty_fn f) -> result {
1987
1973
fn adaptor_fn( val_and_ty_fn f,
1974
+ @ty. t elt_ty,
1988
1975
@block_ctxt cx,
1989
- ValueRef av ,
1990
- ValueRef bv ,
1991
- @ty . t t ) -> result {
1992
- ret f( cx, bv , t ) ;
1976
+ ValueRef v ) -> result {
1977
+ auto llty = type_of ( cx . fcx . ccx , elt_ty ) ;
1978
+ auto p = cx . build . PointerCast ( v , T_ptr ( llty ) ) ;
1979
+ ret f( cx, load_scalar_or_boxed ( cx , p , elt_ty ) , elt_ty ) ;
1993
1980
}
1994
1981
1995
- be iter_sequence_pair_inner( cx, src, src, src_lim, elt_ty,
1996
- bind adaptor_fn( f, _, _, _, _) ) ;
1982
+ auto elt_sz = size_of( cx, elt_ty) ;
1983
+ be iter_sequence_raw( elt_sz. bcx, src, src_lim, elt_sz. val,
1984
+ bind adaptor_fn( f, elt_ty, _, _) ) ;
1997
1985
}
1998
1986
1999
1987
@@ -5475,34 +5463,136 @@ fn trans_vec_append_glue(@crate_ctxt cx) {
5475
5463
5476
5464
auto bcx = new_top_block_ctxt ( fcx) ;
5477
5465
5466
+ auto lldst_vec = bcx. build . Load ( lldst_vec_ptr) ;
5467
+
5478
5468
// First the dst vec needs to grow to accommodate the src vec.
5479
5469
// To do this we have to figure out how many bytes to add.
5480
- auto n_bytes =
5481
- bcx. build . Load ( bcx. build . GEP ( llsrc_vec,
5482
- vec ( C_int ( 0 ) ,
5483
- C_int ( abi. vec_elt_fill ) ) ) ) ;
5484
5470
5485
- n_bytes = bcx. build . Select ( llskipnull,
5486
- bcx. build . Sub ( n_bytes, C_int ( 1 ) ) ,
5487
- n_bytes) ;
5471
+ fn vec_fill ( @block_ctxt bcx , ValueRef v) -> ValueRef {
5472
+ ret bcx. build . Load ( bcx. build . GEP ( v, vec ( C_int ( 0 ) ,
5473
+ C_int ( abi. vec_elt_fill ) ) ) ) ;
5474
+ }
5475
+
5476
+ fn put_vec_fill ( @block_ctxt bcx , ValueRef v, ValueRef fill) -> ValueRef {
5477
+ ret bcx. build . Store ( fill,
5478
+ bcx. build . GEP ( v,
5479
+ vec ( C_int ( 0 ) ,
5480
+ C_int ( abi. vec_elt_fill ) ) ) ) ;
5481
+ }
5488
5482
5483
+ fn vec_fill_adjusted ( @block_ctxt bcx , ValueRef v,
5484
+ ValueRef skipnull) -> ValueRef {
5485
+ auto f = bcx. build . Load ( bcx. build . GEP ( v,
5486
+ vec ( C_int ( 0 ) ,
5487
+ C_int ( abi. vec_elt_fill ) ) ) ) ;
5488
+ ret bcx. build . Select ( skipnull, bcx. build . Sub ( f, C_int ( 1 ) ) , f) ;
5489
+ }
5489
5490
5490
- auto llneed_copy_ptr = bcx. build . Alloca ( T_int ( ) ) ;
5491
+ fn vec_p0 ( @block_ctxt bcx , ValueRef v) -> ValueRef {
5492
+ auto p = bcx. build . GEP ( v, vec ( C_int ( 0 ) ,
5493
+ C_int ( abi. vec_elt_data ) ) ) ;
5494
+ ret bcx. build . PointerCast ( p, T_ptr ( T_i8 ( ) ) ) ;
5495
+ }
5496
+
5497
+
5498
+ fn vec_p1 ( @block_ctxt bcx , ValueRef v) -> ValueRef {
5499
+ auto len = vec_fill ( bcx, v) ;
5500
+ ret bcx. build . GEP ( vec_p0 ( bcx, v) , vec ( len) ) ;
5501
+ }
5502
+
5503
+ fn vec_p1_adjusted ( @block_ctxt bcx , ValueRef v,
5504
+ ValueRef skipnull) -> ValueRef {
5505
+ auto len = vec_fill_adjusted ( bcx, v, skipnull) ;
5506
+ ret bcx. build . GEP ( vec_p0 ( bcx, v) , vec ( len) ) ;
5507
+ }
5508
+
5509
+
5510
+ auto llcopy_dst_ptr = bcx. build . Alloca ( T_int ( ) ) ;
5491
5511
auto llnew_vec_res =
5492
5512
trans_upcall ( bcx, "upcall_vec_grow" ,
5493
- vec ( vp2i ( bcx, bcx . build . Load ( lldst_vec_ptr ) ) ,
5494
- n_bytes ,
5495
- vp2i ( bcx, llneed_copy_ptr ) ,
5513
+ vec ( vp2i ( bcx, lldst_vec ) ,
5514
+ vec_fill_adjusted ( bcx , llsrc_vec , llskipnull ) ,
5515
+ vp2i ( bcx, llcopy_dst_ptr ) ,
5496
5516
vp2i ( bcx, llvec_tydesc) ) ) ;
5497
5517
5498
5518
bcx = llnew_vec_res. bcx ;
5499
5519
auto llnew_vec = vi2p ( bcx, llnew_vec_res. val ,
5500
5520
T_opaque_vec_ptr ( ) ) ;
5501
5521
5522
+ put_vec_fill ( bcx, llnew_vec, C_int ( 0 ) ) ;
5502
5523
5503
- // FIXME: complete this.
5524
+ auto copy_dst_cx = new_sub_block_ctxt ( bcx, "copy new <- dst" ) ;
5525
+ auto copy_src_cx = new_sub_block_ctxt ( bcx, "copy new <- src" ) ;
5504
5526
5505
- bcx. build . RetVoid ( ) ;
5527
+ auto pp0 = bcx. build . Alloca ( T_ptr ( T_i8 ( ) ) ) ;
5528
+ bcx. build . Store ( vec_p0 ( bcx, llnew_vec) , pp0) ;
5529
+
5530
+ bcx. build . CondBr ( bcx. build . TruncOrBitCast
5531
+ ( bcx. build . Load ( llcopy_dst_ptr) ,
5532
+ T_i1 ( ) ) ,
5533
+ copy_dst_cx. llbb ,
5534
+ copy_src_cx. llbb ) ;
5535
+
5536
+
5537
+ fn copy_elts ( @block_ctxt cx ,
5538
+ ValueRef elt_tydesc ,
5539
+ ValueRef dst,
5540
+ ValueRef src,
5541
+ ValueRef n_bytes) -> result {
5542
+
5543
+ auto src_lim = cx. build . GEP ( src, vec ( n_bytes) ) ;
5544
+
5545
+ auto elt_llsz =
5546
+ cx. build . Load ( cx. build . GEP ( elt_tydesc,
5547
+ vec ( C_int ( 0 ) ,
5548
+ C_int ( abi. tydesc_field_size ) ) ) ) ;
5549
+
5550
+ fn take_one ( ValueRef elt_tydesc ,
5551
+ @block_ctxt cx , ValueRef v) -> result {
5552
+ call_tydesc_glue_full ( cx, v,
5553
+ elt_tydesc,
5554
+ abi. tydesc_field_take_glue_off ) ;
5555
+ ret res( cx, v) ;
5556
+ }
5557
+
5558
+ auto bcx = iter_sequence_raw ( cx, src, src_lim,
5559
+ elt_llsz, bind take_one ( elt_tydesc,
5560
+ _, _) ) . bcx ;
5561
+
5562
+ ret call_memcpy ( bcx, dst, src, n_bytes) ;
5563
+ }
5564
+
5565
+ // Copy any dst elements in, omitting null if doing str.
5566
+ auto n_bytes = vec_fill_adjusted ( copy_dst_cx, lldst_vec, llskipnull) ;
5567
+ copy_dst_cx = copy_elts ( copy_dst_cx,
5568
+ llelt_tydesc,
5569
+ copy_dst_cx. build . Load ( pp0) ,
5570
+ vec_p0 ( copy_dst_cx, lldst_vec) ,
5571
+ n_bytes) . bcx ;
5572
+
5573
+ put_vec_fill ( copy_dst_cx, llnew_vec, n_bytes) ;
5574
+ copy_dst_cx. build . Store ( vec_p1_adjusted ( copy_dst_cx,
5575
+ llnew_vec, llskipnull) ,
5576
+ pp0) ;
5577
+ copy_dst_cx. build . Br ( copy_src_cx. llbb ) ;
5578
+
5579
+
5580
+ // Copy any src elements in, carrying along null if doing str.
5581
+ n_bytes = vec_fill ( copy_src_cx, llsrc_vec) ;
5582
+ copy_src_cx = copy_elts ( copy_src_cx,
5583
+ llelt_tydesc,
5584
+ copy_src_cx. build . Load ( pp0) ,
5585
+ vec_p0 ( copy_src_cx, llsrc_vec) ,
5586
+ n_bytes) . bcx ;
5587
+
5588
+ put_vec_fill ( copy_src_cx, llnew_vec,
5589
+ copy_src_cx. build . Add ( vec_fill ( copy_src_cx,
5590
+ llnew_vec) ,
5591
+ n_bytes) ) ;
5592
+
5593
+ // Write new_vec back through the alias we were given.
5594
+ copy_src_cx. build . Store ( llnew_vec, lldst_vec_ptr) ;
5595
+ copy_src_cx. build . RetVoid ( ) ;
5506
5596
}
5507
5597
5508
5598
0 commit comments