From 8e08556fa7f2b6e9c43b040f2aea06dccead5d13 Mon Sep 17 00:00:00 2001 From: careworry <167077904+careworry@users.noreply.github.com> Date: Thu, 18 Apr 2024 23:32:34 +0800 Subject: [PATCH 01/20] chore: remove repetitive words (#10573) Signed-off-by: careworry --- lib/syntax_suggest/clean_document.rb | 2 +- spec/ruby/language/break_spec.rb | 2 +- weakmap.c | 2 +- yjit/src/codegen.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/syntax_suggest/clean_document.rb b/lib/syntax_suggest/clean_document.rb index 0847a62e271a6a..2790ccae8654f2 100644 --- a/lib/syntax_suggest/clean_document.rb +++ b/lib/syntax_suggest/clean_document.rb @@ -267,7 +267,7 @@ def join_groups(groups) groups.each do |lines| line = lines.first - # Handle the case of multiple groups in a a row + # Handle the case of multiple groups in a row # if one is already replaced, move on next if @document[line.index].empty? diff --git a/spec/ruby/language/break_spec.rb b/spec/ruby/language/break_spec.rb index 627cb4a071fca4..e725e77e80d0b3 100644 --- a/spec/ruby/language/break_spec.rb +++ b/spec/ruby/language/break_spec.rb @@ -372,7 +372,7 @@ def three end.should_not raise_error end - it "raises LocalJumpError when converted into a proc during a a super call" do + it "raises LocalJumpError when converted into a proc during a super call" do cls1 = Class.new { def foo(&b); b; end } cls2 = Class.new(cls1) { def foo; super { break 1 }.call; end } diff --git a/weakmap.c b/weakmap.c index a8e9fe2f8ad435..86920952f3d657 100644 --- a/weakmap.c +++ b/weakmap.c @@ -586,7 +586,7 @@ wmap_size(VALUE self) * the key and the object as the value. This means that the key is of the type * `VALUE *` while the value is of the type `VALUE`. * - * The object is not not directly stored as keys in the table because + * The object is not directly stored as keys in the table because * `rb_gc_mark_weak` requires a pointer to the memory location to overwrite * when the object is reclaimed. Using a pointer into the ST table entry is not * safe because the pointer can change when the ST table is resized. diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index d212719c09a9a4..b047aa3310ae69 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -1418,7 +1418,7 @@ fn gen_putobject( Some(KeepCompiling) } -/// Combine `putobject` and and `opt_ltlt` together if profitable, for example when +/// Combine `putobject` and `opt_ltlt` together if profitable, for example when /// left shifting an integer by a constant amount. fn fuse_putobject_opt_ltlt( jit: &mut JITState, From 147ca9585ede559fd68e162cbbbaba84f009c9a1 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 17 Apr 2024 16:30:41 -0700 Subject: [PATCH 02/20] Implement equality for CI comparison when CC searching When we're searching for CCs, compare the argc and flags for CI rather than comparing pointers. This means we don't need to store a reference to the CI, and it also naturally "de-duplicates" CC objects. We can observe the effect with the following code: ```ruby require "objspace" hash = {} p ObjectSpace.memsize_of(Hash) eval ("a".."zzz").map { |key| "hash.merge(:#{key} => 1)" }.join("; ") p ObjectSpace.memsize_of(Hash) ``` On master: ``` $ ruby -v test.rb ruby 3.4.0dev (2024-04-15T16:21:41Z master d019b3baec) [arm64-darwin23] test.rb:3: warning: assigned but unused variable - hash 3424 527736 ``` On this branch: ``` $ make runruby compiling vm.c linking miniruby builtin_binary.inc updated compiling builtin.c linking static-library libruby.3.4-static.a ln -sf ../../rbconfig.rb .ext/arm64-darwin23/rbconfig.rb linking ruby ld: warning: ignoring duplicate libraries: '-ldl', '-lobjc', '-lpthread' RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems ./test.rb 2240 2368 ``` Co-authored-by: John Hawthorn --- gc.c | 3 --- imemo.c | 1 - vm_callinfo.h | 3 ++- vm_insnhelper.c | 24 ++++++++++++++++-------- vm_method.c | 1 - 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/gc.c b/gc.c index 377ee528ea795c..279841fd7fa721 100644 --- a/gc.c +++ b/gc.c @@ -9978,9 +9978,6 @@ update_cc_tbl_i(VALUE ccs_ptr, void *data) } for (int i=0; ilen; i++) { - if (gc_object_moved_p(objspace, (VALUE)ccs->entries[i].ci)) { - ccs->entries[i].ci = (struct rb_callinfo *)rb_gc_location((VALUE)ccs->entries[i].ci); - } if (gc_object_moved_p(objspace, (VALUE)ccs->entries[i].cc)) { ccs->entries[i].cc = (struct rb_callcache *)rb_gc_location((VALUE)ccs->entries[i].cc); } diff --git a/imemo.c b/imemo.c index 8403859146cc67..3ecee056525c29 100644 --- a/imemo.c +++ b/imemo.c @@ -196,7 +196,6 @@ cc_table_mark_i(ID id, VALUE ccs_ptr, void *data) VM_ASSERT((VALUE)data == ccs->entries[i].cc->klass); VM_ASSERT(vm_cc_check_cme(ccs->entries[i].cc, ccs->cme)); - rb_gc_mark_movable((VALUE)ccs->entries[i].ci); rb_gc_mark_movable((VALUE)ccs->entries[i].cc); } return ID_TABLE_CONTINUE; diff --git a/vm_callinfo.h b/vm_callinfo.h index 21e0755aa80a1c..1629d9f0a9882e 100644 --- a/vm_callinfo.h +++ b/vm_callinfo.h @@ -575,7 +575,8 @@ struct rb_class_cc_entries { int len; const struct rb_callable_method_entry_struct *cme; struct rb_class_cc_entries_entry { - const struct rb_callinfo *ci; + unsigned int argc; + unsigned int flag; const struct rb_callcache *cc; } *entries; }; diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 84ef21205338da..108201295b69fc 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2023,7 +2023,8 @@ vm_ccs_push(VALUE klass, struct rb_class_cc_entries *ccs, const struct rb_callin VM_ASSERT(ccs->len < ccs->capa); const int pos = ccs->len++; - RB_OBJ_WRITE(klass, &ccs->entries[pos].ci, ci); + ccs->entries[pos].argc = vm_ci_argc(ci); + ccs->entries[pos].flag = vm_ci_flag(ci); RB_OBJ_WRITE(klass, &ccs->entries[pos].cc, cc); if (RB_DEBUG_COUNTER_SETMAX(ccs_maxlen, ccs->len)) { @@ -2038,7 +2039,9 @@ rb_vm_ccs_dump(struct rb_class_cc_entries *ccs) { ruby_debug_printf("ccs:%p (%d,%d)\n", (void *)ccs, ccs->len, ccs->capa); for (int i=0; ilen; i++) { - vm_ci_dump(ccs->entries[i].ci); + ruby_debug_printf("CCS CI ID:flag:%x argc:%u\n", + ccs->entries[i].flag, + ccs->entries[i].argc); rp(ccs->entries[i].cc); } } @@ -2050,11 +2053,8 @@ vm_ccs_verify(struct rb_class_cc_entries *ccs, ID mid, VALUE klass) VM_ASSERT(ccs->len <= ccs->capa); for (int i=0; ilen; i++) { - const struct rb_callinfo *ci = ccs->entries[i].ci; const struct rb_callcache *cc = ccs->entries[i].cc; - VM_ASSERT(vm_ci_p(ci)); - VM_ASSERT(vm_ci_mid(ci) == mid); VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache)); VM_ASSERT(vm_cc_class_check(cc, klass)); VM_ASSERT(vm_cc_check_cme(cc, ccs->cme)); @@ -2076,6 +2076,8 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) VALUE ccs_data; if (cc_tbl) { + // CCS data is keyed on method id, so we don't need the method id + // for doing comparisons in the `for` loop below. if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) { ccs = (struct rb_class_cc_entries *)ccs_data; const int ccs_len = ccs->len; @@ -2088,14 +2090,20 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci) else { VM_ASSERT(vm_ccs_verify(ccs, mid, klass)); + // We already know the method id is correct because we had + // to look up the ccs_data by method id. All we need to + // compare is argc and flag + unsigned int argc = vm_ci_argc(ci); + unsigned int flag = vm_ci_flag(ci); + for (int i=0; ientries[i].ci; + unsigned int ccs_ci_argc = ccs->entries[i].argc; + unsigned int ccs_ci_flag = ccs->entries[i].flag; const struct rb_callcache *ccs_cc = ccs->entries[i].cc; - VM_ASSERT(vm_ci_p(ccs_ci)); VM_ASSERT(IMEMO_TYPE_P(ccs_cc, imemo_callcache)); - if (ccs_ci == ci) { // TODO: equality + if (ccs_ci_argc == argc && ccs_ci_flag == flag) { RB_DEBUG_COUNTER_INC(cc_found_in_ccs); VM_ASSERT(vm_cc_cme(ccs_cc)->called_id == mid); diff --git a/vm_method.c b/vm_method.c index 5ca302a86a8c75..b58049bf7deb6d 100644 --- a/vm_method.c +++ b/vm_method.c @@ -31,7 +31,6 @@ vm_ccs_dump_i(ID mid, VALUE val, void *data) rp(ccs->cme); for (int i=0; ilen; i++) { - fprintf(stderr, " | [%d]\t", i); vm_ci_dump(ccs->entries[i].ci); rp_m( " | \t", ccs->entries[i].cc); } From 8f908a354ea80c01029af26d60adf14ef8ca33b8 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Thu, 18 Apr 2024 14:27:38 -0400 Subject: [PATCH 03/20] [ruby/prism] "Fix" transpose issue in parser compiler https://github.com/ruby/prism/commit/593d637178 --- lib/prism/translation/parser/compiler.rb | 30 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb index 9437589623f26b..1025595925c952 100644 --- a/lib/prism/translation/parser/compiler.rb +++ b/lib/prism/translation/parser/compiler.rb @@ -1535,19 +1535,29 @@ def visit_string_node(node) elsif node.opening == "?" builder.character([node.unescaped, srange(node.location)]) else - parts = if node.content.lines.count <= 1 || node.unescaped.lines.count <= 1 - [builder.string_internal([node.unescaped, srange(node.content_loc)])] - else - start_offset = node.content_loc.start_offset + content_lines = node.content.lines + unescaped_lines = node.unescaped.lines - [node.content.lines, node.unescaped.lines].transpose.map do |content_line, unescaped_line| - end_offset = start_offset + content_line.length - offsets = srange_offsets(start_offset, end_offset) - start_offset = end_offset + parts = + if content_lines.length <= 1 || unescaped_lines.length <= 1 + [builder.string_internal([node.unescaped, srange(node.content_loc)])] + elsif content_lines.length != unescaped_lines.length + # This occurs when we have line continuations in the string. We + # need to come back and fix this, but for now this stops the + # code from breaking when we encounter it because of trying to + # transpose arrays of different lengths. + [builder.string_internal([node.unescaped, srange(node.content_loc)])] + else + start_offset = node.content_loc.start_offset + + [content_lines, unescaped_lines].transpose.map do |content_line, unescaped_line| + end_offset = start_offset + content_line.length + offsets = srange_offsets(start_offset, end_offset) + start_offset = end_offset - builder.string_internal([unescaped_line, offsets]) + builder.string_internal([unescaped_line, offsets]) + end end - end builder.string_compose( token(node.opening_loc), From a51139230bfbd509b300fafc48e9a195b4d07c77 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Thu, 18 Apr 2024 14:36:42 -0400 Subject: [PATCH 04/20] [ruby/prism] Bump to v0.26.0 https://github.com/ruby/prism/commit/eadb09ef36 --- lib/prism/prism.gemspec | 2 +- prism/extension.h | 2 +- prism/templates/lib/prism/serialize.rb.erb | 2 +- prism/version.h | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/prism/prism.gemspec b/lib/prism/prism.gemspec index e55cac6df6d21b..e0134ff8ad9747 100644 --- a/lib/prism/prism.gemspec +++ b/lib/prism/prism.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |spec| spec.name = "prism" - spec.version = "0.25.0" + spec.version = "0.26.0" spec.authors = ["Shopify"] spec.email = ["ruby@shopify.com"] diff --git a/prism/extension.h b/prism/extension.h index 59a3f0232ac9e6..3e407d97aec57d 100644 --- a/prism/extension.h +++ b/prism/extension.h @@ -1,7 +1,7 @@ #ifndef PRISM_EXT_NODE_H #define PRISM_EXT_NODE_H -#define EXPECTED_PRISM_VERSION "0.25.0" +#define EXPECTED_PRISM_VERSION "0.26.0" #include #include diff --git a/prism/templates/lib/prism/serialize.rb.erb b/prism/templates/lib/prism/serialize.rb.erb index 36d5d5432df696..5920eaa952d4a6 100644 --- a/prism/templates/lib/prism/serialize.rb.erb +++ b/prism/templates/lib/prism/serialize.rb.erb @@ -10,7 +10,7 @@ module Prism # The minor version of prism that we are expecting to find in the serialized # strings. - MINOR_VERSION = 25 + MINOR_VERSION = 26 # The patch version of prism that we are expecting to find in the serialized # strings. diff --git a/prism/version.h b/prism/version.h index c96fe6882f16a7..489a8107cf4c28 100644 --- a/prism/version.h +++ b/prism/version.h @@ -14,7 +14,7 @@ /** * The minor version of the Prism library as an int. */ -#define PRISM_VERSION_MINOR 25 +#define PRISM_VERSION_MINOR 26 /** * The patch version of the Prism library as an int. @@ -24,6 +24,6 @@ /** * The version of the Prism library as a constant string. */ -#define PRISM_VERSION "0.25.0" +#define PRISM_VERSION "0.26.0" #endif From 2f8128986a035fdfa9d6452b8e0e1c8531360216 Mon Sep 17 00:00:00 2001 From: git Date: Thu, 18 Apr 2024 18:37:53 +0000 Subject: [PATCH 05/20] Update default gems list at a51139230bfbd509b300fafc48e9a1 [ci skip] --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 7b36564bb13ef2..5188ffc0aefc61 100644 --- a/NEWS.md +++ b/NEWS.md @@ -49,7 +49,7 @@ The following default gems are updated. * json 2.7.2 * net-http 0.4.1 * optparse 0.5.0 -* prism 0.25.0 +* prism 0.26.0 * rdoc 6.6.3.1 * reline 0.5.2 * resolv 0.4.0 From ea7975c59bce30fd6d48a068d089fb62d8f73ec7 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 17 Apr 2024 13:36:20 -0400 Subject: [PATCH 06/20] Include coderange.h in encoding.h ruby_coderange_type is defined in ruby/internal/encoding/coderange.h so we need to include it. --- include/ruby/internal/encoding/encoding.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/ruby/internal/encoding/encoding.h b/include/ruby/internal/encoding/encoding.h index dc3e0151f0420c..a680651a818073 100644 --- a/include/ruby/internal/encoding/encoding.h +++ b/include/ruby/internal/encoding/encoding.h @@ -28,6 +28,7 @@ #include "ruby/internal/attr/pure.h" #include "ruby/internal/attr/returns_nonnull.h" #include "ruby/internal/dllexport.h" +#include "ruby/internal/encoding/coderange.h" #include "ruby/internal/value.h" #include "ruby/internal/core/rbasic.h" #include "ruby/internal/fl_type.h" From 64d0817ea995ddf46aacc8f9da11b234e4e77962 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 18 Apr 2024 13:00:55 -0700 Subject: [PATCH 07/20] Remove markable guard before pushing on ccs list CCS list doesn't mark CI objects, so it doesn't matter whether or not they are markable before pushing. --- vm_insnhelper.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 108201295b69fc..249bb49ea7af5c 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2006,9 +2006,6 @@ vm_ccs_push(VALUE klass, struct rb_class_cc_entries *ccs, const struct rb_callin if (! vm_cc_markable(cc)) { return; } - else if (! vm_ci_markable(ci)) { - return; - } if (UNLIKELY(ccs->len == ccs->capa)) { if (ccs->capa == 0) { From 6443d690aead62d8d1ecd3fe32601455496390c6 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Fri, 12 Apr 2024 09:18:47 -0400 Subject: [PATCH 08/20] Don't mark empty singleton cc's These cc's aren't managed by the garbage collector so we shouldn't try to mark and move them. --- iseq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iseq.c b/iseq.c index 15635332ffbc3e..38f756d9c8bcf6 100644 --- a/iseq.c +++ b/iseq.c @@ -292,6 +292,10 @@ static bool cc_is_active(const struct rb_callcache *cc, bool reference_updating) { if (cc) { + if (cc == rb_vm_empty_cc() || rb_vm_empty_cc_for_super()) { + return false; + } + if (reference_updating) { cc = (const struct rb_callcache *)rb_gc_location((VALUE)cc); } From b7c4c8869cbedccd92fb2a598515ab56c1aee925 Mon Sep 17 00:00:00 2001 From: ilyazub <282605+ilyazub@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:11:27 +0200 Subject: [PATCH 09/20] Update turbo_tests to 2.2.3 or higher commands/pristine_spec.rb is passed with the turbo_tests 2.2.3 because it the removed json dependency. Related to https://github.com/ruby/ruby/pull/10496 Related to d60b2caa95b01f37d35db9ef8be1d035d14b408d --- tool/bundler/dev_gems.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/bundler/dev_gems.rb b/tool/bundler/dev_gems.rb index 74f4190f11ecca..1422cfc7a5238a 100644 --- a/tool/bundler/dev_gems.rb +++ b/tool/bundler/dev_gems.rb @@ -7,7 +7,7 @@ gem "rb_sys" gem "webrick", "~> 1.6" -gem "turbo_tests", "= 2.2.0" +gem "turbo_tests", "~> 2.2.3" gem "parallel_tests", "< 3.9.0" gem "parallel", "~> 1.19" gem "rspec-core", "~> 3.12" From 7f87ad9fc4bc45faf8cd33602a025f27c094b2fd Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 19 Apr 2024 12:58:53 +0900 Subject: [PATCH 10/20] Refer autoconfigured endian macro (#10572) Remove the case `RB_IO_BUFFER_HOST_ENDIAN` is not defined. --- include/ruby/io/buffer.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/include/ruby/io/buffer.h b/include/ruby/io/buffer.h index b044db053995bf..e4d98bf0511b12 100644 --- a/include/ruby/io/buffer.h +++ b/include/ruby/io/buffer.h @@ -69,14 +69,10 @@ enum rb_io_buffer_endian { RB_IO_BUFFER_LITTLE_ENDIAN = 4, RB_IO_BUFFER_BIG_ENDIAN = 8, -#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_LITTLE_ENDIAN, -#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#if defined(WORDS_BIGENDIAN) RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN, -#elif defined(REG_DWORD) && REG_DWORD == REG_DWORD_LITTLE_ENDIAN +#else RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_LITTLE_ENDIAN, -#elif defined(REG_DWORD) && REG_DWORD == REG_DWORD_BIG_ENDIAN - RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN, #endif RB_IO_BUFFER_NETWORK_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN From 3169c15863497f4269b819b2dc3b1c5bff3699b0 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 18 Apr 2024 13:58:58 +0900 Subject: [PATCH 11/20] Fix rubyspec-capiext dependency Not to build the rubyspec-capiext extension libraries again on the next build after the build all extensions get built, ensure these extensions are up to date when recursively building from exts.mk. --- defs/gmake.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/defs/gmake.mk b/defs/gmake.mk index e502b9f83e19c3..c914b39690d50f 100644 --- a/defs/gmake.mk +++ b/defs/gmake.mk @@ -513,10 +513,12 @@ ifneq ($(POSTLINK),) endif $(Q) $(RMALL) $@.* -rubyspec-capiext: $(patsubst %.c,$(RUBYSPEC_CAPIEXT)/%.$(DLEXT),$(notdir $(wildcard $(srcdir)/$(RUBYSPEC_CAPIEXT)/*.c))) +RUBYSPEC_CAPIEXT_SO := $(patsubst %.c,$(RUBYSPEC_CAPIEXT)/%.$(DLEXT),$(notdir $(wildcard $(srcdir)/$(RUBYSPEC_CAPIEXT)/*.c))) +rubyspec-capiext: $(RUBYSPEC_CAPIEXT_SO) @ $(NULLCMD) ifeq ($(ENABLE_SHARED),yes) +ruby: $(if $(LIBRUBY_SO_UPDATE),$(RUBYSPEC_CAPIEXT_SO)) exts: rubyspec-capiext endif From 801e4a4febbb226a7afd764c84b15f183d857815 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 19 Apr 2024 09:57:23 +0900 Subject: [PATCH 12/20] Remove UPDATE_LIBRARIES It has not been used since e48375c112022fa321786ccd95dd4e718efd78a3. --- common.mk | 2 +- ext/extmk.rb | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/common.mk b/common.mk index 77aa8b04ffee8b..0369b7615256f8 100644 --- a/common.mk +++ b/common.mk @@ -411,7 +411,7 @@ configure-ext: $(EXTS_MK) build-ext: $(EXTS_MK) $(Q)$(MAKE) -f $(EXTS_MK) $(mflags) libdir="$(libdir)" LIBRUBY_EXTS=$(LIBRUBY_EXTS) \ EXTENCS="$(ENCOBJS)" BASERUBY="$(BASERUBY)" MINIRUBY="$(MINIRUBY)" \ - UPDATE_LIBRARIES=no $(EXTSTATIC) + $(EXTSTATIC) $(Q)$(MAKE) $(EXTS_NOTE) exts-note: $(EXTS_MK) diff --git a/ext/extmk.rb b/ext/extmk.rb index 6c7c7aeab777e4..2f76e174d5db84 100755 --- a/ext/extmk.rb +++ b/ext/extmk.rb @@ -773,7 +773,6 @@ def mf.macro(name, values, max = 70) end submakeopts << 'EXTLDFLAGS="$(EXTLDFLAGS)"' submakeopts << 'EXTINITS="$(EXTINITS)"' - submakeopts << 'UPDATE_LIBRARIES="$(UPDATE_LIBRARIES)"' submakeopts << 'SHOWFLAGS=' mf.macro "SUBMAKEOPTS", submakeopts mf.macro "NOTE_MESG", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb skip] From 05d681f91e45dfd487463f5108872d4bd30c1beb Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 19 Apr 2024 10:23:14 +0900 Subject: [PATCH 13/20] Make `Output.new` accepts keyword arguments --- tool/lib/output.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tool/lib/output.rb b/tool/lib/output.rb index 5c645daca6c0d2..8cb426ae4af69b 100644 --- a/tool/lib/output.rb +++ b/tool/lib/output.rb @@ -4,10 +4,15 @@ class Output attr_reader :path, :vpath - def initialize - @path = @timestamp = @ifchange = @color = nil - @overwrite = @create_only = false - @vpath = VPath.new + def initialize(path: nil, timestamp: nil, ifchange: nil, color: nil, + overwrite: false, create_only: false, vpath: VPath.new) + @path = path + @timestamp = timestamp + @ifchange = ifchange + @color = color + @overwrite = overwrite + @create_only = create_only + @vpath = vpath end COLOR_WHEN = { From 1984db2db8ee54c33aabf6994718b972c56e2283 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 19 Apr 2024 10:24:08 +0900 Subject: [PATCH 14/20] Preserve old encinit.c if unchanged --- enc/encinit.c.erb | 3 +++ enc/make_encmake.rb | 8 ++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/enc/encinit.c.erb b/enc/encinit.c.erb index 120408f8e331b9..3662ba200d5b14 100644 --- a/enc/encinit.c.erb +++ b/enc/encinit.c.erb @@ -1,3 +1,6 @@ +/* Automatically generated from <%= erb.filename %> + * Do not edit<%# directly%>. + */ /* Copyright 2012 Google Inc. Some Rights Reserved. * Author: yugui@google.com (Yugui Sonoda) */ diff --git a/enc/make_encmake.rb b/enc/make_encmake.rb index 9761edd6d9b70d..96d1944bcba31c 100755 --- a/enc/make_encmake.rb +++ b/enc/make_encmake.rb @@ -147,10 +147,6 @@ def target_transcoders Dir.mkdir 'enc' rescue Errno::EEXIST end - File.open("enc/encinit.c", "w") {|f| - f.puts "/* Automatically generated from enc/encinit.c.erb" - f.puts " * Do not edit." - f.puts " */" - f.puts tmp - } + require 'tool/lib/output' + Output.new(path: "enc/encinit.c", ifchange: true).write(tmp) end From 09cbbe0e3d2006bd191e33785154775fcfff9532 Mon Sep 17 00:00:00 2001 From: fatkodima Date: Wed, 30 Oct 2019 18:17:56 +0200 Subject: [PATCH 15/20] [rubygems/rubygems] Add plugin hooks for Bundler.require https://github.com/rubygems/rubygems/commit/b373b7ed0d --- lib/bundler.rb | 19 ++++++ lib/bundler/installer.rb | 16 +---- lib/bundler/plugin/events.rb | 24 ++++++++ lib/bundler/runtime.rb | 17 ++++-- spec/bundler/plugins/hook_spec.rb | 99 +++++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+), 19 deletions(-) diff --git a/lib/bundler.rb b/lib/bundler.rb index 59a1107bb71d01..13bb24b6b62517 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -184,6 +184,7 @@ def setup(*groups) # Bundler.require(:test) # requires second_gem # def require(*groups) + Bundler.load_plugins setup(*groups).require(*groups) end @@ -560,6 +561,24 @@ def feature_flag @feature_flag ||= FeatureFlag.new(VERSION) end + def load_plugins(definition = Bundler.definition) + return if defined?(@load_plugins_ran) + + Bundler.rubygems.load_plugins + + requested_path_gems = definition.requested_specs.select {|s| s.source.is_a?(Source::Path) } + path_plugin_files = requested_path_gems.map do |spec| + begin + Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}") + rescue TypeError + error_message = "#{spec.name} #{spec.version} has an invalid gemspec" + raise Gem::InvalidSpecificationException, error_message + end + end.flatten + Bundler.rubygems.load_plugin_files(path_plugin_files) + @load_plugins_ran = true + end + def reset! reset_paths! Plugin.reset! diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index 018324f8402e8e..72e5602cc31284 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -81,7 +81,7 @@ def run(options) if resolve_if_needed(options) ensure_specs_are_compatible! - load_plugins + Bundler.load_plugins(@definition) options.delete(:jobs) else options[:jobs] = 1 # to avoid the overhead of Bundler::Worker @@ -213,20 +213,6 @@ def installation_parallelization(options) Bundler.settings.processor_count end - def load_plugins - Gem.load_plugins - - requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) } - path_plugin_files = requested_path_gems.map do |spec| - Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}") - rescue TypeError - error_message = "#{spec.name} #{spec.version} has an invalid gemspec" - raise Gem::InvalidSpecificationException, error_message - end.flatten - Gem.load_plugin_files(path_plugin_files) - Gem.load_env_plugins - end - def ensure_specs_are_compatible! @definition.specs.each do |spec| unless spec.matches_current_ruby? diff --git a/lib/bundler/plugin/events.rb b/lib/bundler/plugin/events.rb index bc037d1af507b7..29c05098ae1443 100644 --- a/lib/bundler/plugin/events.rb +++ b/lib/bundler/plugin/events.rb @@ -56,6 +56,30 @@ def self.defined_event?(event) # Includes an Array of Bundler::Dependency objects # GEM_AFTER_INSTALL_ALL = "after-install-all" define :GEM_AFTER_INSTALL_ALL, "after-install-all" + + # @!parse + # A hook called before each individual gem is required + # Includes a Bundler::Dependency. + # GEM_BEFORE_REQUIRE = "before-require" + define :GEM_BEFORE_REQUIRE, "before-require" + + # @!parse + # A hook called after each individual gem is required + # Includes a Bundler::Dependency. + # GEM_AFTER_REQUIRE = "after-require" + define :GEM_AFTER_REQUIRE, "after-require" + + # @!parse + # A hook called before any gems require + # Includes an Array of Bundler::Dependency objects. + # GEM_BEFORE_REQUIRE_ALL = "before-require-all" + define :GEM_BEFORE_REQUIRE_ALL, "before-require-all" + + # @!parse + # A hook called after all gems required + # Includes an Array of Bundler::Dependency objects. + # GEM_AFTER_REQUIRE_ALL = "after-require-all" + define :GEM_AFTER_REQUIRE_ALL, "after-require-all" end end end diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index ec772cfe7b2e77..dba6e7ac836f62 100644 --- a/lib/bundler/runtime.rb +++ b/lib/bundler/runtime.rb @@ -41,12 +41,17 @@ def require(*groups) groups.map!(&:to_sym) groups = [:default] if groups.empty? - @definition.dependencies.each do |dep| - # Skip the dependency if it is not in any of the requested groups, or - # not for the current platform, or doesn't match the gem constraints. - next unless (dep.groups & groups).any? && dep.should_include? + dependencies = @definition.dependencies.select do |dep| + # Select the dependency if it is in any of the requested groups, and + # for the current platform, and matches the gem constraints. + (dep.groups & groups).any? && dep.should_include? + end + + Plugin.hook(Plugin::Events::GEM_BEFORE_REQUIRE_ALL, dependencies) + dependencies.each do |dep| required_file = nil + Plugin.hook(Plugin::Events::GEM_BEFORE_REQUIRE, dep) begin # Loop through all the specified autorequires for the @@ -76,7 +81,11 @@ def require(*groups) end end end + + Plugin.hook(Plugin::Events::GEM_AFTER_REQUIRE, dep) end + + Plugin.hook(Plugin::Events::GEM_AFTER_REQUIRE_ALL, dependencies) end def self.definition_method(meth) diff --git a/spec/bundler/plugins/hook_spec.rb b/spec/bundler/plugins/hook_spec.rb index 72feb14d84ee08..d20321b1266b38 100644 --- a/spec/bundler/plugins/hook_spec.rb +++ b/spec/bundler/plugins/hook_spec.rb @@ -106,4 +106,103 @@ expect(out).to include "installed gem rack : installed" end end + + context "before-require-all hook" do + before do + build_repo2 do + build_plugin "before-require-all-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_REQUIRE_ALL do |deps| + puts "gems to be required \#{deps.map(&:name).join(", ")}" + end + RUBY + end + end + + bundle "plugin install before-require-all-plugin --source #{file_uri_for(gem_repo2)}" + end + + it "runs before all rubygems are required" do + install_gemfile_and_bundler_require + expect(out).to include "gems to be required rake, rack" + end + end + + context "before-require hook" do + before do + build_repo2 do + build_plugin "before-require-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_REQUIRE do |dep| + puts "requiring gem \#{dep.name}" + end + RUBY + end + end + + bundle "plugin install before-require-plugin --source #{file_uri_for(gem_repo2)}" + end + + it "runs before each rubygem is required" do + install_gemfile_and_bundler_require + expect(out).to include "requiring gem rake" + expect(out).to include "requiring gem rack" + end + end + + context "after-require-all hook" do + before do + build_repo2 do + build_plugin "after-require-all-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_REQUIRE_ALL do |deps| + puts "required gems \#{deps.map(&:name).join(", ")}" + end + RUBY + end + end + + bundle "plugin install after-require-all-plugin --source #{file_uri_for(gem_repo2)}" + end + + it "runs after all rubygems are required" do + install_gemfile_and_bundler_require + expect(out).to include "required gems rake, rack" + end + end + + context "after-require hook" do + before do + build_repo2 do + build_plugin "after-require-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_REQUIRE do |dep| + puts "required gem \#{dep.name}" + end + RUBY + end + end + + bundle "plugin install after-require-plugin --source #{file_uri_for(gem_repo2)}" + end + + it "runs after each rubygem is required" do + install_gemfile_and_bundler_require + expect(out).to include "required gem rake" + expect(out).to include "required gem rack" + end + end + + def install_gemfile_and_bundler_require + install_gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem "rake" + gem "rack" + G + + ruby! <<-RUBY + require "#{lib}/bundler" + Bundler.require + RUBY + end end From 0a14fee02f5720e6bec5116559e3ae872bc6f40b Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 10 Mar 2023 16:37:34 +0900 Subject: [PATCH 16/20] [rubygems/rubygems] Removed redundant begin https://github.com/rubygems/rubygems/commit/a9d22e5f46 --- lib/bundler.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/bundler.rb b/lib/bundler.rb index 13bb24b6b62517..078bf1a311a0d0 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -568,12 +568,10 @@ def load_plugins(definition = Bundler.definition) requested_path_gems = definition.requested_specs.select {|s| s.source.is_a?(Source::Path) } path_plugin_files = requested_path_gems.map do |spec| - begin - Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}") - rescue TypeError - error_message = "#{spec.name} #{spec.version} has an invalid gemspec" - raise Gem::InvalidSpecificationException, error_message - end + Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}") + rescue TypeError + error_message = "#{spec.name} #{spec.version} has an invalid gemspec" + raise Gem::InvalidSpecificationException, error_message end.flatten Bundler.rubygems.load_plugin_files(path_plugin_files) @load_plugins_ran = true From a95b46db067ef5013c20db2340c1b6fd76b3e5df Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 18 Apr 2024 14:56:44 +0900 Subject: [PATCH 17/20] [rubygems/rubygems] Track HEAD changes for old PR proposal https://github.com/rubygems/rubygems/commit/e3d180620c --- lib/bundler.rb | 1 + lib/bundler/rubygems_integration.rb | 12 ++++++++++++ spec/bundler/plugins/hook_spec.rb | 4 ++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/bundler.rb b/lib/bundler.rb index 078bf1a311a0d0..98a58502be1ba8 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -574,6 +574,7 @@ def load_plugins(definition = Bundler.definition) raise Gem::InvalidSpecificationException, error_message end.flatten Bundler.rubygems.load_plugin_files(path_plugin_files) + Bundler.rubygems.load_env_plugins @load_plugins_ran = true end diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb index da555681f98aba..494030eab22846 100644 --- a/lib/bundler/rubygems_integration.rb +++ b/lib/bundler/rubygems_integration.rb @@ -156,6 +156,18 @@ def loaded_gem_paths loaded_gem_paths.flatten end + def load_plugins + Gem.load_plugins + end + + def load_plugin_files(plugin_files) + Gem.load_plugin_files(plugin_files) + end + + def load_env_plugins + Gem.load_env_plugins + end + def ui=(obj) Gem::DefaultUserInteraction.ui = obj end diff --git a/spec/bundler/plugins/hook_spec.rb b/spec/bundler/plugins/hook_spec.rb index d20321b1266b38..f6ee0ba210c898 100644 --- a/spec/bundler/plugins/hook_spec.rb +++ b/spec/bundler/plugins/hook_spec.rb @@ -200,8 +200,8 @@ def install_gemfile_and_bundler_require gem "rack" G - ruby! <<-RUBY - require "#{lib}/bundler" + ruby <<-RUBY + require "bundler" Bundler.require RUBY end From acc326b7c4867429f3ea0d96e12c0efa6bfcb079 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 18 Apr 2024 14:56:57 +0900 Subject: [PATCH 18/20] [rubygems/rubygems] Removed needless class name https://github.com/rubygems/rubygems/commit/a2f43d3756 --- lib/bundler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bundler.rb b/lib/bundler.rb index 98a58502be1ba8..50b7a0c837819a 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -184,7 +184,7 @@ def setup(*groups) # Bundler.require(:test) # requires second_gem # def require(*groups) - Bundler.load_plugins + load_plugins setup(*groups).require(*groups) end From 7522d1bffea93989f33895da90746e40ce26d52b Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 18 Apr 2024 18:54:55 +0900 Subject: [PATCH 19/20] [rubygems/rubygems] Keep backword compatibility of Bundler.require https://github.com/rubygems/rubygems/commit/f6f79f4c37 --- lib/bundler/runtime.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index dba6e7ac836f62..54aa30ce0bd0ad 100644 --- a/lib/bundler/runtime.rb +++ b/lib/bundler/runtime.rb @@ -86,6 +86,8 @@ def require(*groups) end Plugin.hook(Plugin::Events::GEM_AFTER_REQUIRE_ALL, dependencies) + + dependencies end def self.definition_method(meth) From 662ce928a7fb31117bc584aad10d9c5c82689abd Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Fri, 19 Apr 2024 13:21:55 +0900 Subject: [PATCH 20/20] `RUBY_TRY_UNUSED_BLOCK_WARNING_STRICT` `RUBY_TRY_UNUSED_BLOCK_WARNING_STRICT=1 ruby ...` will enable strict check for unused block warning. This option is only for trial to compare the results so the envname is not considered well. Should be removed before Ruby 3.4.0 release. --- compile.c | 7 +++++-- vm.c | 6 ++++++ vm_core.h | 1 + vm_insnhelper.c | 10 +++++++--- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/compile.c b/compile.c index 853fadf5b04892..725c65b45195f1 100644 --- a/compile.c +++ b/compile.c @@ -2006,8 +2006,11 @@ iseq_set_use_block(rb_iseq_t *iseq) body->param.flags.use_block = 1; rb_vm_t *vm = GET_VM(); - st_data_t key = (st_data_t)rb_intern_str(body->location.label); // String -> ID - st_insert(vm->unused_block_warning_table, key, 1); + + if (!vm->unused_block_warning_strict) { + st_data_t key = (st_data_t)rb_intern_str(body->location.label); // String -> ID + st_insert(vm->unused_block_warning_table, key, 1); + } } } diff --git a/vm.c b/vm.c index b4f6a4bf16b738..0b3edea58c65a4 100644 --- a/vm.c +++ b/vm.c @@ -4261,6 +4261,12 @@ Init_BareVM(void) vm->constant_cache = rb_id_table_create(0); vm->unused_block_warning_table = st_init_numtable(); + // TODO: remove before Ruby 3.4.0 release + const char *s = getenv("RUBY_TRY_UNUSED_BLOCK_WARNING_STRICT"); + if (s && strcmp(s, "1") == 0) { + vm->unused_block_warning_strict = true; + } + // setup main thread th->nt = ZALLOC(struct rb_native_thread); th->vm = vm; diff --git a/vm_core.h b/vm_core.h index 2400b02c7e4042..a8a3dde58a0339 100644 --- a/vm_core.h +++ b/vm_core.h @@ -774,6 +774,7 @@ typedef struct rb_vm_struct { struct rb_id_table *negative_cme_table; st_table *overloaded_cme_table; // cme -> overloaded_cme st_table *unused_block_warning_table; + bool unused_block_warning_strict; // This id table contains a mapping from ID to ICs. It does this with ID // keys and nested st_tables as values. The nested tables have ICs as keys diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 249bb49ea7af5c..377f7b513ad8d0 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2978,6 +2978,7 @@ warn_unused_block(const rb_callable_method_entry_t *cme, const rb_iseq_t *iseq, { rb_vm_t *vm = GET_VM(); st_table *dup_check_table = vm->unused_block_warning_table; + st_data_t key; union { VALUE v; @@ -2989,14 +2990,17 @@ warn_unused_block(const rb_callable_method_entry_t *cme, const rb_iseq_t *iseq, }; // relax check - st_data_t key = (st_data_t)cme->def->original_id; + if (!vm->unused_block_warning_strict) { + key = (st_data_t)cme->def->original_id; - if (st_lookup(dup_check_table, key, NULL)) { - return; + if (st_lookup(dup_check_table, key, NULL)) { + return; + } } // strict check // make unique key from pc and me->def pointer + key = 0; for (int i=0; i