From 0654bcd4f809e97bca4a099fa78db9990fa5a4ae Mon Sep 17 00:00:00 2001 From: Satoshi Tagomori Date: Wed, 26 Nov 2025 00:21:40 +0900 Subject: [PATCH 01/11] Box: Add a test to drop the reference to a box --- test/ruby/test_box.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/ruby/test_box.rb b/test/ruby/test_box.rb index 9b87f9b5bc458a..7023ecab16aa0e 100644 --- a/test/ruby/test_box.rb +++ b/test/ruby/test_box.rb @@ -810,4 +810,21 @@ def test_loading_extension_libs_in_main_box 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 From e84b91a292f3cd94fdf5f2ef548bf2377b1cf537 Mon Sep 17 00:00:00 2001 From: Satoshi Tagomori Date: Wed, 26 Nov 2025 00:36:55 +0900 Subject: [PATCH 02/11] Box: mark/move Box object referred via ENV/rb_env_t --- imemo.c | 7 +++++++ vm.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/imemo.c b/imemo.c index d83c690ba5ae81..8ec58ae4a92e52 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/vm.c b/vm.c index fd8c923649cb65..f9c615c3e23c30 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)) { From 1e6079dcaff8853d4b36cda9e9bb751139b27375 Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Wed, 26 Nov 2025 01:22:39 +0000 Subject: [PATCH 03/11] [DOC] Use Aliki as the documentation website theme (#15319) Use Aliki as the documentation website theme --- .rdoc_options | 15 +++++++++++++++ gems/bundled_gems | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.rdoc_options b/.rdoc_options index b8b511efe67f1e..f38a0da35537dd 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/gems/bundled_gems b/gems/bundled_gems index 2d5c6bdaa1cea1..fbe741c335864e 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -39,7 +39,7 @@ ostruct 0.6.3 https://github.com/ruby/ostruct pstore 0.2.0 https://github.com/ruby/pstore benchmark 0.5.0 https://github.com/ruby/benchmark logger 1.7.0 https://github.com/ruby/logger -rdoc 6.15.1 https://github.com/ruby/rdoc +rdoc 6.16.0 https://github.com/ruby/rdoc win32ole 1.9.2 https://github.com/ruby/win32ole irb 1.15.3 https://github.com/ruby/irb reline 0.6.3 https://github.com/ruby/reline From 6354afa64a5c59de50f064a7827cbd15d29dc874 Mon Sep 17 00:00:00 2001 From: git Date: Wed, 26 Nov 2025 01:23:33 +0000 Subject: [PATCH 04/11] Update bundled gems list as of 2025-11-26 --- NEWS.md | 4 ++-- gems/bundled_gems | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9d47bb774ef626..fbbc06713438cd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -167,7 +167,7 @@ The following bundled gems are promoted from default gems. * pstore 0.2.0 * benchmark 0.5.0 * logger 1.7.0 -* rdoc 6.15.1 +* rdoc 6.16.0 * win32ole 1.9.2 * irb 1.15.3 * reline 0.6.3 @@ -221,7 +221,7 @@ The following bundled gems are updated. * minitest 5.26.2 * power_assert 3.0.1 * rake 13.3.1 -* test-unit 3.7.1 +* test-unit 3.7.3 * rexml 3.4.4 * net-ftp 0.3.9 * net-imap 0.5.12 diff --git a/gems/bundled_gems b/gems/bundled_gems index fbe741c335864e..e1e6b01bfdda10 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -9,7 +9,7 @@ minitest 5.26.2 https://github.com/minitest/minitest power_assert 3.0.1 https://github.com/ruby/power_assert rake 13.3.1 https://github.com/ruby/rake -test-unit 3.7.1 https://github.com/test-unit/test-unit +test-unit 3.7.3 https://github.com/test-unit/test-unit rexml 3.4.4 https://github.com/ruby/rexml rss 0.3.1 https://github.com/ruby/rss net-ftp 0.3.9 https://github.com/ruby/net-ftp From 26a9e0b4e31f7b5a9cbd755e0a15823a8fa51bae Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 26 Nov 2025 10:47:17 +0900 Subject: [PATCH 05/11] Reset the cache variable before retrying --- .rdoc_options | 15 --------------- NEWS.md | 4 ++-- configure.ac | 4 +++- gems/bundled_gems | 4 ++-- imemo.c | 7 ------- test/ruby/test_box.rb | 17 ----------------- vm.c | 7 ------- 7 files changed, 7 insertions(+), 51 deletions(-) diff --git a/.rdoc_options b/.rdoc_options index f38a0da35537dd..b8b511efe67f1e 100644 --- a/.rdoc_options +++ b/.rdoc_options @@ -11,8 +11,6 @@ rdoc_include: exclude: - \.gemspec\z -generator_name: aliki - autolink_excluded_words: - Class - Method @@ -25,16 +23,3 @@ 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/NEWS.md b/NEWS.md index fbbc06713438cd..9d47bb774ef626 100644 --- a/NEWS.md +++ b/NEWS.md @@ -167,7 +167,7 @@ The following bundled gems are promoted from default gems. * pstore 0.2.0 * benchmark 0.5.0 * logger 1.7.0 -* rdoc 6.16.0 +* rdoc 6.15.1 * win32ole 1.9.2 * irb 1.15.3 * reline 0.6.3 @@ -221,7 +221,7 @@ The following bundled gems are updated. * minitest 5.26.2 * power_assert 3.0.1 * rake 13.3.1 -* test-unit 3.7.3 +* test-unit 3.7.1 * rexml 3.4.4 * net-ftp 0.3.9 * net-imap 0.5.12 diff --git a/configure.ac b/configure.ac index 9120fc25ecddf4..22baeabb32ab46 100644 --- a/configure.ac +++ b/configure.ac @@ -1749,8 +1749,10 @@ AS_IF([test "$GCC" = yes], [ for lib in "" atomic; do AS_IF([test "$lib" != ""], [ AC_CHECK_LIB([atomic], [__atomic_fetch_add_8]) + unset rb_cv_gcc_atomic_builtins_64 ]) - AC_CACHE_CHECK([for 64bit __atomic builtins], [rb_cv_gcc_atomic_builtins_64], [ + AC_CACHE_CHECK([for 64bit __atomic builtins${lib:+ with -l$lib}], + [rb_cv_gcc_atomic_builtins_64], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include uint64_t atomic_var;]], [[ diff --git a/gems/bundled_gems b/gems/bundled_gems index e1e6b01bfdda10..2d5c6bdaa1cea1 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -9,7 +9,7 @@ minitest 5.26.2 https://github.com/minitest/minitest power_assert 3.0.1 https://github.com/ruby/power_assert rake 13.3.1 https://github.com/ruby/rake -test-unit 3.7.3 https://github.com/test-unit/test-unit +test-unit 3.7.1 https://github.com/test-unit/test-unit rexml 3.4.4 https://github.com/ruby/rexml rss 0.3.1 https://github.com/ruby/rss net-ftp 0.3.9 https://github.com/ruby/net-ftp @@ -39,7 +39,7 @@ ostruct 0.6.3 https://github.com/ruby/ostruct pstore 0.2.0 https://github.com/ruby/pstore benchmark 0.5.0 https://github.com/ruby/benchmark logger 1.7.0 https://github.com/ruby/logger -rdoc 6.16.0 https://github.com/ruby/rdoc +rdoc 6.15.1 https://github.com/ruby/rdoc win32ole 1.9.2 https://github.com/ruby/win32ole irb 1.15.3 https://github.com/ruby/irb reline 0.6.3 https://github.com/ruby/reline diff --git a/imemo.c b/imemo.c index 8ec58ae4a92e52..d83c690ba5ae81 100644 --- a/imemo.c +++ b/imemo.c @@ -426,13 +426,6 @@ 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 7023ecab16aa0e..9b87f9b5bc458a 100644 --- a/test/ruby/test_box.rb +++ b/test/ruby/test_box.rb @@ -810,21 +810,4 @@ def test_loading_extension_libs_in_main_box 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 f9c615c3e23c30..fd8c923649cb65 100644 --- a/vm.c +++ b/vm.c @@ -3677,13 +3677,6 @@ 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)) { From 0b0c2cc4cbed72e952233953f90bc2dbdc77c11b Mon Sep 17 00:00:00 2001 From: git Date: Wed, 26 Nov 2025 02:08:43 +0000 Subject: [PATCH 06/11] Update bundled gems list as of 2025-11-25 --- NEWS.md | 4 ++-- gems/bundled_gems | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9d47bb774ef626..fbbc06713438cd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -167,7 +167,7 @@ The following bundled gems are promoted from default gems. * pstore 0.2.0 * benchmark 0.5.0 * logger 1.7.0 -* rdoc 6.15.1 +* rdoc 6.16.0 * win32ole 1.9.2 * irb 1.15.3 * reline 0.6.3 @@ -221,7 +221,7 @@ The following bundled gems are updated. * minitest 5.26.2 * power_assert 3.0.1 * rake 13.3.1 -* test-unit 3.7.1 +* test-unit 3.7.3 * rexml 3.4.4 * net-ftp 0.3.9 * net-imap 0.5.12 diff --git a/gems/bundled_gems b/gems/bundled_gems index 2d5c6bdaa1cea1..e1e6b01bfdda10 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -9,7 +9,7 @@ minitest 5.26.2 https://github.com/minitest/minitest power_assert 3.0.1 https://github.com/ruby/power_assert rake 13.3.1 https://github.com/ruby/rake -test-unit 3.7.1 https://github.com/test-unit/test-unit +test-unit 3.7.3 https://github.com/test-unit/test-unit rexml 3.4.4 https://github.com/ruby/rexml rss 0.3.1 https://github.com/ruby/rss net-ftp 0.3.9 https://github.com/ruby/net-ftp @@ -39,7 +39,7 @@ ostruct 0.6.3 https://github.com/ruby/ostruct pstore 0.2.0 https://github.com/ruby/pstore benchmark 0.5.0 https://github.com/ruby/benchmark logger 1.7.0 https://github.com/ruby/logger -rdoc 6.15.1 https://github.com/ruby/rdoc +rdoc 6.16.0 https://github.com/ruby/rdoc win32ole 1.9.2 https://github.com/ruby/win32ole irb 1.15.3 https://github.com/ruby/irb reline 0.6.3 https://github.com/ruby/reline From 724e94a09c616fb71edd992e274e73ee14bee896 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Tue, 25 Nov 2025 13:10:31 -0500 Subject: [PATCH 07/11] ZJIT: CI: Run `btest` with call-threshold=2 --- .github/workflows/zjit-ubuntu.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index 040187fca3baf7..7778c449e8e8ea 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -61,6 +61,12 @@ jobs: specopts: '-T --zjit-disable-hir-opt -T --zjit-call-threshold=1' configure: '--enable-zjit=dev' + # The optimizer benefits from at least 1 iteration of profiling. Also, many + # regression tests in bootstraptest/test_yjit.rb assume call-threshold=2. + - test_task: 'btest' + run_opts: '--zjit-call-threshold=2' + configure: '--enable-zjit=dev' + - test_task: 'zjit-check' # zjit-test + quick feedback of test_zjit.rb configure: '--enable-yjit --enable-zjit=dev' rust_version: '1.85.0' From 2f53985da9ee593fe524d408256835667938c7d7 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 26 Nov 2025 11:34:33 +0900 Subject: [PATCH 08/11] Revert miscommit at "Reset the cache variable before retrying" This reverts commit 26a9e0b4e31f7b5a9cbd755e0a15823a8fa51bae partially. --- .rdoc_options | 15 +++++++++++++++ imemo.c | 7 +++++++ test/ruby/test_box.rb | 17 +++++++++++++++++ vm.c | 7 +++++++ 4 files changed, 46 insertions(+) diff --git a/.rdoc_options b/.rdoc_options index b8b511efe67f1e..f38a0da35537dd 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 d83c690ba5ae81..8ec58ae4a92e52 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 9b87f9b5bc458a..7023ecab16aa0e 100644 --- a/test/ruby/test_box.rb +++ b/test/ruby/test_box.rb @@ -810,4 +810,21 @@ def test_loading_extension_libs_in_main_box 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 fd8c923649cb65..f9c615c3e23c30 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)) { From 30fe3654cabc56314b75ec6f837a583e0b0a1577 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 26 Nov 2025 11:48:36 +0900 Subject: [PATCH 09/11] Ignore missed commits [ci skip] --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 5fb9ba5f7dd3ac..3ca28ad72c8917 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -36,3 +36,5 @@ a0f7de814ae5c299d6ce99bed5fb308a05d50ba0 d4e24021d39e1f80f0055b55d91f8d5f22e15084 7a56c316418980b8a41fcbdc94067b2bda2ad112 e90282be7ba1bc8e3119f6e1a2c80356ceb3f80a +26a9e0b4e31f7b5a9cbd755e0a15823a8fa51bae +2f53985da9ee593fe524d408256835667938c7d7 From 72eb929ec1cafa9a4439520b5ba75ac4e5ef1a82 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 26 Nov 2025 11:50:24 +0900 Subject: [PATCH 10/11] [DOC] Exclude the word Box from RDoc's autolinking --- .rdoc_options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rdoc_options b/.rdoc_options index f38a0da35537dd..38dca221112c53 100644 --- a/.rdoc_options +++ b/.rdoc_options @@ -14,6 +14,7 @@ exclude: generator_name: aliki autolink_excluded_words: +- Box - Class - Method - Module @@ -37,4 +38,3 @@ footer_content: RubyGems: https://rubygems.org/ Community: X: https://x.com/rubylangorg - From 43ed35de6c1759feef57dbad0a2fad045ee2751f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 26 Nov 2025 15:33:56 +0900 Subject: [PATCH 11/11] [ruby/cgi] Skip unless `CGI::EscapeExt` methods are implemented https://github.com/ruby/cgi/commit/7b5a13952b --- test/cgi/test_cgi_escape.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cgi/test_cgi_escape.rb b/test/cgi/test_cgi_escape.rb index f6ca658934cdec..73d99e8aacda39 100644 --- a/test/cgi/test_cgi_escape.rb +++ b/test/cgi/test_cgi_escape.rb @@ -300,7 +300,7 @@ def setup remove_method :escapeHTML alias _unescapeHTML unescapeHTML remove_method :unescapeHTML - end if defined?(CGI::EscapeExt) + end if defined?(CGI::EscapeExt) and CGI::EscapeExt.method_defined?(:escapeHTML) end def teardown @@ -309,7 +309,7 @@ def teardown remove_method :_escapeHTML alias unescapeHTML _unescapeHTML remove_method :_unescapeHTML - end if defined?(CGI::EscapeExt) + end if defined?(CGI::EscapeExt) and CGI::EscapeExt.method_defined?(:_escapeHTML) end include CGIEscapeTest::UnescapeHTMLTests