From f4b8bbb143c952e5dc6887fbf51af87d96c00d97 Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 17 Dec 2002 18:20:46 +0000 Subject: [PATCH] * string.c (rb_str_new4): handle tail shared string. (ruby-bugs-ja:PR#370) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3164 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ string.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 62f8e5fdb0..4a3ef0141d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Dec 18 02:27:34 2002 Nobuyoshi Nakada + + * string.c (rb_str_new4): handle tail shared string. + (ruby-bugs-ja:PR#370) + Tue Dec 17 21:08:29 2002 Nobuyoshi Nakada * node.h (NODE_ATTRASGN): new node, assignment to attribute. diff --git a/string.c b/string.c index 5ca6aae4d1..01316b9c23 100644 --- a/string.c +++ b/string.c @@ -137,6 +137,21 @@ rb_str_new3(str) return str_new3(rb_obj_class(str), str); } +static VALUE +str_new4(klass, str) + VALUE klass, str; +{ + VALUE str2 = rb_obj_alloc(klass); + + RSTRING(str2)->len = RSTRING(str)->len; + RSTRING(str2)->ptr = RSTRING(str)->ptr; + RSTRING(str)->aux.shared = str2; + FL_SET(str, ELTS_SHARED); + OBJ_INFECT(str2, str); + + return str2; +} + VALUE rb_str_new4(orig) VALUE orig; @@ -145,20 +160,20 @@ rb_str_new4(orig) klass = rb_obj_class(orig); if (FL_TEST(orig, ELTS_SHARED)) { - str = str_new3(klass, RSTRING(orig)->aux.shared); + long ofs; + str = RSTRING(orig)->aux.shared; + ofs = RSTRING(str)->len - RSTRING(orig)->len; + str = str_new3(klass, str); + RSTRING(str)->ptr += ofs; + RSTRING(str)->len -= ofs; } else if (FL_TEST(orig, STR_ASSOC)) { str = str_new(klass, RSTRING(orig)->ptr, RSTRING(orig)->len); + OBJ_INFECT(str, orig); } else { - str = rb_obj_alloc(klass); - - RSTRING(str)->len = RSTRING(orig)->len; - RSTRING(str)->ptr = RSTRING(orig)->ptr; - RSTRING(orig)->aux.shared = str; - FL_SET(orig, ELTS_SHARED); + str = str_new4(klass, orig); } - OBJ_INFECT(str, orig); OBJ_FREEZE(str); return str; } @@ -477,7 +492,7 @@ rb_str_substr(str, beg, len) if (len > sizeof(struct RString)/2 && beg + len == RSTRING(str)->len && !FL_TEST(str, STR_ASSOC)) { - if (!FL_TEST(str, ELTS_SHARED)) str = rb_str_new4(str); + if (!FL_TEST(str, ELTS_SHARED)) str = str_new4(CLASS_OF(str), str); str2 = rb_str_new3(str); RSTRING(str2)->ptr += beg; RSTRING(str2)->len = len;