summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJemma Issroff <jemmaissroff@gmail.com>2023-09-21 15:28:08 -0400
committerGitHub <noreply@github.com>2023-09-21 15:28:08 -0400
commita7b3217fff72df6a547ef9df4a28aa602523bd5f (patch)
tree0d4f2c872891b0e94dde1de7e9086790093e72d1
parent39a6272cf45c8946255c20708e6153ce8c222699 (diff)
[YARP] Add tests for popped instructions (#8494)
-rw-r--r--test/yarp/compiler_test.rb11
-rw-r--r--yarp/yarp_compiler.c292
2 files changed, 102 insertions, 201 deletions
diff --git a/test/yarp/compiler_test.rb b/test/yarp/compiler_test.rb
index 07e2473283..18303579de 100644
--- a/test/yarp/compiler_test.rb
+++ b/test/yarp/compiler_test.rb
@@ -225,7 +225,7 @@ module YARP
def test_InterpolatedXStringNode
test_yarp_eval('`echo #{1}`')
- test_yarp_eval('`printf "100"`')
+ test_yarp_eval('`printf #{"100"}`')
end
def test_RegularExpressionNode
@@ -278,11 +278,18 @@ module YARP
private
- def test_yarp_eval(source)
+ def compare_eval(source)
ruby_eval = RubyVM::InstructionSequence.compile(source).eval
yarp_eval = RubyVM::InstructionSequence.compile_yarp(source).eval
assert_equal ruby_eval, yarp_eval
end
+
+ def test_yarp_eval(source)
+ compare_eval(source)
+
+ # Test "popped" functionality
+ compare_eval("#{source}; 1")
+ end
end
end
diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c
index b6f453c906..817f8b4258 100644
--- a/yarp/yarp_compiler.c
+++ b/yarp/yarp_compiler.c
@@ -21,6 +21,18 @@
#define YP_COMPILE_NOT_POPPED(node) \
yp_compile_node(iseq, (node), ret, src, false, compile_context)
+#define YP_POP_IF_POPPED \
+ if (popped) ADD_INSN(ret, &dummy_line_node, pop);
+
+#define YP_POP_UNLESS_POPPED \
+ if (!popped) ADD_INSN(ret, &dummy_line_node, pop);
+
+#define YP_DUP_UNLESS_POPPED \
+ if (!popped) ADD_INSN(ret, &dummy_line_node, dup);
+
+#define YP_PUTNIL_UNLESS_POPPED \
+ if (!popped) ADD_INSN(ret, &dummy_line_node, putnil);
+
rb_iseq_t *
yp_iseq_new_with_opt(yp_scope_node_t *node, yp_parser_t *parser, VALUE name, VALUE path, VALUE realpath,
int first_lineno, const rb_iseq_t *parent, int isolated_depth,
@@ -274,7 +286,7 @@ again:
static void
yp_compile_if(rb_iseq_t *iseq, const int line, yp_statements_node_t *node_body, yp_node_t *node_else, yp_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, yp_compile_context_t *compile_context) {
- NODE line_node = generate_dummy_line_node(line, line);
+ NODE dummy_line_node = generate_dummy_line_node(line, line);
DECL_ANCHOR(cond_seq);
@@ -295,22 +307,16 @@ yp_compile_if(rb_iseq_t *iseq, const int line, yp_statements_node_t *node_body,
INIT_ANCHOR(then_seq);
if (node_body) {
yp_compile_node(iseq, (yp_node_t *)node_body, then_seq, src, popped, compile_context);
- if (popped) {
- ADD_INSN(ret, &line_node, pop);
- }
+ YP_POP_IF_POPPED;
}
else {
- if (!popped) {
- ADD_INSN(ret, &line_node, putnil);
- }
+ YP_PUTNIL_UNLESS_POPPED;
}
if (else_label->refcnt) {
end_label = NEW_LABEL(line);
- ADD_INSNL(then_seq, &line_node, jump, end_label);
- if (!popped) {
- ADD_INSN(then_seq, &line_node, pop);
- }
+ ADD_INSNL(then_seq, &dummy_line_node, jump, end_label);
+ YP_POP_UNLESS_POPPED;
}
ADD_SEQ(ret, then_seq);
}
@@ -324,9 +330,7 @@ yp_compile_if(rb_iseq_t *iseq, const int line, yp_statements_node_t *node_body,
yp_compile_node(iseq, (yp_node_t *)(((yp_else_node_t *)node_else)->statements), else_seq, src, popped, compile_context);
}
else {
- if (!popped) {
- ADD_INSN(ret, &line_node, putnil);
- }
+ YP_PUTNIL_UNLESS_POPPED;
}
ADD_SEQ(ret, else_seq);
@@ -395,9 +399,7 @@ yp_compile_while(rb_iseq_t *iseq, int lineno, yp_node_flags_t flags, enum yp_nod
ADD_LABEL(ret, break_label);
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label, NULL,
break_label);
@@ -430,9 +432,6 @@ yp_interpolated_node_compile(yp_node_list_t parts, rb_iseq_t *iseq, NODE dummy_l
ADD_INSN(ret, &dummy_line_node, dup);
ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE));
ADD_INSN(ret, &dummy_line_node, anytostring);
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
}
}
}
@@ -546,9 +545,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_SEND(ret, &dummy_line_node, id_core_set_method_alias, INT2FIX(3));
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
@@ -557,14 +554,10 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
LABEL *end_label = NEW_LABEL(lineno);
YP_COMPILE_NOT_POPPED(and_node->left);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE(and_node->right);
ADD_LABEL(ret, end_label);
return;
@@ -614,9 +607,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
// TODO: Not sure this is accurate, look at FLUSH_CHUNK in the compiler
ADD_INSN1(ret, &dummy_line_node, newarraykwsplat, INT2FIX(0));
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_BACK_REFERENCE_READ_NODE: {
@@ -700,9 +691,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(orig_argc), INT2FIX(flags));
}
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_CLASS_NODE: {
@@ -719,7 +708,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
// TODO: Once we merge constant path nodes correctly, fix this flag
const int flags = VM_DEFINECLASS_TYPE_CLASS |
(class_node->superclass ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) |
- yp_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node, src, popped, compile_context);
+ yp_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node, src, false, compile_context);
if (class_node->superclass) {
YP_COMPILE(class_node->superclass);
@@ -731,9 +720,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN3(ret, &dummy_line_node, defineclass, ID2SYM(class_id), class_iseq, INT2FIX(flags));
RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)class_iseq);
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_CLASS_VARIABLE_AND_WRITE_NODE: {
@@ -748,21 +735,15 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
class_variable_name_val,
get_cvar_ic_value(iseq, class_variable_name_id));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE_NOT_POPPED(class_variable_and_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN2(ret, &dummy_line_node, setclassvariable,
class_variable_name_val,
@@ -787,9 +768,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
int flags = VM_CALL_ARGS_SIMPLE;
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN2(ret, &dummy_line_node, setclassvariable,
class_variable_name_val,
@@ -809,21 +788,15 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
class_variable_name_val,
get_cvar_ic_value(iseq, class_variable_name_id));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE_NOT_POPPED(class_variable_or_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN2(ret, &dummy_line_node, setclassvariable,
class_variable_name_val,
@@ -855,9 +828,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
case YP_CLASS_VARIABLE_WRITE_NODE: {
yp_class_variable_write_node_t *write_node = (yp_class_variable_write_node_t *) node;
YP_COMPILE_NOT_POPPED(write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ID cvar_name = yp_constant_id_lookup(compile_context, write_node->name);
ADD_INSN2(ret, &dummy_line_node, setclassvariable, ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name));
@@ -866,7 +837,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
case YP_CONSTANT_PATH_NODE: {
yp_constant_path_node_t *constant_path_node = (yp_constant_path_node_t*) node;
if (constant_path_node->parent) {
- YP_COMPILE(constant_path_node->parent);
+ YP_COMPILE_NOT_POPPED(constant_path_node->parent);
}
ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse);
@@ -874,14 +845,13 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
yp_constant_read_node_t *child = (yp_constant_read_node_t *) constant_path_node->child;
ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(yp_constant_id_lookup(compile_context, child->name)));
+ YP_POP_IF_POPPED;
return;
}
case YP_CONSTANT_PATH_WRITE_NODE: {
yp_constant_path_write_node_t *constant_path_write_node = (yp_constant_path_write_node_t*) node;
YP_COMPILE(constant_path_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ID constant_var_name = parse_location_symbol(&constant_path_write_node->target->base.location);
@@ -894,9 +864,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN(ret, &dummy_line_node, putnil);
ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(yp_constant_id_lookup(compile_context, constant_read_node->name)));
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_CONSTANT_AND_WRITE_NODE: {
@@ -909,21 +877,15 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN(ret, &dummy_line_node, putnil);
ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE_NOT_POPPED(constant_and_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
@@ -945,9 +907,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
int flags = VM_CALL_ARGS_SIMPLE;
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(constant_name));
@@ -971,22 +931,16 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
ADD_LABEL(ret, set_label);
YP_COMPILE_NOT_POPPED(constant_or_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
@@ -1004,9 +958,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
yp_constant_write_node_t *constant_write_node = (yp_constant_write_node_t *) node;
YP_COMPILE_NOT_POPPED(constant_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(yp_constant_id_lookup(compile_context, constant_write_node->name)));
@@ -1047,9 +999,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN(ret, &dummy_line_node, putnil);
}
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
// TODO: Concatenate the strings that exist here
return;
}
@@ -1119,21 +1069,15 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE_NOT_POPPED(global_variable_and_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
ADD_LABEL(ret, end_label);
@@ -1152,9 +1096,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
int flags = VM_CALL_ARGS_SIMPLE;
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
@@ -1175,22 +1117,16 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
ADD_LABEL(ret, set_label);
YP_COMPILE_NOT_POPPED(global_variable_or_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
ADD_LABEL(ret, end_label);
@@ -1201,9 +1137,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
yp_global_variable_read_node_t *global_variable_read_node = (yp_global_variable_read_node_t *)node;
VALUE global_variable_name = ID2SYM(yp_constant_id_lookup(compile_context, global_variable_read_node->name));
ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_GLOBAL_VARIABLE_TARGET_NODE: {
@@ -1216,9 +1150,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
case YP_GLOBAL_VARIABLE_WRITE_NODE: {
yp_global_variable_write_node_t *write_node = (yp_global_variable_write_node_t *) node;
YP_COMPILE_NOT_POPPED(write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ID ivar_name = yp_constant_id_lookup(compile_context, write_node->name);
ADD_INSN1(ret, &dummy_line_node, setglobal, ID2SYM(ivar_name));
return;
@@ -1279,21 +1211,15 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
instance_variable_name_val,
get_ivar_ic_value(iseq, instance_variable_name_id));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE_NOT_POPPED(instance_variable_and_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
instance_variable_name_val,
@@ -1318,9 +1244,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
int flags = VM_CALL_ARGS_SIMPLE;
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
instance_variable_name_val,
@@ -1340,21 +1264,15 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
instance_variable_name_val,
get_ivar_ic_value(iseq, instance_variable_name_id));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE_NOT_POPPED(instance_variable_or_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
instance_variable_name_val,
@@ -1386,9 +1304,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
yp_instance_variable_write_node_t *write_node = (yp_instance_variable_write_node_t *) node;
YP_COMPILE_NOT_POPPED(write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ID ivar_name = yp_constant_id_lookup(compile_context, write_node->name);
ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
@@ -1409,6 +1325,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(0), INT2FIX((int)(interp_regular_expression_node->parts.size)));
}
+ YP_POP_IF_POPPED;
return;
}
case YP_INTERPOLATED_STRING_NODE: {
@@ -1419,6 +1336,8 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
if (parts_size > 1) {
ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size)));
}
+
+ YP_POP_IF_POPPED;
return;
}
case YP_INTERPOLATED_SYMBOL_NODE: {
@@ -1433,6 +1352,9 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
if (!popped) {
ADD_INSN(ret, &dummy_line_node, intern);
}
+ else {
+ ADD_INSN(ret, &dummy_line_node, pop);
+ }
return;
}
@@ -1447,9 +1369,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
}
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, rb_intern("`"), INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_KEYWORD_HASH_NODE: {
@@ -1474,9 +1394,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_CALL_WITH_BLOCK(ret, &dummy_line_node, idLambda, argc, block);
RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block);
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_LOCAL_VARIABLE_AND_WRITE_NODE: {
@@ -1489,21 +1407,15 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
int local_index = yp_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth);
ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE_NOT_POPPED(local_variable_and_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
ADD_LABEL(ret, end_label);
@@ -1525,9 +1437,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
int flags = VM_CALL_ARGS_SIMPLE | VM_CALL_FCALL | VM_CALL_VCALL;
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
@@ -1547,22 +1457,16 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
int local_index = yp_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth);
ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
ADD_LABEL(ret, set_label);
YP_COMPILE_NOT_POPPED(local_variable_or_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
ADD_LABEL(ret, end_label);
@@ -1591,9 +1495,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
yp_local_variable_write_node_t *local_write_node = (yp_local_variable_write_node_t *) node;
YP_COMPILE_NOT_POPPED(local_write_node->value);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
yp_constant_id_t constant_id = local_write_node->name;
int index = yp_lookup_local_index(iseq, compile_context, constant_id);
@@ -1622,19 +1524,19 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN3(ret, &dummy_line_node, defineclass, ID2SYM(module_id), module_iseq, INT2FIX(flags));
RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)module_iseq);
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_MULTI_WRITE_NODE: {
yp_multi_write_node_t *multi_write_node = (yp_multi_write_node_t *)node;
- YP_COMPILE(multi_write_node->value);
+ YP_COMPILE_NOT_POPPED(multi_write_node->value);
// TODO: int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00);
int flag = 0x00;
- ADD_INSN(ret, &dummy_line_node, dup);
+ if (!popped) {
+ ADD_INSN(ret, &dummy_line_node, dup);
+ }
ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(multi_write_node->targets.size), INT2FIX(flag));
yp_node_list_t node_list = multi_write_node->targets;
@@ -1659,9 +1561,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
return;
}
case YP_NIL_NODE:
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, putnil);
- }
+ YP_PUTNIL_UNLESS_POPPED
return;
case YP_NUMBERED_REFERENCE_READ_NODE: {
if (!popped) {
@@ -1676,14 +1576,10 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
LABEL *end_label = NEW_LABEL(lineno);
YP_COMPILE_NOT_POPPED(or_node->left);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, dup);
- }
+ YP_DUP_UNLESS_POPPED;
ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
- if (!popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_UNLESS_POPPED;
YP_COMPILE(or_node->right);
ADD_LABEL(ret, end_label);
@@ -1703,7 +1599,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
yp_parentheses_node_t *parentheses_node = (yp_parentheses_node_t *) node;
if (parentheses_node->body == NULL) {
- ADD_INSN(ret, &dummy_line_node, putnil);
+ YP_PUTNIL_UNLESS_POPPED;
} else {
YP_COMPILE(parentheses_node->body);
}
@@ -1977,9 +1873,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
return;
}
case YP_STATEMENTS_NODE: {
@@ -2071,6 +1965,8 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN(ret, &dummy_line_node, putself);
ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&xstring_node->unescaped));
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, rb_intern("`"), INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
+
+ YP_POP_IF_POPPED;
return;
}
case YP_YIELD_NODE: {
@@ -2081,9 +1977,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN1(ret, &dummy_line_node, invokeblock, new_callinfo(iseq, 0, FIX2INT(argc), flag, keywords, FALSE));
- if (popped) {
- ADD_INSN(ret, &dummy_line_node, pop);
- }
+ YP_POP_IF_POPPED;
int level = 0;
const rb_iseq_t *tmp_iseq = iseq;