diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | ext/-test-/debug/profile_frames.c | 2 | ||||
-rw-r--r-- | include/ruby/debug.h | 2 | ||||
-rw-r--r-- | internal.h | 1 | ||||
-rw-r--r-- | iseq.c | 14 | ||||
-rw-r--r-- | test/-ext-/debug/test_profile_frames.rb | 36 | ||||
-rw-r--r-- | vm_backtrace.c | 27 |
7 files changed, 89 insertions, 5 deletions
@@ -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 diff --git a/ext/-test-/debug/profile_frames.c b/ext/-test-/debug/profile_frames.c index cbabe1b015..5d9501046c 100644 --- a/ext/-test-/debug/profile_frames.c +++ b/ext/-test-/debug/profile_frames.c @@ -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); } diff --git a/include/ruby/debug.h b/include/ruby/debug.h index 2ef99d4185..add719545f 100644 --- a/include/ruby/debug.h +++ b/include/ruby/debug.h @@ -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; diff --git a/internal.h b/internal.h index 690e26c969..c96245db19 100644 --- a/internal.h +++ b/internal.h @@ -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); @@ -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); diff --git a/test/-ext-/debug/test_profile_frames.rb b/test/-ext-/debug/test_profile_frames.rb index 854f3bc2db..cca4607c73 100644 --- a/test/-ext-/debug/test_profile_frames.rb +++ b/test/-ext-/debug/test_profile_frames.rb @@ -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", + ] + + assert_equal(labels.size, frames.size) - frames.each.with_index{|(path, absolute_path, label, base_label, first_lineno, classpath, singleton_p), i| + 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 diff --git a/vm_backtrace.c b/vm_backtrace.c index b4f16f68fc..8155c85856 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -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; + } +} |