* vm_backtrace.c, include/ruby/debug.h: add new APIs

* VALUE rb_profile_frame_method_name(VALUE frame)
* VALUE rb_profile_frame_qualified_method_name(VALUE frame)
* iseq.c (rb_iseq_klass), internal.h: add new internal function
  rb_iseq_method_name().
* ext/-test-/debug/profile_frames.c (profile_frames),
  test/-ext-/debug/test_profile_frames.rb: add a test.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2013-10-08 12:08:20 +00:00
Родитель 377758fdcb
Коммит cff2b2b666
7 изменённых файлов: 89 добавлений и 5 удалений

Просмотреть файл

@ -1,3 +1,15 @@
Tue Oct 8 21:03:35 2013 Koichi Sasada <ko1@atdot.net>
* vm_backtrace.c, include/ruby/debug.h: add new APIs
* VALUE rb_profile_frame_method_name(VALUE frame)
* VALUE rb_profile_frame_qualified_method_name(VALUE frame)
* iseq.c (rb_iseq_klass), internal.h: add new internal function
rb_iseq_method_name().
* ext/-test-/debug/profile_frames.c (profile_frames),
test/-ext-/debug/test_profile_frames.rb: add a test.
Tue Oct 8 16:11:11 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* array.c (rb_ary_uniq): use rb_hash_values(), as well as the case no

Просмотреть файл

@ -26,6 +26,8 @@ profile_frames(VALUE self, VALUE start_v, VALUE num_v)
rb_ary_push(ary, rb_profile_frame_first_lineno(buff[i]));
rb_ary_push(ary, rb_profile_frame_classpath(buff[i]));
rb_ary_push(ary, rb_profile_frame_singleton_method_p(buff[i]));
rb_ary_push(ary, rb_profile_frame_method_name(buff[i]));
rb_ary_push(ary, rb_profile_frame_qualified_method_name(buff[i]));
rb_ary_push(result, ary);
}

Просмотреть файл

@ -34,6 +34,8 @@ VALUE rb_profile_frame_base_label(VALUE frame);
VALUE rb_profile_frame_first_lineno(VALUE frame);
VALUE rb_profile_frame_classpath(VALUE frame);
VALUE rb_profile_frame_singleton_method_p(VALUE frame);
VALUE rb_profile_frame_method_name(VALUE frame);
VALUE rb_profile_frame_qualified_method_name(VALUE frame);
/* debug inspector APIs */
typedef struct rb_debug_inspector_struct rb_debug_inspector_t;

Просмотреть файл

@ -457,6 +457,7 @@ VALUE rb_iseq_label(VALUE iseqval);
VALUE rb_iseq_base_label(VALUE iseqval);
VALUE rb_iseq_first_lineno(VALUE iseqval);
VALUE rb_iseq_klass(VALUE iseqval); /* completely temporary fucntion */
VALUE rb_iseq_method_name(VALUE self);
/* load.c */
VALUE rb_get_load_path(void);

14
iseq.c
Просмотреть файл

@ -959,6 +959,20 @@ rb_iseq_klass(VALUE self)
return iseq->local_iseq->klass;
}
VALUE
rb_iseq_method_name(VALUE self)
{
rb_iseq_t *iseq, *local_iseq;
GetISeqPtr(self, iseq);
local_iseq = iseq->local_iseq;
if (local_iseq->type == ISEQ_TYPE_METHOD) {
return local_iseq->location.base_label;
}
else {
return Qnil;
}
}
static
VALUE iseq_data_to_ary(rb_iseq_t *iseq);

Просмотреть файл

@ -2,8 +2,14 @@ require 'test/unit'
require '-test-/debug'
class SampleClassForTestProfileFrames
class Sample2
def baz(block)
block.call
end
end
def self.bar(block)
block.call
Sample2.new.baz(block)
end
def foo(block)
@ -17,31 +23,49 @@ class TestProfileFrames < Test::Unit::TestCase
Fiber.yield SampleClassForTestProfileFrames.new.foo(lambda{ Bug::Debug.profile_frames(0, 10) })
}.resume
assert_equal(4, frames.size)
labels = [
"block (2 levels) in test_profile_frames",
"baz",
"bar",
"foo",
"block in test_profile_frames",
]
base_labels = [
"test_profile_frames",
"baz",
"bar",
"foo",
"test_profile_frames",
]
classes = [
TestProfileFrames,
SampleClassForTestProfileFrames::Sample2,
SampleClassForTestProfileFrames, # singleton method
SampleClassForTestProfileFrames,
TestProfileFrames,
]
singleton_method_p = [
false, true, false, false, false,
false, false, true, false, false, false,
]
methdo_names = [
"test_profile_frames",
"baz",
"bar",
"foo",
"test_profile_frames",
]
qualified_method_names = [
"TestProfileFrames#test_profile_frames",
"SampleClassForTestProfileFrames::Sample2#baz",
"SampleClassForTestProfileFrames.bar",
"SampleClassForTestProfileFrames#foo",
"TestProfileFrames#test_profile_frames",
]
frames.each.with_index{|(path, absolute_path, label, base_label, first_lineno, classpath, singleton_p), i|
assert_equal(labels.size, frames.size)
frames.each.with_index{|(path, absolute_path, label, base_label, first_lineno,
classpath, singleton_p, method_name, qualified_method_name), i|
err_msg = "#{i}th frame"
assert_equal(__FILE__, path, err_msg)
assert_equal(__FILE__, absolute_path, err_msg)
@ -49,6 +73,8 @@ class TestProfileFrames < Test::Unit::TestCase
assert_equal(base_labels[i], base_label, err_msg)
assert_equal(classes[i].to_s, classpath, err_msg)
assert_equal(singleton_method_p[i], singleton_p, err_msg)
assert_equal(methdo_names[i], method_name, err_msg)
assert_equal(qualified_method_names[i], qualified_method_name, err_msg)
}
end
end

Просмотреть файл

@ -1287,3 +1287,30 @@ rb_profile_frame_singleton_method_p(VALUE frame)
return Qfalse;
}
}
VALUE
rb_profile_frame_method_name(VALUE frame)
{
return rb_iseq_method_name(frame2iseq(frame));
}
VALUE
rb_profile_frame_qualified_method_name(VALUE frame)
{
VALUE method_name = rb_iseq_method_name(frame2iseq(frame));
if (method_name != Qnil) {
VALUE classpath = rb_profile_frame_classpath(frame);
VALUE singleton_p = rb_profile_frame_singleton_method_p(frame);
if (classpath != Qnil) {
return rb_sprintf("%"PRIsVALUE"%s%"PRIsVALUE,
classpath, singleton_p == Qtrue ? "." : "#", method_name);
}
else {
return method_name;
}
}
else {
return Qnil;
}
}