diff options
| author | KOBAYASHI Shuji <[email protected]> | 2019-08-14 22:20:34 +0900 |
|---|---|---|
| committer | KOBAYASHI Shuji <[email protected]> | 2019-08-14 22:20:34 +0900 |
| commit | af6724c2f6b012316cef4ffc2d0c9eec8bd2853c (patch) | |
| tree | 54eb1822fd36ef5964fa009861c5f79fbd8107c6 | |
| parent | d986b9ff7b360a0961410950b2387ee49b5ac3c7 (diff) | |
| download | mruby-af6724c2f6b012316cef4ffc2d0c9eec8bd2853c.tar.gz mruby-af6724c2f6b012316cef4ffc2d0c9eec8bd2853c.zip | |
Extract initialization code of shared and fshared string to function
| -rw-r--r-- | src/string.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/src/string.c b/src/string.c index 2e0b1e301..d0547ba3f 100644 --- a/src/string.c +++ b/src/string.c @@ -62,6 +62,34 @@ str_init_embed(struct RString *s, const char *p, size_t len) } static void +str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, mrb_shared_string *shared) +{ + if (shared) { + shared->refcnt++; + } + else { + shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); + shared->refcnt = 2; + shared->nofree = !!RSTR_NOFREE_P(orig); + shared->ptr = orig->as.heap.ptr; + shared->len = orig->as.heap.len; + } + s->as.heap.ptr = orig->as.heap.ptr; + s->as.heap.len = orig->as.heap.len; + s->as.heap.aux.shared = shared; + RSTR_SET_SHARED_FLAG(s); +} + +static void +str_init_fshared(const struct RString *orig, struct RString *s, struct RString *fshared) +{ + s->as.heap.ptr = orig->as.heap.ptr; + s->as.heap.len = orig->as.heap.len; + s->as.heap.aux.fshared = fshared; + RSTR_SET_FSHARED_FLAG(s); +} + +static void str_init(mrb_state *mrb, struct RString *s, const char *p, size_t len) { if (RSTR_EMBEDDABLE_P(len)) { @@ -435,54 +463,29 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) static void str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s) { - mrb_shared_string *shared; mrb_int len = RSTR_LEN(orig); mrb_assert(!RSTR_EMBED_P(orig)); if (RSTR_SHARED_P(orig)) { - shared = orig->as.heap.aux.shared; - shared->refcnt++; - s->as.heap.ptr = orig->as.heap.ptr; - s->as.heap.len = len; - s->as.heap.aux.shared = shared; - RSTR_SET_SHARED_FLAG(s); + str_init_shared(mrb, orig, s, orig->as.heap.aux.shared); RSTR_UNSET_EMBED_FLAG(s); } else if (RSTR_FSHARED_P(orig)) { - struct RString *fs; - - fs = orig->as.heap.aux.fshared; - s->as.heap.ptr = orig->as.heap.ptr; - s->as.heap.len = len; - s->as.heap.aux.fshared = fs; - RSTR_SET_FSHARED_FLAG(s); + str_init_fshared(orig, s, orig->as.heap.aux.fshared); RSTR_UNSET_EMBED_FLAG(s); } else if (MRB_FROZEN_P(orig) && !RSTR_POOL_P(orig)) { - s->as.heap.ptr = orig->as.heap.ptr; - s->as.heap.len = len; - s->as.heap.aux.fshared = orig; - RSTR_SET_FSHARED_FLAG(s); + str_init_fshared(orig, s, orig); RSTR_UNSET_EMBED_FLAG(s); } else { - shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); - shared->refcnt = 2; - shared->nofree = !!RSTR_NOFREE_P(orig); - if (!shared->nofree && orig->as.heap.aux.capa > orig->as.heap.len) { - shared->ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); - orig->as.heap.ptr = shared->ptr; - } - else { - shared->ptr = orig->as.heap.ptr; + if (!RSTR_NOFREE_P(orig) && orig->as.heap.aux.capa > orig->as.heap.len) { + orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); } - orig->as.heap.aux.shared = shared; + str_init_shared(mrb, orig, s, NULL); + RSTR_UNSET_EMBED_FLAG(s); + orig->as.heap.aux.shared = s->as.heap.aux.shared; RSTR_SET_SHARED_FLAG(orig); - shared->len = len; - s->as.heap.aux.shared = shared; - s->as.heap.ptr = shared->ptr; - s->as.heap.len = len; - RSTR_SET_SHARED_FLAG(s); RSTR_UNSET_EMBED_FLAG(s); } } |
