@@ -614,16 +614,16 @@ ary_fit_stride_batch(VALUE ary, const VALUE *argv, long argc)
614614 if (all_fix && ary_fixnum_fits_stride (lo , stride , uns ) && ary_fixnum_fits_stride (hi , stride , uns )) {
615615 return ; /* everything fits as is */
616616 }
617- if (ARY_SHARED_P (ary )) rb_ary_cancel_sharing (ary ); /* see ary_fit_stride */
617+ /* A view must not change the root's buffer: take a private copy first. */
618+ if (ARY_SHARED_P (ary )) rb_ary_cancel_sharing (ary );
618619 if (!all_fix || (uns && lo < 0 )) {
619620 rb_ary_widen (ary ); /* non-Fixnum, or negative into unsigned */
620621 return ;
621622 }
622- /* Width these elements need, keeping the array's signedness: a signed
623- * array must stay signed even if every element here is non-negative. */
624- long range_lo = (!uns && lo >= 0 ) ? -1 : lo ;
623+ /* A signed array stays signed even if every element here is non-negative. */
624+ if (!uns && lo >= 0 ) lo = -1 ;
625625 int need_uns ;
626- int need = ary_stride_for_range (range_lo , hi , & need_uns );
626+ int need = ary_stride_for_range (lo , hi , & need_uns );
627627 if (need == RARRAY_STRIDE_VALUE ) {
628628 rb_ary_widen (ary );
629629 }
@@ -638,7 +638,8 @@ ary_fixnum_fits_stride(long v, int stride, int uns)
638638{
639639 if (stride == RARRAY_STRIDE_VALUE ) return true;
640640
641- long min , max ;
641+ /* int64_t, not long: UINT32_MAX does not fit a 32-bit long (LLP64, i686). */
642+ int64_t min , max ;
642643 if (uns ) {
643644 min = 0 ;
644645 switch (stride ) {
@@ -989,36 +990,7 @@ ary_fit_stride(VALUE ary, VALUE elem)
989990 if (FIXNUM_P (elem ) && ary_fixnum_fits_stride (FIX2LONG (elem ), stride , rb_array_stride_unsigned_p (ary ))) {
990991 return ; /* fits as is; a view may write in place into its root's buffer */
991992 }
992-
993- /* The representation has to change. A view must not do that to the
994- * root's buffer: take a private copy first. */
995- if (ARY_SHARED_P (ary )) rb_ary_cancel_sharing (ary );
996-
997- if (!FIXNUM_P (elem )) {
998- rb_ary_widen (ary );
999- return ;
1000- }
1001-
1002- long v = FIX2LONG (elem );
1003- int uns = rb_array_stride_unsigned_p (ary );
1004- if (ary_fixnum_fits_stride (v , stride , uns )) return ;
1005-
1006- int new_uns ;
1007- int needed = ary_stride_for_fixnum (v , & new_uns );
1008-
1009- /* Sign mismatch: picking a signed width that also covers the existing
1010- * elements needs a scan of the buffer. Widen for now. */
1011- if (uns != new_uns ) {
1012- rb_ary_widen (ary );
1013- return ;
1014- }
1015-
1016- if (needed == RARRAY_STRIDE_VALUE ) {
1017- rb_ary_widen (ary );
1018- return ;
1019- }
1020-
1021- ary_promote_stride (ary , needed , uns );
993+ ary_fit_stride_batch (ary , & elem , 1 );
1022994}
1023995
1024996static void
0 commit comments