ruby-changes:43135
From: nobu <ko1@a...>
Date: Mon, 30 May 2016 14:50:31 +0900 (JST)
Subject: [ruby-changes:43135] nobu:r55209 (trunk): string.c: get rid of unnecessary empty string
nobu 2016-05-30 14:50:27 +0900 (Mon, 30 May 2016) New Revision: 55209 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55209 Log: string.c: get rid of unnecessary empty string * string.c (str_substr, rb_str_aref): refactor not to create unnecessary empty string. * string.c (str_byte_substr, str_byte_aref): ditto. Modified files: trunk/ChangeLog trunk/string.c Index: string.c =================================================================== --- string.c (revision 55208) +++ string.c (revision 55209) @@ -2316,9 +2316,17 @@ rb_str_subpos(VALUE str, long beg, long https://github.com/ruby/ruby/blob/trunk/string.c#L2316 return p; } +static VALUE str_substr(VALUE str, long beg, long len, int empty); + VALUE rb_str_substr(VALUE str, long beg, long len) { + return str_substr(str, beg, len, TRUE); +} + +static VALUE +str_substr(VALUE str, long beg, long len, int empty) +{ VALUE str2; char *p = rb_str_subpos(str, beg, &len); @@ -2331,6 +2339,7 @@ rb_str_substr(VALUE str, long beg, long https://github.com/ruby/ruby/blob/trunk/string.c#L2339 RSTRING(str2)->as.heap.len = len; } else { + if (!len && !empty) return Qnil; str2 = rb_str_new_with_class(str, p, len); OBJ_INFECT(str2, str); RB_GC_GUARD(str); @@ -4002,46 +4011,30 @@ rb_str_aref(VALUE str, VALUE indx) https://github.com/ruby/ruby/blob/trunk/string.c#L4011 if (FIXNUM_P(indx)) { idx = FIX2LONG(indx); - - num_index: - str = rb_str_substr(str, idx, 1); - if (!NIL_P(str) && RSTRING_LEN(str) == 0) return Qnil; - return str; } - - if (SPECIAL_CONST_P(indx)) goto generic; - switch (BUILTIN_TYPE(indx)) { - case T_REGEXP: + else if (RB_TYPE_P(indx, T_REGEXP)) { return rb_str_subpat(str, indx, INT2FIX(0)); - - case T_STRING: + } + else if (RB_TYPE_P(indx, T_STRING)) { if (rb_str_index(str, indx, 0) != -1) return rb_str_dup(indx); return Qnil; - - generic: - default: + } + else { /* check if indx is Range */ - { - long beg, len; - VALUE tmp; - - len = str_strlen(str, NULL); - switch (rb_range_beg_len(indx, &beg, &len, len, 0)) { - case Qfalse: - break; - case Qnil: - return Qnil; - default: - tmp = rb_str_substr(str, beg, len); - return tmp; - } + long beg, len = str_strlen(str, NULL); + switch (rb_range_beg_len(indx, &beg, &len, len, 0)) { + case Qfalse: + break; + case Qnil: + return Qnil; + default: + return rb_str_substr(str, beg, len); } idx = NUM2LONG(indx); - goto num_index; } - UNREACHABLE; + return str_substr(str, idx, 1, FALSE); } @@ -4121,7 +4114,7 @@ rb_str_aref_m(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/string.c#L4114 if (RB_TYPE_P(argv[0], T_REGEXP)) { return rb_str_subpat(str, argv[0], argv[1]); } - { + else { long beg = NUM2LONG(argv[0]); long len = NUM2LONG(argv[1]); return rb_str_substr(str, beg, len); @@ -5024,7 +5017,7 @@ rb_str_setbyte(VALUE str, VALUE index, V https://github.com/ruby/ruby/blob/trunk/string.c#L5017 } static VALUE -str_byte_substr(VALUE str, long beg, long len) +str_byte_substr(VALUE str, long beg, long len, int empty) { char *p, *s = RSTRING_PTR(str); long n = RSTRING_LEN(str); @@ -5038,6 +5031,7 @@ str_byte_substr(VALUE str, long beg, lon https://github.com/ruby/ruby/blob/trunk/string.c#L5031 if (beg + len > n) len = n - beg; if (len <= 0) { + if (!empty) return Qnil; len = 0; p = 0; } @@ -5082,34 +5076,25 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/string.c#L5076 str_byte_aref(VALUE str, VALUE indx) { long idx; - switch (TYPE(indx)) { - case T_FIXNUM: + if (FIXNUM_P(indx)) { idx = FIX2LONG(indx); - - num_index: - str = str_byte_substr(str, idx, 1); - if (NIL_P(str) || RSTRING_LEN(str) == 0) return Qnil; - return str; - - default: + } + else { /* check if indx is Range */ - { - long beg, len = RSTRING_LEN(str); + long beg, len = RSTRING_LEN(str); - switch (rb_range_beg_len(indx, &beg, &len, len, 0)) { - case Qfalse: - break; - case Qnil: - return Qnil; - default: - return str_byte_substr(str, beg, len); - } + switch (rb_range_beg_len(indx, &beg, &len, len, 0)) { + case Qfalse: + break; + case Qnil: + return Qnil; + default: + return str_byte_substr(str, beg, len, TRUE); } + idx = NUM2LONG(indx); - goto num_index; } - - UNREACHABLE; + return str_byte_substr(str, idx, 1, FALSE); } /* @@ -5141,7 +5126,7 @@ rb_str_byteslice(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/string.c#L5126 if (argc == 2) { long beg = NUM2LONG(argv[0]); long end = NUM2LONG(argv[1]); - return str_byte_substr(str, beg, end); + return str_byte_substr(str, beg, end, TRUE); } rb_check_arity(argc, 1, 2); return str_byte_aref(str, argv[0]); Index: ChangeLog =================================================================== --- ChangeLog (revision 55208) +++ ChangeLog (revision 55209) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Mon May 30 14:50:25 2016 Nobuyoshi Nakada <nobu@r...> + + * string.c (str_substr, rb_str_aref): refactor not to create + unnecessary empty string. + + * string.c (str_byte_substr, str_byte_aref): ditto. + Mon May 30 00:09:37 2016 NAKAMURA Usaku <usa@r...> * ext/-test-/auto_ext.rb: fixed a heedless bug introduced at r55198. -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/