diff --git a/insns.def b/insns.def index 53f9bc0c16..65410e1451 100644 --- a/insns.def +++ b/insns.def @@ -365,13 +365,7 @@ concatstrings (...) (VALUE val) // inc += 1 - num; { - rb_num_t i = num - 1; - - val = rb_str_resurrect(TOPN(i)); - while (i-- > 0) { - const VALUE v = TOPN(i); - rb_str_append_literal(val, v); - } + val = rb_str_concat_literals(num, &TOPN(num-1)); POPN(num); } diff --git a/string.c b/string.c index 04d849f136..4ee59b2bd9 100644 --- a/string.c +++ b/string.c @@ -2677,13 +2677,24 @@ rb_str_append(VALUE str, VALUE str2) } VALUE -rb_str_append_literal(VALUE str, VALUE str2) +rb_str_concat_literals(size_t num, const VALUE *strary) { - int encidx = rb_enc_get_index(str2); - rb_str_buf_append(str, str2); - if (encidx != ENCINDEX_US_ASCII) { - if (rb_enc_get_index(str) == ENCINDEX_US_ASCII) - rb_enc_associate_index(str, encidx); + VALUE str; + size_t i; + + if (!num) return rb_str_new(0, 0); + str = rb_str_resurrect(strary[0]); + for (i = 1; i < num; ++i) { + const VALUE v = strary[i]; + int encidx = ENCODING_GET(v); + + rb_enc_cr_str_buf_cat(str, RSTRING_PTR(v), RSTRING_LEN(v), + encidx, ENC_CODERANGE(v), NULL); + OBJ_INFECT_RAW(str, v); + if (encidx != ENCINDEX_US_ASCII) { + if (ENCODING_GET_INLINED(str) == ENCINDEX_US_ASCII) + rb_enc_set_index(str, encidx); + } } return str; } diff --git a/vm.c b/vm.c index 64081b49e5..77f57d9839 100644 --- a/vm.c +++ b/vm.c @@ -23,7 +23,7 @@ #include "probes.h" #include "probes_helper.h" -VALUE rb_str_append_literal(VALUE str, VALUE str2); +VALUE rb_str_concat_literals(size_t, const VALUE*); static inline VALUE * VM_EP_LEP(VALUE *ep)