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

ruby-changes:35923

From: nagachika <ko1@a...>
Date: Sun, 19 Oct 2014 03:35:43 +0900 (JST)
Subject: [ruby-changes:35923] nagachika:r48004 (ruby_2_1): merge revision(s) r48000: [Backport #10368]

nagachika	2014-10-19 03:35:31 +0900 (Sun, 19 Oct 2014)

  New Revision: 48004

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

  Log:
    merge revision(s) r48000: [Backport #10368]
    
    * vm_core.h, vm.c, proc.c: fix GC mark miss on bindings.
      [ruby-dev:48616] [Bug #10368]
    
    * test/ruby/test_eval.rb: add a test code.

  Modified directories:
    branches/ruby_2_1/
  Modified files:
    branches/ruby_2_1/ChangeLog
    branches/ruby_2_1/proc.c
    branches/ruby_2_1/test/ruby/test_eval.rb
    branches/ruby_2_1/version.h
    branches/ruby_2_1/vm.c
    branches/ruby_2_1/vm_core.h
Index: ruby_2_1/ChangeLog
===================================================================
--- ruby_2_1/ChangeLog	(revision 48003)
+++ ruby_2_1/ChangeLog	(revision 48004)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1
+Sun Oct 19 03:22:53 2014  Kazuki Tsujimoto  <kazuki@c...>
+
+	* vm_core.h, vm.c, proc.c: fix GC mark miss on bindings.
+	  [ruby-dev:48616] [Bug #10368]
+
+	* test/ruby/test_eval.rb: add a test code.
+
 Sun Oct 19 03:13:38 2014  Nobuyoshi Nakada  <nobu@r...>
 
 	* parse.y (parser_here_document): do not append already appended
Index: ruby_2_1/vm_core.h
===================================================================
--- ruby_2_1/vm_core.h	(revision 48003)
+++ ruby_2_1/vm_core.h	(revision 48004)
@@ -726,6 +726,7 @@ extern const rb_data_type_t ruby_binding https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm_core.h#L726
 typedef struct {
     VALUE env;
     VALUE path;
+    VALUE blockprocval;	/* for GC mark */
     unsigned short first_lineno;
 } rb_binding_t;
 
@@ -842,6 +843,7 @@ rb_block_t *rb_vm_control_frame_block_pt https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm_core.h#L843
 /* VM related object allocate functions */
 VALUE rb_thread_alloc(VALUE klass);
 VALUE rb_proc_alloc(VALUE klass);
+VALUE rb_binding_alloc(VALUE klass);
 
 /* for debug */
 extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
@@ -862,6 +864,7 @@ int rb_thread_method_id_and_class(rb_thr https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm_core.h#L864
 VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
 			int argc, const VALUE *argv, const rb_block_t *blockptr);
 VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
+VALUE rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp);
 VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
 VALUE rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp);
 VALUE *rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars);
Index: ruby_2_1/proc.c
===================================================================
--- ruby_2_1/proc.c	(revision 48003)
+++ ruby_2_1/proc.c	(revision 48004)
@@ -262,6 +262,7 @@ binding_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/proc.c#L262
 	bind = ptr;
 	RUBY_MARK_UNLESS_NULL(bind->env);
 	RUBY_MARK_UNLESS_NULL(bind->path);
+	RUBY_MARK_UNLESS_NULL(bind->blockprocval);
     }
     RUBY_MARK_LEAVE("binding");
 }
@@ -282,8 +283,8 @@ const rb_data_type_t ruby_binding_data_t https://github.com/ruby/ruby/blob/trunk/ruby_2_1/proc.c#L283
     NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
 };
 
-static VALUE
-binding_alloc(VALUE klass)
+VALUE
+rb_binding_alloc(VALUE klass)
 {
     VALUE obj;
     rb_binding_t *bind;
@@ -295,12 +296,13 @@ binding_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/proc.c#L296
 static VALUE
 binding_dup(VALUE self)
 {
-    VALUE bindval = binding_alloc(rb_cBinding);
+    VALUE bindval = rb_binding_alloc(rb_cBinding);
     rb_binding_t *src, *dst;
     GetBindingPtr(self, src);
     GetBindingPtr(bindval, dst);
     dst->env = src->env;
     dst->path = src->path;
+    dst->blockprocval = src->blockprocval;
     dst->first_lineno = src->first_lineno;
     return bindval;
 }
@@ -317,30 +319,7 @@ binding_clone(VALUE self) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/proc.c#L319
 VALUE
 rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp)
 {
-    rb_control_frame_t *cfp = rb_vm_get_binding_creatable_next_cfp(th, src_cfp);
-    rb_control_frame_t *ruby_level_cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
-    VALUE bindval, envval;
-    rb_binding_t *bind;
-
-    if (cfp == 0 || ruby_level_cfp == 0) {
-	rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
-    }
-
-    while (1) {
-	envval = rb_vm_make_env_object(th, cfp);
-	if (cfp == ruby_level_cfp) {
-	    break;
-	}
-	cfp = rb_vm_get_binding_creatable_next_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
-    }
-
-    bindval = binding_alloc(rb_cBinding);
-    GetBindingPtr(bindval, bind);
-    bind->env = envval;
-    bind->path = ruby_level_cfp->iseq->location.path;
-    bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
-
-    return bindval;
+    return rb_vm_make_binding(th, src_cfp);
 }
 
 VALUE
@@ -2409,9 +2388,10 @@ proc_binding(VALUE self) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/proc.c#L2388
 	}
     }
 
-    bindval = binding_alloc(rb_cBinding);
+    bindval = rb_binding_alloc(rb_cBinding);
     GetBindingPtr(bindval, bind);
     bind->env = proc->envval;
+    bind->blockprocval = proc->blockprocval;
     if (RUBY_VM_NORMAL_ISEQ_P(proc->block.iseq)) {
 	bind->path = proc->block.iseq->location.path;
 	bind->first_lineno = FIX2INT(rb_iseq_first_lineno(proc->block.iseq->self));
Index: ruby_2_1/vm.c
===================================================================
--- ruby_2_1/vm.c	(revision 48003)
+++ ruby_2_1/vm.c	(revision 48004)
@@ -688,6 +688,39 @@ rb_vm_make_proc(rb_thread_t *th, const r https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm.c#L688
     return procval;
 }
 
+/* Binding */
+
+VALUE
+rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
+{
+    rb_control_frame_t *cfp = rb_vm_get_binding_creatable_next_cfp(th, src_cfp);
+    rb_control_frame_t *ruby_level_cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
+    VALUE bindval, envval;
+    rb_binding_t *bind;
+    VALUE blockprocval = 0;
+
+    if (cfp == 0 || ruby_level_cfp == 0) {
+	rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
+    }
+
+    while (1) {
+	envval = vm_make_env_object(th, cfp, &blockprocval);
+	if (cfp == ruby_level_cfp) {
+	    break;
+	}
+	cfp = rb_vm_get_binding_creatable_next_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
+    }
+
+    bindval = rb_binding_alloc(rb_cBinding);
+    GetBindingPtr(bindval, bind);
+    bind->env = envval;
+    bind->path = ruby_level_cfp->iseq->location.path;
+    bind->blockprocval = blockprocval;
+    bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
+
+    return bindval;
+}
+
 VALUE *
 rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
 {
@@ -699,6 +732,7 @@ rb_binding_add_dynavars(rb_binding_t *bi https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm.c#L732
     NODE *node = 0;
     ID minibuf[4], *dyns = minibuf;
     VALUE idtmp = 0;
+    VALUE blockprocval = 0;
 
     if (dyncount < 0) return 0;
 
@@ -719,7 +753,8 @@ rb_binding_add_dynavars(rb_binding_t *bi https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm.c#L753
     ALLOCV_END(idtmp);
 
     vm_set_eval_stack(th, iseqval, 0, base_block);
-    bind->env = rb_vm_make_env_object(th, th->cfp);
+    bind->env = vm_make_env_object(th, th->cfp, &blockprocval);
+    bind->blockprocval = blockprocval;
     vm_pop_frame(th);
     GetEnvPtr(bind->env, env);
 
Index: ruby_2_1/version.h
===================================================================
--- ruby_2_1/version.h	(revision 48003)
+++ ruby_2_1/version.h	(revision 48004)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1
 #define RUBY_VERSION "2.1.4"
 #define RUBY_RELEASE_DATE "2014-10-19"
-#define RUBY_PATCHLEVEL 260
+#define RUBY_PATCHLEVEL 261
 
 #define RUBY_RELEASE_YEAR 2014
 #define RUBY_RELEASE_MONTH 10
Index: ruby_2_1/test/ruby/test_eval.rb
===================================================================
--- ruby_2_1/test/ruby/test_eval.rb	(revision 48003)
+++ ruby_2_1/test/ruby/test_eval.rb	(revision 48004)
@@ -484,4 +484,19 @@ class TestEval < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_eval.rb#L484
 
     assert_same a, b
   end
+
+  def test_gced_binding_block
+    assert_normal_exit %q{
+      def m
+        binding
+      end
+      GC.stress = true
+      b = nil
+      tap do
+        b = m {}
+      end
+      0.times.to_a
+      b.eval('yield')
+    }, '[Bug #10368]'
+  end
 end

Property changes on: ruby_2_1
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r48000


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

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