summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--ext/-test-/debug/profile_frames.c2
-rw-r--r--include/ruby/debug.h2
-rw-r--r--internal.h1
-rw-r--r--iseq.c14
-rw-r--r--test/-ext-/debug/test_profile_frames.rb36
-rw-r--r--vm_backtrace.c27
7 files changed, 89 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 79f30707fd..d6af7c82d5 100644
--- a/ChangeLog
+++ b/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
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);
diff --git a/iseq.c b/iseq.c
index a06a0a915f..8545e6c881 100644
--- a/iseq.c
+++ b/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);
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;
+ }
+}