All the method call types need to handle argument shifting in case they're
called by `.send`, and we weren't handling that in `OPTIMIZED_METHOD_TYPE_CALL`.

Lack of shifting caused the stack size assertion in gen_leave() to fail.

Discovered by Rails CI: https://buildkite.com/rails/rails/builds/91705#018516c4-f8f8-469e-bc2d-ddeb25ca8317/1920-2067
Diagnosed with help from `@eileencodes` and `@k0kubun`.
This commit is contained in:
Alan Wu 2022-12-15 18:10:28 -05:00 коммит произвёл GitHub
Родитель e9ba3042e1
Коммит 14158f1f8c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 12 добавлений и 1 удалений

Просмотреть файл

@ -1022,6 +1022,12 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
def test_send_to_call
assert_compiles(<<~'RUBY', result: :ok)
->{ :ok }.send(:call)
RUBY
end
private
def code_gc_helpers

Просмотреть файл

@ -5938,6 +5938,11 @@ fn gen_send_general(
return CantCompile;
}
// If this is a .send call we need to adjust the stack
if flags & VM_CALL_OPT_SEND != 0 {
handle_opt_send_shift_stack(asm, argc as i32, ctx);
}
// About to reset the SP, need to load this here
let recv_load = asm.load(recv);
@ -6309,7 +6314,7 @@ fn gen_leave(
ocb: &mut OutlinedCb,
) -> CodegenStatus {
// Only the return value should be on the stack
assert!(ctx.get_stack_size() == 1);
assert_eq!(1, ctx.get_stack_size());
// Create a side-exit to fall back to the interpreter
let side_exit = get_side_exit(jit, ocb, ctx);