summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2025-11-26 11:34:33 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2025-11-26 11:35:15 +0900
commit2f53985da9ee593fe524d408256835667938c7d7 (patch)
tree25f497330974a02da2808a95bbcf594d60233d7b
parent724e94a09c616fb71edd992e274e73ee14bee896 (diff)
Revert miscommit at "Reset the cache variable before retrying"
This reverts commit 26a9e0b4e31f7b5a9cbd755e0a15823a8fa51bae partially.
-rw-r--r--.rdoc_options15
-rw-r--r--imemo.c7
-rw-r--r--test/ruby/test_box.rb17
-rw-r--r--vm.c7
4 files changed, 46 insertions, 0 deletions
diff --git a/.rdoc_options b/.rdoc_options
index b8b511efe6..f38a0da355 100644
--- a/.rdoc_options
+++ b/.rdoc_options
@@ -11,6 +11,8 @@ rdoc_include:
exclude:
- \.gemspec\z
+generator_name: aliki
+
autolink_excluded_words:
- Class
- Method
@@ -23,3 +25,16 @@ autolink_excluded_words:
- YJIT
canonical_root: https://docs.ruby-lang.org/en/master
+
+footer_content:
+ Ruby:
+ Documentation: index.html
+ Official Website: https://www.ruby-lang.org/
+ Playground: https://ruby.github.io/play-ruby/
+ Resources:
+ GitHub: https://github.com/ruby/ruby
+ Issue Tracker: https://bugs.ruby-lang.org/projects/ruby-master/issues
+ RubyGems: https://rubygems.org/
+ Community:
+ X: https://x.com/rubylangorg
+
diff --git a/imemo.c b/imemo.c
index d83c690ba5..8ec58ae4a9 100644
--- a/imemo.c
+++ b/imemo.c
@@ -426,6 +426,13 @@ rb_imemo_mark_and_move(VALUE obj, bool reference_updating)
rb_gc_mark_and_move_ptr(&env->iseq);
+ if (VM_ENV_LOCAL_P(env->ep) && VM_ENV_BOXED_P(env->ep)) {
+ const rb_box_t *box = VM_ENV_BOX(env->ep);
+ if (BOX_USER_P(box)) {
+ rb_gc_mark_and_move((VALUE *)&box->box_object);
+ }
+ }
+
if (reference_updating) {
((VALUE *)env->ep)[VM_ENV_DATA_INDEX_ENV] = rb_gc_location(env->ep[VM_ENV_DATA_INDEX_ENV]);
}
diff --git a/test/ruby/test_box.rb b/test/ruby/test_box.rb
index 9b87f9b5bc..7023ecab16 100644
--- a/test/ruby/test_box.rb
+++ b/test/ruby/test_box.rb
@@ -810,4 +810,21 @@ class TestBox < Test::Unit::TestCase
assert_equal expected, 1
end;
end
+
+ def test_mark_box_object_referred_only_from_binding
+ assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
+ begin;
+ box = Ruby::Box.new
+ box.eval('class Integer; def +(*)=42; end')
+ b = box.eval('binding')
+ box = nil # remove direct reference to the box
+
+ assert_equal 42, b.eval('1+2')
+
+ GC.stress = true
+ GC.start
+
+ assert_equal 42, b.eval('1+2')
+ end;
+ end
end
diff --git a/vm.c b/vm.c
index fd8c923649..f9c615c3e2 100644
--- a/vm.c
+++ b/vm.c
@@ -3677,6 +3677,13 @@ rb_execution_context_mark(const rb_execution_context_t *ec)
rb_gc_mark_movable((VALUE)cfp->iseq);
rb_gc_mark_movable((VALUE)cfp->block_code);
+ if (VM_ENV_LOCAL_P(ep) && VM_ENV_BOXED_P(ep)) {
+ const rb_box_t *box = VM_ENV_BOX(ep);
+ if (BOX_USER_P(box)) {
+ rb_gc_mark_movable(box->box_object);
+ }
+ }
+
if (!VM_ENV_LOCAL_P(ep)) {
const VALUE *prev_ep = VM_ENV_PREV_EP(ep);
if (VM_ENV_FLAGS(prev_ep, VM_ENV_FLAG_ESCAPED)) {