10000 merge revision(s) bbd249e351af7e4929b518a5de73a832b5617273: [Backport… · ruby/ruby@ed2fbb3 · GitHub
[go: up one dir, main page]

Skip to content

Commit ed2fbb3

Browse files
committed
merge revision(s) bbd249e: [Backport #20192]
YJIT: Properly reject keyword splat with `yield` We don't have support for keyword splat anywhere, but we tried to compile these anyways in case of `invokeblock`. This led to bad things happening such as passing the wrong value and passing a hash into rb_yjit_array_len(), which raised in the middle of compilation. [Bug #20192]
1 parent eb7cb16 commit ed2fbb3

File tree

4 files changed

+19
-1
lines changed

4 files changed

+19
-1
lines changed

bootstraptest/test_yjit.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ def call_foo
1111
call_foo
1212
}
1313

14+
# regression test for keyword splat with yield
15+
assert_equal 'nil', %q{
16+
def splat_kw(kwargs) = yield(**kwargs)
17+
18+
splat_kw({}) { _1 }.inspect
19+
}
20+
1421
# regression test for arity check with splat
1522
assert_equal '[:ae, :ae]', %q{
1623
def req_one(a_, b_ = 1) = raise

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
1212
#define RUBY_VERSION_TEENY 0
1313
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
14-
#define RUBY_PATCHLEVEL 19
14+
#define RUBY_PATCHLEVEL 20
1515

1616
#include "ruby/version.h"
1717
#include "ruby/internal/abi.h"

yjit/src/codegen.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6009,6 +6009,7 @@ fn gen_send_iseq(
60096009
exit_if_tail_call(asm, ci)?;
60106010
exit_if_has_post(asm, iseq)?;
60116011
exit_if_has_kwrest(asm, iseq)?;
6012+
exit_if_kw_splat(asm, flags)?;
60126013
exit_if_splat_and_ruby2_keywords(asm, jit, flags)?;
60136014
exit_if_has_rest_and_captured(asm, iseq_has_rest, captured_opnd)?;
60146015
exit_if_has_rest_and_supplying_kws(asm, iseq_has_rest, iseq, supplying_kws)?;
@@ -6139,6 +6140,9 @@ fn gen_send_iseq(
61396140
let array = jit.peek_at_stack(&asm.ctx, if block_arg { 1 } else { 0 }) ;
61406141
let array_length = if array == Qnil {
61416142
0
6143+
} else if unsafe { !RB_TYPE_P(array, RUBY_T_ARRAY) } {
6144+
gen_counter_incr(asm, Counter::send_iseq_splat_not_array);
6145+
return None;
61426146
} else {
61436147
unsafe { rb_yjit_array_len(array) as u32}
61446148
};
@@ -6820,6 +6824,11 @@ fn exit_if_has_kwrest(asm: &mut Assembler, iseq: *const rb_iseq_t) -> Option<()>
68206824
exit_if(asm, unsafe { get_iseq_flags_has_kwrest(iseq) }, Counter::send_iseq_has_kwrest)
68216825
}
68226826

6827+
#[must_use]
6828+
fn exit_if_kw_splat(asm: &mut Assembler, flags: u32) -> Option<()> {
6829+
exit_if(asm, flags & VM_CALL_KW_SPLAT != 0, Counter::send_iseq_kw_splat)
6830+
}
6831+
68236832
#[must_use]
68246833
fn exit_if_splat_and_ruby2_keywords(asm: &mut Assembler, jit: &mut JITState, flags: u32) -> Option<()> {
68256834
// In order to handle backwards compatibility between ruby 3 and 2

yjit/src/stats.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,13 +331,15 @@ make_counters! {
331331
send_iseq_clobbering_block_arg,
332332
send_iseq_leaf_builtin_block_arg_block_param,
333333
send_iseq_only_keywords,
334+
send_iseq_kw_splat,
334335
send_iseq_kwargs_req_and_opt_missing,
335336
send_iseq_kwargs_mismatch,
336337
send_iseq_has_post,
337338
send_iseq_has_kwrest,
338339
send_iseq_has_no_kw,
339340
send_iseq_accepts_no_kwarg,
340341
send_iseq_materialized_block,
342+
send_iseq_splat_not_array,
341343
send_iseq_splat_with_opt,
342344
send_iseq_splat_with_kw,
343345
send_iseq_missing_optional_kw,

0 commit comments

Comments
 (0)
0