summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-12-23 14:46:59 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-12-23 14:46:59 +0000
commit3044138bd734cf94e09250ac1bcb0886c26cdb27 (patch)
treee1a0a176fc78504dfb88c9c009ca5badf4d21801 /iseq.c
parentac40fc997b6b27c4f61084d9f6fae83ea251d614 (diff)
RubyVM::InstructionSequence#trace_points.
* iseq.c (iseqw_trace_points): add `RubyVM::InstructionSequence#trace_points` method for tools which want to manipulate ISeq (and traces). * test/ruby/test_iseq.rb: add a test for this method. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61427 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/iseq.c b/iseq.c
index e25c423b83..d1e567a17d 100644
--- a/iseq.c
+++ b/iseq.c
@@ -1874,6 +1874,43 @@ iseqw_each_child(VALUE self)
return self;
}
+static void
+push_event_info(const rb_iseq_t *iseq, rb_event_flag_t events, int line, VALUE ary)
+{
+#define C(ev, cstr, l) if (events & ev) rb_ary_push(ary, rb_ary_new_from_args(2, l, ID2SYM(rb_intern(cstr))));
+ C(RUBY_EVENT_CLASS, "class", rb_iseq_first_lineno(iseq));
+ C(RUBY_EVENT_CALL, "call", rb_iseq_first_lineno(iseq));
+ C(RUBY_EVENT_B_CALL, "b_call", rb_iseq_first_lineno(iseq));
+ C(RUBY_EVENT_LINE, "line", INT2FIX(line));
+ C(RUBY_EVENT_END, "end", INT2FIX(line));
+ C(RUBY_EVENT_RETURN, "return", INT2FIX(line));
+ C(RUBY_EVENT_B_RETURN, "b_return", INT2FIX(line));
+#undef C
+}
+
+/*
+ * call-seq:
+ * iseq.trace_points -> ary
+ *
+ * Return trace points in the instruction sequence.
+ * Return an array of [line, event_symbol] pair.
+ */
+static VALUE
+iseqw_trace_points(VALUE self)
+{
+ const rb_iseq_t *iseq = iseqw_check(self);
+ unsigned int i;
+ VALUE ary = rb_ary_new();
+
+ for (i=0; i<iseq->body->insns_info_size; i++) {
+ const struct iseq_insn_info_entry *entry = &iseq->body->insns_info[i];
+ if (entry->events) {
+ push_event_info(iseq, entry->events, entry->line_no, ary);
+ }
+ }
+ return ary;
+}
+
/*
* Returns the instruction sequence containing the given proc or method.
*
@@ -2679,6 +2716,7 @@ Init_ISeq(void)
rb_define_method(rb_cISeq, "label", iseqw_label, 0);
rb_define_method(rb_cISeq, "base_label", iseqw_base_label, 0);
rb_define_method(rb_cISeq, "first_lineno", iseqw_first_lineno, 0);
+ rb_define_method(rb_cISeq, "trace_points", iseqw_trace_points, 0);
rb_define_method(rb_cISeq, "each_child", iseqw_each_child, 0);
#if 0 /* TBD */