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

ruby-changes:70286

From: John <ko1@a...>
Date: Sat, 18 Dec 2021 08:26:16 +0900 (JST)
Subject: [ruby-changes:70286] c2197bf821 (master): YJIT: Fix check for required kwargs

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

From c2197bf82171ca2dad6f7ef67521fdd30a245d9c Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Thu, 16 Dec 2021 15:08:07 -0800
Subject: YJIT: Fix check for required kwargs

Previously, YJIT would not check that all the required keywords were
specified in the case that there were optional arguments specified. In
this case YJIT would incorrectly call the method with invalid arguments.
---
 bootstraptest/test_yjit.rb |  8 ++++++++
 yjit_codegen.c             | 13 +++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 501f00d5b34..05947c48ed2 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -2234,6 +2234,14 @@ assert_equal '[:ok]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L2234
   5.times.map { kwargs() rescue :ok }.uniq
 }
 
+assert_equal '[:ok]', %q{
+  def kwargs(a:, b: nil)
+    value
+  end
+
+  5.times.map { kwargs(b: 123) rescue :ok }.uniq
+}
+
 assert_equal '[[1, 2]]', %q{
   def kwargs(left:, right:)
     [left, right]
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 3782d8eea37..b18ec44c7a3 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -3562,6 +3562,8 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3562
         // keyword parameters.
         const struct rb_iseq_param_keyword *keyword = iseq->body->param.keyword;
 
+        int required_kwargs_filled = 0;
+
         if (keyword->num > 30) {
             // We have so many keywords that (1 << num) encoded as a FIXNUM
             // (which shifts it left one more) no longer fits inside a 32-bit
@@ -3604,9 +3606,16 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3606
                     GEN_COUNTER_INC(cb, send_iseq_kwargs_mismatch);
                     return YJIT_CANT_COMPILE;
                 }
+
+                // Keep a count to ensure all required kwargs are specified
+                if (callee_idx < keyword->required_num) {
+                    required_kwargs_filled++;
+                }
             }
-        } else if (keyword->required_num != 0) {
-            // No keywords provided so if any are required this is a mismatch
+        }
+
+        RUBY_ASSERT(required_kwargs_filled <= keyword->required_num);
+        if (required_kwargs_filled != keyword->required_num) {
             GEN_COUNTER_INC(cb, send_iseq_kwargs_mismatch);
             return YJIT_CANT_COMPILE;
         }
-- 
cgit v1.2.1


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

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