summaryrefslogtreecommitdiff
path: root/vm_backtrace.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-02 15:59:37 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-02 15:59:37 +0000
commitb57c81ae3efd33599e993500816bce18e108a2d3 (patch)
tree1b2b9ccd8ce1f6873bbea4a9bda8ef2b985cd654 /vm_backtrace.c
parent3657d629c151bfe063e2db62506e47060f946b56 (diff)
* 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.c137
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);
}