summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJemma Issroff <jemmaissroff@gmail.com>2023-10-30 13:56:30 -0300
committerJemma Issroff <jemmaissroff@gmail.com>2023-10-31 13:08:09 -0300
commit57748ef2a26cbdfe075347c6f7064eb419b4949a (patch)
tree245fbc6d2d46f1cd2e61b3e7710d98061f446a16
parente2d950733ee274e577813b5a4e930f617c60634f (diff)
[PRISM] Compile forwarding super node
-rw-r--r--prism_compile.c28
-rw-r--r--test/ruby/test_compile_prism.rb5
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