[前][次][番号順一覧][スレッド一覧]

ruby-changes:52224

From: nagachika <ko1@a...>
Date: Sat, 18 Aug 2018 12:38:01 +0900 (JST)
Subject: [ruby-changes:52224] nagachika:r64432 (ruby_2_5): merge revision(s) 63549, 63551, 63554: [Backport #14805]

nagachika	2018-08-18 12:37:56 +0900 (Sat, 18 Aug 2018)

  New Revision: 64432

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64432

  Log:
    merge revision(s) 63549,63551,63554: [Backport #14805]
    
    memo->u3.cnt is long not int [Bug #14805]
    
    enum.c: mitigate overflows
    
    * enum.c (enum_count): convert counters to Integer as unsigned
      long, instead of long, to mitigate overflows.
      [ruby-core:87348] [Bug #14805]
    
    * enum.c (ary_inject_op): ditto.
    
    * enum.c (each_with_index_i): ditto, instead of int.
    
    * enum.c (find_index_i, find_index_iter_i): ditto, instead of
      unsigned int.
    
    enum.c: bignum counter
    
    * enum.c (imemo_count_up, imemo_count_value): promote the counter
      value to a bignum on overflow.  [Bug #14805]

  Modified directories:
    branches/ruby_2_5/
  Modified files:
    branches/ruby_2_5/enum.c
    branches/ruby_2_5/version.h
Index: ruby_2_5/version.h
===================================================================
--- ruby_2_5/version.h	(revision 64431)
+++ ruby_2_5/version.h	(revision 64432)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_5/version.h#L1
 #define RUBY_VERSION "2.5.2"
 #define RUBY_RELEASE_DATE "2018-08-18"
-#define RUBY_PATCHLEVEL 75
+#define RUBY_PATCHLEVEL 76
 
 #define RUBY_RELEASE_YEAR 2018
 #define RUBY_RELEASE_MONTH 8
Index: ruby_2_5/enum.c
===================================================================
--- ruby_2_5/enum.c	(revision 64431)
+++ ruby_2_5/enum.c	(revision 64432)
@@ -141,6 +141,34 @@ enum_grep_v(VALUE obj, VALUE pat) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L141
     return ary;
 }
 
+#define COUNT_BIGNUM IMEMO_FL_USER0
+#define MEMO_V3_SET(m, v) RB_OBJ_WRITE((m), &(m)->u3.value, (v))
+
+static void
+imemo_count_up(struct MEMO *memo)
+{
+    if (memo->flags & COUNT_BIGNUM) {
+	MEMO_V3_SET(memo, rb_int_succ(memo->u3.value));
+    }
+    else if (++memo->u3.cnt == 0) {
+	/* overflow */
+	unsigned long buf[2] = {0, 1};
+	MEMO_V3_SET(memo, rb_big_unpack(buf, 2));
+	memo->flags |= COUNT_BIGNUM;
+    }
+}
+
+static VALUE
+imemo_count_value(struct MEMO *memo)
+{
+    if (memo->flags & COUNT_BIGNUM) {
+	return memo->u3.value;
+    }
+    else {
+	return ULONG2NUM(memo->u3.cnt);
+    }
+}
+
 static VALUE
 count_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memop))
 {
@@ -149,7 +177,7 @@ count_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, me https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L177
     ENUM_WANT_SVALUE();
 
     if (rb_equal(i, memo->v1)) {
-	memo->u3.cnt++;
+	imemo_count_up(memo);
     }
     return Qnil;
 }
@@ -160,7 +188,7 @@ count_iter_i(RB_BLOCK_CALL_FUNC_ARGLIST( https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L188
     struct MEMO *memo = MEMO_CAST(memop);
 
     if (RTEST(rb_yield_values2(argc, argv))) {
-	memo->u3.cnt++;
+	imemo_count_up(memo);
     }
     return Qnil;
 }
@@ -170,7 +198,7 @@ count_all_i(RB_BLOCK_CALL_FUNC_ARGLIST(i https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L198
 {
     struct MEMO *memo = MEMO_CAST(memop);
 
-    memo->u3.cnt++;
+    imemo_count_up(memo);
     return Qnil;
 }
 
@@ -217,7 +245,7 @@ enum_count(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L245
 
     memo = MEMO_NEW(item, 0, 0);
     rb_block_call(obj, id_each, 0, 0, func, (VALUE)memo);
-    return INT2NUM(memo->u3.cnt);
+    return imemo_count_value(memo);
 }
 
 static VALUE
@@ -285,10 +313,10 @@ find_index_i(RB_BLOCK_CALL_FUNC_ARGLIST( https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L313
     ENUM_WANT_SVALUE();
 
     if (rb_equal(i, memo->v2)) {
-	MEMO_V1_SET(memo, UINT2NUM(memo->u3.cnt));
+	MEMO_V1_SET(memo, imemo_count_value(memo));
 	rb_iter_break();
     }
-    memo->u3.cnt++;
+    imemo_count_up(memo);
     return Qnil;
 }
 
@@ -298,10 +326,10 @@ find_index_iter_i(RB_BLOCK_CALL_FUNC_ARG https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L326
     struct MEMO *memo = MEMO_CAST(memop);
 
     if (RTEST(rb_yield_values2(argc, argv))) {
-	MEMO_V1_SET(memo, UINT2NUM(memo->u3.cnt));
+	MEMO_V1_SET(memo, imemo_count_value(memo));
 	rb_iter_break();
     }
-    memo->u3.cnt++;
+    imemo_count_up(memo);
     return Qnil;
 }
 
@@ -688,7 +716,7 @@ ary_inject_op(VALUE ary, VALUE init, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L716
                 if (FIXNUM_P(e)) {
                     n += FIX2LONG(e); /* should not overflow long type */
                     if (!FIXABLE(n)) {
-                        v = rb_big_plus(LONG2NUM(n), v);
+                        v = rb_big_plus(ULONG2NUM(n), v);
                         n = 0;
                     }
                 }
@@ -2227,9 +2255,11 @@ enum_member(VALUE obj, VALUE val) https://github.com/ruby/ruby/blob/trunk/ruby_2_5/enum.c#L2255
 static VALUE
 each_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo))
 {
-    long n = MEMO_CAST(memo)->u3.cnt++;
+    struct MEMO *m = MEMO_CAST(memo);
+    VALUE n = imemo_count_value(m);
 
-    return rb_yield_values(2, rb_enum_values_pack(argc, argv), INT2NUM(n));
+    imemo_count_up(m);
+    return rb_yield_values(2, rb_enum_values_pack(argc, argv), n);
 }
 
 /*
Index: ruby_2_5
===================================================================
--- ruby_2_5	(revision 64431)
+++ ruby_2_5	(revision 64432)

Property changes on: ruby_2_5
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /trunk:r63549,63551,63554

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]