mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 20:19:19 +00:00
YJIT: Bail out if proc would be stored above stack top
Fixes [Bug #21266].
This commit is contained in:
parent
f3b9509b52
commit
9168cad4d6
Notes:
git
2025-12-16 04:05:55 +00:00
@ -4889,6 +4889,16 @@ assert_equal '[:ok, :ok, :ok, :ok, :ok]', %q{
|
||||
tests
|
||||
}
|
||||
|
||||
# regression test for splat with &proc{} when the target has rest (Bug #21266)
|
||||
assert_equal '[]', %q{
|
||||
def foo(args) = bar(*args, &proc { _1 })
|
||||
def bar(_, _, _, _, *rest) = yield rest
|
||||
|
||||
GC.stress = true
|
||||
foo([1,2,3,4])
|
||||
foo([1,2,3,4])
|
||||
}
|
||||
|
||||
# regression test for invalidating an empty block
|
||||
assert_equal '0', %q{
|
||||
def foo = (* = 1).pred
|
||||
|
||||
@ -1772,6 +1772,18 @@ class TestYJIT < Test::Unit::TestCase
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_proc_block_with_kwrest
|
||||
# When the bug was present this required --yjit-stats to trigger.
|
||||
assert_compiles(<<~RUBY, result: {extra: 5})
|
||||
def foo = bar(w: 1, x: 2, y: 3, z: 4, extra: 5, &proc { _1 })
|
||||
def bar(w:, x:, y:, z:, **kwrest) = yield kwrest
|
||||
|
||||
GC.stress = true
|
||||
foo
|
||||
foo
|
||||
RUBY
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def code_gc_helpers
|
||||
|
||||
@ -7896,6 +7896,11 @@ fn gen_send_iseq(
|
||||
gen_counter_incr(jit, asm, Counter::send_iseq_clobbering_block_arg);
|
||||
return None;
|
||||
}
|
||||
if iseq_has_rest || has_kwrest {
|
||||
// The proc would be stored above the current stack top, where GC can't see it
|
||||
gen_counter_incr(jit, asm, Counter::send_iseq_block_arg_gc_unsafe);
|
||||
return None;
|
||||
}
|
||||
let proc = asm.stack_pop(1); // Pop first, as argc doesn't account for the block arg
|
||||
let callee_specval = asm.ctx.sp_opnd(callee_specval);
|
||||
asm.store(callee_specval, proc);
|
||||
|
||||
@ -354,6 +354,7 @@ make_counters! {
|
||||
send_iseq_arity_error,
|
||||
send_iseq_block_arg_type,
|
||||
send_iseq_clobbering_block_arg,
|
||||
send_iseq_block_arg_gc_unsafe,
|
||||
send_iseq_complex_discard_extras,
|
||||
send_iseq_leaf_builtin_block_arg_block_param,
|
||||
send_iseq_kw_splat_non_nil,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user