diff options
| author | Jemma Issroff <jemmaissroff@gmail.com> | 2023-10-30 13:56:30 -0300 |
|---|---|---|
| committer | Jemma Issroff <jemmaissroff@gmail.com> | 2023-10-31 13:08:09 -0300 |
| commit | 57748ef2a26cbdfe075347c6f7064eb419b4949a (patch) | |
| tree | 245fbc6d2d46f1cd2e61b3e7710d98061f446a16 | |
| parent | e2d950733ee274e577813b5a4e930f617c60634f (diff) | |
[PRISM] Compile forwarding super node
| -rw-r--r-- | prism_compile.c | 28 | ||||
| -rw-r--r-- | test/ruby/test_compile_prism.rb | 5 |
2 files changed, 29 insertions, 4 deletions
diff --git a/prism_compile.c b/prism_compile.c index 153d6f8b66..8593fb0b3e 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -36,6 +36,9 @@ #define PM_DUP_UNLESS_POPPED \ if (!popped) PM_DUP; +#define PM_PUTSELF \ + ADD_INSN(ret, &dummy_line_node, putself); + #define PM_PUTNIL \ ADD_INSN(ret, &dummy_line_node, putnil); @@ -1436,7 +1439,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, struct rb_callinfo_kwarg *kw_arg = NULL; if (call_node->receiver == NULL) { - ADD_INSN(ret, &dummy_line_node, putself); + PM_PUTSELF; } else { PM_COMPILE_NOT_POPPED(call_node->receiver); } @@ -2245,7 +2248,24 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, ISEQ_COMPILE_DATA(iseq)->current_block = prevblock; ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, child_iseq, retry_end_l); + return; + } + case PM_FORWARDING_SUPER_NODE: { + pm_forwarding_super_node_t *forwarding_super_node = (pm_forwarding_super_node_t *) node; + const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block; + const rb_iseq_t *block = NULL; + PM_PUTSELF; + int flag = VM_CALL_ZSUPER | VM_CALL_SUPER | VM_CALL_FCALL; + if (forwarding_super_node->block) { + pm_scope_node_t next_scope_node; + pm_scope_node_init((pm_node_t *)forwarding_super_node->block, &next_scope_node, scope_node, parser); + block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); + RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block); + } + + ADD_INSN2(ret, &dummy_line_node, invokesuper, new_callinfo(iseq, 0, 0, flag, NULL, block != NULL), block); + PM_POP_IF_POPPED; return; } case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { @@ -2608,7 +2628,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_INTERPOLATED_X_STRING_NODE: { pm_interpolated_x_string_node_t *interp_x_string_node = (pm_interpolated_x_string_node_t *) node; - ADD_INSN(ret, &dummy_line_node, putself); + PM_PUTSELF; pm_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, scope_node, parser); size_t parts_size = interp_x_string_node->parts.size; @@ -3280,7 +3300,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_SELF_NODE: if (!popped) { - ADD_INSN(ret, &dummy_line_node, putself); + PM_PUTSELF; } return; case PM_SINGLETON_CLASS_NODE: { @@ -3447,7 +3467,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_X_STRING_NODE: { pm_x_string_node_t *xstring_node = (pm_x_string_node_t *) node; - ADD_INSN(ret, &dummy_line_node, putself); + PM_PUTSELF; ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&xstring_node->unescaped, parser)); ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idBackquote, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE)); diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index 18637dc71a..032675d13d 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -781,6 +781,11 @@ module Prism ) end + def test_ForwardingSuperNode + assert_prism_eval("class Forwarding; def to_s; super; end; end") + assert_prism_eval("class Forwarding; def eval(code); super { code }; end; end") + end + def test_KeywordHashNode assert_prism_eval("[a: [:b, :c]]") end |
