From 41e2d180a3466a8d18c44246144a912adadd9d1a Mon Sep 17 00:00:00 2001 From: yui-knk Date: Mon, 8 Jan 2024 14:03:54 +0900 Subject: [PATCH] Do not convert NODE_STR to NODE_LIT when the string is hash key parse.y converted NODE_STR when the string is hash key like ``` h1 = {"str1" => 1} m1("str2" => 2) m2({"str3" => 3}) ``` This commit stop the conversion. `static_literal_node_p` needs to know the node is for hash key or not for the optimization. --- compile.c | 12 ++++++------ parse.y | 9 +++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/compile.c b/compile.c index 390a325a92..a125aa9016 100644 --- a/compile.c +++ b/compile.c @@ -4706,7 +4706,7 @@ compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, NODE **k } static inline int -static_literal_node_p(const NODE *node, const rb_iseq_t *iseq) +static_literal_node_p(const NODE *node, const rb_iseq_t *iseq, bool hash_key) { switch (nd_type(node)) { case NODE_LIT: @@ -4721,7 +4721,7 @@ static_literal_node_p(const NODE *node, const rb_iseq_t *iseq) return TRUE; case NODE_STR: case NODE_FILE: - return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal; + return hash_key || ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal; default: return FALSE; } @@ -4841,10 +4841,10 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop int count = 1; /* pre-allocation check (this branch can be omittable) */ - if (static_literal_node_p(RNODE_LIST(node)->nd_head, iseq)) { + if (static_literal_node_p(RNODE_LIST(node)->nd_head, iseq, false)) { /* count the elements that are optimizable */ const NODE *node_tmp = RNODE_LIST(node)->nd_next; - for (; node_tmp && static_literal_node_p(RNODE_LIST(node_tmp)->nd_head, iseq); node_tmp = RNODE_LIST(node_tmp)->nd_next) + for (; node_tmp && static_literal_node_p(RNODE_LIST(node_tmp)->nd_head, iseq, false); node_tmp = RNODE_LIST(node_tmp)->nd_next) count++; if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_ary_len) { @@ -4899,7 +4899,7 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop static int compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node) { - if (static_literal_node_p(node, iseq)) { + if (static_literal_node_p(node, iseq, false)) { VALUE ary = rb_ary_hidden_new(1); rb_ary_push(ary, static_literal_value(node, iseq)); OBJ_FREEZE(ary); @@ -4917,7 +4917,7 @@ compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node) static inline int static_literal_node_pair_p(const NODE *node, const rb_iseq_t *iseq) { - return RNODE_LIST(node)->nd_head && static_literal_node_p(RNODE_LIST(node)->nd_head, iseq) && static_literal_node_p(RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, iseq); + return RNODE_LIST(node)->nd_head && static_literal_node_p(RNODE_LIST(node)->nd_head, iseq, true) && static_literal_node_p(RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, iseq, true); } static int diff --git a/parse.y b/parse.y index 43e6097d3c..109c7fbcc9 100644 --- a/parse.y +++ b/parse.y @@ -6877,10 +6877,6 @@ assocs : assoc assoc : arg_value tASSOC arg_value { /*%%%*/ - if (nd_type_p($1, NODE_STR)) { - nd_set_type($1, NODE_LIT); - RB_OBJ_WRITE(p->ast, &RNODE_LIT($1)->nd_lit, rb_fstring(RNODE_LIT($1)->nd_lit)); - } $$ = list_append(p, NEW_LIST($1, &@$), $3); /*% %*/ /*% ripper: assoc_new!($1, $3) %*/ @@ -14941,6 +14937,7 @@ nd_type_st_key_enable_p(NODE *node) case NODE_FLOAT: case NODE_RATIONAL: case NODE_IMAGINARY: + case NODE_STR: case NODE_LINE: case NODE_FILE: return true; @@ -14955,6 +14952,8 @@ nd_st_key(struct parser_params *p, NODE *node) switch (nd_type(node)) { case NODE_LIT: return RNODE_LIT(node)->nd_lit; + case NODE_STR: + return RNODE_STR(node)->nd_lit; case NODE_INTEGER: case NODE_FLOAT: case NODE_RATIONAL: @@ -14974,6 +14973,8 @@ nd_st_key_val(struct parser_params *p, NODE *node) switch (nd_type(node)) { case NODE_LIT: return RNODE_LIT(node)->nd_lit; + case NODE_STR: + return RNODE_STR(node)->nd_lit; case NODE_INTEGER: return rb_node_integer_literal_val(node); case NODE_FLOAT: