ruby-changes:66095
From: Yusuke <ko1@a...>
Date: Fri, 7 May 2021 17:02:35 +0900 (JST)
Subject: [ruby-changes:66095] ff69ef27b0 (master): compile.c: Pass node instead of nd_line(node) to ADD_INSN* functions
https://git.ruby-lang.org/ruby.git/commit/?id=ff69ef27b0 From ff69ef27b06eed1ba750e7d9cab8322f351ed245 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh <mame@r...> Date: Fri, 30 Apr 2021 18:54:46 +0900 Subject: compile.c: Pass node instead of nd_line(node) to ADD_INSN* functions ... then, new_insn_core extracts nd_line(node). Also, if a macro "EXPERIMENTAL_ISEQ_NODE_ID" is defined, this changeset keeps nd_node_id(node) for each instruction. This is intended for TypeProf to identify what AST::Node corresponds to each instruction. This patch is originally authored by @yui-knk for showing which column a NoMethodError occurred. https://github.com/ruby/ruby/compare/master...yui-knk:feature/node_id Co-Authored-By: Yuichiro Kaneko <yui-knk@r...> --- ast.c | 14 + compile.c | 1688 +++++++++++++++++++++++++++++++------------------------------ iseq.c | 24 + iseq.h | 8 + 4 files changed, 916 insertions(+), 818 deletions(-) diff --git a/ast.c b/ast.c index 7d65db5..b7416ad 100644 --- a/ast.c +++ b/ast.c @@ -245,6 +245,17 @@ ast_node_type(rb_execution_context_t *ec, VALUE self) https://github.com/ruby/ruby/blob/trunk/ast.c#L245 return rb_sym_intern_ascii_cstr(node_type_to_str(data->node)); } +#ifdef EXPERIMENTAL_ISEQ_NODE_ID +static VALUE +ast_node_node_id(VALUE self) +{ + struct ASTNodeData *data; + TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data); + + return INT2FIX(nd_node_id(data->node)); +} +#endif + #define NEW_CHILD(ast, node) node ? ast_new_internal(ast, node) : Qnil static VALUE @@ -695,4 +706,7 @@ Init_ast(void) https://github.com/ruby/ruby/blob/trunk/ast.c#L706 rb_mAST = rb_define_module_under(rb_cRubyVM, "AbstractSyntaxTree"); rb_cNode = rb_define_class_under(rb_mAST, "Node", rb_cObject); rb_undef_alloc_func(rb_cNode); +#ifdef EXPERIMENTAL_ISEQ_NODE_ID + rb_define_method(rb_cNode, "node_id", ast_node_node_id, 0); +#endif } diff --git a/compile.c b/compile.c index 1cabb8c..a3a828f 100644 --- a/compile.c +++ b/compile.c @@ -93,6 +93,7 @@ typedef struct iseq_insn_data { https://github.com/ruby/ruby/blob/trunk/compile.c#L93 VALUE *operands; struct { int line_no; + int node_id; rb_event_flag_t events; } insn_info; } INSN; @@ -216,77 +217,77 @@ const ID rb_iseq_shared_exc_local_tbl[] = {idERROR_INFO}; https://github.com/ruby/ruby/blob/trunk/compile.c#L217 APPEND_LIST((seq1), (seq2)) /* add an instruction */ -#define ADD_INSN(seq, line, insn) \ - ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0)) +#define ADD_INSN(seq, line_node, insn) \ + ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line_node), BIN(insn), 0)) /* insert an instruction before next */ -#define INSERT_BEFORE_INSN(next, line, insn) \ - ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0)) +#define INSERT_BEFORE_INSN(next, line_node, insn) \ + ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line_node), BIN(insn), 0)) /* insert an instruction after prev */ -#define INSERT_AFTER_INSN(prev, line, insn) \ - ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0)) +#define INSERT_AFTER_INSN(prev, line_node, insn) \ + ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line_node), BIN(insn), 0)) /* add an instruction with some operands (1, 2, 3, 5) */ -#define ADD_INSN1(seq, line, insn, op1) \ +#define ADD_INSN1(seq, line_node, insn, op1) \ ADD_ELEM((seq), (LINK_ELEMENT *) \ - new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1))) + new_insn_body(iseq, (line_node), BIN(insn), 1, (VALUE)(op1))) /* insert an instruction with some operands (1, 2, 3, 5) before next */ -#define INSERT_BEFORE_INSN1(next, line, insn, op1) \ +#define INSERT_BEFORE_INSN1(next, line_node, insn, op1) \ ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) \ - new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1))) + new_insn_body(iseq, (line_node), BIN(insn), 1, (VALUE)(op1))) /* insert an instruction with some operands (1, 2, 3, 5) after prev */ -#define INSERT_AFTER_INSN1(prev, line, insn, op1) \ +#define INSERT_AFTER_INSN1(prev, line_node, insn, op1) \ ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) \ - new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1))) + new_insn_body(iseq, (line_node), BIN(insn), 1, (VALUE)(op1))) #define LABEL_REF(label) ((label)->refcnt++) /* add an instruction with label operand (alias of ADD_INSN1) */ -#define ADD_INSNL(seq, line, insn, label) (ADD_INSN1(seq, line, insn, label), LABEL_REF(label)) +#define ADD_INSNL(seq, line_node, insn, label) (ADD_INSN1(seq, line_node, insn, label), LABEL_REF(label)) -#define ADD_INSN2(seq, line, insn, op1, op2) \ +#define ADD_INSN2(seq, line_node, insn, op1, op2) \ ADD_ELEM((seq), (LINK_ELEMENT *) \ - new_insn_body(iseq, (line), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2))) + new_insn_body(iseq, (line_node), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2))) -#define ADD_INSN3(seq, line, insn, op1, op2, op3) \ +#define ADD_INSN3(seq, line_node, insn, op1, op2, op3) \ ADD_ELEM((seq), (LINK_ELEMENT *) \ - new_insn_body(iseq, (line), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3))) + new_insn_body(iseq, (line_node), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3))) /* Specific Insn factory */ -#define ADD_SEND(seq, line, id, argc) \ - ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(0), NULL) +#define ADD_SEND(seq, line_node, id, argc) \ + ADD_SEND_R((seq), (line_node), (id), (argc), NULL, (VALUE)INT2FIX(0), NULL) -#define ADD_SEND_WITH_FLAG(seq, line, id, argc, flag) \ - ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)(flag), NULL) +#define ADD_SEND_WITH_FLAG(seq, line_node, id, argc, flag) \ + ADD_SEND_R((seq), (line_node), (id), (argc), NULL, (VALUE)(flag), NULL) -#define ADD_SEND_WITH_BLOCK(seq, line, id, argc, block) \ - ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(0), NULL) +#define ADD_SEND_WITH_BLOCK(seq, line_node, id, argc, block) \ + ADD_SEND_R((seq), (line_node), (id), (argc), (block), (VALUE)INT2FIX(0), NULL) -#define ADD_CALL_RECEIVER(seq, line) \ - ADD_INSN((seq), (line), putself) +#define ADD_CALL_RECEIVER(seq, line_node) \ + ADD_INSN((seq), (line_node), putself) -#define ADD_CALL(seq, line, id, argc) \ - ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(VM_CALL_FCALL), NULL) +#define ADD_CALL(seq, line_node, id, argc) \ + ADD_SEND_R((seq), (line_node), (id), (argc), NULL, (VALUE)INT2FIX(VM_CALL_FCALL), NULL) -#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \ - ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL), NULL) +#define ADD_CALL_WITH_BLOCK(seq, line_node, id, argc, block) \ + ADD_SEND_R((seq), (line_node), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL), NULL) -#define ADD_SEND_R(seq, line, id, argc, block, flag, keywords) \ - ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, (line), (id), (VALUE)(argc), (block), (VALUE)(flag), (keywords))) +#define ADD_SEND_R(seq, line_node, id, argc, block, flag, keywords) \ + ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, (line_node), (id), (VALUE)(argc), (block), (VALUE)(flag), (keywords))) #define ADD_TRACE(seq, event) \ ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event), 0)) #define ADD_TRACE_WITH_DATA(seq, event, data) \ ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event), (data))) -static void iseq_add_getlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, int idx, int level); -static void iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, int idx, int level); +static void iseq_add_getlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const NODE *const line_node, int idx, int level); +static void iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const NODE *const line_node, int idx, int level); -#define ADD_GETLOCAL(seq, line, idx, level) iseq_add_getlocal(iseq, (seq), (line), (idx), (level)) -#define ADD_SETLOCAL(seq, line, idx, level) iseq_add_setlocal(iseq, (seq), (line), (idx), (level)) +#define ADD_GETLOCAL(seq, line_node, idx, level) iseq_add_getlocal(iseq, (seq), (line_node), (idx), (level)) +#define ADD_SETLOCAL(seq, line_node, idx, level) iseq_add_setlocal(iseq, (seq), (line_node), (idx), (level)) /* add label */ #define ADD_LABEL(seq, label) \ @@ -295,8 +296,8 @@ static void iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, https://github.com/ruby/ruby/blob/trunk/compile.c#L296 #define APPEND_LABEL(seq, before, label) \ APPEND_ELEM((seq), (before), (LINK_ELEMENT *) (label)) -#define ADD_ADJUST(seq, line, label) \ - ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), (line))) +#define ADD_ADJUST(seq, line_node, label) \ + ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), nd_line(line_node))) #define ADD_ADJUST_RESTORE(seq, label) \ ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1)) @@ -332,7 +333,7 @@ static void iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, https://github.com/ruby/ruby/blob/trunk/compile.c#L333 #define COMPILE_RECV(anchor, desc, node) \ (private_recv_p(node) ? \ - (ADD_INSN(anchor, nd_line(node), putself), VM_CALL_FCALL) : \ + (ADD_INSN(anchor, node, putself), VM_CALL_FCALL) : \ COMPILE(anchor, desc, node->nd_recv) ? 0 : -1) #define OPERAND_AT(insn, idx) \ @@ -468,7 +469,7 @@ static void dump_disasm_list(const LINK_ELEMENT *elem); https://github.com/ruby/ruby/blob/trunk/compile.c#L469 static int insn_data_length(INSN *iobj); static int calc_sp_depth(int depth, INSN *iobj); -static INSN *new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type insn_id, int argc, ...); +static INSN *new_insn_body(rb_iseq_t *iseq, const NODE *const line_node, enum rub (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/