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

ruby-changes:57748

From: Takashi <ko1@a...>
Date: Sat, 14 Sep 2019 21:39:41 +0900 (JST)
Subject: [ruby-changes:57748] 8263459627 (master): Keep the reference of imemo while argv may be used

https://git.ruby-lang.org/ruby.git/commit/?id=8263459627

From 8263459627b20d4383978b3d1471298bf52bde05 Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Sat, 14 Sep 2019 21:36:41 +0900
Subject: Keep the reference of imemo while argv may be used

To prevent the `v` reference from being eliminated before argv is used,
calling `rb_free_tmp_buffer` against `v` explicitly.

diff --git a/vm_eval.c b/vm_eval.c
index f128e8d..b5d6dcc 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -235,25 +235,27 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L235
     return ret;
 }
 
-static void
+/* Caller should keep the reference to the return value until argv becomes useless. */
+static VALUE
 add_empty_keyword(int *argc, const VALUE **argv, int *kw_splat)
 {
     if (*kw_splat == RB_PASS_CALLED_KEYWORDS || *kw_splat == RB_PASS_EMPTY_KEYWORDS) {
         if (*kw_splat == RB_PASS_EMPTY_KEYWORDS || rb_empty_keyword_given_p()) {
             int n = *argc;
             VALUE v;
-            VALUE *ptr;
-            ptr = rb_alloc_tmp_buffer2(&v, n+1, sizeof(VALUE));
+            VALUE *ptr = rb_alloc_tmp_buffer2(&v, n+1, sizeof(VALUE));
             memcpy(ptr, *argv, sizeof(VALUE)*n);
             ptr[n] = rb_hash_new();
             *argc = ++n;
             *argv = ptr;
             *kw_splat = 1;
+            return v;
         }
         else {
             *kw_splat = rb_keyword_given_p();
         }
     }
+    return 0;
 }
 
 VALUE
@@ -265,8 +267,10 @@ rb_vm_call(rb_execution_context_t *ec, VALUE recv, VALUE id, int argc, const VAL https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L267
 VALUE
 rb_vm_call_kw(rb_execution_context_t *ec, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me, int kw_splat)
 {
-    add_empty_keyword(&argc, &argv, &kw_splat);
-    return rb_vm_call0(ec, recv, id, argc, argv, me, kw_splat);
+    VALUE v = add_empty_keyword(&argc, &argv, &kw_splat);
+    VALUE ret = rb_vm_call0(ec, recv, id, argc, argv, me, kw_splat);
+    rb_free_tmp_buffer(&v);
+    return ret;
 }
 
 static inline VALUE
@@ -291,8 +295,10 @@ vm_call_super(rb_execution_context_t *ec, int argc, const VALUE *argv, int kw_sp https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L295
 	return method_missing(recv, id, argc, argv, MISSING_SUPER);
     }
     else {
-        add_empty_keyword(&argc, &argv, &kw_splat);
-        return rb_vm_call0(ec, recv, id, argc, argv, me, kw_splat);
+        VALUE v = add_empty_keyword(&argc, &argv, &kw_splat);
+        VALUE ret = rb_vm_call0(ec, recv, id, argc, argv, me, kw_splat);
+        rb_free_tmp_buffer(&v);
+        return ret;
     }
 }
 
@@ -940,8 +946,10 @@ rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L946
 VALUE
 rb_funcallv_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
 {
-    add_empty_keyword(&argc, &argv, &kw_splat);
-    return rb_call(recv, mid, argc, argv, kw_splat ? CALL_FCALL_KW : CALL_FCALL);
+    VALUE v = add_empty_keyword(&argc, &argv, &kw_splat);
+    VALUE ret = rb_call(recv, mid, argc, argv, kw_splat ? CALL_FCALL_KW : CALL_FCALL);
+    rb_free_tmp_buffer(&v);
+    return ret;
 }
 
 /*!
@@ -1008,8 +1016,10 @@ rb_funcall_with_block_kw(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1016
         vm_passed_block_handler_set(GET_EC(), passed_procval);
     }
 
-    add_empty_keyword(&argc, &argv, &kw_splat);
-    return rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
+    VALUE v = add_empty_keyword(&argc, &argv, &kw_splat);
+    VALUE ret = rb_call(recv, mid, argc, argv, kw_splat ? CALL_PUBLIC_KW : CALL_PUBLIC);
+    rb_free_tmp_buffer(&v);
+    return ret;
 }
 
 static VALUE *
@@ -1373,13 +1383,15 @@ rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE * argv, https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1383
 {
     struct iter_method_arg arg;
 
-    add_empty_keyword(&argc, &argv, &kw_splat);
+    VALUE v = add_empty_keyword(&argc, &argv, &kw_splat);
     arg.obj = obj;
     arg.mid = mid;
     arg.argc = argc;
     arg.argv = argv;
     arg.kw_splat = kw_splat;
-    return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
+    VALUE ret = rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);
+    rb_free_tmp_buffer(&v);
+    return ret;
 }
 
 VALUE
-- 
cgit v0.10.2


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

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