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

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/

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