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

ruby-changes:9442

From: ko1 <ko1@a...>
Date: Thu, 25 Dec 2008 12:52:17 +0900 (JST)
Subject: [ruby-changes:9442] Ruby:r20980 (trunk): * proc.c (proc_new): should use proc_dup() if block has Proc.

ko1	2008-12-25 12:51:35 +0900 (Thu, 25 Dec 2008)

  New Revision: 20980

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

  Log:
    * proc.c (proc_new): should use proc_dup() if block has Proc.
    * vm.c (vm_make_proc_from_block): should use rb_cProc for block.
    * vm.c (vm_make_proc): add an assertion.
    * bootstraptest/test_proc.rb: add a test.

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 20979)
+++ ChangeLog	(revision 20980)
@@ -1,3 +1,13 @@
+Thu Dec 25 12:49:12 2008  Koichi Sasada  <ko1@a...>
+
+	* proc.c (proc_new): should use proc_dup() if block has Proc.
+
+	* vm.c (vm_make_proc_from_block): should use rb_cProc for block.
+
+	* vm.c (vm_make_proc): add an assertion.
+
+	* bootstraptest/test_proc.rb: add a test.
+
 Thu Dec 25 12:44:27 2008  Koichi Sasada  <ko1@a...>
 
 	* vm_insnhelper.c (vm_yield_with_cfunc): check block has Proc.
Index: bootstraptest/test_proc.rb
===================================================================
--- bootstraptest/test_proc.rb	(revision 20979)
+++ bootstraptest/test_proc.rb	(revision 20980)
@@ -394,3 +394,27 @@
   a_proc = give_it
   f.call_it(&give_it())
 }, '[ruby-core:15711]'
+
+assert_equal 'foo!', %q{
+  class FooProc < Proc
+    def initialize
+      @foo = "foo!"
+    end
+
+    def bar
+      @foo
+    end
+  end
+
+  def bar
+    FooProc.new &lambda{
+      p 1
+    }
+  end
+
+  fp = bar(&lambda{
+    p 2
+  })
+
+  fp.bar
+}, 'Subclass of Proc'
Index: proc.c
===================================================================
--- proc.c	(revision 20979)
+++ proc.c	(revision 20980)
@@ -353,7 +353,6 @@
 	!RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) {
 
 	block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
-	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
     }
     else {
 	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
@@ -363,15 +362,6 @@
 
 	    block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
 
-	    if (block->proc) {
-		return block->proc;
-	    }
-
-	    /* TODO: check more (cfp limit, called via cfunc, etc) */
-	    while (cfp->dfp != block->dfp) {
-		cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
-	    }
-
 	    if (is_lambda) {
 		rb_warn("tried to create Proc object without a block");
 	    }
@@ -383,8 +373,16 @@
     }
 
     procval = block->proc;
-    if (procval && RBASIC(procval)->klass == klass) {
-	return procval;
+
+    if (procval) {
+	if (RBASIC(procval)->klass == klass) {
+	    return procval;
+	}
+	else {
+	    VALUE newprocval = proc_dup(procval);
+	    RBASIC(newprocval)->klass = klass;
+	    return newprocval;
+	}
     }
 
     procval = vm_make_proc(th, block, klass);
Index: vm.c
===================================================================
--- vm.c	(revision 20979)
+++ vm.c	(revision 20980)
@@ -385,20 +385,18 @@
 /* Proc */
 
 static VALUE
-vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block, VALUE klass)
+vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block)
 {
-    VALUE procval;
+    VALUE proc = block->proc;
 
-    procval = block->proc;
-    if (procval && RBASIC(procval)->klass == klass) {
-	return procval;
+    if (block->proc) {
+	return block->proc;
     }
 
-    procval = vm_make_proc(th, block, klass);
-    if (!block->proc) {
-	block->proc = procval;
-    }
-    return procval;
+    proc = vm_make_proc(th, block, rb_cProc);
+    block->proc = proc;
+
+    return proc;
 }
 
 VALUE
@@ -408,12 +406,16 @@
     rb_proc_t *proc;
     rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block);
 
+    if (block->proc) {
+	rb_bug("vm_make_proc: Proc value is already created.");
+    }
+
     if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
 	if (!RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) {
 	    rb_proc_t *p;
 
 	    blockprocval = vm_make_proc_from_block(
-		th, (rb_block_t *)GC_GUARDED_PTR_REF(*cfp->lfp), klass);
+		th, (rb_block_t *)GC_GUARDED_PTR_REF(*cfp->lfp));
 
 	    GetProcPtr(blockprocval, p);
 	    *cfp->lfp = GC_GUARDED_PTR(&p->block);

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

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