@@ -343,6 +343,11 @@ rb_ary_modify(VALUE ary)
343
343
ARY_SET_CAPA (ary , len );
344
344
ARY_SET_PTR (ary , ptr );
345
345
}
346
+
347
+ /* TODO: age2 promotion, OBJ_PROMOTED() checks not infant. */
348
+ if (OBJ_PROMOTED (ary ) && !OBJ_PROMOTED (shared )) {
349
+ rb_gc_writebarrier_remember_promoted (ary );
350
+ }
346
351
}
347
352
}
348
353
@@ -898,19 +903,6 @@ rb_ary_push(VALUE ary, VALUE item)
898
903
return ary ;
899
904
}
900
905
901
- static VALUE
902
- rb_ary_push_1 (VALUE ary , VALUE item )
903
- {
904
- long idx = RARRAY_LEN (ary );
905
-
906
- if (idx >= ARY_CAPA (ary )) {
907
- ary_double_capa (ary , idx );
908
- }
909
- RARRAY_ASET (ary , idx , item );
910
- ARY_SET_LEN (ary , idx + 1 );
911
- return ary ;
912
- }
913
-
914
906
VALUE
915
907
rb_ary_cat (VALUE ary , const VALUE * ptr , long len )
916
908
{
@@ -1593,6 +1585,7 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
1593
1585
MEMMOVE (RARRAY_PTR (ary ) + beg , RARRAY_CONST_PTR (rpl ), VALUE , rlen );
1594
1586
}
1595
1587
}
1588
+ RB_GC_GUARD (rpl );
1596
1589
}
1597
1590
1598
1591
void
@@ -3077,7 +3070,7 @@ ary_reject(VALUE orig, VALUE result)
3077
3070
for (i = 0 ; i < RARRAY_LEN (orig ); i ++ ) {
3078
3071
VALUE v = RARRAY_AREF (orig , i );
3079
3072
if (!RTEST (rb_yield (v ))) {
3080
- rb_ary_push_1 (result , v );
3073
+ rb_ary_push (result , v );
3081
3074
}
3082
3075
}
3083
3076
return result ;
@@ -4690,6 +4683,25 @@ rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
4690
4683
#define tmpary (n ) rb_ary_tmp_new(n)
4691
4684
#define tmpary_discard (a ) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray))
4692
4685
4686
+ /*
4687
+ * Build a ruby array of the corresponding values and yield it to the
4688
+ * associated block.
4689
+ * Return the class of +values+ for reentry check.
4690
+ */
4691
+ static int
4692
+ yield_indexed_values (const VALUE values , const long r , const long * const p )
4693
+ {
4694
+ const VALUE result = rb_ary_new2 (r );
4695
+ VALUE * const result_array = RARRAY_PTR (result );
4696
+ const VALUE * const values_array = RARRAY_CONST_PTR (values );
4697
+ long i ;
4698
+
4699
+ for (i = 0 ; i < r ; i ++ ) result_array [i ] = values_array [p [i ]];
4700
+ ARY_SET_LEN (result , r );
4701
+ rb_yield (result );
4702
+ return !RBASIC (values )-> klass ;
4703
+ }
4704
+
4693
4705
/*
4694
4706
* Recursively compute permutations of +r+ elements of the set
4695
4707
* <code>[0..n-1]</code>.
@@ -4707,7 +4719,7 @@ rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
4707
4719
static void
4708
4720
permute0 (long n , long r , long * p , long index , char * used , VALUE values )
4709
4721
{
4710
- long i , j ;
4722
+ long i ;
4711
4723
for (i = 0 ; i < n ; i ++ ) {
4712
4724
if (used [i ] == 0 ) {
4713
4725
p [index ] = i ;
@@ -4718,17 +4730,7 @@ permute0(long n, long r, long *p, long index, char *used, VALUE values)
4718
4730
used [i ] = 0 ; /* index unused */
4719
4731
}
4720
4732
else {
4721
- /* We have a complete permutation of array indexes */
4722
- /* Build a ruby array of the corresponding values */
4723
- /* And yield it to the associated block */
4724
- VALUE result = rb_ary_new2 (r );
4725
- VALUE * result_array = RARRAY_PTR (result );
4726
- const VALUE * values_array = RARRAY_PTR (values );
4727
-
4728
- for (j = 0 ; j < r ; j ++ ) result_array [j ] = values_array [p [j ]];
4729
- ARY_SET_LEN (result , r );
4730
- rb_yield (result );
4731
- if (RBASIC (values )-> klass ) {
4733
+ if (!yield_indexed_values (values , r , p )) {
4732
4734
rb_raise (rb_eRuntimeError , "permute reentered" );
4733
4735
}
4734
4736
}
@@ -4826,7 +4828,7 @@ rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
4826
4828
}
4827
4829
}
4828
4830
else { /* this is the general case */
4829
- volatile VALUE t0 = tmpbuf (n ,sizeof (long ));
4831
+ volatile VALUE t0 = tmpbuf (r ,sizeof (long ));
4830
4832
long * p = (long * )RSTRING_PTR (t0 );
4831
4833
volatile VALUE t1 = tmpbuf (n ,sizeof (char ));
4832
4834
char * used = (char * )RSTRING_PTR (t1 );
@@ -4897,21 +4899,19 @@ rb_ary_combination(VALUE ary, VALUE num)
4897
4899
}
4898
4900
}
4899
4901
else {
4900
- volatile VALUE t0 = tmpbuf (n + 1 , sizeof (long ));
4901
- long * stack = (long * )RSTRING_PTR (t0 );
4902
- volatile VALUE cc = tmpary (n );
4903
- VALUE * chosen = RARRAY_PTR (cc );
4902
+ VALUE ary0 = ary_make_shared_copy (ary ); /* private defensive copy of ary */
4903
+ volatile VALUE t0 ;
4904
+ long * stack = ALLOCV_N (long , t0 , n + 1 );
4904
4905
long lev = 0 ;
4905
4906
4906
- MEMZERO (stack , long , n );
4907
+ RBASIC_CLEAR_CLASS (ary0 );
4908
+ MEMZERO (stack + 1 , long , n );
4907
4909
stack [0 ] = -1 ;
4908
4910
for (;;) {
4909
- chosen [lev ] = RARRAY_AREF (ary , stack [lev + 1 ]);
4910
4911
for (lev ++ ; lev < n ; lev ++ ) {
4911
- chosen [ lev ] = RARRAY_AREF ( ary , stack [lev + 1 ] = stack [lev ]+ 1 ) ;
4912
+ stack [lev + 1 ] = stack [lev ]+ 1 ;
4912
4913
}
4913
- rb_yield (rb_ary_new4 (n , chosen ));
4914
- if (RBASIC (t0 )-> klass ) {
4914
+ if (!yield_indexed_values (ary0 , n , stack + 1 )) {
4915
4915
rb_raise (rb_eRuntimeError , "combination reentered" );
4916
4916
}
4917
4917
do {
@@ -4920,8 +4920,8 @@ rb_ary_combination(VALUE ary, VALUE num)
4920
4920
} while (stack [lev + 1 ]+ n == len + lev + 1 );
4921
4921
}
4922
4922
done :
4923
- tmpbuf_discard (t0 );
4924
- tmpary_discard ( cc );
4923
+ ALLOCV_END (t0 );
4924
+ RBASIC_SET_CLASS_RAW ( ary0 , rb_cArray );
4925
4925
}
4926
4926
return ary ;
4927
4927
}
@@ -4942,24 +4942,14 @@ rb_ary_combination(VALUE ary, VALUE num)
4942
4942
static void
4943
4943
rpermute0 (long n , long r , long * p , long index , VALUE values )
4944
4944
{
4945
- long i , j ;
4945
+ long i ;
4946
4946
for (i = 0 ; i < n ; i ++ ) {
4947
4947
p [index ] = i ;
4948
4948
if (index < r - 1 ) { /* if not done yet */
4949
4949
rpermute0 (n , r , p , index + 1 , values ); /* recurse */
4950
4950
}
4951
4951
else {
4952
- /* We have a complete permutation of array indexes */
4953
- /* Build a ruby array of the corresponding values */
4954
- /* And yield it to the associated block */
4955
- VALUE result = rb_ary_new2 (r );
4956
- VALUE * result_array = RARRAY_PTR (result );
4957
- const VALUE * values_array = RARRAY_PTR (values );
4958
-
4959
- for (j = 0 ; j < r ; j ++ ) result_array [j ] = values_array [p [j ]];
4960
- ARY_SET_LEN (result , r );
4961
- rb_yield (result );
4962
- if (RBASIC (values )-> klass ) {
4952
+ if (!yield_indexed_values (values , r , p )) {
4963
4953
rb_raise (rb_eRuntimeError , "repeated permute reentered" );
4964
4954
}
4965
4955
}
@@ -5040,22 +5030,14 @@ rb_ary_repeated_permutation(VALUE ary, VALUE num)
5040
5030
static void
5041
5031
rcombinate0 (long n , long r , long * p , long index , long rest , VALUE values )
5042
5032
{
5043
- long j ;
5044
5033
if (rest > 0 ) {
5045
5034
for (; index < n ; ++ index ) {
5046
5035
p [r - rest ] = index ;
5047
5036
rcombinate0 (n , r , p , index , rest - 1 , values );
5048
5037
}
5049
5038
}
5050
5039
else {
5051
- VALUE result = rb_ary_new2 (r );
5052
- VALUE * result_array = RARRAY_PTR (result );
5053
- const VALUE * values_array = RARRAY_PTR (values );
5054
-
5055
- for (j = 0 ; j < r ; ++ j ) result_array [j ] = values_array [p [j ]];
5056
- ARY_SET_LEN (result , r );
5057
- rb_yield (result );
5058
- if (RBASIC (values )-> klass ) {
5040
+ if (!yield_indexed_values (values , r , p )) {
5059
5041
rb_raise (rb_eRuntimeError , "repeated combination reentered" );
5060
5042
}
5061
5043
}
0 commit comments