From a7b3217fff72df6a547ef9df4a28aa602523bd5f Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Thu, 21 Sep 2023 15:28:08 -0400 Subject: [PATCH] [YARP] Add tests for popped instructions (#8494) --- test/yarp/compiler_test.rb | 11 +- yarp/yarp_compiler.c | 292 ++++++++++++------------------------- 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;