mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 20:19:19 +00:00
YJIT: Add frozen guard for struct aset (#15835)
We used to just skip this check (oops), but we should not allow modifying frozen objects.
This commit is contained in:
parent
51ab7b0405
commit
e08f316f28
Notes:
git
2026-01-09 19:26:17 +00:00
Merged-By: tekknolagi <donotemailthisaddress@bernsteinbear.com>
@ -657,6 +657,26 @@ class TestYJIT < Test::Unit::TestCase
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_struct_aset_guards_recv_is_not_frozen
|
||||
assert_compiles(<<~RUBY, result: :ok, exits: { opt_send_without_block: 1 })
|
||||
def foo(obj)
|
||||
obj.foo = 123
|
||||
end
|
||||
|
||||
Foo = Struct.new(:foo)
|
||||
obj = Foo.new(123)
|
||||
100.times do
|
||||
foo(obj)
|
||||
end
|
||||
obj.freeze
|
||||
begin
|
||||
foo(obj)
|
||||
rescue FrozenError
|
||||
:ok
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_getblockparam
|
||||
assert_compiles(<<~'RUBY', insns: [:getblockparam])
|
||||
def foo &blk
|
||||
|
||||
@ -8973,6 +8973,17 @@ fn gen_struct_aset(
|
||||
assert!(unsafe { RB_TYPE_P(comptime_recv, RUBY_T_STRUCT) });
|
||||
assert!((off as i64) < unsafe { RSTRUCT_LEN(comptime_recv) });
|
||||
|
||||
// Even if the comptime recv was not frozen, future recv may be. So we need to emit a guard
|
||||
// that the recv is not frozen.
|
||||
// We know all structs are heap objects, so we can check the flag directly.
|
||||
let recv = asm.stack_opnd(1);
|
||||
let recv = asm.load(recv);
|
||||
let flags = asm.load(Opnd::mem(VALUE_BITS, recv, RUBY_OFFSET_RBASIC_FLAGS));
|
||||
asm.test(flags, (RUBY_FL_FREEZE as u64).into());
|
||||
asm.jnz(Target::side_exit(Counter::opt_aset_frozen));
|
||||
|
||||
// Not frozen, so we can proceed.
|
||||
|
||||
asm_comment!(asm, "struct aset");
|
||||
|
||||
let val = asm.stack_pop(1);
|
||||
|
||||
@ -489,6 +489,7 @@ make_counters! {
|
||||
opt_aset_not_array,
|
||||
opt_aset_not_fixnum,
|
||||
opt_aset_not_hash,
|
||||
opt_aset_frozen,
|
||||
|
||||
opt_case_dispatch_megamorphic,
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user