diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-06-02 15:59:37 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-06-02 15:59:37 +0000 |
commit | b57c81ae3efd33599e993500816bce18e108a2d3 (patch) | |
tree | 1b2b9ccd8ce1f6873bbea4a9bda8ef2b985cd654 /vm_backtrace.c | |
parent | 3657d629c151bfe063e2db62506e47060f946b56 (diff) | |
download | ruby-b57c81ae3efd33599e993500816bce18e108a2d3.tar.gz |
* common.mk: fix to build vm_backtrace.c only itself (vm_backtrace.c
is no longer included from vm.c). I hope this separation reduce
compile time of vm.c.
* internal.h: ditto.
* vm.c, vm_core.h, vm_dump.c, vm_eval.c: ditto.
* vm_eval.c: some functions (callee, etc) moved to vm_backtrace.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_backtrace.c')
-rw-r--r-- | vm_backtrace.c | 137 |
1 files changed, 133 insertions, 4 deletions
diff --git a/vm_backtrace.c b/vm_backtrace.c index 9216a548de..e21b580b56 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -9,7 +9,12 @@ **********************************************************************/ -/* this file is included by vm.c */ +#include "ruby/ruby.h" +#include "ruby/encoding.h" + +#include "internal.h" +#include "vm_core.h" +#include "iseq.h" static VALUE rb_cBacktrace; static VALUE rb_cFrameInfo; @@ -586,13 +591,13 @@ backtrace_load_data(VALUE self, VALUE str) return self; } -static VALUE +VALUE vm_backtrace_str_ary(rb_thread_t *th, int lev, int n) { return backtrace_to_str_ary2(backtrace_object(th), lev, n); } -static VALUE +VALUE vm_backtrace_frame_ary(rb_thread_t *th, int lev, int n) { return backtrace_to_frame_ary(backtrace_object(th), lev, n); @@ -701,7 +706,129 @@ rb_backtrace_print_as_bugreport(void) &arg); } -static void +void +rb_backtrace(void) +{ + vm_backtrace_print(stderr); +} + +VALUE +rb_make_backtrace(void) +{ + return vm_backtrace_str_ary(GET_THREAD(), 0, 0); +} + +VALUE +rb_thread_backtrace(VALUE thval) +{ + rb_thread_t *th; + GetThreadPtr(thval, th); + + switch (th->status) { + case THREAD_RUNNABLE: + case THREAD_STOPPED: + case THREAD_STOPPED_FOREVER: + break; + case THREAD_TO_KILL: + case THREAD_KILLED: + return Qnil; + } + + return vm_backtrace_str_ary(th, 0, 0); +} + +/* + * call-seq: + * caller(start=1) -> array or nil + * + * Returns the current execution stack---an array containing strings in + * the form ``<em>file:line</em>'' or ``<em>file:line: in + * `method'</em>''. The optional _start_ parameter + * determines the number of initial stack entries to omit from the + * result. + * + * Returns +nil+ if _start_ is greater than the size of + * current execution stack. + * + * def a(skip) + * caller(skip) + * end + * def b(skip) + * a(skip) + * end + * def c(skip) + * b(skip) + * end + * c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10:in `<main>'"] + * c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11:in `<main>'"] + * c(2) #=> ["prog:8:in `c'", "prog:12:in `<main>'"] + * c(3) #=> ["prog:13:in `<main>'"] + * c(4) #=> [] + * c(5) #=> nil + */ + +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); +} + +static VALUE +rb_f_caller_frame_info(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); +} + +/* called from Init_vm() in vm.c */ +void Init_vm_backtrace(void) { /* ::RubyVM::Backtrace */ @@ -722,4 +849,6 @@ Init_vm_backtrace(void) rb_define_method(rb_cFrameInfo, "iseq", frame_info_iseq_m, 0); rb_define_method(rb_cFrameInfo, "to_s", frame_info_to_str_m, 0); rb_define_singleton_method(rb_cFrameInfo, "caller", rb_f_caller_frame_info, -1); + + rb_define_global_function("caller", rb_f_caller, -1); } |