From e7d480df5da955c021158efd1accfb2c44d64464 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Tue, 20 Feb 2024 11:23:06 -0500 Subject: [PATCH] [PRISM] Remove more dummy line usage * returns * retry * self * singleton class --- prism_compile.c | 131 ++++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 59 deletions(-) diff --git a/prism_compile.c b/prism_compile.c index 20be456cad0817..5b4e330b49cbfc 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -4,6 +4,9 @@ /* These macros operate on pm_line_column_t structs as opposed to NODE*s. */ /******************************************************************************/ +#define PUSH_ADJUST(seq, location, label) \ + ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), (int) (location).line)) + #define PUSH_ADJUST_RESTORE(seq, label) \ ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1)) @@ -19,6 +22,9 @@ #define PUSH_INSN2(seq, location, insn, op1, op2) \ ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (int) (location).line, (int) (location).column, BIN(insn), 2, (VALUE)(op1), (VALUE)(op2))) +#define PUSH_INSN3(seq, location, insn, op1, op2, op3) \ + ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (int) (location).line, (int) (location).column, BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3))) + #define PUSH_LABEL(seq, label) \ ADD_ELEM((seq), (LINK_ELEMENT *) (label)) @@ -6809,68 +6815,72 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, return; } case PM_RETURN_NODE: { - pm_arguments_node_t *arguments = ((pm_return_node_t *)node)->arguments; - - if (iseq) { - enum rb_iseq_type type = ISEQ_BODY(iseq)->type; - LABEL *splabel = 0; - - const rb_iseq_t *parent_iseq = iseq; - enum rb_iseq_type parent_type = ISEQ_BODY(parent_iseq)->type; - while (parent_type == ISEQ_TYPE_RESCUE || parent_type == ISEQ_TYPE_ENSURE) { - if (!(parent_iseq = ISEQ_BODY(parent_iseq)->parent_iseq)) break; - parent_type = ISEQ_BODY(parent_iseq)->type; - } + // return + // ^^^^^^ + // + // return 1 + // ^^^^^^^^ + const pm_return_node_t *cast = (const pm_return_node_t *) node; + const pm_arguments_node_t *arguments = cast->arguments; - switch (parent_type) { - case ISEQ_TYPE_TOP: - case ISEQ_TYPE_MAIN: - if (arguments) { - rb_warn("argument of top-level return is ignored"); - } - if (parent_iseq == iseq) { - type = ISEQ_TYPE_METHOD; - } - break; - default: - break; - } + enum rb_iseq_type type = ISEQ_BODY(iseq)->type; + LABEL *splabel = 0; - if (type == ISEQ_TYPE_METHOD) { - splabel = NEW_LABEL(0); - ADD_LABEL(ret, splabel); - ADD_ADJUST(ret, &dummy_line_node, 0); - } + const rb_iseq_t *parent_iseq = iseq; + enum rb_iseq_type parent_type = ISEQ_BODY(parent_iseq)->type; + while (parent_type == ISEQ_TYPE_RESCUE || parent_type == ISEQ_TYPE_ENSURE) { + if (!(parent_iseq = ISEQ_BODY(parent_iseq)->parent_iseq)) break; + parent_type = ISEQ_BODY(parent_iseq)->type; + } + switch (parent_type) { + case ISEQ_TYPE_TOP: + case ISEQ_TYPE_MAIN: if (arguments) { - PM_COMPILE_NOT_POPPED((pm_node_t *)arguments); + rb_warn("argument of top-level return is ignored"); } - else { - PM_PUTNIL; + if (parent_iseq == iseq) { + type = ISEQ_TYPE_METHOD; } + break; + default: + break; + } - if (type == ISEQ_TYPE_METHOD && can_add_ensure_iseq(iseq)) { - pm_add_ensure_iseq(ret, iseq, 1, scope_node); - ADD_TRACE(ret, RUBY_EVENT_RETURN); - ADD_INSN(ret, &dummy_line_node, leave); - ADD_ADJUST_RESTORE(ret, splabel); + if (type == ISEQ_TYPE_METHOD) { + splabel = NEW_LABEL(0); + PUSH_LABEL(ret, splabel); + PUSH_ADJUST(ret, location, 0); + } - PM_PUTNIL_UNLESS_POPPED; - } - else { - ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(TAG_RETURN)); - PM_POP_IF_POPPED; - } + if (arguments) { + PM_COMPILE_NOT_POPPED((const pm_node_t *) arguments); + } + else { + PUSH_INSN(ret, location, putnil); + } + + if (type == ISEQ_TYPE_METHOD && can_add_ensure_iseq(iseq)) { + pm_add_ensure_iseq(ret, iseq, 1, scope_node); + PUSH_TRACE(ret, RUBY_EVENT_RETURN); + PUSH_INSN(ret, location, leave); + PUSH_ADJUST_RESTORE(ret, splabel); + if (!popped) PUSH_INSN(ret, location, putnil); + } + else { + PUSH_INSN1(ret, location, throw, INT2FIX(TAG_RETURN)); + if (popped) PUSH_INSN(ret, location, pop); } return; } case PM_RETRY_NODE: { + // retry + // ^^^^^ if (ISEQ_BODY(iseq)->type == ISEQ_TYPE_RESCUE) { - PM_PUTNIL; - ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(TAG_RETRY)); - - PM_POP_IF_POPPED; + PUSH_INSN(ret, location, putnil); + PUSH_INSN1(ret, location, throw, INT2FIX(TAG_RETRY)); + if (popped) PUSH_INSN(ret, location, pop); } else { COMPILE_ERROR(ERROR_ARGS "Invalid retry"); return; @@ -7745,28 +7755,31 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, return; } case PM_SELF_NODE: + // self + // ^^^^ if (!popped) { - PM_PUTSELF; + PUSH_INSN(ret, location, putself); } return; case PM_SINGLETON_CLASS_NODE: { - pm_singleton_class_node_t *singleton_class_node = (pm_singleton_class_node_t *)node; + // class << self; end + // ^^^^^^^^^^^^^^^^^^ + const pm_singleton_class_node_t *cast = (const pm_singleton_class_node_t *) node; pm_scope_node_t next_scope_node; - pm_scope_node_init((pm_node_t *)singleton_class_node, &next_scope_node, scope_node, parser); - const rb_iseq_t *singleton_class = NEW_ISEQ(&next_scope_node, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, lineno); + pm_scope_node_init((const pm_node_t *) cast, &next_scope_node, scope_node, parser); + const rb_iseq_t *child_iseq = NEW_ISEQ(&next_scope_node, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, location.line); pm_scope_node_destroy(&next_scope_node); - PM_COMPILE_NOT_POPPED(singleton_class_node->expression); - PM_PUTNIL; + PM_COMPILE_NOT_POPPED(cast->expression); + PUSH_INSN(ret, location, putnil); + ID singletonclass; CONST_ID(singletonclass, "singletonclass"); + PUSH_INSN3(ret, location, defineclass, ID2SYM(singletonclass), child_iseq, INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS)); - ADD_INSN3(ret, &dummy_line_node, defineclass, - ID2SYM(singletonclass), singleton_class, - INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS)); - PM_POP_IF_POPPED; - RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)singleton_class); + if (popped) PUSH_INSN(ret, location, pop); + RB_OBJ_WRITTEN(iseq, Qundef, (VALUE) child_iseq); return; }