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/