diff options
author | Kevin Newton <[email protected]> | 2024-05-21 13:08:08 -0400 |
---|---|---|
committer | Kevin Newton <[email protected]> | 2024-05-21 14:27:37 -0400 |
commit | 42930d28a48bf7495180e81fd6e5cf742f3f47c7 (patch) | |
tree | 9853c1ee48a97633e6d253e02c66f2247bd1020f /prism_compile.c | |
parent | 16b0bb3d5370c48194e220bf4083887a316f4575 (diff) |
[PRISM] Handle safe navigation in call target nodes
Diffstat (limited to 'prism_compile.c')
-rw-r--r-- | prism_compile.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/prism_compile.c b/prism_compile.c index 58c70748e1..18f1d38b7d 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -3962,6 +3962,13 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons pm_compile_node(iseq, cast->receiver, parents, false, scope_node); + LABEL *safe_label = NULL; + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + safe_label = NEW_LABEL(location.line); + PUSH_INSN(parents, location, dup); + PUSH_INSNL(parents, location, branchnil, safe_label); + } + if (state != NULL) { PUSH_INSN1(writes, location, topn, INT2FIX(1)); pm_multi_target_state_push(state, (INSN *) LAST_ELEMENT(writes), 1); @@ -3972,7 +3979,9 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) flags |= VM_CALL_FCALL; PUSH_SEND_WITH_FLAG(writes, location, method_id, INT2FIX(1), INT2FIX(flags)); + if (safe_label != NULL && state == NULL) PUSH_LABEL(writes, safe_label); PUSH_INSN(writes, location, pop); + if (safe_label != NULL && state != NULL) PUSH_LABEL(writes, safe_label); if (state != NULL) { PUSH_INSN(cleanup, location, pop); |