Commit 450684ab authored by KOBAYASHI Shuji's avatar KOBAYASHI Shuji

`mrb_str_modify_keep_ascii` can embed one more byte

The condition to make an embedded string was incorrect. Because there were
several similar codes, extracted into `RSTR_EMBEDDABLE_P` macro.
parent ce7fd7e1
...@@ -52,6 +52,8 @@ struct RString { ...@@ -52,6 +52,8 @@ struct RString {
} while (0) } while (0)
#define RSTR_EMBED_LEN(s)\ #define RSTR_EMBED_LEN(s)\
(mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT) (mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT)
#define RSTR_EMBEDDABLE_P(len) ((len) <= RSTRING_EMBED_LEN_MAX)
#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr) #define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr)
#define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len) #define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len)
#define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa) #define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa)
......
...@@ -60,7 +60,7 @@ str_new(mrb_state *mrb, const char *p, size_t len) ...@@ -60,7 +60,7 @@ str_new(mrb_state *mrb, const char *p, size_t len)
return str_new_static(mrb, p, len); return str_new_static(mrb, p, len);
} }
s = mrb_obj_alloc_string(mrb); s = mrb_obj_alloc_string(mrb);
if (len <= RSTRING_EMBED_LEN_MAX) { if (RSTR_EMBEDDABLE_P(len)) {
RSTR_SET_EMBED_FLAG(s); RSTR_SET_EMBED_FLAG(s);
RSTR_SET_EMBED_LEN(s, len); RSTR_SET_EMBED_LEN(s, len);
if (p) { if (p) {
...@@ -135,7 +135,7 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) ...@@ -135,7 +135,7 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity)
mrb_assert(capacity < MRB_INT_MAX); mrb_assert(capacity < MRB_INT_MAX);
#endif #endif
if (RSTR_EMBED_P(s)) { if (RSTR_EMBED_P(s)) {
if (RSTRING_EMBED_LEN_MAX < capacity) { if (!RSTR_EMBEDDABLE_P(capacity)) {
char *const tmp = (char *)mrb_malloc(mrb, capacity+1); char *const tmp = (char *)mrb_malloc(mrb, capacity+1);
const mrb_int len = RSTR_EMBED_LEN(s); const mrb_int len = RSTR_EMBED_LEN(s);
memcpy(tmp, s->as.ary, len); memcpy(tmp, s->as.ary, len);
...@@ -478,7 +478,7 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) ...@@ -478,7 +478,7 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
struct RString *orig, *s; struct RString *orig, *s;
orig = mrb_str_ptr(str); orig = mrb_str_ptr(str);
if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0 || len <= RSTRING_EMBED_LEN_MAX) { if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0 || RSTR_EMBEDDABLE_P(len)) {
s = str_new(mrb, RSTR_PTR(orig)+beg, len); s = str_new(mrb, RSTR_PTR(orig)+beg, len);
} }
else { else {
...@@ -588,7 +588,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) ...@@ -588,7 +588,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
RSTR_UNSET_FSHARED_FLAG(s1); RSTR_UNSET_FSHARED_FLAG(s1);
RSTR_UNSET_NOFREE_FLAG(s1); RSTR_UNSET_NOFREE_FLAG(s1);
if (len <= RSTRING_EMBED_LEN_MAX) { if (RSTR_EMBEDDABLE_P(len)) {
RSTR_UNSET_SHARED_FLAG(s1); RSTR_UNSET_SHARED_FLAG(s1);
RSTR_UNSET_FSHARED_FLAG(s1); RSTR_UNSET_FSHARED_FLAG(s1);
RSTR_SET_EMBED_FLAG(s1); RSTR_SET_EMBED_FLAG(s1);
...@@ -728,7 +728,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) ...@@ -728,7 +728,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
p = RSTR_PTR(s); p = RSTR_PTR(s);
len = s->as.heap.len; len = s->as.heap.len;
if (len < RSTRING_EMBED_LEN_MAX) { if (RSTR_EMBEDDABLE_P(len)) {
RSTR_SET_EMBED_FLAG(s); RSTR_SET_EMBED_FLAG(s);
RSTR_SET_EMBED_LEN(s, len); RSTR_SET_EMBED_LEN(s, len);
ptr = RSTR_PTR(s); ptr = RSTR_PTR(s);
...@@ -754,7 +754,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) ...@@ -754,7 +754,7 @@ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
RSTR_UNSET_FSHARED_FLAG(s); RSTR_UNSET_FSHARED_FLAG(s);
RSTR_UNSET_NOFREE_FLAG(s); RSTR_UNSET_NOFREE_FLAG(s);
RSTR_UNSET_FSHARED_FLAG(s); RSTR_UNSET_FSHARED_FLAG(s);
if (len < RSTRING_EMBED_LEN_MAX) { if (RSTR_EMBEDDABLE_P(len)) {
RSTR_SET_EMBED_FLAG(s); RSTR_SET_EMBED_FLAG(s);
RSTR_SET_EMBED_LEN(s, len); RSTR_SET_EMBED_LEN(s, len);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment