File tree Expand file tree Collapse file tree 4 files changed +39
-3
lines changed
Expand file tree Collapse file tree 4 files changed +39
-3
lines changed Original file line number Diff line number Diff line change @@ -12590,6 +12590,7 @@ proc.$(OBJEXT): $(top_srcdir)/internal/compilers.h
1259012590proc.$(OBJEXT): $(top_srcdir)/internal/error.h
1259112591proc.$(OBJEXT): $(top_srcdir)/internal/eval.h
1259212592proc.$(OBJEXT): $(top_srcdir)/internal/gc.h
12593+ proc.$(OBJEXT): $(top_srcdir)/internal/hash.h
1259312594proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
1259412595proc.$(OBJEXT): $(top_srcdir)/internal/object.h
1259512596proc.$(OBJEXT): $(top_srcdir)/internal/proc.h
Original file line number Diff line number Diff line change 1515#include "internal/error.h"
1616#include "internal/eval.h"
1717#include "internal/gc.h"
18+ #include "internal/hash.h"
1819#include "internal/object.h"
1920#include "internal/proc.h"
2021#include "internal/symbol.h"
@@ -1426,8 +1427,24 @@ rb_hash_proc(st_index_t hash, VALUE prc)
14261427{
14271428 rb_proc_t * proc ;
14281429 GetProcPtr (prc , proc );
1429- hash = rb_hash_uint (hash , (st_index_t )proc -> block .as .captured .code .val );
1430- hash = rb_hash_uint (hash , (st_index_t )proc -> block .as .captured .self );
1430+
1431+ switch (vm_block_type (& proc -> block )) {
1432+ case block_type_iseq :
1433+ hash = rb_st_hash_uint (hash , (st_index_t )proc -> block .as .captured .code .iseq -> body );
1434+ break ;
1435+ case block_type_ifunc :
1436+ hash = rb_st_hash_uint (hash , (st_index_t )proc -> block .as .captured .code .ifunc -> func );
1437+ break ;
1438+ case block_type_symbol :
1439+ hash = rb_st_hash_uint (hash , rb_any_hash (proc -> block .as .symbol ));
1440+ break ;
1441+ case block_type_proc :
1442+ hash = rb_st_hash_uint (hash , rb_any_hash (proc -> block .as .proc ));
1443+ break ;
1444+ default :
1445+ rb_bug ("rb_hash_proc: unknown block type %d" , vm_block_type (& proc -> block ));
1446+ }
1447+
14311448 return rb_hash_uint (hash , (st_index_t )proc -> block .as .captured .ep );
14321449}
14331450
Original file line number Diff line number Diff line change @@ -168,6 +168,24 @@ def self.capture(&block)
168168 assert_operator ( procs . map ( &:hash ) . uniq . size , :>= , 500 )
169169 end
170170
171+ def test_hash_does_not_change_after_compaction
172+ # [Bug #20853]
173+ [
174+ "proc {}" , # iseq backed proc
175+ "{}.to_proc" , # ifunc backed proc
176+ ":hello.to_proc" , # symbol backed proc
177+ ] . each do |proc |
178+ assert_separately ( [ ] , <<~RUBY )
179+ p1 = #{ proc }
180+ hash = p1.hash
181+
182+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
183+
184+ assert_equal(hash, p1.hash, "proc is `#{ proc } `")
185+ RUBY
186+ end
187+ end
188+
171189 def test_block_par
172190 assert_equal ( 10 , Proc . new { |&b | b . call ( 10 ) } . call { |x | x } )
173191 assert_equal ( 12 , Proc . new { |a , &b | b . call ( a ) } . call ( 12 ) { |x | x } )
Original file line number Diff line number Diff line change 1111# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
1212#define RUBY_VERSION_TEENY 5
1313#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
14- #define RUBY_PATCHLEVEL 107
14+ #define RUBY_PATCHLEVEL 108
1515
1616#include "ruby/version.h"
1717#include "ruby/internal/abi.h"
You can’t perform that action at this time.
0 commit comments