diff options
Diffstat (limited to 'prism_compile.c')
-rw-r--r-- | prism_compile.c | 82 |
1 files changed, 66 insertions, 16 deletions
diff --git a/prism_compile.c b/prism_compile.c index 0508ced5ff..e919a44c08 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -787,6 +787,44 @@ pm_interpolated_node_compile(pm_node_list_t *parts, rb_iseq_t *iseq, NODE dummy_ if (parts_size > 0) { VALUE current_string = Qnil; + bool literal = true; + for (size_t index = 0; index < parts_size; index++) { + const pm_node_t *part = parts->nodes[index]; + + if (!PM_NODE_TYPE_P(part, PM_STRING_NODE)) { + literal = false; + break; + } + } + + if (literal) { + for (size_t index = 0; index < parts_size; index++) { + const pm_node_t *part = parts->nodes[index]; + const pm_string_node_t *string_node = (const pm_string_node_t *)part; + VALUE string_value = parse_string_encoded(scope_node, (pm_node_t *)string_node, &string_node->unescaped); + + if (RTEST(current_string)) { + current_string = rb_str_concat(current_string, string_value); + } + else { + current_string = string_value; + } + } + + const pm_node_t *part = parts->nodes[0]; + current_string = rb_fstring(current_string); + if (PM_NODE_FLAG_P(part, PM_STRING_FLAGS_FROZEN)) { + ADD_INSN1(ret, &dummy_line_node, putobject, current_string); + } + else if (PM_NODE_FLAG_P(part, PM_STRING_FLAGS_MUTABLE)) { + ADD_INSN1(ret, &dummy_line_node, putstring, current_string); + } + else { + ADD_INSN1(ret, &dummy_line_node, putchilledstring, current_string); + } + return 1; + } + for (size_t index = 0; index < parts_size; index++) { const pm_node_t *part = parts->nodes[index]; @@ -820,12 +858,7 @@ pm_interpolated_node_compile(pm_node_list_t *parts, rb_iseq_t *iseq, NODE dummy_ current_string = rb_enc_str_new(NULL, 0, scope_node->encoding); } - if (frozen_string_literal_p(iseq)) { - ADD_INSN1(ret, &dummy_line_node, putobject, rb_str_freeze(current_string)); - } - else { - ADD_INSN1(ret, &dummy_line_node, putstring, rb_str_freeze(current_string)); - } + ADD_INSN1(ret, &dummy_line_node, putobject, rb_fstring(current_string)); current_string = Qnil; number_of_items_pushed++; @@ -841,14 +874,7 @@ pm_interpolated_node_compile(pm_node_list_t *parts, rb_iseq_t *iseq, NODE dummy_ if (RTEST(current_string)) { current_string = rb_fstring(current_string); - - if (frozen_string_literal_p(iseq)) { - ADD_INSN1(ret, &dummy_line_node, putobject, current_string); - } - else { - ADD_INSN1(ret, &dummy_line_node, putstring, current_string); - } - + ADD_INSN1(ret, &dummy_line_node, putobject, current_string); current_string = Qnil; number_of_items_pushed++; } @@ -7925,9 +7951,12 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_FROZEN)) { PUSH_INSN1(ret, location, putobject, string); } - else { + else if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_MUTABLE)) { PUSH_INSN1(ret, location, putstring, string); } + else { + PUSH_INSN1(ret, location, putchilledstring, string); + } } return; } @@ -7979,9 +8008,12 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, if (PM_NODE_FLAG_P(node, PM_STRING_FLAGS_FROZEN)) { PUSH_INSN1(ret, location, putobject, value); } - else { + else if (PM_NODE_FLAG_P(node, PM_STRING_FLAGS_MUTABLE)) { PUSH_INSN1(ret, location, putstring, value); } + else { + PUSH_INSN1(ret, location, putchilledstring, value); + } } return; } @@ -8354,6 +8386,24 @@ pm_parse_file_script_lines(const pm_scope_node_t *scope_node, const pm_parser_t return lines; } +void +pm_options_frozen_string_literal_init(pm_parse_result_t *result, int frozen_string_literal) +{ + switch (frozen_string_literal) { + case ISEQ_FROZEN_STRING_LITERAL_UNSET: + break; + case ISEQ_FROZEN_STRING_LITERAL_DISABLED: + pm_options_frozen_string_literal_set(&result->options, false); + break; + case ISEQ_FROZEN_STRING_LITERAL_ENABLED: + pm_options_frozen_string_literal_set(&result->options, true); + break; + default: + rb_bug("pm_options_frozen_string_literal_init: invalid frozen_string_literal=%d", frozen_string_literal); + break; + } +} + /** * Attempt to load the file into memory. Return a Ruby error if the file cannot * be read. |