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

ruby-changes:47387

From: nagachika <ko1@a...>
Date: Sat, 5 Aug 2017 00:06:29 +0900 (JST)
Subject: [ruby-changes:47387] nagachika:r59503 (ruby_2_4): merge revision(s) 59063: [Backport #13605]

nagachika	2017-08-05 00:06:22 +0900 (Sat, 05 Aug 2017)

  New Revision: 59503

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

  Log:
    merge revision(s) 59063: [Backport #13605]
    
    
    * proc.c (get_local_variable_ptr): return found env ptr. Returned env
      will be used by write barrier at `bind_local_variable_set()'.
      [Bug #13605]
    
    * test/ruby/test_proc.rb: add a test for this issue.

  Modified directories:
    branches/ruby_2_4/
  Modified files:
    branches/ruby_2_4/proc.c
    branches/ruby_2_4/test/ruby/test_proc.rb
    branches/ruby_2_4/version.h
Index: ruby_2_4/proc.c
===================================================================
--- ruby_2_4/proc.c	(revision 59502)
+++ ruby_2_4/proc.c	(revision 59503)
@@ -392,8 +392,9 @@ bind_eval(int argc, VALUE *argv, VALUE b https://github.com/ruby/ruby/blob/trunk/ruby_2_4/proc.c#L392
 }
 
 static const VALUE *
-get_local_variable_ptr(const rb_env_t *env, ID lid)
+get_local_variable_ptr(const rb_env_t **envp, ID lid)
 {
+    const rb_env_t *env = *envp;
     do {
 	if (!VM_ENV_FLAGS(env->ep, VM_FRAME_FLAG_CFRAME)) {
 	    const rb_iseq_t *iseq = env->iseq;
@@ -403,15 +404,18 @@ get_local_variable_ptr(const rb_env_t *e https://github.com/ruby/ruby/blob/trunk/ruby_2_4/proc.c#L404
 
 	    for (i=0; i<iseq->body->local_table_size; i++) {
 		if (iseq->body->local_table[i] == lid) {
+		    *envp = env;
 		    return &env->env[i];
 		}
 	    }
 	}
 	else {
+	    *envp = NULL;
 	    return NULL;
 	}
     } while ((env = rb_vm_env_prev_env(env)) != NULL);
 
+    *envp = NULL;
     return NULL;
 }
 
@@ -494,12 +498,14 @@ bind_local_variable_get(VALUE bindval, V https://github.com/ruby/ruby/blob/trunk/ruby_2_4/proc.c#L498
     ID lid = check_local_id(bindval, &sym);
     const rb_binding_t *bind;
     const VALUE *ptr;
+    const rb_env_t *env;
 
     if (!lid) goto undefined;
 
     GetBindingPtr(bindval, bind);
 
-    if ((ptr = get_local_variable_ptr(VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block)), lid)) == NULL) {
+    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
+    if ((ptr = get_local_variable_ptr(&env, lid)) == NULL) {
 	sym = ID2SYM(lid);
       undefined:
 	rb_name_err_raise("local variable `%1$s' not defined for %2$s",
@@ -546,7 +552,7 @@ bind_local_variable_set(VALUE bindval, V https://github.com/ruby/ruby/blob/trunk/ruby_2_4/proc.c#L552
 
     GetBindingPtr(bindval, bind);
     env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
-    if ((ptr = get_local_variable_ptr(env, lid)) == NULL) {
+    if ((ptr = get_local_variable_ptr(&env, lid)) == NULL) {
 	/* not found. create new env */
 	ptr = rb_binding_add_dynavars(bind, 1, &lid);
 	env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
@@ -579,11 +585,13 @@ bind_local_variable_defined_p(VALUE bind https://github.com/ruby/ruby/blob/trunk/ruby_2_4/proc.c#L585
 {
     ID lid = check_local_id(bindval, &sym);
     const rb_binding_t *bind;
+    const rb_env_t *env;
 
     if (!lid) return Qfalse;
 
     GetBindingPtr(bindval, bind);
-    return get_local_variable_ptr(VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block)), lid) ? Qtrue : Qfalse;
+    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
+    return get_local_variable_ptr(&env, lid) ? Qtrue : Qfalse;
 }
 
 /*
Index: ruby_2_4/version.h
===================================================================
--- ruby_2_4/version.h	(revision 59502)
+++ ruby_2_4/version.h	(revision 59503)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/version.h#L1
 #define RUBY_VERSION "2.4.2"
 #define RUBY_RELEASE_DATE "2017-08-04"
-#define RUBY_PATCHLEVEL 169
+#define RUBY_PATCHLEVEL 170
 
 #define RUBY_RELEASE_YEAR 2017
 #define RUBY_RELEASE_MONTH 8
Index: ruby_2_4/test/ruby/test_proc.rb
===================================================================
--- ruby_2_4/test/ruby/test_proc.rb	(revision 59502)
+++ ruby_2_4/test/ruby/test_proc.rb	(revision 59503)
@@ -1322,6 +1322,20 @@ class TestProc < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/ruby/test_proc.rb#L1322
     assert_equal(20, b.eval("b"))
   end
 
+  def test_local_variable_set_wb
+    assert_ruby_status([], <<-'end;', '[Bug #13605]')
+      b = binding
+      n = 20_000
+
+      n.times do |i|
+        v = rand(2_000)
+        name = "n#{v}"
+        value = Object.new
+        b.local_variable_set name, value
+      end
+    end;
+  end
+
   def test_local_variable_defined?
     b = get_binding
     assert_equal(true, b.local_variable_defined?(:a))
Index: ruby_2_4
===================================================================
--- ruby_2_4	(revision 59502)
+++ ruby_2_4	(revision 59503)

Property changes on: ruby_2_4
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /trunk:r59063

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

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