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

ruby-changes:33547

From: nobu <ko1@a...>
Date: Fri, 18 Apr 2014 21:48:30 +0900 (JST)
Subject: [ruby-changes:33547] nobu:r45628 (trunk): string.c: share middle of a string

nobu	2014-04-18 21:48:26 +0900 (Fri, 18 Apr 2014)

  New Revision: 45628

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45628

  Log:
    string.c: share middle of a string
    
    * string.c (rb_str_new_frozen): consider the shared string at
      middle.
    * string.c (rb_str_subseq, rb_str_substr, str_byte_substr): share
      middle of a string.

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/string.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45627)
+++ ChangeLog	(revision 45628)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Apr 18 21:48:24 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* string.c (rb_str_new_frozen): consider the shared string at
+	  middle.
+
+	* string.c (rb_str_subseq, rb_str_substr, str_byte_substr): share
+	  middle of a string.
+
 Fri Apr 18 15:40:05 2014  NARUSE, Yui  <naruse@r...>
 
 	* string.c: use uintptr_t instead of VALUE because they are not ruby
Index: string.c
===================================================================
--- string.c	(revision 45627)
+++ string.c	(revision 45628)
@@ -823,16 +823,17 @@ rb_str_new_frozen(VALUE orig) https://github.com/ruby/ruby/blob/trunk/string.c#L823
     else {
 	if (FL_TEST(orig, STR_SHARED)) {
 	    VALUE shared = RSTRING(orig)->as.heap.aux.shared;
-	    long ofs = RSTRING_LEN(shared) - RSTRING_LEN(orig);
+	    long ofs = RSTRING_PTR(orig) - RSTRING_PTR(shared);
+	    long rest = RSTRING_LEN(shared) - ofs - RSTRING_LEN(orig);
 	    assert(OBJ_FROZEN(shared));
 
-	    if ((ofs > 0) ||
+	    if ((ofs > 0) || (rest > 0) ||
 		(klass != RBASIC(shared)->klass) ||
 		((RBASIC(shared)->flags ^ RBASIC(orig)->flags) & FL_TAINT) ||
 		ENCODING_GET(shared) != ENCODING_GET(orig)) {
 		str = str_new_shared(klass, shared);
 		RSTRING(str)->as.heap.ptr += ofs;
-		RSTRING(str)->as.heap.len -= ofs;
+		RSTRING(str)->as.heap.len -= ofs + rest;
 	    }
 	    else {
 		return shared;
@@ -1789,10 +1790,12 @@ rb_str_subseq(VALUE str, long beg, long https://github.com/ruby/ruby/blob/trunk/string.c#L1790
 {
     VALUE str2;
 
-    if (RSTRING_LEN(str) == beg + len &&
-        RSTRING_EMBED_LEN_MAX < len) {
-        str2 = rb_str_new_shared(rb_str_new_frozen(str));
-        rb_str_drop_bytes(str2, beg);
+    if (RSTRING_EMBED_LEN_MAX < len) {
+	long olen;
+	str2 = rb_str_new_shared(rb_str_new_frozen(str));
+	RSTRING(str2)->as.heap.ptr += beg;
+	olen = RSTRING(str2)->as.heap.len;
+	if (olen > len) RSTRING(str2)->as.heap.len = len;
     }
     else {
         str2 = rb_str_new_with_class(str, RSTRING_PTR(str)+beg, len);
@@ -1897,10 +1900,11 @@ rb_str_substr(VALUE str, long beg, long https://github.com/ruby/ruby/blob/trunk/string.c#L1900
     char *p = rb_str_subpos(str, beg, &len);
 
     if (!p) return Qnil;
-    if (len > RSTRING_EMBED_LEN_MAX && p + len == RSTRING_END(str)) {
+    if (len > RSTRING_EMBED_LEN_MAX) {
+	long ofs = p - RSTRING_PTR(str);
 	str2 = rb_str_new_frozen(str);
 	str2 = str_new_shared(rb_obj_class(str2), str2);
-	RSTRING(str2)->as.heap.ptr += RSTRING(str2)->as.heap.len - len;
+	RSTRING(str2)->as.heap.ptr += ofs;
 	RSTRING(str2)->as.heap.len = len;
     }
     else {
@@ -4409,10 +4413,10 @@ str_byte_substr(VALUE str, long beg, lon https://github.com/ruby/ruby/blob/trunk/string.c#L4413
     else
 	p = s + beg;
 
-    if (len > RSTRING_EMBED_LEN_MAX && beg + len == n) {
+    if (len > RSTRING_EMBED_LEN_MAX) {
 	str2 = rb_str_new_frozen(str);
 	str2 = str_new_shared(rb_obj_class(str2), str2);
-	RSTRING(str2)->as.heap.ptr += RSTRING(str2)->as.heap.len - len;
+	RSTRING(str2)->as.heap.ptr += beg;
 	RSTRING(str2)->as.heap.len = len;
     }
     else {
Index: NEWS
===================================================================
--- NEWS	(revision 45627)
+++ NEWS	(revision 45628)
@@ -107,3 +107,8 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L107
   Ruby's heaps.
 
 * rb_str_cat_cstr() added. This is same as `rb_str_cat2()`.
+
+* `rb_str_substr()` and `rb_str_subseq()` now share middle of a string,
+  but not only the end of a string.  Therefore, result strings may not
+  be NULL-terminated, `StringValueCStr()` is needed calling to obtain a
+  NULL-terminated C string.

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

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