diff options
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 30 |
1 files changed, 18 insertions, 12 deletions
@@ -68,7 +68,6 @@ VALUE rb_cSymbol; if (FL_TEST((s),STR_NOEMBED)) FL_UNSET((s),(ELTS_SHARED|STR_ASSOC));\ } while (0) - #define STR_SET_NOEMBED(str) do {\ FL_SET((str), STR_NOEMBED);\ STR_SET_EMBED_LEN((str), 0);\ @@ -119,6 +118,11 @@ VALUE rb_cSymbol; }\ } while (0) +#define STR_SET_SHARED(str, shared_str) do { \ + OBJ_WRITE((str), &RSTRING(str)->as.heap.aux.shared, (shared_str)); \ + FL_SET((str), ELTS_SHARED); \ +} while (0) + #define is_ascii_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) #define is_broken_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) @@ -375,7 +379,7 @@ rb_str_capacity(VALUE str) static inline VALUE str_alloc(VALUE klass) { - NEWOBJ_OF(str, struct RString, klass, T_STRING); + NEWOBJ_OF(str, struct RString, klass, T_STRING | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0)); str->as.heap.ptr = 0; str->as.heap.len = 0; @@ -649,8 +653,7 @@ str_replace_shared_without_enc(VALUE str2, VALUE str) FL_SET(str2, STR_NOEMBED); RSTRING(str2)->as.heap.len = RSTRING_LEN(str); RSTRING(str2)->as.heap.ptr = RSTRING_PTR(str); - RSTRING(str2)->as.heap.aux.shared = str; - FL_SET(str2, ELTS_SHARED); + STR_SET_SHARED(str2, str); } return str2; } @@ -699,12 +702,10 @@ str_new4(VALUE klass, VALUE str) if (STR_SHARED_P(str)) { VALUE shared = RSTRING(str)->as.heap.aux.shared; assert(OBJ_FROZEN(shared)); - FL_SET(str2, ELTS_SHARED); - RSTRING(str2)->as.heap.aux.shared = shared; + STR_SET_SHARED(str2, shared); /* TODO: WB is not needed because str2 is *new* object */ } else { - FL_SET(str, ELTS_SHARED); - RSTRING(str)->as.heap.aux.shared = str2; + STR_SET_SHARED(str, str2); } rb_enc_cr_str_exact_copy(str2, str); OBJ_INFECT(str2, str); @@ -720,6 +721,9 @@ rb_str_new_frozen(VALUE orig) klass = rb_obj_class(orig); if (STR_SHARED_P(orig) && (str = RSTRING(orig)->as.heap.aux.shared)) { long ofs; + if (!OBJ_FROZEN(str)) { + rb_bug("xyzzy"); + } assert(OBJ_FROZEN(str)); ofs = RSTRING_LEN(str) - RSTRING_LEN(orig); if ((ofs > 0) || (klass != RBASIC(str)->klass) || @@ -742,7 +746,8 @@ rb_str_new_frozen(VALUE orig) FL_UNSET(orig, STR_ASSOC); str = str_new4(klass, orig); FL_SET(str, STR_ASSOC); - RSTRING(str)->as.heap.aux.shared = assoc; + OBJ_WRITE(str, &RSTRING(str)->as.heap.aux.shared, assoc); + /* TODO: WB is not needed because str is new object */ } else { str = str_new4(klass, orig); @@ -878,8 +883,9 @@ rb_str_shared_replace(VALUE str, VALUE str2) RSTRING(str)->as.heap.ptr = RSTRING_PTR(str2); RSTRING(str)->as.heap.len = RSTRING_LEN(str2); if (STR_NOCAPA_P(str2)) { + VALUE shared = RSTRING(str2)->as.heap.aux.shared; FL_SET(str, RBASIC(str2)->flags & STR_NOCAPA); - RSTRING(str)->as.heap.aux.shared = RSTRING(str2)->as.heap.aux.shared; + OBJ_WRITE(str, &RSTRING(str)->as.heap.aux.shared, shared); } else { RSTRING(str)->as.heap.aux.capa = RSTRING(str2)->as.heap.aux.capa; @@ -925,7 +931,7 @@ str_replace(VALUE str, VALUE str2) RSTRING(str)->as.heap.ptr = RSTRING_PTR(str2); FL_SET(str, ELTS_SHARED); FL_UNSET(str, STR_ASSOC); - RSTRING(str)->as.heap.aux.shared = shared; + STR_SET_SHARED(str, shared); } else { str_replace_shared(str, str2); @@ -1447,7 +1453,7 @@ rb_str_associate(VALUE str, VALUE add) } FL_SET(str, STR_ASSOC); RBASIC_CLEAR_CLASS(add); - RSTRING(str)->as.heap.aux.shared = add; + OBJ_WRITE(str, &RSTRING(str)->as.heap.aux.shared, add); } } |