From d5af8d785888f3af5efb844be5948df71d777b22 Mon Sep 17 00:00:00 2001 From: Satoshi Tagomori Date: Tue, 30 Dec 2025 14:46:19 +0900 Subject: [PATCH 1/3] Box: allocate classes as boxable when it happens in the root box 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. --- class.c | 4 +++- test/ruby/test_box.rb | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/class.c b/class.c index 840bdeb0c2f9e6..8c773125e19b00 100644 --- a/class.c +++ b/class.c @@ -491,6 +491,7 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_box_t *bo while (subclass_entry) { if (subclass_entry->klass && RB_TYPE_P(subclass_entry->klass, T_ICLASS)) { iclass = subclass_entry->klass; + VM_ASSERT(RB_TYPE_P(iclass, T_ICLASS)); if (RBASIC_CLASS(iclass) == klass) { // Is the subclass an ICLASS including this module into another class // If so we need to re-associate it under our box with the new ext @@ -819,7 +820,8 @@ class_alloc0(enum ruby_value_type type, VALUE klass, bool boxable) static VALUE class_alloc(enum ruby_value_type type, VALUE klass) { - return class_alloc0(type, klass, false); + bool boxable = BOX_ROOT_P(rb_current_box()); + return class_alloc0(type, klass, boxable); } static VALUE diff --git a/test/ruby/test_box.rb b/test/ruby/test_box.rb index 28c9dd02b03d09..763f6148cb5483 100644 --- a/test/ruby/test_box.rb +++ b/test/ruby/test_box.rb @@ -855,4 +855,20 @@ def test_loaded_extension_deleted_in_user_box assert_empty(Dir.children(tmpdir)) end end + + def test_root_box_iclasses_should_be_boxable + assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true) + begin; + Ruby::Box.root.eval("class IMath; include Math; end") # (*) + module Math + def foo = :foo + end + # This test crashes here if iclasses (created at the line (*) is not boxable) + class IMath2; include Math; end + assert_equal :foo, IMath2.new.foo + assert_raise NoMethodError do + Ruby::Box.root.eval("IMath.new.foo") + end + end; + end end From 3f616d5701592360cf07dae885aa706596ad07fd Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 30 Dec 2025 18:33:03 +0900 Subject: [PATCH 2/3] Update ruby/setup-ruby action to v1.276.0 --- .github/workflows/annocheck.yml | 2 +- .github/workflows/auto_review_pr.yml | 2 +- .github/workflows/baseruby.yml | 2 +- .github/workflows/check_dependencies.yml | 2 +- .github/workflows/modgc.yml | 2 +- .github/workflows/parse_y.yml | 2 +- .github/workflows/spec_guards.yml | 2 +- .github/workflows/sync_default_gems.yml | 2 +- .github/workflows/ubuntu.yml | 2 +- .github/workflows/wasm.yml | 2 +- .github/workflows/windows.yml | 2 +- .github/workflows/yjit-ubuntu.yml | 2 +- .github/workflows/zjit-ubuntu.yml | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml index a2958fc00971dc..042748389ea87b 100644 --- a/.github/workflows/annocheck.yml +++ b/.github/workflows/annocheck.yml @@ -72,7 +72,7 @@ jobs: builddir: build makeup: true - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/auto_review_pr.yml b/.github/workflows/auto_review_pr.yml index 1351e78b98abef..4fc54902315d31 100644 --- a/.github/workflows/auto_review_pr.yml +++ b/.github/workflows/auto_review_pr.yml @@ -21,7 +21,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v6.0.1 - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.4' bundler: none diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml index 9ad8978c3e6e51..ee4f8c9a2a78a0 100644 --- a/.github/workflows/baseruby.yml +++ b/.github/workflows/baseruby.yml @@ -48,7 +48,7 @@ jobs: - ruby-3.3 steps: - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index 218bef28186e2d..7d5b5e79efe4c4 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -40,7 +40,7 @@ jobs: - uses: ./.github/actions/setup/directories - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/modgc.yml b/.github/workflows/modgc.yml index 7851005e5133e1..fe01b3dcbefbbb 100644 --- a/.github/workflows/modgc.yml +++ b/.github/workflows/modgc.yml @@ -61,7 +61,7 @@ jobs: uses: ./.github/actions/setup/ubuntu if: ${{ contains(matrix.os, 'ubuntu') }} - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/parse_y.yml b/.github/workflows/parse_y.yml index a1035ef451dd82..c06d7b8fa93f74 100644 --- a/.github/workflows/parse_y.yml +++ b/.github/workflows/parse_y.yml @@ -58,7 +58,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml index 8ccb954d84548d..88b69e888e7a80 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -47,7 +47,7 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml index 3947001ccdf71a..8e44b96908738f 100644 --- a/.github/workflows/sync_default_gems.yml +++ b/.github/workflows/sync_default_gems.yml @@ -36,7 +36,7 @@ jobs: with: token: ${{ github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.4' bundler: none diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index bf34baaced0fd2..6489454c57c74b 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -69,7 +69,7 @@ jobs: with: arch: ${{ matrix.arch }} - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 9b9ea1841029d4..6022da8c3b0585 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -98,7 +98,7 @@ jobs: run: | echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 7f3e60349642e0..e0bd6893a6f7e7 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -59,7 +59,7 @@ jobs: - run: md build working-directory: - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: # windows-11-arm has only 3.4.1, 3.4.2, 3.4.3, head ruby-version: ${{ !endsWith(matrix.os, 'arm') && '3.1' || '3.4' }} diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml index 7dce69cda4ea78..bd90a57c2a0d87 100644 --- a/.github/workflows/yjit-ubuntu.yml +++ b/.github/workflows/yjit-ubuntu.yml @@ -128,7 +128,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index 29b7aaad592c7e..13b1add5b09568 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -111,7 +111,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 + - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 with: ruby-version: '3.1' bundler: none From 27d6c966583c65c9ffd02f931d9c4efe8d7232e0 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 30 Dec 2025 17:58:44 +0900 Subject: [PATCH 3/3] Add 4.0 to the spec_guards workflow --- .github/workflows/spec_guards.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml index 88b69e888e7a80..971547351de67e 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -42,6 +42,7 @@ jobs: - ruby-3.2 - ruby-3.3 - ruby-3.4 + - ruby-4.0 fail-fast: false steps: