[前][次][番号順一覧][スレッド一覧]

ruby-changes:13254

From: nobu <ko1@a...>
Date: Mon, 21 Sep 2009 17:12:32 +0900 (JST)
Subject: [ruby-changes:13254] Ruby:r25015 (trunk): * proc.c (proc_binding): allow proc from method.

nobu	2009-09-21 17:12:12 +0900 (Mon, 21 Sep 2009)

  New Revision: 25015

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25015

  Log:
    * proc.c (proc_binding): allow proc from method.  [ruby-core:25589]
    
    * vm.c (collect_local_variables_in_env): block iseq can be NULL.

  Modified files:
    trunk/ChangeLog
    trunk/proc.c
    trunk/test/ruby/test_proc.rb
    trunk/vm.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 25014)
+++ ChangeLog	(revision 25015)
@@ -1,3 +1,9 @@
+Mon Sep 21 17:12:10 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* proc.c (proc_binding): allow proc from method.  [ruby-core:25589]
+
+	* vm.c (collect_local_variables_in_env): block iseq can be NULL.
+
 Mon Sep 21 10:13:22 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* cont.c (cont_new, cont_capture, fiber_t_alloc): needs already
Index: proc.c
===================================================================
--- proc.c	(revision 25014)
+++ proc.c	(revision 25015)
@@ -33,6 +33,8 @@
 
 /* Proc */
 
+#define IS_METHOD_PROC_NODE(node) (nd_type(node) == NODE_IFUNC && (node)->nd_cfnc == bmcall)
+
 static void
 proc_free(void *ptr)
 {
@@ -633,7 +635,7 @@
 	}
 	else {
 	    NODE *node = (NODE *)iseq;
-	    if (nd_type(node) == NODE_IFUNC && node->nd_cfnc == bmcall) {
+	    if (IS_METHOD_PROC_NODE(node)) {
 		/* method(:foo).to_proc.arity */
 		return method_arity(node->nd_tval);
 	    }
@@ -654,7 +656,7 @@
     if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) {
 	NODE *node = (NODE *)iseq;
 	iseq = 0;
-	if (nd_type(node) == NODE_IFUNC && node->nd_cfnc == bmcall) {
+	if (IS_METHOD_PROC_NODE(node)) {
 	    /* method(:foo).to_proc */
 	    iseq = rb_method_get_iseq(node->nd_tval);
 	    if (is_proc) *is_proc = 0;
@@ -1807,16 +1809,18 @@
 proc_binding(VALUE self)
 {
     rb_proc_t *proc;
-    VALUE bindval = binding_alloc(rb_cBinding);
+    VALUE bindval;
     rb_binding_t *bind;
 
     GetProcPtr(self, proc);
-    GetBindingPtr(bindval, bind);
-
     if (TYPE(proc->block.iseq) == T_NODE) {
-	rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
+	if (!IS_METHOD_PROC_NODE((NODE *)proc->block.iseq)) {
+	    rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
+	}
     }
 
+    bindval = binding_alloc(rb_cBinding);
+    GetBindingPtr(bindval, bind);
     bind->env = proc->envval;
     return bindval;
 }
Index: vm.c
===================================================================
--- vm.c	(revision 25014)
+++ vm.c	(revision 25015)
@@ -381,19 +381,26 @@
 }
 
 static int
-collect_local_variables_in_env(rb_env_t * const env, const VALUE ary)
+collect_local_variables_in_iseq(rb_iseq_t *iseq, const VALUE ary)
 {
     int i;
-    for (i = 0; i < env->block.iseq->local_table_size; i++) {
-	ID lid = env->block.iseq->local_table[i];
+    if (!iseq) return 0;
+    for (i = 0; i < iseq->local_table_size; i++) {
+	ID lid = iseq->local_table[i];
 	if (rb_is_local_id(lid)) {
 	    rb_ary_push(ary, ID2SYM(lid));
 	}
     }
-    if (env->prev_envval) {
-	rb_env_t *prevenv;
-	GetEnvPtr(env->prev_envval, prevenv);
-	collect_local_variables_in_env(prevenv, ary);
+    return 1;
+}
+
+static int
+collect_local_variables_in_env(rb_env_t * env, const VALUE ary)
+{
+    
+    while (collect_local_variables_in_iseq(env->block.iseq, ary),
+	   env->prev_envval) {
+	GetEnvPtr(env->prev_envval, env);
     }
     return 0;
 }
Index: test/ruby/test_proc.rb
===================================================================
--- test/ruby/test_proc.rb	(revision 25014)
+++ test/ruby/test_proc.rb	(revision 25015)
@@ -144,6 +144,7 @@
   def test_method_to_proc
     b = block()
     assert_equal "OK", b.call
+    assert_instance_of(Binding, b.binding, '[ruby-core:25589]')
   end
 
   def test_curry

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]