summaryrefslogtreecommitdiff
path: root/yjit/src
diff options
context:
space:
mode:
authorNARUSE, Yui <nurse@users.noreply.github.com>2024-05-29 06:52:47 +0900
committerGitHub <noreply@github.com>2024-05-28 14:52:47 -0700
commit93d7bf5c5c635567fa519affdfd54edeb9064834 (patch)
treea6c569ac9fef1b27eae07c22a29c31252d4c5aed /yjit/src
parentf18ba2c6c6a9b2a74a8c2d655ab42947edb1fc6a (diff)
merge revision(s) bbd249e351af7e4929b518a5de73a832b5617273: [Backport #20192] (#10249)
* merge revision(s) bbd249e351af7e4929b518a5de73a832b5617273: [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] * Skip a new test for RJIT
Diffstat (limited to 'yjit/src')
-rw-r--r--yjit/src/codegen.rs9
-rw-r--r--yjit/src/stats.rs2
2 files changed, 11 insertions, 0 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 75986dedb1..df98fcdf08 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -6009,6 +6009,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)?;
@@ -6139,6 +6140,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}
};
@@ -6821,6 +6825,11 @@ fn exit_if_has_kwrest(asm: &mut Assembler, iseq: *const rb_iseq_t) -> Option<()>
}
#[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
// ruby2_keywords was introduced. It is called only on methods
diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs
index dcaa9af2b5..eab3db010f 100644
--- a/yjit/src/stats.rs
+++ b/yjit/src/stats.rs
@@ -331,6 +331,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,
@@ -338,6 +339,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,