Project

General

Profile

Bug #22074 ยป yjit_many_locals_simple_repro.rb

Script to reproduce the locals issue - ibrahima (Ibrahim Awwal), 05/19/2026 10:06 PM

 
# frozen_string_literal: true

# Minimal generated-code repro for the YJIT local-register mapping bug.
#
# Run with:
#
# ruby --yjit /workspace/yjit_many_locals_simple_repro.rb
#
# The method generated below has 257 locals:
#
# total
# y0, x0, y1, x1, ... y127, x127
#
# On buggy YJIT builds, x127's local index wraps onto total's register mapping.
# The final `total += 1` then reads an Object instead of 0 and fails.

source = +"def many_locals\n"
source << " total = 0\n"

128.times do |i|
source << " y#{i} = 1\n"
source << " x#{i} = Object.new\n"
end

source << " total += 1\n"
source << " total\n"
source << "end\n"

eval(source, TOPLEVEL_BINDING, __FILE__, 1)

iterations = Integer(ENV.fetch("ITERATIONS", "100000"))

puts "ruby=#{RUBY_DESCRIPTION}"
puts "yjit=#{RubyVM::YJIT.enabled? if defined?(RubyVM::YJIT)}"
puts "iterations=#{iterations}"

unless defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
warn "YJIT is not enabled. Re-run with: ruby --yjit #{__FILE__}"
end

iterations.times do |i|
result = many_locals
raise "wrong result: #{result.inspect}" unless result == 1
puts "iteration=#{i + 1}" if ((i + 1) % 10_000).zero?
rescue Exception => e # rubocop:disable Lint/RescueException
warn "failed_at=#{i + 1}"
warn e.full_message(highlight: false, order: :top)
raise
end

puts "ok iterations=#{iterations}"
    (1-1/1)