YJIT: Fix false assumption that String#+@ => ::String

Could return a subclass.

[Bug #19444]
This commit is contained in:
Alan Wu 2023-02-16 17:41:52 -05:00
Родитель c178926fbe
Коммит a4b7ec1229
2 изменённых файлов: 24 добавлений и 3 удалений

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

@ -1119,6 +1119,23 @@ class TestYJIT < Test::Unit::TestCase
RUBY RUBY
end end
def test_str_uplus_subclass
assert_compiles(<<~RUBY, frozen_string_literal: true, result: :subclass)
class S < String
def encoding
:subclass
end
end
def test(str)
(+str).encoding
end
test ""
test S.new
RUBY
end
private private
def code_gc_helpers def code_gc_helpers

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

@ -4164,10 +4164,14 @@ fn jit_rb_str_uplus(
_ci: *const rb_callinfo, _ci: *const rb_callinfo,
_cme: *const rb_callable_method_entry_t, _cme: *const rb_callable_method_entry_t,
_block: Option<IseqPtr>, _block: Option<IseqPtr>,
_argc: i32, argc: i32,
_known_recv_class: *const VALUE, _known_recv_class: *const VALUE,
) -> bool ) -> bool
{ {
if argc != 0 {
return false;
}
// We allocate when we dup the string // We allocate when we dup the string
jit_prepare_routine_call(jit, ctx, asm); jit_prepare_routine_call(jit, ctx, asm);
@ -4178,8 +4182,8 @@ fn jit_rb_str_uplus(
let ret_label = asm.new_label("stack_ret"); let ret_label = asm.new_label("stack_ret");
// We guard for the receiver being a ::String, so the return value is too // String#+@ can only exist on T_STRING
let stack_ret = ctx.stack_push(Type::CString); let stack_ret = ctx.stack_push(Type::TString);
// If the string isn't frozen, we just return it. // If the string isn't frozen, we just return it.
asm.mov(stack_ret, recv_opnd); asm.mov(stack_ret, recv_opnd);