e$B$J$+$@$G$9!#e(B
Binding.of_callere$B$H$+e(BBinding#callere$B$H$+e(Bbindinge$B$N%*%W%7%g%J%k0z?te(B
e$B$H$+$r<BAu$7$F$_$^$7$?!#e(B
Index: proc.c
— proc.c (revision 14286)
+++ proc.c (working copy)
@@ -174,18 +174,93 @@ binding_clone(VALUE self)
}
+static int
+caller_level(int argc, VALUE *argv, int minimum)
+{
- VALUE v;
- int level;
- if (!argc) return minimum;
- rb_scan_args(argc, argv, “1”, &v);
- level = NUM2INT(v);
- if (level < 0) {
- rb_raise(rb_eArgError, “negative caller level: %d”, level);
- }
- if (level < minimum) {
- rb_raise(rb_eArgError, “caller level out of range: %d”, level);
- }
- return level;
+}
+VALUE
+rb_binding_caller(VALUE self, int level)
+{
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp;
- rb_binding_t *bind;
- VALUE envval, bindval;
- GetBindingPtr(self, bind);
- envval = bind->env;
- cfp = bind->cfp;
- do {
- cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- cfp = vm_get_ruby_level_cfp(th, cfp);
- if (!cfp) return Qnil;
- } while (level-- > 0);
- bindval = binding_alloc(rb_obj_class(self));
- GetBindingPtr(bindval, bind);
- bind->env = vm_make_env_object(th, cfp);
- bind->cref_stack = vm_get_cref(th, cfp->iseq, cfp);
- bind->cfp = cfp;
- return bindval;
+}
+static VALUE
+binding_caller(int argc, VALUE *argv, VALUE self)
+{
- return rb_binding_caller(self, caller_level(argc, argv, 1));
+}
VALUE
rb_binding_new(void)
{
- return rb_binding_at(0);
+}
+static VALUE
+binding_at(VALUE klass, int level)
+{
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- VALUE bindval = binding_alloc(rb_cBinding);
-
rb_control_frame_t *cfp = th->cfp;
-
VALUE bindval;
rb_binding_t *bind; -
for (;
{
-
cfp = vm_get_ruby_level_cfp(th, cfp);
-
if (!cfp) return Qnil;
-
if (level-- <= 0) break;
-
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
-
}
-
bindval = binding_alloc(klass);
GetBindingPtr(bindval, bind);
bind->env = vm_make_env_object(th, cfp);
- bind->cref_stack = ruby_cref();
- bind->cref_stack = vm_get_cref(th, cfp->iseq, cfp);
- bind->cfp = cfp;
return bindval;
}
+VALUE
+rb_binding_at(int level)
+{
- return binding_at(rb_cBinding, level);
+}
+static VALUE
+rb_binding_of_caller(int argc, VALUE *argv, VALUE klass)
+{
- return binding_at(klass, caller_level(argc, argv, 1));
+}
/*
- call-seq:
@@ -205,7 +280,7 @@ rb_binding_new(void)
static VALUE
-rb_f_binding(VALUE self)
+rb_f_binding(int argc, VALUE *argv, VALUE self)
{
- return rb_binding_new();
- return rb_binding_at(caller_level(argc, argv, 0));
}
@@ -1604,5 +1679,7 @@ Init_Binding(void)
rb_define_method(rb_cBinding, “dup”, binding_dup, 0);
rb_define_method(rb_cBinding, “eval”, bind_eval, -1);
- rb_define_global_function(“binding”, rb_f_binding, 0);
- rb_define_method(rb_cBinding, “caller”, binding_caller, -1);
- rb_define_singleton_method(rb_cBinding, “of_caller”,
rb_binding_of_caller, -1); - rb_define_global_function(“binding”, rb_f_binding, -1);
}
Index: vm_core.h
— vm_core.h (revision 14286)
+++ vm_core.h (working copy)
@@ -509,4 +509,5 @@ typedef struct {
VALUE env;
NODE *cref_stack;
- rb_control_frame_t *cfp;
} rb_binding_t;
Index: include/ruby/intern.h
— include/ruby/intern.h (revision 14286)
+++ include/ruby/intern.h (working copy)
@@ -254,4 +254,6 @@ VALUE rb_proc_call(VALUE, VALUE);
int rb_proc_arity(VALUE);
VALUE rb_binding_new(void);
+VALUE rb_binding_at(int);
+VALUE rb_binding_caller(VALUE, int);
VALUE rb_obj_method(VALUE, VALUE);
VALUE rb_method_call(int, VALUE*, VALUE);