summaryrefslogtreecommitdiff
path: root/vm_backtrace.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-19 06:07:06 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-19 06:07:06 +0000
commit15d940b8b0361925e15f412913f346fca4bf3400 (patch)
treeccf8f87f25f960b7cb90687a9e52af6f1d9072c9 /vm_backtrace.c
parent3918bbfac493d7c83371e0491570ea11d53d249a (diff)
* thread.c: add `Thread#backtrace_locations' method.
This method is similart to `caller_locations' method for specific method. And fix to accept `level' and `n' parameters for `Thread#backtrace' and `Thread#backtrace_locations'. `caller' (and `caller_locations') do not return `caller' method frame. However, `Thread#backtrace' (and `Thread#backtrace_locations') return `Thread#backtrace' method frame itself if `Thread.current.backtrace' was called. * vm_backtrace.c: ditto. * internal.h: ditto. * test/ruby/test_backtrace.rb: add tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37716 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_backtrace.c')
-rw-r--r--vm_backtrace.c105
1 files changed, 52 insertions, 53 deletions
diff --git a/vm_backtrace.c b/vm_backtrace.c
index 4e01c7b723..12617443e5 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -697,8 +697,43 @@ rb_make_backtrace(void)
return vm_backtrace_str_ary(GET_THREAD(), 0, 0);
}
-VALUE
-rb_thread_backtrace(VALUE thval)
+static VALUE
+vm_backtrace_to_ary(rb_thread_t *th, int argc, VALUE *argv, int lev_deafult, int lev_plus, int to_str)
+{
+ VALUE level, vn;
+ int lev, n;
+
+ rb_scan_args(argc, argv, "02", &level, &vn);
+
+ lev = NIL_P(level) ? lev_deafult : NUM2INT(level);
+
+ if (NIL_P(vn)) {
+ n = 0;
+ }
+ else {
+ n = NUM2INT(vn);
+ if (n == 0) {
+ return rb_ary_new();
+ }
+ }
+
+ if (lev < 0) {
+ rb_raise(rb_eArgError, "negative level (%d)", lev);
+ }
+ if (n < 0) {
+ rb_raise(rb_eArgError, "negative n (%d)", n);
+ }
+
+ if (to_str) {
+ return vm_backtrace_str_ary(th, lev+lev_plus, n);
+ }
+ else {
+ return vm_backtrace_frame_ary(th, lev+lev_plus, n);
+ }
+}
+
+static VALUE
+thread_backtrace_to_ary(int argc, VALUE *argv, VALUE thval, int to_str)
{
rb_thread_t *th;
GetThreadPtr(thval, th);
@@ -713,7 +748,19 @@ rb_thread_backtrace(VALUE thval)
return Qnil;
}
- return vm_backtrace_str_ary(th, 0, 0);
+ return vm_backtrace_to_ary(th, argc, argv, 0, 0, to_str);
+}
+
+VALUE
+vm_thread_backtrace(int argc, VALUE *argv, VALUE thval)
+{
+ return thread_backtrace_to_ary(argc, argv, thval, 1);
+}
+
+VALUE
+vm_thread_backtrace_locations(int argc, VALUE *argv, VALUE thval)
+{
+ return thread_backtrace_to_ary(argc, argv, thval, 0);
}
/*
@@ -749,61 +796,13 @@ rb_thread_backtrace(VALUE thval)
static VALUE
rb_f_caller(int argc, VALUE *argv)
{
- VALUE level, vn;
- int lev, n;
-
- rb_scan_args(argc, argv, "02", &level, &vn);
-
- lev = NIL_P(level) ? 1 : NUM2INT(level);
-
- if (NIL_P(vn)) {
- n = 0;
- }
- else {
- n = NUM2INT(vn);
- if (n == 0) {
- return rb_ary_new();
- }
- }
-
- if (lev < 0) {
- rb_raise(rb_eArgError, "negative level (%d)", lev);
- }
- if (n < 0) {
- rb_raise(rb_eArgError, "negative n (%d)", n);
- }
-
- return vm_backtrace_str_ary(GET_THREAD(), lev+1, n);
+ return vm_backtrace_to_ary(GET_THREAD(), argc, argv, 1, 1, 1);
}
static VALUE
rb_f_caller_locations(int argc, VALUE *argv)
{
- VALUE level, vn;
- int lev, n;
-
- rb_scan_args(argc, argv, "02", &level, &vn);
-
- lev = NIL_P(level) ? 1 : NUM2INT(level);
-
- if (NIL_P(vn)) {
- n = 0;
- }
- else {
- n = NUM2INT(vn);
- if (n == 0) {
- return rb_ary_new();
- }
- }
-
- if (lev < 0) {
- rb_raise(rb_eArgError, "negative level (%d)", lev);
- }
- if (n < 0) {
- rb_raise(rb_eArgError, "negative n (%d)", n);
- }
-
- return vm_backtrace_frame_ary(GET_THREAD(), lev+1, n);
+ return vm_backtrace_to_ary(GET_THREAD(), argc, argv, 1, 1, 0);
}
/* called from Init_vm() in vm.c */