ruby-changes:69245
From: Aaron <ko1@a...>
Date: Thu, 21 Oct 2021 08:24:20 +0900 (JST)
Subject: [ruby-changes:69245] 640b162b51 (master): Exit when the object is frozen
https://git.ruby-lang.org/ruby.git/commit/?id=640b162b51 From 640b162b51a704d890c44af9c76fffa4eaf28ca9 Mon Sep 17 00:00:00 2001 From: Aaron Patterson <tenderlove@r...> Date: Fri, 3 Sep 2021 16:06:32 -0700 Subject: Exit when the object is frozen Exit when the object is frozen, also add tests --- bootstraptest/test_yjit.rb | 22 ++++++++++++++++++++++ test/ruby/test_yjit.rb | 14 ++++++++++++++ yjit_codegen.c | 5 +++++ 3 files changed, 41 insertions(+) diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 96141e315c..866d7e2558 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1,3 +1,25 @@ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L1 +# Check that frozen objects are respected +assert_equal 'great', %q{ + class Foo + attr_accessor :bar + def initialize + @bar = 1 + freeze + end + end + + foo = Foo.new + + 5.times do + begin + foo.bar = 2 + rescue FrozenError + end + end + + foo.bar == 1 ? "great" : "NG" +} + # Check that global variable set works assert_equal 'string', %q{ def foo diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index 587e6d3f1d..90940009e2 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -75,6 +75,20 @@ class TestYJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_yjit.rb#L75 assert_no_exits('"i am a string #{true}"') end + def test_compile_attr_set + assert_no_exits(<<~EORB) + class Foo + attr_accessor :bar + end + + foo = Foo.new + foo.bar = 3 + foo.bar = 3 + foo.bar = 3 + foo.bar = 3 + EORB + end + def test_compile_regexp assert_no_exits('/#{true}/') end diff --git a/yjit_codegen.c b/yjit_codegen.c index 2d31fd03de..c0734fddaf 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -1447,6 +1447,11 @@ gen_set_ivar(jitstate_t *jit, ctx_t *ctx, const int max_chain_depth, VALUE compt https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1447 VALUE comptime_val_klass = CLASS_OF(comptime_receiver); const ctx_t starting_context = *ctx; // make a copy for use with jit_chain_guard + ADD_COMMENT(cb, "guard self is not frozen"); + x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags); + test(cb, flags_opnd, imm_opnd(RUBY_FL_FREEZE)); + jnz_ptr(cb, COUNTED_EXIT(side_exit, setivar_frozen)); + // If the class uses the default allocator, instances should all be T_OBJECT // NOTE: This assumes nobody changes the allocator of the class after allocation. // Eventually, we can encode whether an object is T_OBJECT or not -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/