зеркало из https://github.com/github/ruby.git
* 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:
Родитель
377758fdcb
Коммит
cff2b2b666
12
ChangeLog
12
ChangeLog
|
@ -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
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;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче