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
This commit is contained in:
parent
ac40fc997b
commit
3044138bd7
1
NEWS
1
NEWS
@ -168,6 +168,7 @@ with all sufficient information, see the ChangeLog file or Redmine
|
|||||||
* New method:
|
* New method:
|
||||||
|
|
||||||
* RubyVM::InstructionSequence#each_child
|
* RubyVM::InstructionSequence#each_child
|
||||||
|
* RubyVM::InstructionSequence#trace_points
|
||||||
|
|
||||||
* String
|
* String
|
||||||
|
|
||||||
|
@ -763,7 +763,7 @@ rb_vm_insn_addr2insn(const void *addr) /* cold path */
|
|||||||
VALUE *
|
VALUE *
|
||||||
rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */
|
rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */
|
||||||
{
|
{
|
||||||
VALUE *original_code;
|
VALUE *original_code;3
|
||||||
|
|
||||||
if (ISEQ_ORIGINAL_ISEQ(iseq)) return ISEQ_ORIGINAL_ISEQ(iseq);
|
if (ISEQ_ORIGINAL_ISEQ(iseq)) return ISEQ_ORIGINAL_ISEQ(iseq);
|
||||||
original_code = ISEQ_ORIGINAL_ISEQ_ALLOC(iseq, iseq->body->iseq_size);
|
original_code = ISEQ_ORIGINAL_ISEQ_ALLOC(iseq, iseq->body->iseq_size);
|
||||||
|
38
iseq.c
38
iseq.c
@ -1874,6 +1874,43 @@ iseqw_each_child(VALUE self)
|
|||||||
return 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.
|
* 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, "label", iseqw_label, 0);
|
||||||
rb_define_method(rb_cISeq, "base_label", iseqw_base_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, "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);
|
rb_define_method(rb_cISeq, "each_child", iseqw_each_child, 0);
|
||||||
|
|
||||||
#if 0 /* TBD */
|
#if 0 /* TBD */
|
||||||
|
@ -281,27 +281,31 @@ class TestISeq < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_each_child
|
def sample_iseq
|
||||||
iseq = ISeq.compile <<-EOS
|
ISeq.compile <<-EOS.gsub(/^.*?: /, "")
|
||||||
class C
|
1: class C
|
||||||
def foo
|
2: def foo
|
||||||
begin
|
3: begin
|
||||||
rescue
|
4: rescue
|
||||||
p :rescue
|
5: p :rescue
|
||||||
ensure
|
6: ensure
|
||||||
p :ensure
|
7: p :ensure
|
||||||
end
|
8: end
|
||||||
end
|
9: end
|
||||||
def bar
|
10: def bar
|
||||||
1.times{
|
11: 1.times{
|
||||||
2.times{
|
12: 2.times{
|
||||||
}
|
13: }
|
||||||
}
|
14: }
|
||||||
end
|
15: end
|
||||||
end
|
16: end
|
||||||
class D < C
|
17: class D < C
|
||||||
end
|
18: end
|
||||||
EOS
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_each_child
|
||||||
|
iseq = sample_iseq
|
||||||
|
|
||||||
collect_iseq = lambda{|iseq|
|
collect_iseq = lambda{|iseq|
|
||||||
iseqs = []
|
iseqs = []
|
||||||
@ -321,4 +325,36 @@ class TestISeq < Test::Unit::TestCase
|
|||||||
|
|
||||||
assert_equal expected, collect_iseq.call(iseq)
|
assert_equal expected, collect_iseq.call(iseq)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_trace_points
|
||||||
|
collect_iseq = lambda{|iseq|
|
||||||
|
iseqs = []
|
||||||
|
iseq.each_child{|child_iseq|
|
||||||
|
iseqs << collect_iseq.call(child_iseq)
|
||||||
|
}
|
||||||
|
[["#{iseq.label}@#{iseq.first_lineno}", iseq.trace_points], *iseqs.sort_by{|k, *| k}]
|
||||||
|
}
|
||||||
|
assert_equal [["<compiled>@1", [[1, :line],
|
||||||
|
[17, :line]]],
|
||||||
|
[["<class:C>@1", [[1, :class],
|
||||||
|
[2, :line],
|
||||||
|
[10, :line],
|
||||||
|
[16, :end]]],
|
||||||
|
[["bar@10", [[10, :call],
|
||||||
|
[11, :line],
|
||||||
|
[15, :return]]],
|
||||||
|
[["block in bar@11", [[11, :b_call],
|
||||||
|
[12, :line],
|
||||||
|
[14, :b_return]]],
|
||||||
|
[["block (2 levels) in bar@12", [[12, :b_call],
|
||||||
|
[13, :b_return]]]]]],
|
||||||
|
[["foo@2", [[2, :call],
|
||||||
|
[4, :line],
|
||||||
|
[7, :line],
|
||||||
|
[9, :return]]],
|
||||||
|
[["ensure in foo@2", [[7, :line]]]],
|
||||||
|
[["rescue in foo@4", [[5, :line]]]]]],
|
||||||
|
[["<class:D>@17", [[17, :class],
|
||||||
|
[18, :end]]]]], collect_iseq.call(sample_iseq)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user