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

ruby-changes:61978

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

https://git.ruby-lang.org/ruby.git/commit/?id=4f2425549a

From 4f2425549a870d8c42ff26812aa53ab93bba5bc8 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: Thu, 11 Jun 2020 11:45:03 +0900
Subject: rb_ary_slice_bang: 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/array.c b/array.c
index 5bc2eb7..5e27926 100644
--- a/array.c
+++ b/array.c
@@ -4407,6 +4407,37 @@ rb_ary_delete_at_m(VALUE ary, VALUE pos) https://github.com/ruby/ruby/blob/trunk/array.c#L4407
     return rb_ary_delete_at(ary, NUM2LONG(pos));
 }
 
+static VALUE
+ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
+{
+    const long orig_len = RARRAY_LEN(ary);
+
+    if (len < 0) {
+        return Qnil;
+    }
+    else if (pos < -orig_len) {
+        return Qnil;
+    }
+    else if (pos < 0) {
+        pos += orig_len;
+    }
+    else if (orig_len < pos) {
+        return Qnil;
+    }
+    else if (orig_len < pos + len) {
+        len = orig_len - pos;
+    }
+    if (len == 0) {
+        return rb_ary_new2(0);
+    }
+    else {
+        VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
+        RBASIC_SET_CLASS(arg2, rb_obj_class(ary));
+        rb_ary_splice(ary, pos, len, 0, 0);
+        return arg2;
+    }
+}
+
 /*
  *  call-seq:
  *     ary.slice!(index)         -> obj or nil
@@ -4431,39 +4462,24 @@ rb_ary_delete_at_m(VALUE ary, VALUE pos) https://github.com/ruby/ruby/blob/trunk/array.c#L4462
 static VALUE
 rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
 {
-    VALUE arg1, arg2;
-    long pos, len, orig_len;
+    VALUE arg1;
+    long pos, len;
 
     rb_ary_modify_check(ary);
+    rb_check_arity(argc, 1, 2);
+    arg1 = argv[0];
+
     if (argc == 2) {
 	pos = NUM2LONG(argv[0]);
 	len = NUM2LONG(argv[1]);
-      delete_pos_len:
-	if (len < 0) return Qnil;
-	orig_len = RARRAY_LEN(ary);
-	if (pos < 0) {
-	    pos += orig_len;
-	    if (pos < 0) return Qnil;
-	}
-	else if (orig_len < pos) return Qnil;
-	if (orig_len < pos + len) {
-	    len = orig_len - pos;
-	}
-	if (len == 0) return rb_ary_new2(0);
-        arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
-	RBASIC_SET_CLASS(arg2, rb_obj_class(ary));
-	rb_ary_splice(ary, pos, len, 0, 0);
-	return arg2;
+        return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
     }
 
-    rb_check_arity(argc, 1, 2);
-    arg1 = argv[0];
-
     if (!FIXNUM_P(arg1)) {
 	switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
 	  case Qtrue:
 	    /* valid range */
-	    goto delete_pos_len;
+            return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
 	  case Qnil:
 	    /* invalid range */
 	    return Qnil;
-- 
cgit v0.10.2


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

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