<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/test/ruby, branch v4.0.2</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>merge revision(s) 08372635f7ec09f7115bd254246ebd637499651c: [Backport #21926]</title>
<updated>2026-03-16T18:57:04+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2026-03-16T18:57:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a601b899a35c796775309dca01a6d5e64be14c44'/>
<id>a601b899a35c796775309dca01a6d5e64be14c44</id>
<content type='text'>
	Fix race condition right after ubf registration

	Fixes [Bug #21926]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	Fix race condition right after ubf registration

	Fixes [Bug #21926]
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Fix not reading locals from `cfp-&gt;ep` after `YJIT.enable` and exceptional entry</title>
<updated>2026-03-16T18:03:25+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2026-03-12T22:33:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8466e93b1d6eb85ad5952ab3a10575fa453e77e2'/>
<id>8466e93b1d6eb85ad5952ab3a10575fa453e77e2</id>
<content type='text'>
[Backport #21941]

In case of `--yjit-disable`, YJIT only starts to record environment
escapes after `RubyVM::YJIT.enable`. Previously we falsely assumed that
we always have a full history all the way back to VM boot. This had YJIT
install and run code that assume EP=BP when EP≠BP for some exceptional
entry into the middle of a running frame, if the environment escaped
before `YJIT.enable`.

The fix is to reject exceptional entry with an escaped environment.
Rename things and explain in more detail how the predicate for deciding
to assume EP=BP works. It's quite subtle since it reasons about all
parties in the system that push a control frame and then run JIT code.

Note that while can_assume_on_stack_env() checks the currently running
environment if it so happens to be the one YJIT is compiling against, it
can return true for any ISEQ. The check isn't necessary for fixing the
bug, and the load bearing part of this patch is the change to
exceptional entries.

This fix is flat on speed and space on ruby-bench headline benchmarks.

Many thanks for the community effort to create a small test case for
this bug.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Backport #21941]

In case of `--yjit-disable`, YJIT only starts to record environment
escapes after `RubyVM::YJIT.enable`. Previously we falsely assumed that
we always have a full history all the way back to VM boot. This had YJIT
install and run code that assume EP=BP when EP≠BP for some exceptional
entry into the middle of a running frame, if the environment escaped
before `YJIT.enable`.

The fix is to reject exceptional entry with an escaped environment.
Rename things and explain in more detail how the predicate for deciding
to assume EP=BP works. It's quite subtle since it reasons about all
parties in the system that push a control frame and then run JIT code.

Note that while can_assume_on_stack_env() checks the currently running
environment if it so happens to be the one YJIT is compiling against, it
can return true for any ISEQ. The check isn't necessary for fixing the
bug, and the load bearing part of this patch is the change to
exceptional entries.

This fix is flat on speed and space on ruby-bench headline benchmarks.

Many thanks for the community effort to create a small test case for
this bug.
</pre>
</div>
</content>
</entry>
<entry>
<title>ZJIT: Avoid runtime exceptions from RubyVM::ZJIT.stats_string (#16139)</title>
<updated>2026-02-10T18:46:40+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2026-02-10T18:46:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f3bfffe8565b08b3426003aebbe328a0ecedad26'/>
<id>f3bfffe8565b08b3426003aebbe328a0ecedad26</id>
<content type='text'>
Before this it would raise if zjit wasn't enabled
and raise a different exception if zjit was but extended stats were
not (_some_ stats are available).

Co-authored-by: Randy Stauner &lt;randy@r4s6.net&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Before this it would raise if zjit wasn't enabled
and raise a different exception if zjit was but extended stats were
not (_some_ stats are available).

Co-authored-by: Randy Stauner &lt;randy@r4s6.net&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>Fix UnboundMethod#== for methods from included/extended modules [Backport #21873]</title>
<updated>2026-02-10T18:32:51+00:00</updated>
<author>
<name>Mike Dalessio</name>
<email>mike@37signals.com</email>
</author>
<published>2026-02-10T17:10:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=0768f08caff514b0ba616dc26d76aad90577eefe'/>
<id>0768f08caff514b0ba616dc26d76aad90577eefe</id>
<content type='text'>
Method#unbind clones the method entry, preserving its defined_class.
For methods mixed in via include/extend, defined_class is an ICLASS,
causing UnboundMethod#== to return false when comparing against the
same method obtained via Module#instance_method.

Resolve ICLASS defined_class in method_eq.

[Bug #21873]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Method#unbind clones the method entry, preserving its defined_class.
For methods mixed in via include/extend, defined_class is an ICLASS,
causing UnboundMethod#== to return false when comparing against the
same method obtained via Module#instance_method.

Resolve ICLASS defined_class in method_eq.

[Bug #21873]
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix signal crash during keyword argument call</title>
<updated>2026-02-09T21:38:18+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2026-02-07T16:44:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=c6d9ba58c50fd9c07023453d71cb55b4b9c36957'/>
<id>c6d9ba58c50fd9c07023453d71cb55b4b9c36957</id>
<content type='text'>
64f508ade8 changed rb_threadptr_raise to call rb_exception_setup,
which uses rb_scan_args with RB_SCAN_ARGS_PASS_CALLED_KEYWORDS.
This checked rb_keyword_given_p(), which read the interrupted
frame's keyword state rather than the signal raise arguments,
causing a crash when a signal arrived during a keyword call.

Revert rb_threadptr_raise to use rb_make_exception directly, and
have thread_raise_m call rb_exception_setup where
rb_keyword_given_p() reflects the correct frame.

[Bug #21865]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
64f508ade8 changed rb_threadptr_raise to call rb_exception_setup,
which uses rb_scan_args with RB_SCAN_ARGS_PASS_CALLED_KEYWORDS.
This checked rb_keyword_given_p(), which read the interrupted
frame's keyword state rather than the signal raise arguments,
causing a crash when a signal arrived during a keyword call.

Revert rb_threadptr_raise to use rb_make_exception directly, and
have thread_raise_m call rb_exception_setup where
rb_keyword_given_p() reflects the correct frame.

[Bug #21865]
</pre>
</div>
</content>
</entry>
<entry>
<title>Add a test backport missed at a10f7fac1fb1dcbdb1ae41137bd7294764a34793</title>
<updated>2026-01-13T18:57:31+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2026-01-13T18:57:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3176790c0d15dd7a72bb6e349651b3a66111d6f7'/>
<id>3176790c0d15dd7a72bb6e349651b3a66111d6f7</id>
<content type='text'>
https://bugs.ruby-lang.org/issues/21831
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://bugs.ruby-lang.org/issues/21831
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 7e81bf5c0c8f43602e6d901f4253dca2f3d71745: [Backport #21812]</title>
<updated>2026-01-13T01:14:52+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2026-01-13T01:14:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ac596948d4008c6e117449786c62de4e45e434bf'/>
<id>ac596948d4008c6e117449786c62de4e45e434bf</id>
<content type='text'>
	[PATCH] Fix sleep spurious wakeup from sigchld (#15802)

	When sleeping with `sleep`, currently the main thread can get woken up from sigchld
	from any thread (subprocess exited). The timer thread wakes up the main thread when this
	happens, as it checks for signals. The main thread then executes the ruby sigchld handler
	if one is registered and is supposed to go back to sleep immediately. This is not ideal but
	it's the way it's worked for a while. In commit 8d8159e7d8 I added writes to `th-&gt;status`
	before and after `wait_running_turn` in `thread_sched_to_waiting_until_wakeup`, which is
	called from `sleep`. This is usually the right way to set the thread's status, but `sleep`
	is an exception because the writes to `th-&gt;status` are done in `sleep_forever`. There's a
	loop that checks `th-&gt;status` in `sleep_forever`. When the main thread got woken up from
	sigchld it saw the changed `th-&gt;status` and continued to run the main thread instead of
	going back to sleep.

	The following script shows the error. It was returning instead of sleeping forever.

	```ruby
	t = Thread.new do
	  sleep 0.3
	  `echo hello`  # Spawns subprocess
	  puts "Subprocess exited"
	end

	puts "Main thread sleeping..."
	result = sleep  # Should block forever
	puts "sleep returned: #{result.inspect}"
	```

	Fixes [Bug #21812]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[PATCH] Fix sleep spurious wakeup from sigchld (#15802)

	When sleeping with `sleep`, currently the main thread can get woken up from sigchld
	from any thread (subprocess exited). The timer thread wakes up the main thread when this
	happens, as it checks for signals. The main thread then executes the ruby sigchld handler
	if one is registered and is supposed to go back to sleep immediately. This is not ideal but
	it's the way it's worked for a while. In commit 8d8159e7d8 I added writes to `th-&gt;status`
	before and after `wait_running_turn` in `thread_sched_to_waiting_until_wakeup`, which is
	called from `sleep`. This is usually the right way to set the thread's status, but `sleep`
	is an exception because the writes to `th-&gt;status` are done in `sleep_forever`. There's a
	loop that checks `th-&gt;status` in `sleep_forever`. When the main thread got woken up from
	sigchld it saw the changed `th-&gt;status` and continued to run the main thread instead of
	going back to sleep.

	The following script shows the error. It was returning instead of sleeping forever.

	```ruby
	t = Thread.new do
	  sleep 0.3
	  `echo hello`  # Spawns subprocess
	  puts "Subprocess exited"
	end

	puts "Main thread sleeping..."
	result = sleep  # Should block forever
	puts "sleep returned: #{result.inspect}"
	```

	Fixes [Bug #21812]
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) d7a6ff8224519005d2deeb3f4e98689a8a0835ad: [Backport #21819]</title>
<updated>2026-01-13T01:13:00+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2026-01-13T01:13:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6273c59a6e1f8587e549d5a5f44fd9363e6eb018'/>
<id>6273c59a6e1f8587e549d5a5f44fd9363e6eb018</id>
<content type='text'>
	[PATCH] [Bug #21819] Data objects without members should also be frozen
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[PATCH] [Bug #21819] Data objects without members should also be frozen
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 19e539c9ee1701b34189fa0c1feb942adeb0e326: [Backport #21814]</title>
<updated>2026-01-13T01:05:12+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2026-01-13T01:05:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=893dcb5f25cbb0574ae73aa8fc926fd26750a27f'/>
<id>893dcb5f25cbb0574ae73aa8fc926fd26750a27f</id>
<content type='text'>
	[PATCH] [Bug #21814] Fix negative bignum modulo

	If modulo is zero, do not  apply bias even if the divisor is zero.
	`BIGNUM_POSITIVE_P` is true even on bignum zero.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[PATCH] [Bug #21814] Fix negative bignum modulo

	If modulo is zero, do not  apply bias even if the divisor is zero.
	`BIGNUM_POSITIVE_P` is true even on bignum zero.
</pre>
</div>
</content>
</entry>
<entry>
<title>Box: allocate classes as boxable when it happens in the root box</title>
<updated>2026-01-05T21:00:14+00:00</updated>
<author>
<name>Satoshi Tagomori</name>
<email>s-tagomori@sakura.ad.jp</email>
</author>
<published>2025-12-30T05:46:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b3371c6ae5dd6fcecd12128f7b3e1e18e219bd3d'/>
<id>b3371c6ae5dd6fcecd12128f7b3e1e18e219bd3d</id>
<content type='text'>
Without this change, classes (including iclass) are allocated
as un-boxable classes after initializing user boxes (after starting
script evaluation). Under this situation, iclasses are created as
un-boxabled class when core modules are included by a class in the
root box, then it causes problems because it's in the root box but
it can't have multiple classexts.

This change makes it possible to allocate boxable classes even after
initializing user boxes. Classes create in the root box will be
boxable, and those can have 2 or more classexts.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Without this change, classes (including iclass) are allocated
as un-boxable classes after initializing user boxes (after starting
script evaluation). Under this situation, iclasses are created as
un-boxabled class when core modules are included by a class in the
root box, then it causes problems because it's in the root box but
it can't have multiple classexts.

This change makes it possible to allocate boxable classes even after
initializing user boxes. Classes create in the root box will be
boxable, and those can have 2 or more classexts.
</pre>
</div>
</content>
</entry>
</feed>
