diff options
author | Jenny Shen <[email protected]> | 2024-02-02 16:57:51 -0500 |
---|---|---|
committer | Kevin Newton <[email protected]> | 2024-02-05 10:27:58 -0500 |
commit | b35cdb4758c0a569574a047bda6ce6a19c302aef (patch) | |
tree | 4e5fdcfe8511f92dbf803f3ea9ae372f49a82f28 /prism_compile.c | |
parent | 8ed26a3f5923a0f1213060200bf542f172c99b7c (diff) |
[PRISM] Implement opt_aset_with
Part of ruby/prism#2231
Co-authored-by: Adrianna Chang <[email protected]>
Co-authored-by: Peter Zhu <[email protected]>
Diffstat (limited to 'prism_compile.c')
-rw-r--r-- | prism_compile.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/prism_compile.c b/prism_compile.c index 37fdd88699..0d043ac447 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -4175,6 +4175,27 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, pop); } } + else if (method_id == idASET && + !PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) && + call_node->arguments && + PM_NODE_TYPE_P((pm_node_t *)call_node->arguments, PM_ARGUMENTS_NODE) && + ((pm_arguments_node_t *)call_node->arguments)->arguments.size == 2 && + PM_NODE_TYPE_P(((pm_arguments_node_t *)call_node->arguments)->arguments.nodes[0], PM_STRING_NODE) && + call_node->block == NULL && + !ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal && + ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) { + pm_string_node_t *str_node = (pm_string_node_t *)((pm_arguments_node_t *)call_node->arguments)->arguments.nodes[0]; + VALUE str = rb_fstring(parse_string_encoded((pm_node_t *)str_node, &str_node->unescaped, parser)); + PM_COMPILE_NOT_POPPED(call_node->receiver); + PM_COMPILE_NOT_POPPED(((pm_arguments_node_t *)call_node->arguments)->arguments.nodes[1]); + if (!popped) { + ADD_INSN(ret, &dummy_line_node, swap); + ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1)); + } + ADD_INSN2(ret, &dummy_line_node, opt_aset_with, str, new_callinfo(iseq, idASET, 2, 0, NULL, FALSE)); + RB_OBJ_WRITTEN(iseq, Qundef, str); + ADD_INSN(ret, &dummy_line_node, pop); + } else { if ((node->flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) && !popped) { PM_PUTNIL; |