Skip to content

Commit

Permalink
YJIT: Side exit if splat exceeds max stack size we track
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmyhmiller authored and jeremyevans committed Apr 24, 2023
1 parent fcc106b commit f77f0cf
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 0 deletions.
16 changes: 16 additions & 0 deletions bootstraptest/test_yjit.rb
Expand Up @@ -3947,3 +3947,19 @@ def calling_my_func
calling_my_func
}

# Fix failed case for large splat
assert_equal 'true', %q{
def d(a, b=:b)
end
def calling_func
ary = 1380888.times;
d(*ary)
end
begin
calling_func
rescue ArgumentError
true
end
}
6 changes: 6 additions & 0 deletions yjit/src/codegen.rs
Expand Up @@ -1896,6 +1896,8 @@ pub const SEND_MAX_CHAIN_DEPTH: i32 = 20;
// up to 20 different offsets for case-when
pub const CASE_WHEN_MAX_DEPTH: i32 = 20;

pub const MAX_SPLAT_LENGTH: i32 = 127;

// Codegen for setting an instance variable.
// Preconditions:
// - receiver is in REG0
Expand Down Expand Up @@ -5875,6 +5877,10 @@ fn gen_send_iseq(
// all the remaining arguments. In the generated code
// we test if this is true and if not side exit.
argc = argc - 1 + array_length as i32 + remaining_opt as i32;
if argc + asm.ctx.get_stack_size() as i32 > MAX_SPLAT_LENGTH {
gen_counter_incr!(asm, send_splat_too_long);
return None;
}
push_splat_args(array_length, asm);

for _ in 0..remaining_opt {
Expand Down
1 change: 1 addition & 0 deletions yjit/src/stats.rs
Expand Up @@ -261,6 +261,7 @@ make_counters! {
send_args_splat_cfunc_zuper,
send_args_splat_cfunc_ruby2_keywords,
send_iseq_splat_arity_error,
send_splat_too_long,
send_iseq_ruby2_keywords,
send_send_not_imm,
send_send_wrong_args,
Expand Down

0 comments on commit f77f0cf

Please sign in to comment.