diff options
| -rw-r--r-- | test/ruby/test_yjit.rb | 41 | ||||
| -rw-r--r-- | yjit/src/codegen.rs | 4 |
2 files changed, 43 insertions, 2 deletions
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index 3ab04f6fe9..7f0f691320 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -1155,6 +1155,47 @@ class TestYJIT < Test::Unit::TestCase RUBY end + def test_return_to_invalidated_block + # [Bug #19463] + assert_compiles(<<~RUBY, result: [1, 1, :ugokanai]) + klass = Class.new do + def self.lookup(hash, key) = hash[key] + + def self.foo(a, b) = [] + + def self.test(hash, key) + [lookup(hash, key), key, "".freeze] + # 05 opt_send_without_block :lookup + # 07 getlocal_WC_0 :hash + # 09 opt_str_freeze "" + # 12 newarray 3 + # 14 leave + # + # YJIT will put instructions (07..14) into a block. + # When String#freeze is redefined from within lookup(), + # the return address to the block is still on-stack. We rely + # on invalidation patching the code at the return address + # to service this situation correctly. + end + end + + # get YJIT to compile test() + hash = { 1 => [] } + 31.times { klass.test(hash, 1) } + + # inject invalidation into lookup() + evil_hash = Hash.new do |_, key| + class String + undef :freeze + def freeze = :ugokanai + end + + key + end + klass.test(evil_hash, 1) + RUBY + end + private def code_gc_helpers diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index da87104ef6..e4cfe16e73 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -489,8 +489,8 @@ pub fn jit_ensure_block_entry_exit(jit: &mut JITState, ocb: &mut OutlinedCb) { // Generate the exit with the cache in jitstate. block.entry_exit = Some(get_side_exit(jit, ocb, &block_ctx).unwrap_code_ptr()); } else { - let _pc = unsafe { rb_iseq_pc_at_idx(blockid.iseq, blockid.idx) }; - block.entry_exit = Some(gen_outlined_exit(jit.pc, &block_ctx, ocb)); + let block_entry_pc = unsafe { rb_iseq_pc_at_idx(blockid.iseq, blockid.idx) }; + block.entry_exit = Some(gen_outlined_exit(block_entry_pc, &block_ctx, ocb)); } } |
