summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'string.c')
-rw-r--r--string.c104
1 files changed, 48 insertions, 56 deletions
diff --git a/string.c b/string.c
index 470bc59b76..a7d05693f1 100644
--- a/string.c
+++ b/string.c
@@ -110,18 +110,9 @@ VALUE rb_cSymbol;
FL_UNSET((str), STR_SHARED | STR_SHARED_ROOT | STR_BORROWED);\
} while (0)
#define STR_SET_EMBED(str) FL_UNSET((str), (STR_NOEMBED|STR_NOFREE))
-# define STR_SET_EMBED_LEN(str, n) do { \
- assert(str_embed_capa(str) > (n));\
- RSTRING(str)->as.embed.len = (n);\
-} while (0)
#define STR_SET_LEN(str, n) do { \
- if (STR_EMBED_P(str)) {\
- STR_SET_EMBED_LEN((str), (n));\
- }\
- else {\
- RSTRING(str)->as.heap.len = (n);\
- }\
+ RSTRING(str)->len = (n); \
} while (0)
static inline bool
@@ -158,7 +149,7 @@ str_enc_fastpath(VALUE str)
const long tlen = RSTRING_LEN(str);\
memcpy(tmp, RSTRING_PTR(str), tlen);\
RSTRING(str)->as.heap.ptr = tmp;\
- RSTRING(str)->as.heap.len = tlen;\
+ RSTRING(str)->len = tlen;\
STR_SET_NOEMBED(str);\
RSTRING(str)->as.heap.aux.capa = (capacity);\
}\
@@ -222,7 +213,7 @@ rb_str_size_as_embedded(VALUE str)
{
size_t real_size;
if (STR_EMBED_P(str)) {
- real_size = rb_str_embed_size(RSTRING(str)->as.embed.len) + TERM_LEN(str);
+ real_size = rb_str_embed_size(RSTRING(str)->len) + TERM_LEN(str);
}
/* if the string is not currently embedded, but it can be embedded, how
* much space would it require */
@@ -275,10 +266,10 @@ rb_str_make_embedded(VALUE str)
RUBY_ASSERT(!STR_EMBED_P(str));
char *buf = RSTRING(str)->as.heap.ptr;
- long len = RSTRING(str)->as.heap.len;
+ long len = RSTRING(str)->len;
STR_SET_EMBED(str);
- STR_SET_EMBED_LEN(str, len);
+ STR_SET_LEN(str, len);
if (len > 0) {
memcpy(RSTRING_PTR(str), buf, len);
@@ -382,13 +373,13 @@ fstr_update_callback(st_data_t *key, st_data_t *value, st_data_t data, int exist
else {
if (FL_TEST_RAW(str, STR_FAKESTR)) {
if (arg->copy) {
- VALUE new_str = str_new(rb_cString, RSTRING(str)->as.heap.ptr, RSTRING(str)->as.heap.len);
+ VALUE new_str = str_new(rb_cString, RSTRING(str)->as.heap.ptr, RSTRING(str)->len);
rb_enc_copy(new_str, str);
str = new_str;
}
else {
str = str_new_static(rb_cString, RSTRING(str)->as.heap.ptr,
- RSTRING(str)->as.heap.len,
+ RSTRING(str)->len,
ENCODING_GET(str));
}
OBJ_FREEZE_RAW(str);
@@ -486,7 +477,7 @@ setup_fake_str(struct RString *fake_str, const char *name, long len, int encidx)
ENCODING_SET_INLINED((VALUE)fake_str, encidx);
RBASIC_SET_CLASS_RAW((VALUE)fake_str, rb_cString);
- fake_str->as.heap.len = len;
+ fake_str->len = len;
fake_str->as.heap.ptr = (char *)name;
fake_str->as.heap.aux.capa = len;
return (VALUE)fake_str;
@@ -832,7 +823,7 @@ str_capacity(VALUE str, const int termlen)
return str_embed_capa(str) - termlen;
}
else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
- return RSTRING(str)->as.heap.len;
+ return RSTRING(str)->len;
}
else {
return RSTRING(str)->as.heap.aux.capa;
@@ -1012,7 +1003,7 @@ str_new_static(VALUE klass, const char *ptr, long len, int encindex)
else {
RUBY_DTRACE_CREATE_HOOK(STRING, len);
str = str_alloc_heap(klass);
- RSTRING(str)->as.heap.len = len;
+ RSTRING(str)->len = len;
RSTRING(str)->as.heap.ptr = (char *)ptr;
RSTRING(str)->as.heap.aux.capa = len;
RBASIC(str)->flags |= STR_NOFREE;
@@ -1296,7 +1287,6 @@ str_replace_shared_without_enc(VALUE str2, VALUE str)
char *ptr2 = RSTRING(str2)->as.embed.ary;
STR_SET_EMBED(str2);
memcpy(ptr2, RSTRING_PTR(str), len);
- STR_SET_EMBED_LEN(str2, len);
TERM_FILL(ptr2+len, termlen);
}
else {
@@ -1320,10 +1310,12 @@ str_replace_shared_without_enc(VALUE str2, VALUE str)
}
}
FL_SET(str2, STR_NOEMBED);
- RSTRING(str2)->as.heap.len = len;
RSTRING(str2)->as.heap.ptr = ptr;
STR_SET_SHARED(str2, root);
}
+
+ STR_SET_LEN(str2, len);
+
return str2;
}
@@ -1383,7 +1375,7 @@ rb_str_tmp_frozen_release(VALUE orig, VALUE tmp)
if (shared == tmp && !FL_TEST_RAW(tmp, STR_BORROWED)) {
assert(RSTRING(orig)->as.heap.ptr == RSTRING(tmp)->as.heap.ptr);
- assert(RSTRING(orig)->as.heap.len == RSTRING(tmp)->as.heap.len);
+ assert(RSTRING_LEN(orig) == RSTRING_LEN(tmp));
/* Unshare orig since the root (tmp) only has this one child. */
FL_UNSET_RAW(orig, STR_SHARED);
@@ -1393,7 +1385,7 @@ rb_str_tmp_frozen_release(VALUE orig, VALUE tmp)
/* Make tmp embedded and empty so it is safe for sweeping. */
STR_SET_EMBED(tmp);
- STR_SET_EMBED_LEN(tmp, 0);
+ STR_SET_LEN(tmp, 0);
}
}
}
@@ -1411,7 +1403,7 @@ heap_str_make_shared(VALUE klass, VALUE orig)
assert(!STR_SHARED_P(orig));
VALUE str = str_alloc_heap(klass);
- RSTRING(str)->as.heap.len = RSTRING_LEN(orig);
+ STR_SET_LEN(str, RSTRING_LEN(orig));
RSTRING(str)->as.heap.ptr = RSTRING_PTR(orig);
RSTRING(str)->as.heap.aux.capa = RSTRING(orig)->as.heap.aux.capa;
RBASIC(str)->flags |= RBASIC(orig)->flags & STR_NOFREE;
@@ -1438,7 +1430,7 @@ str_new_frozen_buffer(VALUE klass, VALUE orig, int copy_encoding)
if (FL_TEST_RAW(orig, STR_SHARED)) {
VALUE shared = RSTRING(orig)->as.heap.aux.shared;
long ofs = RSTRING(orig)->as.heap.ptr - RSTRING_PTR(shared);
- long rest = RSTRING_LEN(shared) - ofs - RSTRING(orig)->as.heap.len;
+ long rest = RSTRING_LEN(shared) - ofs - RSTRING_LEN(orig);
assert(ofs >= 0);
assert(rest >= 0);
assert(ofs + rest <= RSTRING_LEN(shared));
@@ -1450,7 +1442,7 @@ str_new_frozen_buffer(VALUE klass, VALUE orig, int copy_encoding)
str = str_new_shared(klass, shared);
assert(!STR_EMBED_P(str));
RSTRING(str)->as.heap.ptr += ofs;
- RSTRING(str)->as.heap.len -= ofs + rest;
+ STR_SET_LEN(str, RSTRING_LEN(str) - (ofs + rest));
}
else {
if (RBASIC_CLASS(shared) == 0)
@@ -1462,7 +1454,7 @@ str_new_frozen_buffer(VALUE klass, VALUE orig, int copy_encoding)
str = str_alloc_embed(klass, RSTRING_LEN(orig) + TERM_LEN(orig));
STR_SET_EMBED(str);
memcpy(RSTRING_PTR(str), RSTRING_PTR(orig), RSTRING_LEN(orig));
- STR_SET_EMBED_LEN(str, RSTRING_LEN(orig));
+ STR_SET_LEN(str, RSTRING_LEN(orig));
TERM_FILL(RSTRING_END(str), TERM_LEN(orig));
}
else {
@@ -1591,23 +1583,24 @@ str_shared_replace(VALUE str, VALUE str2)
str_discard(str);
termlen = rb_enc_mbminlen(enc);
+ STR_SET_LEN(str, RSTRING_LEN(str2));
+
if (str_embed_capa(str) >= RSTRING_LEN(str2) + termlen) {
STR_SET_EMBED(str);
memcpy(RSTRING_PTR(str), RSTRING_PTR(str2), (size_t)RSTRING_LEN(str2) + termlen);
- STR_SET_EMBED_LEN(str, RSTRING_LEN(str2));
rb_enc_associate(str, enc);
ENC_CODERANGE_SET(str, cr);
}
else {
if (STR_EMBED_P(str2)) {
assert(!FL_TEST(str2, STR_SHARED));
- long len = RSTRING(str2)->as.embed.len;
+ long len = RSTRING_LEN(str2);
assert(len + termlen <= str_embed_capa(str2));
char *new_ptr = ALLOC_N(char, len + termlen);
memcpy(new_ptr, RSTRING(str2)->as.embed.ary, len + termlen);
RSTRING(str2)->as.heap.ptr = new_ptr;
- RSTRING(str2)->as.heap.len = len;
+ STR_SET_LEN(str2, len);
RSTRING(str2)->as.heap.aux.capa = len;
STR_SET_NOEMBED(str2);
}
@@ -1615,7 +1608,6 @@ str_shared_replace(VALUE str, VALUE str2)
STR_SET_NOEMBED(str);
FL_UNSET(str, STR_SHARED);
RSTRING(str)->as.heap.ptr = RSTRING_PTR(str2);
- RSTRING(str)->as.heap.len = RSTRING_LEN(str2);
if (FL_TEST(str2, STR_SHARED)) {
VALUE shared = RSTRING(str2)->as.heap.aux.shared;
@@ -1628,7 +1620,7 @@ str_shared_replace(VALUE str, VALUE str2)
/* abandon str2 */
STR_SET_EMBED(str2);
RSTRING_PTR(str2)[0] = 0;
- STR_SET_EMBED_LEN(str2, 0);
+ STR_SET_LEN(str2, 0);
rb_enc_associate(str, enc);
ENC_CODERANGE_SET(str, cr);
}
@@ -1664,7 +1656,7 @@ str_replace(VALUE str, VALUE str2)
VALUE shared = RSTRING(str2)->as.heap.aux.shared;
assert(OBJ_FROZEN(shared));
STR_SET_NOEMBED(str);
- RSTRING(str)->as.heap.len = len;
+ STR_SET_LEN(str, len);
RSTRING(str)->as.heap.ptr = RSTRING_PTR(str2);
STR_SET_SHARED(str, shared);
rb_enc_cr_str_exact_copy(str, str2);
@@ -1708,11 +1700,10 @@ str_duplicate_setup(VALUE klass, VALUE str, VALUE dup)
VALUE flags = FL_TEST_RAW(str, flag_mask);
int encidx = 0;
if (STR_EMBED_P(str)) {
- long len = RSTRING_EMBED_LEN(str);
+ long len = RSTRING_LEN(str);
assert(STR_EMBED_P(dup));
assert(str_embed_capa(dup) >= len + 1);
- STR_SET_EMBED_LEN(dup, len);
MEMCPY(RSTRING(dup)->as.embed.ary, RSTRING(str)->as.embed.ary, char, len + 1);
}
else {
@@ -1727,13 +1718,14 @@ str_duplicate_setup(VALUE klass, VALUE str, VALUE dup)
assert(!STR_SHARED_P(root));
assert(RB_OBJ_FROZEN_RAW(root));
- RSTRING(dup)->as.heap.len = RSTRING_LEN(str);
RSTRING(dup)->as.heap.ptr = RSTRING_PTR(str);
FL_SET(root, STR_SHARED_ROOT);
RB_OBJ_WRITE(dup, &RSTRING(dup)->as.heap.aux.shared, root);
flags |= RSTRING_NOEMBED | STR_SHARED;
}
+ STR_SET_LEN(dup, RSTRING_LEN(str));
+
if ((flags & ENCODING_MASK) == (ENCODING_INLINE_MAX<<ENCODING_SHIFT)) {
encidx = rb_enc_get_index(str);
flags &= ~ENCODING_MASK;
@@ -1751,7 +1743,7 @@ ec_str_duplicate(struct rb_execution_context_struct *ec, VALUE klass, VALUE str)
dup = ec_str_alloc_heap(ec, klass);
}
else {
- dup = ec_str_alloc_embed(ec, klass, RSTRING_EMBED_LEN(str) + TERM_LEN(str));
+ dup = ec_str_alloc_embed(ec, klass, RSTRING_LEN(str) + TERM_LEN(str));
}
return str_duplicate_setup(klass, str, dup);
@@ -1765,7 +1757,7 @@ str_duplicate(VALUE klass, VALUE str)
dup = str_alloc_heap(klass);
}
else {
- dup = str_alloc_embed(klass, RSTRING_EMBED_LEN(str) + TERM_LEN(str));
+ dup = str_alloc_embed(klass, RSTRING_LEN(str) + TERM_LEN(str));
}
return str_duplicate_setup(klass, str, dup);
@@ -1841,14 +1833,14 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
str_modifiable(str);
if (STR_EMBED_P(str)) { /* make noembed always */
char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
- assert(RSTRING(str)->as.embed.len + 1 <= str_embed_capa(str));
- memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING(str)->as.embed.len + 1);
+ assert(RSTRING_LEN(str) + 1 <= str_embed_capa(str));
+ memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING_LEN(str) + 1);
RSTRING(str)->as.heap.ptr = new_ptr;
}
else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
const size_t size = (size_t)capa + termlen;
const char *const old_ptr = RSTRING_PTR(str);
- const size_t osize = RSTRING(str)->as.heap.len + TERM_LEN(str);
+ const size_t osize = RSTRING_LEN(str) + TERM_LEN(str);
char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
memcpy(new_ptr, old_ptr, osize < size ? osize : size);
FL_UNSET_RAW(str, STR_SHARED|STR_NOFREE);
@@ -1858,7 +1850,7 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
(size_t)capa + termlen, STR_HEAP_SIZE(str));
}
- RSTRING(str)->as.heap.len = len;
+ STR_SET_LEN(str, len);
TERM_FILL(&RSTRING(str)->as.heap.ptr[len], termlen);
if (n == 1) {
memcpy(RSTRING(str)->as.heap.ptr, RSTRING_PTR(orig), len);
@@ -2350,7 +2342,7 @@ str_make_independent_expand(VALUE str, long len, long expand, const int termlen)
STR_SET_EMBED(str);
memcpy(RSTRING(str)->as.embed.ary, ptr, len);
TERM_FILL(RSTRING(str)->as.embed.ary + len, termlen);
- STR_SET_EMBED_LEN(str, len);
+ STR_SET_LEN(str, len);
return;
}
@@ -2366,7 +2358,7 @@ str_make_independent_expand(VALUE str, long len, long expand, const int termlen)
FL_UNSET(str, STR_SHARED|STR_NOFREE);
TERM_FILL(ptr + len, termlen);
RSTRING(str)->as.heap.ptr = ptr;
- RSTRING(str)->as.heap.len = len;
+ STR_SET_LEN(str, len);
RSTRING(str)->as.heap.aux.capa = capa;
}
@@ -2418,7 +2410,7 @@ str_discard(VALUE str)
if (!STR_EMBED_P(str) && !FL_TEST(str, STR_SHARED|STR_NOFREE)) {
ruby_sized_xfree(STR_HEAP_PTR(str), STR_HEAP_SIZE(str));
RSTRING(str)->as.heap.ptr = 0;
- RSTRING(str)->as.heap.len = 0;
+ STR_SET_LEN(str, 0);
}
}
@@ -2751,8 +2743,8 @@ str_subseq(VALUE str, long beg, long len)
str2 = str_new_shared(rb_cString, str);
ENC_CODERANGE_CLEAR(str2);
RSTRING(str2)->as.heap.ptr += beg;
- if (RSTRING(str2)->as.heap.len > len) {
- RSTRING(str2)->as.heap.len = len;
+ if (RSTRING_LEN(str2) > len) {
+ STR_SET_LEN(str2, len);
}
}
@@ -3001,7 +2993,7 @@ rb_str_resize(VALUE str, long len)
if (STR_EMBED_P(str)) {
if (len == slen) return str;
if (str_embed_capa(str) >= len + termlen) {
- STR_SET_EMBED_LEN(str, len);
+ STR_SET_LEN(str, len);
TERM_FILL(RSTRING(str)->as.embed.ary + len, termlen);
return str;
}
@@ -3013,7 +3005,7 @@ rb_str_resize(VALUE str, long len)
if (slen > len) slen = len;
if (slen > 0) MEMCPY(RSTRING(str)->as.embed.ary, ptr, char, slen);
TERM_FILL(RSTRING(str)->as.embed.ary + len, termlen);
- STR_SET_EMBED_LEN(str, len);
+ STR_SET_LEN(str, len);
if (independent) ruby_xfree(ptr);
return str;
}
@@ -3028,7 +3020,7 @@ rb_str_resize(VALUE str, long len)
RSTRING(str)->as.heap.aux.capa = len;
}
else if (len == slen) return str;
- RSTRING(str)->as.heap.len = len;
+ STR_SET_LEN(str, len);
TERM_FILL(RSTRING(str)->as.heap.ptr + len, termlen); /* sentinel */
}
return str;
@@ -5158,7 +5150,6 @@ rb_str_drop_bytes(VALUE str, long len)
char *oldptr = ptr;
int fl = (int)(RBASIC(str)->flags & (STR_NOEMBED|STR_SHARED|STR_NOFREE));
STR_SET_EMBED(str);
- STR_SET_EMBED_LEN(str, nlen);
ptr = RSTRING(str)->as.embed.ary;
memmove(ptr, oldptr + len, nlen);
if (fl == STR_NOEMBED) xfree(oldptr);
@@ -5170,8 +5161,9 @@ rb_str_drop_bytes(VALUE str, long len)
OBJ_FREEZE(shared);
}
ptr = RSTRING(str)->as.heap.ptr += len;
- RSTRING(str)->as.heap.len = nlen;
}
+ STR_SET_LEN(str, nlen);
+
ptr[nlen] = 0;
ENC_CODERANGE_CLEAR(str);
return str;
@@ -5946,7 +5938,7 @@ rb_str_clear(VALUE str)
{
str_discard(str);
STR_SET_EMBED(str);
- STR_SET_EMBED_LEN(str, 0);
+ STR_SET_LEN(str, 0);
RSTRING_PTR(str)[0] = 0;
if (rb_enc_asciicompat(STR_ENC_GET(str)))
ENC_CODERANGE_SET(str, ENC_CODERANGE_7BIT);
@@ -7926,7 +7918,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
}
TERM_FILL((char *)t, termlen);
RSTRING(str)->as.heap.ptr = (char *)buf;
- RSTRING(str)->as.heap.len = t - buf;
+ STR_SET_LEN(str, t - buf);
STR_SET_NOEMBED(str);
RSTRING(str)->as.heap.aux.capa = max;
}
@@ -8002,7 +7994,7 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
}
TERM_FILL((char *)t, termlen);
RSTRING(str)->as.heap.ptr = (char *)buf;
- RSTRING(str)->as.heap.len = t - buf;
+ STR_SET_LEN(str, t - buf);
STR_SET_NOEMBED(str);
RSTRING(str)->as.heap.aux.capa = max;
}
@@ -10722,7 +10714,7 @@ rb_str_b(VALUE str)
str2 = str_alloc_heap(rb_cString);
}
else {
- str2 = str_alloc_embed(rb_cString, RSTRING_EMBED_LEN(str) + TERM_LEN(str));
+ str2 = str_alloc_embed(rb_cString, RSTRING_LEN(str) + TERM_LEN(str));
}
str_replace_shared_without_enc(str2, str);