Project

General

Profile

Feature #3917 » 0001-add-Kernel-called_from-which-is-similar-to-caller.patch

code (patch for 1.9.2-p0) - kwatch (makoto kuwata), 10/08/2010 08:45 AM

View differences:

vm.c
return TRUE;
}
static VALUE
vm_backtrace_get_location(rb_thread_t *th, int lev)
{
const rb_control_frame_t *limit_cfp = th->cfp;
const rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size);
int line_no;
VALUE filename, name;
cfp -= 2;
while (lev-- >= 0) {
if (++limit_cfp > cfp) {
return Qnil;
}
}
if (limit_cfp->iseq == NULL) {
return Qnil;
}
line_no = rb_vm_get_sourceline(limit_cfp);
filename = limit_cfp->iseq->filename;
name = limit_cfp->iseq->name;
return rb_ary_new3(3, filename, line_no ? INT2NUM(line_no) : Qnil, name);
}
static void
vm_backtrace_alloc(void *arg)
{
vm_eval.c
static inline VALUE vm_backtrace(rb_thread_t *th, int lev);
static int vm_backtrace_each(rb_thread_t *th, int lev, void (*init)(void *), rb_backtrace_iter_func *iter, void *arg);
static NODE *vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr);
static VALUE vm_backtrace_get_location(rb_thread_t *th, int lev);
static VALUE vm_exec(rb_thread_t *th);
static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref);
static int vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary);
......
return vm_backtrace(GET_THREAD(), lev);
}
/*
* call-seq:
* called_from(start=1) -> array or nil
*
* Returns file name, line number, and method name of the stack.
* The optional _start_ parameter represents the number of stack
* entries to skip.
*
* Returns +nil+ if _start_ is greater than the size of
* current execution stack.
*
* Raises ArgumentError if _start_ is negative value.
*
* # example.rb
* 1: def f1()
* 2: f2()
* 3: end
* 4: def f2()
* 5: f3()
* 6: end
* 7: def f3()
* 8: p called_from() #=> ["example.rb", 5, "f2"]
* 9: p called_from(0) #=> ["example.rb", 9, "f3"]
* 10: p called_from(1) #=> ["example.rb", 5, "f2"]
* 11: p called_from(2) #=> ["example.rb", 2, "f1"]
* 12: p called_from(3) #=> ["example.rb", 15, "<main>"]
* 13: p called_from(4) #=> nil
* 14: end
* 15: f1()
*/
static VALUE
rb_f_called_from(int argc, VALUE *argv)
{
VALUE level;
int lev;
VALUE ary = Qnil;
rb_scan_args(argc, argv, "01", &level);
lev = NIL_P(level) ? 1 : NUM2INT(level);
if (lev < 0) rb_raise(rb_eArgError, "negative level (%d)", lev);
return vm_backtrace_get_location(GET_THREAD(), lev);
}
static int
print_backtrace(void *arg, VALUE file, int line, VALUE method)
{
......
rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
rb_define_global_function("caller", rb_f_caller, -1);
rb_define_global_function("called_from", rb_f_called_from, -1);
}
(1-1/3)