summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_yjit.rb8
-rw-r--r--yjit_codegen.c13
2 files changed, 19 insertions, 2 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 501f00d5b3..05947c48ed 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -2234,6 +2234,14 @@ assert_equal '[:ok]', %q{
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 3782d8eea3..b18ec44c7a 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
// 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
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;
}