YJIT: Fallback setivar if the receiver isn't T_OBJECT (#8160)

Followup: https://github.com/ruby/ruby/pull/8152

If the receiver is a T_MODULE or T_CLASS and has a lot of
ivars, `get_next_shape_internal` will return `NULL`.

Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
This commit is contained in:
Jean byroot Boussier 2023-08-02 17:33:12 +02:00 коммит произвёл GitHub
Родитель 3c41a04b6c
Коммит e20f1e443f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 24 добавлений и 1 удалений

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

@ -1238,6 +1238,29 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
def test_setivar_on_class
# Bug in https://github.com/ruby/ruby/pull/8152
assert_compiles(<<~RUBY, result: :ok)
class Base
def self.or_equal
@or_equal ||= Object.new
end
end
Base.or_equal # ensure compiled
class Child < Base
end
200.times do |iv| # Need to be more than MAX_IVAR
Child.instance_variable_set("@_iv_\#{iv}", Object.new)
end
Child.or_equal
:ok
RUBY
end
def test_nested_send
#[Bug #19464]
assert_compiles(<<~RUBY, result: [:ok, :ok])

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

@ -2204,7 +2204,7 @@ fn gen_setinstancevariable(
};
// Get the next shape information if it needs transition
let new_shape = if !shape_too_complex && ivar_index.is_none() {
let new_shape = if !shape_too_complex && receiver_t_object && ivar_index.is_none() {
let shape = comptime_receiver.shape_of();
let current_capacity = unsafe { (*shape).capacity };