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

ruby-changes:62075

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Mon, 29 Jun 2020 11:08:49 +0900 (JST)
Subject: [ruby-changes:62075] 9c5804ac1c (master): range_each: do not goto into a branch

https://git.ruby-lang.org/ruby.git/commit/?id=9c5804ac1c

From 9c5804ac1ce78126670082327fa3ab80cff0ee25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Tue, 16 Jun 2020 14:31:11 +0900
Subject: range_each: do not goto into a branch

I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.

diff --git a/range.c b/range.c
index d4732a1..b00800b 100644
--- a/range.c
+++ b/range.c
@@ -829,6 +829,36 @@ range_enum_size(VALUE range, VALUE args, VALUE eobj) https://github.com/ruby/ruby/blob/trunk/range.c#L829
     return range_size(range);
 }
 
+RBIMPL_ATTR_NORETURN()
+static void
+range_each_bignum_endless(VALUE beg)
+{
+    for (;; beg = rb_big_plus(beg, INT2FIX(1))) {
+        rb_yield(beg);
+    }
+}
+
+RBIMPL_ATTR_NORETURN()
+static void
+range_each_fixnum_endless(VALUE beg)
+{
+    for (long i = FIX2LONG(beg); FIXABLE(i); i++) {
+        rb_yield(LONG2FIX(i));
+    }
+
+    range_each_bignum_endless(LONG2NUM(RUBY_FIXNUM_MAX + 1));
+}
+
+static VALUE
+range_each_fixnum_loop(VALUE beg, VALUE end, VALUE range)
+{
+    long lim = FIX2LONG(end) + !EXCL(range);
+    for (long i = FIX2LONG(beg); i < lim; i++) {
+        rb_yield(LONG2FIX(i));
+    }
+    return range;
+}
+
 /*
  *  call-seq:
  *     rng.each {| i | block } -> rng
@@ -854,7 +884,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/range.c#L884
 range_each(VALUE range)
 {
     VALUE beg, end;
-    long i, lim;
+    long i;
 
     RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_size);
 
@@ -862,24 +892,10 @@ range_each(VALUE range) https://github.com/ruby/ruby/blob/trunk/range.c#L892
     end = RANGE_END(range);
 
     if (FIXNUM_P(beg) && NIL_P(end)) {
-      fixnum_endless:
-	i = FIX2LONG(beg);
-	while (FIXABLE(i)) {
-	    rb_yield(LONG2FIX(i++));
-	}
-	beg = LONG2NUM(i);
-      bignum_endless:
-	for (;; beg = rb_big_plus(beg, INT2FIX(1)))
-	    rb_yield(beg);
+        range_each_fixnum_endless(beg);
     }
     else if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
-      fixnum_loop:
-	lim = FIX2LONG(end);
-	if (!EXCL(range))
-	    lim += 1;
-	for (i = FIX2LONG(beg); i < lim; i++) {
-	    rb_yield(LONG2FIX(i));
-	}
+        return range_each_fixnum_loop(beg, end, range);
     }
     else if (RB_INTEGER_TYPE_P(beg) && (NIL_P(end) || RB_INTEGER_TYPE_P(end))) {
 	if (SPECIAL_CONST_P(end) || RBIGNUM_POSITIVE_P(end)) { /* end >= FIXNUM_MIN */
@@ -888,11 +904,11 @@ range_each(VALUE range) https://github.com/ruby/ruby/blob/trunk/range.c#L904
 		    do {
 			rb_yield(beg);
 		    } while (!FIXNUM_P(beg = rb_big_plus(beg, INT2FIX(1))));
-		    if (NIL_P(end)) goto fixnum_endless;
-		    if (FIXNUM_P(end)) goto fixnum_loop;
+                    if (NIL_P(end)) range_each_fixnum_endless(beg);
+                    if (FIXNUM_P(end)) return range_each_fixnum_loop(beg, end, range);
 		}
 		else {
-		    if (NIL_P(end)) goto bignum_endless;
+                    if (NIL_P(end)) range_each_bignum_endless(beg);
 		    if (FIXNUM_P(end)) return range;
 		}
 	    }
-- 
cgit v0.10.2


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

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