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]
This commit is contained in:
parent
61da90c1b8
commit
bbd249e351
@ -11,6 +11,13 @@ assert_normal_exit %q{
|
||||
call_foo
|
||||
}
|
||||
|
||||
# regression test for keyword splat with yield
|
||||
assert_equal 'nil', %q{
|
||||
def splat_kw(kwargs) = yield(**kwargs)
|
||||
|
||||
splat_kw({}) { _1 }.inspect
|
||||
}
|
||||
|
||||
# regression test for arity check with splat
|
||||
assert_equal '[:ae, :ae]', %q{
|
||||
def req_one(a_, b_ = 1) = raise
|
||||
|
@ -6131,6 +6131,7 @@ fn gen_send_iseq(
|
||||
exit_if_tail_call(asm, ci)?;
|
||||
exit_if_has_post(asm, iseq)?;
|
||||
exit_if_has_kwrest(asm, iseq)?;
|
||||
exit_if_kw_splat(asm, flags)?;
|
||||
exit_if_splat_and_ruby2_keywords(asm, jit, flags)?;
|
||||
exit_if_has_rest_and_captured(asm, iseq_has_rest, captured_opnd)?;
|
||||
exit_if_has_rest_and_supplying_kws(asm, iseq_has_rest, iseq, supplying_kws)?;
|
||||
@ -6261,6 +6262,9 @@ fn gen_send_iseq(
|
||||
let array = jit.peek_at_stack(&asm.ctx, if block_arg { 1 } else { 0 }) ;
|
||||
let array_length = if array == Qnil {
|
||||
0
|
||||
} else if unsafe { !RB_TYPE_P(array, RUBY_T_ARRAY) } {
|
||||
gen_counter_incr(asm, Counter::send_iseq_splat_not_array);
|
||||
return None;
|
||||
} else {
|
||||
unsafe { rb_yjit_array_len(array) as u32}
|
||||
};
|
||||
@ -6939,6 +6943,11 @@ fn exit_if_has_kwrest(asm: &mut Assembler, iseq: *const rb_iseq_t) -> Option<()>
|
||||
exit_if(asm, unsafe { get_iseq_flags_has_kwrest(iseq) }, Counter::send_iseq_has_kwrest)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn exit_if_kw_splat(asm: &mut Assembler, flags: u32) -> Option<()> {
|
||||
exit_if(asm, flags & VM_CALL_KW_SPLAT != 0, Counter::send_iseq_kw_splat)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn exit_if_splat_and_ruby2_keywords(asm: &mut Assembler, jit: &mut JITState, flags: u32) -> Option<()> {
|
||||
// In order to handle backwards compatibility between ruby 3 and 2
|
||||
|
@ -333,6 +333,7 @@ make_counters! {
|
||||
send_iseq_clobbering_block_arg,
|
||||
send_iseq_leaf_builtin_block_arg_block_param,
|
||||
send_iseq_only_keywords,
|
||||
send_iseq_kw_splat,
|
||||
send_iseq_kwargs_req_and_opt_missing,
|
||||
send_iseq_kwargs_mismatch,
|
||||
send_iseq_has_post,
|
||||
@ -340,6 +341,7 @@ make_counters! {
|
||||
send_iseq_has_no_kw,
|
||||
send_iseq_accepts_no_kwarg,
|
||||
send_iseq_materialized_block,
|
||||
send_iseq_splat_not_array,
|
||||
send_iseq_splat_with_opt,
|
||||
send_iseq_splat_with_kw,
|
||||
send_iseq_missing_optional_kw,
|
||||
|
Loading…
x
Reference in New Issue
Block a user