Compare commits

...

501 Commits

Author SHA1 Message Date
Kuba Suder
bea48adbca
[DOC] fixed pid shown in the doc comment on fork 2026-01-28 02:48:37 +00:00
Peter Zhu
5eb17ea4aa [DOC] Fix hash style in Hash#flatten 2026-01-27 17:11:52 -05:00
Kevin Newton
d5616094f4 [ruby/prism] Mark insert_on_sp as private
https://github.com/ruby/prism/commit/db72066cde
2026-01-27 20:51:32 +00:00
Benoit Daloze
5c15f9380f [ruby/prism] Use the terminology "column in bytes/characters/code units"
* Consistent and clear.
* Avoids the confusion that "column number" might be understood
  as a column in an editor starting at 1 (they all start at 0).

https://github.com/ruby/prism/commit/91f1c4b9d5
2026-01-27 20:49:02 +00:00
Kevin Newton
1cd32536a5 [ruby/prism] Mark STATES as a private constant
https://github.com/ruby/prism/commit/c78f742581
2026-01-27 20:48:49 +00:00
git
6687167b43 Update default gems list at ec154654a99c07d065108e9c31793e [ci skip] 2026-01-27 20:31:17 +00:00
Kevin Newton
af4a1ca021 Use slices instead of locations
In the C API, we want to use slices instead of locations in the
AST. In this case a "slice" is effectively the same thing as the
location, expect it is represented using a 32-bit offset and a
32-bit length. This will cut down on half of the space of all of
the locations in the AST.

Note that from the Ruby/Java/JavaScript side, this is effectively
an invisible change. This only impacts the C/Rust side.
2026-01-27 15:30:45 -05:00
Kevin Newton
ec154654a9 [ruby/prism] Bump to v1.9.0
https://github.com/ruby/prism/commit/e722e577ef
2026-01-27 20:30:23 +00:00
Kevin Newton
68902e3593 [ruby/prism] Add Prism::Node#find_all
https://github.com/ruby/prism/commit/51df90ef04
2026-01-27 20:17:12 +00:00
Kevin Newton
c983b7aee6 [ruby/prism] Rename line_to_byte_offset -> byte_offset
Also, include the column in here. Hopefully we can do some additional
optimizations later.

https://github.com/ruby/prism/commit/7759acdd26
2026-01-27 20:06:22 +00:00
Randy Stauner
39b28e67a6
ZJIT: Remove unused import to eliminate build warning (#15984) 2026-01-27 20:00:33 +00:00
Nozomi Hijikata
6f6ed79a97
ZJIT: Compile invokesuperforward (#15958)
Closes: https://github.com/Shopify/ruby/issues/862

Add dynamic dispatch for `invokesuperforward` instruction as a first step.
Specialization like YJIT’s is not implemented yet and will be handled separately.

## Benchmark 
### lobsters

<details>

<summary>before patch</summary>

```
Average of last 10, non-warmup iters: 654ms
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (59.5% of total 15,599,811):
                                               Hash#fetch: 3,185,110 (20.4%)
                                            Regexp#match?:   708,802 ( 4.5%)
                                                Hash#key?:   696,422 ( 4.5%)
                                              String#sub!:   489,840 ( 3.1%)
                                             Set#include?:   396,625 ( 2.5%)
                                                String#<<:   396,279 ( 2.5%)
                                       String#start_with?:   379,336 ( 2.4%)
                                              Hash#delete:   325,992 ( 2.1%)
                                               String.new:   307,248 ( 2.0%)
                                              Integer#===:   279,054 ( 1.8%)
                                         Symbol#end_with?:   255,539 ( 1.6%)
                                             Kernel#is_a?:   246,961 ( 1.6%)
                                    Process.clock_gettime:   221,588 ( 1.4%)
                                                Integer#>:   219,718 ( 1.4%)
                                            String#match?:   218,056 ( 1.4%)
                                               Integer#<=:   202,617 ( 1.3%)
                                                Time#to_i:   192,214 ( 1.2%)
                                              Time#subsec:   189,240 ( 1.2%)
                                            String#to_sym:   185,593 ( 1.2%)
                                          String#include?:   182,862 ( 1.2%)
Top-20 calls to C functions from JIT code (83.7% of total 126,406,213):
                             rb_vm_opt_send_without_block: 37,054,888 (29.3%)
                                               rb_vm_send: 10,068,319 ( 8.0%)
                                          rb_vm_env_write:  8,529,584 ( 6.7%)
                                             rb_hash_aref:  8,014,188 ( 6.3%)
                     rb_zjit_writebarrier_check_immediate:  7,697,828 ( 6.1%)
                                rb_vm_getinstancevariable:  5,954,987 ( 4.7%)
                           rb_ivar_get_at_no_ractor_check:  4,759,191 ( 3.8%)
                                        rb_obj_is_kind_of:  3,722,656 ( 2.9%)
                                        rb_vm_invokesuper:  2,663,433 ( 2.1%)
                                             rb_hash_aset:  2,416,121 ( 1.9%)
                                rb_vm_setinstancevariable:  2,355,463 ( 1.9%)
                               rb_vm_opt_getconstant_path:  2,297,784 ( 1.8%)
                                               Hash#fetch:  1,779,524 ( 1.4%)
                                                    fetch:  1,405,586 ( 1.1%)
                                        rb_vm_invokeblock:  1,385,970 ( 1.1%)
                                        rb_str_buf_append:  1,369,178 ( 1.1%)
                                rb_ec_ary_new_from_values:  1,336,805 ( 1.1%)
                               rb_class_allocate_instance:  1,281,590 ( 1.0%)
                                    rb_hash_new_with_size:    899,859 ( 0.7%)
                                        rb_vm_sendforward:    798,572 ( 0.6%)
Top-2 not optimized method types for send (100.0% of total 4,889,764):
  iseq: 4,886,942 (99.9%)
  null:     2,822 ( 0.1%)
Top-3 not optimized method types for send_without_block (100.0% of total 525,349):
        optimized_send: 478,875 (91.2%)
                  null:  42,175 ( 8.0%)
  optimized_block_call:   4,299 ( 0.8%)
Top-3 not optimized method types for super (100.0% of total 2,350,295):
    cfunc: 2,239,567 (95.3%)
    alias:   107,374 ( 4.6%)
  attrset:     3,354 ( 0.1%)
Top-3 instructions with uncategorized fallback reason (100.0% of total 2,216,938):
             invokeblock: 1,385,970 (62.5%)
             sendforward:   798,572 (36.0%)
  opt_send_without_block:    32,396 ( 1.5%)
Top-20 send fallback reasons (99.9% of total 51,971,182):
                          send_without_block_polymorphic: 18,639,354 (35.9%)
                                    singleton_class_seen:  9,274,307 (17.8%)
                          send_without_block_no_profiles:  7,217,551 (13.9%)
                          send_not_optimized_method_type:  4,889,764 ( 9.4%)
                                        send_no_profiles:  2,882,604 ( 5.5%)
                         super_not_optimized_method_type:  2,350,295 ( 4.5%)
                                           uncategorized:  2,216,938 ( 4.3%)
                            one_or_more_complex_arg_pass:  1,543,405 ( 3.0%)
                          send_without_block_megamorphic:    723,037 ( 1.4%)
                                        send_polymorphic:    544,570 ( 1.0%)
  send_without_block_not_optimized_method_type_optimized:    483,174 ( 0.9%)
        send_without_block_not_optimized_need_permission:    390,366 ( 0.8%)
                                   too_many_args_for_lir:    312,568 ( 0.6%)
                                 super_complex_args_pass:    111,053 ( 0.2%)
                          super_target_complex_args_pass:    104,723 ( 0.2%)
                                       super_polymorphic:     87,851 ( 0.2%)
                                     argc_param_mismatch:     50,382 ( 0.1%)
            send_without_block_not_optimized_method_type:     42,175 ( 0.1%)
                                obj_to_string_not_string:     34,861 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     32,436 ( 0.1%)
Top-4 setivar fallback reasons (100.0% of total 2,355,463):
            not_monomorphic: 2,132,748 (90.5%)
               not_t_object:   125,163 ( 5.3%)
                too_complex:    97,531 ( 4.1%)
  new_shape_needs_extension:        21 ( 0.0%)
Top-2 getivar fallback reasons (100.0% of total 6,080,097):
  not_monomorphic: 5,808,527 (95.5%)
      too_complex:   271,570 ( 4.5%)
Top-3 definedivar fallback reasons (100.0% of total 405,302):
  not_monomorphic: 397,150 (98.0%)
      too_complex:   5,122 ( 1.3%)
     not_t_object:   3,030 ( 0.7%)
Top-6 invokeblock handler (100.0% of total 1,385,970):
   monomorphic_iseq: 688,147 (49.7%)
        polymorphic: 523,864 (37.8%)
  monomorphic_other: 106,268 ( 7.7%)
  monomorphic_ifunc:  55,505 ( 4.0%)
        megamorphic:   6,762 ( 0.5%)
        no_profiles:   5,424 ( 0.4%)
Top-8 popular complex argument-parameter features not optimized (100.0% of total 1,850,659):
  param_forwardable: 685,936 (37.1%)
        param_block: 641,355 (34.7%)
         param_rest: 327,046 (17.7%)
       param_kwrest: 120,210 ( 6.5%)
    caller_kw_splat:  36,147 ( 2.0%)
       caller_splat:  34,029 ( 1.8%)
    caller_blockarg:   5,826 ( 0.3%)
       caller_kwarg:     110 ( 0.0%)
Top-1 compile error reasons (100.0% of total 191,769):
  exception_handler: 191,769 (100.0%)
Top-6 unhandled YARV insns (100.0% of total 89,278):
  invokesuperforward: 81,667 (91.5%)
         getconstant:  3,318 ( 3.7%)
       setblockparam:  2,837 ( 3.2%)
          checkmatch:    929 ( 1.0%)
         expandarray:    360 ( 0.4%)
                once:    167 ( 0.2%)
Top-3 unhandled HIR insns (100.0% of total 236,976):
          throw: 198,481 (83.8%)
  invokebuiltin:  35,774 (15.1%)
      array_max:   2,721 ( 1.1%)
Top-20 side exit reasons (100.0% of total 15,409,202):
                   guard_type_failure: 6,871,609 (44.6%)
                  guard_shape_failure: 6,854,409 (44.5%)
  block_param_proxy_not_iseq_or_ifunc: 1,008,346 ( 6.5%)
                   unhandled_hir_insn:   236,976 ( 1.5%)
                        compile_error:   191,769 ( 1.2%)
                  unhandled_yarv_insn:    89,278 ( 0.6%)
                 fixnum_mult_overflow:    50,739 ( 0.3%)
           block_param_proxy_modified:    28,119 ( 0.2%)
     patchpoint_stable_constant_names:    19,872 ( 0.1%)
         unhandled_newarray_send_pack:    14,481 ( 0.1%)
                  unhandled_block_arg:    13,787 ( 0.1%)
               fixnum_lshift_overflow:    10,085 ( 0.1%)
              patchpoint_no_ep_escape:     7,815 ( 0.1%)
                  expandarray_failure:     4,532 ( 0.0%)
             guard_super_method_entry:     4,475 ( 0.0%)
          patchpoint_method_redefined:     1,212 ( 0.0%)
        patchpoint_no_singleton_class:     1,130 ( 0.0%)
               obj_to_string_fallback:       275 ( 0.0%)
                   guard_less_failure:       163 ( 0.0%)
                            interrupt:       111 ( 0.0%)
                             send_count: 152,221,918
                     dynamic_send_count:  51,971,182 (34.1%)
                   optimized_send_count: 100,250,736 (65.9%)
                  dynamic_setivar_count:   2,355,463 ( 1.5%)
                  dynamic_getivar_count:   6,080,097 ( 4.0%)
              dynamic_definedivar_count:     405,302 ( 0.3%)
              iseq_optimized_send_count:  40,162,692 (26.4%)
      inline_cfunc_optimized_send_count:  40,296,415 (26.5%)
       inline_iseq_optimized_send_count:   3,344,046 ( 2.2%)
non_variadic_cfunc_optimized_send_count:   8,915,909 ( 5.9%)
    variadic_cfunc_optimized_send_count:   7,531,674 ( 4.9%)
compiled_iseq_count:                               5,554
failed_iseq_count:                                     0
compile_time:                                    1,779ms
profile_time:                                       13ms
gc_time:                                            19ms
invalidation_time:                                 248ms
vm_write_pc_count:                           133,179,978
vm_write_sp_count:                           133,179,978
vm_write_locals_count:                       129,160,863
vm_write_stack_count:                        129,160,863
vm_write_to_parent_iseq_local_count:             693,262
vm_read_from_parent_iseq_local_count:         14,736,626
guard_type_count:                            157,425,618
guard_type_exit_ratio:                              4.4%
guard_shape_count:                            64,005,824
guard_shape_exit_ratio:                            10.7%
code_region_bytes:                            29,147,136
zjit_alloc_bytes:                             44,468,338
total_mem_bytes:                              73,615,474
side_exit_count:                              15,409,202
total_insn_count:                            934,468,730
vm_insn_count:                               166,726,703
zjit_insn_count:                             767,742,027
ratio_in_zjit:                                     82.2%
```

</details>

<details>

<summary>after patch</summary>

```
Average of last 10, non-warmup iters: 648ms
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (59.5% of total 15,571,939):
                                               Hash#fetch: 3,185,114 (20.5%)
                                            Regexp#match?:   708,795 ( 4.6%)
                                                Hash#key?:   696,422 ( 4.5%)
                                              String#sub!:   489,841 ( 3.1%)
                                             Set#include?:   396,625 ( 2.5%)
                                                String#<<:   396,279 ( 2.5%)
                                       String#start_with?:   370,465 ( 2.4%)
                                              Hash#delete:   325,992 ( 2.1%)
                                               String.new:   307,248 ( 2.0%)
                                              Integer#===:   277,929 ( 1.8%)
                                         Symbol#end_with?:   255,540 ( 1.6%)
                                             Kernel#is_a?:   246,961 ( 1.6%)
                                    Process.clock_gettime:   221,588 ( 1.4%)
                                                Integer#>:   219,718 ( 1.4%)
                                            String#match?:   218,057 ( 1.4%)
                                               Integer#<=:   202,617 ( 1.3%)
                                                Time#to_i:   192,214 ( 1.2%)
                                              Time#subsec:   189,240 ( 1.2%)
                                            String#to_sym:   185,593 ( 1.2%)
                                          String#include?:   182,863 ( 1.2%)
Top-20 calls to C functions from JIT code (83.7% of total 126,248,940):
                             rb_vm_opt_send_without_block: 36,875,422 (29.2%)
                                               rb_vm_send: 10,068,311 ( 8.0%)
                                          rb_vm_env_write:  8,529,572 ( 6.8%)
                                             rb_hash_aref:  8,014,184 ( 6.3%)
                     rb_zjit_writebarrier_check_immediate:  7,697,776 ( 6.1%)
                                rb_vm_getinstancevariable:  5,934,206 ( 4.7%)
                           rb_ivar_get_at_no_ractor_check:  4,759,185 ( 3.8%)
                                        rb_obj_is_kind_of:  3,745,913 ( 3.0%)
                                        rb_vm_invokesuper:  2,663,429 ( 2.1%)
                                             rb_hash_aset:  2,416,112 ( 1.9%)
                                rb_vm_setinstancevariable:  2,361,107 ( 1.9%)
                               rb_vm_opt_getconstant_path:  2,294,768 ( 1.8%)
                                               Hash#fetch:  1,779,524 ( 1.4%)
                                                    fetch:  1,405,590 ( 1.1%)
                                        rb_vm_invokeblock:  1,385,975 ( 1.1%)
                                        rb_str_buf_append:  1,369,179 ( 1.1%)
                                rb_ec_ary_new_from_values:  1,336,806 ( 1.1%)
                               rb_class_allocate_instance:  1,281,533 ( 1.0%)
                                    rb_hash_new_with_size:    899,857 ( 0.7%)
                                        rb_vm_sendforward:    798,572 ( 0.6%)
Top-2 not optimized method types for send (100.0% of total 4,889,758):
  iseq: 4,886,936 (99.9%)
  null:     2,822 ( 0.1%)
Top-3 not optimized method types for send_without_block (100.0% of total 525,350):
        optimized_send: 478,875 (91.2%)
                  null:  42,176 ( 8.0%)
  optimized_block_call:   4,299 ( 0.8%)
Top-3 not optimized method types for super (100.0% of total 2,350,289):
    cfunc: 2,239,565 (95.3%)
    alias:   107,374 ( 4.6%)
  attrset:     3,350 ( 0.1%)
Top-4 instructions with uncategorized fallback reason (100.0% of total 2,298,609):
             invokeblock: 1,385,975 (60.3%)
             sendforward:   798,572 (34.7%)
      invokesuperforward:    81,666 ( 3.6%)
  opt_send_without_block:    32,396 ( 1.4%)
Top-20 send fallback reasons (99.9% of total 51,873,375):
                          send_without_block_polymorphic: 18,540,291 (35.7%)
                                    singleton_class_seen:  9,210,394 (17.8%)
                          send_without_block_no_profiles:  7,202,051 (13.9%)
                          send_not_optimized_method_type:  4,889,758 ( 9.4%)
                                        send_no_profiles:  2,882,602 ( 5.6%)
                         super_not_optimized_method_type:  2,350,289 ( 4.5%)
                                           uncategorized:  2,298,609 ( 4.4%)
                            one_or_more_complex_arg_pass:  1,543,404 ( 3.0%)
                          send_without_block_megamorphic:    723,037 ( 1.4%)
                                        send_polymorphic:    544,570 ( 1.0%)
  send_without_block_not_optimized_method_type_optimized:    483,174 ( 0.9%)
        send_without_block_not_optimized_need_permission:    389,384 ( 0.8%)
                                   too_many_args_for_lir:    312,568 ( 0.6%)
                                 super_complex_args_pass:    111,054 ( 0.2%)
                          super_target_complex_args_pass:    104,723 ( 0.2%)
                                       super_polymorphic:     87,852 ( 0.2%)
                                     argc_param_mismatch:     50,382 ( 0.1%)
            send_without_block_not_optimized_method_type:     42,176 ( 0.1%)
                                obj_to_string_not_string:     34,853 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     32,436 ( 0.1%)
Top-4 setivar fallback reasons (100.0% of total 2,361,107):
            not_monomorphic: 2,138,392 (90.6%)
               not_t_object:   125,163 ( 5.3%)
                too_complex:    97,531 ( 4.1%)
  new_shape_needs_extension:        21 ( 0.0%)
Top-2 getivar fallback reasons (100.0% of total 6,059,319):
  not_monomorphic: 5,787,746 (95.5%)
      too_complex:   271,573 ( 4.5%)
Top-3 definedivar fallback reasons (100.0% of total 405,302):
  not_monomorphic: 397,150 (98.0%)
      too_complex:   5,122 ( 1.3%)
     not_t_object:   3,030 ( 0.7%)
Top-6 invokeblock handler (100.0% of total 1,385,975):
   monomorphic_iseq: 688,157 (49.7%)
        polymorphic: 523,861 (37.8%)
  monomorphic_other: 106,268 ( 7.7%)
  monomorphic_ifunc:  55,505 ( 4.0%)
        megamorphic:   6,760 ( 0.5%)
        no_profiles:   5,424 ( 0.4%)
Top-8 popular complex argument-parameter features not optimized (100.0% of total 1,850,658):
  param_forwardable: 685,941 (37.1%)
        param_block: 641,355 (34.7%)
         param_rest: 327,046 (17.7%)
       param_kwrest: 120,209 ( 6.5%)
    caller_kw_splat:  36,147 ( 2.0%)
       caller_splat:  34,029 ( 1.8%)
    caller_blockarg:   5,821 ( 0.3%)
       caller_kwarg:     110 ( 0.0%)
Top-1 compile error reasons (100.0% of total 191,769):
  exception_handler: 191,769 (100.0%)
Top-5 unhandled YARV insns (100.0% of total 7,611):
    getconstant: 3,318 (43.6%)
  setblockparam: 2,837 (37.3%)
     checkmatch:   929 (12.2%)
    expandarray:   360 ( 4.7%)
           once:   167 ( 2.2%)
Top-3 unhandled HIR insns (100.0% of total 236,976):
          throw: 198,481 (83.8%)
  invokebuiltin:  35,774 (15.1%)
      array_max:   2,721 ( 1.1%)
Top-20 side exit reasons (100.0% of total 15,343,302):
                   guard_type_failure: 6,886,972 (44.9%)
                  guard_shape_failure: 6,854,835 (44.7%)
  block_param_proxy_not_iseq_or_ifunc: 1,008,346 ( 6.6%)
                   unhandled_hir_insn:   236,976 ( 1.5%)
                        compile_error:   191,769 ( 1.2%)
                 fixnum_mult_overflow:    50,739 ( 0.3%)
           block_param_proxy_modified:    28,119 ( 0.2%)
     patchpoint_stable_constant_names:    19,858 ( 0.1%)
         unhandled_newarray_send_pack:    14,481 ( 0.1%)
                  unhandled_block_arg:    13,787 ( 0.1%)
               fixnum_lshift_overflow:    10,085 ( 0.1%)
              patchpoint_no_ep_escape:     7,815 ( 0.1%)
                  unhandled_yarv_insn:     7,611 ( 0.0%)
                  expandarray_failure:     4,533 ( 0.0%)
             guard_super_method_entry:     4,475 ( 0.0%)
          patchpoint_method_redefined:     1,212 ( 0.0%)
        patchpoint_no_singleton_class:     1,130 ( 0.0%)
               obj_to_string_fallback:       275 ( 0.0%)
                   guard_less_failure:       163 ( 0.0%)
                            interrupt:       102 ( 0.0%)
                             send_count: 152,019,764
                     dynamic_send_count:  51,873,375 (34.1%)
                   optimized_send_count: 100,146,389 (65.9%)
                  dynamic_setivar_count:   2,361,107 ( 1.6%)
                  dynamic_getivar_count:   6,059,319 ( 4.0%)
              dynamic_definedivar_count:     405,302 ( 0.3%)
              iseq_optimized_send_count:  40,149,182 (26.4%)
      inline_cfunc_optimized_send_count:  40,168,875 (26.4%)
       inline_iseq_optimized_send_count:   3,408,619 ( 2.2%)
non_variadic_cfunc_optimized_send_count:   8,896,927 ( 5.9%)
    variadic_cfunc_optimized_send_count:   7,522,786 ( 4.9%)
compiled_iseq_count:                               5,554
failed_iseq_count:                                     0
compile_time:                                    1,784ms
profile_time:                                       13ms
gc_time:                                            19ms
invalidation_time:                                 261ms
vm_write_pc_count:                           133,027,580
vm_write_sp_count:                           133,027,580
vm_write_locals_count:                       129,024,228
vm_write_stack_count:                        129,024,228
vm_write_to_parent_iseq_local_count:             693,264
vm_read_from_parent_iseq_local_count:         14,727,716
guard_type_count:                            157,500,381
guard_type_exit_ratio:                              4.4%
guard_shape_count:                            64,160,894
guard_shape_exit_ratio:                            10.7%
code_region_bytes:                            29,196,288
zjit_alloc_bytes:                             44,686,498
total_mem_bytes:                              73,882,786
side_exit_count:                              15,343,302
total_insn_count:                            934,219,385
vm_insn_count:                               167,485,651
zjit_insn_count:                             766,733,734
ratio_in_zjit:                                     82.1%
```

</details>




### rails-bench

<details>

<summary>before patch</summary>

```
Average of last 10, non-warmup iters: 1146ms
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (52.4% of total 38,306,776):
                                  Hash#key?: 3,141,619 ( 8.2%)
                              Regexp#match?: 2,420,225 ( 6.3%)
                                 Hash#fetch: 2,245,557 ( 5.9%)
                                Integer#===: 1,098,163 ( 2.9%)
                                Hash#delete: 1,014,375 ( 2.6%)
                                 Array#any?: 1,007,766 ( 2.6%)
                                 String.new: 1,004,713 ( 2.6%)
                                   String#b:   797,913 ( 2.1%)
                              String#to_sym:   680,943 ( 1.8%)
                                 Array#all?:   650,132 ( 1.7%)
                              Fiber.current:   649,003 ( 1.7%)
                                 Array#join:   641,038 ( 1.7%)
                             Array#include?:   613,837 ( 1.6%)
                               Kernel#Array:   610,311 ( 1.6%)
                                  String#<<:   606,240 ( 1.6%)
                           Symbol#end_with?:   598,807 ( 1.6%)
                      String#force_encoding:   593,535 ( 1.5%)
                                 Kernel#dup:   580,051 ( 1.5%)
                                   Array#[]:   562,360 ( 1.5%)
                         Kernel#respond_to?:   550,441 ( 1.4%)
Top-20 calls to C functions from JIT code (75.5% of total 262,197,810):
               rb_vm_opt_send_without_block: 54,534,682 (20.8%)
                               rb_hash_aref: 22,920,285 ( 8.7%)
                            rb_vm_env_write: 19,385,633 ( 7.4%)
                                 rb_vm_send: 17,070,477 ( 6.5%)
       rb_zjit_writebarrier_check_immediate: 13,780,973 ( 5.3%)
                  rb_vm_getinstancevariable: 12,379,513 ( 4.7%)
             rb_ivar_get_at_no_ractor_check: 12,156,906 ( 4.6%)
                          rb_vm_invokesuper:  8,086,665 ( 3.1%)
                               rb_hash_aset:  5,043,536 ( 1.9%)
                          rb_obj_is_kind_of:  4,431,123 ( 1.7%)
                          rb_vm_invokeblock:  4,036,483 ( 1.5%)
                                  Hash#key?:  3,141,619 ( 1.2%)
                 rb_vm_opt_getconstant_path:  3,053,319 ( 1.2%)
                 rb_class_allocate_instance:  2,878,526 ( 1.1%)
                      rb_hash_new_with_size:  2,823,745 ( 1.1%)
                  rb_ec_ary_new_from_values:  2,585,553 ( 1.0%)
                     rb_str_concat_literals:  2,450,764 ( 0.9%)
                              Regexp#match?:  2,420,225 ( 0.9%)
                               rb_obj_alloc:  2,419,171 ( 0.9%)
                  rb_vm_setinstancevariable:  2,357,067 ( 0.9%)
Top-2 not optimized method types for send (100.0% of total 8,550,760):
       iseq: 8,518,289 (99.6%)
  optimized:    32,471 ( 0.4%)
Top-2 not optimized method types for send_without_block (100.0% of total 789,641):
  optimized_send: 606,885 (76.9%)
            null: 182,756 (23.1%)
Top-2 not optimized method types for super (100.0% of total 6,689,859):
    cfunc: 6,640,180 (99.3%)
  attrset:    49,679 ( 0.7%)
Top-3 instructions with uncategorized fallback reason (100.0% of total 5,962,039):
             invokeblock: 4,036,483 (67.7%)
             sendforward: 1,871,601 (31.4%)
  opt_send_without_block:    53,955 ( 0.9%)
Top-20 send fallback reasons (100.0% of total 85,599,908):
                          send_without_block_polymorphic: 31,804,276 (37.2%)
                          send_without_block_no_profiles: 13,349,825 (15.6%)
                          send_not_optimized_method_type:  8,550,760 (10.0%)
                         super_not_optimized_method_type:  6,689,859 ( 7.8%)
                                           uncategorized:  5,962,039 ( 7.0%)
                                        send_no_profiles:  5,200,278 ( 6.1%)
                            one_or_more_complex_arg_pass:  4,198,502 ( 4.9%)
                                        send_polymorphic:  3,318,658 ( 3.9%)
        send_without_block_not_optimized_need_permission:  1,274,177 ( 1.5%)
                                   too_many_args_for_lir:  1,139,487 ( 1.3%)
                                    singleton_class_seen:  1,101,973 ( 1.3%)
                                 super_complex_args_pass:    829,842 ( 1.0%)
  send_without_block_not_optimized_method_type_optimized:    606,885 ( 0.7%)
                          send_without_block_megamorphic:    565,874 ( 0.7%)
                          super_target_complex_args_pass:    414,600 ( 0.5%)
            send_without_block_not_optimized_method_type:    182,756 ( 0.2%)
                                obj_to_string_not_string:    158,141 ( 0.2%)
                                   super_call_with_block:    100,004 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     99,588 ( 0.1%)
                                       super_polymorphic:     52,360 ( 0.1%)
Top-2 setivar fallback reasons (100.0% of total 2,357,067):
  not_monomorphic: 2,255,283 (95.7%)
     not_t_object:   101,784 ( 4.3%)
Top-1 getivar fallback reasons (100.0% of total 12,379,538):
  not_monomorphic: 12,379,538 (100.0%)
Top-2 definedivar fallback reasons (100.0% of total 350,548):
  not_monomorphic: 350,461 (100.0%)
     not_t_object:      87 ( 0.0%)
Top-6 invokeblock handler (100.0% of total 4,036,483):
   monomorphic_iseq: 2,189,057 (54.2%)
        polymorphic: 1,207,002 (29.9%)
  monomorphic_other:   334,248 ( 8.3%)
  monomorphic_ifunc:   221,225 ( 5.5%)
        megamorphic:    84,439 ( 2.1%)
        no_profiles:       512 ( 0.0%)
Top-8 popular complex argument-parameter features not optimized (100.0% of total 5,212,154):
  param_forwardable: 1,824,953 (35.0%)
        param_block: 1,792,214 (34.4%)
         param_rest:   861,894 (16.5%)
       caller_splat:   283,669 ( 5.4%)
    caller_kw_splat:   248,291 ( 4.8%)
       param_kwrest:   200,208 ( 3.8%)
    caller_blockarg:       752 ( 0.0%)
       caller_kwarg:       173 ( 0.0%)
Top-1 compile error reasons (100.0% of total 391,562):
  exception_handler: 391,562 (100.0%)
Top-6 unhandled YARV insns (100.0% of total 1,000,531):
  invokesuperforward: 498,993 (49.9%)
         getconstant: 400,945 (40.1%)
         expandarray:  49,985 ( 5.0%)
       setblockparam:  49,972 ( 5.0%)
          checkmatch:     480 ( 0.0%)
                once:     156 ( 0.0%)
Top-2 unhandled HIR insns (100.0% of total 268,151):
          throw: 232,560 (86.7%)
  invokebuiltin:  35,591 (13.3%)
Top-19 side exit reasons (100.0% of total 8,709,784):
                  guard_shape_failure: 2,497,335 (28.7%)
  block_param_proxy_not_iseq_or_ifunc: 1,988,408 (22.8%)
                   guard_type_failure: 1,722,007 (19.8%)
                  unhandled_yarv_insn: 1,000,531 (11.5%)
                        compile_error:   391,562 ( 4.5%)
         unhandled_newarray_send_pack:   298,017 ( 3.4%)
                   unhandled_hir_insn:   268,151 ( 3.1%)
          patchpoint_method_redefined:   200,632 ( 2.3%)
                  unhandled_block_arg:   151,295 ( 1.7%)
           block_param_proxy_modified:   124,245 ( 1.4%)
                   guard_less_failure:    50,126 ( 0.6%)
               fixnum_lshift_overflow:     9,985 ( 0.1%)
     patchpoint_stable_constant_names:     6,350 ( 0.1%)
                 fixnum_mult_overflow:       570 ( 0.0%)
               obj_to_string_fallback:       405 ( 0.0%)
              patchpoint_no_ep_escape:       109 ( 0.0%)
                            interrupt:        42 ( 0.0%)
             guard_super_method_entry:         8 ( 0.0%)
             guard_greater_eq_failure:         6 ( 0.0%)
                             send_count: 329,199,237
                     dynamic_send_count:  85,599,908 (26.0%)
                   optimized_send_count: 243,599,329 (74.0%)
                  dynamic_setivar_count:   2,357,067 ( 0.7%)
                  dynamic_getivar_count:  12,379,538 ( 3.8%)
              dynamic_definedivar_count:     350,548 ( 0.1%)
              iseq_optimized_send_count:  93,946,576 (28.5%)
      inline_cfunc_optimized_send_count:  97,478,983 (29.6%)
       inline_iseq_optimized_send_count:   9,138,886 ( 2.8%)
non_variadic_cfunc_optimized_send_count:  25,367,116 ( 7.7%)
    variadic_cfunc_optimized_send_count:  17,667,768 ( 5.4%)
compiled_iseq_count:                               2,888
failed_iseq_count:                                     0
compile_time:                                      876ms
profile_time:                                       28ms
gc_time:                                             6ms
invalidation_time:                                   8ms
vm_write_pc_count:                           287,051,837
vm_write_sp_count:                           287,051,837
vm_write_locals_count:                       273,948,883
vm_write_stack_count:                        273,948,883
vm_write_to_parent_iseq_local_count:           1,079,877
vm_read_from_parent_iseq_local_count:         30,814,984
guard_type_count:                            310,888,965
guard_type_exit_ratio:                              0.6%
guard_shape_count:                           108,669,058
guard_shape_exit_ratio:                             2.3%
code_region_bytes:                            14,352,384
zjit_alloc_bytes:                             18,992,674
total_mem_bytes:                              33,345,058
side_exit_count:                               8,709,784
total_insn_count:                          1,705,856,454
vm_insn_count:                               122,246,885
zjit_insn_count:                           1,583,609,569
ratio_in_zjit:                                     92.8%
```

</details>

<details>

<summary>after patch</summary>

```
Average of last 10, non-warmup iters: 1072ms
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (52.5% of total 38,239,504):
                                  Hash#key?: 3,141,619 ( 8.2%)
                              Regexp#match?: 2,420,215 ( 6.3%)
                                 Hash#fetch: 2,245,557 ( 5.9%)
                                Integer#===: 1,097,515 ( 2.9%)
                                Hash#delete: 1,014,375 ( 2.7%)
                                 Array#any?: 1,007,756 ( 2.6%)
                                 String.new: 1,004,713 ( 2.6%)
                                   String#b:   797,913 ( 2.1%)
                              String#to_sym:   680,943 ( 1.8%)
                                 Array#all?:   650,132 ( 1.7%)
                              Fiber.current:   649,003 ( 1.7%)
                                 Array#join:   641,038 ( 1.7%)
                             Array#include?:   613,837 ( 1.6%)
                               Kernel#Array:   610,311 ( 1.6%)
                                  String#<<:   606,240 ( 1.6%)
                           Symbol#end_with?:   598,807 ( 1.6%)
                      String#force_encoding:   593,535 ( 1.6%)
                                 Kernel#dup:   580,051 ( 1.5%)
                                   Array#[]:   562,360 ( 1.5%)
                         Kernel#respond_to?:   550,441 ( 1.4%)
Top-20 calls to C functions from JIT code (75.4% of total 262,218,592):
               rb_vm_opt_send_without_block: 54,249,429 (20.7%)
                               rb_hash_aref: 22,920,271 ( 8.7%)
                            rb_vm_env_write: 19,385,609 ( 7.4%)
                                 rb_vm_send: 17,070,463 ( 6.5%)
       rb_zjit_writebarrier_check_immediate: 13,780,893 ( 5.3%)
                  rb_vm_getinstancevariable: 12,322,924 ( 4.7%)
             rb_ivar_get_at_no_ractor_check: 12,156,898 ( 4.6%)
                          rb_vm_invokesuper:  8,086,659 ( 3.1%)
                               rb_hash_aset:  5,043,532 ( 1.9%)
                          rb_obj_is_kind_of:  4,474,826 ( 1.7%)
                          rb_vm_invokeblock:  4,036,471 ( 1.5%)
                                  Hash#key?:  3,141,619 ( 1.2%)
                 rb_vm_opt_getconstant_path:  3,053,286 ( 1.2%)
                 rb_class_allocate_instance:  2,878,505 ( 1.1%)
                      rb_hash_new_with_size:  2,823,748 ( 1.1%)
                  rb_ec_ary_new_from_values:  2,585,561 ( 1.0%)
                     rb_str_concat_literals:  2,450,756 ( 0.9%)
                              Regexp#match?:  2,420,215 ( 0.9%)
                               rb_obj_alloc:  2,419,146 ( 0.9%)
                  rb_vm_setinstancevariable:  2,357,065 ( 0.9%)
Top-2 not optimized method types for send (100.0% of total 8,550,755):
       iseq: 8,518,284 (99.6%)
  optimized:    32,471 ( 0.4%)
Top-2 not optimized method types for send_without_block (100.0% of total 789,641):
  optimized_send: 606,885 (76.9%)
            null: 182,756 (23.1%)
Top-2 not optimized method types for super (100.0% of total 6,689,853):
    cfunc: 6,640,178 (99.3%)
  attrset:    49,675 ( 0.7%)
Top-4 instructions with uncategorized fallback reason (100.0% of total 6,461,020):
             invokeblock: 4,036,471 (62.5%)
             sendforward: 1,871,601 (29.0%)
      invokesuperforward:   498,993 ( 7.7%)
  opt_send_without_block:    53,955 ( 0.8%)
Top-20 send fallback reasons (100.0% of total 85,813,616):
                          send_without_block_polymorphic: 31,519,543 (36.7%)
                          send_without_block_no_profiles: 13,349,751 (15.6%)
                          send_not_optimized_method_type:  8,550,755 (10.0%)
                         super_not_optimized_method_type:  6,689,853 ( 7.8%)
                                           uncategorized:  6,461,020 ( 7.5%)
                                        send_no_profiles:  5,200,273 ( 6.1%)
                            one_or_more_complex_arg_pass:  4,198,498 ( 4.9%)
                                        send_polymorphic:  3,318,658 ( 3.9%)
        send_without_block_not_optimized_need_permission:  1,273,739 ( 1.5%)
                                   too_many_args_for_lir:  1,139,487 ( 1.3%)
                                    singleton_class_seen:  1,101,973 ( 1.3%)
                                 super_complex_args_pass:    829,842 ( 1.0%)
  send_without_block_not_optimized_method_type_optimized:    606,885 ( 0.7%)
                          send_without_block_megamorphic:    565,874 ( 0.7%)
                          super_target_complex_args_pass:    414,600 ( 0.5%)
            send_without_block_not_optimized_method_type:    182,756 ( 0.2%)
                                obj_to_string_not_string:    158,133 ( 0.2%)
                                   super_call_with_block:    100,004 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     99,588 ( 0.1%)
                                       super_polymorphic:     52,360 ( 0.1%)
Top-2 setivar fallback reasons (100.0% of total 2,357,065):
  not_monomorphic: 2,255,281 (95.7%)
     not_t_object:   101,784 ( 4.3%)
Top-1 getivar fallback reasons (100.0% of total 12,322,949):
  not_monomorphic: 12,322,949 (100.0%)
Top-2 definedivar fallback reasons (100.0% of total 350,548):
  not_monomorphic: 350,461 (100.0%)
     not_t_object:      87 ( 0.0%)
Top-6 invokeblock handler (100.0% of total 4,036,471):
   monomorphic_iseq: 2,189,045 (54.2%)
        polymorphic: 1,207,002 (29.9%)
  monomorphic_other:   334,248 ( 8.3%)
  monomorphic_ifunc:   221,225 ( 5.5%)
        megamorphic:    84,439 ( 2.1%)
        no_profiles:       512 ( 0.0%)
Top-8 popular complex argument-parameter features not optimized (100.0% of total 5,212,150):
  param_forwardable: 1,824,953 (35.0%)
        param_block: 1,792,214 (34.4%)
         param_rest:   861,894 (16.5%)
       caller_splat:   283,669 ( 5.4%)
    caller_kw_splat:   248,291 ( 4.8%)
       param_kwrest:   200,208 ( 3.8%)
    caller_blockarg:       748 ( 0.0%)
       caller_kwarg:       173 ( 0.0%)
Top-1 compile error reasons (100.0% of total 391,562):
  exception_handler: 391,562 (100.0%)
Top-5 unhandled YARV insns (100.0% of total 501,538):
    getconstant: 400,945 (79.9%)
    expandarray:  49,985 (10.0%)
  setblockparam:  49,972 (10.0%)
     checkmatch:     480 ( 0.1%)
           once:     156 ( 0.0%)
Top-2 unhandled HIR insns (100.0% of total 268,152):
          throw: 232,560 (86.7%)
  invokebuiltin:  35,592 (13.3%)
Top-19 side exit reasons (100.0% of total 8,210,699):
                  guard_shape_failure: 2,497,552 (30.4%)
  block_param_proxy_not_iseq_or_ifunc: 1,988,408 (24.2%)
                   guard_type_failure: 1,721,809 (21.0%)
                  unhandled_yarv_insn:   501,538 ( 6.1%)
                        compile_error:   391,562 ( 4.8%)
         unhandled_newarray_send_pack:   298,017 ( 3.6%)
                   unhandled_hir_insn:   268,152 ( 3.3%)
          patchpoint_method_redefined:   200,632 ( 2.4%)
                  unhandled_block_arg:   151,295 ( 1.8%)
           block_param_proxy_modified:   124,245 ( 1.5%)
                   guard_less_failure:    50,033 ( 0.6%)
               fixnum_lshift_overflow:     9,985 ( 0.1%)
     patchpoint_stable_constant_names:     6,342 ( 0.1%)
                 fixnum_mult_overflow:       570 ( 0.0%)
               obj_to_string_fallback:       405 ( 0.0%)
              patchpoint_no_ep_escape:       109 ( 0.0%)
                            interrupt:        31 ( 0.0%)
             guard_super_method_entry:         8 ( 0.0%)
             guard_greater_eq_failure:         6 ( 0.0%)
                             send_count: 328,805,013
                     dynamic_send_count:  85,813,616 (26.1%)
                   optimized_send_count: 242,991,397 (73.9%)
                  dynamic_setivar_count:   2,357,065 ( 0.7%)
                  dynamic_getivar_count:  12,322,949 ( 3.7%)
              dynamic_definedivar_count:     350,548 ( 0.1%)
              iseq_optimized_send_count:  93,990,621 (28.6%)
      inline_cfunc_optimized_send_count:  96,851,696 (29.5%)
       inline_iseq_optimized_send_count:   9,181,467 ( 2.8%)
non_variadic_cfunc_optimized_send_count:  25,304,458 ( 7.7%)
    variadic_cfunc_optimized_send_count:  17,663,155 ( 5.4%)
compiled_iseq_count:                               2,886
failed_iseq_count:                                     0
compile_time:                                      875ms
profile_time:                                       27ms
gc_time:                                            66ms
invalidation_time:                                   9ms
vm_write_pc_count:                           287,186,308
vm_write_sp_count:                           287,186,308
vm_write_locals_count:                       274,139,228
vm_write_stack_count:                        274,139,228
vm_write_to_parent_iseq_local_count:           1,079,877
vm_read_from_parent_iseq_local_count:         30,810,378
guard_type_count:                            310,644,961
guard_type_exit_ratio:                              0.6%
guard_shape_count:                           109,072,242
guard_shape_exit_ratio:                             2.3%
code_region_bytes:                            14,352,384
zjit_alloc_bytes:                             19,186,174
total_mem_bytes:                              33,538,558
side_exit_count:                               8,210,699
total_insn_count:                          1,705,193,555
vm_insn_count:                               123,691,343
zjit_insn_count:                           1,581,502,212
ratio_in_zjit:                                     92.7%
```

</details>
2026-01-27 14:53:24 -05:00
Luke Gruber
52e71ad4b7
Fix test for mutex starvation as well as small fix in thread_sync.c (#15982)
Don't reset `th->running_time_us` when unlocking from `mutex_free` or
force unlocking during thread destruction. Follow-up to 994257ab06072d.
2026-01-27 12:36:55 -05:00
Earlopain
5d769228c1 [ruby/prism] Remove Prism.lex_ripper
Since `on_sp` is emitted, it doesn't do a whole lot anymore.

This leaves one incompatibility for code like `"x#$%"`

Ripper confuses this for bare interpolation with a global, but `$%` is not a valid global name. Still,
it emits two string tokens in such a case. It doesn't make sense for prism to work around this bug,
so the affected files are added as excludes.

Since the only usage of this method makes sense for testing in prism itself,
the method is removed instead of deprecated.

https://github.com/ruby/prism/commit/31be379f98
2026-01-27 14:43:51 +00:00
Nobuyoshi Nakada
fa3e3d1090
Ignore EOL code changes [ci skip] 2026-01-27 23:38:38 +09:00
Jean Boussier
83713db7f1 gc.c: Fix rb_gc_obj_needs_cleanup_p
- T_BIGNUM may have fields via `#object_id`.
- The T_DATA logic was inversed. If `dfree` is unset we don't need cleanup.
2026-01-27 13:51:06 +01:00
Michael Yang
ade85c45da [ruby/resolv] remove test for every class
https://github.com/ruby/resolv/commit/96e483d55b
2026-01-27 10:02:02 +00:00
Michael Yang
c55d214ed3 [ruby/resolv] add getresources test for every resource typeclass
https://github.com/ruby/resolv/commit/4bad8bccfc
2026-01-27 10:02:02 +00:00
Michael Yang
09872ea950 [ruby/resolv] add missing typeclasses to doc
https://github.com/ruby/resolv/commit/78df896829
2026-01-27 10:02:02 +00:00
Peter Zhu
969fd30cb1 [ruby/net-http] [DOC] Fix links
The RDoc link format has changed so these are all broken links.

https://github.com/ruby/net-http/commit/97fe6085c3
2026-01-27 03:40:07 +00:00
Peter Zhu
491e38902c [DOC] Fix links to What's Here
The RDoc link format has changed so these are all broken links.
2026-01-26 17:18:19 -05:00
Max Bernstein
6b0dda496e
ZJIT: Add temporary local definite assignment validator (#15973)
Until we get our global register allocator, we need our HIR to be in
100% block-local SSA. Add a validator to enforce that.
2026-01-26 22:11:06 +00:00
BurdetteLamar
b7102933ee [DOC] Doc for Module.nesting 2026-01-26 17:07:53 -05:00
BurdetteLamar
21f8472e77 [DOC] Fix links in Array 2026-01-26 17:05:18 -05:00
BurdetteLamar
ed0a5c6f0f [DOC] Fix links in Complex 2026-01-26 17:04:58 -05:00
Aaron Patterson
2605d4e5fc ZJIT: Extract VRegId from a usize
We would like to do type matching on the VRegId.  Extracting the VRegID
from a usize makes the code a bit easier to understand and refactor.
MemBase uses a VReg, and there is also a VReg in Opnd.  We should be
sharing types between these two, so this is a step in the direction of
sharing a type
2026-01-26 12:47:56 -08:00
Luke Gruber
994257ab06
Prevent starvation when acquiring mutex over and over (#15877)
Continually locking a mutex m can lead to starvation if all other threads are on the waitq of m.

See https://bugs.ruby-lang.org/issues/21840 for more details.

Solution:

When a thread `T1` wakes up `T2` during mutex unlock but `T1` or any other thread successfully acquires it
before `T2`, then we record the `running_time` of the thread during mutex acquisition. Then during unlock, if
that thread's running_time is less than the saved running time, we set it back to the saved time.

Fixes [Bug #21840]
2026-01-26 14:34:37 -05:00
Matt Valentine-House
3c634893e2 Remove the unnecesary integer comparison
Most compilers will optimise this anyway
2026-01-26 18:01:09 +00:00
Matt Valentine-House
d15117e293 BIGNUM can't have fields other than object_id 2026-01-26 18:01:09 +00:00
Matt Valentine-House
7444f415db rename rb_gc_obj_free_on_sweep -> rb_gc_obj_needs_cleanup_p 2026-01-26 18:01:09 +00:00
Matt Valentine-House
8e73aa7ffe We don't need this wrapper function anymore 2026-01-26 18:01:09 +00:00
Matt Valentine-House
efde37b712 Move the gc fast path out of the default GC impl
It relies too much on VM level concerns, such that it can't be built
with modular GC enabled.

We'll move it into the VM, and then expose it to the GC
implementations so they can use it.
2026-01-26 18:01:09 +00:00
Matt Valentine-House
211714f1bf Clarify the use of some FLAGS 2026-01-26 18:01:09 +00:00
Matt Valentine-House
c21f3490d1 Implement a fast path for sweeping (gc_sweep_fast_path_p).
[Feature #21846]

There is a single path through our GC Sweeping code, and we always call
rb_gc_obj_free_vm_weak_references and rb_gc_obj_free before adding the
object back to the freelist.

We do this even when the object has no external resources that require
being free'd and has no weak references pointing to it.

This commit introduces a conservative fast path through gc_sweep_plane
that uses the object flags to identify certain cases where these calls
can be skipped - for these objects we just add them straight back on the
freelist. Any object for which gc_sweep_fast_path_p returns false will
use the current full sweep code (referred to here as the slow path).

Currently there are 2 checks that
will _always_ require an object to go down the slow path:

1. Has it's object_id been observed and stored in the id2ref_table
2. Has it got generic ivars in the gen_fields table

If neither of these are true, then we run some flag checks on the object
and send the following cases down the fast path:

- Objects that are not heap allocated
- Embedded strings that aren't in the fstring table
- Embedded Arrays
- Embedded Hashes
- Embedded Bignums
- Embedded Strings
- Floats, Rationals and Complex
- Various IMEMO subtypes that do no allocation

We've benchmarked this code using ruby-bench as well as the gcbench
benchmarks inside Ruby (benchmarks/gc) and this patch results in a
modest speed improvement on almost all of the headline benchmarks (2% in
railsbench with YJIT enabled), and an observable 30% improvement in time
spent sweeping during the GC benchmarks:

```
master: ruby 4.1.0dev (2026-01-19T12:03:33Z master 859920dfd2) +YJIT +PRISM [x86_64-linux]
experiment: ruby 4.1.0dev (2026-01-16T21:36:46Z mvh-sweep-fast-pat.. c3ffe377a1) +YJIT +PRISM [x86_64-linux]

--------------  -----------  ----------  ---------------  ----------  ------------------  -----------------
bench           master (ms)  stddev (%)  experiment (ms)  stddev (%)  experiment 1st itr  master/experiment
lobsters        N/A          N/A         N/A              N/A         N/A                 N/A
activerecord    132.5        0.9         132.5            1.0         1.056               1.001
chunky-png      577.2        0.4         580.1            0.4         0.994               0.995
erubi-rails     902.9        0.2         894.3            0.2         1.040               1.010
hexapdf         1763.9       3.3         1760.6           3.7         1.027               1.002
liquid-c        56.9         0.6         56.7             1.4         1.004               1.003
liquid-compile  46.3         2.1         46.1             2.1         1.005               1.004
liquid-render   77.8         0.8         75.1             0.9         1.023               1.036
mail            114.7        0.4         113.0            1.4         1.054               1.015
psych-load      1635.4       1.4         1625.9           0.5         0.988               1.006
railsbench      1685.4       2.4         1650.1           2.0         0.989               1.021
rubocop         133.5        8.1         130.3            7.8         1.002               1.024
ruby-lsp        140.3        1.9         137.5            1.8         1.007               1.020
sequel          64.6         0.7         63.9             0.7         1.003               1.011
shipit          1196.2       4.3         1181.5           4.2         1.003               1.012
--------------  -----------  ----------  ---------------  ----------  ------------------  -----------------

Legend:
- experiment 1st itr: ratio of master/experiment time for the first benchmarking iteration.
- master/experiment: ratio of master/experiment time. Higher is better for experiment. Above 1 represents a speedup.
```

```
Benchmark      │    Wall(B)   Sweep(B)  Mark(B) │    Wall(E)   Sweep(E)  Mark(E) │   Wall Δ  Sweep Δ
───────────────┼─────────────────────────────────┼─────────────────────────────────┼──────────────────
null           │     0.000s        1ms      4ms │     0.000s        1ms      4ms │       0%       0%
hash1          │     4.330s      875ms     46ms │     3.960s      531ms     44ms │ +8.6% +39.3%
hash2          │     6.356s      243ms    988ms │     6.298s      176ms    1.03s │ +0.9% +27.6%
rdoc           │    37.337s      2.42s    1.09s │    36.678s      2.11s    1.20s │ +1.8% +13.1%
binary_trees   │     3.366s      426ms    252ms │     3.082s      275ms    239ms │ +8.4% +35.4%
ring           │     5.252s       14ms    2.47s │     5.327s       12ms    2.43s │ -1.4% +14.3%
redblack       │     2.966s       28ms     41ms │     2.940s       21ms     38ms │ +0.9% +25.0%
───────────────┼─────────────────────────────────┼─────────────────────────────────┼──────────────────

Legend: (B) = Baseline, (E) = Experiment, Δ = improvement (positive = faster)
        Wall = total wallclock, Sweep = GC sweeping time, Mark = GC marking time
        Times are median of 3 runs
```

These results are also borne out when YJIT is disabled:

```
master: ruby 4.1.0dev (2026-01-19T12:03:33Z master 859920dfd2) +PRISM [x86_64-linux]
experiment: ruby 4.1.0dev (2026-01-16T21:36:46Z mvh-sweep-fast-pat.. c3ffe377a1) +PRISM [x86_64-linux]

--------------  -----------  ----------  ---------------  ----------  ------------------  -----------------
bench           master (ms)  stddev (%)  experiment (ms)  stddev (%)  experiment 1st itr  master/experiment
lobsters        N/A          N/A         N/A              N/A         N/A                 N/A
activerecord    389.6        0.3         377.5            0.3         1.032               1.032
chunky-png      1123.4       0.2         1109.2           0.2         1.013               1.013
erubi-rails     1754.3       0.1         1725.7           0.1         1.035               1.017
hexapdf         3346.5       0.9         3326.9           0.7         1.003               1.006
liquid-c        84.0         0.5         83.5             0.5         0.992               1.006
liquid-compile  74.0         1.5         73.5             1.4         1.011               1.008
liquid-render   199.9        0.4         199.6            0.4         1.000               1.002
mail            177.8        0.4         176.4            0.4         1.069               1.008
psych-load      2749.6       0.7         2777.0           0.0         0.980               0.990
railsbench      2983.0       1.0         2965.5           0.8         1.041               1.006
rubocop         228.8        1.0         227.5            1.2         1.015               1.005
ruby-lsp        221.8        0.9         216.1            0.8         1.011               1.026
sequel          89.1         0.5         89.1             1.8         1.005               1.000
shipit          2385.6       1.6         2371.8           1.0         1.002               1.006
--------------  -----------  ----------  ---------------  ----------  ------------------  -----------------

Legend:
- experiment 1st itr: ratio of master/experiment time for the first benchmarking iteration.
- master/experiment: ratio of master/experiment time. Higher is better for experiment. Above 1 represents a speedup.
```

```
Benchmark      │    Wall(B)   Sweep(B)  Mark(B) │    Wall(E)   Sweep(E)  Mark(E) │   Wall Δ  Sweep Δ
───────────────┼─────────────────────────────────┼─────────────────────────────────┼──────────────────
null           │     0.000s        1ms      4ms │     0.000s        1ms      3ms │       0%       0%
hash1          │     4.349s      877ms     45ms │     4.045s      532ms     44ms │ +7.0% +39.3%
hash2          │     6.575s      235ms    967ms │     6.540s      181ms    1.04s │ +0.5% +23.0%
rdoc           │    45.782s      2.23s    1.14s │    44.925s      1.90s    1.01s │ +1.9% +15.0%
binary_trees   │     6.433s      426ms    252ms │     6.268s      278ms    240ms │ +2.6% +34.7%
ring           │     6.584s       17ms    2.33s │     6.738s       13ms    2.33s │ -2.3% +30.8%
redblack       │    13.334s       31ms     42ms │    13.296s       24ms    107ms │ +0.3% +22.6%
───────────────┼─────────────────────────────────┼─────────────────────────────────┼──────────────────

Legend: (B) = Baseline, (E) = Experiment, Δ = improvement (positive = faster)
        Wall = total wallclock, Sweep = GC sweeping time, Mark = GC marking time
        Times are median of 3 runs
```
2026-01-26 18:01:09 +00:00
Chris Hasiński
5add7c3ea9
Fix RUBY_MN_THREADS sleep returning prematurely (#15868)
timer_thread_check_exceed() was returning true when the remaining time
was less than 1ms, treating it as "too short time". This caused
sub-millisecond sleeps (like sleep(0.0001)) to return immediately
instead of actually sleeping.

The fix removes this optimization that was incorrectly short-circuiting
short sleep durations. Now the timeout is only considered exceeded when
the actual deadline has passed.

Note: There's still a separate performance issue where MN_THREADS mode
is slower for sub-millisecond sleeps due to the timer thread using
millisecond-resolution polling. This will require a separate fix to
use sub-millisecond timeouts in kqueue/epoll.

[Bug #21836]
2026-01-26 10:17:35 -05:00
Kevin Newton
2947aa41d4 [ruby/prism] Use each_line to avoid allocating array
Though very unlikely, it could potentially allocate a large array
of whitespace.

https://github.com/ruby/prism/commit/3389947819
2026-01-26 14:43:01 +00:00
Earlopain
5f25420918 [ruby/prism] Fix on_words_sep for ripper translator with newlines
Ripper emits a token each per line.

https://github.com/ruby/prism/commit/4b5c9f5437
2026-01-26 11:34:49 +00:00
Hiroshi SHIBATA
e410d938fa Workround for directly loading Gem::Version 2026-01-26 20:24:14 +09:00
Hiroshi SHIBATA
a308311336 [ruby/rubygems] Removed unused deprecate loading
https://github.com/ruby/rubygems/commit/e379022ed0
2026-01-26 09:38:31 +00:00
Nobuyoshi Nakada
b839989fd2 win32: Add CR to all batch files.
This reverts commit 23f9a0d655c4d405bb2397a147a1523436205486, "win32:
Strip CR from batch files", and add CR to the other batch files too.

`cmd.exe` seems to work well with LF at a glance, but sometimes `goto`
jumps to an unexpected line.  This is probably because it is looking
for the beginning of a line, assuming that all lines end with CRLF,
and as a result mistaking the `goto` operand for a label.
2026-01-26 18:17:45 +09:00
Edouard CHIN
ace5b10de4 [ruby/rubygems] Fix Bundler that re-exec $0 when a version is present in the config:
- ### Problem

  If you have a `version` in your config file (this feature was
  introduced in #6817), then running any `bundle` command will
  make Bundler re-exec and ultimately run the `bundle` binstub twice.

  ### Details

  When the `bundle` binstub gets executed, a `require "bundler"` is
  evaluated. RubyGems tries to require the `bundler.rb` file from
  the right `bundler` gem (in the event where you have multiple
  bundler versions in your system).
  RubyGems will prioritize a bundler version based on a few
  heurisitics.

  b50c40c92a/lib/rubygems/bundler_version_finder.rb (L19-L21)

  This prioritize logic doesn't take into account the bundler version
  a user has specific in this config. So what happens is:

  1. User execute the `bundle` binstub
  2. `require 'bundler'` is evaluated.
  3. RubyGems prioritize activating the bundler version specified
     in the Gemfile.lock
  4. The CLI starts, and [Auto switch kicks in](b50c40c92a/bundler/lib/bundler/cli.rb (L81)). Bundler detects that
     user specifed a version in its config and the current Bundler
     version doesn't match.
  5. Bundler exit and re-exec with the right bundler version.

  ### Solution

  This patch introduce two fixes. First, it reads the bundler config
  file and check for the local config first and then the global
  config. This is because the local has precedence over global.

  Second, the prioritization takes into account the version in config
  and let RubyGems activate the right version in order to prevent
  re-exec moments later.

  Finally, I also want to fix this problem because its a step toward
  fixing https://github.com/ruby/rubygems/issues/8106. I'll open
  a follow up patch to explain.

https://github.com/ruby/rubygems/commit/d6e0f43133
2026-01-26 08:48:22 +00:00
Hiroshi SHIBATA
b3cca1e201 [ruby/rubygems] Re-generate certificates with sha256WithRSAEncryption for modern OS
https://github.com/ruby/rubygems/commit/41612df71d
2026-01-26 08:44:50 +00:00
Hiroshi SHIBATA
6e00da098a [ruby/rubygems] Revert "Merge pull request #8989 from nobu/test-tmpdir"
This reverts commit https://github.com/ruby/rubygems/commit/3aa3ee3ee440, reversing
changes made to https://github.com/ruby/rubygems/commit/d1ff3df70f55.

https://github.com/ruby/rubygems/commit/0231b5b1bc
2026-01-26 07:46:45 +00:00
Hiroshi SHIBATA
016b2628e8 [ruby/rubygems] Fixed missing classname
https://github.com/ruby/rubygems/commit/b2002d47d2
2026-01-26 07:01:48 +00:00
Nobuyoshi Nakada
b96416802d [ruby/rubygems] Do not pollute source directory by tests
https://github.com/ruby/rubygems/commit/ab3c2200d2
2026-01-26 07:01:47 +00:00
Edouard CHIN
78d9b454ce [ruby/rubygems] Fix RubyGems not able to require the right gem:
- Fix https://github.com/ruby/rubygems/issues/9238
- ### Problem

  This is an issue that bites gem maintainers from time to time, with
  the most recent one in https://github.com/minitest/minitest/issues/1040#issuecomment-3679370619

  The issue is summarized as follow:

  1) A gem "X" has a feature in "lib/feature.rb"
  2) Maintainer wants to extract this feature into its own gem "Y"
  3) Maintainer cut a release of X without that new feature.
  4) Users install the new version of X and also install the new
     gem "Y" since the feature is now extracted.
  5) When a call to "require 'feature'" is encountered, RG will
     fail to load the right gem, resulting in a `LoadError`.

  ### Details

  Now that we have two gems (old version of X and new gem Y) with
  the same path, RubyGems will detect that `feature.rb` can be loaded
  from the old version of X, but if the new version of X had already
  been loaded, then RubyGems will raise due to versions conflicting.

  ```ruby
  require 'x' # Loads the new version of X without the feature which was extracted.
  require 'feature' # Rubygems see that the old version of X include that file and tries to activate the spec.
  ```

  ### Solution

  I propose that RubyGems fallback to a spec that's not yet loaded.
  We try to find a spec by its path and filter it out in case a spec
  with the same name has already been loaded.

  Its worth to note that RubyGems already has a
  `find_inactive_by_path` but we can't use it. This method only checks
  if the spec object is active and doesn't look if other spec with the
  same name have been loaded. The new method we are introducing
  verifies this.

https://github.com/ruby/rubygems/commit/f298e2c68e
2026-01-26 05:56:37 +00:00
dependabot[bot]
ee32a2dc93 Bump lewagon/wait-on-check-action from 1.4.1 to 1.5.0
Bumps [lewagon/wait-on-check-action](https://github.com/lewagon/wait-on-check-action) from 1.4.1 to 1.5.0.
- [Release notes](https://github.com/lewagon/wait-on-check-action/releases)
- [Changelog](https://github.com/lewagon/wait-on-check-action/blob/master/CHANGELOG.md)
- [Commits](3603e826ee...74049309df)

---
updated-dependencies:
- dependency-name: lewagon/wait-on-check-action
  dependency-version: 1.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-25 18:32:38 -08:00
Nobuyoshi Nakada
2856aa67df
[DOC] State that an interpolated string in %W is not split
It is split statically at the parse time, not the whole string is
built then split.
2026-01-26 10:09:35 +09:00
Earlopain
9269069e90 [ruby/prism] Optimize ripper translator token sorting
With the benchmark from 2ea81398cc
Prism is:
* 1.33x slower before
* 1.07x slower after

https://github.com/ruby/prism/commit/a18b0acd80
2026-01-25 21:14:13 +00:00
Peter Zhu
b75938e2c3 [DOC] Improve class doc for Coverage 2026-01-25 10:09:17 -05:00
Nobuyoshi Nakada
23f9a0d655
win32: Strip CR from batch files
Recent versions of `cmd.exe` seem to work with just LF, and the other
batch files are LF only already.
2026-01-25 22:15:51 +09:00
Nobuyoshi Nakada
f23e554f68
Fix missing return
And align the condition with `enc_find_basename` to remove the code
path that `*baselen` potentially can be unset in that function.
2026-01-25 20:05:55 +09:00
Peter Zhu
8f9aade9be Fix warning in rb_file_s_basename
file.c:5053:16: warning: `f` may be used uninitialized [-Wmaybe-uninitialized]
    5053 |             if (!(f = rmext(p, f, n, fp, RSTRING_LEN(fext), enc))) {
         |                ^
2026-01-24 21:31:09 -05:00
Stan Lo
a00cc983dd
Ignore AI agents related files (#15955) 2026-01-25 01:47:23 +00:00
Earlopain
985b58a4ed [ruby/prism] Remove unneeded lex_compat token types
These are either fixed in prism or ruby/ripper itself.

https://github.com/ruby/prism/commit/41c7c126b2
2026-01-24 23:11:19 +00:00
Earlopain
f7bc28d824 [ruby/prism] Further optimize ripper translator by not using delegate
Using it seems pretty bad for performance:

```rb
require "benchmark/ips"
require "prism"
require "ripper"

codes = Dir["**/*.rb"].map { File.read(it) }

Benchmark.ips do |x|
  x.report("prism") { codes.each { Prism::Translation::Ripper.lex(it) } }
  x.report("ripper") { codes.each { Ripper.lex(it) } }
  x.compare!
end
```

```
# Before
ruby 4.0.0 (2025-12-25 revision https://github.com/ruby/prism/commit/553f1675f3) +PRISM [x86_64-linux]
Warming up --------------------------------------
               prism     1.000 i/100ms
              ripper     1.000 i/100ms
Calculating -------------------------------------
               prism      0.319 (± 0.0%) i/s     (3.14 s/i) -      2.000 in   6.276154s
              ripper      0.647 (± 0.0%) i/s     (1.54 s/i) -      4.000 in   6.182662s

Comparison:
              ripper:        0.6 i/s
               prism:        0.3 i/s - 2.03x  slower
# After
ruby 4.0.0 (2025-12-25 revision https://github.com/ruby/prism/commit/553f1675f3) +PRISM [x86_64-linux]
Warming up --------------------------------------
               prism     1.000 i/100ms
              ripper     1.000 i/100ms
Calculating -------------------------------------
               prism      0.482 (± 0.0%) i/s     (2.08 s/i) -      3.000 in   6.225603s
              ripper      0.645 (± 0.0%) i/s     (1.55 s/i) -      4.000 in   6.205636s

Comparison:
              ripper:        0.6 i/s
               prism:        0.5 i/s - 1.34x  slower
```

`vernier` tells me it does `method_missing` even for explicitly defined methods like `location`.

https://github.com/ruby/prism/commit/2ea81398cc
2026-01-24 23:10:34 +00:00
Peter Zhu
1de6133825 [DOC] Fix hash style in Hash#except 2026-01-24 09:43:54 -05:00
Bodhi Russell Silberling
3dd928c284
[DOC] Fix typo: occurences -> occurrences 2026-01-24 03:41:36 +00:00
Nelli Simkova
3328246b91 [DOC] Fix typo in String#scrub doc 2026-01-24 12:38:15 +09:00
Peter Zhu
887913efc0 [DOC] Improve docs for eval 2026-01-23 17:36:06 -05:00
Max Bernstein
7c75dbe51e
ZJIT: Reset all the counters in RubyVM::ZJIT::reset_stats! (#15950)
We previously forgot about these.
2026-01-23 16:14:59 -05:00
Luke Gruber
e7e9303236
Fix kqueue timeout for 0-valued timespec (#15940)
Timeout with 0-valued timespec means try to get an event, but return
immediately if there is none. Apparently timespec can have other
members, so best to 0 it out in that case.
2026-01-23 11:54:44 -05:00
Kazuki Yamaguchi
48848e8da4 [ruby/openssl] ssl: update tests for SSLContext#servername_cb callback
If an exception is raised by the SSLContext#servername_cb proc, the
handshake should be canceled by sending an "unrecognized_name" alert to
the client, and the exception should be re-raised from SSLSocket#accept.

Add more direct assertions to confirm these behaviors.

https://github.com/ruby/openssl/commit/ac8df7f30f
2026-01-23 16:47:31 +00:00
Kazuki Yamaguchi
0fddb9afca [ruby/openssl] ssl: refactor peeraddr_ip_str()
Remove an unnecessary instance variable lookup and constant lookup.
Ruby's public headers provide rb_eSystemCallError.

https://github.com/ruby/openssl/commit/46c92233fb
2026-01-23 16:41:17 +00:00
Kazuki Yamaguchi
0379aab6c0 [ruby/openssl] ssl: fix errno display in exception messages
The errno reported in an OpenSSL::SSL::SSLError raised by
SSLSocket#accept and #connect sometimes does not match what SSL_accept()
or SSL_connect() actually encountered. Depending on the evaluation order
of arguments passed to ossl_raise(), errno may be overwritten by
peeraddr_ip_str().

While we could just fix peeraddr_ip_str(), we should avoid passing
around errno since it is error-prone. Replace rb_sys_fail() and
rb_io_{maybe_,}wait_{read,writ}able() with equivalents that do not read
errno.

https://github.com/ruby/openssl/commit/bfc7df860f
2026-01-23 16:41:17 +00:00
Sharon Rosner
05b85fc1ab [ruby/openssl] Add sync_close kwarg to SSLSocket.new (fixes
https://github.com/ruby/openssl/pull/955)

https://github.com/ruby/openssl/commit/8d9a676dfa
2026-01-23 15:38:19 +00:00
git
f02fffbe04 * remove trailing spaces. [ci skip] 2026-01-23 06:06:16 +00:00
Benoit Daloze
aba48bd5d6
[ruby/pathname] Remove omit's for File.path since it is fixed in the last TruffleRuby release
https://github.com/ruby/pathname/commit/97c97bc956
2026-01-23 15:03:49 +09:00
Benoit Daloze
5b7b81a7b1
[ruby/pathname] Reenable truffleruby in CI and omit the 2 failing tests
* See https://github.com/ruby/pathname/pull/73

https://github.com/ruby/pathname/commit/a8d7f8bde3
2026-01-23 15:03:33 +09:00
BurdetteLamar
7d7c776fdf
[ruby/pathname] [DOC] Doc for ::getwd
https://github.com/ruby/pathname/commit/d99e62665e
2026-01-23 14:56:11 +09:00
BurdetteLamar
489916a607
[ruby/pathname] Add details
https://github.com/ruby/pathname/commit/b4016cba98
2026-01-23 14:56:11 +09:00
BurdetteLamar
bf098417a1
[ruby/pathname] [DOC] Doc for Pathname#+
https://github.com/ruby/pathname/commit/c6d32879c4
2026-01-23 14:56:10 +09:00
Nobuyoshi Nakada
4449100a11
[ruby/pathname] Omit failure on JRuby and truffleruby
https://github.com/ruby/pathname/commit/fc70010d40
2026-01-23 14:56:10 +09:00
Nozomi Hijikata
5c58327065
ZJIT: Resolve alias in reduce_send_to_ccall (#15947)
Just minor fix to resolve aliases in `reduce_send_to_ccall`.
2026-01-23 00:01:26 -05:00
Étienne Barrié
f5ae56c8a2 Remove unused variable warning 2026-01-23 13:44:03 +09:00
dependabot[bot]
00fdcb3ecd Bump actions/checkout from 6.0.1 to 6.0.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-22 18:34:31 -08:00
dependabot[bot]
528e54b707 Bump actions/checkout in /.github/actions/setup/directories
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](8e8c483db8...de0fac2e45)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-22 18:32:37 -08:00
Augustin Gottlieb
6ef0eb29c6
Add early type validation for ObjectSpace.memsize_of_all klass argument 2026-01-23 11:00:37 +09:00
Peter Zhu
1d497946af [DOC] Fix hash style in Hash#[] 2026-01-22 20:10:35 -05:00
Hiroshi SHIBATA
13bb5599a4 [ruby/rubygems] Validate executable names for invalid characters
https://github.com/ruby/rubygems/commit/95dabef672
2026-01-23 00:24:03 +00:00
Ufuk Kayserilioglu
459222a4e2
[DOC] ZJIT: Add ZJIT logo to the docs page (#15943)
Add ZJIT logo to the docs page
2026-01-22 23:57:21 +00:00
Max Bernstein
c1dde6d387
ZJIT: Count GuardBitEquals for shapes as GuardShape in stats (#15936)
This brings back the GuardShape exit ratio in stats.
2026-01-22 14:53:28 -08:00
BurdetteLamar
51a030833c [ruby/json] Improve class JSON intro
https://github.com/ruby/json/commit/062fcdd228
2026-01-22 22:33:20 +00:00
Peter Zhu
319f142a3a [DOC] Improve docs for Coverage.setup 2026-01-22 17:11:44 -05:00
Earlopain
253bfd7d09
Check for folder in sync_default_gems (#15933)
It was not clear to me that you have to do anything for this command to work.
Previous versions (for example on the 3.4 branch) had this check
but it got lost along the way.

Without this when the folder doesn't exist, you get this error (after it deleted all the files):
```
$ ./tool/sync_default_gems.rb syntax_suggest
Sync ruby/syntax_suggest
./tool/sync_default_gems.rb:464:in 'SyncDefaultGems.check_prerelease_version': undefined method 'version' for nil (NoMethodError)

    puts "#{gem}-#{spec.version} is not latest version of rubygems.org" if spec.version.to_s != latest_version
                                                                               ^^^^^^^^
        from ./tool/sync_default_gems.rb:436:in 'SyncDefaultGems.sync_default_gems'
        from ./tool/sync_default_gems.rb:942:in '<module:SyncDefaultGems>'
        from ./tool/sync_default_gems.rb:10:in '<main>'
```

Now you get

```
$ ./tool/sync_default_gems.rb syntax_suggest
Sync ruby/syntax_suggest
Expected '../ruby/syntax_suggest' (/home/earlopain/Documents/ruby/syntax_suggest)  to be a directory, but it didn't exist.
```

This was changed in b722631b48

Since then, `sync_lib` is unused, delete it
2026-01-22 18:20:28 +00:00
Max Bernstein
fd7bf518a6
ZJIT: Make sure to add a LIR basic block in compile failure entrypoint (#15932)
We need to add a dummy block for this stub otherwise it won't be able to
push any instructions. Without this, `--zjit-stats` is broken.
2026-01-22 12:35:11 -05:00
Max Bernstein
a7a0c36b20
ZJIT: Clean up partial SSI (#15929)
After Kokubun requested named unions, I realized we don't actually need
a `Type::subtract` function. They were only used for the ad-hoc unions.

Also, add a test that is illustrative of what we can get from this
partial SSI.
2026-01-22 11:41:23 -05:00
Hiroshi SHIBATA
61724b9e4a
Update the latest versions of actions 2026-01-22 15:04:08 +09:00
Hiroshi SHIBATA
7f8994f15b
Update the latest maintenance status of Pathname 2026-01-22 12:19:57 +09:00
dependabot[bot]
fd0b9243e3 Bump github.com/microsoft/vcpkg from master to 2026.01.16
Bumps [github.com/microsoft/vcpkg](https://github.com/microsoft/vcpkg) from master to 2026.01.16. This release includes the previously tagged commit.
- [Release notes](https://github.com/microsoft/vcpkg/releases)
- [Commits](84bab45d41...66c0373dc7)

---
updated-dependencies:
- dependency-name: github.com/microsoft/vcpkg
  dependency-version: 2026.01.16
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-22 12:10:12 +09:00
Kevin Menard
6c2ecb231a
ZJIT: Use TypeDistribution to track stats about the super CME (#15928)
This is a follow up to #15816. Since I was only optimizing `invokesuper` for monomorphic cases, I could track that with a boolean value (actually, `Option` in this case). But, `TypeDistribution` is a better way to track this information and will put us on better footing if we end up handling polymorphic cases.
2026-01-22 00:19:55 +00:00
Nozomi Hijikata
436ec3a9d6
ZJIT: Compile getblockparam (#15896)
Closes: https://github.com/Shopify/ruby/issues/863

Compile `getblockparam` insn to `GetBlockParam` HIR so that we can handle it in ZJIT.

## Benchmark 
### lobsters

<details>

<summary>before patch</summary>

```
Average of last 10, non-warmup iters: 778ms
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (58.4% of total 16,091,748):
                                               Hash#fetch: 3,237,974 (20.1%)
                                            Regexp#match?:   708,838 ( 4.4%)
                                                Hash#key?:   702,565 ( 4.4%)
                                              String#sub!:   489,843 ( 3.0%)
                                             Set#include?:   402,395 ( 2.5%)
                                                String#<<:   396,364 ( 2.5%)
                                       String#start_with?:   379,338 ( 2.4%)
                                              Hash#delete:   331,679 ( 2.1%)
                                               String.new:   308,268 ( 1.9%)
                                              Integer#===:   279,074 ( 1.7%)
                                         Symbol#end_with?:   255,538 ( 1.6%)
                                             Kernel#is_a?:   250,000 ( 1.6%)
                                    Process.clock_gettime:   221,598 ( 1.4%)
                                                Integer#>:   219,718 ( 1.4%)
                                            String#match?:   218,057 ( 1.4%)
                                          String#downcase:   213,127 ( 1.3%)
                                               Integer#<=:   202,617 ( 1.3%)
                                                Time#to_i:   195,248 ( 1.2%)
                                              Time#subsec:   192,277 ( 1.2%)
                                                Time#utc?:   188,500 ( 1.2%)
Top-20 calls to C functions from JIT code (83.4% of total 126,501,142):
                             rb_vm_opt_send_without_block: 35,338,443 (27.9%)
                                               rb_vm_send: 10,126,272 ( 8.0%)
                                             rb_hash_aref:  9,221,146 ( 7.3%)
                                          rb_vm_env_write:  8,615,394 ( 6.8%)
                     rb_zjit_writebarrier_check_immediate:  7,666,061 ( 6.1%)
                                rb_vm_getinstancevariable:  5,902,473 ( 4.7%)
                           rb_ivar_get_at_no_ractor_check:  4,775,750 ( 3.8%)
                                        rb_obj_is_kind_of:  3,718,303 ( 2.9%)
                                        rb_vm_invokesuper:  2,705,394 ( 2.1%)
                                             rb_hash_aset:  2,422,892 ( 1.9%)
                                rb_vm_setinstancevariable:  2,385,262 ( 1.9%)
                               rb_vm_opt_getconstant_path:  2,321,875 ( 1.8%)
                                               Hash#fetch:  1,819,675 ( 1.4%)
                                                    fetch:  1,418,299 ( 1.1%)
                                        rb_vm_invokeblock:  1,387,466 ( 1.1%)
                                        rb_str_buf_append:  1,378,634 ( 1.1%)
                                rb_ec_ary_new_from_values:  1,338,599 ( 1.1%)
                               rb_class_allocate_instance:  1,300,827 ( 1.0%)
                                    rb_hash_new_with_size:    906,352 ( 0.7%)
                                        rb_vm_sendforward:    799,626 ( 0.6%)
Top-2 not optimized method types for send (100.0% of total 5,166,211):
  iseq: 5,163,389 (99.9%)
  null:     2,822 ( 0.1%)
Top-3 not optimized method types for send_without_block (100.0% of total 526,119):
        optimized_send: 479,643 (91.2%)
                  null:  42,176 ( 8.0%)
  optimized_block_call:   4,300 ( 0.8%)
Top-3 not optimized method types for super (100.0% of total 2,365,999):
    cfunc: 2,251,438 (95.2%)
    alias:   111,257 ( 4.7%)
  attrset:     3,304 ( 0.1%)
Top-3 instructions with uncategorized fallback reason (100.0% of total 2,214,821):
             invokeblock: 1,387,466 (62.6%)
             sendforward:   799,626 (36.1%)
  opt_send_without_block:    27,729 ( 1.3%)
Top-20 send fallback reasons (100.0% of total 50,357,201):
                          send_without_block_polymorphic: 18,307,466 (36.4%)
                                    singleton_class_seen:  9,310,336 (18.5%)
                          send_not_optimized_method_type:  5,166,211 (10.3%)
                          send_without_block_no_profiles:  4,756,165 ( 9.4%)
                            one_or_more_complex_arg_pass:  2,906,412 ( 5.8%)
                                        send_no_profiles:  2,864,323 ( 5.7%)
                         super_not_optimized_method_type:  2,365,999 ( 4.7%)
                                           uncategorized:  2,214,821 ( 4.4%)
                          send_without_block_megamorphic:    581,552 ( 1.2%)
  send_without_block_not_optimized_method_type_optimized:    483,943 ( 1.0%)
        send_without_block_not_optimized_need_permission:    390,364 ( 0.8%)
                                        send_polymorphic:    329,064 ( 0.7%)
                                   too_many_args_for_lir:    173,570 ( 0.3%)
                          super_target_complex_args_pass:    131,841 ( 0.3%)
                                 super_complex_args_pass:    111,056 ( 0.2%)
                                       super_polymorphic:     86,986 ( 0.2%)
                                     argc_param_mismatch:     48,546 ( 0.1%)
            send_without_block_not_optimized_method_type:     42,176 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     37,484 ( 0.1%)
                                obj_to_string_not_string:     34,865 ( 0.1%)
Top-4 setivar fallback reasons (100.0% of total 2,385,262):
            not_monomorphic: 2,162,525 (90.7%)
               not_t_object:   125,178 ( 5.2%)
                too_complex:    97,538 ( 4.1%)
  new_shape_needs_extension:        21 ( 0.0%)
Top-2 getivar fallback reasons (100.0% of total 6,027,586):
  not_monomorphic: 5,776,418 (95.8%)
      too_complex:   251,168 ( 4.2%)
Top-3 definedivar fallback reasons (100.0% of total 406,027):
  not_monomorphic: 397,876 (98.0%)
      too_complex:   5,122 ( 1.3%)
     not_t_object:   3,029 ( 0.7%)
Top-6 invokeblock handler (100.0% of total 1,387,466):
   monomorphic_iseq: 700,051 (50.5%)
        polymorphic: 513,455 (37.0%)
  monomorphic_other: 106,268 ( 7.7%)
  monomorphic_ifunc:  55,505 ( 4.0%)
        megamorphic:   6,762 ( 0.5%)
        no_profiles:   5,425 ( 0.4%)
Top-9 popular complex argument-parameter features not optimized (100.0% of total 3,353,961):
       param_kw_opt: 1,408,663 (42.0%)
  param_forwardable:   697,209 (20.8%)
        param_block:   632,488 (18.9%)
         param_rest:   346,363 (10.3%)
       param_kwrest:   139,856 ( 4.2%)
    caller_kw_splat:    79,861 ( 2.4%)
       caller_splat:    43,585 ( 1.3%)
    caller_blockarg:     5,826 ( 0.2%)
       caller_kwarg:       110 ( 0.0%)
Top-1 compile error reasons (100.0% of total 188,362):
  exception_handler: 188,362 (100.0%)
Top-7 unhandled YARV insns (100.0% of total 184,408):
       getblockparam: 95,129 (51.6%)
  invokesuperforward: 81,668 (44.3%)
         getconstant:  3,318 ( 1.8%)
       setblockparam:  2,837 ( 1.5%)
          checkmatch:    929 ( 0.5%)
         expandarray:    360 ( 0.2%)
                once:    167 ( 0.1%)
Top-3 unhandled HIR insns (100.0% of total 237,876):
          throw: 199,380 (83.8%)
  invokebuiltin:  35,775 (15.0%)
      array_max:   2,721 ( 1.1%)
Top-20 side exit reasons (100.0% of total 15,592,861):
                   guard_type_failure: 6,993,070 (44.8%)
                  guard_shape_failure: 6,862,785 (44.0%)
  block_param_proxy_not_iseq_or_ifunc: 1,006,781 ( 6.5%)
                   unhandled_hir_insn:   237,876 ( 1.5%)
                        compile_error:   188,362 ( 1.2%)
                  unhandled_yarv_insn:   184,408 ( 1.2%)
           block_param_proxy_modified:    29,130 ( 0.2%)
     patchpoint_stable_constant_names:    22,145 ( 0.1%)
         unhandled_newarray_send_pack:    14,481 ( 0.1%)
                  unhandled_block_arg:    13,788 ( 0.1%)
                 fixnum_mult_overflow:    10,866 ( 0.1%)
               fixnum_lshift_overflow:    10,085 ( 0.1%)
              patchpoint_no_ep_escape:     7,815 ( 0.1%)
                  expandarray_failure:     4,533 ( 0.0%)
             guard_super_method_entry:     4,475 ( 0.0%)
          patchpoint_method_redefined:     1,212 ( 0.0%)
        patchpoint_no_singleton_class:       423 ( 0.0%)
               obj_to_string_fallback:       330 ( 0.0%)
                   guard_less_failure:       163 ( 0.0%)
                            interrupt:       114 ( 0.0%)
                             send_count: 152,442,683
                     dynamic_send_count:  50,357,201 (33.0%)
                   optimized_send_count: 102,085,482 (67.0%)
                  dynamic_setivar_count:   2,385,262 ( 1.6%)
                  dynamic_getivar_count:   6,027,586 ( 4.0%)
              dynamic_definedivar_count:     406,027 ( 0.3%)
              iseq_optimized_send_count:  39,671,621 (26.0%)
      inline_cfunc_optimized_send_count:  42,053,762 (27.6%)
       inline_iseq_optimized_send_count:   3,462,562 ( 2.3%)
non_variadic_cfunc_optimized_send_count:   9,195,248 ( 6.0%)
    variadic_cfunc_optimized_send_count:   7,702,289 ( 5.1%)
compiled_iseq_count:                              5,552
failed_iseq_count:                                    0
compile_time:                                   1,926ms
profile_time:                                      20ms
gc_time:                                           27ms
invalidation_time:                                531ms
vm_write_pc_count:                          132,750,117
vm_write_sp_count:                          132,750,117
vm_write_locals_count:                      128,780,465
vm_write_stack_count:                       128,780,465
vm_write_to_parent_iseq_local_count:            694,799
vm_read_from_parent_iseq_local_count:        14,812,747
guard_type_count:                           159,813,452
guard_type_exit_ratio:                             4.4%
guard_shape_count:                                    0
code_region_bytes:                           29,425,664
zjit_alloc_bytes:                            44,592,776
total_mem_bytes:                             74,018,440
side_exit_count:                             15,592,861
total_insn_count:                           938,453,078
vm_insn_count:                              167,693,539
zjit_insn_count:                            770,759,539
ratio_in_zjit:                                    82.1%

```

</details>

<details>

<summary>after patch</summary>

```
Average of last 10, non-warmup iters: 725ms
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (58.2% of total 16,004,664):
                                               Hash#fetch: 3,185,115 (19.9%)
                                            Regexp#match?:   708,806 ( 4.4%)
                                                Hash#key?:   702,551 ( 4.4%)
                                              String#sub!:   489,841 ( 3.1%)
                                             Set#include?:   396,625 ( 2.5%)
                                                String#<<:   396,279 ( 2.5%)
                                       String#start_with?:   379,337 ( 2.4%)
                                              Hash#delete:   331,667 ( 2.1%)
                                               String.new:   307,248 ( 1.9%)
                                              Integer#===:   279,054 ( 1.7%)
                                         Symbol#end_with?:   255,538 ( 1.6%)
                                             Kernel#is_a?:   246,961 ( 1.5%)
                                    Process.clock_gettime:   221,588 ( 1.4%)
                                                Integer#>:   219,718 ( 1.4%)
                                            String#match?:   218,059 ( 1.4%)
                                          String#downcase:   213,109 ( 1.3%)
                                               Integer#<=:   202,617 ( 1.3%)
                                                Time#to_i:   192,211 ( 1.2%)
                                              Time#subsec:   189,240 ( 1.2%)
                                            String#to_sym:   185,947 ( 1.2%)
Top-20 calls to C functions from JIT code (83.4% of total 126,772,007):
                             rb_vm_opt_send_without_block: 35,829,863 (28.3%)
                                               rb_vm_send: 10,108,894 ( 8.0%)
                                             rb_hash_aref:  9,009,231 ( 7.1%)
                                          rb_vm_env_write:  8,571,665 ( 6.8%)
                     rb_zjit_writebarrier_check_immediate:  7,702,599 ( 6.1%)
                                rb_vm_getinstancevariable:  5,930,325 ( 4.7%)
                           rb_ivar_get_at_no_ractor_check:  4,764,439 ( 3.8%)
                                        rb_obj_is_kind_of:  3,722,865 ( 2.9%)
                                        rb_vm_invokesuper:  2,687,484 ( 2.1%)
                                             rb_hash_aset:  2,421,186 ( 1.9%)
                                rb_vm_setinstancevariable:  2,355,461 ( 1.9%)
                               rb_vm_opt_getconstant_path:  2,295,528 ( 1.8%)
                                               Hash#fetch:  1,779,524 ( 1.4%)
                                                    fetch:  1,405,591 ( 1.1%)
                                        rb_vm_invokeblock:  1,385,989 ( 1.1%)
                                        rb_str_buf_append:  1,369,177 ( 1.1%)
                                rb_ec_ary_new_from_values:  1,337,865 ( 1.1%)
                               rb_class_allocate_instance:  1,295,755 ( 1.0%)
                                    rb_hash_new_with_size:    902,684 ( 0.7%)
                                        rb_vm_sendforward:    798,572 ( 0.6%)
Top-2 not optimized method types for send (100.0% of total 4,902,716):
  iseq: 4,899,894 (99.9%)
  null:     2,822 ( 0.1%)
Top-3 not optimized method types for send_without_block (100.0% of total 526,064):
        optimized_send: 479,589 (91.2%)
                  null:  42,176 ( 8.0%)
  optimized_block_call:   4,299 ( 0.8%)
Top-3 not optimized method types for super (100.0% of total 2,350,245):
    cfunc: 2,239,567 (95.3%)
    alias:   107,374 ( 4.6%)
  attrset:     3,304 ( 0.1%)
Top-3 instructions with uncategorized fallback reason (100.0% of total 2,216,683):
             invokeblock: 1,385,989 (62.5%)
             sendforward:   798,572 (36.0%)
  opt_send_without_block:    32,122 ( 1.4%)
Top-20 send fallback reasons (99.9% of total 50,810,802):
                          send_without_block_polymorphic: 18,668,686 (36.7%)
                                    singleton_class_seen:  9,323,039 (18.3%)
                          send_not_optimized_method_type:  4,902,716 ( 9.6%)
                          send_without_block_no_profiles:  4,824,297 ( 9.5%)
                                        send_no_profiles:  2,853,944 ( 5.6%)
                            one_or_more_complex_arg_pass:  2,829,717 ( 5.6%)
                         super_not_optimized_method_type:  2,350,245 ( 4.6%)
                                           uncategorized:  2,216,683 ( 4.4%)
                          send_without_block_megamorphic:    723,037 ( 1.4%)
                                        send_polymorphic:    544,026 ( 1.1%)
  send_without_block_not_optimized_method_type_optimized:    483,888 ( 1.0%)
        send_without_block_not_optimized_need_permission:    390,364 ( 0.8%)
                                   too_many_args_for_lir:    172,809 ( 0.3%)
                          super_target_complex_args_pass:    128,824 ( 0.3%)
                                 super_complex_args_pass:    111,053 ( 0.2%)
                                       super_polymorphic:     87,851 ( 0.2%)
                                     argc_param_mismatch:     50,382 ( 0.1%)
            send_without_block_not_optimized_method_type:     42,176 ( 0.1%)
                                obj_to_string_not_string:     34,861 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     32,436 ( 0.1%)
Top-4 setivar fallback reasons (100.0% of total 2,355,461):
            not_monomorphic: 2,132,746 (90.5%)
               not_t_object:   125,163 ( 5.3%)
                too_complex:    97,531 ( 4.1%)
  new_shape_needs_extension:        21 ( 0.0%)
Top-2 getivar fallback reasons (100.0% of total 6,055,438):
  not_monomorphic: 5,806,179 (95.9%)
      too_complex:   249,259 ( 4.1%)
Top-3 definedivar fallback reasons (100.0% of total 405,302):
  not_monomorphic: 397,150 (98.0%)
      too_complex:   5,122 ( 1.3%)
     not_t_object:   3,030 ( 0.7%)
Top-6 invokeblock handler (100.0% of total 1,385,989):
   monomorphic_iseq: 688,167 (49.7%)
        polymorphic: 523,864 (37.8%)
  monomorphic_other: 106,268 ( 7.7%)
  monomorphic_ifunc:  55,505 ( 4.0%)
        megamorphic:   6,761 ( 0.5%)
        no_profiles:   5,424 ( 0.4%)
Top-9 popular complex argument-parameter features not optimized (100.0% of total 3,234,958):
       param_kw_opt: 1,381,881 (42.7%)
  param_forwardable:   685,939 (21.2%)
        param_block:   640,948 (19.8%)
         param_rest:   327,046 (10.1%)
       param_kwrest:   120,209 ( 3.7%)
    caller_kw_splat:    38,970 ( 1.2%)
       caller_splat:    34,029 ( 1.1%)
    caller_blockarg:     5,826 ( 0.2%)
       caller_kwarg:       110 ( 0.0%)
Top-1 compile error reasons (100.0% of total 187,347):
  exception_handler: 187,347 (100.0%)
Top-6 unhandled YARV insns (100.0% of total 89,278):
  invokesuperforward: 81,667 (91.5%)
         getconstant:  3,318 ( 3.7%)
       setblockparam:  2,837 ( 3.2%)
          checkmatch:    929 ( 1.0%)
         expandarray:    360 ( 0.4%)
                once:    167 ( 0.2%)
Top-3 unhandled HIR insns (100.0% of total 236,977):
          throw: 198,481 (83.8%)
  invokebuiltin:  35,775 (15.1%)
      array_max:   2,721 ( 1.1%)
Top-20 side exit reasons (100.0% of total 15,458,443):
                   guard_type_failure: 6,918,397 (44.8%)
                  guard_shape_failure: 6,859,686 (44.4%)
  block_param_proxy_not_iseq_or_ifunc: 1,008,346 ( 6.5%)
                   unhandled_hir_insn:   236,977 ( 1.5%)
                        compile_error:   187,347 ( 1.2%)
                  unhandled_yarv_insn:    89,278 ( 0.6%)
                 fixnum_mult_overflow:    50,739 ( 0.3%)
           block_param_proxy_modified:    28,119 ( 0.2%)
     patchpoint_stable_constant_names:    22,145 ( 0.1%)
         unhandled_newarray_send_pack:    14,481 ( 0.1%)
                  unhandled_block_arg:    13,787 ( 0.1%)
               fixnum_lshift_overflow:    10,085 ( 0.1%)
              patchpoint_no_ep_escape:     7,815 ( 0.1%)
                  expandarray_failure:     4,533 ( 0.0%)
             guard_super_method_entry:     4,475 ( 0.0%)
          patchpoint_method_redefined:     1,212 ( 0.0%)
        patchpoint_no_singleton_class:       423 ( 0.0%)
               obj_to_string_fallback:       330 ( 0.0%)
                   guard_less_failure:       163 ( 0.0%)
                            interrupt:        86 ( 0.0%)
                             send_count: 151,889,096
                     dynamic_send_count:  50,810,802 (33.5%)
                   optimized_send_count: 101,078,294 (66.5%)
                  dynamic_setivar_count:   2,355,461 ( 1.6%)
                  dynamic_getivar_count:   6,055,438 ( 4.0%)
              dynamic_definedivar_count:     405,302 ( 0.3%)
              iseq_optimized_send_count:  39,470,508 (26.0%)
      inline_cfunc_optimized_send_count:  41,381,565 (27.2%)
       inline_iseq_optimized_send_count:   3,370,961 ( 2.2%)
non_variadic_cfunc_optimized_send_count:   9,210,651 ( 6.1%)
    variadic_cfunc_optimized_send_count:   7,644,609 ( 5.0%)
compiled_iseq_count:                              5,552
failed_iseq_count:                                    0
compile_time:                                   1,809ms
profile_time:                                      15ms
gc_time:                                           21ms
invalidation_time:                                526ms
vm_write_pc_count:                          132,774,559
vm_write_sp_count:                          132,774,559
vm_write_locals_count:                      128,748,998
vm_write_stack_count:                       128,748,998
vm_write_to_parent_iseq_local_count:            693,262
vm_read_from_parent_iseq_local_count:        14,737,431
guard_type_count:                           158,811,089
guard_type_exit_ratio:                             4.4%
guard_shape_count:                                    0
code_region_bytes:                           29,458,432
zjit_alloc_bytes:                            44,650,569
total_mem_bytes:                             74,109,001
side_exit_count:                             15,458,443
total_insn_count:                           934,491,306
vm_insn_count:                              166,025,364
zjit_insn_count:                            768,465,942
ratio_in_zjit:                                    82.2%
```

</details>




### rails-bench

<details>

<summary>before patch</summary>

```
Average of last 10, non-warmup iters: 1254ms
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (52.8% of total 39,182,033):
                                  Hash#key?: 3,141,634 ( 8.0%)
                              Regexp#match?: 2,420,227 ( 6.2%)
                                 Hash#fetch: 2,245,557 ( 5.7%)
                                 Array#any?: 1,157,418 ( 3.0%)
                                Hash#delete: 1,114,346 ( 2.8%)
                                Integer#===: 1,098,163 ( 2.8%)
                                 String.new: 1,004,713 ( 2.6%)
                               MatchData#[]:   831,442 ( 2.1%)
                                   String#b:   797,913 ( 2.0%)
                              String#to_sym:   680,943 ( 1.7%)
                                 Kernel#dup:   680,022 ( 1.7%)
                                 Array#all?:   650,132 ( 1.7%)
                              Fiber.current:   649,003 ( 1.7%)
                                 Array#join:   641,038 ( 1.6%)
                             Array#include?:   613,837 ( 1.6%)
                               Kernel#Array:   610,311 ( 1.6%)
                                  String#<<:   606,240 ( 1.5%)
                           Symbol#end_with?:   598,807 ( 1.5%)
                      String#force_encoding:   593,535 ( 1.5%)
                         Kernel#respond_to?:   550,441 ( 1.4%)
Top-20 calls to C functions from JIT code (75.2% of total 260,204,372):
               rb_vm_opt_send_without_block: 52,620,850 (20.2%)
                               rb_hash_aref: 22,920,184 ( 8.8%)
                            rb_vm_env_write: 19,484,445 ( 7.5%)
                                 rb_vm_send: 16,570,926 ( 6.4%)
       rb_zjit_writebarrier_check_immediate: 13,628,686 ( 5.2%)
                  rb_vm_getinstancevariable: 12,378,112 ( 4.8%)
             rb_ivar_get_at_no_ractor_check: 12,208,856 ( 4.7%)
                          rb_vm_invokesuper:  8,086,664 ( 3.1%)
                               rb_hash_aset:  5,043,532 ( 1.9%)
                          rb_obj_is_kind_of:  4,431,294 ( 1.7%)
                          rb_vm_invokeblock:  4,036,483 ( 1.6%)
                                  Hash#key?:  3,141,634 ( 1.2%)
                 rb_vm_opt_getconstant_path:  3,051,909 ( 1.2%)
                 rb_class_allocate_instance:  2,878,743 ( 1.1%)
                      rb_hash_new_with_size:  2,873,398 ( 1.1%)
                  rb_ec_ary_new_from_values:  2,584,790 ( 1.0%)
                     rb_str_concat_literals:  2,450,752 ( 0.9%)
                              Regexp#match?:  2,420,227 ( 0.9%)
                               rb_obj_alloc:  2,419,180 ( 0.9%)
                  rb_vm_setinstancevariable:  2,357,067 ( 0.9%)
Top-2 not optimized method types for send (100.0% of total 8,550,761):
       iseq: 8,518,290 (99.6%)
  optimized:    32,471 ( 0.4%)
Top-2 not optimized method types for send_without_block (100.0% of total 790,792):
  optimized_send: 608,036 (76.9%)
            null: 182,756 (23.1%)
Top-2 not optimized method types for super (100.0% of total 6,689,860):
    cfunc: 6,640,181 (99.3%)
  attrset:    49,679 ( 0.7%)
Top-3 instructions with uncategorized fallback reason (100.0% of total 5,911,882):
             invokeblock: 4,036,483 (68.3%)
             sendforward: 1,871,601 (31.7%)
  opt_send_without_block:     3,798 ( 0.1%)
Top-20 send fallback reasons (100.0% of total 83,186,524):
                          send_without_block_polymorphic: 33,814,235 (40.6%)
                          send_not_optimized_method_type:  8,550,761 (10.3%)
                          send_without_block_no_profiles:  8,405,471 (10.1%)
                         super_not_optimized_method_type:  6,689,860 ( 8.0%)
                                           uncategorized:  5,911,882 ( 7.1%)
                            one_or_more_complex_arg_pass:  5,502,146 ( 6.6%)
                                        send_no_profiles:  4,700,820 ( 5.7%)
                                        send_polymorphic:  3,318,564 ( 4.0%)
        send_without_block_not_optimized_need_permission:  1,274,177 ( 1.5%)
                                    singleton_class_seen:  1,101,973 ( 1.3%)
                                   too_many_args_for_lir:    905,412 ( 1.1%)
                                 super_complex_args_pass:    829,842 ( 1.0%)
  send_without_block_not_optimized_method_type_optimized:    608,036 ( 0.7%)
                          send_without_block_megamorphic:    565,874 ( 0.7%)
                          super_target_complex_args_pass:    414,600 ( 0.5%)
            send_without_block_not_optimized_method_type:    182,756 ( 0.2%)
                                obj_to_string_not_string:    158,141 ( 0.2%)
                                   super_call_with_block:    100,004 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     99,588 ( 0.1%)
                                       super_polymorphic:     52,358 ( 0.1%)
Top-2 setivar fallback reasons (100.0% of total 2,357,067):
  not_monomorphic: 2,255,283 (95.7%)
     not_t_object:   101,784 ( 4.3%)
Top-1 getivar fallback reasons (100.0% of total 12,378,137):
  not_monomorphic: 12,378,137 (100.0%)
Top-2 definedivar fallback reasons (100.0% of total 350,548):
  not_monomorphic: 350,461 (100.0%)
     not_t_object:      87 ( 0.0%)
Top-6 invokeblock handler (100.0% of total 4,036,483):
   monomorphic_iseq: 2,189,057 (54.2%)
        polymorphic: 1,207,002 (29.9%)
  monomorphic_other:   334,248 ( 8.3%)
  monomorphic_ifunc:   221,225 ( 5.5%)
        megamorphic:    84,439 ( 2.1%)
        no_profiles:       512 ( 0.0%)
Top-9 popular complex argument-parameter features not optimized (100.0% of total 7,096,505):
       param_kw_opt: 1,834,705 (25.9%)
  param_forwardable: 1,824,953 (25.7%)
        param_block: 1,792,214 (25.3%)
         param_rest:   861,894 (12.1%)
    caller_kw_splat:   297,937 ( 4.2%)
       caller_splat:   283,669 ( 4.0%)
       param_kwrest:   200,208 ( 2.8%)
    caller_blockarg:       752 ( 0.0%)
       caller_kwarg:       173 ( 0.0%)
Top-1 compile error reasons (100.0% of total 391,562):
  exception_handler: 391,562 (100.0%)
Top-7 unhandled YARV insns (100.0% of total 1,899,393):
       getblockparam: 898,862 (47.3%)
  invokesuperforward: 498,993 (26.3%)
         getconstant: 400,945 (21.1%)
         expandarray:  49,985 ( 2.6%)
       setblockparam:  49,972 ( 2.6%)
          checkmatch:     480 ( 0.0%)
                once:     156 ( 0.0%)
Top-2 unhandled HIR insns (100.0% of total 268,151):
          throw: 232,560 (86.7%)
  invokebuiltin:  35,591 (13.3%)
Top-19 side exit reasons (100.0% of total 9,609,677):
                  guard_shape_failure: 2,498,160 (26.0%)
  block_param_proxy_not_iseq_or_ifunc: 1,988,408 (20.7%)
                  unhandled_yarv_insn: 1,899,393 (19.8%)
                   guard_type_failure: 1,722,167 (17.9%)
                        compile_error:   391,562 ( 4.1%)
         unhandled_newarray_send_pack:   298,017 ( 3.1%)
                   unhandled_hir_insn:   268,151 ( 2.8%)
          patchpoint_method_redefined:   200,632 ( 2.1%)
                  unhandled_block_arg:   151,295 ( 1.6%)
           block_param_proxy_modified:   124,245 ( 1.3%)
                   guard_less_failure:    50,126 ( 0.5%)
               fixnum_lshift_overflow:     9,985 ( 0.1%)
     patchpoint_stable_constant_names:     6,366 ( 0.1%)
                 fixnum_mult_overflow:       570 ( 0.0%)
               obj_to_string_fallback:       429 ( 0.0%)
              patchpoint_no_ep_escape:       109 ( 0.0%)
                            interrupt:        48 ( 0.0%)
             guard_super_method_entry:         8 ( 0.0%)
             guard_greater_eq_failure:         6 ( 0.0%)
                             send_count: 328,547,991
                     dynamic_send_count:  83,186,524 (25.3%)
                   optimized_send_count: 245,361,467 (74.7%)
                  dynamic_setivar_count:   2,357,067 ( 0.7%)
                  dynamic_getivar_count:  12,378,137 ( 3.8%)
              dynamic_definedivar_count:     350,548 ( 0.1%)
              iseq_optimized_send_count:  93,424,465 (28.4%)
      inline_cfunc_optimized_send_count:  98,338,280 (29.9%)
       inline_iseq_optimized_send_count:   9,338,763 ( 2.8%)
non_variadic_cfunc_optimized_send_count:  26,452,910 ( 8.1%)
    variadic_cfunc_optimized_send_count:  17,807,049 ( 5.4%)
compiled_iseq_count:                               2,887
failed_iseq_count:                                     0
compile_time:                                      877ms
profile_time:                                       32ms
gc_time:                                            11ms
invalidation_time:                                  15ms
vm_write_pc_count:                           284,341,923
vm_write_sp_count:                           284,341,923
vm_write_locals_count:                       272,137,494
vm_write_stack_count:                        272,137,494
vm_write_to_parent_iseq_local_count:           1,079,867
vm_read_from_parent_iseq_local_count:         30,816,135
guard_type_count:                            313,667,907
guard_type_exit_ratio:                              0.5%
guard_shape_count:                                     0
code_region_bytes:                            14,417,920
zjit_alloc_bytes:                             19,075,183
total_mem_bytes:                              33,493,103
side_exit_count:                               9,609,677
total_insn_count:                          1,706,360,231
vm_insn_count:                               124,793,155
zjit_insn_count:                           1,581,567,076
ratio_in_zjit:                                     92.7%
```

</details>

<details>

<summary>after patch</summary>

```
Average of last 10, non-warmup iters: 1136ms
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (52.8% of total 39,182,033):
                                  Hash#key?: 3,141,634 ( 8.0%)
                              Regexp#match?: 2,420,227 ( 6.2%)
                                 Hash#fetch: 2,245,557 ( 5.7%)
                                 Array#any?: 1,157,418 ( 3.0%)
                                Hash#delete: 1,114,346 ( 2.8%)
                                Integer#===: 1,098,163 ( 2.8%)
                                 String.new: 1,004,713 ( 2.6%)
                               MatchData#[]:   831,442 ( 2.1%)
                                   String#b:   797,913 ( 2.0%)
                              String#to_sym:   680,943 ( 1.7%)
                                 Kernel#dup:   680,022 ( 1.7%)
                                 Array#all?:   650,132 ( 1.7%)
                              Fiber.current:   649,003 ( 1.7%)
                                 Array#join:   641,038 ( 1.6%)
                             Array#include?:   613,837 ( 1.6%)
                               Kernel#Array:   610,311 ( 1.6%)
                                  String#<<:   606,240 ( 1.5%)
                           Symbol#end_with?:   598,807 ( 1.5%)
                      String#force_encoding:   593,535 ( 1.5%)
                         Kernel#respond_to?:   550,441 ( 1.4%)
Top-20 calls to C functions from JIT code (74.8% of total 261,805,313):
               rb_vm_opt_send_without_block: 52,621,173 (20.1%)
                               rb_hash_aref: 22,920,184 ( 8.8%)
                            rb_vm_env_write: 19,484,925 ( 7.4%)
                                 rb_vm_send: 16,571,020 ( 6.3%)
       rb_zjit_writebarrier_check_immediate: 13,780,332 ( 5.3%)
                  rb_vm_getinstancevariable: 12,378,114 ( 4.7%)
             rb_ivar_get_at_no_ractor_check: 12,208,856 ( 4.7%)
                          rb_vm_invokesuper:  8,086,666 ( 3.1%)
                               rb_hash_aset:  5,043,537 ( 1.9%)
                          rb_obj_is_kind_of:  4,431,299 ( 1.7%)
                          rb_vm_invokeblock:  4,036,481 ( 1.5%)
                                  Hash#key?:  3,141,634 ( 1.2%)
                 rb_vm_opt_getconstant_path:  3,051,909 ( 1.2%)
                 rb_class_allocate_instance:  2,878,746 ( 1.1%)
                      rb_hash_new_with_size:  2,873,398 ( 1.1%)
                  rb_ec_ary_new_from_values:  2,585,224 ( 1.0%)
                     rb_str_concat_literals:  2,450,752 ( 0.9%)
                              Regexp#match?:  2,420,227 ( 0.9%)
                               rb_obj_alloc:  2,419,182 ( 0.9%)
                  rb_vm_setinstancevariable:  2,357,067 ( 0.9%)
Top-2 not optimized method types for send (100.0% of total 8,550,761):
       iseq: 8,518,290 (99.6%)
  optimized:    32,471 ( 0.4%)
Top-2 not optimized method types for send_without_block (100.0% of total 790,792):
  optimized_send: 608,036 (76.9%)
            null: 182,756 (23.1%)
Top-2 not optimized method types for super (100.0% of total 6,689,860):
    cfunc: 6,640,181 (99.3%)
  attrset:    49,679 ( 0.7%)
Top-3 instructions with uncategorized fallback reason (100.0% of total 5,911,883):
             invokeblock: 4,036,481 (68.3%)
             sendforward: 1,871,601 (31.7%)
  opt_send_without_block:     3,801 ( 0.1%)
Top-20 send fallback reasons (100.0% of total 83,186,941):
                          send_without_block_polymorphic: 33,814,528 (40.6%)
                          send_not_optimized_method_type:  8,550,761 (10.3%)
                          send_without_block_no_profiles:  8,405,497 (10.1%)
                         super_not_optimized_method_type:  6,689,860 ( 8.0%)
                                           uncategorized:  5,911,883 ( 7.1%)
                            one_or_more_complex_arg_pass:  5,502,147 ( 6.6%)
                                        send_no_profiles:  4,700,820 ( 5.7%)
                                        send_polymorphic:  3,318,658 ( 4.0%)
        send_without_block_not_optimized_need_permission:  1,274,177 ( 1.5%)
                                    singleton_class_seen:  1,101,973 ( 1.3%)
                                   too_many_args_for_lir:    905,412 ( 1.1%)
                                 super_complex_args_pass:    829,842 ( 1.0%)
  send_without_block_not_optimized_method_type_optimized:    608,036 ( 0.7%)
                          send_without_block_megamorphic:    565,874 ( 0.7%)
                          super_target_complex_args_pass:    414,600 ( 0.5%)
            send_without_block_not_optimized_method_type:    182,756 ( 0.2%)
                                obj_to_string_not_string:    158,141 ( 0.2%)
                                   super_call_with_block:    100,004 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     99,588 ( 0.1%)
                                       super_polymorphic:     52,360 ( 0.1%)
Top-2 setivar fallback reasons (100.0% of total 2,357,067):
  not_monomorphic: 2,255,283 (95.7%)
     not_t_object:   101,784 ( 4.3%)
Top-1 getivar fallback reasons (100.0% of total 12,378,139):
  not_monomorphic: 12,378,139 (100.0%)
Top-2 definedivar fallback reasons (100.0% of total 350,548):
  not_monomorphic: 350,461 (100.0%)
     not_t_object:      87 ( 0.0%)
Top-6 invokeblock handler (100.0% of total 4,036,481):
   monomorphic_iseq: 2,189,057 (54.2%)
        polymorphic: 1,207,002 (29.9%)
  monomorphic_other:   334,248 ( 8.3%)
  monomorphic_ifunc:   221,223 ( 5.5%)
        megamorphic:    84,439 ( 2.1%)
        no_profiles:       512 ( 0.0%)
Top-9 popular complex argument-parameter features not optimized (100.0% of total 7,096,506):
       param_kw_opt: 1,834,706 (25.9%)
  param_forwardable: 1,824,953 (25.7%)
        param_block: 1,792,214 (25.3%)
         param_rest:   861,894 (12.1%)
    caller_kw_splat:   297,937 ( 4.2%)
       caller_splat:   283,669 ( 4.0%)
       param_kwrest:   200,208 ( 2.8%)
    caller_blockarg:       752 ( 0.0%)
       caller_kwarg:       173 ( 0.0%)
Top-1 compile error reasons (100.0% of total 391,562):
  exception_handler: 391,562 (100.0%)
Top-6 unhandled YARV insns (100.0% of total 1,000,531):
  invokesuperforward: 498,993 (49.9%)
         getconstant: 400,945 (40.1%)
         expandarray:  49,985 ( 5.0%)
       setblockparam:  49,972 ( 5.0%)
          checkmatch:     480 ( 0.0%)
                once:     156 ( 0.0%)
Top-2 unhandled HIR insns (100.0% of total 268,154):
          throw: 232,560 (86.7%)
  invokebuiltin:  35,594 (13.3%)
Top-19 side exit reasons (100.0% of total 8,710,811):
                  guard_shape_failure: 2,498,161 (28.7%)
  block_param_proxy_not_iseq_or_ifunc: 1,988,408 (22.8%)
                   guard_type_failure: 1,722,168 (19.8%)
                  unhandled_yarv_insn: 1,000,531 (11.5%)
                        compile_error:   391,562 ( 4.5%)
         unhandled_newarray_send_pack:   298,017 ( 3.4%)
                   unhandled_hir_insn:   268,154 ( 3.1%)
          patchpoint_method_redefined:   200,632 ( 2.3%)
                  unhandled_block_arg:   151,295 ( 1.7%)
           block_param_proxy_modified:   124,245 ( 1.4%)
                   guard_less_failure:    50,126 ( 0.6%)
               fixnum_lshift_overflow:     9,985 ( 0.1%)
     patchpoint_stable_constant_names:     6,366 ( 0.1%)
                 fixnum_mult_overflow:       570 ( 0.0%)
               obj_to_string_fallback:       429 ( 0.0%)
              patchpoint_no_ep_escape:       109 ( 0.0%)
                            interrupt:        39 ( 0.0%)
             guard_super_method_entry:         8 ( 0.0%)
             guard_greater_eq_failure:         6 ( 0.0%)
                             send_count: 328,747,903
                     dynamic_send_count:  83,186,941 (25.3%)
                   optimized_send_count: 245,560,962 (74.7%)
                  dynamic_setivar_count:   2,357,067 ( 0.7%)
                  dynamic_getivar_count:  12,378,139 ( 3.8%)
              dynamic_definedivar_count:     350,548 ( 0.1%)
              iseq_optimized_send_count:  93,623,831 (28.5%)
      inline_cfunc_optimized_send_count:  98,338,311 (29.9%)
       inline_iseq_optimized_send_count:   9,338,766 ( 2.8%)
non_variadic_cfunc_optimized_send_count:  26,453,005 ( 8.0%)
    variadic_cfunc_optimized_send_count:  17,807,049 ( 5.4%)
compiled_iseq_count:                               2,888
failed_iseq_count:                                     0
compile_time:                                      858ms
profile_time:                                       29ms
gc_time:                                            59ms
invalidation_time:                                  15ms
vm_write_pc_count:                           285,990,091
vm_write_sp_count:                           285,990,091
vm_write_locals_count:                       272,886,376
vm_write_stack_count:                        272,886,376
vm_write_to_parent_iseq_local_count:           1,079,877
vm_read_from_parent_iseq_local_count:         30,816,135
guard_type_count:                            314,169,071
guard_type_exit_ratio:                              0.5%
guard_shape_count:                                     0
code_region_bytes:                            14,401,536
zjit_alloc_bytes:                             19,128,598
total_mem_bytes:                              33,530,134
side_exit_count:                               8,710,811
total_insn_count:                          1,705,461,649
vm_insn_count:                               121,244,824
zjit_insn_count:                           1,584,216,825
ratio_in_zjit:                                     92.9%
```

</details>
2026-01-21 18:54:10 -05:00
Peter Zhu
965b16d766 [DOC] Add doc about eval coverage 2026-01-21 17:43:44 -05:00
Max Bernstein
0cc4e212c4
ZJIT: Get type information from branchif, branchunless, branchnil instructions (#15915)
Do a sort of "partial static single information (SSI)" form that learns
types of operands from branch instructions. A branchif, for example,
tells us that in the truthy path, we know the operand is not nil, and
not false. Similarly, in the falsy path, we know the operand is either
nil or false.

Add a RefineType instruction to attach this information.

This PR does this in SSA construction because it's pretty
straightforward, but we can also do a more aggressive version of this
that can learn information about e.g. int ranges from other checks later
in the optimization pipeline.
2026-01-21 19:23:29 +00:00
Kevin Menard
cfa97af7e1
ZJIT: Introduce GetLEP HIR instruction (#15917)
This PR is a follow-up to #15816. There, I introduced the `GuardSuperMethodEntry` HIR instruction and that needed the LEP. The LEP was also used by `GetBlockHandler`. Consequently, the codegen for `invokesuper` ended up loading the LEP twice. By introducing a new HIR instruction, we can load the LEP once and use it in both `GetBlockHandler` and `GuardSuperMethodEntry`.

I also updated `IsBlockGiven`, which conditionally loaded the LEP. To ensure we only use `GetLEP` in the cases we need it, I lifted most of the `IsBlockGiven` handler to HIR. As an added benefit, this addressed a TODO that @tekknolagi had written: when `block_given?` is called outside of a method we can rewrite to a constant `false`.

We could use `GetLEP` in the handling of `Defined`, but that looked a bit more involved and I wanted to keep this PR focused, so I'm suggesting we handle that as future work.
2026-01-21 19:07:20 +00:00
Aaron Patterson
6d0b47de86
ZJIT: Add a CFG to the LIR backend (#15879)
We want to use [linear scan register allocation](https://bernsteinbear.com/blog/linear-scan/), but a prerequisite is having a CFG available.  Previously LIR only had a linear block of instructions, this PR introduces a CFG to the LIR backend.  I've done my best to ensure that the "hot path" machine code we generate is the same (as I was testing I noticed that side exit machine code was being dumped in a different order).

This PR doesn't make any changes to the existing register allocator, it simply introduces a CFG to LIR.  The basic blocks in the LIR CFG always start with a label (the first instruction is a label) and the last 0, 1, or 2 instructions will be jump instructions.  No other jump instructions should appear mid-block.
2026-01-21 14:00:15 -05:00
Earlopain
f3a5b0cdb5
Apply backport label to 4.X branches (#15925) 2026-01-21 09:50:28 -08:00
git
e7f6a30d79 Update default gems list at 7f687b0abc155cd941d416677184f9 [ci skip] 2026-01-21 16:02:13 +00:00
Schneems
7f687b0abc [ruby/syntax_suggest] v2.0.3
https://github.com/ruby/syntax_suggest/commit/a81b92fcf2
2026-01-21 16:01:16 +00:00
Schneems
54fa9c81e1 [ruby/syntax_suggest] Refactor multi-prism version logic
The reason this logic for different methods branches in the class instead of internally was to be eagerly aggressive about runtime performance. This code is currently only used once for the document where it's invoked ~N times (where N is number of lines):

```ruby
module SyntaxSuggest
  class CleanDocument
    # ...
    def join_trailing_slash!
      trailing_groups = @document.select(&:trailing_slash?).map do |code_line|
        take_while_including(code_line.index..) { |x| x.trailing_slash? }
      end
      join_groups(trailing_groups)
      self
    end
```

Since this is not currently a hot-spot I think merging the branches and using a case statement is a reasonable tradeoff and avoids the need to do specific version testing.

An alternative idea was presented in #241 of behavior-based testing for branch logic (which I would prefer), however, calling the code triggered requiring a `DelegateClass` when the `syntax_suggest/api` is being required.

https://github.com/ruby/syntax_suggest/commit/ab122c455f
2026-01-21 15:57:38 +00:00
Earlopain
8aedb89681 [ruby/prism] Also handle BasicObject as a return value
We should touch these as little as possible and just pass them along

https://github.com/ruby/prism/commit/52c4fa785e
2026-01-21 13:21:37 +00:00
Benoit Daloze
913ffcd1dd [ruby/prism] Check using Prism nodes if a command call has any arguments in Ripper translator
* We don't know what `on_*` events might return so we cannot assume it's an Array.
* See https://github.com/ruby/prism/issues/3838#issuecomment-3774702396

https://github.com/ruby/prism/commit/bed4271ce2
2026-01-21 13:21:37 +00:00
Jean Boussier
519a4bdbc1 Optimize File.basename
The actual algorithm is largely unchanged, just allowed to use
singlebyte checks for common encodings.

It could certainly be optimized much further, as here again it often
scans from the front of the string when we're interested in the back of
it. But the algorithm as many Windows only corner cases so I'd rather
ship a good improvement now and eventually come back to it later.

Most of improvement here is from the reduced setup cost (avodi double
null checks, avoid duping the argument, etc), and skipping the multi-byte
checks.

```
compare-ruby: ruby 4.1.0dev (2026-01-19T03:51:30Z master 631bf19b37) +PRISM [arm64-darwin25]
built-ruby: ruby 4.1.0dev (2026-01-21T08:21:05Z opt-basename 7eb11745b2) +PRISM [arm64-darwin25]
```

|           |compare-ruby|built-ruby|
|:----------|-----------:|---------:|
|long       |      3.412M|   18.158M|
|           |           -|     5.32x|
|long_name  |      1.981M|    8.580M|
|           |           -|     4.33x|
|withext    |      3.200M|   12.986M|
|           |           -|     4.06x|
2026-01-21 11:23:01 +01:00
Hiroshi SHIBATA
0f1eea0949 [ruby/rubygems] Skip failing tests
https://github.com/ruby/rubygems/commit/ee68fd8d20
2026-01-21 07:40:49 +00:00
Jason Lunn
d93235874a [ruby/rubygems] Appease the linter again
https://github.com/ruby/rubygems/commit/92f35e9684
2026-01-21 07:40:48 +00:00
Jason Lunn
2efffe09e1 [ruby/rubygems] Appease the linter
https://github.com/ruby/rubygems/commit/aba307411a
2026-01-21 07:40:48 +00:00
Jason Lunn
c959741695 [ruby/rubygems] Add test
https://github.com/ruby/rubygems/commit/3d8140b289
2026-01-21 07:40:48 +00:00
Jason Lunn
3aa866ca0d [ruby/rubygems] Remove special behavior for rake
Fixes https://github.com/ruby/rubygems/pull/9244

https://github.com/ruby/rubygems/commit/7dc3d43d2e
2026-01-21 07:40:47 +00:00
Randy Stauner
6f1453dc08
ZJIT: Support optional keyword arguments in direct send (#15873)
This fills in constants when unspecified optional keyword args have static default values.
For complex defaults we calculate the kw_bits and utilize the checkkeyword logic we already had.

The following benchmarks used to register param_kw_opt.
Some of them (like graphql*) just trade that for some other complexity, or "too_many_args_for_lir".
Notable improvements include activerecord where the previous param_kw_opt count has a corresponding drop in complex args and dynamic_send_count and a nearly equal rise in optimized_send_count.
The gains are similar but not as complete in hexapdf, liquid-render, lobsters, railsbench, shipit.

| Benchmark | param_kw_opt | Δ one_or_more_complex | Δ too_many_args | Δ dynamic_send | Δ optimized_send |
|-----------|-------------:|----------------------:|----------------:|---------------:|-----------------:|
| activerecord | 6,307,141 | -6,253,823 | +4,084 | -6,306,223 | +6,279,766 |
| blurhash | 21 | -21 | +0 | -23 | +20 |
| chunky-png | 813,604 | -813,604 | +0 | -813,616 | +813,556 |
| erubi-rails | 1,590,395 | -590,274 | +35,578 | -552,914 | +550,826 |
| fluentd | 4,906 | -4,854 | +21 | -5,745 | +5,080 |
| graphql | 1,610,439 | -1,610,432 | +1,605,751 | -4,688 | +4,628 |
| graphql-native | 16,332,386 | -16,332,375 | +16,309,681 | -22,701 | +22,638 |
| hexapdf | 9,165,465 | -9,124,509 | +203,754 | -8,920,727 | +8,839,295 |
| liquid-compile | 14,817 | -14,792 | +0 | -14,705 | +15,045 |
| liquid-render | 3,994,905 | -3,994,901 | +0 | -3,994,868 | +3,020,779 |
| lobsters | 2,467,510 | -2,297,298 | +205,610 | -2,216,583 | +1,694,092 |
| protoboeuf | 11,521 | -11,521 | +0 | -11,523 | +11,520 |
| psych-load | 77,612 | -77,609 | +29,942 | -77,613 | -12,242 |
| rack | 2,743 | -2,742 | +0 | -2,750 | +2,668 |
| railsbench | 3,579,778 | -2,517,615 | +432,575 | -2,084,480 | +1,882,928 |
| ruby-lsp | 287,171 | -379,716 | +37 | -409,368 | -267,248 |
| rubyboy | 5,993,004 | -5,993,003 | +0 | -5,993,006 | +5,992,993 |
| sequel | 182,652 | -182,631 | +0 | -182,563 | +122,687 |
| shipit | 3,289,456 | -2,778,419 | +306,867 | -3,201,395 | +1,068,505 |
| tinygql | 2,732 | -2,732 | +1 | -2,734 | +2,729 |
2026-01-21 01:19:34 -05:00
Peter Zhu
01984fa80e [ruby/mmtk] Pass whether GC is moving to rb_mmtk_update_global_tables
https://github.com/ruby/mmtk/commit/002faa8f92
2026-01-21 01:55:16 +00:00
Alan Wu
36809a8d0c ZJIT: Add fail-fast assert for non-register {cpush,cpop}_pair
There is no splitting for these so let's add a assert to try and catch
misuse. VRegs are not necessarily registers in the end, so this is best
effort. In those situations they'll get a less proximate panic message.
2026-01-20 19:42:25 -05:00
Jeff Zhang
f7e73ba3bf ZJIT: A64: Avoid gaps in the stack when preserving registers for calls
Previously, we used a `str x, [sp, #-0x10]!` for each value, which
left an 8-byte gap. Use STP to store a pair at a time instead.
2026-01-20 19:42:25 -05:00
Peter Zhu
e24b52885f Allow objects on Ruby stack to be GC movable
Objects on the Ruby stack can be GC movable and there is corresponding
code in rb_execution_context_update to update references for moved objects.
2026-01-20 18:01:22 -05:00
Alan Wu
631a5076da ZJIT: Delete Insn::CPushAll and Insn::CPopAll
Since we automatically preserve registers across calls, it's never
necessary to manually and imprecisely do it with `C{Push,Pop}All`.
Delete them to remove the maintenance burden and reduce confusion.
2026-01-20 16:37:51 -05:00
Alan Wu
1bc5111411 ZJIT: Add a smoke test for --zjit-trace-exits
Better than nothing!
2026-01-20 16:37:51 -05:00
Earlopain
9ad8dd00b1 [ruby/prism] Fix on_* return value of ripper translator
You're supposed to return the first argument.
```rb
# Before
[[:stmts_new], [:rescue_mod, nil, nil], [:stmts_add, nil, nil], [:program, nil]]
# After
[[:stmts_new], [:rescue_mod, "1", "2"], [:stmts_add, nil, "1"], [:program, nil]]
```

The correct result would be:
`[[:rescue_mod, "1", "2"], [:stmts_new], [:stmts_add, nil, "1"], [:program, nil]]`

But the order depends on the prism AST so it seems very difficult to match.

https://github.com/ruby/prism/commit/94e0107729
2026-01-20 20:23:18 +00:00
Jeff Zhang
d225bb8b46
ZJIT: Compile IsA into load + compare for String/Array/Hash (#15878)
Resolves https://github.com/Shopify/ruby/issues/880

Implemented this by using the code generation for `GuardType` as a reference.
Not sure if this is the best way to go about it, but it seems to work.
2026-01-20 10:50:43 -05:00
Nobuyoshi Nakada
c27ae8d91a [ruby/psych] Remove excessive check of message
The order of "unexpected" and "missing" keyword argument errors at
`Data#initialize` had not been defined strictly.

[Bug #21844](https://bugs.ruby-lang.org/issues/21844)
ruby/ruby#15910

https://github.com/ruby/psych/commit/ba748d9b04
2026-01-20 14:15:41 +00:00
Earlopain
2842e61c92 Reapply "[ruby/prism] Add Ripper :on_sp events for Prism.lex_compat and Prism::Translation::Ripper"
This reverts commit 58f1127b51cf4fbb1f334f8701a041f40701dca2.
2026-01-20 14:18:30 +01:00
Earlopain
20113a228d Handle on_sp in syntax_suggest when using prism
It used to not emit this token type, but now it does.
So when a newer version of prism is present, we can fall back
to the same code that ripper uses.
2026-01-20 14:18:30 +01:00
Nobuyoshi Nakada
300927b4bb
[Bug #21845] Rebuild gem extensions at RUBY_ABI_VERSION change
As `TARGET_SO_DIR_TIMESTAMP` contains `ruby_version`, after bumping
`RUBY_ABI_VERSION` it should not be existing.  Usually such outdated
files will be removed by `make outdate-bundled-gems` automatically
invoked by `make up`.
2026-01-20 19:21:45 +09:00
Hiroshi SHIBATA
58f1127b51
Revert "[ruby/prism] Add Ripper :on_sp events for Prism.lex_compat and Prism::Translation::Ripper"
This reverts commit 35a7b5159f39de2cac848c072674e5350cc41aa4.

This broke syntax_suggest.

https://github.com/ruby/ruby/actions/runs/21167011751/job/60874111912
2026-01-20 19:10:16 +09:00
Benoit Daloze
35a7b5159f [ruby/prism] Add Ripper :on_sp events for Prism.lex_compat and Prism::Translation::Ripper
* Handle line continuations.
* Handle space at the end of file in LexCompat.

https://github.com/ruby/prism/commit/32bd13eb7d

Co-authored-by: Earlopain <14981592+Earlopain@users.noreply.github.com>
2026-01-20 09:53:08 +00:00
Jean Boussier
53fe9933fd Optimize File.extname for common encodings
Similar optimizations to the ones performed in GH-15907.

- Skip the expensive multi-byte encoding handling for the common
  encodings that are known to be safe.
- Use `CheckPath` to save on copying the argument and only scan it for
  NULL bytes once.
- Create the return string with rb_enc_str_new instead of rb_str_subseq
  as it's going to be a very small string anyway.

This could be optimized a little bit further by searching for both `.` and `dirsep`
in one pass,

```
compare-ruby: ruby 4.1.0dev (2026-01-19T03:51:30Z master 631bf19b37) +PRISM [arm64-darwin25]
built-ruby: ruby 4.1.0dev (2026-01-20T07:33:42Z master 6fb50434e3) +PRISM [arm64-darwin25]
```

|           |compare-ruby|built-ruby|
|:----------|-----------:|---------:|
|long       |      3.606M|   22.229M|
|           |           -|     6.17x|
|long_name  |      2.254M|   13.416M|
|           |           -|     5.95x|
|short      |     16.488M|   29.969M|
|           |           -|     1.82x|
2026-01-20 09:58:51 +01:00
Jean Boussier
6fb50434e3 file.c: Stop passing NULL for encoding
`rb_encoding *` is defined as `nonnull` so `if (enc)` is optimized
out by the compiler. We have to pass a boolean alongside it to
avoid crashes.
2026-01-20 08:33:42 +01:00
Jean Boussier
2d10f15118 file.c: dirname_n also use strrdirsep when n > 1
It's both simpler and faster.

|       |compare-ruby|built-ruby|
|:------|-----------:|---------:|
|long   |      3.960M|   24.072M|
|       |           -|     6.08x|
|short  |     15.417M|   29.841M|
|       |           -|     1.94x|
|n_4    |      3.858M|   18.415M|
|       |           -|     4.77x|
2026-01-20 08:33:42 +01:00
Jean Boussier
990cf1286a file.c: Inc macro now handle NULL encoding 2026-01-20 08:33:42 +01:00
Jean Boussier
240a58ecc6 file.c: skiproot doesn't need encoding 2026-01-20 08:33:42 +01:00
Jean Boussier
11d29d32d2 file.c: strrdirsep search from the back of the string for common encodings
`strrdirsep` quite innficiently search for the last separator from the front
of the string.

This is surprising but necessary because in Shift-JS, `0x5c` can
be the second byte of some multi-byte characters, as such it's
not possible to do a pure ASCII search. And it's even more costly
because for each character we need to do expensive checks to
handle this possibility.

However in the overwhelming majority of cases, paths are encoded
in UTF-8 or ASCII, so for these common encodings we can use the
more logical and efficient algorithm.

```
compare-ruby: ruby 4.1.0dev (2026-01-17T14:40:03Z master 00a3b71eaf) +PRISM [arm64-darwin25]
built-ruby: ruby 4.1.0dev (2026-01-19T07:43:57Z file-dirname-lower.. a8d3535e5b) +PRISM [arm64-darwin25]
```

|       |compare-ruby|built-ruby|
|:------|-----------:|---------:|
|long   |      3.974M|   23.674M|
|       |           -|     5.96x|
|short  |     15.281M|   29.034M|
|       |           -|     1.90x|
2026-01-20 08:33:42 +01:00
Jean Boussier
27bb1623cd file.c: Optimize rb_file_dirname_n fixed costs
- `str_null_check` was performed twice, once by `FilePathStringValue`
  and a second time by `StringValueCStr`.
- `StringValueCStr` was checking for the terminator presence, but we
  don't care about that.
- `FilePathStringValue` calls `rb_str_new_frozen` to ensure `fname`
  isn't mutated, but that's costly for such a check. Instead we
  can do it in debug mode only.
- `rb_enc_get` is slow because it accepts arbitrary objects, even immediates,
  so it has to do numerous type checks. Add a much faster `rb_str_enc_get`
  when we know we're dealing with a string.
- `rb_enc_copy` is slow for the same reasons, since we already have the
  encoding, we can use `rb_enc_str_new` instead.
2026-01-20 08:33:42 +01:00
Alan Wu
826dbcfb2b ZJIT: A64: Remove nop padding after conditional branches
Previously, there were a lot of nops after conditional branches. They
come from branch to LIR labels:

    ./miniruby --zjit-call-threshold=1 --zjit-dump-disasm -e 'Object || String'

    # Insn: v14 CheckInterrupts
    # RUBY_VM_CHECK_INTS(ec)
      ldur w2, [x20, #0x20]
      tst w2, w2
      b.ne #0x120900278
      nop
      nop
      nop
      nop
      nop
    # Insn: v15 Test v11
      tst x0, #-5
      mov x2, #0
      mov x3, #1
      csel x2, x2, x3, eq
    # Insn: v16 IfTrue v15, bb3(v6, v11)
      tst x2, x2
      b.eq #0x120900198
      nop
      nop
      nop
      nop
      nop

They gunk up the disassembly and can't be helpful for speed. This commit
removes them. I think they were accidentally inherited from certain YJIT
branches that require padding for patching. ZJIT doesn't have these
requirements.

Use a single branch instruction for conditional branches to labels; Jmp
already uses a single `B` instruction. This will work for assemblers
that generate less than ~260,000 instructions -- plenty.

Let the CodeBlock::label_ref() callback return a failure, so we can
fail compilation instead of panicking in case we do get large offsets.
2026-01-19 22:47:36 -05:00
Peter Zhu
fa910e2bba [ruby/mmtk] Restore MMTK_DEBUG around zeroing in obj_free
https://github.com/ruby/mmtk/commit/ae69d69768
2026-01-20 01:32:51 +00:00
Earlopain
16adb9303f [ruby/prism] Optimize ripper translator
Creating state classes is pretty expensive.
Since they are not modifiable, we can reuse them instead.

Benchmark script:
```rb
require "ripper"
require "prism"
require "benchmark/ips"

codes = Dir["**/*.rb"].map { File.read(it) }

Benchmark.ips do |x|
  x.config(time: 10)
  x.report("prism") { codes.each { Prism::Translation::Ripper.lex(it) } }
  x.report("ripper") { codes.each { Ripper.lex(it) } }

  x.compare!
end
```

Before:

```
ruby 4.0.0 (2025-12-25 revision https://github.com/ruby/prism/commit/553f1675f3) +PRISM [x86_64-linux]
Warming up --------------------------------------
               prism     1.000 i/100ms
              ripper     1.000 i/100ms
Calculating -------------------------------------
               prism      0.293 (± 0.0%) i/s     (3.42 s/i) -      3.000 in  10.248348s
              ripper      0.633 (± 0.0%) i/s     (1.58 s/i) -      7.000 in  11.055687s

Comparison:
              ripper:        0.6 i/s
               prism:        0.3 i/s - 2.16x  slower
```

After

```
ruby 4.0.0 (2025-12-25 revision https://github.com/ruby/prism/commit/553f1675f3) +PRISM [x86_64-linux]
Warming up --------------------------------------
               prism     1.000 i/100ms
              ripper     1.000 i/100ms
Calculating -------------------------------------
               prism      0.486 (± 0.0%) i/s     (2.06 s/i) -      5.000 in  10.280413s
              ripper      0.635 (± 0.0%) i/s     (1.58 s/i) -      7.000 in  11.027169s

Comparison:
              ripper:        0.6 i/s
               prism:        0.5 i/s - 1.31x  slower
```

https://github.com/ruby/prism/commit/bdde16554c
2026-01-19 23:54:39 +00:00
Peter Zhu
c939330b7a [DOC] Escape Coverage 2026-01-19 17:09:29 -05:00
Alan Wu
6f890976e0 JITs: Fix comment about ARM64 stack growth direction [ci skip] 2026-01-19 15:17:11 -05:00
Benoit Daloze
859920dfd2 [ruby/prism] Add Prism::Source#line_to_byte_offset and replace direct accesses to offsets
https://github.com/ruby/prism/commit/ff81a29ba5
2026-01-19 12:03:33 +00:00
Benoit Daloze
ae5efb55d1 [ruby/prism] Simplify and optimize Prism::Node#tunnel
* By comparing byte offsets which folds 3 branches into 1.
* Also avoids allocation of Location objects.

https://github.com/ruby/prism/commit/71fcb891e0
2026-01-19 12:03:33 +00:00
Benoit Daloze
e85fd7c878 [ruby/prism] Fix docs of opening_loc/closing_loc of BlockNode
https://github.com/ruby/prism/commit/0b22d9060a
2026-01-19 12:03:33 +00:00
dependabot[bot]
aa31754e56 Bump actions/cache in /.github/actions/setup/directories
Bumps [actions/cache](https://github.com/actions/cache) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](9255dc7a25...8b402f58fb)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: 5.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 18:56:44 +09:00
Earlopain
3c9ca23ba4 [ruby/prism] Remove duplicate lex tests
`RipperTest` already does this (added in https://github.com/ruby/prism/pull/3849)
Since it doesn't use the token classes, it also lists out all the excludes instead of just claiming some are passing.

https://github.com/ruby/prism/commit/e86a28263c
2026-01-19 07:46:48 +00:00
Hiroshi SHIBATA
df479f41f8 [ruby/rubygems] Added another usage of pristine command
ref. https://github.com/rubygems/guides/issues/388

https://github.com/ruby/rubygems/commit/43f3768f09
2026-01-19 07:14:33 +00:00
Sutou Kouhei
fb75e99efe [ruby/rubygems] Add missing .binmode for Gem::AtomicFileWriter
In https://github.com/ruby/rubygems/pull/9202, I commented that `temp_file.binmode` is redundant. But I
was wrong. We need `temp_file.binmode` even when we specify
`File::BINARY`. Sorry.

https://github.com/ruby/rubygems/commit/d9f1f5c6a6
2026-01-19 07:10:42 +00:00
Hiroshi SHIBATA
631bf19b37
Skip Onigmo file sync. This target is only for commit sync. 2026-01-19 12:51:30 +09:00
dependabot[bot]
ed116239c7 Bump actions/cache from 5.0.1 to 5.0.2
Bumps [actions/cache](https://github.com/actions/cache) from 5.0.1 to 5.0.2.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](9255dc7a25...8b402f58fb)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: 5.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-18 18:34:27 -08:00
Herwin
b4a62a1ca9
[DOC] Update docs for rb_interned_str and related functions (#15897)
Related to [Bug #21842].

* rb_interned_str: document what decides whether the returned string is
  in US-ASCII or BINARY encoding.
* rb_interned_str_cstr: include the same description as rb_interned_str
  for the encoding. This one was still missing the update for US-ASCII
  and erroneously said the returned string was alwasy in BINARY encoding
* rb_str_to_interned_str: document how the encoding of the result is
  defined.

Co-authored-by: Herwin <herwinw@users.noreply.github.com>
2026-01-19 11:16:47 +09:00
Peter Zhu
64c142770a [ruby/mmtk] Fix assertion in rb_gc_impl_ractor_cache_free for RUBY_FREE_AT_EXIT
https://github.com/ruby/mmtk/commit/e2a89d5a22
2026-01-18 21:34:57 +00:00
Peter Zhu
b7e9e66b59 [ruby/mmtk] Check RUBY_FL_FINALIZE on new location of object if moved
https://github.com/ruby/mmtk/commit/a31deee342
2026-01-18 21:34:57 +00:00
Peter Zhu
4111c5465f [ruby/mmtk] Replace RUBY_ASSERT with MMTK_ASSERT
https://github.com/ruby/mmtk/commit/e92baf15ef
2026-01-18 21:34:57 +00:00
tomoya ishida
b536c6a849
[DOC] Remove _emphasis_ in code blocks which is not handled as emphasis anymore (#15901) 2026-01-19 04:59:09 +09:00
tomoya ishida
37c7ee536d
[DOC] Replace rdoc style codeblocks with markdown style backtick codeblocks in markdown documents (#15900) 2026-01-19 02:25:02 +09:00
Jean Boussier
43d879d3ac rb_file_join_fastpath: removed useless StringValueCStr 2026-01-18 17:15:36 +01:00
Peter Zhu
19450d85d6 [DOC] Improve docs for ObjectSpace.define_finalizer 2026-01-18 10:47:13 -05:00
Jean Boussier
7e0e9984d0 rb_file_join_fastpath: optimize searching for separators
`chompdirsep` searches from the start of the string each time, which
perhaps is necessary for certain encodings (not even sure?) but for
the common encodings it's very wasteful. Instead we can start from the
back of the string and only compare one or two characters in most cases.

Also replace `StringValueCStr` for the simpler `rb_str_null_check`
as we only care about whether the string contains `NULL` bytes, we
don't care whether it is NULL terminated or not.

We also only check the final string for NULLs.

```
compare-ruby: ruby 4.1.0dev (2026-01-17T14:40:03Z master 00a3b71eaf) +PRISM [arm64-darwin25]
built-ruby: ruby 4.1.0dev (2026-01-18T12:55:15Z spedup-file-join 5948e92e03) +PRISM [arm64-darwin25]
warming up....

|              |compare-ruby|built-ruby|
|:-------------|-----------:|---------:|
|two_strings   |      2.477M|   19.317M|
|              |           -|     7.80x|
|many_strings  |    547.577k|   10.298M|
|              |           -|    18.81x|
|array         |    515.280k|  523.291k|
|              |           -|     1.02x|
|mixed         |    621.840k|  635.422k|
|              |           -|     1.02x|
```
2026-01-18 16:31:31 +01:00
Jean Boussier
6cd4549060 Optimize File.join common use case
`File.join` is a hotspot for common libraries such as Zeitwerk
and Bootsnap. It has a fairly flexible signature, but 99% of
the time it's called with just two (or a small number of) UTF-8 strings.

If we optimistically optimize for that use case we can cut down a large
number of type and encoding checks, significantly speeding up the method.

The one remaining expensive check we could try to optimize is `str_null_check`.
Given it's common to use the same base string for joining, we could memoize it.
Also we could precompute it for literal strings.

```
compare-ruby: ruby 4.1.0dev (2026-01-17T14:40:03Z master 00a3b71eaf) +PRISM [arm64-darwin25]
built-ruby: ruby 4.1.0dev (2026-01-18T12:10:38Z spedup-file-join 069bab58d4) +PRISM [arm64-darwin25]
warming up....

|              |compare-ruby|built-ruby|
|:-------------|-----------:|---------:|
|two_strings   |      2.475M|    9.444M|
|              |           -|     3.82x|
|many_strings  |    551.975k|    2.346M|
|              |           -|     4.25x|
|array         |    514.946k|  522.034k|
|              |           -|     1.01x|
|mixed         |    621.236k|  633.189k|
|              |           -|     1.02x|
```
2026-01-18 16:31:31 +01:00
Earlopain
d1dc4bdb2f [ruby/prism] Fix ripper translator for __END__
https://github.com/ruby/prism/commit/2792ac78ca
2026-01-18 14:07:06 +00:00
Peter Zhu
00a3b71eaf [DOC] Improve docs for ObjectSpace.memsize_of_all 2026-01-17 09:40:03 -05:00
Masafumi Koba
81e06e7004 [ruby/timeout] Improve Timeout.timeout documentation formatting and typos
This commit makes a few minor improvements to the documentation of the `Timeout.timeout` method.
The changes include fixing typos and enhancing formatting for better readability.

We can see the latest version of the documentation here:
https://docs.ruby-lang.org/en/master/Timeout.html#method-c-timeout

Also, we can verify this change locally by running:

```shell
rdoc
open doc/Timeout.html
```

https://github.com/ruby/timeout/commit/53ee559e15
2026-01-17 14:05:07 +00:00
Nobuyoshi Nakada
78b7646bdb
[Bug #21842] Let rb_interned_str return US-ASCII if possible 2026-01-17 14:19:15 +09:00
Nobuyoshi Nakada
8ca2f6489b
Revert "Fix rb_interned_str: create strings with BINARY (akak ASCII_8BIT) encoding"
This reverts commit 1f3c52dc155fb7fbc42fc8e146924091ba1dfa20.
2026-01-17 13:38:55 +09:00
Max Bernstein
3e13b7d4ef ZJIT: Fix land race
InvokeProc and HIR effects landed without an intermediate rebase so we
got a conflict in the form of a type checker error (not handled new
opcode in a new function).
2026-01-16 23:07:00 -05:00
Nozomi Hijikata
0e0fad1e58
ZJIT: Specialize OPTIMIZED_METHOD_TYPE_CALL (#15859)
Closes: https://github.com/Shopify/ruby/issues/865

## Benchmark 
### lobsters
- wall clock time
  - before patch: Average of last 10, non-warmup iters: 809ms
  - after patch: Average of last 10, non-warmup iters: 754ms
- zjit stats below

<details>

<summary>before patch</summary>

```
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (54.9% of total 18,003,698):
                                               Hash#fetch: 3,184,106 (17.7%)
                                            Regexp#match?:   707,148 ( 3.9%)
                                                Hash#key?:   689,879 ( 3.8%)
                                              String#sub!:   489,841 ( 2.7%)
                                           Array#include?:   470,648 ( 2.6%)
                                             Set#include?:   397,520 ( 2.2%)
                                                String#<<:   396,279 ( 2.2%)
                                       String#start_with?:   373,666 ( 2.1%)
                                               Kernel#dup:   352,617 ( 2.0%)
                                               Array#any?:   350,454 ( 1.9%)
                                              Hash#delete:   331,784 ( 1.8%)
                                               String.new:   307,248 ( 1.7%)
                                              Integer#===:   262,336 ( 1.5%)
                                         Symbol#end_with?:   255,538 ( 1.4%)
                                             Kernel#is_a?:   247,292 ( 1.4%)
                                    Process.clock_gettime:   221,588 ( 1.2%)
                                                Integer#>:   219,718 ( 1.2%)
                                            String#match?:   216,903 ( 1.2%)
                                          String#downcase:   213,108 ( 1.2%)
                                               Integer#<=:   202,617 ( 1.1%)
Top-20 calls to C functions from JIT code (80.3% of total 130,255,689):
                             rb_vm_opt_send_without_block: 28,329,698 (21.7%)
                                             rb_hash_aref:  8,992,191 ( 6.9%)
                                          rb_vm_env_write:  8,526,087 ( 6.5%)
                                               rb_vm_send:  8,337,448 ( 6.4%)
                     rb_zjit_writebarrier_check_immediate:  7,809,310 ( 6.0%)
                                        rb_obj_is_kind_of:  6,098,929 ( 4.7%)
                                rb_vm_getinstancevariable:  5,783,055 ( 4.4%)
                                        rb_vm_invokesuper:  5,038,443 ( 3.9%)
                           rb_ivar_get_at_no_ractor_check:  4,762,093 ( 3.7%)
                                             rb_ary_entry:  4,283,966 ( 3.3%)
                                             rb_hash_aset:  2,429,862 ( 1.9%)
                                rb_vm_setinstancevariable:  2,343,571 ( 1.8%)
                               rb_vm_opt_getconstant_path:  2,284,810 ( 1.8%)
                                               Hash#fetch:  1,778,515 ( 1.4%)
                                                    fetch:  1,405,591 ( 1.1%)
                                        rb_vm_invokeblock:  1,381,332 ( 1.1%)
                                        rb_str_buf_append:  1,362,272 ( 1.0%)
                                rb_ec_ary_new_from_values:  1,324,997 ( 1.0%)
                               rb_class_allocate_instance:  1,288,936 ( 1.0%)
                                    rb_hash_new_with_size:    998,628 ( 0.8%)
Top-2 not optimized method types for send (100.0% of total 4,896,274):
  iseq: 4,893,452 (99.9%)
  null:     2,822 ( 0.1%)
Top-4 not optimized method types for send_without_block (100.0% of total 782,296):
        optimized_send: 479,562 (61.3%)
        optimized_call: 256,609 (32.8%)
                  null:  41,967 ( 5.4%)
  optimized_block_call:   4,158 ( 0.5%)
Top-4 instructions with uncategorized fallback reason (100.0% of total 7,250,555):
             invokesuper: 5,038,443 (69.5%)
             invokeblock: 1,381,332 (19.1%)
             sendforward:   798,924 (11.0%)
  opt_send_without_block:    31,856 ( 0.4%)
Top-18 send fallback reasons (100.0% of total 43,885,845):
                          send_without_block_polymorphic: 18,533,639 (42.2%)
                                           uncategorized:  7,250,555 (16.5%)
                          send_not_optimized_method_type:  4,896,274 (11.2%)
                          send_without_block_no_profiles:  4,741,871 (10.8%)
                                        send_no_profiles:  2,865,577 ( 6.5%)
                            one_or_more_complex_arg_pass:  2,825,240 ( 6.4%)
  send_without_block_not_optimized_method_type_optimized:    740,329 ( 1.7%)
                          send_without_block_megamorphic:    709,818 ( 1.6%)
                                        send_polymorphic:    541,186 ( 1.2%)
        send_without_block_not_optimized_need_permission:    382,622 ( 0.9%)
                                   too_many_args_for_lir:    173,244 ( 0.4%)
                                     argc_param_mismatch:     50,382 ( 0.1%)
            send_without_block_not_optimized_method_type:     41,967 ( 0.1%)
                 send_without_block_cfunc_array_variadic:     36,302 ( 0.1%)
                                obj_to_string_not_string:     34,169 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     32,436 ( 0.1%)
                                        send_megamorphic:     28,613 ( 0.1%)
                          ccall_with_frame_too_many_args:      1,621 ( 0.0%)
Top-4 setivar fallback reasons (100.0% of total 2,343,571):
            not_monomorphic: 2,120,856 (90.5%)
               not_t_object:   125,163 ( 5.3%)
                too_complex:    97,531 ( 4.2%)
  new_shape_needs_extension:        21 ( 0.0%)
Top-2 getivar fallback reasons (100.0% of total 5,908,168):
  not_monomorphic: 5,658,909 (95.8%)
      too_complex:   249,259 ( 4.2%)
Top-3 definedivar fallback reasons (100.0% of total 405,079):
  not_monomorphic: 397,150 (98.0%)
      too_complex:   5,122 ( 1.3%)
     not_t_object:   2,807 ( 0.7%)
Top-6 invokeblock handler (100.0% of total 1,381,332):
   monomorphic_iseq: 685,359 (49.6%)
        polymorphic: 521,992 (37.8%)
  monomorphic_other: 104,640 ( 7.6%)
  monomorphic_ifunc:  55,505 ( 4.0%)
        no_profiles:   9,164 ( 0.7%)
        megamorphic:   4,672 ( 0.3%)
Top-9 popular complex argument-parameter features not optimized (100.0% of total 3,097,538):
       param_kw_opt: 1,333,367 (43.0%)
        param_block:   632,885 (20.4%)
  param_forwardable:   600,601 (19.4%)
         param_rest:   329,020 (10.6%)
       param_kwrest:   119,971 ( 3.9%)
    caller_kw_splat:    39,001 ( 1.3%)
       caller_splat:    36,785 ( 1.2%)
    caller_blockarg:     5,798 ( 0.2%)
       caller_kwarg:       110 ( 0.0%)
Top-1 compile error reasons (100.0% of total 186,900):
  exception_handler: 186,900 (100.0%)
Top-7 unhandled YARV insns (100.0% of total 186,598):
       getblockparam: 99,414 (53.3%)
  invokesuperforward: 81,667 (43.8%)
       setblockparam:  2,837 ( 1.5%)
         getconstant:  1,537 ( 0.8%)
          checkmatch:    616 ( 0.3%)
         expandarray:    360 ( 0.2%)
                once:    167 ( 0.1%)
Top-3 unhandled HIR insns (100.0% of total 236,962):
          throw: 198,474 (83.8%)
  invokebuiltin:  35,767 (15.1%)
      array_max:   2,721 ( 1.1%)
Top-19 side exit reasons (100.0% of total 15,427,184):
                   guard_type_failure: 6,865,696 (44.5%)
                  guard_shape_failure: 6,779,586 (43.9%)
  block_param_proxy_not_iseq_or_ifunc: 1,030,319 ( 6.7%)
                   unhandled_hir_insn:   236,962 ( 1.5%)
                        compile_error:   186,900 ( 1.2%)
                  unhandled_yarv_insn:   186,598 ( 1.2%)
                 fixnum_mult_overflow:    50,739 ( 0.3%)
           block_param_proxy_modified:    28,119 ( 0.2%)
        patchpoint_no_singleton_class:    14,903 ( 0.1%)
         unhandled_newarray_send_pack:    14,481 ( 0.1%)
               fixnum_lshift_overflow:    10,085 ( 0.1%)
     patchpoint_stable_constant_names:     9,198 ( 0.1%)
              patchpoint_no_ep_escape:     7,815 ( 0.1%)
                  expandarray_failure:     4,533 ( 0.0%)
          patchpoint_method_redefined:       662 ( 0.0%)
               obj_to_string_fallback:       277 ( 0.0%)
                   guard_less_failure:       163 ( 0.0%)
                            interrupt:       128 ( 0.0%)
             guard_greater_eq_failure:        20 ( 0.0%)
                             send_count: 151,233,937
                     dynamic_send_count:  43,885,845 (29.0%)
                   optimized_send_count: 107,348,092 (71.0%)
                  dynamic_setivar_count:   2,343,571 ( 1.5%)
                  dynamic_getivar_count:   5,908,168 ( 3.9%)
              dynamic_definedivar_count:     405,079 ( 0.3%)
              iseq_optimized_send_count:  37,324,023 (24.7%)
      inline_cfunc_optimized_send_count:  46,056,028 (30.5%)
       inline_iseq_optimized_send_count:   3,756,875 ( 2.5%)
non_variadic_cfunc_optimized_send_count:  11,618,909 ( 7.7%)
    variadic_cfunc_optimized_send_count:   8,592,257 ( 5.7%)
compiled_iseq_count:                              5,289
failed_iseq_count:                                    0
compile_time:                                   1,664ms
profile_time:                                      13ms
gc_time:                                           20ms
invalidation_time:                                479ms
vm_write_pc_count:                          127,571,422
vm_write_sp_count:                          127,571,422
vm_write_locals_count:                      122,781,971
vm_write_stack_count:                       122,781,971
vm_write_to_parent_iseq_local_count:            689,945
vm_read_from_parent_iseq_local_count:        14,721,820
guard_type_count:                           167,633,896
guard_type_exit_ratio:                             4.1%
guard_shape_count:                                    0
code_region_bytes:                           38,912,000
zjit_alloc_bytes:                            40,542,102
total_mem_bytes:                             79,454,102
side_exit_count:                             15,427,184
total_insn_count:                           927,373,567
vm_insn_count:                              156,976,359
zjit_insn_count:                            770,397,208
ratio_in_zjit:                                    83.1%
```

</details>

<details>

<summary>after patch</summary>

```
***ZJIT: Printing ZJIT statistics on exit***
Top-20 not inlined C methods (55.0% of total 18,012,630):
                                               Hash#fetch: 3,184,101 (17.7%)
                                            Regexp#match?:   707,150 ( 3.9%)
                                                Hash#key?:   689,871 ( 3.8%)
                                              String#sub!:   489,841 ( 2.7%)
                                           Array#include?:   470,648 ( 2.6%)
                                             Set#include?:   397,520 ( 2.2%)
                                                String#<<:   396,279 ( 2.2%)
                                       String#start_with?:   382,538 ( 2.1%)
                                               Kernel#dup:   352,617 ( 2.0%)
                                               Array#any?:   350,454 ( 1.9%)
                                              Hash#delete:   331,802 ( 1.8%)
                                               String.new:   307,248 ( 1.7%)
                                              Integer#===:   262,336 ( 1.5%)
                                         Symbol#end_with?:   255,540 ( 1.4%)
                                             Kernel#is_a?:   247,292 ( 1.4%)
                                    Process.clock_gettime:   221,588 ( 1.2%)
                                                Integer#>:   219,718 ( 1.2%)
                                            String#match?:   216,905 ( 1.2%)
                                          String#downcase:   213,107 ( 1.2%)
                                               Integer#<=:   202,617 ( 1.1%)
Top-20 calls to C functions from JIT code (80.1% of total 130,218,934):
                             rb_vm_opt_send_without_block: 28,073,153 (21.6%)
                                             rb_hash_aref:  8,992,167 ( 6.9%)
                                          rb_vm_env_write:  8,526,089 ( 6.5%)
                                               rb_vm_send:  8,337,453 ( 6.4%)
                     rb_zjit_writebarrier_check_immediate:  7,786,426 ( 6.0%)
                                        rb_obj_is_kind_of:  6,098,927 ( 4.7%)
                                rb_vm_getinstancevariable:  5,783,053 ( 4.4%)
                                        rb_vm_invokesuper:  5,038,444 ( 3.9%)
                           rb_ivar_get_at_no_ractor_check:  4,762,093 ( 3.7%)
                                             rb_ary_entry:  4,283,965 ( 3.3%)
                                             rb_hash_aset:  2,429,864 ( 1.9%)
                                rb_vm_setinstancevariable:  2,343,573 ( 1.8%)
                               rb_vm_opt_getconstant_path:  2,284,809 ( 1.8%)
                                               Hash#fetch:  1,778,510 ( 1.4%)
                                                    fetch:  1,405,591 ( 1.1%)
                                        rb_vm_invokeblock:  1,381,329 ( 1.1%)
                                        rb_str_buf_append:  1,362,272 ( 1.0%)
                                rb_ec_ary_new_from_values:  1,325,005 ( 1.0%)
                               rb_class_allocate_instance:  1,288,944 ( 1.0%)
                                    rb_hash_new_with_size:    998,629 ( 0.8%)
Top-2 not optimized method types for send (100.0% of total 4,896,276):
  iseq: 4,893,454 (99.9%)
  null:     2,822 ( 0.1%)
Top-3 not optimized method types for send_without_block (100.0% of total 525,687):
        optimized_send: 479,562 (91.2%)
                  null:  41,967 ( 8.0%)
  optimized_block_call:   4,158 ( 0.8%)
Top-4 instructions with uncategorized fallback reason (100.0% of total 7,250,556):
             invokesuper: 5,038,444 (69.5%)
             invokeblock: 1,381,329 (19.1%)
             sendforward:   798,924 (11.0%)
  opt_send_without_block:    31,859 ( 0.4%)
Top-18 send fallback reasons (100.0% of total 43,629,303):
                          send_without_block_polymorphic: 18,533,669 (42.5%)
                                           uncategorized:  7,250,556 (16.6%)
                          send_not_optimized_method_type:  4,896,276 (11.2%)
                          send_without_block_no_profiles:  4,741,899 (10.9%)
                                        send_no_profiles:  2,865,579 ( 6.6%)
                            one_or_more_complex_arg_pass:  2,825,242 ( 6.5%)
                          send_without_block_megamorphic:    709,818 ( 1.6%)
                                        send_polymorphic:    541,187 ( 1.2%)
  send_without_block_not_optimized_method_type_optimized:    483,720 ( 1.1%)
        send_without_block_not_optimized_need_permission:    382,623 ( 0.9%)
                                   too_many_args_for_lir:    173,244 ( 0.4%)
                                     argc_param_mismatch:     50,382 ( 0.1%)
            send_without_block_not_optimized_method_type:     41,967 ( 0.1%)
                 send_without_block_cfunc_array_variadic:     36,302 ( 0.1%)
                                obj_to_string_not_string:     34,169 ( 0.1%)
              send_without_block_direct_keyword_mismatch:     32,436 ( 0.1%)
                                        send_megamorphic:     28,613 ( 0.1%)
                          ccall_with_frame_too_many_args:      1,621 ( 0.0%)
Top-4 setivar fallback reasons (100.0% of total 2,343,573):
            not_monomorphic: 2,120,858 (90.5%)
               not_t_object:   125,163 ( 5.3%)
                too_complex:    97,531 ( 4.2%)
  new_shape_needs_extension:        21 ( 0.0%)
Top-2 getivar fallback reasons (100.0% of total 5,908,165):
  not_monomorphic: 5,658,912 (95.8%)
      too_complex:   249,253 ( 4.2%)
Top-3 definedivar fallback reasons (100.0% of total 405,079):
  not_monomorphic: 397,150 (98.0%)
      too_complex:   5,122 ( 1.3%)
     not_t_object:   2,807 ( 0.7%)
Top-6 invokeblock handler (100.0% of total 1,381,329):
   monomorphic_iseq: 685,363 (49.6%)
        polymorphic: 521,984 (37.8%)
  monomorphic_other: 104,640 ( 7.6%)
  monomorphic_ifunc:  55,505 ( 4.0%)
        no_profiles:   9,164 ( 0.7%)
        megamorphic:   4,673 ( 0.3%)
Top-9 popular complex argument-parameter features not optimized (100.0% of total 3,094,719):
       param_kw_opt: 1,333,367 (43.1%)
        param_block:   632,886 (20.5%)
  param_forwardable:   600,605 (19.4%)
         param_rest:   329,019 (10.6%)
       param_kwrest:   119,971 ( 3.9%)
    caller_kw_splat:    39,001 ( 1.3%)
       caller_splat:    33,962 ( 1.1%)
    caller_blockarg:     5,798 ( 0.2%)
       caller_kwarg:       110 ( 0.0%)
Top-1 compile error reasons (100.0% of total 186,917):
  exception_handler: 186,917 (100.0%)
Top-7 unhandled YARV insns (100.0% of total 186,598):
       getblockparam: 99,414 (53.3%)
  invokesuperforward: 81,667 (43.8%)
       setblockparam:  2,837 ( 1.5%)
         getconstant:  1,537 ( 0.8%)
          checkmatch:    616 ( 0.3%)
         expandarray:    360 ( 0.2%)
                once:    167 ( 0.1%)
Top-3 unhandled HIR insns (100.0% of total 236,969):
          throw: 198,475 (83.8%)
  invokebuiltin:  35,773 (15.1%)
      array_max:   2,721 ( 1.1%)
Top-19 side exit reasons (100.0% of total 15,450,102):
                   guard_type_failure: 6,888,596 (44.6%)
                  guard_shape_failure: 6,779,586 (43.9%)
  block_param_proxy_not_iseq_or_ifunc: 1,030,319 ( 6.7%)
                   unhandled_hir_insn:   236,969 ( 1.5%)
                        compile_error:   186,917 ( 1.2%)
                  unhandled_yarv_insn:   186,598 ( 1.2%)
                 fixnum_mult_overflow:    50,739 ( 0.3%)
           block_param_proxy_modified:    28,119 ( 0.2%)
        patchpoint_no_singleton_class:    14,903 ( 0.1%)
         unhandled_newarray_send_pack:    14,481 ( 0.1%)
               fixnum_lshift_overflow:    10,085 ( 0.1%)
     patchpoint_stable_constant_names:     9,198 ( 0.1%)
              patchpoint_no_ep_escape:     7,815 ( 0.1%)
                  expandarray_failure:     4,533 ( 0.0%)
          patchpoint_method_redefined:       662 ( 0.0%)
               obj_to_string_fallback:       277 ( 0.0%)
                   guard_less_failure:       163 ( 0.0%)
                            interrupt:       122 ( 0.0%)
             guard_greater_eq_failure:        20 ( 0.0%)
                             send_count: 150,986,368
                     dynamic_send_count:  43,629,303 (28.9%)
                   optimized_send_count: 107,357,065 (71.1%)
                  dynamic_setivar_count:   2,343,573 ( 1.6%)
                  dynamic_getivar_count:   5,908,165 ( 3.9%)
              dynamic_definedivar_count:     405,079 ( 0.3%)
              iseq_optimized_send_count:  37,324,039 (24.7%)
      inline_cfunc_optimized_send_count:  46,056,046 (30.5%)
       inline_iseq_optimized_send_count:   3,756,881 ( 2.5%)
non_variadic_cfunc_optimized_send_count:  11,618,958 ( 7.7%)
    variadic_cfunc_optimized_send_count:   8,601,141 ( 5.7%)
compiled_iseq_count:                              5,289
failed_iseq_count:                                    0
compile_time:                                   1,700ms
profile_time:                                      13ms
gc_time:                                           21ms
invalidation_time:                                519ms
vm_write_pc_count:                          127,557,549
vm_write_sp_count:                          127,557,549
vm_write_locals_count:                      122,768,084
vm_write_stack_count:                       122,768,084
vm_write_to_parent_iseq_local_count:            689,953
vm_read_from_parent_iseq_local_count:        14,730,705
guard_type_count:                           167,853,730
guard_type_exit_ratio:                             4.1%
guard_shape_count:                                    0
code_region_bytes:                           38,928,384
zjit_alloc_bytes:                            41,103,415
total_mem_bytes:                             80,031,799
side_exit_count:                             15,450,102
total_insn_count:                           927,432,364
vm_insn_count:                              157,182,251
zjit_insn_count:                            770,250,113
ratio_in_zjit:                                    83.1%
```

</details>
2026-01-16 21:19:54 -05:00
Peter Zhu
8a586af33b Don't force major GC when there are allocatable slots
[Bug #21838]

When we have allocatable slots, we can grow the heap instead of forcing
a major GC. This prevents major GC to be ran very often in certain situations.
See the ticket for more details.

On ruby-bench, we can see that this patch doesn't cause any significant
regressions:

    --------------  -----------  ----------  ---------  -----------  ----------  ---------  --------------  -------------
    bench           master (ms)  stddev (%)  RSS (MiB)  branch (ms)  stddev (%)  RSS (MiB)  branch 1st itr  master/branch
    activerecord    148.2        0.3         59.2       150.0        0.8         69.7       1.015           0.988
    chunky-png      435.2        0.3         72.9       438.8        0.1         66.7       0.993           0.992
    erubi-rails     733.8        1.2         118.7      704.8        0.2         98.3       1.077           1.041
    hexapdf         1400.4       1.1         247.0      1405.0       0.9         223.7      0.986           0.997
    liquid-c        32.5         3.3         32.8       32.5         2.1         30.7       1.042           0.999
    liquid-compile  31.0         1.7         35.1       33.4         3.9         32.8       0.938           0.928
    liquid-render   84.7         0.4         30.8       86.3         0.4         30.8       0.981           0.982
    lobsters        594.7        0.6         310.5      596.6        0.4         306.0      1.057           0.997
    mail            75.6         2.8         53.3       76.9         0.7         53.2       0.968           0.982
    psych-load      1122.8       1.2         29.2       1145.1       0.4         31.7       0.964           0.981
    railsbench      1244.7       0.3         115.5      1254.8       1.1         115.2      0.939           0.992
    rubocop         103.7        0.5         94.1       104.3        0.5         92.4       0.985           0.994
    ruby-lsp        88.3         0.6         78.5       88.5         1.2         77.9       0.992           0.997
    sequel          26.9         0.9         33.6       28.3         1.4         32.1       0.954           0.952
    shipit          1119.3       1.5         171.4      1075.7       2.1         162.5      1.873           1.040
    --------------  -----------  ----------  ---------  -----------  ----------  ---------  --------------  -------------
2026-01-16 17:02:03 -05:00
Jean Boussier
1f3c52dc15 Fix rb_interned_str: create strings with BINARY (akak ASCII_8BIT) encoding
[Bug #21842]

The documentation always stated as much, and it's consistent with the
rb_str_* family of functions.
2026-01-16 22:44:38 +01:00
John Hawthorn
c56ce8a6c1 Remove objspace->flags.has_newobj_hook
We aren't using this anymore and the hook is called in gc.c
2026-01-16 12:46:20 -08:00
Earlopain
87147ba5e9 [ruby/prism] Make the ripper shim work with rdoc
The filter class is a 1:1 copy of ruby.

rdoc has 32 test failures. It seems to expect `on_sp` in some cases to render code as written.

https://github.com/ruby/prism/commit/74bb12c825
2026-01-16 20:19:26 +00:00
Jean Boussier
1c7e19f961 rb_free_tmp_buffer: use ruby_sized_xfree
We know the buffer length, we might as well feed that information
back to the GC.
2026-01-16 21:11:17 +01:00
Jean Boussier
3164d4e8a2 [ruby/json] Extract json_fast_memcpy16 for readability
https://github.com/ruby/json/commit/1b276c8623
2026-01-16 17:52:54 +00:00
Scott Myron
456ef9140a [ruby/json] Use __builtin_memcpy, if available, to copy overlapping byte ranges in copy_remaining_bytes to avoid a branch to MEMCPY. Additionally use a space as padding byte instead of an 'X' so it can be represented diretly on AArch64 with a single instruction.
https://github.com/ruby/json/commit/643ee11fed
2026-01-16 17:52:54 +00:00
Jacob
bc6c895d7b
ZJIT: Create HIR effect system (#15359)
**Progress**
I've added a new directory, `zjit/src/hir_effect`. It follows the same structure as `zjit/src/hir_type` and includes:
- a ruby script to generate a rust file containing a bitset of effects we want to track
- a modified `hir.rs` to include an `effects_of` function that catalogs effects for each HIR instruction, similar to `infer_type`. Right now these effects are not specialized, all instructions currently return the top of the lattice (any effect)
- a module file for effects at `zjit/src/hir_effect/mod.rs` that again, mirrors `zjit/src/hir_type/mod.rs`. This contains a lot of helper functions and lattice operations like union and intersection

**Design Idea**
The effect system is bitset-based rather than range-based. This is the first kind of effect system described in [Max's blog post](https://bernsteinbear.com/blog/compiler-effects/).
Practically, having effects defined for each HIR instruction should allow us to have better generalization than the implicit effect system we have for c functions that we annotation as elidable, leaf, etc. Additionally, this could allow us to reason about the effects of multiple HIR instructions unioned together, something I don't believe currently exists.

**Practical Goals**
This PR replaces `has_effects` with a new effects-based `is_elidable` function. This has no behavior change to the JIT, but will make it easier to reason about effects of basic blocks and CCalls with the new design. We may be able to accomplish other quality of life improvements, such as consolidation of `nogc`, `leaf`, and other annotations.
2026-01-16 17:08:20 +00:00
Nobuyoshi Nakada
91744cd202
Include abi.h in the dependency of rubyspec-capiext 2026-01-17 00:15:20 +09:00
Earlopain
074a23ab77 [ruby/prism] Add Ripper.tokenize to translation layer
It's public API and trivial to implement.

https://github.com/ruby/prism/commit/e77545f8b5
2026-01-16 12:07:41 +00:00
Andrii Furmanets
f872901bb2
MatchData: Avoid large stack allocations in MatchData (GH-15872) 2026-01-16 19:52:16 +09:00
Nobuyoshi Nakada
16cd9daa39
Rust interface is out of our scope 2026-01-16 18:27:17 +09:00
Nobuyoshi Nakada
67d4ceb525
Expand rb_data_type_t::reserved for future use 2026-01-16 16:52:32 +09:00
Nobuyoshi Nakada
a797561e25
Update Typed Data dump on debuggers [ci skip] 2026-01-16 16:47:34 +09:00
Nobuyoshi Nakada
f7d3f675fe
Win32: refine handing of missing-baseruby failure
`exit` in `cmd.exe` ignores non-option, non-digits argument, and exits with the current %ERRORLEVEL%.
2026-01-16 11:12:32 +09:00
Nobuyoshi Nakada
8c39d8d343
Win32: fix baseruby at reconfig
Get rid of the built `ruby.exe` in the current directory.
2026-01-16 11:08:53 +09:00
Nobuyoshi Nakada
81420d6e13
Win32: split -basic-vars- step 2026-01-16 11:01:27 +09:00
Peter Zhu
5d2fd5088d Fix duplicate static assert names in imemo.h 2026-01-15 17:57:27 -05:00
Peter Zhu
f7ae32ed3b Pin ID symbols
Symbols with a corresponding ID should be pinned because they can be used
by things that don't support compaction.
2026-01-15 17:57:27 -05:00
Peter Zhu
6e480e6714 Allow symbols to move in compaction 2026-01-15 17:57:27 -05:00
Earlopain
c34c7def5a [ruby/prism] Fix locations for invalid syntax when using expect1_opening
Followup to https://github.com/ruby/prism/pull/3827

It sets the start to the opening but it should instead just
continue on as usual.
Fixes https://github.com/ruby/prism/issues/3851

Notice how the AST actually contains "123" in both the body and end keyword.

https://github.com/ruby/prism/commit/8f69c5af08
2026-01-15 21:15:34 +00:00
Earlopain
15939e3c30 [ruby/prism] Make irb work with the ripper shim
This is everything that `irb` uses. It works in their test-suite, but there are 20 failures when using the shim that I haven't looked into at all.

`parse` is not used by `irb`. `scan` is, and it's basically `parse` but also including errors. `irb` doesn't seem to care about the errors, so I didn't implement that.

https://github.com/ruby/prism/commit/2c5826b39f
2026-01-15 21:03:55 +00:00
nozomemein
ce390f1995 ZJIT: Remove redundant unboxing 2026-01-15 09:00:53 -08:00
nozomemein
844f072ce1 ZJIT: Inline ArrayAref 2026-01-15 09:00:53 -08:00
nozomemein
256c806a1d ZJIT: Write the result of UnboxFixnum HIR as type spec so that we can make use of it later (e.g. fold_constants for ArrayAref) 2026-01-15 09:00:53 -08:00
nozomemein
065db7cf61 ZJIT: Rename ArrayArefFixnum -> ArrayAref 2026-01-15 09:00:53 -08:00
Nobuyoshi Nakada
11edc286d8
Make Array#map and Array#select more tolerant
Only when YJIT is enabled, the redefinition of `Array#<<` affects
these methods.
2026-01-15 20:32:20 +09:00
Hiroshi SHIBATA
6afac93c5c Restore irb to warning target
Users should add `irb` to their Gemfile.
`Gem::BUNDLED_GEMS.force_activate 'irb'` is workaround for short term.
2026-01-15 17:20:34 +09:00
Daisuke Aritomo
ca9c61800b Suppress bundled gem warning on `binding.irb'
This patch silences the "this won't work in the next version of Ruby"
warning displayed when irb is autoloaded via `binding.irb`.

    main.rb:1: warning: irb used to be loaded from the standard library, but is not part of the default gems since Ruby 4.0.0.
    You can add irb to your Gemfile or gemspec to fix this error.
    /.../irb.rb:9: warning: reline used to be loaded from the standard library, but is not part of the default gems since Ruby 4.0.0.
    You can add reline to your Gemfile or gemspec to fix this error.

    From: main.rb @ line 1 :

     => 1: binding.irb

    /.../input-method.rb:284: warning: rdoc used to be loaded from the standard library, but is not part of the default gems since Ruby 4.0.0.
    You can add rdoc to your Gemfile or gemspec to fix this error.

This warning is incorrect and misleading: users should not need to
include irb (and its dependencies) to their Gemfiles to use
`binding.irb`, even in future versions of Ruby. It is agreed that the
runtime takes care of that.
2026-01-15 17:20:34 +09:00
Hiroshi SHIBATA
2d79cc9bfc Added example for bundle/inline 2026-01-15 16:16:16 +09:00
Daisuke Aritomo
a28c856183 Add comments 2026-01-15 16:16:16 +09:00
Daisuke Aritomo
270c7fcec1 Fake BUNDLE_GEMFILE and BUNDLE_LOCKFILE to let checks pass
Bundler::Runtime#setup requires a real existing lockfile (see
Bundler::SharedHelpers#default_lockfile).
2026-01-15 16:16:16 +09:00
Daisuke Aritomo
943b085949 [Bug #21723] Let binding.irb properly load irb by fixing force_activate()
This patch fixes a problem where `binding.irb` (= force_activate('irb'))
fails under `bundle exec` when the Gemfile does not contain `irb` and
does contain a gem which is (1) not installed in GEM_HOME (2) sourced
using `path:`/`git:`.

The original approach constructing a temporary definition fails since
it does not set the equalivent of `path:`/`git:`.

Always reconstructing a definition from a Gemfile and applying lockfile
constraints should be a more robust approach.

[Bug #21723]
2026-01-15 16:16:16 +09:00
git
de17b84a3d Update bundled gems list as of 2026-01-15 2026-01-15 06:55:51 +00:00
Nobuyoshi Nakada
886202bac8
Count assertions in child processes
Fix up GH-15785.
2026-01-15 12:30:29 +09:00
OKURA Masafumi
189bb64af8 [ci-skip] Shorter example for Module#instance_method
The previous example code was too complex and includes extra logics
that's not relevant to its main usage: `bind`.
The new example code focuses on `bind_call` so that readers can
understand how it works more easily.
2026-01-15 11:36:18 +09:00
Lars Kanis
806031d2ce Windows: Remove workaround for LLVM windres
It was introduced as part of the Arm64-on-Windows patch:
  https://github.com/ruby/ruby/pull/8995

But a few days later it was fixed on the LLVM side for llvm-18 and backported to MSYS2:
  https://github.com/msys2/MINGW-packages/pull/19157#issuecomment-1825285063

Now this code is only unnecessary complexity.
2026-01-15 11:14:54 +09:00
Kevin Menard
4a21b83693
ZJIT: Optimize common invokesuper cases (#15816)
* ZJIT: Profile `invokesuper` instructions

* ZJIT: Introduce the `InvokeSuperDirect` HIR instruction

The new instruction is an optimized version of `InvokeSuper` when we know the `super` target is an ISEQ.

* ZJIT: Expand definition of unspecializable to more complex cases

* ZJIT: Ensure `invokesuper` optimization works when the inheritance hierarchy is modified

* ZJIT: Simplify `invokesuper` specialization to most common case

Looking at ruby-bench, most `super` calls don't pass a block, which means we can use the already optimized `SendWithoutBlockDirect`.

* ZJIT: Track `super` method entries directly to avoid GC issues

Because the method entry isn't typed as a `VALUE`, we set up barriers on its `VALUE` fields. But, that was insufficient as the method entry itself could be collected in certain cases, resulting in dangling objects. Now we track the method entry as a `VALUE` and can more naturally mark it and its children.

* ZJIT: Optimize `super` calls with simple argument forms

* ZJIT: Report the reason why we can't optimize an `invokesuper` instance

* ZJIT: Revise send fallback reasons for `super` calls

* ZJIT: Assert `super` calls are `FCALL` and don't need visibily checks
2026-01-14 19:10:06 -05:00
Alan Wu
cdb2b0eed5 YJIT: A64: In CPopAll, pop into the register before using MSR
Or else we put garbage into the flags.
2026-01-14 17:19:52 -05:00
Alan Wu
9f3225d0c5 YJIT: Properly preserve register mapping in cpush_all() and cpop_all()
Previously, cpop_all() did not in fact restore the register mapping
state since it was effectively doing a no-op
`self.ctx.set_reg_mapping(self.ctx.get_reg_mapping())`. This desync in
bookkeeping led to issues with the --yjit-dump-insns option because
print_str() used to use cpush_all() and cpop_all().
2026-01-14 17:19:52 -05:00
Alan Wu
9930468479 YJIT: Fix --yjit-dump-insns by removing {cpush,cpop}_all() in printers
cpush_all() and cpop_all() in theory enabled these `print_*` utilities
to work in more spots, but with automatically spilling in asm.ccall(),
the benefits are now limited. They also have a bug at the moment. Stop
using them to dodge the bug.
2026-01-14 17:19:52 -05:00
Alan Wu
ac22989066 YJIT: Add crashing test for --yjit-dump-insns
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2026-01-14 17:19:52 -05:00
Peter Zhu
068713964a [DOC] Add docs for WeakMap#inspect 2026-01-14 17:08:40 -05:00
Max Bernstein
b21edc1323
ZJIT: Add assume_no_singleton_classes to avoid invalidation loops (#15871)
Make sure we check if we have seen a singleton for this class before assuming we have not. Port the API from YJIT.
2026-01-14 21:58:10 +00:00
Jeff Zhang
1ca066059f
ZJIT: Add Type::has_value method (#15867)
Resolves TODO added in #15863 (See https://github.com/ruby/ruby/pull/15863#discussion_r2687769112)

Adds a method `Type::has_value` for comparing value specialized types with a `Const`.
2026-01-14 13:37:14 -05:00
Nobuyoshi Nakada
b8566faca5
[ruby/json] Remove trailing spaces [ci skip]
https://github.com/ruby/json/commit/15eb40dbdf
2026-01-14 21:30:19 +09:00
Scott Myron
a650c90fab [ruby/json] initialize search.chunk_end to silence a warning about it being potentially uninitialized
https://github.com/ruby/json/commit/73818b80c8
2026-01-14 07:59:32 +00:00
Scott Myron
24ad90d3e0 [ruby/json] use a conditional to select SIMD implementation rather than pointer
https://github.com/ruby/json/commit/86a5cce405
2026-01-14 07:59:32 +00:00
git
875dce2f59 Update bundled gems list as of 2026-01-13 2026-01-14 06:55:49 +00:00
Hiroshi SHIBATA
323ad363ca
Switch filename of release and publish workflows 2026-01-14 15:22:04 +09:00
Hiroshi SHIBATA
ab522c8876
Stop to sync tsort changes 2026-01-14 14:47:06 +09:00
Hiroshi SHIBATA
3aa4aed0cb
Skip Onigumo to check latest version 2026-01-14 14:44:14 +09:00
Nobuyoshi Nakada
49ce12d2ef
Silence building rubyspec-capiext [ci skip] 2026-01-14 13:55:35 +09:00
Chris Hasiński
6e61496531
Pre-allocate IO.select result arrays based on input size (#15850)
io.c: pre-allocate IO.select result arrays based on input size

The ternary (rp?rb_ary_new():rb_ary_new2(0)) became pointless after
commit a51f30c671 (Variable Width Allocation, Mar 2022) made both
rb_ary_new() and rb_ary_new2(0) equivalent.

Instead of just removing the dead code, improve on the original intent
by pre-allocating based on the actual input array size. This avoids
reallocations when many FDs are ready.

Benchmark (100 ready FDs): ~8% improvement (5.59 -> 5.11 us/op)
2026-01-14 14:41:00 +13:00
Jeff Zhang
65a4845780
ZJIT: Constant-fold LoadField/GuardBitEquals from known-frozen object
Resolves https://github.com/Shopify/ruby/issues/915

When we have `LoadField` with a `Shape` return type, we can fold it similar to the object case.
`GuardBitEquals` can be removed when the argument is `Const` and the values are equal.

The behaviors for loading instances variables from frozen/dynamic objects are already covered in existing tests so no new tests were added.
2026-01-13 20:06:01 -05:00
Takashi Kokubun
4f8478f50c misc/.vscode/settings.json: Fix rust-analyzer warnings 2026-01-13 15:27:45 -08:00
Peter Zhu
9f8505f06c [ruby/mmtk] Implement object movement support for finalizer table
https://github.com/ruby/mmtk/commit/e5e2c1c347
2026-01-13 22:59:22 +00:00
Max Bernstein
6f38d3de7f
ZJIT: Only print bold text in TTY (#15864)
This is really irritating when piping to a file or pager.
2026-01-13 20:47:26 +00:00
Randy Stauner
1a0b356d40 Add pushtoarray insn to fix segfault with forwarding + splat
Example insns diff for `def x = [3]; def a(...) = b(*x, 2, 3, ...)`

     == disasm: #<ISeq:a@-e:1 (1,13)-(1,42)>
     local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
     [ 1] "..."@0
     0000 putself                                                          (   1)[Ca]
     0000 putself
     0000 opt_send_without_block                 <calldata!mid:x, argc:0, FCALL|VCALL|ARGS_SIMPLE>
     0000 splatarray                             true
     0000 putobject                              2
     0000 putobject                              3
    +0000 pushtoarray                            2
     0000 getlocal_WC_0                          "..."@0
     0000 sendforward                            <calldata!mid:b, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL|FORWARDING>, nil
     0000 leave                                  [Re]

This matches the insns produced by parse.y
2026-01-13 11:18:19 -08:00
tkling
9db0a8c7db [DOC] zjit: small typo fix
prerequists -> prerequisites
2026-01-13 10:36:15 -05:00
Jun Aruga
6a0a3d605b [ruby/openssl] Fix test_digest.rb in FIPS.
https://github.com/ruby/openssl/commit/27a9a92309
2026-01-13 15:22:09 +00:00
Edouard CHIN
b722d37f21 [ruby/rubygems] Add a missing "require 'etc'" statement:
- Ref https://github.com/ruby/rubygems/pull/9171#discussion_r2658056892
- Referencing the constant Etc may raise a `NameError` depending on
  whether other Rubygems/Bundler codepath have evaluated a prior
  "require 'etc'". This can be reproduced with this Gemfile:

  ```ruby
  source "https://rubygems.org"

  gem 'prism', github: "ruby/prism"
  ```

https://github.com/ruby/rubygems/commit/5d435e6863
2026-01-13 11:12:00 +00:00
eileencodes
b7dbdfe23a [ruby/rubygems] Refactor atomic file write
This refactoring is based off the changes in
test/rubygems/test_gem_remote_fetcher.rb. It no longer uses tempfile as
a result.

https://github.com/ruby/rubygems/commit/be6fd6550b
2026-01-13 07:12:47 +00:00
卜部昌平
60cf8598b2 [nit] refactor rename inline functions
Pretty sure commit 0f64da9672d88921439f6fdb306d16fece9b9c90 didn't
intend to welcome extension libraries to use these functions.
2026-01-13 11:53:43 +09:00
git
9fb9bfab60 Update default gems list at ead107f0d7bd3cf1f30428b7907b98 [ci skip] 2026-01-13 01:53:37 +00:00
Takashi Kokubun
ead107f0d7 [ruby/prism] Bump to v1.8.0
https://github.com/ruby/prism/commit/9c12be6e6a
2026-01-13 01:52:48 +00:00
Nobuyoshi Nakada
910fcfad14
mk_builtin_loader: Count local variable definition lines 2026-01-13 10:34:38 +09:00
Chris Hasiński
5de4cc5608 Fix regexp performance regression for patterns starting with s/k
Commit 981ee02c7c ("Fix performance problem with /k/i and /s/i") was
merged for Ruby 4.0 to enable partial Boyer-Moore optimization for
patterns containing 's' or 'k' by using the prefix before those
characters.

However, when 's' or 'k' appears at the start of a pattern (no usable
prefix), set_bm_skip() returns 0 and the code returned early without
setting any optimization mode, leaving reg->optimize at
ONIG_OPTIMIZE_NONE. This caused up to 30x slowdown for patterns like
/slackware/i when matched against strings with non-ASCII characters.

This patch keeps the improvement from 981ee02c7c for patterns with
3+ char prefix, while fixing the regression by falling back to
ONIG_OPTIMIZE_EXACT_IC with the full pattern when the usable prefix
is less than 3 characters.

Before: /\bslackware\b/i with non-ASCII string: 2.24 us/op
After:  /\bslackware\b/i with non-ASCII string: 0.70 us/op (3.2x faster)

[Bug #21824]
2026-01-13 10:19:44 +09:00
Takashi Kokubun
09cd13114a redmine-backporter.rb: Check remote-tracking branch
on `has_commit` check for the `backport` command.

I don't maintain local "master" branch on my ruby repository for stable
branch maintenance. I want just running `git fetch origin` to make it
work. It should work for those who pull origin/master into their local
master too.
2026-01-12 16:55:53 -08:00
Randy Stauner
7c91db9ea0
ZJIT: Check arg limit before pushing SendWithoutBLockDirect insn (#15854)
This reduces some processing and makes the HIR more accurate.
2026-01-12 23:28:06 +00:00
Peter Zhu
2daed3c022 [ruby/mmtk] Clear slot when object is freed
https://github.com/ruby/mmtk/commit/87290e45b2
2026-01-12 22:23:34 +00:00
Max Bernstein
328655633b ZJIT: Optimize Integer#[]
This is used a lot in optcarrot.
2026-01-12 17:11:47 -05:00
Earlopain
ee1aa78bee [ruby/prism] Correctly expose ripper state
It is for example used by `irb`, `rdoc`, `syntax_suggest`

https://github.com/ruby/prism/commit/255aeb2485
2026-01-12 22:08:25 +00:00
Randy Stauner
d81a11d4e6 ZJIT: Snapshot FrameState with reordered args before direct send
You can see the reordered args in the new Snapshot right before the
DirectSend insn:

       v14:Any = Snapshot FrameState { pc: 0x00, stack: [v6, v11, v13], locals: [] }
       PatchPoint MethodRedefined(Object@0x00, a@0x00, cme:0x00)
       PatchPoint NoSingletonClass(Object@0x00)
       v22:HeapObject[class_exact*:Object@VALUE(0x00)] = GuardType v6, HeapObject[class_exact*:Object@VALUE(0x00)]
    -  v23:BasicObject = SendWithoutBlockDirect v22, :a (0x00), v13, v11
    -  v16:Any = Snapshot FrameState { pc: 0x00, stack: [v23], locals: [] }
    +  v23:Any = Snapshot FrameState { pc: 0x00, stack: [v6, v13, v11], locals: [] }
    +  v24:BasicObject = SendWithoutBlockDirect v22, :a (0x00), v13, v11
    +  v16:Any = Snapshot FrameState { pc: 0x00, stack: [v24], locals: [] }
2026-01-12 16:50:48 -05:00
Randy Stauner
351616af8c ZJIT: Add snapshot tests for direct send 2026-01-12 16:50:48 -05:00
Max Bernstein
41d9eb784b ZJIT: Inline Array#empty? 2026-01-12 16:43:49 -05:00
Max Bernstein
5cec11f45a ZJIT: Inline Array#length 2026-01-12 16:43:49 -05:00
Earlopain
a1ba9f5733 [ruby/prism] Use one file for versioned parser classes
One per version seems excessive.

Do note that `rubocop-ast` used to require individual parser files. I wouldn't consider that to be part of the API since everything is autoloaded.
From a GitHub code search, I didn't find anyone else doing it like that.

https://github.com/ruby/prism/commit/458f622c34
2026-01-12 16:13:08 +00:00
Nobuyoshi Nakada
f34297604f
Remove a direct call of rb_raise in Onigmo 2026-01-12 20:24:56 +09:00
Nobuyoshi Nakada
aaf47cca03
Now onigenc_single_byte_code_to_mbclen checks out-of-bound 2026-01-12 20:24:55 +09:00
K.Takata
76b1d4a481
[k-takata/Onigmo] Disable error message for capture history when not needed
Add `#ifdef USE_CAPTURE_HISTORY`.

https://github.com/k-takata/Onigmo/commit/8217be2c3a
2026-01-12 20:01:43 +09:00
K.Takata
81c1334904
[k-takata/Onigmo] Fix out-of-bounds read in parse_char_class()
(Close
https://github.com/k-takata/Onigmo/pull/139)

/[\x{111111}]/ causes out-of-bounds read when encoding is a single byte
encoding. \x{111111} is an invalid codepoint for a single byte encoding.
Check if it is a valid codepoint.

https://github.com/k-takata/Onigmo/commit/d4cf99d30b
2026-01-12 20:01:43 +09:00
K.Takata
16086128cc
[k-takata/Onigmo] Suppress warning on 64-bit builds
https://github.com/k-takata/Onigmo/commit/ced209d5e9
2026-01-12 20:01:43 +09:00
K.Takata
ac379278e8
[k-takata/Onigmo] Fix stack overflow with X+++++++++++++++++++…
Imported the fix from:
4097828d7c

https://github.com/k-takata/Onigmo/commit/786b4849c1
2026-01-12 20:01:43 +09:00
K.Takata
f0b31a5898
[k-takata/Onigmo] Fix SEGV in onig_error_code_to_str() (Fix
https://github.com/k-takata/Onigmo/pull/132)

When onig_new(ONIG_SYNTAX_PERL) fails with ONIGERR_INVALID_GROUP_NAME,
onig_error_code_to_str() crashes.
onig_scan_env_set_error_string() should have been used when returning
ONIGERR_INVALID_GROUP_NAME.

https://github.com/k-takata/Onigmo/commit/00cc7e28a3
2026-01-12 20:01:43 +09:00
K.Takata
496e74d0cc
[k-takata/Onigmo] Fix that onig_new() may crash
When onig_reg_init() returns an error, onig_free_body() which is called
via onig_new() may crash because some members are not properly
initialized.  Fix it.

https://github.com/k-takata/Onigmo/commit/d2a090a57e
2026-01-12 20:01:42 +09:00
K.Takata
ad150e9039
[k-takata/Onigmo] Update version number (6.2.0)
* Update the version number to 6.2.0
* Update LTVERSION to 6:5:0.

https://github.com/k-takata/Onigmo/commit/9e0f7ceee0
2026-01-12 20:01:42 +09:00
K.Takata
a097878ed4
[k-takata/Onigmo] Comment out unused errors
https://github.com/k-takata/Onigmo/commit/5555ee4c81
2026-01-12 20:01:42 +09:00
K.Takata
916fbf1063
[k-takata/Onigmo] Update copyright information
* Update our copyright information.
* Import the latest information from oniguruma.

Related: #95

https://github.com/k-takata/Onigmo/commit/0d8662b500
2026-01-12 20:01:42 +09:00
K.Takata
85a7171b41
[k-takata/Onigmo] Add USE_CASE_MAP_API config
The case_map API is mainly (only?) used in Ruby.
Make it possible to disable the API.

https://github.com/k-takata/Onigmo/commit/80e289d6bb
2026-01-12 20:01:42 +09:00
K.Takata
f9131412f8
[k-takata/Onigmo] Revise set_bm_skip()
https://github.com/k-takata/Onigmo/commit/6875da50f7
2026-01-12 20:01:42 +09:00
K.Takata
bbf9bf3fc5
[k-takata/Onigmo] Remove code for backward BM search
The code has not been used for long.
(Oniguruma also removed this code.)

https://github.com/k-takata/Onigmo/commit/8796781fdd
2026-01-12 20:01:42 +09:00
K.Takata
fb7f344b09
[k-takata/Onigmo] Remove code for reg->int_map
https://github.com/k-takata/Onigmo/commit/6c58de82d2
2026-01-12 20:01:42 +09:00
Nobuyoshi Nakada
6484a71a4f
Add Onigmo to sync_default_gems.rb 2026-01-12 20:01:41 +09:00
Benoit Daloze
bf36ad9c12 ZJIT: remove unused rb_RSTRUCT_LEN() 2026-01-12 08:44:26 +01:00
Benoit Daloze
916c0a8105 ZJIT: remove unused rb_RSTRUCT_SET() 2026-01-12 08:44:26 +01:00
Nobuyoshi Nakada
d57c3296a9
Re-fix VCS::GIT#branch_beginning
Count the last release date from the whole working directory, not
only the version headers.
2026-01-12 11:28:06 +09:00
Peter Zhu
61c372a1b7 [DOC] Improve docs for ObjectSpace.count_symbols 2026-01-11 10:46:56 -05:00
Peter Zhu
1267a3ab56 [DOC] Improve docs for ObjectSpace.count_imemo_objects 2026-01-11 10:46:56 -05:00
Peter Zhu
cf5c5abe1e [DOC] Improve docs for ObjectSpace.count_tdata_objects 2026-01-11 10:46:56 -05:00
Nobuyoshi Nakada
8baaece6d9
[ruby/prism] [Bug #21831] Fix denominator of rational float literal
Denominators can contain underscores in fraction part as well as other
numeric literals.

[Bug #21831]: https://bugs.ruby-lang.org/issues/21831

https://github.com/ruby/prism/commit/e247cb58c7
2026-01-11 22:53:12 +09:00
Chris Hasiński
a071078e90 pack.c: remove wasted allocation in BER integer packing
The 'w' format (BER compressed integer) was allocating an empty
string with rb_str_new(0, 0) then immediately overwriting it with
the correctly-sized allocation. Remove the wasted first allocation.

~50% improvement on BER pack benchmarks.
2026-01-11 21:42:37 +09:00
Heath Dutton🕴️
3363861a5a Remove RUBY_API_VERSION check in cxxanyargs.hpp
The version check used undefined macros, causing -Wundef warnings.
The conditional is no longer needed as Ruby is past version 3.1.
2026-01-11 21:06:51 +09:00
Jean Boussier
73be9992e9 Disambiguate private and public RSTRUCT_ helpers
RSTRUCT_LEN / RSTRUCT_GET / RSTRUCT_SET all existing in two
versions, one public that does type and frozens checks
and one private that doesn't.

The problem is that this is error prone because the public version
is always accessible, but the private one require to include
`internal/struct.h`. So you may have some code that rely on the
public version, and later on the private header is included and
changes the behavior.

This already led to introducing a bug in YJIT & ZJIT:
https://github.com/ruby/ruby/pull/15835
2026-01-11 13:03:03 +01:00
Nobuyoshi Nakada
6a630d992e
Push the commits to the origin at make matz [ci skip] 2026-01-11 17:09:40 +09:00
Nobuyoshi Nakada
463a806fb1
Fix VCS::GIT#branch_beginning to search since the last relase
The ChangeLog in ruby-4.0.0 did not contain entries for 3.5.0.
2026-01-11 15:12:58 +09:00
Nobuyoshi Nakada
acd0c68a07
Relax the flaky test threshold on RHEL 10.0 x86_64 2026-01-11 14:51:49 +09:00
Peter Zhu
0d4538b57d [DOC] Improve docs for Module#>= 2026-01-10 09:31:35 -05:00
Peter Zhu
f0f4a683b4 [DOC] Improve docs for Module#<= 2026-01-10 09:31:35 -05:00
Peter Zhu
0b83346f1c [DOC] Improve docs for Module#< 2026-01-10 09:31:35 -05:00
Peter Zhu
98c414a678 [DOC] Improve docs for Module#> 2026-01-10 09:31:35 -05:00
Jun Aruga
0b69f7fa34 [ruby/openssl] Fix test_cipher.rb in FIPS.
https://github.com/ruby/openssl/commit/11bd2efb2a
2026-01-10 07:20:55 +00:00
Peter Zhu
c3f6fcc4c5 Skip ObjectSpaceTest#test_count_nodes for RBS 2026-01-09 18:05:43 -05:00
Peter Zhu
e8c61f5139 Remove ObjectSpace.count_nodes
ObjectSpace.count_nodes has been a no-op and returning an empty hash since
Ruby 2.5 because parser nodes are not GC managed.
2026-01-09 18:05:43 -05:00
BurdetteLamar
ef488bff98 [DOC] Doc for Enumerator.new 2026-01-09 18:05:33 -05:00
BurdetteLamar
77cad87dc1 [DOC] Doc for Enumerator class 2026-01-09 17:36:32 -05:00
Burdette Lamar
3d242a82a3
[DOC] Harmonize #> methods 2026-01-09 17:36:26 -05:00
Max Bernstein
e08f316f28
YJIT: Add frozen guard for struct aset (#15835)
We used to just skip this check (oops), but we should not allow
modifying frozen objects.
2026-01-09 14:25:48 -05:00
Jean Boussier
51ab7b0405 YJIT: gen_struct_aset check for frozen status 2026-01-09 17:31:10 +01:00
Peter Zhu
7379b9ed78 Optimize rb_mark_generic_ivar for T_DATA and T_STRUCT
T_DATA and T_STRUCT could have ivars but might not use the generic_fields_tbl.
This commit skips lookup in the generic_fields_tbl for those cases.
2026-01-09 17:31:10 +01:00
Nobuyoshi Nakada
c794a97940 Rename alloca_overflow to stack_overflow
`alloca` is an implementation detail to raise a stack overflow.
2026-01-09 20:02:54 +09:00
Nobuyoshi Nakada
e01e13c239
Use assert_ruby_status if no assertion 2026-01-09 17:16:22 +09:00
Nobuyoshi Nakada
fc0c67deb2
Make assert_separately to count assertions in forked processes 2026-01-09 17:16:22 +09:00
Nobuyoshi Nakada
364e25b1c3
Make assert_separately tolerant to core method redefinitions
And split `TestRubyOptimization#test_objtostring` for each target
class.
2026-01-09 16:06:13 +09:00
Jörmungandrk
3185786874 Fix integer overflow checks in enumerator 2026-01-09 15:04:05 +09:00
Nobuyoshi Nakada
b61e18d76b
Win32: configure without an intermediate makefile
This batch file used `nmake` on the old `command.com` to extract the
parent directory name of this file and to get around the command line
argument length limit.  However, Windows 9X support as a build host
ended over a decade ago, and this file now utilizes the functionality
of `cmd.exe` already.
2026-01-09 11:36:46 +09:00
Peter Zhu
e89db8567c [ruby/mmtk] Assert that objects are not T_NONE in the write barrier
https://github.com/ruby/mmtk/commit/59d27203e2
2026-01-09 01:33:41 +00:00
Peter Zhu
aa7eb97d06 [ruby/mmtk] Add MMTK_ASSERT
https://github.com/ruby/mmtk/commit/e34d5cf32f
2026-01-09 01:33:41 +00:00
Earlopain
b3216bc1e1 Fix Ripper::Lexer::State#[] for to_s
The instance variable is called `to_s`, not `event`.
2026-01-09 09:33:16 +09:00
Stan Lo
50b719115a
Remove ruby-bench excludes (#15828)
These benchmarks should be working fine now.
2026-01-08 23:07:50 +00:00
Peter Zhu
c6f9a4d393 Remove check for rb_obj_gen_fields_p in rb_hash_dup
rb_copy_generic_ivar already checks for it, so we don't need to call
rb_obj_gen_fields_p twice.
2026-01-08 17:33:32 -05:00
Max Bernstein
523857bfcb
ZJIT: Replace GuardShape with LoadField+GuardBitEquals (#15821)
GuardShape is just load+guard, so use the existing HIR instructions for load+guard. Probably makes future analysis slightly easier.
2026-01-08 19:57:55 +00:00
Earlopain
16863f2ec1 [ruby/prism] Decouple ripper translator from ripper library
Ripper exposes Ripper::Lexer:State in its output, which is a bit of a problem. To make this work, I basically copy-pasted the implementation.

I'm unsure if that is acceptable and added a test to make sure that these values never go out of sync.
I don't imagine them changing often, prism maps them 1:1 for its own usage.

This also fixed the shim by accident. `Ripper.lex` went to `Translation::Ripper.lex` when it should have been the original. Removing the need for the original resolves that issue.

https://github.com/ruby/prism/commit/2c0bea076d
2026-01-08 18:35:26 +00:00
Earlopain
fc66de3e6b [ruby/prism] Remove unneeded ripper requires
Ripper is either not used or loaded where it is actually needed

https://github.com/ruby/prism/commit/a73a4fb00c
2026-01-08 18:35:25 +00:00
Earlopain
3bfc86558b [ruby/prism] Move LexRipper into its own file
It has a hard dependency on ripper that can't be removed.
This makes it so that ripper can be loaded only when the class is actually used.

https://github.com/ruby/prism/commit/3b5b4a8a6d
2026-01-08 18:35:25 +00:00
git
dcfbbdc38c Update bundled gems list as of 2026-01-08 2026-01-08 09:48:38 +00:00
Hiroshi SHIBATA
19d3f2da66 Skip collection install test 2026-01-08 18:48:00 +09:00
Hiroshi SHIBATA
eaa9902ca7 Exclude ruby-lsp benchmark because released version of rbs didn't have tsort dependency 2026-01-08 18:48:00 +09:00
Hiroshi SHIBATA
4a988b7f48 Inject tsort path before rdoc 2026-01-08 18:48:00 +09:00
Hiroshi SHIBATA
9c49084a20 Update tsort entries under the doc 2026-01-08 18:48:00 +09:00
Hiroshi SHIBATA
9580c7d07b Migrate tsort as bundled gems 2026-01-08 18:48:00 +09:00
Nobuyoshi Nakada
946b1c1ba1
Move parentheses around macro arguments 2026-01-08 13:41:07 +09:00
Nobuyoshi Nakada
1852ef4377
Fail if the Ruby specified with --with-baseruby is too old
If the baseruby is explicitly specified, fail because the option is
not accepted if it does not meet the requirements.  If the option is
not specified, just display the warning and continue, in the hope that
it is not needed.

Follow up GH-15809
2026-01-08 13:30:47 +09:00
Nobuyoshi Nakada
725e3d0aa7
Fluent and/or is supported by Prism too now 2026-01-08 13:29:23 +09:00
Chris Hasiński
7688628684 Fix incorrect bundled gems warning for hyphenated gem names
When requiring a file like "benchmark/ips", the warning system would
incorrectly warn about the "benchmark" gem not being a default gem,
even when the user has "benchmark-ips" (a separate third-party gem)
in their Gemfile.

The fix checks if a hyphenated version of the require path exists in
the bundle specs before issuing a warning. For example, requiring
"benchmark/ips" now checks for both "benchmark" and "benchmark-ips"
in the Gemfile.

[Bug #21828]
2026-01-08 13:15:29 +09:00
Misaki Shioi
080d66beca
Avoid flaky test failures by retrying on local port conflicts (#15818)
This test obtains an available port number by calling `TCPServer.new`,
then closes it and passes the same port number as `local_port` to `TCPSocket.new`.

However, `TCPSocket.new` could occasionally fail with `Errno::EADDRINUSE`
at the bind(2) step.
I believe this happens when tests are run in parallel and another process
on the same host happens to bind the same port in the short window between
closing the `TCPServer` and calling `TCPSocket.new`.

To address this race condition, the test now retries with a newly selected
available port when such a conflict occurs.
2026-01-08 09:41:42 +09:00
Nozomi Hijikata
950ffa90b7
ZJIT: Add ArrayAset instruction to HIR (#15747)
Inline `Array#[]=` into `ArrayAset`.
2026-01-07 18:24:29 -05:00
Burdette Lamar
3ea6ec8344
[DOC] Harmonize #=~ methods (#15814) 2026-01-07 18:02:22 -05:00
Burdette Lamar
5230f835e8
[DOC] Harmonize #[] methods 2026-01-07 18:01:56 -05:00
Hiroshi SHIBATA
7d49838038 [ruby/rubygems] bin/rubocop -A
https://github.com/ruby/rubygems/commit/e3f418aa11
2026-01-07 08:49:23 +00:00
Takuya Noguchi
3657700c40 [ruby/rubygems] Bundler: validate more options for add sub-command
Signed-off-by: Takuya Noguchi <takninnovationresearch@gmail.com>

https://github.com/ruby/rubygems/commit/6ca2e28680
2026-01-07 08:49:23 +00:00
neimadTL
8846799686 [ruby/rubygems] Update custom errors with Exception#full_message
The use of `Exception#full_message` makes more sense as it shows
the cause and the backstrace.

https://github.com/ruby/rubygems/commit/62a92c3f5e
2026-01-07 07:44:55 +00:00
eileencodes
e1087c1226 [ruby/rubygems] Fix dependency source bug in bundler
I stumbled across a bundler bug that had me scratching my head for
awhile, because I hadn't experienced it before.

In some cases when changing the source in a gemfile from a
`Source::Gemspec` to either a `Source::Path` or `Source::Git` only the
parent gem will have it's gem replaced and updated and the child
components will retain the original version. This only happens if the gem
version of the `Source::Gemspec` and `Source::Git` are the same. It also
requires another gem to share a dependency with the one being updated.

For example if I have the following gemfile:

```
gem "rails", "~> 8.1.1"
gem "propshaft"
```

Rails has a component called `actionpack` which `propshaft` depends on.

If I change `rails` to point at a git source (or path source), only the
path for `rails` gets updated:

```
gem "rails", github: "rails/rails", branch: "8-1-stable"
gem "propshaft"
```

Because `actionpack` is a dependency of `propshaft`, it will remain in
the rubygems source in the lock file WHILE the other gems are correctly
pointing to the git source.

Gemfile.lock:

```
GIT
  remote: https://github.com/rails/rails.git
  revision: https://github.com/ruby/rubygems/commit/9439f463e0ef
  branch: 8-1-stable
  specs:
    actioncable (8.1.1)
      ...
    actionmailbox (8.1.1)
      ...
    actionmailer (8.1.1)
      ...
    actiontext (8.1.1)
      ...
    activejob (8.1.1)
      ...
    activemodel (8.1.1)
      ...
    activerecord (8.1.1)
      ...
    activestorage (8.1.1)
      ...
    rails (8.1.1)
      ...
    railties (8.1.1)
      ...

GEM
  remote: https://rubygems.org/
  specs:
    action_text-trix (2.1.15)
      railties
    actionpack (8.1.1) <===== incorrectly left in Rubygems source
      ...
```

The gemfile will contain `actionpack` in the rubygems source, but will
be missing in the git source so the path will be incorrect. A bundle
show on Rails will point to the correct place:

```
$ bundle show rails
/Users/eileencodes/.gem/ruby/3.4.4/bundler/gems/rails-9439f463e0ef
```

but a bundle show on actionpack will be incorrect:

```
$ bundle show actionpack
/Users/eileencodes/.gem/ruby/3.4.4/gems/actionpack-8.1.1
```

This bug requires the following to reproduce:

1) A gem like Rails that contains components that are released as their
own standalone gem is added to the gemfile pointing to rubygems
2) A second gem is added that depends on one of the gems in the first
gem (like propshaft does on actionpack)
3) The Rails gem is updated to use a git source, pointing to the same
version that is being used by rubygems (ie 8.1.1)
4) `bundle` will only update the path for Rails component gems if no
other gem depends on it.

This incorrectly leaves Rails (or any gem like it) using two different
codepaths / gem source code.

https://github.com/ruby/rubygems/commit/dff76ba4f6
2026-01-07 07:30:26 +00:00
Jarek Prokop
25c72b0e8e Support customizable rustc_flags for rustc builds.
Add `rustc_flags` option for configure that appends to RUSTC_FLAGS
flags used when compiling with rustc for customizable build flags.
It appends to existing defaults in RUSTC_FLAGS.

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2026-01-06 23:55:06 -05:00
Peter Zhu
1abb609d66 [ruby/mmtk] Check that a and b are valid objects in write barrier
https://github.com/ruby/mmtk/commit/350625ebb3
2026-01-07 00:58:14 +00:00
Peter Zhu
08f6b8673a [ruby/mmtk] Set MMTK_DEBUG in C compiler for debug builds
https://github.com/ruby/mmtk/commit/12a3904b04
2026-01-07 00:58:14 +00:00
yui-knk
a024dca391 Remove in_masgn field from struct iseq_compile_data
`in_masgn` has not been used since fb6e3a80009a744a4e0b75660f1ce6da65e20e6c.
2026-01-07 08:26:37 +08:00
Philip Hallstrom
b2ed4cdced [ruby/time] Add changelog URI to time.gemspec
https://github.com/ruby/time/commit/08f896ca0d
2026-01-06 23:05:30 +00:00
Peter Zhu
5c24f4081d Add potential missing GC guard in iseq_data_to_ary
The iseq object might be optimized away by the compiler in iseq_data_to_ary
because we mainly only use the iseq_body. With MMTk, this crash occasionally
happens:

    TestIseqLoad#test_stressful_roundtrip [test/-ext-/iseq_load/test_iseq_load.rb:20]:
    pid 106677 killed by SIGSEGV (signal 11) (core dumped)
    | -:10: [BUG] Segmentation fault at 0x0000000000f1410c
    | ruby 4.1.0dev (2026-01-05T23:31:16Z master 5d26a2aeea) +PRISM +GC[mmtk] [x86_64-linux]
    |
    | -- Control frame information -----------------------------------------------
    | c:0005 p:---- s:0022 e:000021 l:y b:---- CFUNC  :to_a
    | c:0004 p:0039 s:0018 e:000017 l:y b:0001 METHOD -:10
    | c:0003 p:0013 s:0010 e:000009 l:y b:0001 METHOD -:16
    | c:0002 p:0054 s:0006 e:000005 l:n b:---- EVAL   -:26 [FINISH]
    | c:0001 p:0000 s:0003 E:0003a0 l:y b:---- DUMMY  [FINISH]
    |
    | -- Ruby level backtrace information ----------------------------------------
    | -:26:in '<main>'
    | -:16:in 'test_bug8543'
    | -:10:in 'assert_iseq_roundtrip'
    | -:10:in 'to_a'
    |
    | -- Threading information ---------------------------------------------------
    | Total ractor count: 1
    | Ruby thread count for this ractor: 1
    |
    | -- Machine register context ------------------------------------------------
    |  RIP: 0x000055b581f866f5 RBP: 0x0000000000000000 RSP: 0x00007ffccce2ffe0
    |  RAX: 0x00000200ffee2b08 RBX: 0x0000000000f1410c RCX: 0x0000000000000000
    |  RDX: 0x000000000010c7f2 RDI: 0x00000200ffee2b08 RSI: 0x00000200ffee2b08
    |   R8: 0x0000000000000004  R9: 0x00000c0803ffb8ac R10: 0x00007fe9074c0cc8
    |  R11: 0x0000000000000246 R12: 0x0000000000000000 R13: 0x0000000000000001
    |  R14: 0x0000000000000001 R15: 0x00000200ffee2208 EFL: 0x0000000000010246
    |
    | -- C level backtrace information -------------------------------------------
    | ruby(rb_print_backtrace+0x14) [0x55b582119a9f] vm_dump.c:1105
    | ruby(rb_vm_bugreport) vm_dump.c:1450
    | ruby(rb_bug_for_fatal_signal+0x102) [0x55b582409072] error.c:1131
    | ruby(sigsegv+0x46) [0x55b582051bf6] signal.c:948
    | /lib/x86_64-linux-gnu/libc.so.6(0x7fe907645330) [0x7fe907645330]
    | ruby(iseq_data_to_ary+0xe5) [0x55b581f866f5] iseq.c:3380
    | ruby(iseq_data_to_ary+0x6b2) [0x55b581f86cc2] iseq.c:3470
    | ruby(vm_call_cfunc_with_frame_+0x10d) [0x55b5820e4a0d] vm_insnhelper.c:3902
2026-01-06 17:16:38 -05:00
Burdette Lamar
58fb95af36
[DOC] Harmonize #== methods (#15805) 2026-01-06 17:13:15 -05:00
Matt Valentine-House
49ca241d6d Show a more verbose message if BASERUBY is too old 2026-01-06 17:09:27 +00:00
Nobuyoshi Nakada
925d04108b
Add rake target to run the bundled rake 2026-01-06 18:37:41 +09:00
Steve Savio
bff7c6d9e9 [DOC] Fix minor typo on shareable procs section 2026-01-06 18:30:33 +09:00
Schneems
ad6b85450d [ruby/rubygems] Retain current bundler version on bundle clean
Previously: In #9218 a reproduction is shared where running `bundle clean` using a binstub (`bin/bundle`) results in bundler removing itself. This results in Ruby falling back to its default bundler version. This behavior seems to be present for as long as there has been a default version of bundler (Ruby 2.6+).

Now: Bundler will explicitly add its current version number to the specs to be preserved. This prevents `bundle clean` from removing the current bundler version.

close https://github.com/ruby/rubygems/pull/9218

https://github.com/ruby/rubygems/commit/e3f0167ae4
2026-01-06 04:38:13 +00:00
Schneems
4377249bbf [ruby/rubygems] Test for removing current bundler version
https://github.com/ruby/rubygems/commit/675342e6d0
2026-01-06 04:38:13 +00:00
Schneems
16bdfa1b2a [ruby/rubygems] Split logic to two lines
https://github.com/ruby/rubygems/commit/5a6eca4cf9
2026-01-06 04:38:12 +00:00
lolwut
3143543f95 [ruby/rubygems] Compare like values in find_bundler
The input to this method is not guaranteed to be a string, it could be a `Gem::Version` this normalizes the comparison.

https://github.com/ruby/rubygems/commit/1f43c7a988
2026-01-06 04:38:12 +00:00
Hiroshi SHIBATA
1b476606f2
Update the latest versions of actions 2026-01-06 13:07:49 +09:00
dependabot[bot]
95f2c78fc2 Bump dependabot/fetch-metadata from 2.4.0 to 2.5.0
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.4.0 to 2.5.0.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](08eff52bf6...21025c705c)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-version: 2.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-06 11:42:34 +09:00
Peter Zhu
5d26a2aeea [ruby/mmtk] Assert pinning object is not moved
https://github.com/ruby/mmtk/commit/8813e76bf8
2026-01-05 23:31:16 +00:00
BurdetteLamar
dd67874ad9 [DOC] Harmonize #=== methods 2026-01-05 18:30:40 -05:00
BurdetteLamar
a25f468917 [DOC] Harmonize #>= methods 2026-01-05 18:23:55 -05:00
Takashi Kokubun
7a1180afb6 ruby-bench: Prefer --excludes over rm -rf
to remind us of skipped benchmarks in the CI job names
2026-01-05 13:33:58 -08:00
Max Bernstein
23765a5e09
ZJIT: Update Iongraph (#15806)
Fix some rendering bugs and remove React.
2026-01-05 15:16:48 -05:00
Luke Gruber
7e81bf5c0c
Fix sleep spurious wakeup from sigchld (#15802)
When sleeping with `sleep`, currently the main thread can get woken up from sigchld
from any thread (subprocess exited). The timer thread wakes up the main thread when this
happens, as it checks for signals. The main thread then executes the ruby sigchld handler
if one is registered and is supposed to go back to sleep immediately. This is not ideal but
it's the way it's worked for a while. In commit 8d8159e7d8 I added writes to `th->status`
before and after `wait_running_turn` in `thread_sched_to_waiting_until_wakeup`, which is
called from `sleep`. This is usually the right way to set the thread's status, but `sleep`
is an exception because the writes to `th->status` are done in `sleep_forever`. There's a
loop that checks `th->status` in `sleep_forever`. When the main thread got woken up from
sigchld it saw the changed `th->status` and continued to run the main thread instead of
going back to sleep.

The following script shows the error. It was returning instead of sleeping forever.

```ruby
t = Thread.new do
  sleep 0.3
  `echo hello`  # Spawns subprocess
  puts "Subprocess exited"
end

puts "Main thread sleeping..."
result = sleep  # Should block forever
puts "sleep returned: #{result.inspect}"
```

Fixes [Bug #21812]
2026-01-05 12:18:47 -05:00
Brandon Zylstra
c65a5548a8 Update box.md
"Code" (when used to refer to what we create in Ruby or any other programming language) is an abstract non-count noun, so it cannot be pluralized.  ("Codes" would be used when referring to specific countable things like PIN codes, which is a different use of the word "code".)

This is somewhat confusing because English allows converting count nouns into non-count nouns, and converting non-count nouns into count nouns, and because many words have both forms.

For an example of converting a non-count noun to a count noun, "water" is normally a non-count noun:

> The world is covered with water.

but people who work in restaurants often use the word as a count noun, as a shorthand for "cup of water":

> I need 7 waters on the big table by the window.

For an example of the opposite conversion, "worm" is normally a count noun:

> There are lots of worms in the puddle.

but someone might use it as a non-count noun when talking about non-distinct remains of worms:

> You have worm all over the bottom of your shoe!

So although a given noun can be flexible enough to be used in either way—even when it is unconventional—there is a definite change of meaning when using a word as a count noun or a non-count noun.
2026-01-05 17:11:06 +09:00
Nobuyoshi Nakada
3267460610 Update bindgen 2026-01-05 16:47:14 +09:00
Nobuyoshi Nakada
28b0e5125f [Bug #18433] Remove unneeded declaration
This `rb_cObject` declaration was only for `rb_cData()` that was
removed at 7c738ce5e649b82bdc1305d5c347e81886ee759a.
2026-01-05 16:47:14 +09:00
Hiroshi SHIBATA
d3ecd9d2ab [ruby/rubygems] Lock minitest ~> 5.1
https://github.com/ruby/rubygems/commit/7b9bfb4e18
2026-01-05 07:22:11 +00:00
Hiroshi SHIBATA
b87b6edf2e [ruby/rubygems] Update vendored net-http to 0.9.1
https://github.com/ruby/rubygems/commit/12072e8d23
2026-01-05 07:22:10 +00:00
Hiroshi SHIBATA
8c8561adbc [ruby/rubygems] Update vendored connection_pool to 2.5.5
https://github.com/ruby/rubygems/commit/4c1eb2b274
2026-01-05 07:22:10 +00:00
Hiroshi SHIBATA
05f791bf41 [ruby/rubygems] rake update
https://github.com/ruby/rubygems/commit/aa7632161e
2026-01-05 07:22:09 +00:00
Tsutomu Katsube
99bd18b5b8 Unskip RBS test on Windows for NoMemoryError workaround
test-unit 3.7.7 has been fixed this problem.

See also:
https://github.com/test-unit/test-unit/releases/tag/3.7.7
2026-01-05 13:48:29 +09:00
Shugo Maeda
e6762d23cb
[DOC] Fix a typo and trim trailing whitespace per .editorconfig 2026-01-05 11:49:48 +09:00
Hiroshi SHIBATA
01e8b38f60
Use RUBY_VERSION in specs instead of hardcoded 'Ruby 4.0.0' to make tests version-independent 2026-01-05 11:32:42 +09:00
Jeremy Evans
699813b65f [ruby/rubygems] Remove date require from rebuild command
As far as I can see, this isn't used.

https://github.com/ruby/rubygems/commit/67c97e7180
2026-01-05 00:58:13 +00:00
Peter Zhu
7d5c0247eb Dump fstr and frozen status in rb_raw_obj_info_buitin_type 2026-01-04 12:26:06 -05:00
Benoit Daloze
6eadc01cda Fix condition for UTF-8 default in magic_comment_spec.rb 2026-01-04 18:13:08 +01:00
Benoit Daloze
9888a3e8bd UNIXSocket#recvfrom only returns the path on Linux
* Notably it does not on BSD, macOS and Windows.
2026-01-04 18:10:42 +01:00
Benoit Daloze
2bf9543053 Remove assertion which does not hold
* https://github.com/ruby/ruby/actions/runs/20694508956/job/59407571754
  1)
  UNIXSocket.pair emulates unnamed sockets with a temporary file with a path FAILED
  Expected "C:\\a\\_temp\\102424668889-2384.($)".match? /\\AppData\\Local\\Temp\\\d+-\d+\.\(\$\)\z/
  to be truthy but was false
2026-01-04 16:04:02 +01:00
Benoit Daloze
e79f8974b5 Get better error if UNIXSocket.socketpair spec fails 2026-01-04 15:39:31 +01:00
Benoit Daloze
29e7973e05 Update to ruby/spec@94dbd55 2026-01-04 15:36:02 +01:00
Peter Zhu
6939f03f4c Add field handle_weak_references to TypedData
This commit adds a field handle_weak_references to rb_data_type_struct for
the callback when handling weak references. This avoids TypedData objects
from needing to expose their rb_data_type_struct and weak references function.
2026-01-04 09:02:40 -05:00
Benoit Daloze
1b3382cbab Update to ruby/spec@f54296d 2026-01-04 14:53:24 +01:00
Nobuyoshi Nakada
18672b392b
[DOC] Add base-url to ChangeLog by default
It is used to expand repository references to URL.
2026-01-04 16:01:27 +09:00
Augustin Gottlieb
912cf819b9 [ruby/openssl] Improve Argument Error Message in EC:Group.new
Before, passing the wrong number of arguments (e.g., 2) to
OpenSSL::PKey::EC::Group.new raised a generic "wrong number of
arguments"
error.

This change updates it to show the actual argument count and the
expected
options (1 or 4), making debugging easier for the user.

Example:
ArgumentError: wrong number of arguments (given 2, expected 1 or 4)

I hope it helps!

https://github.com/ruby/openssl/commit/783c99e6c7
2026-01-04 06:56:57 +00:00
Koichi ITO
ca0fece56a [DOC] Tweak an example in language/box.md
Although the example code comments indicate that it returns `false`,
a non-matching result for `=~` is actually `nil`.

```ruby
Foo.foo.blank? #=> false
"foo".blank?   #=> false
```

https://github.com/ruby/ruby/blob/v4.0.0-preview3/doc/language/box.md?plain=1#L115-L122

This PR replaces `=~` with `match?` so that it returns the expected `false`.
Since this makes the result a boolean, it also aligns with the expected behavior of
a predicate method name like `blank?`.
2026-01-04 12:53:42 +09:00
Koichi ITO
d8d41d7441 [DOC] Use Ruby::Box#require_relative in box.md examples
Based on the example, it appears that `foo.rb` and `main.rb` are expected to be in the same directory.
Since Ruby 1.9, the current directory is not included in `$LOAD_PATH` by default.
As a result, running `box.require('foo')` as shown in the sample code raises a `LoadError`:

```console
main.rb:2:in `Ruby::Box#require': cannot load such file -- foo (LoadError)
        from main.rb:2:in `<main>'
```

To avoid this, it seems simplest to show either `box.require('./foo')` or `box.require_relative('foo')`.
In this PR, `box.require('foo')` is replaced with `box.require_relative('foo')` to make the intention of
using a relative path explicit.

This should reduce the chance that users trying Ruby Box will run into an unexpected error.
2026-01-04 12:52:40 +09:00
Peter Zhu
5064af7ed1 [ruby/mmtk] Process obj_free candidates in parallel
Redos commit 544770d which seems to have accidentally been undone in b27d935.
2026-01-04 10:26:54 +09:00
Peter Zhu
a0c483fcfb Also output GC thread backtrace in rb_mmtk_gc_thread_bug 2026-01-03 10:43:24 -05:00
Peter Zhu
5b87294d2f Add rb_gc_print_backtrace 2026-01-03 10:43:24 -05:00
Shannon Skipper
65f9c4a06a Drop memberless Data/Struct#inspect trailing space
Anonymous memberless Structs and Data were returning `#<struct >` and
`#<data >` with a trailing space. Now they return `#<struct>` and
`#<data>` to match attrless class behavior and look a bit more compact.
2026-01-03 18:12:44 +09:00
Scott Myron
b6463d59e7 [ruby/json] Directly write to the output buffer when converting UTF32 to UTF8.
https://github.com/ruby/json/commit/a51317c949
2026-01-03 08:30:20 +00:00
Nobuyoshi Nakada
d7a6ff8224
[Bug #21819] Data objects without members should also be frozen 2026-01-03 15:03:57 +09:00
Nobuyoshi Nakada
a8a989b6f6
Test net-imap with ruby/net-imap#593
Delete test/net/imap/test_data_lite.rb, because the target of this
test file has been deleted by [ruby/net-imap#543].

[ruby/net-imap#543]: https://github.com/ruby/net-imap/pull/593
2026-01-03 13:28:58 +09:00
Peter Zhu
2f4119eaea [ruby/mmtk] Use rb_mmtk_gc_thread_bug for rb_mmtk_call_object_closure
https://github.com/ruby/mmtk/commit/308936296a
2026-01-03 00:02:22 +00:00
Peter Zhu
60d9b10dab [ruby/mmtk] Propagate crash of GC thread to mutator thread
This allows the mutator thread to dump its backtrace when a GC thread crashes.

https://github.com/ruby/mmtk/commit/40ff9ffee7
2026-01-03 00:02:22 +00:00
Jean Boussier
16feb46fa2 Convert Queue and SizedQueue to rb builtin
A large part of `thread_sync.c` was migrated already, might as well
go all the way. It also allow to remove a bunch of Rdoc commands.
2026-01-03 00:07:44 +01:00
Peter Zhu
e7695ba3d9 [ruby/mmtk] Check for T_NONE during marking
https://github.com/ruby/mmtk/commit/c3e338bb25
2026-01-02 20:42:11 +00:00
Peter Zhu
31fb970c18 [ruby/mmtk] Assert target is not pinned during normal tracing
https://github.com/ruby/mmtk/commit/58210c88ed
2026-01-02 17:58:49 +00:00
Jean Boussier
c47a8052f6 Add a test case for complex argument forward reference
Using `eval` it's possible to reference a later argument, and
this requires careful initialization of the stack.
2026-01-02 16:59:00 +01:00
Jean Boussier
1596853428 Skip initializing optional arguments to nil
They are optional because they have a default value, so I don't
understand why we'd need to initialize them to nil.
2026-01-02 16:59:00 +01:00
Peter Zhu
b9819ad06c Register a dupped identity hash as pinning 2026-01-02 08:54:56 -05:00
Jean Boussier
177949c8b2 Speedup Queue initialization
Rather than to push items one by one we can directly memcpy.
2026-01-02 13:51:36 +01:00
dependabot[bot]
11165495f4 [ruby/rubygems] Bump the rb-sys group across 2 directories with 1 update
Bumps the rb-sys group with 1 update in the /test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib directory: [rb-sys](https://github.com/oxidize-rb/rb-sys).
Bumps the rb-sys group with 1 update in the /test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example directory: [rb-sys](https://github.com/oxidize-rb/rb-sys).

Updates `rb-sys` from 0.9.117 to 0.9.123
- [Release notes](https://github.com/oxidize-rb/rb-sys/releases)
- [Commits](https://github.com/oxidize-rb/rb-sys/compare/v0.9.117...v0.9.123)

Updates `rb-sys` from 0.9.117 to 0.9.123
- [Release notes](https://github.com/oxidize-rb/rb-sys/releases)
- [Commits](https://github.com/oxidize-rb/rb-sys/compare/v0.9.117...v0.9.123)

---
updated-dependencies:
- dependency-name: rb-sys
  dependency-version: 0.9.123
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: rb-sys
- dependency-name: rb-sys
  dependency-version: 0.9.123
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: rb-sys
...

Signed-off-by: dependabot[bot] <support@github.com>

https://github.com/ruby/rubygems/commit/551c665b6b
2026-01-02 08:43:54 +00:00
git
0ec5678cd5 Update bundled gems list as of 2026-01-02 2026-01-02 06:55:45 +00:00
Nobuyoshi Nakada
dd34d6273a
Extract git version only
The version message may contain other info such as the distribution.
e.g.:
```console
$ /usr/bin/git --version
git version 2.50.1 (Apple Git-155)
```
2026-01-02 13:13:40 +09:00
Nobuyoshi Nakada
0e9d698930
Prefer dedicated assertions 2026-01-02 11:40:27 +09:00
Peter Zhu
acda63debc [ruby/mmtk] Format imports to be each on a new line
https://github.com/ruby/mmtk/commit/42adba630e
2026-01-01 14:03:49 +00:00
Benoit Daloze
26a5bcd6de [ruby/prism] Fix spacing in the generated #each_child_node
https://github.com/ruby/prism/commit/91f60cb736
2026-01-01 12:30:20 +00:00
Jean Boussier
8ce61f90ba Thread::Queue use a ring buffer
Thread::Queue spends a significant amount of time in array functions,
checking for invariants we know aren't a problem, and whether the backing
array need to reordered.

By using a ring buffer we can remove a lot of overhead (~23% faster).

```
$ hyperfine './miniruby --yjit /tmp/q.rb' './miniruby-qrb --yjit /tmp/q.rb'
Benchmark 1: ./miniruby --yjit /tmp/q.rb
  Time (mean ± σ):      1.050 s ±  0.191 s    [User: 0.988 s, System: 0.004 s]
  Range (min … max):    0.984 s …  1.595 s    10 runs

Benchmark 2: ./miniruby-qrb --yjit /tmp/q.rb
  Time (mean ± σ):     844.2 ms ±   3.1 ms    [User: 840.4 ms, System: 2.8 ms]
  Range (min … max):   838.6 ms … 848.9 ms    10 runs

Summary
  ./miniruby-qrb --yjit /tmp/q.rb ran
    1.24 ± 0.23 times faster than ./miniruby --yjit /tmp/q.rb
```

```
q = Queue.new([1, 2, 3, 4, 5, 6, 7, 8])
i = 2_000_000
while i > 0
  i -= 1
  q.push(q.pop)
  q.push(q.pop)
  q.push(q.pop)
  q.push(q.pop)
  q.push(q.pop)
  q.push(q.pop)
  q.push(q.pop)
  q.push(q.pop)
  q.push(q.pop)
  q.push(q.pop)
end
```
2026-01-01 10:20:08 +01:00
Peter Zhu
4129256214 Use STR_SET_SHARED in str_duplicate_setup_heap
str_duplicate_setup_heap is missing a call to rb_gc_register_pinning_obj
that STR_SET_SHARED correctly calls.
2025-12-31 21:57:01 -05:00
Nobuyoshi Nakada
ea05c23ee8 Extract RBIMPL_TYPEDDATA_PRECONDITION 2026-01-01 10:00:33 +09:00
Peter Zhu
7cf6cc83f3 Register imemo_ment as a pinning object
It sometimes pins itself when it is in the overloaded_cme table.
2025-12-31 12:47:43 -05:00
Nobuyoshi Nakada
b27d9353a7
Use is_obj_encoding instead of is_data_encoding
The argument to `is_data_encoding` is assumed to be `T_DATA`.
2025-12-31 23:56:58 +09:00
Peter Zhu
dbfedeb3a3 [ruby/mmtk] Split ProcessObjFreeCandidates to parallel and non-parallel
This makes it easier to visualize in profilers which one is non-parallel.

https://github.com/ruby/mmtk/commit/ba68b2ef3b
2025-12-31 14:22:38 +00:00
Peter Zhu
544770d566 [ruby/mmtk] Process obj_free candidates in parallel
This commit allows objects that are safe to be freed in parallel to do so.
A decrease in object freeing time can be seen in profiles.

The benchmarks don't show much difference.

Before:

--------------  --------------------  ----------  ---------
bench           sequential free (ms)  stddev (%)  RSS (MiB)
activerecord    242.3                 7.4         84.3
chunky-png      439.1                 0.6         75.6
erubi-rails     1221.2                4.2         132.7
hexapdf         1544.8                1.8         429.1
liquid-c        42.7                  7.4         48.5
liquid-compile  41.4                  8.3         52.2
liquid-render   100.6                 3.0         56.8
mail            108.9                 2.1         65.1
psych-load      1536.9                0.6         43.4
railsbench      1633.5                2.6         146.2
rubocop         126.5                 15.8        142.1
ruby-lsp        129.6                 9.7         112.2
sequel          47.9                  6.5         44.6
shipit          1152.0                2.7         315.2
--------------  --------------------  ----------  ---------

After:

--------------  ------------------  ----------  ---------
bench           parallel free (ms)  stddev (%)  RSS (MiB)
activerecord    235.1               5.5         87.4
chunky-png      440.8               0.8         68.1
erubi-rails     1105.3              0.8         128.0
hexapdf         1578.3              4.1         405.1
liquid-c        42.6                7.1         48.4
liquid-compile  41.5                8.1         52.1
liquid-render   101.2               2.8         53.3
mail            109.7               2.7         64.8
psych-load      1567.7              1.1         44.4
railsbench      1644.9              1.9         150.9
rubocop         125.6               15.4        148.5
ruby-lsp        127.9               5.8         104.6
sequel          48.2                6.1         44.1
shipit          1215.3              4.7         320.5
--------------  ------------------  ----------  ---------

https://github.com/ruby/mmtk/commit/4f0b5fd2eb
2025-12-31 14:22:38 +00:00
Nobuyoshi Nakada
99249cc582 [ruby/json] Fix non-portable code
A plain `char` may be `signed` or `unsigned` depending on the
implementation.  Also, bitwise ORing of `signed` values ​​is not
guaranteed to be `signed`.  To ensure portability, should logical-OR
each comparison, but casting to `signed char` is usually sufficient.

https://github.com/ruby/json/commit/8ad744c532
2025-12-31 12:44:18 +00:00
Scott Myron
c97f5d591b [ruby/json] Simplify unescape_unicode
https://github.com/ruby/json/commit/976ba36629

Co-Authored-By: Jean Boussier <jean.boussier@gmail.com>
2025-12-31 10:07:33 +00:00
Scott Myron
61d45c857b [ruby/json] Keep track of the the number of additional backslashes to avoid an extra memchr searching the remaining characters when no more backslashes exist.
https://github.com/ruby/json/commit/d21d9362fa
2025-12-31 09:54:25 +00:00
Nobuyoshi Nakada
094145fbc1
[DOC] Move typed-data related macros
The flags for `rb_data_type_t::flags` are public constants for
defining `rb_data_type_t`.  The embedded data flag and mask are
internal implementation detail.
2025-12-31 17:54:42 +09:00
Nobuyoshi Nakada
d95bebe06c
Make RTYPEDDATA_EMBEDDABLE_P internal-use only
It should not be exposed because it is so implementation specific that
it is only used in gc.c even within the entire Ruby source tree.
2025-12-31 11:29:29 +09:00
Nobuyoshi Nakada
c352808fa9
Introduce typed-data embeddable predicate macros
The combination of `&` and `&&` is confusing.
2025-12-31 11:27:46 +09:00
Peter Zhu
9d37155cfc [ruby/mmtk] Use MMTK_HEAP_COUNT for SIZE_POOL_COUNT
https://github.com/ruby/mmtk/commit/290a2aec4e
2025-12-30 18:02:00 +00:00
Nobuyoshi Nakada
d40e056cc8
Skip the hang-up test on Windows 2025-12-31 02:24:21 +09:00
Nobuyoshi Nakada
3086d58263
Run also test-tool on mingw 2025-12-31 02:24:03 +09:00
Peter Zhu
b7bf8c20b0 Add RVALUE_OLD_AGE to GC::INTERNAL_CONSTANTS for MMTk 2025-12-30 10:59:21 -05:00
Peter Zhu
f2833e358c Fix generational GC for weak references
Fixes issue pointed out in https://bugs.ruby-lang.org/issues/21084#note-7.
The following script crashes:

    wmap = ObjectSpace::WeakMap.new

    GC.disable # only manual GCs
    GC.start
    GC.start

    retain = []
    50.times do
      k = Object.new
      wmap[k] = true
      retain << k
    end

    GC.start # wmap promoted, other objects still young

    retain.clear

    GC.start(full_mark: false)

    wmap.keys.each(&:itself) # call method on keys to cause crash
2025-12-30 10:59:21 -05:00
Benoit Daloze
c05e10605e Exclude rbs tests which need updates for {Method,UnboundMethod,Proc}#source_location
* See https://github.com/ruby/ruby/pull/15580
2025-12-30 16:02:39 +01:00
Benoit Daloze
a7fec4d661 Update version guards in ruby/spec 2025-12-30 16:02:39 +01:00
Benoit Daloze
c970d2941d [Bug #21784] Fix the Proc#source_location start_column for stabby lambdas
* Consistent with plain `blocks` and `for` blocks and methods
  where the source_location covers their entire definition.
* Matches the documentation which mentions
  "where the definition starts/ends".
* Partially reverts d357d50f0a74409446f4cccec78593373f5adf2f
  which was a workaround to be compatible with parse.y.
2025-12-30 16:02:39 +01:00
Benoit Daloze
cd66d15858 [Bug #21783] Fix documentation of {Method,UnboundMethod,Proc}#source_location 2025-12-30 16:02:39 +01:00
Benoit Daloze
d82fc3360d Reapply "[Feature #6012] Extend source_location for end position
* This reverts commit 065c48cdf11a1c4cece84db44ed8624d294f8fd5.
* This functionality is very valuable and has already taken 14 years
  to agree on the API.
* Let's just document it's byte columns (in the next commit).
* See https://bugs.ruby-lang.org/issues/21783#note-9
2025-12-30 16:02:39 +01:00
Nobuyoshi Nakada
19e539c9ee
[Bug #21814] Fix negative bignum modulo
If modulo is zero, do not  apply bias even if the divisor is zero.
`BIGNUM_POSITIVE_P` is true even on bignum zero.
2025-12-30 23:00:18 +09:00
Satoshi Tagomori
966dbba8db Box: skip checking the current box is the root box
Because checking the current box is not a cheap process.
2025-12-30 22:31:51 +09:00
Nobuyoshi Nakada
27d6c96658
Add 4.0 to the spec_guards workflow 2025-12-30 18:33:20 +09:00
Nobuyoshi Nakada
3f616d5701
Update ruby/setup-ruby action to v1.276.0 2025-12-30 18:33:03 +09:00
Satoshi Tagomori
d5af8d7858 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.
2025-12-30 17:06:34 +09:00
Earlopain
65634d8df5 [ruby/prism] Optimize ruby visitor
`compact_child_nodes` allocates an array. We can skip that step by simply yielding the nodes.

Benchmark for visiting the rails codebase:

```rb
require "prism"
require "benchmark/ips"

files = Dir.glob("../rails/**/*.rb")
results = files.map { Prism.parse_file(it) }
visitor = Prism::Visitor.new

Benchmark.ips do |x|
  x.config(warmup: 3, time: 10)

  x.report do
    results.each do
      visitor.visit(it.value)
    end
  end
end

RubyVM::YJIT.enable

Benchmark.ips do |x|
  x.config(warmup: 3, time: 10)

  x.report do
    results.each do
      visitor.visit(it.value)
    end
  end
end
```

Before:
```
ruby 3.4.8 (2025-12-17 revision https://github.com/ruby/prism/commit/995b59f666) +PRISM [x86_64-linux]
Warming up --------------------------------------
                         1.000 i/100ms
Calculating -------------------------------------
                          2.691 (± 0.0%) i/s  (371.55 ms/i) -     27.000 in  10.089422s
ruby 3.4.8 (2025-12-17 revision https://github.com/ruby/prism/commit/995b59f666) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
                         1.000 i/100ms
Calculating -------------------------------------
                          7.278 (±13.7%) i/s  (137.39 ms/i) -     70.000 in  10.071568s
```
After:
```
ruby 3.4.8 (2025-12-17 revision https://github.com/ruby/prism/commit/995b59f666) +PRISM [x86_64-linux]
Warming up --------------------------------------
                         1.000 i/100ms
Calculating -------------------------------------
                          3.429 (± 0.0%) i/s  (291.65 ms/i) -     35.000 in  10.208580s
ruby 3.4.8 (2025-12-17 revision https://github.com/ruby/prism/commit/995b59f666) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
                         1.000 i/100ms
Calculating -------------------------------------
                         16.815 (± 0.0%) i/s   (59.47 ms/i) -    169.000 in  10.054668s
```

~21% faster on the interpreter, ~56% with YJIT

https://github.com/ruby/prism/commit/bf631750cf
2025-12-29 14:14:00 +00:00
Thomas Marshall
14fbcf0e6e [ruby/prism] Report missing end errors at opening token
This commit adds an `expect1_opening` function that expects a token and
attaches the error to the opening token location rather than the current
position. This is useful for errors about missing closing tokens, where
we want to point to the line with the opening token rather than the end
of the file.

For example:

```ruby
def foo
def bar
def baz
       ^ expected an `end` to close the `def` statement
       ^ expected an `end` to close the `def` statement
       ^ expected an `end` to close the `def` statement
```

This would previously produce three identical errors at the end of the
file. After this commit, they would be reported at the opening token
location:

```ruby
def foo
^~~ expected an `end` to close the `def` statement
def bar
^~~ expected an `end` to close the `def` statement
def baz
^~~ expected an `end` to close the `def` statement
```

I considered using the end of the line where the opening token is
located, but in some cases that would be less useful than the opening
token location itself. For example:

```ruby
def foo def bar def baz
```

Here the end of the line where the opening token is located would be the
same for each of the unclosed `def` nodes.

https://github.com/ruby/prism/commit/2d7829f060
2025-12-29 14:12:20 +00:00
Thomas Marshall
8afd4fade6 [ruby/prism] Add unterminated construct tests
https://github.com/ruby/prism/commit/166764f794
2025-12-29 14:12:20 +00:00
Peter Zhu
782d959f67 Implement moving Immix in MMTk
This commit implements moving Immix in MMTk, which allows objects to move
in the GC.

The performance of this implementation is not yet amazing. It is very
similar to non-moving Immix in many of them and slightly slower in others.
The benchmark results is shown below.

    --------------  -----------------  ----------  ---------
    bench           Moving Immix (ms)  stddev (%)  RSS (MiB)
    activerecord    241.9              0.5         86.6
    chunky-png      447.8              0.8         74.9
    erubi-rails     1183.9             0.8         136.1
    hexapdf         1607.9             2.6         402.3
    liquid-c        45.4               6.7         44.9
    liquid-compile  44.1               9.3         53.0
    liquid-render   105.4              4.5         55.9
    lobsters        650.1              9.7         418.4
    mail            115.4              2.1         64.4
    psych-load      1656.8             0.8         43.6
    railsbench      1653.5             1.3         149.8
    rubocop         127.0              15.6        142.1
    ruby-lsp        130.7              10.5        99.4
    sequel          52.8               7.2         45.6
    shipit          1187.0             3.9         311.0
    --------------  -----------------  ----------  ---------

    --------------  ---------------------  ----------  ---------
    bench           Non-moving Immix (ms)  stddev (%)  RSS (MiB)
    activerecord    218.9                  2.7         86.1
    chunky-png      464.6                  0.8         66.7
    erubi-rails     1119.0                 4.3         132.7
    hexapdf         1539.8                 1.8         425.2
    liquid-c        40.6                   6.9         45.2
    liquid-compile  40.6                   8.1         52.9
    liquid-render   99.3                   2.3         48.3
    mail            107.4                  5.3         65.4
    psych-load      1535.6                 1.0         39.5
    railsbench      1565.6                 1.1         149.6
    rubocop         122.5                  14.3        146.7
    ruby-lsp        128.4                  10.7        106.4
    sequel          44.1                   4.0         45.7
    shipit          1154.5                 2.7         358.5
    --------------  ---------------------  ----------  ---------
2025-12-29 09:03:31 -05:00
Peter Zhu
7902ae34d0 Add rb_gc_move_obj_during_marking 2025-12-29 09:03:31 -05:00
Peter Zhu
01cd9c9fad Add rb_gc_register_pinning_obj 2025-12-29 09:03:31 -05:00
Peter Zhu
56147001ec Move MEMO_NEW to imemo.c and rename to rb_imemo_memo_new 2025-12-29 09:03:31 -05:00
Nobuyoshi Nakada
da89f7f58d
Prefer ALLOCV over ALLOCA for unknown size
`ALLOCA` with too large size may result in stack overflow.
Incidentally, this suppresses the GCC false maybe-uninitialized
warning in `product_each`.

Also shrink `struct product_state` when `sizeof(int) < sizeof(VALUE)`.
2025-12-29 20:26:00 +09:00
Nobuyoshi Nakada
26088dcd4a
[DOC] State that rb_unexpected_type is private 2025-12-29 18:41:58 +09:00
Nobuyoshi Nakada
56a6a21f28
Return NULL in a void * function 2025-12-29 18:40:48 +09:00
Nobuyoshi Nakada
0f64da9672
Make rb_check_typeddata and rbimpl_check_typeddata identical 2025-12-29 18:40:47 +09:00
Nobuyoshi Nakada
72627d85e3
Declare rb_data_typed_t parameters and return values as nonull 2025-12-29 18:20:36 +09:00
Luke Jahnke
4e0bb58a0a fix underflow 2025-12-29 17:21:33 +09:00
Jeremy Evans
38701a4de8 Remove deprecated support for to_set taking arguments 2025-12-29 14:54:41 +09:00
Nobuyoshi Nakada
cb01b9023e
rtypeddata.h: Add missing RBIMPL_CAST
In public headers, casts should be enclosed in `RBIMPL_CAST` for
compilation in C++.
2025-12-29 10:33:31 +09:00
Peter Zhu
9e78353c0f Fix maybe uninitialized warnings in random.c
Fixes the following compiler warnings:

    random.c: In function `random_init`:
    random.c:416:38: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized]
      416 |     unsigned int major = rng->version.major;
          |                          ~~~~~~~~~~~~^~~~~~
    random.c: In function `random_bytes`:
    random.c:1284:8: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized]
    1284 |     rng->get_bytes(rnd, ptr, n);
         |     ~~~^~~~~~~~~~~
    random.c:1299:34: note: `rng` was declared here
    1299 |     const rb_random_interface_t *rng;
         |                                  ^~~
    random.c: In function `rand_random_number`:
    random.c:1606:12: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized]
    1606 |     return rand_range(obj, rng, rnd, vmax);
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    random.c:1624:34: note: `rng` was declared here
    1624 |     const rb_random_interface_t *rng;
          |                                  ^~~
    random.c: In function `random_rand`:
    random.c:1120:15: warning: `rng` may be used uninitialized in this function [-Wmaybe-uninitialized]
    1120 |     return rng->get_int32(rnd);
         |            ~~~^~~~~~~~~~~
    random.c:1573:34: note: `rng` was declared here
    1573 |     const rb_random_interface_t *rng;
         |                                  ^~~
2025-12-28 16:25:49 -05:00
Burdette Lamar
d615dbf4e2
[DOC] Japanese for multi-byte characters 2025-12-28 15:51:10 -05:00
Nobuyoshi Nakada
44e762a99c
Extract rb_random_interface_t alongside rb_random_t as well 2025-12-29 02:01:12 +09:00
Nobuyoshi Nakada
68cd46353c
Ensure T_DATA before RTYPEDDATA_P
For the precondition of `RTYPEDDATA_P` that the argument must be a
Ruby object of `::RUBY_T_DATA`.
2025-12-29 02:01:12 +09:00
Peter Zhu
eaa83e505f Always allocate Fiber objects in Thread
Currently, root fibers of threads do not have a corresponding Ruby object
backing it by default (it does have one when an object is required, such
as when Fiber.current is called). This is a problem for the new GC weak
references design in #12606 since Thread is not declared as having weak
references but it does hold weak references (the generic ivar cache).

This commit changes it to always allocate a Fiber object for the root
fiber.
2025-12-28 08:55:38 -05:00
Misaki Shioi
3fe2ebf8e4
Remove unnecessary comparison from is_local_port_fixed (#15757)
Simplify the conditions:
- Return false if the port is 0 or a negative number
- Return true if the port is a positive number
2025-12-28 17:23:50 +09:00
Nobuyoshi Nakada
6544c89708
Skip the hang-up test on mingw 2025-12-28 10:34:17 +09:00
BurdetteLamar
8415f8facc [DOC] Use Japanese for multi-byte characters 2025-12-27 13:28:57 -05:00
BurdetteLamar
a92c0342dd [DOC] Japanese only for multi-byte chars examples 2025-12-27 10:59:48 -05:00
BurdetteLamar
38d24294ac [DOC] Multibyte chars Japanese only 2025-12-27 10:59:23 -05:00
Misaki Shioi
a8c3d5e127
Fix: Do not fast_fallback if local_port is explicitly specified (#15732)
`fast fallback` cannot be used with explicitly specified local port,
because concurrent binds to the same `local_host:local_port`
can raise `Errno::EADDRINUSE`.

This issue is more likely to occur on hosts with `IPV6_V6ONLY` disabled,
because IPv6 binds can also occupy IPv4-mapped IPv6 address space.
2025-12-27 18:26:56 +09:00
Kazuki Yamaguchi
3c9e61f5ef [ruby/openssl] cipher: remove incorrect assertion in Cipher#update
Commit https://github.com/ruby/openssl/commit/1de3b80a46c2 (cipher: make output buffer String independent,
2024-12-10) ensures the output buffer String has sufficient capacity,
bu the length can be shorter. The assert() is simply incorrect and
should be removed.

Also remove a similar assert() in Cipher#final. While not incorrect, it
is not useful either.

https://github.com/ruby/openssl/commit/0ce6ab97dd
2025-12-27 07:46:03 +00:00
git
b8201a09e0 Update bundled gems list as of 2025-12-27 2025-12-27 06:53:51 +00:00
Burdette Lamar
dedde99676
[DOC] Use Japanese for multi-byte characters (#15745) 2025-12-26 14:06:21 -06:00
Peter Zhu
7b3b1a1442 [DOC] Use self in call-seq for Method#call 2025-12-26 10:14:04 -05:00
Peter Zhu
6ae69e9ac1 [DOC] Remove args from call-seq of Method#call 2025-12-26 10:14:04 -05:00
Jean Boussier
b304c149aa [DOC] Remove outdated documentation about command injection
[Feature #19630]

This dangerous behavior was removed in 4.0 (996cae65f3cc8fed60c6bb758b00882cac49389d)
but the documentation wasn't updated.
2025-12-26 13:05:29 +01:00
Nobuyoshi Nakada
c342461582
Remove an useless macro definition RSTRUCT_PTR
The underlying definition, `rb_struct_ptr`, was removed four years
ago.
2025-12-26 19:33:03 +09:00
Nobuyoshi Nakada
8c7b1401a5
Remove rb_iterate deprecated since 1.9 2025-12-26 17:53:23 +09:00
Nobuyoshi Nakada
2ac4cc0a1b
Remove RUBY_FL_DUPPED deprecated for 4 years 2025-12-26 17:53:23 +09:00
Nobuyoshi Nakada
a3ac83b7b8
Remove taintedness/trustedness enums/macros deprecated for 4 years 2025-12-26 17:53:22 +09:00
Nobuyoshi Nakada
a447d39da2
Remove rb_gc_force_recycle deprecated as "removed soon" 2025-12-26 17:02:42 +09:00
Nobuyoshi Nakada
cf60dc2642
Remove rb_clone_setup and rb_dup_setup deprecated for 4 years 2025-12-26 17:02:42 +09:00
Nobuyoshi Nakada
a41b154029
Remove rb_complex_polar deprecated for 7 years 2025-12-26 17:02:42 +09:00
Nobuyoshi Nakada
f84110e601
Remove old APIs to allocate a data object deprecated for 5 years 2025-12-26 17:02:41 +09:00
Nobuyoshi Nakada
5c2f6639c5
Remove rb_clear_constant_cache deprecated for 3 years 2025-12-26 16:48:16 +09:00
Nobuyoshi Nakada
1ca464347a
CI: Warn deprecated features to be removed at this version 2025-12-26 15:11:23 +09:00
Nobuyoshi Nakada
ccc8610b66
Remove RUBY_GC_HEAP_INIT_SLOTS environment variable 2025-12-26 15:11:23 +09:00
Nobuyoshi Nakada
4c07e61bc9
Deprecate old VC 2025-12-26 15:11:23 +09:00
Nobuyoshi Nakada
0b65ac6daf
Remove a no longer used prototype declaration in re.c
Include internal/error.h instead.
2025-12-26 15:11:23 +09:00
Yusuke Endoh
704ac72fb6 Clarify the intent of the test for "ruby -h" to fit in 80x25 2025-12-26 14:20:00 +09:00
Andrii Furmanets
b01fd2d8c3 Fix RSET_IS_MEMBER macro parameter mismatch
The RSET_IS_MEMBER macro had a parameter named 'sobj' but the macro
body used 'set' instead, causing the first argument to be ignored.

This worked by accident because all current callers use a variable
named 'set', but would cause compilation failure if called with a
differently named variable:

    error: use of undeclared identifier 'set'

Changed the parameter name from 'sobj' to 'set' to match the macro
body and be consistent with other RSET_* macros.
2025-12-26 14:05:11 +09:00
Nobuyoshi Nakada
bad7dd5d74
[DOC] Separate updated gems lists into sections in NEWS.md 2025-12-26 13:27:32 +09:00
Takashi Sakaguchi
594dd8bfd4 [ruby/pp] Support private instance_variables_to_inspect
(https://github.com/ruby/pp/pull/70)

* Support private instance_variables_to_inspect in pp

Ruby supports calling instance_variables_to_inspect even when
it is defined as a private method (ruby/ruby#13555).

This change aligns pp with Ruby's behavior.

https://github.com/ruby/pp/commit/8450e76db6
2025-12-26 03:38:16 +00:00
Hiroshi SHIBATA
9824724b2f Skip test_write_binary(GemSingletonTest) at rbs tests
```
Errno::EACCES: Permission denied @ rb_file_s_rename
...
D:/a/ruby/ruby/src/lib/rubygems/util/atomic_file_writer.rb:42:in 'File.rename'
```

It may caused with atomic_file_writer.rb
2025-12-26 12:12:05 +09:00
Hiroshi SHIBATA
02275b1e53 uutils-coreutils 0.5.0 has been removed uutils wrapper 2025-12-26 12:12:05 +09:00
git
e95a9942bb Update default gems list at 565ea26ad10ea8c3c6ce9bdae6cbb7 [ci skip] 2025-12-26 02:01:49 +00:00
Hiroshi SHIBATA
565ea26ad1 Disabled to run lobsters benchmark because it didn't work with Ruby 4.1 yet 2025-12-26 11:00:51 +09:00
Hiroshi SHIBATA
89af235435 Added ruby_41? platform 2025-12-26 11:00:51 +09:00
Hiroshi SHIBATA
93df966848 Mark development version for unreleased gems 2025-12-26 11:00:51 +09:00
Sutou Kouhei
70c7f3ad77 [ruby/strscan] Bump version
https://github.com/ruby/strscan/commit/747a3b5def
2025-12-26 11:00:51 +09:00
Benoit Daloze
fda7019c80 [ruby/net-protocol] Add Net::Protocol::TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
* To find out efficiently if TCPSocket#initialize supports the open_timeout keyword argument.

https://github.com/ruby/net-protocol/commit/738c06f950
2025-12-26 11:00:51 +09:00
Jean Boussier
4d7db86a79 [ruby/json] Add missing documentation for allow_control_characters parsing option
https://github.com/ruby/json/commit/a5c160f372
2025-12-26 11:00:51 +09:00
久我山菜々
8ccfb375b9 [ruby/json] Update fpconv_dtoa definition to use dest[32]
https://github.com/ruby/json/commit/4808fee9af
2025-12-26 11:00:51 +09:00
Taketo Takashima
1f526b3489 [ruby/ipaddr] Follow-up fix for InvalidAddressError messages
https://github.com/ruby/ipaddr/commit/b92ef74b91
2025-12-26 11:00:51 +09:00
Koichi ITO
f3149af35a [ruby/prism] Sync Prism::Translation::ParserCurrent with Ruby 4.0
This PR updates the fallback version for `Prism::Translation::ParserCurrent` from 3.4 to 4.0.

Currently, the fallback resolves to `Parser34`, as shown below:

```console
$ ruby -v -rprism -rprism/translation/parser_current -e 'p Prism::Translation::ParserCurrent'
ruby 3.0.7p220 (2024-04-23 revision https://github.com/ruby/prism/commit/724a071175) [x86_64-darwin23]
warning: `Prism::Translation::Current` is loading Prism::Translation::Parser34, but you are running 3.0.
Prism::Translation::Parser34
```

Following the comment "Keep this in sync with released Ruby.",
it seems like the right time to set this to Ruby 4.0, which is scheduled for release this week.

https://github.com/ruby/prism/commit/115f0a118c
2025-12-26 11:00:51 +09:00
t-mangoe
44a1765684 [ruby/timeout] add test case for string argument
https://github.com/ruby/timeout/commit/fef9d07f44
2025-12-26 11:00:51 +09:00
Jean-Samuel Aubry-Guzzi
f8d0960af2 [ruby/resolv] Handle TCP Requester #recv_reply incomplete data
https://github.com/ruby/resolv/commit/9c640bdc4a
2025-12-26 11:00:51 +09:00
Jean-Samuel Aubry-Guzzi
4b7bbd4340 [ruby/resolv] Fix TCP Requester #recv_reply
https://github.com/ruby/resolv/commit/96dc3d15fe
2025-12-26 11:00:51 +09:00
Hiroshi SHIBATA
74becf1b61 Start to develop 4.1.0.dev 2025-12-26 11:00:51 +09:00
eileencodes
bdbe8d5015 [ruby/rubygems] Write gem files atomically
This change updates `write_binary` to use a new class,
`AtomicFileWriter.open` to write the gem's files. This implementation
is borrowed from Active Support's [`atomic_write`](https://github.com/rails/rails/blob/main/activesupport/lib/active_support/core_ext/file/atomic.rb).

Atomic write will write the files to a temporary file and then once
created, sets permissions and renames the file. If the file is corrupted
- ie on failed download, an error occurs, or for some other reason, the
real file will not be created. The changes made here make `verify_gz`
obsolete, we don't need to verify it if we have successfully created the
file atomically. If it exists, it is not corrupt. If it is corrupt, the
file won't exist on disk.

While writing tests for this functionality I replaced the
`RemoteFetcher` stub with `FakeFetcher` except for where we really do
need to overwrite the `RemoteFetcher`. The new test implementation is much
clearer on what it's trying to accomplish versus the prior test
implementation.

https://github.com/ruby/rubygems/commit/0cd4b54291
2025-12-26 11:00:51 +09:00
Hiroshi SHIBATA
c5376a3a16 [ruby/rubygems] Remove deprecated, unused Gem::List
https://github.com/ruby/rubygems/commit/43371085f4
2025-12-26 11:00:51 +09:00
Maciej Mensfeld
8024245854 [ruby/date] remove conditional for uint64_t
https://github.com/ruby/date/commit/47778c32d8
2025-12-26 11:00:51 +09:00
Maciej Mensfeld
5960fb9fa0 [ruby/date] remove redundant code
https://github.com/ruby/date/commit/5e6a458179
2025-12-26 11:00:51 +09:00
Maciej Mensfeld
bcaa127ecd [ruby/date] code remarks, macros and r2.6 support
https://github.com/ruby/date/commit/2682dc79c0
2025-12-26 11:00:51 +09:00
Maciej Mensfeld
ea03f263b5 [ruby/date] improve styling
https://github.com/ruby/date/commit/cd7a329dfd
2025-12-26 11:00:51 +09:00
Maciej Mensfeld
f09e35ee4a [ruby/date] [ruby/date] Optimize Gregorian date conversions with Neri-Schneider algorithm
Replace floating-point arithmetic and iterative loops with pure integer
operations for ~40% faster Date operations. Date.ordinal and Date.commercial
are ~2x faster due to O(1) first-day-of-year calculation.

Reference: https://arxiv.org/abs/2102.06959

https://github.com/ruby/date/commit/cc639549d6
2025-12-26 11:00:51 +09:00
Burdette Lamar
ae46f916f1 [ruby/stringio] [DOC] Doc for StringIO#read
(https://github.com/ruby/stringio/pull/197)

Previous doc merely linked to `IO#read`; new doc stays local, shows
examples using `StringIO`.

https://github.com/ruby/stringio/commit/e8b66f8cdd
2025-12-26 11:00:51 +09:00
Burdette Lamar
9a76ccdbab [ruby/stringio] [DOC] Doc for StringIO#putc
(https://github.com/ruby/stringio/pull/196)

Previous doc merely linked to `IO#putc`. The new doc stays local,
provides examples using `StringIO` objects.

https://github.com/ruby/stringio/commit/8983f32c50
2025-12-26 11:00:51 +09:00
Burdette Lamar
354dc574de [ruby/stringio] [DOC] Doc for StringIO#pread
(https://github.com/ruby/stringio/pull/195)

Previous doc unhelpfully pointed to `IO#pread`; this PR documents
locally, with StringIO examples.

https://github.com/ruby/stringio/commit/806f3d9741
2025-12-26 11:00:51 +09:00
Sutou Kouhei
67f830e092 [ruby/stringio] Development of 3.2.1 started.
https://github.com/ruby/stringio/commit/c9cd1c9947
2025-12-26 11:00:51 +09:00
Peter Zhu
290fa0d8b4 [ruby/mmtk] Fix cargo fmt
https://github.com/ruby/mmtk/commit/f4c46cabc7
2025-12-26 00:31:28 +00:00
git
715d69ac71 Update default gems list at a06a59e3b34cd5227363dc3af14dc6 [ci skip] 2025-12-26 00:07:09 +00:00
Hiroshi SHIBATA
a06a59e3b3
Rename and enabled auto-update bundled gems again 2025-12-26 09:06:11 +09:00
Hiroshi SHIBATA
2fa02d6d2e
Enabled auto-update NEWS.md and sync for default gems again 2025-12-26 09:06:05 +09:00
Yukihiro "Matz" Matsumoto
010dcf8556
Development of 4.1.0 started. 2025-12-26 08:59:23 +09:00
Yukihiro "Matz" Matsumoto
99e9ca1f40
[DOC] Flush NEWS.md 2025-12-26 08:59:22 +09:00
Peter Zhu
7eb088084a Update zjit bindings 2025-12-25 09:18:17 -05:00
Peter Zhu
57637827e6 Implement cont using declare weak references 2025-12-25 09:18:17 -05:00
Peter Zhu
0c07a4246c Implement weak references on gen fields cache 2025-12-25 09:18:17 -05:00
Peter Zhu
ade779b1e1 Implement callcache using declare weak references 2025-12-25 09:18:17 -05:00
Peter Zhu
a7ef2a9b0c Implement declarative weak references in MMTk 2025-12-25 09:18:17 -05:00
Peter Zhu
b2feb09efe Implement WeakMap and WeakKeyMap using declare weak references 2025-12-25 09:18:17 -05:00
Peter Zhu
10b97f52fd Implement declaring weak references
[Feature #21084]

 # Summary

The current way of marking weak references uses `rb_gc_mark_weak(VALUE *ptr)`.
This presents challenges because Ruby's GC is incremental, meaning that if the
`ptr` changes (e.g. realloc'd or free'd), then we could have an invalid memory
access. This also overwrites `*ptr = Qundef` if `*ptr` is dead, which prevents
any cleanup to be run (e.g. freeing memory or deleting entries from hash
tables). This ticket proposes `rb_gc_declare_weak_references` which declares
that an object has weak references and calls a cleanup function after marking,
allowing the object to clean up any memory for dead objects.

 # Introduction

In [[Feature #19783]](https://bugs.ruby-lang.org/issues/19783), I introduced an
API allowing objects to mark weak references, the function signature looks like
this:

```c
void rb_gc_mark_weak(VALUE *ptr);
```

`rb_gc_mark_weak` is called during the marking phase of the GC to specify that
the memory at `ptr` holds a pointer to a Ruby object that is weakly referenced.
`rb_gc_mark_weak` appends this pointer to a list that is processed after the
marking phase of the GC. If the object at `*ptr` is no longer alive, then it
overwrites the object reference with a special value (`*ptr = Qundef`).

However, this API resulted in two challenges:

1. Ruby's default GC is incremental, which means that the GC is not ran in one
   phase, but rather split into chunks of work that interleaves with Ruby
   execution. The `ptr` passed into `rb_gc_mark_weak` could be on the malloc
   heap, and that memory could be realloc'd or even free'd. We had to use
   workarounds such as `rb_gc_remove_weak` to ensure that there were no illegal
   memory accesses. This made `rb_gc_mark_weak` difficult to use, impacted
   runtime performance, and increased memory usage.
2. When an object dies, `rb_gc_mark_weak` only overwites the reference with
   `Qundef`. This means that if we want to do any cleanup (e.g. free a piece of
   memory or delete a hash table entry), we could not do that and had to defer
   this process elsewhere (e.g. during marking or runtime).

In this ticket, I'm proposing a new API for weak references. Instead of an
object marking its weak references during the marking phase, the object declares
that it has weak references using the `rb_gc_declare_weak_references` function.
This declaration occurs during runtime (e.g. after the object has been created)
rather than during GC.

After an object declares that it has weak references, it will have its callback
function called after marking as long as that object is alive. This callback
function can then call a special function `rb_gc_handle_weak_references_alive_p`
to determine whether its references are alive. This will allow the callback
function to do whatever it wants on the object, allowing it to perform any
cleanup work it needs.

This significantly simplifies the code for `ObjectSpace::WeakMap` and
`ObjectSpace::WeakKeyMap` because it no longer needs to have the workarounds for
the limitations of `rb_gc_mark_weak`.

 # Performance

The performance results below demonstrate that `ObjectSpace::WeakMap#[]=` is now
about 60% faster because the implementation has been simplified and the number
of allocations has been reduced. We can see that there is not a significant
impact on the performance of `ObjectSpace::WeakMap#[]`.

Base:

```
ObjectSpace::WeakMap#[]=
                          4.620M (± 6.4%) i/s  (216.44 ns/i) -     23.342M in   5.072149s
ObjectSpace::WeakMap#[]
                         30.967M (± 1.9%) i/s   (32.29 ns/i) -    154.998M in   5.007157s
```

Branch:

```
ObjectSpace::WeakMap#[]=
                          7.336M (± 2.8%) i/s  (136.31 ns/i) -     36.755M in   5.013983s
ObjectSpace::WeakMap#[]
                         30.902M (± 5.4%) i/s   (32.36 ns/i) -    155.901M in   5.064060s
```

Code:

```
require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "benchmark-ips"
end

wmap = ObjectSpace::WeakMap.new
key = Object.new
val = Object.new
wmap[key] = val

Benchmark.ips do |x|
  x.report("ObjectSpace::WeakMap#[]=") do |times|
    i = 0
    while i < times
      wmap[Object.new] = Object.new
      i += 1
    end
  end

  x.report("ObjectSpace::WeakMap#[]") do |times|
    i = 0
    while i < times
      wmap[key]
      wmap[val] # does not exist
      i += 1
    end
  end
end
```

 # Alternative designs

Currently, `rb_gc_declare_weak_references` is designed to be an internal-only
API. This allows us to assume the object types that call
`rb_gc_declare_weak_references`. In the future, if we want to open up this API
to third parties, we may want to change this function to something like:

```c
void rb_gc_add_cleaner(VALUE obj, void (*callback)(VALUE obj));
```

This will allow the third party to implement a custom `callback` that gets
called after the marking phase of GC to clean up any dead references. I chose
not to implement this design because it is less efficient as we would need to
store a mapping from `obj` to `callback`, which requires extra memory.
2025-12-25 09:18:17 -05:00
Peter Zhu
16626d500d Implement rb_darray_swap_remove 2025-12-25 09:18:17 -05:00
Sorah Fukumori
099da884fe
test_box: avoid failure with --program-suffix (#15734) 2025-12-25 12:35:15 +00:00
NARUSE, Yui
6a66129d6c fix the condition of www repo 2025-12-25 15:31:50 +09:00
691 changed files with 20524 additions and 10979 deletions

View File

@ -185,12 +185,19 @@ define rp
print (struct RBasic *)($arg0)
else
if ($flags & RUBY_T_MASK) == RUBY_T_DATA
if ((struct RTypedData *)($arg0))->type & 1
printf "%sT_DATA%s(%s): ", $color_type, $color_end, ((const rb_data_type_t *)(((struct RTypedData *)($arg0))->type & ~1))->wrap_struct_name
print (struct RTypedData *)($arg0)
if ($flags & RUBY_TYPED_FL_IS_TYPED_DATA)
set $data = (struct RTypedData *)($arg0)
set $type = (const rb_data_type_t *)($data->type & ~1)
printf "%sT_DATA%s(%s): ", $color_type, $color_end, $type->wrap_struct_name
print *$type
if ($data->type & 1)
print (void *)&$data->data
else
print $data
end
else
printf "%sT_DATA%s: ", $color_type, $color_end
print (struct RData *)($arg0)
print *(struct RData *)($arg0)
end
else
if ($flags & RUBY_T_MASK) == RUBY_T_MATCH

View File

@ -39,3 +39,7 @@ d4e24021d39e1f80f0055b55d91f8d5f22e15084
e90282be7ba1bc8e3119f6e1a2c80356ceb3f80a
26a9e0b4e31f7b5a9cbd755e0a15823a8fa51bae
2f53985da9ee593fe524d408256835667938c7d7
# Win32: EOL code of batch files
23f9a0d655c4d405bb2397a147a1523436205486
b839989fd22fef85e2af19de1bc83aa72a5b22bd

View File

@ -95,12 +95,12 @@ runs:
git config --global init.defaultBranch garbage
- if: inputs.checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: ${{ inputs.srcdir }}
fetch-depth: ${{ inputs.fetch-depth }}
- uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
- uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: ${{ inputs.srcdir }}/.downloaded-cache
key: ${{ runner.os }}-${{ runner.arch }}-downloaded-cache

1
.github/labeler.yml vendored
View File

@ -4,3 +4,4 @@ Documentation:
Backport:
- base-branch: 'ruby_3_\d'
- base-branch: 'ruby_4_\d'

View File

@ -61,7 +61,7 @@ jobs:
- run: id
working-directory:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
@ -72,7 +72,7 @@ jobs:
builddir: build
makeup: true
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.1'
bundler: none

View File

@ -19,9 +19,9 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.1
uses: actions/checkout@v6.0.2
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.4'
bundler: none

View File

@ -48,12 +48,12 @@ jobs:
- ruby-3.3
steps:
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/setup/ubuntu

View File

@ -1,7 +1,7 @@
name: bundled_gems
env:
UPDATE_NEWS_ENABLED: false
UPDATE_ENABLED: true
on:
push:
@ -34,7 +34,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }}
@ -59,7 +59,7 @@ jobs:
id: bundled_gems
run: |
ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems >> $GITHUB_OUTPUT
if: ${{ env.UPDATE_NEWS_ENABLED == 'true' }}
if: ${{ env.UPDATE_ENABLED == 'true' }}
- name: Update spec/bundler/support/builders.rb
run: |
@ -67,12 +67,12 @@ jobs:
rake_version = File.read("gems/bundled_gems")[/^rake\s+(\S+)/, 1]
print ARGF.read.sub(/^ *def rake_version\s*\K".*?"/) {rake_version.dump}
shell: ruby -i~ {0} spec/bundler/support/builders.rb
if: ${{ env.UPDATE_NEWS_ENABLED == 'true' }}
if: ${{ env.UPDATE_ENABLED == 'true' }}
- name: Maintain updated gems list in NEWS
run: |
ruby tool/update-NEWS-gemlist.rb bundled
if: ${{ env.UPDATE_NEWS_ENABLED == 'true' }}
if: ${{ env.UPDATE_ENABLED == 'true' }}
- name: Check diffs
id: diff

View File

@ -30,7 +30,7 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/setup/ubuntu
if: ${{ contains(matrix.os, 'ubuntu') }}
@ -40,7 +40,7 @@ jobs:
- uses: ./.github/actions/setup/directories
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.1'
bundler: none

View File

@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }}
@ -53,6 +53,22 @@ jobs:
exit $fail
working-directory: include
- id: now
run: |
date +"mon=%-m"%n"day=%-d" >> $GITHUB_OUTPUT
env:
TZ: Tokyo/Asia
- id: deprecation
run: |
eval $(sed -n 's/^#define RUBY_API_VERSION_\(MAJOR\|MINOR\) /\1=/p' include/ruby/version.h)
if git --no-pager grep --color -o 'rb_warn_deprecated_to_remove_at('$MAJOR'\.'$MINOR',.*' -- '*.c' >&2; then
false
else
true
fi
continue-on-error: ${{ steps.now.outputs.mon < 12 }}
- name: Check if to generate documents
id: rdoc
run: |
@ -61,7 +77,7 @@ jobs:
echo RDOC='ruby -W0 --disable-gems tool/rdoc-srcdir -q' >> $GITHUB_ENV
- name: Checkout rdoc
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ruby/rdoc
ref: ${{ steps.rdoc.outputs.ref }}

View File

@ -58,7 +58,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install libraries
if: ${{ contains(matrix.os, 'macos') }}

View File

@ -51,7 +51,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
# Set fetch-depth: 10 so that Launchable can receive commits information.
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
@ -74,7 +74,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- name: 'GCC 15 LTO'
@ -104,7 +104,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'clang 22', with: { tag: 'clang-22' }, timeout-minutes: 5 }
@ -125,7 +125,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'clang 13', with: { tag: 'clang-13' }, timeout-minutes: 5 }
@ -146,7 +146,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
# -Wno-strict-prototypes is necessary with current clang-15 since
@ -172,7 +172,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'C++20', with: { CXXFLAGS: '-std=c++20 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }, timeout-minutes: 5 }
@ -192,7 +192,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'disable-jit', with: { append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 }
@ -214,7 +214,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'NDEBUG', with: { cppflags: '-DNDEBUG' }, timeout-minutes: 5 }
@ -234,7 +234,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'HASH_DEBUG', with: { cppflags: '-DHASH_DEBUG' }, timeout-minutes: 5 }
@ -254,7 +254,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'USE_LAZY_LOAD', with: { cppflags: '-DUSE_LAZY_LOAD' }, timeout-minutes: 5 }
@ -274,7 +274,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'GC_DEBUG_STRESS_TO_CLASS', with: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' }, timeout-minutes: 5 }
@ -293,7 +293,7 @@ jobs:
timeout-minutes: 60
services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } }
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
- { uses: './.github/actions/compilers', name: 'VM_DEBUG_BP_CHECK', with: { cppflags: '-DVM_DEBUG_BP_CHECK' }, timeout-minutes: 5 }
@ -319,7 +319,7 @@ jobs:
- 'compileB'
- 'compileC'
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
- uses: ./.github/actions/slack
with:

View File

@ -40,7 +40,7 @@ jobs:
steps:
- run: git config --global core.autocrlf input
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Cygwin
uses: cygwin/cygwin-install-action@master

View File

@ -2,7 +2,7 @@ name: Update default gems list
on: [push, pull_request, merge_group]
env:
UPDATE_NEWS_ENABLED: false
UPDATE_NEWS_ENABLED: true
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@ -23,7 +23,7 @@ jobs:
if: ${{ github.repository == 'ruby/ruby' }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }}

View File

@ -13,11 +13,11 @@ jobs:
if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'ruby/ruby'
steps:
- name: Dependabot metadata
uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0
uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a # v2.5.0
id: metadata
- name: Wait for status checks
uses: lewagon/wait-on-check-action@3603e826ee561ea102b58accb5ea55a1a7482343 # v1.4.1
uses: lewagon/wait-on-check-action@74049309dfeff245fe8009a0137eacf28136cb3c # v1.5.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}

View File

@ -61,7 +61,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github

View File

@ -166,7 +166,7 @@ jobs:
[ ${#failed[@]} -eq 0 ]
shell: sh
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
@ -207,7 +207,7 @@ jobs:
- name: test
timeout-minutes: 30
run: make test
run: make test test-tool
env:
GNUMAKEFLAGS: ''
RUBY_TESTOPTS: '-v --tty=no'

View File

@ -48,7 +48,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
@ -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@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.1'
bundler: none

View File

@ -51,14 +51,14 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
- uses: ./.github/actions/setup/ubuntu
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.1'
bundler: none

View File

@ -28,7 +28,7 @@ jobs:
REDMINE_SYS_API_KEY: ${{ secrets.REDMINE_SYS_API_KEY }}
if: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/ruby_') }}
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 500 # for notify-slack-commits
token: ${{ secrets.MATZBOT_AUTO_UPDATE_TOKEN }}

View File

@ -25,7 +25,7 @@ jobs:
&& github.event.workflow_run.event == 'pull_request')
}}
steps:
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |

View File

@ -1,18 +1,107 @@
name: Start release workflow
name: Publish Ruby packages
on:
push:
tags:
- '*'
repository_dispatch:
types:
- release
workflow_dispatch:
inputs:
version:
description: 'Version of the Ruby package to release'
required: true
default: '3.3.4'
jobs:
notify:
release:
runs-on: ubuntu-latest
steps:
- name: Build release package
- uses: actions/checkout@v6.0.2
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3.4
- name: Store Ruby version
run: |
echo "RUBY_VERSION=${{ github.event.client_payload.version || github.event.inputs.version }}" >> $GITHUB_ENV
- name: Store ABI version
run: echo "ABI_VERSION=$(echo ${{ env.RUBY_VERSION }} | cut -d '.' -f 1-2)" >> $GITHUB_ENV
- name: Copy draft package `/tmp` to `/pub` directory
run: tool/release.sh ${{ env.RUBY_VERSION }}
env:
AWS_ACCESS_KEY_ID: ${{ secrets.FTP_R_L_O_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.FTP_R_L_O_AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: us-west-2
- name: Purge URLs of release package
run: |
curl -X POST \
-H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \
https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.tar.gz
curl -X POST \
-H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \
https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.tar.xz
curl -X POST \
-H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \
https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.zip
- name: Create a release on GitHub
run: |
RELEASE_TAG=$(ruby tool/ruby-version.rb tag "${{ env.RUBY_VERSION }}")
echo $RELEASE_TAG
PREVIOUS_RELEASE_TAG=$(ruby tool/ruby-version.rb previous-tag "${{ env.RUBY_VERSION }}")
echo $PREVIOUS_RELEASE_TAG
tool/gen-github-release.rb $PREVIOUS_RELEASE_TAG $RELEASE_TAG --no-dry-run
env:
GITHUB_TOKEN: ${{ secrets.MATZBOT_AUTO_UPDATE_TOKEN }}
- name: Update versions index
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ruby/actions/dispatches \
-d '{"event_type": "${{ github.ref }}"}'
-d '{"event_type": "update_index"}'
- name: Build and push Docker images
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ruby/docker-images/actions/workflows/build.yml/dispatches \
-d '{"ref": "master", "inputs": {"ruby_version": "${{ env.RUBY_VERSION }}"}}'
- name: Build snapcraft packages
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ruby/snap.ruby/dispatches \
-d '{"event_type": "build", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}"}}'
- name: Store the latest LTS version of OpenSSL
run: |
echo "OPENSSL_VERSION=`curl -s https://api.github.com/repos/openssl/openssl/releases | jq -r '.[].tag_name | select(startswith("openssl-3.0"))' | sort -Vr | head -n1 | cut -d'-' -f2`" >> $GITHUB_ENV
- name: Update ruby-build definition
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.RUBY_BUILD_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/rbenv/ruby-build/dispatches \
-d '{"event_type": "update-ruby", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}", "openssl_version": "${{ env.OPENSSL_VERSION }}"}}'
- name: Update all-ruby definition
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ruby/all-ruby/dispatches \
-d '{"event_type": "update"}'

View File

@ -1,107 +1,18 @@
name: Publish Ruby packages
name: Start release workflow
on:
repository_dispatch:
types:
- release
workflow_dispatch:
inputs:
version:
description: 'Version of the Ruby package to release'
required: true
default: '3.3.4'
push:
tags:
- '*'
jobs:
release:
notify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3.4
- name: Store Ruby version
run: |
echo "RUBY_VERSION=${{ github.event.client_payload.version || github.event.inputs.version }}" >> $GITHUB_ENV
- name: Store ABI version
run: echo "ABI_VERSION=$(echo ${{ env.RUBY_VERSION }} | cut -d '.' -f 1-2)" >> $GITHUB_ENV
- name: Copy draft package `/tmp` to `/pub` directory
run: tool/release.sh ${{ env.RUBY_VERSION }}
env:
AWS_ACCESS_KEY_ID: ${{ secrets.FTP_R_L_O_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.FTP_R_L_O_AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: us-west-2
- name: Purge URLs of release package
run: |
curl -X POST \
-H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \
https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.tar.gz
curl -X POST \
-H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \
https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.tar.xz
curl -X POST \
-H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \
https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.zip
- name: Create a release on GitHub
run: |
RELEASE_TAG=$(ruby tool/ruby-version.rb tag "${{ env.RUBY_VERSION }}")
echo $RELEASE_TAG
PREVIOUS_RELEASE_TAG=$(ruby tool/ruby-version.rb previous-tag "${{ env.RUBY_VERSION }}")
echo $PREVIOUS_RELEASE_TAG
tool/gen-github-release.rb $PREVIOUS_RELEASE_TAG $RELEASE_TAG --no-dry-run
env:
GITHUB_TOKEN: ${{ secrets.MATZBOT_AUTO_UPDATE_TOKEN }}
- name: Update versions index
- name: Build release package
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ruby/actions/dispatches \
-d '{"event_type": "update_index"}'
- name: Build and push Docker images
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ruby/docker-images/actions/workflows/build.yml/dispatches \
-d '{"ref": "master", "inputs": {"ruby_version": "${{ env.RUBY_VERSION }}"}}'
- name: Build snapcraft packages
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ruby/snap.ruby/dispatches \
-d '{"event_type": "build", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}"}}'
- name: Store the latest LTS version of OpenSSL
run: |
echo "OPENSSL_VERSION=`curl -s https://api.github.com/repos/openssl/openssl/releases | jq -r '.[].tag_name | select(startswith("openssl-3.0"))' | sort -Vr | head -n1 | cut -d'-' -f2`" >> $GITHUB_ENV
- name: Update ruby-build definition
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.RUBY_BUILD_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/rbenv/ruby-build/dispatches \
-d '{"event_type": "update-ruby", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}", "openssl_version": "${{ env.OPENSSL_VERSION }}"}}'
- name: Update all-ruby definition
run: |
curl -L -X POST \
-H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/ruby/all-ruby/dispatches \
-d '{"event_type": "update"}'
-d '{"event_type": "${{ github.ref }}"}'

View File

@ -36,7 +36,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install Rust
run: rustup default beta

View File

@ -34,7 +34,7 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

View File

@ -42,12 +42,13 @@ jobs:
- ruby-3.2
- ruby-3.3
- ruby-3.4
- ruby-4.0
fail-fast: false
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none

View File

@ -1,7 +1,7 @@
name: Sync default gems
env:
DEFAULT_GEM_SYNC_ENABLED: false
DEFAULT_GEM_SYNC_ENABLED: true
on:
workflow_dispatch:
@ -31,12 +31,12 @@ jobs:
if: ${{ github.repository == 'ruby/ruby' }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
name: Check out ruby/ruby
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@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.4'
bundler: none

View File

@ -60,7 +60,7 @@ jobs:
)}}
steps: &make-steps
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
@ -69,7 +69,7 @@ jobs:
with:
arch: ${{ matrix.arch }}
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.1'
bundler: none
@ -208,7 +208,7 @@ jobs:
matrix:
include:
# Using the same setup as ZJIT jobs
- bench_opts: '--warmup=1 --bench=1'
- bench_opts: '--warmup=1 --bench=1 --excludes=lobsters'
runs-on: ubuntu-24.04
@ -221,7 +221,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/setup/ubuntu
@ -237,11 +237,13 @@ jobs:
- run: make install
- name: Checkout ruby-bench
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ruby/ruby-bench
path: ruby-bench
# If you want to skip failing benchmark, consider using `--excludes`.
# e.g. `bench_opts: '--warmup=1 --bench=1 --excludes=railsbench,lobsters'`
- name: Run ruby-bench
run: ruby run_benchmarks.rb -e "ruby::../build/install/bin/ruby" ${{ matrix.bench_opts }}
working-directory: ruby-bench

View File

@ -59,7 +59,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
@ -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@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.1'
bundler: none

View File

@ -59,14 +59,14 @@ jobs:
- run: md build
working-directory:
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.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' }}
bundler: none
windows-toolchain: none
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
@ -88,7 +88,7 @@ jobs:
- name: Restore vcpkg artifact
id: restore-vcpkg
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: src\vcpkg_installed
key: windows-${{ matrix.os }}-vcpkg-${{ hashFiles('src/vcpkg.json') }}
@ -100,7 +100,7 @@ jobs:
if: ${{ ! steps.restore-vcpkg.outputs.cache-hit }}
- name: Save vcpkg artifact
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
uses: actions/cache/save@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: src\vcpkg_installed
key: windows-${{ matrix.os }}-vcpkg-${{ hashFiles('src/vcpkg.json') }}
@ -112,7 +112,7 @@ jobs:
# https://github.com/actions/virtual-environments/issues/712#issuecomment-613004302
run: |
::- Set up VC ${{ matrix.vc }}
set | uutils sort > old.env
set | sort > old.env
call ..\src\win32\vssetup.cmd ^
-arch=${{ matrix.target || 'amd64' }} ^
${{ matrix.vcvars && '-vcvars_ver=' || '' }}${{ matrix.vcvars }}
@ -122,8 +122,8 @@ jobs:
set MAKEFLAGS=l
set /a TEST_JOBS=(15 * %NUMBER_OF_PROCESSORS% / 10) > nul
set RUBY_OPT_DIR=%GITHUB_WORKSPACE:\=/%/src/vcpkg_installed/%VCPKG_DEFAULT_TRIPLET%
set | uutils sort > new.env
uutils comm -13 old.env new.env >> %GITHUB_ENV%
set | sort > new.env
comm -13 old.env new.env >> %GITHUB_ENV%
del *.env
- name: baseruby version

View File

@ -41,7 +41,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- run: RUST_BACKTRACE=1 cargo test
working-directory: yjit
@ -83,7 +83,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github

View File

@ -36,7 +36,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# For now we can't run cargo test --offline because it complains about the
# capstone dependency, even though the dependency is optional
@ -68,7 +68,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Check that we don't have linting errors in release mode, too
- run: cargo clippy --all-targets --all-features
@ -121,14 +121,14 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
- uses: ./.github/actions/setup/ubuntu
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.1'
bundler: none

View File

@ -68,7 +68,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
@ -158,7 +158,7 @@ jobs:
include:
# Test --call-threshold=2 with 2 iterations in total
- ruby_opts: '--zjit-call-threshold=2'
bench_opts: '--warmup=1 --bench=1'
bench_opts: '--warmup=1 --bench=1 --excludes=lobsters'
configure: '--enable-zjit=dev_nodebug' # --enable-zjit=dev is too slow
runs-on: macos-14
@ -172,7 +172,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/setup/macos
@ -192,11 +192,13 @@ jobs:
run: echo "MAKEFLAGS=" >> "$GITHUB_ENV"
- name: Checkout ruby-bench
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ruby/ruby-bench
path: ruby-bench
# If you want to skip failing benchmark, consider using `--excludes`.
# e.g. `bench_opts: '--warmup=1 --bench=1 --excludes=railsbench,lobsters'`
- name: Run ruby-bench
run: ruby run_benchmarks.rb -e "zjit::../build/install/bin/ruby ${{ matrix.ruby_opts }}" ${{ matrix.bench_opts }}
working-directory: ruby-bench

View File

@ -41,7 +41,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- run: cargo clippy --all-targets --all-features
working-directory: zjit
@ -104,14 +104,14 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout-cone-mode: false
sparse-checkout: /.github
- uses: ./.github/actions/setup/ubuntu
- uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0
- uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.1'
bundler: none
@ -215,7 +215,7 @@ jobs:
include:
# Test --call-threshold=2 with 2 iterations in total
- ruby_opts: '--zjit-call-threshold=2'
bench_opts: '--warmup=1 --bench=1'
bench_opts: '--warmup=1 --bench=1 --excludes=lobsters'
configure: '--enable-zjit=dev_nodebug' # --enable-zjit=dev is too slow
runs-on: ubuntu-24.04
@ -229,7 +229,7 @@ jobs:
)}}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/setup/ubuntu
@ -245,11 +245,13 @@ jobs:
- run: make install
- name: Checkout ruby-bench
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ruby/ruby-bench
path: ruby-bench
# If you want to skip failing benchmark, consider using `--excludes`.
# e.g. `bench_opts: '--warmup=1 --bench=1 --excludes=railsbench,lobsters'`
- name: Run ruby-bench
run: ruby run_benchmarks.rb -e "zjit::../build/install/bin/ruby ${{ matrix.ruby_opts }}" ${{ matrix.bench_opts }}
working-directory: ruby-bench

5
.gitignore vendored
View File

@ -278,3 +278,8 @@ lcov*.info
/bundled_gems.json
/default_gems.json
/gems/default_gems
# AI agents
/.claude
/AGENTS.md
/CLAUDE.md

9
LEGAL
View File

@ -713,9 +713,8 @@ mentioned below.
Copyright (c) 2022 James Edward Anhalt III - https://github.com/jeaiii/itoa
{MIT License}[rdoc-ref:@MIT+License]
[ext/json/ext/vendor/ryu.h]
[ext/json/vendor/ryu.h]
This file is adapted from the Ryu algorithm by Ulf Adams https://github.com/ulfjack/ryu.
It is dual-licensed under {Apache License 2.0}[rdoc-ref:@Apache+License+2.0] OR
{Boost Software License 1.0}[rdoc-ref:@Boost+Software+License+1.0].
@ -1071,21 +1070,21 @@ mentioned below.
>>>
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT

778
NEWS.md
View File

@ -1,802 +1,88 @@
# NEWS for Ruby 4.0.0
# NEWS for Ruby 4.1.0
This document is a list of user-visible feature changes
since the **3.4.0** release, except for bug fixes.
since the **4.0.0** release, except for bug fixes.
Note that each entry is kept to a minimum, see links for details.
## Language changes
* `*nil` no longer calls `nil.to_a`, similar to how `**nil` does
not call `nil.to_hash`. [[Feature #21047]]
* Logical binary operators (`||`, `&&`, `and` and `or`) at the
beginning of a line continue the previous line, like fluent dot.
The following code examples are equal:
```ruby
if condition1
&& condition2
...
end
```
Previously:
```ruby
if condition1 && condition2
...
end
```
```ruby
if condition1 &&
condition2
...
end
```
[[Feature #20925]]
## Core classes updates
Note: We're only listing outstanding class updates.
* Array
* Method
* `Array#rfind` has been added as a more efficient alternative to `array.reverse_each.find` [[Feature #21678]]
* `Array#find` has been added as a more efficient override of `Enumerable#find` [[Feature #21678]]
* Binding
* `Binding#local_variables` does no longer include numbered parameters.
Also, `Binding#local_variable_get`, `Binding#local_variable_set`, and
`Binding#local_variable_defined?` reject to handle numbered parameters.
[[Bug #21049]]
* `Binding#implicit_parameters`, `Binding#implicit_parameter_get`, and
`Binding#implicit_parameter_defined?` have been added to access
numbered parameters and "it" parameter. [[Bug #21049]]
* Enumerator
* `Enumerator.produce` now accepts an optional `size` keyword argument
to specify the size of the enumerator. It can be an integer,
`Float::INFINITY`, a callable object (such as a lambda), or `nil` to
indicate unknown size. When not specified, the size defaults to
`Float::INFINITY`.
```ruby
# Infinite enumerator
enum = Enumerator.produce(1, size: Float::INFINITY, &:succ)
enum.size # => Float::INFINITY
# Finite enumerator with known/computable size
abs_dir = File.expand_path("./baz") # => "/foo/bar/baz"
traverser = Enumerator.produce(abs_dir, size: -> { abs_dir.count("/") + 1 }) {
raise StopIteration if it == "/"
File.dirname(it)
}
traverser.size # => 4
```
[[Feature #21701]]
* ErrorHighlight
* When an ArgumentError is raised, it now displays code snippets for
both the method call (caller) and the method definition (callee).
[[Feature #21543]]
```
test.rb:1:in 'Object#add': wrong number of arguments (given 1, expected 2) (ArgumentError)
caller: test.rb:3
| add(1)
^^^
callee: test.rb:1
| def add(x, y) = x + y
^^^
from test.rb:3:in '<main>'
```
* Fiber
* Introduce support for `Fiber#raise(cause:)` argument similar to
`Kernel#raise`. [[Feature #21360]]
* Fiber::Scheduler
* Introduce `Fiber::Scheduler#fiber_interrupt` to interrupt a fiber with a
given exception. The initial use case is to interrupt a fiber that is
waiting on a blocking IO operation when the IO operation is closed.
[[Feature #21166]]
* Introduce `Fiber::Scheduler#yield` to allow the fiber scheduler to
continue processing when signal exceptions are disabled.
[[Bug #21633]]
* Reintroduce the `Fiber::Scheduler#io_close` hook for asynchronous `IO#close`.
* Invoke `Fiber::Scheduler#io_write` when flushing the IO write buffer.
[[Bug #21789]]
* File
* `File::Stat#birthtime` is now available on Linux via the statx
system call when supported by the kernel and filesystem.
[[Feature #21205]]
* IO
* `IO.select` accepts `Float::INFINITY` as a timeout argument.
[[Feature #20610]]
* A deprecated behavior, process creation by `IO` class methods
with a leading `|`, was removed. [[Feature #19630]]
* Kernel
* `Kernel#inspect` now checks for the existence of a `#instance_variables_to_inspect` method,
allowing control over which instance variables are displayed in the `#inspect` string:
```ruby
class DatabaseConfig
def initialize(host, user, password)
@host = host
@user = user
@password = password
end
private def instance_variables_to_inspect = [:@host, :@user]
end
conf = DatabaseConfig.new("localhost", "root", "hunter2")
conf.inspect #=> #<DatabaseConfig:0x0000000104def350 @host="localhost", @user="root">
```
[[Feature #21219]]
* A deprecated behavior, process creation by `Kernel#open` with a
leading `|`, was removed. [[Feature #19630]]
* Math
* `Math.log1p` and `Math.expm1` are added. [[Feature #21527]]
* Pathname
* Pathname has been promoted from a default gem to a core class of Ruby.
[[Feature #17473]]
* Proc
* `Proc#parameters` now shows anonymous optional parameters as `[:opt]`
instead of `[:opt, nil]`, making the output consistent with when the
anonymous parameter is required. [[Bug #20974]]
* Ractor
* `Ractor::Port` class was added for a new synchronization mechanism
to communicate between Ractors. [[Feature #21262]]
```ruby
port1 = Ractor::Port.new
port2 = Ractor::Port.new
Ractor.new port1, port2 do |port1, port2|
port1 << 1
port2 << 11
port1 << 2
port2 << 12
end
2.times{ p port1.receive } #=> 1, 2
2.times{ p port2.receive } #=> 11, 12
```
`Ractor::Port` provides the following methods:
* `Ractor::Port#receive`
* `Ractor::Port#send` (or `Ractor::Port#<<`)
* `Ractor::Port#close`
* `Ractor::Port#closed?`
As a result, `Ractor.yield` and `Ractor#take` were removed.
* `Ractor#join` and `Ractor#value` were added to wait for the
termination of a Ractor. These are similar to `Thread#join`
and `Thread#value`.
* `Ractor#monitor` and `Ractor#unmonitor` were added as low-level
interfaces used internally to implement `Ractor#join`.
* `Ractor.select` now only accepts Ractors and Ports. If Ractors are given,
it returns when a Ractor terminates.
* `Ractor#default_port` was added. Each `Ractor` has a default port,
which is used by `Ractor.send`, `Ractor.receive`.
* `Ractor#close_incoming` and `Ractor#close_outgoing` were removed.
* `Ractor.shareable_proc` and `Ractor.shareable_lambda` are introduced
to make shareable Proc or lambda.
[[Feature #21550]], [[Feature #21557]]
* Range
* `Range#to_set` now performs size checks to prevent issues with
endless ranges. [[Bug #21654]]
* `Range#overlap?` now correctly handles infinite (unbounded) ranges.
[[Bug #21185]]
* `Range#max` behavior on beginless integer ranges has been fixed.
[[Bug #21174]] [[Bug #21175]]
* Ruby
* A new toplevel module `Ruby` has been defined, which contains
Ruby-related constants. This module was reserved in Ruby 3.4
and is now officially defined. [[Feature #20884]]
* Ruby::Box
* A new (experimental) feature to provide separation about definitions.
For the detail of "Ruby Box", see [doc/language/box.md](doc/language/box.md).
[[Feature #21311]] [[Misc #21385]]
* `Method#source_location`, `Proc#source_location`, and
`UnboundMethod#source_location` now return extended location
information with 5 elements: `[path, start_line, start_column,
end_line, end_column]`. The previous 2-element format `[path,
line]` can still be obtained by calling `.take(2)` on the result.
[[Feature #6012]]
* Set
* `Set` is now a core class, instead of an autoloaded stdlib class.
[[Feature #21216]]
* `Set#inspect` now uses a simpler display, similar to literal arrays.
(e.g., `Set[1, 2, 3]` instead of `#<Set: {1, 2, 3}>`). [[Feature #21389]]
* Passing arguments to `Set#to_set` and `Enumerable#to_set` is now deprecated.
[[Feature #21390]]
* Socket
* `Socket.tcp` & `TCPSocket.new` accepts an `open_timeout` keyword argument to specify
the timeout for the initial connection. [[Feature #21347]]
* When a user-specified timeout occurred in `TCPSocket.new`, either `Errno::ETIMEDOUT`
or `IO::TimeoutError` could previously be raised depending on the situation.
This behavior has been unified so that `IO::TimeoutError` is now consistently raised.
(Please note that, in `Socket.tcp`, there are still cases where `Errno::ETIMEDOUT`
may be raised in similar situations, and that in both cases `Errno::ETIMEDOUT` may be
raised when the timeout occurs at the OS level.)
* String
* Update Unicode to Version 17.0.0 and Emoji Version 17.0.
[[Feature #19908]][[Feature #20724]][[Feature #21275]] (also applies to Regexp)
* `String#strip`, `strip!`, `lstrip`, `lstrip!`, `rstrip`, and `rstrip!`
are extended to accept `*selectors` arguments. [[Feature #21552]]
* Thread
* Introduce support for `Thread#raise(cause:)` argument similar to
`Kernel#raise`. [[Feature #21360]]
* A deprecated behavior, `Set#to_set`, `Range#to_set`, and
`Enumerable#to_set` accepting arguments, was removed. [[Feature #21390]]
## Stdlib updates
### The following bundled gems are added.
We only list stdlib changes that are notable feature changes.
Other changes are listed in the following sections. We also listed release
history from the previous bundled version that is Ruby 3.4.0 if it has GitHub
releases.
The following bundled gems are promoted from default gems.
### The following bundled gem is promoted from default gems.
* ostruct 0.6.3
* 0.6.1 to [v0.6.2][ostruct-v0.6.2], [v0.6.3][ostruct-v0.6.3]
* pstore 0.2.0
* 0.1.4 to [v0.2.0][pstore-v0.2.0]
* benchmark 0.5.0
* 0.4.0 to [v0.4.1][benchmark-v0.4.1], [v0.5.0][benchmark-v0.5.0]
* logger 1.7.0
* 1.6.4 to [v1.6.5][logger-v1.6.5], [v1.6.6][logger-v1.6.6], [v1.7.0][logger-v1.7.0]
* rdoc 7.0.3
* 6.14.0 to [v6.14.1][rdoc-v6.14.1], [v6.14.2][rdoc-v6.14.2], [v6.15.0][rdoc-v6.15.0], [v6.15.1][rdoc-v6.15.1], [v6.16.0][rdoc-v6.16.0], [v6.16.1][rdoc-v6.16.1], [v6.17.0][rdoc-v6.17.0], [v7.0.0][rdoc-v7.0.0], [v7.0.1][rdoc-v7.0.1], [v7.0.2][rdoc-v7.0.2], [v7.0.3][rdoc-v7.0.3]
* win32ole 1.9.2
* 1.9.1 to [v1.9.2][win32ole-v1.9.2]
* irb 1.16.0
* 1.14.3 to [v1.15.0][irb-v1.15.0], [v1.15.1][irb-v1.15.1], [v1.15.2][irb-v1.15.2], [v1.15.3][irb-v1.15.3], [v1.16.0][irb-v1.16.0]
* reline 0.6.3
* 0.6.0 to [v0.6.1][reline-v0.6.1], [v0.6.2][reline-v0.6.2], [v0.6.3][reline-v0.6.3]
* readline 0.0.4
* fiddle 1.1.8
* 1.1.6 to [v1.1.7][fiddle-v1.1.7], [v1.1.8][fiddle-v1.1.8]
* tsort 0.2.0
The following default gem is added.
### The following default gem is added.
* win32-registry 0.1.2
### The following default gems are updated.
The following default gems are updated.
* RubyGems 4.1.0.dev
* bundler 4.1.0.dev
* prism 1.9.0
* stringio 3.2.1.dev
* strscan 3.1.7.dev
* syntax_suggest 2.0.3
* RubyGems 4.0.3
* bundler 4.0.3
* date 3.5.1
* 3.4.1 to [v3.5.0][date-v3.5.0], [v3.5.1][date-v3.5.1]
* delegate 0.6.1
* 0.4.0 to [v0.5.0][delegate-v0.5.0], [v0.6.0][delegate-v0.6.0], [v0.6.1][delegate-v0.6.1]
* digest 3.2.1
* 3.2.0 to [v3.2.1][digest-v3.2.1]
* english 0.8.1
* 0.8.0 to [v0.8.1][english-v0.8.1]
* erb 6.0.1
* 4.0.4 to [v5.1.2][erb-v5.1.2], [v5.1.3][erb-v5.1.3], [v6.0.0][erb-v6.0.0], [v6.0.1][erb-v6.0.1]
* error_highlight 0.7.1
* etc 1.4.6
* fcntl 1.3.0
* 1.2.0 to [v1.3.0][fcntl-v1.3.0]
* fileutils 1.8.0
* 1.7.3 to [v1.8.0][fileutils-v1.8.0]
* forwardable 1.4.0
* 1.3.3 to [v1.4.0][forwardable-v1.4.0]
* io-console 0.8.2
* 0.8.1 to [v0.8.2][io-console-v0.8.2]
* io-nonblock 0.3.2
* io-wait 0.4.0
* 0.3.2 to [v0.3.3][io-wait-v0.3.3], [v0.3.5.test1][io-wait-v0.3.5.test1], [v0.3.5][io-wait-v0.3.5], [v0.3.6][io-wait-v0.3.6], [v0.4.0][io-wait-v0.4.0]
* ipaddr 1.2.8
* json 2.18.0
* 2.9.1 to [v2.10.0][json-v2.10.0], [v2.10.1][json-v2.10.1], [v2.10.2][json-v2.10.2], [v2.11.0][json-v2.11.0], [v2.11.1][json-v2.11.1], [v2.11.2][json-v2.11.2], [v2.11.3][json-v2.11.3], [v2.12.0][json-v2.12.0], [v2.12.1][json-v2.12.1], [v2.12.2][json-v2.12.2], [v2.13.0][json-v2.13.0], [v2.13.1][json-v2.13.1], [v2.13.2][json-v2.13.2], [v2.14.0][json-v2.14.0], [v2.14.1][json-v2.14.1], [v2.15.0][json-v2.15.0], [v2.15.1][json-v2.15.1], [v2.15.2][json-v2.15.2], [v2.16.0][json-v2.16.0], [v2.17.0][json-v2.17.0], [v2.17.1][json-v2.17.1], [v2.18.0][json-v2.18.0]
* net-http 0.9.1
* 0.6.0 to [v0.7.0][net-http-v0.7.0], [v0.8.0][net-http-v0.8.0], [v0.9.0][net-http-v0.9.0], [v0.9.1][net-http-v0.9.1]
* openssl 4.0.0
* 3.3.1 to [v3.3.2][openssl-v3.3.2], [v4.0.0][openssl-v4.0.0]
* optparse 0.8.1
* 0.6.0 to [v0.7.0][optparse-v0.7.0], [v0.8.0][optparse-v0.8.0], [v0.8.1][optparse-v0.8.1]
* pp 0.6.3
* 0.6.2 to [v0.6.3][pp-v0.6.3]
* prism 1.7.0
* 1.5.2 to [v1.6.0][prism-v1.6.0], [v1.7.0][prism-v1.7.0]
* psych 5.3.1
* 5.2.2 to [v5.2.3][psych-v5.2.3], [v5.2.4][psych-v5.2.4], [v5.2.5][psych-v5.2.5], [v5.2.6][psych-v5.2.6], [v5.3.0][psych-v5.3.0], [v5.3.1][psych-v5.3.1]
* resolv 0.7.0
* 0.6.2 to [v0.6.3][resolv-v0.6.3], [v0.7.0][resolv-v0.7.0]
* stringio 3.2.0
* 3.1.2 to [v3.1.3][stringio-v3.1.3], [v3.1.4][stringio-v3.1.4], [v3.1.5][stringio-v3.1.5], [v3.1.6][stringio-v3.1.6], [v3.1.7][stringio-v3.1.7], [v3.1.8][stringio-v3.1.8], [v3.1.9][stringio-v3.1.9], [v3.2.0][stringio-v3.2.0]
* strscan 3.1.6
* 3.1.2 to [v3.1.3][strscan-v3.1.3], [v3.1.4][strscan-v3.1.4], [v3.1.5][strscan-v3.1.5], [v3.1.6][strscan-v3.1.6]
* time 0.4.2
* 0.4.1 to [v0.4.2][time-v0.4.2]
* timeout 0.6.0
* 0.4.3 to [v0.4.4][timeout-v0.4.4], [v0.5.0][timeout-v0.5.0], [v0.6.0][timeout-v0.6.0]
* uri 1.1.1
* 1.0.4 to [v1.1.0][uri-v1.1.0], [v1.1.1][uri-v1.1.1]
* weakref 0.1.4
* 0.1.3 to [v0.1.4][weakref-v0.1.4]
* zlib 3.2.2
* 3.2.1 to [v3.2.2][zlib-v3.2.2]
### The following bundled gems are updated.
The following bundled gems are updated.
* minitest 6.0.0
* power_assert 3.0.1
* 2.0.5 to [v3.0.0][power_assert-v3.0.0], [v3.0.1][power_assert-v3.0.1]
* rake 13.3.1
* 13.2.1 to [v13.3.0][rake-v13.3.0], [v13.3.1][rake-v13.3.1]
* test-unit 3.7.5
* 3.6.7 to [3.6.8][test-unit-3.6.8], [3.6.9][test-unit-3.6.9], [3.7.0][test-unit-3.7.0], [3.7.1][test-unit-3.7.1], [3.7.2][test-unit-3.7.2], [3.7.3][test-unit-3.7.3], [3.7.4][test-unit-3.7.4], [3.7.5][test-unit-3.7.5]
* rexml 3.4.4
* minitest 6.0.1
* test-unit 3.7.7
* rss 0.3.2
* 0.3.1 to [0.3.2][rss-0.3.2]
* net-ftp 0.3.9
* 0.3.8 to [v0.3.9][net-ftp-v0.3.9]
* net-imap 0.6.2
* 0.5.8 to [v0.5.9][net-imap-v0.5.9], [v0.5.10][net-imap-v0.5.10], [v0.5.11][net-imap-v0.5.11], [v0.5.12][net-imap-v0.5.12], [v0.5.13][net-imap-v0.5.13], [v0.6.0][net-imap-v0.6.0], [v0.6.1][net-imap-v0.6.1], [v0.6.2][net-imap-v0.6.2]
* net-smtp 0.5.1
* 0.5.0 to [v0.5.1][net-smtp-v0.5.1]
* matrix 0.4.3
* 0.4.2 to [v0.4.3][matrix-v0.4.3]
* prime 0.1.4
* 0.1.3 to [v0.1.4][prime-v0.1.4]
* rbs 3.10.0
* 3.8.0 to [v3.8.1][rbs-v3.8.1], [v3.9.0.dev.1][rbs-v3.9.0.dev.1], [v3.9.0.pre.1][rbs-v3.9.0.pre.1], [v3.9.0.pre.2][rbs-v3.9.0.pre.2], [v3.9.0][rbs-v3.9.0], [v3.9.1][rbs-v3.9.1], [v3.9.2][rbs-v3.9.2], [v3.9.3][rbs-v3.9.3], [v3.9.4][rbs-v3.9.4], [v3.9.5][rbs-v3.9.5], [v3.10.0.pre.1][rbs-v3.10.0.pre.1], [v3.10.0.pre.2][rbs-v3.10.0.pre.2], [v3.10.0][rbs-v3.10.0]
* rbs 3.10.2
* typeprof 0.31.1
* debug 1.11.1
* 1.11.0 to [v1.11.1][debug-v1.11.1]
* base64 0.3.0
* 0.2.0 to [v0.3.0][base64-v0.3.0]
* bigdecimal 4.0.1
* 3.1.8 to [v3.2.0][bigdecimal-v3.2.0], [v3.2.1][bigdecimal-v3.2.1], [v3.2.2][bigdecimal-v3.2.2], [v3.2.3][bigdecimal-v3.2.3], [v3.3.0][bigdecimal-v3.3.0], [v3.3.1][bigdecimal-v3.3.1], [v4.0.0][bigdecimal-v4.0.0], [v4.0.1][bigdecimal-v4.0.1]
* drb 2.2.3
* 2.2.1 to [v2.2.3][drb-v2.2.3]
* syslog 0.3.0
* 0.2.0 to [v0.3.0][syslog-v0.3.0]
* csv 3.3.5
* 3.3.2 to [v3.3.3][csv-v3.3.3], [v3.3.4][csv-v3.3.4], [v3.3.5][csv-v3.3.5]
* repl_type_completor 0.1.12
* mutex_m 0.3.0
* resolv-replace 0.2.0
* rdoc 7.1.0
### RubyGems and Bundler
Ruby 4.0 bundled RubyGems and Bundler version 4. see the following links for details.
* [Upgrading to RubyGems/Bundler 4 - RubyGems Blog](https://blog.rubygems.org/2025/12/03/upgrade-to-rubygems-bundler-4.html)
* [4.0.0 Released - RubyGems Blog](https://blog.rubygems.org/2025/12/03/4.0.0-released.html)
* [4.0.1 Released - RubyGems Blog](https://blog.rubygems.org/2025/12/09/4.0.1-released.html)
* [4.0.2 Released - RubyGems Blog](https://blog.rubygems.org/2025/12/17/4.0.2-released.html)
* [4.0.3 Released - RubyGems Blog](https://blog.rubygems.org/2025/12/23/4.0.3-released.html)
## Supported platforms
* Windows
* Dropped support for MSVC versions older than 14.0 (_MSC_VER 1900).
This means Visual Studio 2015 or later is now required.
## Compatibility issues
* The following methods were removed from Ractor due to the addition of `Ractor::Port`:
* `Ractor.yield`
* `Ractor#take`
* `Ractor#close_incoming`
* `Ractor#close_outgoing`
[[Feature #21262]]
* `ObjectSpace._id2ref` is deprecated. [[Feature #15408]]
* `Process::Status#&` and `Process::Status#>>` have been removed.
They were deprecated in Ruby 3.3. [[Bug #19868]]
* `rb_path_check` has been removed. This function was used for
`$SAFE` path checking which was removed in Ruby 2.7,
and was already deprecated.
[[Feature #20971]]
* A backtrace for `ArgumentError` of "wrong number of arguments" now
include the receiver's class or module name (e.g., in `Foo#bar`
instead of in `bar`). [[Bug #21698]]
* Backtraces no longer display `internal` frames.
These methods now appear as if it is in the Ruby source file,
consistent with other C-implemented methods. [[Bug #20968]]
Before:
```
ruby -e '[1].fetch_values(42)'
<internal:array>:211:in 'Array#fetch': index 42 outside of array bounds: -1...1 (IndexError)
from <internal:array>:211:in 'block in Array#fetch_values'
from <internal:array>:211:in 'Array#map!'
from <internal:array>:211:in 'Array#fetch_values'
from -e:1:in '<main>'
```
After:
```
$ ruby -e '[1].fetch_values(42)'
-e:1:in 'Array#fetch_values': index 42 outside of array bounds: -1...1 (IndexError)
from -e:1:in '<main>'
```
## Stdlib compatibility issues
* CGI library is removed from the default gems. Now we only provide `cgi/escape` for
the following methods:
* `CGI.escape` and `CGI.unescape`
* `CGI.escapeHTML` and `CGI.unescapeHTML`
* `CGI.escapeURIComponent` and `CGI.unescapeURIComponent`
* `CGI.escapeElement` and `CGI.unescapeElement`
[[Feature #21258]]
* With the move of `Set` from stdlib to core class, `set/sorted_set.rb` has
been removed, and `SortedSet` is no longer an autoloaded constant. Please
install the `sorted_set` gem and `require 'sorted_set'` to use `SortedSet`.
[[Feature #21287]]
* Net::HTTP
* The default behavior of automatically setting the `Content-Type` header
to `application/x-www-form-urlencoded` for requests with a body
(e.g., `POST`, `PUT`) when the header was not explicitly set has been
removed. If your application relied on this automatic default, your
requests will now be sent without a Content-Type header, potentially
breaking compatibility with certain servers.
[[GH-net-http #205]]
## C API updates
* IO
* `rb_thread_fd_close` is deprecated and now a no-op. If you need to expose
file descriptors from C extensions to Ruby code, create an `IO` instance
using `RUBY_IO_MODE_EXTERNAL` and use `rb_io_close(io)` to close it (this
also interrupts and waits for all pending operations on the `IO`
instance). Directly closing file descriptors does not interrupt pending
operations, and may lead to undefined behaviour. In other words, if two
`IO` objects share the same file descriptor, closing one does not affect
the other. [[Feature #18455]]
* GVL
* `rb_thread_call_with_gvl` now works with or without the GVL.
This allows gems to avoid checking `ruby_thread_has_gvl_p`.
Please still be diligent about the GVL. [[Feature #20750]]
* Set
* A C API for `Set` has been added. The following methods are supported:
[[Feature #21459]]
* `rb_set_foreach`
* `rb_set_new`
* `rb_set_new_capa`
* `rb_set_lookup`
* `rb_set_add`
* `rb_set_clear`
* `rb_set_delete`
* `rb_set_size`
## Implementation improvements
* `Class#new` (ex. `Object.new`) is faster in all cases, but especially when passing keyword arguments. This has also been integrated into YJIT and ZJIT. [[Feature #21254]]
* GC heaps of different size pools now grow independently, reducing memory usage when only some pools contain long-lived objects
* GC sweeping is faster on pages of large objects
* "Generic ivar" objects (String, Array, `TypedData`, etc.) now use a new internal "fields" object for faster instance variable access
* The GC avoids maintaining an internal `id2ref` table until it is first used, making `object_id` allocation and GC sweeping faster
* `object_id` and `hash` are faster on Class and Module objects
* Larger bignum Integers can remain embedded using variable width allocation
* `Random`, `Enumerator::Product`, `Enumerator::Chain`, `Addrinfo`,
`StringScanner`, and some internal objects are now write-barrier protected,
which reduces GC overhead.
### Ractor
A lot of work has gone into making Ractors more stable, performant, and usable. These improvements bring Ractor implementation closer to leaving experimental status.
* Performance improvements
* Frozen strings and the symbol table internally use a lock-free hash set [[Feature #21268]]
* Method cache lookups avoid locking in most cases
* Class (and generic ivar) instance variable access is faster and avoids locking
* CPU cache contention is avoided in object allocation by using a per-ractor counter
* CPU cache contention is avoided in xmalloc/xfree by using a thread-local counter
* `object_id` avoids locking in most cases
* Bug fixes and stability
* Fixed possible deadlocks when combining Ractors and Threads
* Fixed issues with require and autoload in a Ractor
* Fixed encoding/transcoding issues across Ractors
* Fixed race conditions in GC operations and method invalidation
* Fixed issues with processes forking after starting a Ractor
* GC allocation counts are now accurate under Ractors
* Fixed TracePoints not working after GC [[Bug #19112]]
## JIT
* ZJIT
* Introduce an [experimental method-based JIT compiler](https://docs.ruby-lang.org/en/master/jit/zjit_md.html).
Where available, ZJIT can be enabled at runtime with the `--zjit` option or by calling `RubyVM::ZJIT.enable`.
When building Ruby, Rust 1.85.0 or later is required to include ZJIT support.
* As of Ruby 4.0.0, ZJIT is faster than the interpreter, but not yet as fast as YJIT.
We encourage experimentation with ZJIT, but advise against deploying it in production for now.
* Our goal is to make ZJIT faster than YJIT and production-ready in Ruby 4.1.
* YJIT
* `RubyVM::YJIT.runtime_stats`
* `ratio_in_yjit` no longer works in the default build.
Use `--enable-yjit=stats` on `configure` to enable it on `--yjit-stats`.
* Add `invalidate_everything` to default stats, which is
incremented when every code is invalidated by TracePoint.
* Add `mem_size:` and `call_threshold:` options to `RubyVM::YJIT.enable`.
* RJIT
* `--rjit` is removed. We will move the implementation of the third-party JIT API
to the [ruby/rjit](https://github.com/ruby/rjit) repository.
[Feature #15408]: https://bugs.ruby-lang.org/issues/15408
[Feature #17473]: https://bugs.ruby-lang.org/issues/17473
[Feature #18455]: https://bugs.ruby-lang.org/issues/18455
[Bug #19112]: https://bugs.ruby-lang.org/issues/19112
[Feature #19630]: https://bugs.ruby-lang.org/issues/19630
[Bug #19868]: https://bugs.ruby-lang.org/issues/19868
[Feature #19908]: https://bugs.ruby-lang.org/issues/19908
[Feature #20610]: https://bugs.ruby-lang.org/issues/20610
[Feature #20724]: https://bugs.ruby-lang.org/issues/20724
[Feature #20750]: https://bugs.ruby-lang.org/issues/20750
[Feature #20884]: https://bugs.ruby-lang.org/issues/20884
[Feature #20925]: https://bugs.ruby-lang.org/issues/20925
[Bug #20968]: https://bugs.ruby-lang.org/issues/20968
[Feature #20971]: https://bugs.ruby-lang.org/issues/20971
[Bug #20974]: https://bugs.ruby-lang.org/issues/20974
[Feature #21047]: https://bugs.ruby-lang.org/issues/21047
[Bug #21049]: https://bugs.ruby-lang.org/issues/21049
[Feature #21166]: https://bugs.ruby-lang.org/issues/21166
[Bug #21174]: https://bugs.ruby-lang.org/issues/21174
[Bug #21175]: https://bugs.ruby-lang.org/issues/21175
[Bug #21185]: https://bugs.ruby-lang.org/issues/21185
[Feature #21205]: https://bugs.ruby-lang.org/issues/21205
[Feature #21216]: https://bugs.ruby-lang.org/issues/21216
[Feature #21219]: https://bugs.ruby-lang.org/issues/21219
[Feature #21254]: https://bugs.ruby-lang.org/issues/21254
[Feature #21258]: https://bugs.ruby-lang.org/issues/21258
[Feature #21268]: https://bugs.ruby-lang.org/issues/21268
[Feature #21262]: https://bugs.ruby-lang.org/issues/21262
[Feature #21275]: https://bugs.ruby-lang.org/issues/21275
[Feature #21287]: https://bugs.ruby-lang.org/issues/21287
[Feature #21311]: https://bugs.ruby-lang.org/issues/21311
[Feature #21347]: https://bugs.ruby-lang.org/issues/21347
[Feature #21360]: https://bugs.ruby-lang.org/issues/21360
[Misc #21385]: https://bugs.ruby-lang.org/issues/21385
[Feature #21389]: https://bugs.ruby-lang.org/issues/21389
[Feature #6012]: https://bugs.ruby-lang.org/issues/6012
[Feature #21390]: https://bugs.ruby-lang.org/issues/21390
[Feature #21459]: https://bugs.ruby-lang.org/issues/21459
[Feature #21527]: https://bugs.ruby-lang.org/issues/21527
[Feature #21543]: https://bugs.ruby-lang.org/issues/21543
[Feature #21550]: https://bugs.ruby-lang.org/issues/21550
[Feature #21552]: https://bugs.ruby-lang.org/issues/21552
[Feature #21557]: https://bugs.ruby-lang.org/issues/21557
[Bug #21633]: https://bugs.ruby-lang.org/issues/21633
[Bug #21654]: https://bugs.ruby-lang.org/issues/21654
[Feature #21678]: https://bugs.ruby-lang.org/issues/21678
[Bug #21698]: https://bugs.ruby-lang.org/issues/21698
[Feature #21701]: https://bugs.ruby-lang.org/issues/21701
[Bug #21789]: https://bugs.ruby-lang.org/issues/21789
[GH-net-http #205]: https://github.com/ruby/net-http/issues/205
[ostruct-v0.6.2]: https://github.com/ruby/ostruct/releases/tag/v0.6.2
[ostruct-v0.6.3]: https://github.com/ruby/ostruct/releases/tag/v0.6.3
[pstore-v0.2.0]: https://github.com/ruby/pstore/releases/tag/v0.2.0
[benchmark-v0.4.1]: https://github.com/ruby/benchmark/releases/tag/v0.4.1
[benchmark-v0.5.0]: https://github.com/ruby/benchmark/releases/tag/v0.5.0
[logger-v1.6.5]: https://github.com/ruby/logger/releases/tag/v1.6.5
[logger-v1.6.6]: https://github.com/ruby/logger/releases/tag/v1.6.6
[logger-v1.7.0]: https://github.com/ruby/logger/releases/tag/v1.7.0
[rdoc-v6.14.1]: https://github.com/ruby/rdoc/releases/tag/v6.14.1
[rdoc-v6.14.2]: https://github.com/ruby/rdoc/releases/tag/v6.14.2
[rdoc-v6.15.0]: https://github.com/ruby/rdoc/releases/tag/v6.15.0
[rdoc-v6.15.1]: https://github.com/ruby/rdoc/releases/tag/v6.15.1
[rdoc-v6.16.0]: https://github.com/ruby/rdoc/releases/tag/v6.16.0
[rdoc-v6.16.1]: https://github.com/ruby/rdoc/releases/tag/v6.16.1
[rdoc-v6.17.0]: https://github.com/ruby/rdoc/releases/tag/v6.17.0
[rdoc-v7.0.0]: https://github.com/ruby/rdoc/releases/tag/v7.0.0
[rdoc-v7.0.1]: https://github.com/ruby/rdoc/releases/tag/v7.0.1
[rdoc-v7.0.2]: https://github.com/ruby/rdoc/releases/tag/v7.0.2
[rdoc-v7.0.3]: https://github.com/ruby/rdoc/releases/tag/v7.0.3
[win32ole-v1.9.2]: https://github.com/ruby/win32ole/releases/tag/v1.9.2
[irb-v1.15.0]: https://github.com/ruby/irb/releases/tag/v1.15.0
[irb-v1.15.1]: https://github.com/ruby/irb/releases/tag/v1.15.1
[irb-v1.15.2]: https://github.com/ruby/irb/releases/tag/v1.15.2
[irb-v1.15.3]: https://github.com/ruby/irb/releases/tag/v1.15.3
[irb-v1.16.0]: https://github.com/ruby/irb/releases/tag/v1.16.0
[reline-v0.6.1]: https://github.com/ruby/reline/releases/tag/v0.6.1
[reline-v0.6.2]: https://github.com/ruby/reline/releases/tag/v0.6.2
[reline-v0.6.3]: https://github.com/ruby/reline/releases/tag/v0.6.3
[fiddle-v1.1.7]: https://github.com/ruby/fiddle/releases/tag/v1.1.7
[fiddle-v1.1.8]: https://github.com/ruby/fiddle/releases/tag/v1.1.8
[date-v3.5.0]: https://github.com/ruby/date/releases/tag/v3.5.0
[date-v3.5.1]: https://github.com/ruby/date/releases/tag/v3.5.1
[delegate-v0.5.0]: https://github.com/ruby/delegate/releases/tag/v0.5.0
[delegate-v0.6.0]: https://github.com/ruby/delegate/releases/tag/v0.6.0
[delegate-v0.6.1]: https://github.com/ruby/delegate/releases/tag/v0.6.1
[digest-v3.2.1]: https://github.com/ruby/digest/releases/tag/v3.2.1
[english-v0.8.1]: https://github.com/ruby/english/releases/tag/v0.8.1
[erb-v5.1.2]: https://github.com/ruby/erb/releases/tag/v5.1.2
[erb-v5.1.3]: https://github.com/ruby/erb/releases/tag/v5.1.3
[erb-v6.0.0]: https://github.com/ruby/erb/releases/tag/v6.0.0
[erb-v6.0.1]: https://github.com/ruby/erb/releases/tag/v6.0.1
[fcntl-v1.3.0]: https://github.com/ruby/fcntl/releases/tag/v1.3.0
[fileutils-v1.8.0]: https://github.com/ruby/fileutils/releases/tag/v1.8.0
[forwardable-v1.4.0]: https://github.com/ruby/forwardable/releases/tag/v1.4.0
[io-console-v0.8.2]: https://github.com/ruby/io-console/releases/tag/v0.8.2
[io-wait-v0.3.3]: https://github.com/ruby/io-wait/releases/tag/v0.3.3
[io-wait-v0.3.5.test1]: https://github.com/ruby/io-wait/releases/tag/v0.3.5.test1
[io-wait-v0.3.5]: https://github.com/ruby/io-wait/releases/tag/v0.3.5
[io-wait-v0.3.6]: https://github.com/ruby/io-wait/releases/tag/v0.3.6
[io-wait-v0.4.0]: https://github.com/ruby/io-wait/releases/tag/v0.4.0
[json-v2.10.0]: https://github.com/ruby/json/releases/tag/v2.10.0
[json-v2.10.1]: https://github.com/ruby/json/releases/tag/v2.10.1
[json-v2.10.2]: https://github.com/ruby/json/releases/tag/v2.10.2
[json-v2.11.0]: https://github.com/ruby/json/releases/tag/v2.11.0
[json-v2.11.1]: https://github.com/ruby/json/releases/tag/v2.11.1
[json-v2.11.2]: https://github.com/ruby/json/releases/tag/v2.11.2
[json-v2.11.3]: https://github.com/ruby/json/releases/tag/v2.11.3
[json-v2.12.0]: https://github.com/ruby/json/releases/tag/v2.12.0
[json-v2.12.1]: https://github.com/ruby/json/releases/tag/v2.12.1
[json-v2.12.2]: https://github.com/ruby/json/releases/tag/v2.12.2
[json-v2.13.0]: https://github.com/ruby/json/releases/tag/v2.13.0
[json-v2.13.1]: https://github.com/ruby/json/releases/tag/v2.13.1
[json-v2.13.2]: https://github.com/ruby/json/releases/tag/v2.13.2
[json-v2.14.0]: https://github.com/ruby/json/releases/tag/v2.14.0
[json-v2.14.1]: https://github.com/ruby/json/releases/tag/v2.14.1
[json-v2.15.0]: https://github.com/ruby/json/releases/tag/v2.15.0
[json-v2.15.1]: https://github.com/ruby/json/releases/tag/v2.15.1
[json-v2.15.2]: https://github.com/ruby/json/releases/tag/v2.15.2
[json-v2.16.0]: https://github.com/ruby/json/releases/tag/v2.16.0
[json-v2.17.0]: https://github.com/ruby/json/releases/tag/v2.17.0
[json-v2.17.1]: https://github.com/ruby/json/releases/tag/v2.17.1
[json-v2.18.0]: https://github.com/ruby/json/releases/tag/v2.18.0
[net-http-v0.7.0]: https://github.com/ruby/net-http/releases/tag/v0.7.0
[net-http-v0.8.0]: https://github.com/ruby/net-http/releases/tag/v0.8.0
[net-http-v0.9.0]: https://github.com/ruby/net-http/releases/tag/v0.9.0
[net-http-v0.9.1]: https://github.com/ruby/net-http/releases/tag/v0.9.1
[openssl-v3.3.2]: https://github.com/ruby/openssl/releases/tag/v3.3.2
[openssl-v4.0.0]: https://github.com/ruby/openssl/releases/tag/v4.0.0
[optparse-v0.7.0]: https://github.com/ruby/optparse/releases/tag/v0.7.0
[optparse-v0.8.0]: https://github.com/ruby/optparse/releases/tag/v0.8.0
[optparse-v0.8.1]: https://github.com/ruby/optparse/releases/tag/v0.8.1
[pp-v0.6.3]: https://github.com/ruby/pp/releases/tag/v0.6.3
[prism-v1.6.0]: https://github.com/ruby/prism/releases/tag/v1.6.0
[prism-v1.7.0]: https://github.com/ruby/prism/releases/tag/v1.7.0
[psych-v5.2.3]: https://github.com/ruby/psych/releases/tag/v5.2.3
[psych-v5.2.4]: https://github.com/ruby/psych/releases/tag/v5.2.4
[psych-v5.2.5]: https://github.com/ruby/psych/releases/tag/v5.2.5
[psych-v5.2.6]: https://github.com/ruby/psych/releases/tag/v5.2.6
[psych-v5.3.0]: https://github.com/ruby/psych/releases/tag/v5.3.0
[psych-v5.3.1]: https://github.com/ruby/psych/releases/tag/v5.3.1
[resolv-v0.6.3]: https://github.com/ruby/resolv/releases/tag/v0.6.3
[resolv-v0.7.0]: https://github.com/ruby/resolv/releases/tag/v0.7.0
[stringio-v3.1.3]: https://github.com/ruby/stringio/releases/tag/v3.1.3
[stringio-v3.1.4]: https://github.com/ruby/stringio/releases/tag/v3.1.4
[stringio-v3.1.5]: https://github.com/ruby/stringio/releases/tag/v3.1.5
[stringio-v3.1.6]: https://github.com/ruby/stringio/releases/tag/v3.1.6
[stringio-v3.1.7]: https://github.com/ruby/stringio/releases/tag/v3.1.7
[stringio-v3.1.8]: https://github.com/ruby/stringio/releases/tag/v3.1.8
[stringio-v3.1.9]: https://github.com/ruby/stringio/releases/tag/v3.1.9
[stringio-v3.2.0]: https://github.com/ruby/stringio/releases/tag/v3.2.0
[strscan-v3.1.3]: https://github.com/ruby/strscan/releases/tag/v3.1.3
[strscan-v3.1.4]: https://github.com/ruby/strscan/releases/tag/v3.1.4
[strscan-v3.1.5]: https://github.com/ruby/strscan/releases/tag/v3.1.5
[strscan-v3.1.6]: https://github.com/ruby/strscan/releases/tag/v3.1.6
[time-v0.4.2]: https://github.com/ruby/time/releases/tag/v0.4.2
[timeout-v0.4.4]: https://github.com/ruby/timeout/releases/tag/v0.4.4
[timeout-v0.5.0]: https://github.com/ruby/timeout/releases/tag/v0.5.0
[timeout-v0.6.0]: https://github.com/ruby/timeout/releases/tag/v0.6.0
[uri-v1.1.0]: https://github.com/ruby/uri/releases/tag/v1.1.0
[uri-v1.1.1]: https://github.com/ruby/uri/releases/tag/v1.1.1
[weakref-v0.1.4]: https://github.com/ruby/weakref/releases/tag/v0.1.4
[zlib-v3.2.2]: https://github.com/ruby/zlib/releases/tag/v3.2.2
[power_assert-v3.0.0]: https://github.com/ruby/power_assert/releases/tag/v3.0.0
[power_assert-v3.0.1]: https://github.com/ruby/power_assert/releases/tag/v3.0.1
[rake-v13.3.0]: https://github.com/ruby/rake/releases/tag/v13.3.0
[rake-v13.3.1]: https://github.com/ruby/rake/releases/tag/v13.3.1
[test-unit-3.6.8]: https://github.com/test-unit/test-unit/releases/tag/3.6.8
[test-unit-3.6.9]: https://github.com/test-unit/test-unit/releases/tag/3.6.9
[test-unit-3.7.0]: https://github.com/test-unit/test-unit/releases/tag/3.7.0
[test-unit-3.7.1]: https://github.com/test-unit/test-unit/releases/tag/3.7.1
[test-unit-3.7.2]: https://github.com/test-unit/test-unit/releases/tag/3.7.2
[test-unit-3.7.3]: https://github.com/test-unit/test-unit/releases/tag/3.7.3
[test-unit-3.7.4]: https://github.com/test-unit/test-unit/releases/tag/3.7.4
[test-unit-3.7.5]: https://github.com/test-unit/test-unit/releases/tag/3.7.5
[rss-0.3.2]: https://github.com/ruby/rss/releases/tag/0.3.2
[net-ftp-v0.3.9]: https://github.com/ruby/net-ftp/releases/tag/v0.3.9
[net-imap-v0.5.9]: https://github.com/ruby/net-imap/releases/tag/v0.5.9
[net-imap-v0.5.10]: https://github.com/ruby/net-imap/releases/tag/v0.5.10
[net-imap-v0.5.11]: https://github.com/ruby/net-imap/releases/tag/v0.5.11
[net-imap-v0.5.12]: https://github.com/ruby/net-imap/releases/tag/v0.5.12
[net-imap-v0.5.13]: https://github.com/ruby/net-imap/releases/tag/v0.5.13
[net-imap-v0.6.0]: https://github.com/ruby/net-imap/releases/tag/v0.6.0
[net-imap-v0.6.1]: https://github.com/ruby/net-imap/releases/tag/v0.6.1
[net-imap-v0.6.2]: https://github.com/ruby/net-imap/releases/tag/v0.6.2
[net-smtp-v0.5.1]: https://github.com/ruby/net-smtp/releases/tag/v0.5.1
[matrix-v0.4.3]: https://github.com/ruby/matrix/releases/tag/v0.4.3
[prime-v0.1.4]: https://github.com/ruby/prime/releases/tag/v0.1.4
[rbs-v3.8.1]: https://github.com/ruby/rbs/releases/tag/v3.8.1
[rbs-v3.9.0.dev.1]: https://github.com/ruby/rbs/releases/tag/v3.9.0.dev.1
[rbs-v3.9.0.pre.1]: https://github.com/ruby/rbs/releases/tag/v3.9.0.pre.1
[rbs-v3.9.0.pre.2]: https://github.com/ruby/rbs/releases/tag/v3.9.0.pre.2
[rbs-v3.9.0]: https://github.com/ruby/rbs/releases/tag/v3.9.0
[rbs-v3.9.1]: https://github.com/ruby/rbs/releases/tag/v3.9.1
[rbs-v3.9.2]: https://github.com/ruby/rbs/releases/tag/v3.9.2
[rbs-v3.9.3]: https://github.com/ruby/rbs/releases/tag/v3.9.3
[rbs-v3.9.4]: https://github.com/ruby/rbs/releases/tag/v3.9.4
[rbs-v3.9.5]: https://github.com/ruby/rbs/releases/tag/v3.9.5
[rbs-v3.10.0.pre.1]: https://github.com/ruby/rbs/releases/tag/v3.10.0.pre.1
[rbs-v3.10.0.pre.2]: https://github.com/ruby/rbs/releases/tag/v3.10.0.pre.2
[rbs-v3.10.0]: https://github.com/ruby/rbs/releases/tag/v3.10.0
[debug-v1.11.1]: https://github.com/ruby/debug/releases/tag/v1.11.1
[base64-v0.3.0]: https://github.com/ruby/base64/releases/tag/v0.3.0
[bigdecimal-v3.2.0]: https://github.com/ruby/bigdecimal/releases/tag/v3.2.0
[bigdecimal-v3.2.1]: https://github.com/ruby/bigdecimal/releases/tag/v3.2.1
[bigdecimal-v3.2.2]: https://github.com/ruby/bigdecimal/releases/tag/v3.2.2
[bigdecimal-v3.2.3]: https://github.com/ruby/bigdecimal/releases/tag/v3.2.3
[bigdecimal-v3.3.0]: https://github.com/ruby/bigdecimal/releases/tag/v3.3.0
[bigdecimal-v3.3.1]: https://github.com/ruby/bigdecimal/releases/tag/v3.3.1
[bigdecimal-v4.0.0]: https://github.com/ruby/bigdecimal/releases/tag/v4.0.0
[bigdecimal-v4.0.1]: https://github.com/ruby/bigdecimal/releases/tag/v4.0.1
[drb-v2.2.3]: https://github.com/ruby/drb/releases/tag/v2.2.3
[syslog-v0.3.0]: https://github.com/ruby/syslog/releases/tag/v0.3.0
[csv-v3.3.3]: https://github.com/ruby/csv/releases/tag/v3.3.3
[csv-v3.3.4]: https://github.com/ruby/csv/releases/tag/v3.3.4
[csv-v3.3.5]: https://github.com/ruby/csv/releases/tag/v3.3.5

42
array.c
View File

@ -1789,14 +1789,10 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
/*
* call-seq:
* self[index] -> object or nil
* self[start, length] -> object or nil
* self[offset] -> object or nil
* self[offset, size] -> object or nil
* self[range] -> object or nil
* self[aseq] -> object or nil
* slice(index) -> object or nil
* slice(start, length) -> object or nil
* slice(range) -> object or nil
* slice(aseq) -> object or nil
*
* Returns elements from +self+; does not modify +self+.
*
@ -1804,27 +1800,27 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
*
* a = [:foo, 'bar', 2]
*
* # Single argument index: returns one element.
* # Single argument offset: returns one element.
* a[0] # => :foo # Zero-based index.
* a[-1] # => 2 # Negative index counts backwards from end.
*
* # Arguments start and length: returns an array.
* # Arguments offset and size: returns an array.
* a[1, 2] # => ["bar", 2]
* a[-2, 2] # => ["bar", 2] # Negative start counts backwards from end.
* a[-2, 2] # => ["bar", 2] # Negative offset counts backwards from end.
*
* # Single argument range: returns an array.
* a[0..1] # => [:foo, "bar"]
* a[0..-2] # => [:foo, "bar"] # Negative range-begin counts backwards from end.
* a[-2..2] # => ["bar", 2] # Negative range-end counts backwards from end.
*
* When a single integer argument +index+ is given, returns the element at offset +index+:
* When a single integer argument +offset+ is given, returns the element at offset +offset+:
*
* a = [:foo, 'bar', 2]
* a[0] # => :foo
* a[2] # => 2
* a # => [:foo, "bar", 2]
*
* If +index+ is negative, counts backwards from the end of +self+:
* If +offset+ is negative, counts backwards from the end of +self+:
*
* a = [:foo, 'bar', 2]
* a[-1] # => 2
@ -1832,29 +1828,29 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
*
* If +index+ is out of range, returns +nil+.
*
* When two Integer arguments +start+ and +length+ are given,
* returns a new array of size +length+ containing successive elements beginning at offset +start+:
* When two Integer arguments +offset+ and +size+ are given,
* returns a new array of size +size+ containing successive elements beginning at offset +offset+:
*
* a = [:foo, 'bar', 2]
* a[0, 2] # => [:foo, "bar"]
* a[1, 2] # => ["bar", 2]
*
* If <tt>start + length</tt> is greater than <tt>self.length</tt>,
* returns all elements from offset +start+ to the end:
* If <tt>offset + size</tt> is greater than <tt>self.size</tt>,
* returns all elements from offset +offset+ to the end:
*
* a = [:foo, 'bar', 2]
* a[0, 4] # => [:foo, "bar", 2]
* a[1, 3] # => ["bar", 2]
* a[2, 2] # => [2]
*
* If <tt>start == self.size</tt> and <tt>length >= 0</tt>,
* If <tt>offset == self.size</tt> and <tt>size >= 0</tt>,
* returns a new empty array.
*
* If +length+ is negative, returns +nil+.
* If +size+ is negative, returns +nil+.
*
* When a single Range argument +range+ is given,
* treats <tt>range.min</tt> as +start+ above
* and <tt>range.size</tt> as +length+ above:
* treats <tt>range.min</tt> as +offset+ above
* and <tt>range.size</tt> as +size+ above:
*
* a = [:foo, 'bar', 2]
* a[0..1] # => [:foo, "bar"]
@ -8427,12 +8423,12 @@ rb_ary_deconstruct(VALUE ary)
*
* [1, 'one', :one, [2, 'two', :two]]
*
* - A {%w or %W string-array Literal}[rdoc-ref:syntax/literals.rdoc@25w+and+-25W-3A+String-Array+Literals]:
* - A {%w or %W string-array Literal}[rdoc-ref:syntax/literals.rdoc@w-and-w-String-Array-Literals]:
*
* %w[foo bar baz] # => ["foo", "bar", "baz"]
* %w[1 % *] # => ["1", "%", "*"]
*
* - A {%i or %I symbol-array Literal}[rdoc-ref:syntax/literals.rdoc@25i+and+-25I-3A+Symbol-Array+Literals]:
* - A {%i or %I symbol-array Literal}[rdoc-ref:syntax/literals.rdoc@i+and-I-Symbol-Array+Literals]:
*
* %i[foo bar baz] # => [:foo, :bar, :baz]
* %i[1 % *] # => [:"1", :%, :*]
@ -8694,8 +8690,8 @@ rb_ary_deconstruct(VALUE ary)
*
* First, what's elsewhere. Class \Array:
*
* - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
* - Inherits from {class Object}[rdoc-ref:Object@Whats-Here].
* - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats-Here],
* which provides dozens of additional methods.
*
* Here, class \Array provides methods that are useful for:

View File

@ -245,7 +245,8 @@ class Array
value = nil
result = Primitive.ary_sized_alloc
while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) })
result << yield(value)
value = yield(value)
Primitive.cexpr!(%q{ rb_ary_push(result, value) })
end
result
end
@ -270,7 +271,9 @@ class Array
value = nil
result = Primitive.ary_sized_alloc
while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) })
result << value if yield value
if yield value
Primitive.cexpr!(%q{ rb_ary_push(result, value) })
end
end
result
end

View File

@ -0,0 +1,6 @@
prelude: |
# frozen_string_literal: true
benchmark:
long: File.basename("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml")
long_name: File.basename("Users_george_src_github.com_ruby_ruby_benchmark_file_dirname.yml")
withext: File.basename("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml", ".yml")

View File

@ -0,0 +1,6 @@
prelude: |
# frozen_string_literal: true
benchmark:
long: File.dirname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml")
short: File.dirname("foo/bar")
n_4: File.dirname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml", 4)

View File

@ -0,0 +1,6 @@
prelude: |
# frozen_string_literal: true
benchmark:
long: File.extname("/Users/george/src/github.com/ruby/ruby/benchmark/file_dirname.yml")
long_name: File.extname("Users_george_src_github.com_ruby_ruby_benchmark_file_dirname.yml")
short: File.extname("foo/bar")

7
benchmark/file_join.yml Normal file
View File

@ -0,0 +1,7 @@
prelude: |
# frozen_string_literal: true
benchmark:
two_strings: File.join(__FILE__, "path")
many_strings: File.join(__FILE__, "path", "a", "b", "c", "d")
array: File.join([__FILE__, "path", "a", "b", "c", "d"])
mixed: File.join(__FILE__, "path", "a", "b", ["c", "d"])

View File

@ -259,7 +259,3 @@ benchmark:
to_set_10: s1.to_set
to_set_100: s2.to_set
to_set_1000: s3.to_set
to_set_arg_0: s0.to_set set_subclass
to_set_arg_10: s1.to_set set_subclass
to_set_arg_100: s2.to_set set_subclass
to_set_arg_1000: s3.to_set set_subclass

View File

@ -7070,7 +7070,7 @@ int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
zn = mn;
z = bignew(zn, 1);
bary_powm_gmp(BDIGITS(z), zn, BDIGITS(x), xn, BDIGITS(y), yn, BDIGITS(m), mn);
if (nega_flg & BIGNUM_POSITIVE_P(z)) {
if (nega_flg && BIGNUM_POSITIVE_P(z) && !BIGZEROP(z)) {
z = rb_big_minus(z, m);
}
RB_GC_GUARD(x);
@ -7098,7 +7098,7 @@ int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg)
x = rb_int_modulo(x, m);
}
if (nega_flg && rb_int_positive_p(tmp)) {
if (nega_flg && rb_int_positive_p(tmp) && !rb_int_zero_p(tmp)) {
tmp = rb_int_minus(tmp, m);
}
return tmp;
@ -7210,6 +7210,11 @@ rb_int_powm(int const argc, VALUE * const argv, VALUE const num)
rb_raise(rb_eTypeError, "Integer#pow() 2nd argument not allowed unless all arguments are integers");
}
if (rb_int_zero_p(a) && !rb_int_zero_p(b)) {
/* shortcut; 0**x => 0 except for x == 0 */
return INT2FIX(0);
}
if (rb_int_negative_p(m)) {
m = rb_int_uminus(m);
nega_flg = 1;

View File

@ -1427,3 +1427,10 @@ assert_equal 'ok', <<~RUBY
test
RUBY
assert_equal '[1, 2, 3]', %q{
def target(*args) = args
def x = [1]
def forwarder(...) = target(*x, 2, ...)
forwarder(3).inspect
}, '[Bug #21832] post-splat args before forwarding'

View File

@ -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 = rb_box_available() && BOX_ROOT_P(rb_current_box());
return class_alloc0(type, klass, boxable);
}
static VALUE

View File

@ -269,21 +269,15 @@ MAKE_LINK = $(MINIRUBY) -rfileutils -e "include FileUtils::Verbose" \
# For release builds
YJIT_RUSTC_ARGS = --crate-name=yjit \
$(JIT_RUST_FLAGS) \
$(RUSTC_FLAGS) \
--edition=2021 \
-g \
-C lto=thin \
-C opt-level=3 \
-C overflow-checks=on \
'--out-dir=$(CARGO_TARGET_DIR)/release/' \
'$(top_srcdir)/yjit/src/lib.rs'
ZJIT_RUSTC_ARGS = --crate-name=zjit \
$(JIT_RUST_FLAGS) \
$(RUSTC_FLAGS) \
--edition=2024 \
-g \
-C lto=thin \
-C opt-level=3 \
-C overflow-checks=on \
'--out-dir=$(CARGO_TARGET_DIR)/release/' \
'$(top_srcdir)/zjit/src/lib.rs'
@ -803,7 +797,7 @@ clean-platform distclean-platform realclean-platform:
RUBYSPEC_CAPIEXT = spec/ruby/optional/capi/ext
RUBYSPEC_CAPIEXT_SRCDIR = $(srcdir)/$(RUBYSPEC_CAPIEXT)
RUBYSPEC_CAPIEXT_DEPS = $(RUBYSPEC_CAPIEXT_SRCDIR)/rubyspec.h $(RUBY_H_INCLUDES) $(LIBRUBY)
RUBYSPEC_CAPIEXT_DEPS = $(RUBYSPEC_CAPIEXT_SRCDIR)/rubyspec.h $(RUBY_H_INCLUDES) {$(VPATH)}internal/abi.h $(LIBRUBY)
RUBYSPEC_CAPIEXT_BUILD = $(enable_shared:yes=rubyspec-capiext)
rubyspec-capiext: build-ext $(DOT_WAIT)
@ -1620,6 +1614,11 @@ test-syntax-suggest:
check: $(DOT_WAIT) $(PREPARE_SYNTAX_SUGGEST) test-syntax-suggest
RAKER = $(XRUBY) -I$(srcdir)/gems/lib$(PATH_SEPARATOR)$(srcdir)/.bundle/lib \
-rrubygems $(srcdir)/.bundle/bin/rake
rake:
$(RAKER) $(RAKE_OPTS) $(RAKE)
test-bundler-precheck: $(TEST_RUNNABLE)-test-bundler-precheck
no-test-bundler-precheck:
yes-test-bundler-precheck: main $(arch)-fake.rb

View File

@ -95,10 +95,13 @@ cmpint(VALUE x, VALUE y)
/*
* call-seq:
* obj > other -> true or false
* self > other -> true or false
*
* Compares two objects based on the receiver's <code><=></code>
* method, returning true if it returns a value greater than 0.
* Returns whether +self+ is "greater than" +other+;
* equivalent to <tt>(self <=> other) > 0</tt>:
*
* 'foo' > 'foo' # => false
* 'food' > 'foo' # => true
*/
static VALUE
@ -109,10 +112,15 @@ cmp_gt(VALUE x, VALUE y)
/*
* call-seq:
* obj >= other -> true or false
* self >= other -> true or false
*
* Returns whether +self+ is "greater than or equal to" +other+;
* equivalent to <tt>(self <=> other) >= 0</tt>:
*
* 'food' >= 'foo' # => true
* 'foo' >= 'foo' # => true
* 'foo' >= 'food' # => false
*
* Compares two objects based on the receiver's <code><=></code>
* method, returning true if it returns a value greater than or equal to 0.
*/
static VALUE

View File

@ -10926,10 +10926,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_MASGN:{
bool prev_in_masgn = ISEQ_COMPILE_DATA(iseq)->in_masgn;
ISEQ_COMPILE_DATA(iseq)->in_masgn = true;
compile_massign(iseq, ret, node, popped);
ISEQ_COMPILE_DATA(iseq)->in_masgn = prev_in_masgn;
break;
}

View File

@ -1226,10 +1226,10 @@ rb_complex_pow(VALUE self, VALUE other)
/*
* call-seq:
* complex == object -> true or false
* self == other -> true or false
*
* Returns +true+ if <tt>self.real == object.real</tt>
* and <tt>self.imag == object.imag</tt>:
* Returns whether both <tt>self.real == other.real</tt>
* and <tt>self.imag == other.imag</tt>:
*
* Complex.rect(2, 3) == Complex.rect(2.0, 3.0) # => true
*
@ -1778,12 +1778,6 @@ rb_complex_new_polar(VALUE x, VALUE y)
return f_complex_polar(rb_cComplex, x, y);
}
VALUE
rb_complex_polar(VALUE x, VALUE y)
{
return rb_complex_new_polar(x, y);
}
VALUE
rb_Complex(VALUE x, VALUE y)
{
@ -1809,7 +1803,7 @@ rb_dbl_complex_new(double real, double imag)
* Complex.rect(1, Rational(0, 1)).to_i # => 1
*
* Raises RangeError if <tt>self.imag</tt> is not exactly zero
* (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>).
* (either <tt>Integer(0)</tt> or <tt>Rational(0, n)</tt>).
*/
static VALUE
nucomp_to_i(VALUE self)
@ -1833,7 +1827,7 @@ nucomp_to_i(VALUE self)
* Complex.rect(1, Rational(0, 1)).to_f # => 1.0
*
* Raises RangeError if <tt>self.imag</tt> is not exactly zero
* (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>).
* (either <tt>Integer(0)</tt> or <tt>Rational(0, n)</tt>).
*/
static VALUE
nucomp_to_f(VALUE self)
@ -1858,7 +1852,7 @@ nucomp_to_f(VALUE self)
* Complex.rect(1, 0.0).to_r # => (1/1)
*
* Raises RangeError if <tt>self.imag</tt> is not exactly zero
* (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>)
* (either <tt>Integer(0)</tt> or <tt>Rational(0, n)</tt>)
* and <tt>self.imag.to_r</tt> is not exactly zero.
*
* Related: Complex#rationalize.
@ -2651,9 +2645,9 @@ float_arg(VALUE self)
* First, what's elsewhere:
*
* - Class \Complex inherits (directly or indirectly)
* from classes {Numeric}[rdoc-ref:Numeric@What-27s+Here]
* and {Object}[rdoc-ref:Object@What-27s+Here].
* - Includes (indirectly) module {Comparable}[rdoc-ref:Comparable@What-27s+Here].
* from classes {Numeric}[rdoc-ref:Numeric@Whats-Here]
* and {Object}[rdoc-ref:Object@Whats-Here].
* - Includes (indirectly) module {Comparable}[rdoc-ref:Comparable@Whats-Here].
*
* Here, class \Complex has methods for:
*

View File

@ -69,6 +69,7 @@ dnl 93(bright yellow) is copied from .github/workflows/mingw.yml
AC_ARG_VAR([cflags], [additional CFLAGS (ignored when CFLAGS is given)])dnl
AC_ARG_VAR([cppflags], [additional CPPFLAGS (ignored when CPPFLAGS is given)])dnl
AC_ARG_VAR([cxxflags], [additional CXXFLAGS (ignored when CXXFLAGS is given)])dnl
AC_ARG_VAR([rustc_flags], [additional RUSTC_FLAGS])dnl
[begin]_group "environment section" && {
HAVE_BASERUBY=yes
@ -82,9 +83,17 @@ AC_ARG_WITH(baseruby,
],
[
AC_PATH_PROG([BASERUBY], [ruby], [false])
HAVE_BASERUBY=
])
AS_IF([test "$HAVE_BASERUBY" != no], [
RUBYOPT=- $BASERUBY --disable=gems -rerb -rfileutils -rtempfile "${tooldir}/missing-baseruby.bat" || HAVE_BASERUBY=no
AS_IF([test "$HAVE_BASERUBY" = no], [
# --without-baseruby
], [error=`RUBYOPT=- $BASERUBY --disable=gems "${tooldir}/missing-baseruby.bat" --verbose 2>&1`], [
HAVE_BASERUBY=yes
], [test "$HAVE_BASERUBY" = ""], [ # no --with-baseruby option
AC_MSG_WARN($error) # just warn and continue
HAVE_BASERUBY=no
], [ # the ruby given by --with-baseruby is too old
AC_MSG_ERROR($error) # bail out
])
AS_IF([test "${HAVE_BASERUBY:=no}" != no], [
AS_CASE(["$build_os"], [mingw*], [
@ -537,7 +546,6 @@ AS_CASE(["$target_os"],
])
rb_cv_binary_elf=no
: ${enable_shared=yes}
AS_IF([$WINDRES --version | grep LLVM > /dev/null], [USE_LLVM_WINDRES=yes], [USE_LLVM_WINDRES=no])
],
[hiuxmpp*], [AC_DEFINE(__HIUX_MPP__)]) # by TOYODA Eizi <toyoda@npd.kishou.go.jp>
@ -4049,6 +4057,11 @@ AS_CASE(["${ZJIT_SUPPORT}"],
AC_DEFINE(USE_ZJIT, 0)
])
RUSTC_FLAGS='-g -C lto=thin -C opt-level=3 -C overflow-checks=on'
AS_IF([test -n "${rustc_flags}"], [
RUSTC_FLAGS="${RUSTC_FLAGS} ${rustc_flags}"
])
JIT_RUST_FLAGS='--crate-type=staticlib --cfg feature=\"stats_allocator\"'
RLIB_DIR=
AS_CASE(["$JIT_CARGO_SUPPORT:$YJIT_SUPPORT:$ZJIT_SUPPORT"],
@ -4106,6 +4119,7 @@ AS_IF([test -n "$RUST_LIB"], [
dnl These variables end up in ::RbConfig::CONFIG
AC_SUBST(RUSTC)dnl Rust compiler command
AC_SUBST(JIT_RUST_FLAGS)dnl the common rustc flags for JIT crates such as zjit
AC_SUBST(RUSTC_FLAGS)dnl user-configurable rustc compiler flags
AC_SUBST(CARGO)dnl Cargo command for Rust builds
AC_SUBST(CARGO_BUILD_ARGS)dnl for selecting Rust build profiles
AC_SUBST(YJIT_SUPPORT)dnl what flavor of YJIT the Ruby build includes
@ -4399,7 +4413,6 @@ AC_SUBST(MINIOBJS)
AC_SUBST(THREAD_MODEL)
AC_SUBST(COROUTINE_TYPE, ${coroutine_type})
AC_SUBST(PLATFORM_DIR)
AC_SUBST(USE_LLVM_WINDRES)
firstmf=`echo $FIRSTMAKEFILE | sed 's/:.*//'`
firsttmpl=`echo $FIRSTMAKEFILE | sed 's/.*://'`
@ -4838,6 +4851,7 @@ config_summary "strip command" "$STRIP"
config_summary "install doc" "$DOCTARGETS"
config_summary "YJIT support" "$YJIT_SUPPORT"
config_summary "ZJIT support" "$ZJIT_SUPPORT"
config_summary "RUSTC_FLAGS" "$RUSTC_FLAGS"
config_summary "man page type" "$MANTYPE"
config_summary "search path" "$search_path"
config_summary "static-linked-ext" ${EXTSTATIC:+"yes"}

117
cont.c
View File

@ -48,7 +48,8 @@ static const int DEBUG = 0;
#define RB_PAGE_MASK (~(RB_PAGE_SIZE - 1))
static long pagesize;
static const rb_data_type_t cont_data_type, fiber_data_type;
static const rb_data_type_t rb_cont_data_type;
static const rb_data_type_t rb_fiber_data_type;
static VALUE rb_cContinuation;
static VALUE rb_cFiber;
static VALUE rb_eFiberError;
@ -952,7 +953,9 @@ fiber_verify(const rb_fiber_t *fiber)
switch (fiber->status) {
case FIBER_RESUMED:
VM_ASSERT(fiber->cont.saved_ec.vm_stack != NULL);
if (fiber->cont.saved_ec.thread_ptr->self == 0) {
VM_ASSERT(fiber->cont.saved_ec.vm_stack != NULL);
}
break;
case FIBER_SUSPENDED:
VM_ASSERT(fiber->cont.saved_ec.vm_stack != NULL);
@ -982,7 +985,7 @@ cont_ptr(VALUE obj)
{
rb_context_t *cont;
TypedData_Get_Struct(obj, rb_context_t, &cont_data_type, cont);
TypedData_Get_Struct(obj, rb_context_t, &rb_cont_data_type, cont);
return cont;
}
@ -992,7 +995,7 @@ fiber_ptr(VALUE obj)
{
rb_fiber_t *fiber;
TypedData_Get_Struct(obj, rb_fiber_t, &fiber_data_type, fiber);
TypedData_Get_Struct(obj, rb_fiber_t, &rb_fiber_data_type, fiber);
if (!fiber) rb_raise(rb_eFiberError, "uninitialized fiber");
return fiber;
@ -1140,12 +1143,7 @@ rb_fiber_update_self(rb_fiber_t *fiber)
void
rb_fiber_mark_self(const rb_fiber_t *fiber)
{
if (fiber->cont.self) {
rb_gc_mark_movable(fiber->cont.self);
}
else {
rb_execution_context_mark(&fiber->cont.saved_ec);
}
rb_gc_mark_movable(fiber->cont.self);
}
static void
@ -1211,7 +1209,7 @@ fiber_memsize(const void *ptr)
VALUE
rb_obj_is_fiber(VALUE obj)
{
return RBOOL(rb_typeddata_is_kind_of(obj, &fiber_data_type));
return RBOOL(rb_typeddata_is_kind_of(obj, &rb_fiber_data_type));
}
static void
@ -1242,9 +1240,23 @@ cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont)
MEMCPY(cont->machine.stack, cont->machine.stack_src, VALUE, size);
}
static const rb_data_type_t cont_data_type = {
static void
cont_handle_weak_references(void *ptr)
{
rb_context_t *cont = ptr;
if (!cont) return;
if (!rb_gc_handle_weak_references_alive_p(cont->saved_ec.gen_fields_cache.obj) ||
!rb_gc_handle_weak_references_alive_p(cont->saved_ec.gen_fields_cache.fields_obj)) {
cont->saved_ec.gen_fields_cache.obj = Qundef;
cont->saved_ec.gen_fields_cache.fields_obj = Qundef;
}
}
static const rb_data_type_t rb_cont_data_type = {
"continuation",
{cont_mark, cont_free, cont_memsize, cont_compact},
{cont_mark, cont_free, cont_memsize, cont_compact, cont_handle_weak_references},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
@ -1404,7 +1416,8 @@ cont_new(VALUE klass)
rb_thread_t *th = GET_THREAD();
THREAD_MUST_BE_RUNNING(th);
contval = TypedData_Make_Struct(klass, rb_context_t, &cont_data_type, cont);
contval = TypedData_Make_Struct(klass, rb_context_t, &rb_cont_data_type, cont);
rb_gc_declare_weak_references(contval);
cont->self = contval;
cont_init(cont, th);
return cont;
@ -1983,16 +1996,32 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
*
*/
static const rb_data_type_t fiber_data_type = {
static void
fiber_handle_weak_references(void *ptr)
{
rb_fiber_t *fiber = ptr;
if (!fiber) return;
if (!rb_gc_handle_weak_references_alive_p(fiber->cont.saved_ec.gen_fields_cache.obj) ||
!rb_gc_handle_weak_references_alive_p(fiber->cont.saved_ec.gen_fields_cache.fields_obj)) {
fiber->cont.saved_ec.gen_fields_cache.obj = Qundef;
fiber->cont.saved_ec.gen_fields_cache.fields_obj = Qundef;
}
}
static const rb_data_type_t rb_fiber_data_type = {
"fiber",
{fiber_mark, fiber_free, fiber_memsize, fiber_compact,},
{fiber_mark, fiber_free, fiber_memsize, fiber_compact, fiber_handle_weak_references},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
fiber_alloc(VALUE klass)
{
return TypedData_Wrap_Struct(klass, &fiber_data_type, 0);
VALUE obj = TypedData_Wrap_Struct(klass, &rb_fiber_data_type, 0);
rb_gc_declare_weak_references(obj);
return obj;
}
static rb_serial_t
@ -2034,32 +2063,10 @@ fiber_t_alloc(VALUE fiber_value, unsigned int blocking)
return fiber;
}
static rb_fiber_t *
root_fiber_alloc(rb_thread_t *th)
{
VALUE fiber_value = fiber_alloc(rb_cFiber);
rb_fiber_t *fiber = th->ec->fiber_ptr;
VM_ASSERT(DATA_PTR(fiber_value) == NULL);
VM_ASSERT(fiber->cont.type == FIBER_CONTEXT);
VM_ASSERT(FIBER_RESUMED_P(fiber));
th->root_fiber = fiber;
DATA_PTR(fiber_value) = fiber;
fiber->cont.self = fiber_value;
coroutine_initialize_main(&fiber->context);
return fiber;
}
static inline rb_fiber_t*
fiber_current(void)
{
rb_execution_context_t *ec = GET_EC();
if (ec->fiber_ptr->cont.self == 0) {
root_fiber_alloc(rb_ec_thread_ptr(ec));
}
return ec->fiber_ptr;
}
@ -2565,6 +2572,7 @@ rb_threadptr_root_fiber_setup(rb_thread_t *th)
if (!fiber) {
rb_bug("%s", strerror(errno)); /* ... is it possible to call rb_bug here? */
}
fiber->cont.type = FIBER_CONTEXT;
fiber->cont.saved_ec.fiber_ptr = fiber;
fiber->cont.saved_ec.serial = next_ec_serial(th->ractor);
@ -2572,10 +2580,23 @@ rb_threadptr_root_fiber_setup(rb_thread_t *th)
fiber->blocking = 1;
fiber->killed = 0;
fiber_status_set(fiber, FIBER_RESUMED); /* skip CREATED */
coroutine_initialize_main(&fiber->context);
th->ec = &fiber->cont.saved_ec;
cont_init_jit_cont(&fiber->cont);
}
void
rb_root_fiber_obj_setup(rb_thread_t *th)
{
rb_fiber_t *fiber = th->ec->fiber_ptr;
VALUE fiber_value = fiber_alloc(rb_cFiber);
DATA_PTR(fiber_value) = fiber;
fiber->cont.self = fiber_value;
}
void
rb_threadptr_root_fiber_release(rb_thread_t *th)
{
@ -2646,15 +2667,7 @@ rb_fiber_current(void)
static inline void
fiber_store(rb_fiber_t *next_fiber, rb_thread_t *th)
{
rb_fiber_t *fiber;
if (th->ec->fiber_ptr != NULL) {
fiber = th->ec->fiber_ptr;
}
else {
/* create root fiber */
fiber = root_fiber_alloc(th);
}
rb_fiber_t *fiber = th->ec->fiber_ptr;
if (FIBER_CREATED_P(next_fiber)) {
fiber_prepare_stack(next_fiber);
@ -2690,7 +2703,9 @@ fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, rb_fi
rb_thread_t *th = GET_THREAD();
/* make sure the root_fiber object is available */
if (th->root_fiber == NULL) root_fiber_alloc(th);
if (th->root_fiber == NULL) {
th->root_fiber = th->ec->fiber_ptr;
}
if (th->ec->fiber_ptr == fiber) {
/* ignore fiber context switch
@ -3525,6 +3540,10 @@ Init_Cont(void)
rb_define_singleton_method(rb_cFiber, "schedule", rb_fiber_s_schedule, -1);
rb_thread_t *current_thread = rb_current_thread();
RUBY_ASSERT(CLASS_OF(current_thread->ec->fiber_ptr->cont.self) == 0);
*(VALUE *)&((struct RBasic *)current_thread->ec->fiber_ptr->cont.self)->klass = rb_cFiber;
#ifdef RB_EXPERIMENTAL_FIBER_POOL
/*
* Document-class: Fiber::Pool

View File

@ -6,14 +6,9 @@ MUNICODE_FLAG := $(if $(filter mingw%,$(target_os)),-municode)
override EXE_LDFLAGS += $(MUNICODE_FLAG)
DLLWRAP = @DLLWRAP@ --target=$(target_os) --driver-name="$(CC)"
ifeq (@USE_LLVM_WINDRES@,yes) # USE_LLVM_WINDRES
# llvm-windres fails when preprocessor options are added
windres-cpp :=
else
windres-cpp := $(CPP) -xc
windres-cpp := --preprocessor=$(firstword $(windres-cpp)) \
$(addprefix --preprocessor-arg=,$(wordlist 2,$(words $(windres-cpp)),$(windres-cpp)))
endif
windres-cpp := $(CPP) -xc
windres-cpp := --preprocessor=$(firstword $(windres-cpp)) \
$(addprefix --preprocessor-arg=,$(wordlist 2,$(words $(windres-cpp)),$(windres-cpp)))
WINDRES = @WINDRES@ $(windres-cpp) -DRC_INVOKED
STRIP = @STRIP@

View File

@ -4,6 +4,7 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include "ruby/ruby.h"
// Type for a dynamic array. Use to declare a dynamic array.
// It is a pointer so it fits in st_table nicely. Designed
@ -72,6 +73,20 @@
(*(ptr_to_ary))->meta.size++; \
} while (0)
/* Removes the element at idx and replaces it with the last element.
* ptr_to_ary and idx is evaluated multiple times.
* Warning: not bounds checked.
*
* void rb_darray_swap_remove(rb_darray(T) *ptr_to_ary, size_t idx);
*/
#define rb_darray_swap_remove(ptr_to_ary, idx) do { \
size_t _darray_size = rb_darray_size(*(ptr_to_ary)); \
if ((idx) != _darray_size - 1) { \
(*(ptr_to_ary))->data[idx] = (*(ptr_to_ary))->data[_darray_size - 1]; \
} \
(*(ptr_to_ary))->meta.size--; \
} while (0)
// Iterate over items of the array in a for loop
//
#define rb_darray_foreach(ary, idx_name, elem_ptr_var) \
@ -133,6 +148,9 @@ rb_darray_size(const void *ary)
return meta ? meta->size : 0;
}
/* Estimate of the amount of memory used by this darray.
* Useful for TypedData objects. */
#define rb_darray_memsize(ary) (sizeof(*(ary)) + (rb_darray_size(ary) * sizeof((ary)->data[0])))
static inline void
rb_darray_pop(void *ary, size_t count)

View File

@ -57,6 +57,7 @@ const union {
enum ruby_rstring_flags rstring_flags;
enum ruby_rarray_flags rarray_flags;
enum ruby_rarray_consts rarray_consts;
enum rbimpl_typeddata_flags rtypeddata_consts;
enum {
RUBY_FMODE_READABLE = FMODE_READABLE,
RUBY_FMODE_WRITABLE = FMODE_WRITABLE,

View File

@ -517,7 +517,7 @@ fix-depends check-depends: all hello
# because the same named directory exists in the source tree.
$(RUBYSPEC_CAPIEXT)/%.$(DLEXT): $(srcdir)/$(RUBYSPEC_CAPIEXT)/%.c $(RUBYSPEC_CAPIEXT_DEPS) \
| build-ext
$(ECHO) building $@
$(no_silence:no=$(ECHO) building $@)
$(Q) $(MAKEDIRS) $(@D)
$(Q) $(DLDSHARED) -L. $(XDLDFLAGS) $(XLDFLAGS) $(LDFLAGS) $(INCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ $< $(LIBRUBYARG)
ifneq ($(POSTLINK),)
@ -541,24 +541,25 @@ ruby.pc: $(filter-out ruby.pc,$(ruby_pc))
# Just update the version in the title of NEWS.md.
matz: up
matz: OLD := $(MAJOR).$(MINOR).0
matz-commit: OLD := $(MAJOR).$(MINOR).0
ifdef NEW
matz: MAJOR := $(word 1,$(subst ., ,$(NEW)))
matz: MINOR := $(word 2,$(subst ., ,$(NEW)))
matz: $(DOT_WAIT) bump_news
matz-commit: MAJOR := $(word 1,$(subst ., ,$(NEW)))
matz-commit: MINOR := $(word 2,$(subst ., ,$(NEW)))
matz-commit: $(DOT_WAIT) bump_news
bump_news$(DOT_WAIT): up
bump_headers$(DOT_WAIT): bump_news
else
matz: MINOR := $(shell expr $(MINOR) + 1)
matz: $(DOT_WAIT) reset_news
matz-commit: MINOR := $(shell expr $(MINOR) + 1)
matz-commit: $(DOT_WAIT) reset_news
flush_news$(DOT_WAIT): up
bump_headers$(DOT_WAIT): reset_news
endif
matz: $(DOT_WAIT) bump_headers
matz: override NEW := $(MAJOR).$(MINOR).0
matz: files := include/ruby/version.h include/ruby/internal/abi.h
matz: message := Development of $(NEW) started.
matz: $(DOT_WAIT) matz-commit
matz-commit: bump_headers
matz-commit: override NEW := $(MAJOR).$(MINOR).0
matz-commit: files := include/ruby/version.h include/ruby/internal/abi.h
matz-commit: message := Development of $(NEW) started.
flush_news:
$(GIT_IN_SRC) mv -f NEWS.md doc/NEWS/NEWS-$(OLD).md
@ -589,10 +590,23 @@ bump_news:
-e 'BEGIN {new = ARGV.shift; print gets("").sub(/Ruby \K[0-9.]+/, new)}' \
$(NEW) NEWS.md
matz:
matz: matz-commit matz-push
matz-commit:
$(GIT_IN_SRC) add NEWS.md $(files)
$(GIT_IN_SRC) commit -m "$(message)"
GIT_REMOTE_ORIGIN = origin
matz-push: matz-commit
$(eval origin_url := $(shell $(GIT_IN_SRC) remote get-url $(GIT_REMOTE_ORIGIN)))
$(if $(origin_url),,@false)
$(eval last_commit := $(shell $(GIT_IN_SRC) log -n1 --format=%H --author=matz HEAD~..HEAD))
$(if $(last_commit),,$(ECHO) No matz commits 1>&2; false)
$(if $(filter 12-25 12-26,$(shell date +%m-%d)),,$(ECHO) Not the release date 1>&2; false)
$(ECHO) $$'\e[31m'Pushing to $$'\e[7m'$(GIT_REMOTE_ORIGIN)$$'\e[27m'" ($(origin_url))"$$'\e[m'
$(GIT_IN_SRC) push $(GIT_REMOTE_ORIGIN)
tags:
$(MAKE) GIT="$(GIT)" -C "$(srcdir)" -f defs/tags.mk

View File

@ -40,6 +40,7 @@ else ifneq ($(strip $(RLIB_DIR)),) # combo build
$(RUST_LIB): $(srcdir)/ruby.rs
$(ECHO) 'building $(@F)'
$(gnumake_recursive)$(Q) $(RUSTC) --edition=2024 \
$(RUSTC_FLAGS) \
'-L$(@D)' \
--extern=yjit \
--extern=zjit \
@ -58,6 +59,7 @@ $(JIT_RLIB):
$(gnumake_recursive)$(Q) $(RUSTC) --crate-name=jit \
--edition=2024 \
$(JIT_RUST_FLAGS) \
$(RUSTC_FLAGS) \
'--out-dir=$(@D)' \
'$(top_srcdir)/jit/src/lib.rs'
endif # ifneq ($(JIT_CARGO_SUPPORT),no)

79
depend
View File

@ -300,6 +300,7 @@ ast.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
ast.$(OBJEXT): $(top_srcdir)/internal/serial.h
ast.$(OBJEXT): $(top_srcdir)/internal/set_table.h
ast.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
ast.$(OBJEXT): $(top_srcdir)/internal/struct.h
ast.$(OBJEXT): $(top_srcdir)/internal/symbol.h
ast.$(OBJEXT): $(top_srcdir)/internal/variable.h
ast.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -539,6 +540,7 @@ bignum.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
bignum.$(OBJEXT): $(top_srcdir)/internal/serial.h
bignum.$(OBJEXT): $(top_srcdir)/internal/set_table.h
bignum.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
bignum.$(OBJEXT): $(top_srcdir)/internal/struct.h
bignum.$(OBJEXT): $(top_srcdir)/internal/variable.h
bignum.$(OBJEXT): $(top_srcdir)/internal/vm.h
bignum.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -753,6 +755,7 @@ box.$(OBJEXT): $(top_srcdir)/internal/set_table.h
box.$(OBJEXT): $(top_srcdir)/internal/st.h
box.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
box.$(OBJEXT): $(top_srcdir)/internal/string.h
box.$(OBJEXT): $(top_srcdir)/internal/struct.h
box.$(OBJEXT): $(top_srcdir)/internal/variable.h
box.$(OBJEXT): $(top_srcdir)/internal/vm.h
box.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -796,6 +799,7 @@ box.$(OBJEXT): {$(VPATH)}constant.h
box.$(OBJEXT): {$(VPATH)}darray.h
box.$(OBJEXT): {$(VPATH)}debug_counter.h
box.$(OBJEXT): {$(VPATH)}defines.h
box.$(OBJEXT): {$(VPATH)}encindex.h
box.$(OBJEXT): {$(VPATH)}encoding.h
box.$(OBJEXT): {$(VPATH)}eval_intern.h
box.$(OBJEXT): {$(VPATH)}id.h
@ -991,6 +995,7 @@ builtin.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
builtin.$(OBJEXT): $(top_srcdir)/internal/serial.h
builtin.$(OBJEXT): $(top_srcdir)/internal/set_table.h
builtin.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
builtin.$(OBJEXT): $(top_srcdir)/internal/struct.h
builtin.$(OBJEXT): $(top_srcdir)/internal/variable.h
builtin.$(OBJEXT): $(top_srcdir)/internal/vm.h
builtin.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -1226,6 +1231,7 @@ class.$(OBJEXT): $(top_srcdir)/internal/serial.h
class.$(OBJEXT): $(top_srcdir)/internal/set_table.h
class.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
class.$(OBJEXT): $(top_srcdir)/internal/string.h
class.$(OBJEXT): $(top_srcdir)/internal/struct.h
class.$(OBJEXT): $(top_srcdir)/internal/variable.h
class.$(OBJEXT): $(top_srcdir)/internal/vm.h
class.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -1245,6 +1251,7 @@ class.$(OBJEXT): {$(VPATH)}config.h
class.$(OBJEXT): {$(VPATH)}constant.h
class.$(OBJEXT): {$(VPATH)}debug_counter.h
class.$(OBJEXT): {$(VPATH)}defines.h
class.$(OBJEXT): {$(VPATH)}encindex.h
class.$(OBJEXT): {$(VPATH)}encoding.h
class.$(OBJEXT): {$(VPATH)}id.h
class.$(OBJEXT): {$(VPATH)}id_table.h
@ -1444,6 +1451,7 @@ compar.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
compar.$(OBJEXT): {$(VPATH)}compar.c
compar.$(OBJEXT): {$(VPATH)}config.h
compar.$(OBJEXT): {$(VPATH)}defines.h
compar.$(OBJEXT): {$(VPATH)}encindex.h
compar.$(OBJEXT): {$(VPATH)}encoding.h
compar.$(OBJEXT): {$(VPATH)}id.h
compar.$(OBJEXT): {$(VPATH)}intern.h
@ -1636,6 +1644,7 @@ compile.$(OBJEXT): $(top_srcdir)/internal/serial.h
compile.$(OBJEXT): $(top_srcdir)/internal/set_table.h
compile.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
compile.$(OBJEXT): $(top_srcdir)/internal/string.h
compile.$(OBJEXT): $(top_srcdir)/internal/struct.h
compile.$(OBJEXT): $(top_srcdir)/internal/symbol.h
compile.$(OBJEXT): $(top_srcdir)/internal/thread.h
compile.$(OBJEXT): $(top_srcdir)/internal/variable.h
@ -1895,6 +1904,7 @@ complex.$(OBJEXT): $(top_srcdir)/internal/serial.h
complex.$(OBJEXT): $(top_srcdir)/internal/set_table.h
complex.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
complex.$(OBJEXT): $(top_srcdir)/internal/string.h
complex.$(OBJEXT): $(top_srcdir)/internal/struct.h
complex.$(OBJEXT): $(top_srcdir)/internal/variable.h
complex.$(OBJEXT): $(top_srcdir)/internal/vm.h
complex.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -1914,6 +1924,7 @@ complex.$(OBJEXT): {$(VPATH)}config.h
complex.$(OBJEXT): {$(VPATH)}constant.h
complex.$(OBJEXT): {$(VPATH)}debug_counter.h
complex.$(OBJEXT): {$(VPATH)}defines.h
complex.$(OBJEXT): {$(VPATH)}encindex.h
complex.$(OBJEXT): {$(VPATH)}encoding.h
complex.$(OBJEXT): {$(VPATH)}id.h
complex.$(OBJEXT): {$(VPATH)}id_table.h
@ -2119,6 +2130,7 @@ concurrent_set.$(OBJEXT): {$(VPATH)}concurrent_set.c
concurrent_set.$(OBJEXT): {$(VPATH)}config.h
concurrent_set.$(OBJEXT): {$(VPATH)}debug_counter.h
concurrent_set.$(OBJEXT): {$(VPATH)}defines.h
concurrent_set.$(OBJEXT): {$(VPATH)}encindex.h
concurrent_set.$(OBJEXT): {$(VPATH)}encoding.h
concurrent_set.$(OBJEXT): {$(VPATH)}id.h
concurrent_set.$(OBJEXT): {$(VPATH)}id_table.h
@ -2312,6 +2324,7 @@ cont.$(OBJEXT): $(top_srcdir)/internal/serial.h
cont.$(OBJEXT): $(top_srcdir)/internal/set_table.h
cont.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
cont.$(OBJEXT): $(top_srcdir)/internal/string.h
cont.$(OBJEXT): $(top_srcdir)/internal/struct.h
cont.$(OBJEXT): $(top_srcdir)/internal/thread.h
cont.$(OBJEXT): $(top_srcdir)/internal/variable.h
cont.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -2356,6 +2369,7 @@ cont.$(OBJEXT): {$(VPATH)}constant.h
cont.$(OBJEXT): {$(VPATH)}cont.c
cont.$(OBJEXT): {$(VPATH)}debug_counter.h
cont.$(OBJEXT): {$(VPATH)}defines.h
cont.$(OBJEXT): {$(VPATH)}encindex.h
cont.$(OBJEXT): {$(VPATH)}encoding.h
cont.$(OBJEXT): {$(VPATH)}eval_intern.h
cont.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
@ -2552,6 +2566,7 @@ debug.$(OBJEXT): $(top_srcdir)/internal/serial.h
debug.$(OBJEXT): $(top_srcdir)/internal/set_table.h
debug.$(OBJEXT): $(top_srcdir)/internal/signal.h
debug.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
debug.$(OBJEXT): $(top_srcdir)/internal/struct.h
debug.$(OBJEXT): $(top_srcdir)/internal/variable.h
debug.$(OBJEXT): $(top_srcdir)/internal/vm.h
debug.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -4897,6 +4912,7 @@ enumerator.$(OBJEXT): {$(VPATH)}config.h
enumerator.$(OBJEXT): {$(VPATH)}constant.h
enumerator.$(OBJEXT): {$(VPATH)}debug_counter.h
enumerator.$(OBJEXT): {$(VPATH)}defines.h
enumerator.$(OBJEXT): {$(VPATH)}encindex.h
enumerator.$(OBJEXT): {$(VPATH)}encoding.h
enumerator.$(OBJEXT): {$(VPATH)}enumerator.c
enumerator.$(OBJEXT): {$(VPATH)}id.h
@ -5095,6 +5111,7 @@ error.$(OBJEXT): $(top_srcdir)/internal/serial.h
error.$(OBJEXT): $(top_srcdir)/internal/set_table.h
error.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
error.$(OBJEXT): $(top_srcdir)/internal/string.h
error.$(OBJEXT): $(top_srcdir)/internal/struct.h
error.$(OBJEXT): $(top_srcdir)/internal/symbol.h
error.$(OBJEXT): $(top_srcdir)/internal/thread.h
error.$(OBJEXT): $(top_srcdir)/internal/variable.h
@ -5116,6 +5133,7 @@ error.$(OBJEXT): {$(VPATH)}config.h
error.$(OBJEXT): {$(VPATH)}constant.h
error.$(OBJEXT): {$(VPATH)}debug_counter.h
error.$(OBJEXT): {$(VPATH)}defines.h
error.$(OBJEXT): {$(VPATH)}encindex.h
error.$(OBJEXT): {$(VPATH)}encoding.h
error.$(OBJEXT): {$(VPATH)}error.c
error.$(OBJEXT): {$(VPATH)}id.h
@ -5320,6 +5338,7 @@ eval.$(OBJEXT): $(top_srcdir)/internal/serial.h
eval.$(OBJEXT): $(top_srcdir)/internal/set_table.h
eval.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
eval.$(OBJEXT): $(top_srcdir)/internal/string.h
eval.$(OBJEXT): $(top_srcdir)/internal/struct.h
eval.$(OBJEXT): $(top_srcdir)/internal/thread.h
eval.$(OBJEXT): $(top_srcdir)/internal/variable.h
eval.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -5362,6 +5381,7 @@ eval.$(OBJEXT): {$(VPATH)}config.h
eval.$(OBJEXT): {$(VPATH)}constant.h
eval.$(OBJEXT): {$(VPATH)}debug_counter.h
eval.$(OBJEXT): {$(VPATH)}defines.h
eval.$(OBJEXT): {$(VPATH)}encindex.h
eval.$(OBJEXT): {$(VPATH)}encoding.h
eval.$(OBJEXT): {$(VPATH)}eval.c
eval.$(OBJEXT): {$(VPATH)}eval_error.c
@ -5573,6 +5593,7 @@ file.$(OBJEXT): $(top_srcdir)/internal/array.h
file.$(OBJEXT): $(top_srcdir)/internal/class.h
file.$(OBJEXT): $(top_srcdir)/internal/compilers.h
file.$(OBJEXT): $(top_srcdir)/internal/dir.h
file.$(OBJEXT): $(top_srcdir)/internal/encoding.h
file.$(OBJEXT): $(top_srcdir)/internal/error.h
file.$(OBJEXT): $(top_srcdir)/internal/file.h
file.$(OBJEXT): $(top_srcdir)/internal/gc.h
@ -5854,6 +5875,7 @@ gc.$(OBJEXT): {$(VPATH)}darray.h
gc.$(OBJEXT): {$(VPATH)}debug.h
gc.$(OBJEXT): {$(VPATH)}debug_counter.h
gc.$(OBJEXT): {$(VPATH)}defines.h
gc.$(OBJEXT): {$(VPATH)}encindex.h
gc.$(OBJEXT): {$(VPATH)}encoding.h
gc.$(OBJEXT): {$(VPATH)}eval_intern.h
gc.$(OBJEXT): {$(VPATH)}gc.c
@ -6362,6 +6384,7 @@ hash.$(OBJEXT): {$(VPATH)}config.h
hash.$(OBJEXT): {$(VPATH)}constant.h
hash.$(OBJEXT): {$(VPATH)}debug_counter.h
hash.$(OBJEXT): {$(VPATH)}defines.h
hash.$(OBJEXT): {$(VPATH)}encindex.h
hash.$(OBJEXT): {$(VPATH)}encoding.h
hash.$(OBJEXT): {$(VPATH)}hash.c
hash.$(OBJEXT): {$(VPATH)}hash.rbinc
@ -6563,6 +6586,7 @@ imemo.$(OBJEXT): $(top_srcdir)/internal/serial.h
imemo.$(OBJEXT): $(top_srcdir)/internal/set_table.h
imemo.$(OBJEXT): $(top_srcdir)/internal/st.h
imemo.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
imemo.$(OBJEXT): $(top_srcdir)/internal/struct.h
imemo.$(OBJEXT): $(top_srcdir)/internal/variable.h
imemo.$(OBJEXT): $(top_srcdir)/internal/vm.h
imemo.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -6948,6 +6972,7 @@ io.$(OBJEXT): $(top_srcdir)/internal/serial.h
io.$(OBJEXT): $(top_srcdir)/internal/set_table.h
io.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
io.$(OBJEXT): $(top_srcdir)/internal/string.h
io.$(OBJEXT): $(top_srcdir)/internal/struct.h
io.$(OBJEXT): $(top_srcdir)/internal/thread.h
io.$(OBJEXT): $(top_srcdir)/internal/transcode.h
io.$(OBJEXT): $(top_srcdir)/internal/variable.h
@ -7190,6 +7215,7 @@ io_buffer.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
io_buffer.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
io_buffer.$(OBJEXT): {$(VPATH)}config.h
io_buffer.$(OBJEXT): {$(VPATH)}defines.h
io_buffer.$(OBJEXT): {$(VPATH)}encindex.h
io_buffer.$(OBJEXT): {$(VPATH)}encoding.h
io_buffer.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
io_buffer.$(OBJEXT): {$(VPATH)}id.h
@ -7396,6 +7422,7 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/serial.h
iseq.$(OBJEXT): $(top_srcdir)/internal/set_table.h
iseq.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
iseq.$(OBJEXT): $(top_srcdir)/internal/string.h
iseq.$(OBJEXT): $(top_srcdir)/internal/struct.h
iseq.$(OBJEXT): $(top_srcdir)/internal/symbol.h
iseq.$(OBJEXT): $(top_srcdir)/internal/thread.h
iseq.$(OBJEXT): $(top_srcdir)/internal/variable.h
@ -7440,6 +7467,7 @@ iseq.$(OBJEXT): {$(VPATH)}config.h
iseq.$(OBJEXT): {$(VPATH)}constant.h
iseq.$(OBJEXT): {$(VPATH)}debug_counter.h
iseq.$(OBJEXT): {$(VPATH)}defines.h
iseq.$(OBJEXT): {$(VPATH)}encindex.h
iseq.$(OBJEXT): {$(VPATH)}encoding.h
iseq.$(OBJEXT): {$(VPATH)}eval_intern.h
iseq.$(OBJEXT): {$(VPATH)}id.h
@ -7645,6 +7673,7 @@ jit.$(OBJEXT): $(top_srcdir)/internal/serial.h
jit.$(OBJEXT): $(top_srcdir)/internal/set_table.h
jit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
jit.$(OBJEXT): $(top_srcdir)/internal/string.h
jit.$(OBJEXT): $(top_srcdir)/internal/struct.h
jit.$(OBJEXT): $(top_srcdir)/internal/variable.h
jit.$(OBJEXT): $(top_srcdir)/internal/vm.h
jit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -7687,6 +7716,7 @@ jit.$(OBJEXT): {$(VPATH)}config.h
jit.$(OBJEXT): {$(VPATH)}constant.h
jit.$(OBJEXT): {$(VPATH)}debug_counter.h
jit.$(OBJEXT): {$(VPATH)}defines.h
jit.$(OBJEXT): {$(VPATH)}encindex.h
jit.$(OBJEXT): {$(VPATH)}encoding.h
jit.$(OBJEXT): {$(VPATH)}id.h
jit.$(OBJEXT): {$(VPATH)}id_table.h
@ -7897,6 +7927,7 @@ load.$(OBJEXT): $(top_srcdir)/internal/serial.h
load.$(OBJEXT): $(top_srcdir)/internal/set_table.h
load.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
load.$(OBJEXT): $(top_srcdir)/internal/string.h
load.$(OBJEXT): $(top_srcdir)/internal/struct.h
load.$(OBJEXT): $(top_srcdir)/internal/thread.h
load.$(OBJEXT): $(top_srcdir)/internal/variable.h
load.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -7940,6 +7971,7 @@ load.$(OBJEXT): {$(VPATH)}constant.h
load.$(OBJEXT): {$(VPATH)}darray.h
load.$(OBJEXT): {$(VPATH)}defines.h
load.$(OBJEXT): {$(VPATH)}dln.h
load.$(OBJEXT): {$(VPATH)}encindex.h
load.$(OBJEXT): {$(VPATH)}encoding.h
load.$(OBJEXT): {$(VPATH)}eval_intern.h
load.$(OBJEXT): {$(VPATH)}id.h
@ -9035,6 +9067,7 @@ memory_view.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/serial.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/set_table.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/struct.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/variable.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/vm.h
memory_view.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -9252,6 +9285,7 @@ miniinit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/serial.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/set_table.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/struct.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/variable.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/vm.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -9508,6 +9542,7 @@ node.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
node.$(OBJEXT): $(top_srcdir)/internal/serial.h
node.$(OBJEXT): $(top_srcdir)/internal/set_table.h
node.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
node.$(OBJEXT): $(top_srcdir)/internal/struct.h
node.$(OBJEXT): $(top_srcdir)/internal/variable.h
node.$(OBJEXT): $(top_srcdir)/internal/vm.h
node.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -9722,6 +9757,7 @@ node_dump.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/set_table.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/struct.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/vm.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -9939,6 +9975,7 @@ numeric.$(OBJEXT): $(top_srcdir)/internal/serial.h
numeric.$(OBJEXT): $(top_srcdir)/internal/set_table.h
numeric.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
numeric.$(OBJEXT): $(top_srcdir)/internal/string.h
numeric.$(OBJEXT): $(top_srcdir)/internal/struct.h
numeric.$(OBJEXT): $(top_srcdir)/internal/util.h
numeric.$(OBJEXT): $(top_srcdir)/internal/variable.h
numeric.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -9958,6 +9995,7 @@ numeric.$(OBJEXT): {$(VPATH)}builtin.h
numeric.$(OBJEXT): {$(VPATH)}config.h
numeric.$(OBJEXT): {$(VPATH)}constant.h
numeric.$(OBJEXT): {$(VPATH)}defines.h
numeric.$(OBJEXT): {$(VPATH)}encindex.h
numeric.$(OBJEXT): {$(VPATH)}encoding.h
numeric.$(OBJEXT): {$(VPATH)}id.h
numeric.$(OBJEXT): {$(VPATH)}id_table.h
@ -10179,6 +10217,7 @@ object.$(OBJEXT): {$(VPATH)}config.h
object.$(OBJEXT): {$(VPATH)}constant.h
object.$(OBJEXT): {$(VPATH)}debug_counter.h
object.$(OBJEXT): {$(VPATH)}defines.h
object.$(OBJEXT): {$(VPATH)}encindex.h
object.$(OBJEXT): {$(VPATH)}encoding.h
object.$(OBJEXT): {$(VPATH)}id.h
object.$(OBJEXT): {$(VPATH)}id_table.h
@ -10377,6 +10416,7 @@ pack.$(OBJEXT): $(top_srcdir)/internal/serial.h
pack.$(OBJEXT): $(top_srcdir)/internal/set_table.h
pack.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
pack.$(OBJEXT): $(top_srcdir)/internal/string.h
pack.$(OBJEXT): $(top_srcdir)/internal/struct.h
pack.$(OBJEXT): $(top_srcdir)/internal/symbol.h
pack.$(OBJEXT): $(top_srcdir)/internal/variable.h
pack.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -10396,6 +10436,7 @@ pack.$(OBJEXT): {$(VPATH)}builtin.h
pack.$(OBJEXT): {$(VPATH)}config.h
pack.$(OBJEXT): {$(VPATH)}constant.h
pack.$(OBJEXT): {$(VPATH)}defines.h
pack.$(OBJEXT): {$(VPATH)}encindex.h
pack.$(OBJEXT): {$(VPATH)}encoding.h
pack.$(OBJEXT): {$(VPATH)}id.h
pack.$(OBJEXT): {$(VPATH)}id_table.h
@ -10601,6 +10642,7 @@ parse.$(OBJEXT): $(top_srcdir)/internal/serial.h
parse.$(OBJEXT): $(top_srcdir)/internal/set_table.h
parse.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
parse.$(OBJEXT): $(top_srcdir)/internal/string.h
parse.$(OBJEXT): $(top_srcdir)/internal/struct.h
parse.$(OBJEXT): $(top_srcdir)/internal/symbol.h
parse.$(OBJEXT): $(top_srcdir)/internal/thread.h
parse.$(OBJEXT): $(top_srcdir)/internal/variable.h
@ -10621,6 +10663,7 @@ parse.$(OBJEXT): {$(VPATH)}config.h
parse.$(OBJEXT): {$(VPATH)}constant.h
parse.$(OBJEXT): {$(VPATH)}defines.h
parse.$(OBJEXT): {$(VPATH)}defs/keywords
parse.$(OBJEXT): {$(VPATH)}encindex.h
parse.$(OBJEXT): {$(VPATH)}encoding.h
parse.$(OBJEXT): {$(VPATH)}id.h
parse.$(OBJEXT): {$(VPATH)}id_table.h
@ -12059,6 +12102,7 @@ proc.$(OBJEXT): $(top_srcdir)/internal/serial.h
proc.$(OBJEXT): $(top_srcdir)/internal/set_table.h
proc.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
proc.$(OBJEXT): $(top_srcdir)/internal/string.h
proc.$(OBJEXT): $(top_srcdir)/internal/struct.h
proc.$(OBJEXT): $(top_srcdir)/internal/symbol.h
proc.$(OBJEXT): $(top_srcdir)/internal/variable.h
proc.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -12101,6 +12145,7 @@ proc.$(OBJEXT): {$(VPATH)}config.h
proc.$(OBJEXT): {$(VPATH)}constant.h
proc.$(OBJEXT): {$(VPATH)}debug_counter.h
proc.$(OBJEXT): {$(VPATH)}defines.h
proc.$(OBJEXT): {$(VPATH)}encindex.h
proc.$(OBJEXT): {$(VPATH)}encoding.h
proc.$(OBJEXT): {$(VPATH)}eval_intern.h
proc.$(OBJEXT): {$(VPATH)}id.h
@ -12310,6 +12355,7 @@ process.$(OBJEXT): $(top_srcdir)/internal/serial.h
process.$(OBJEXT): $(top_srcdir)/internal/set_table.h
process.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
process.$(OBJEXT): $(top_srcdir)/internal/string.h
process.$(OBJEXT): $(top_srcdir)/internal/struct.h
process.$(OBJEXT): $(top_srcdir)/internal/thread.h
process.$(OBJEXT): $(top_srcdir)/internal/time.h
process.$(OBJEXT): $(top_srcdir)/internal/variable.h
@ -12331,6 +12377,7 @@ process.$(OBJEXT): {$(VPATH)}constant.h
process.$(OBJEXT): {$(VPATH)}debug_counter.h
process.$(OBJEXT): {$(VPATH)}defines.h
process.$(OBJEXT): {$(VPATH)}dln.h
process.$(OBJEXT): {$(VPATH)}encindex.h
process.$(OBJEXT): {$(VPATH)}encoding.h
process.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
process.$(OBJEXT): {$(VPATH)}hrtime.h
@ -12560,6 +12607,7 @@ ractor.$(OBJEXT): {$(VPATH)}config.h
ractor.$(OBJEXT): {$(VPATH)}constant.h
ractor.$(OBJEXT): {$(VPATH)}debug_counter.h
ractor.$(OBJEXT): {$(VPATH)}defines.h
ractor.$(OBJEXT): {$(VPATH)}encindex.h
ractor.$(OBJEXT): {$(VPATH)}encoding.h
ractor.$(OBJEXT): {$(VPATH)}eval_intern.h
ractor.$(OBJEXT): {$(VPATH)}id.h
@ -12765,6 +12813,7 @@ random.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
random.$(OBJEXT): $(top_srcdir)/internal/serial.h
random.$(OBJEXT): $(top_srcdir)/internal/set_table.h
random.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
random.$(OBJEXT): $(top_srcdir)/internal/struct.h
random.$(OBJEXT): $(top_srcdir)/internal/variable.h
random.$(OBJEXT): $(top_srcdir)/internal/vm.h
random.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -12992,6 +13041,7 @@ range.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
range.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
range.$(OBJEXT): {$(VPATH)}config.h
range.$(OBJEXT): {$(VPATH)}defines.h
range.$(OBJEXT): {$(VPATH)}encindex.h
range.$(OBJEXT): {$(VPATH)}encoding.h
range.$(OBJEXT): {$(VPATH)}id.h
range.$(OBJEXT): {$(VPATH)}id_table.h
@ -13378,6 +13428,7 @@ re.$(OBJEXT): $(top_srcdir)/internal/box.h
re.$(OBJEXT): $(top_srcdir)/internal/class.h
re.$(OBJEXT): $(top_srcdir)/internal/compilers.h
re.$(OBJEXT): $(top_srcdir)/internal/encoding.h
re.$(OBJEXT): $(top_srcdir)/internal/error.h
re.$(OBJEXT): $(top_srcdir)/internal/gc.h
re.$(OBJEXT): $(top_srcdir)/internal/hash.h
re.$(OBJEXT): $(top_srcdir)/internal/imemo.h
@ -13389,6 +13440,7 @@ re.$(OBJEXT): $(top_srcdir)/internal/serial.h
re.$(OBJEXT): $(top_srcdir)/internal/set_table.h
re.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
re.$(OBJEXT): $(top_srcdir)/internal/string.h
re.$(OBJEXT): $(top_srcdir)/internal/struct.h
re.$(OBJEXT): $(top_srcdir)/internal/time.h
re.$(OBJEXT): $(top_srcdir)/internal/variable.h
re.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -14616,6 +14668,7 @@ ruby.$(OBJEXT): $(top_srcdir)/internal/serial.h
ruby.$(OBJEXT): $(top_srcdir)/internal/set_table.h
ruby.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
ruby.$(OBJEXT): $(top_srcdir)/internal/string.h
ruby.$(OBJEXT): $(top_srcdir)/internal/struct.h
ruby.$(OBJEXT): $(top_srcdir)/internal/thread.h
ruby.$(OBJEXT): $(top_srcdir)/internal/variable.h
ruby.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -14659,6 +14712,7 @@ ruby.$(OBJEXT): {$(VPATH)}constant.h
ruby.$(OBJEXT): {$(VPATH)}debug_counter.h
ruby.$(OBJEXT): {$(VPATH)}defines.h
ruby.$(OBJEXT): {$(VPATH)}dln.h
ruby.$(OBJEXT): {$(VPATH)}encindex.h
ruby.$(OBJEXT): {$(VPATH)}encoding.h
ruby.$(OBJEXT): {$(VPATH)}eval_intern.h
ruby.$(OBJEXT): {$(VPATH)}id.h
@ -14867,6 +14921,7 @@ ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
ruby_parser.$(OBJEXT): {$(VPATH)}config.h
ruby_parser.$(OBJEXT): {$(VPATH)}defines.h
ruby_parser.$(OBJEXT): {$(VPATH)}encindex.h
ruby_parser.$(OBJEXT): {$(VPATH)}encoding.h
ruby_parser.$(OBJEXT): {$(VPATH)}intern.h
ruby_parser.$(OBJEXT): {$(VPATH)}internal.h
@ -15258,6 +15313,7 @@ set.$(OBJEXT): $(top_srcdir)/internal/serial.h
set.$(OBJEXT): $(top_srcdir)/internal/set_table.h
set.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
set.$(OBJEXT): $(top_srcdir)/internal/string.h
set.$(OBJEXT): $(top_srcdir)/internal/struct.h
set.$(OBJEXT): $(top_srcdir)/internal/symbol.h
set.$(OBJEXT): $(top_srcdir)/internal/variable.h
set.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -15276,6 +15332,7 @@ set.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
set.$(OBJEXT): {$(VPATH)}config.h
set.$(OBJEXT): {$(VPATH)}constant.h
set.$(OBJEXT): {$(VPATH)}defines.h
set.$(OBJEXT): {$(VPATH)}encindex.h
set.$(OBJEXT): {$(VPATH)}encoding.h
set.$(OBJEXT): {$(VPATH)}id.h
set.$(OBJEXT): {$(VPATH)}id_table.h
@ -15648,6 +15705,7 @@ shape.$(OBJEXT): {$(VPATH)}config.h
shape.$(OBJEXT): {$(VPATH)}constant.h
shape.$(OBJEXT): {$(VPATH)}debug_counter.h
shape.$(OBJEXT): {$(VPATH)}defines.h
shape.$(OBJEXT): {$(VPATH)}encindex.h
shape.$(OBJEXT): {$(VPATH)}encoding.h
shape.$(OBJEXT): {$(VPATH)}id.h
shape.$(OBJEXT): {$(VPATH)}id_table.h
@ -15862,6 +15920,7 @@ signal.$(OBJEXT): {$(VPATH)}config.h
signal.$(OBJEXT): {$(VPATH)}constant.h
signal.$(OBJEXT): {$(VPATH)}debug_counter.h
signal.$(OBJEXT): {$(VPATH)}defines.h
signal.$(OBJEXT): {$(VPATH)}encindex.h
signal.$(OBJEXT): {$(VPATH)}encoding.h
signal.$(OBJEXT): {$(VPATH)}eval_intern.h
signal.$(OBJEXT): {$(VPATH)}id.h
@ -16071,6 +16130,7 @@ sprintf.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
sprintf.$(OBJEXT): {$(VPATH)}config.h
sprintf.$(OBJEXT): {$(VPATH)}constant.h
sprintf.$(OBJEXT): {$(VPATH)}defines.h
sprintf.$(OBJEXT): {$(VPATH)}encindex.h
sprintf.$(OBJEXT): {$(VPATH)}encoding.h
sprintf.$(OBJEXT): {$(VPATH)}id.h
sprintf.$(OBJEXT): {$(VPATH)}id_table.h
@ -16427,6 +16487,7 @@ strftime.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
strftime.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
strftime.$(OBJEXT): {$(VPATH)}config.h
strftime.$(OBJEXT): {$(VPATH)}defines.h
strftime.$(OBJEXT): {$(VPATH)}encindex.h
strftime.$(OBJEXT): {$(VPATH)}encoding.h
strftime.$(OBJEXT): {$(VPATH)}intern.h
strftime.$(OBJEXT): {$(VPATH)}internal.h
@ -16895,6 +16956,7 @@ struct.$(OBJEXT): {$(VPATH)}config.h
struct.$(OBJEXT): {$(VPATH)}constant.h
struct.$(OBJEXT): {$(VPATH)}debug_counter.h
struct.$(OBJEXT): {$(VPATH)}defines.h
struct.$(OBJEXT): {$(VPATH)}encindex.h
struct.$(OBJEXT): {$(VPATH)}encoding.h
struct.$(OBJEXT): {$(VPATH)}id.h
struct.$(OBJEXT): {$(VPATH)}id_table.h
@ -17108,8 +17170,10 @@ symbol.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
symbol.$(OBJEXT): {$(VPATH)}builtin.h
symbol.$(OBJEXT): {$(VPATH)}config.h
symbol.$(OBJEXT): {$(VPATH)}constant.h
symbol.$(OBJEXT): {$(VPATH)}darray.h
symbol.$(OBJEXT): {$(VPATH)}debug_counter.h
symbol.$(OBJEXT): {$(VPATH)}defines.h
symbol.$(OBJEXT): {$(VPATH)}encindex.h
symbol.$(OBJEXT): {$(VPATH)}encoding.h
symbol.$(OBJEXT): {$(VPATH)}id.c
symbol.$(OBJEXT): {$(VPATH)}id.h
@ -17320,6 +17384,7 @@ thread.$(OBJEXT): $(top_srcdir)/internal/set_table.h
thread.$(OBJEXT): $(top_srcdir)/internal/signal.h
thread.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
thread.$(OBJEXT): $(top_srcdir)/internal/string.h
thread.$(OBJEXT): $(top_srcdir)/internal/struct.h
thread.$(OBJEXT): $(top_srcdir)/internal/thread.h
thread.$(OBJEXT): $(top_srcdir)/internal/time.h
thread.$(OBJEXT): $(top_srcdir)/internal/variable.h
@ -17366,6 +17431,7 @@ thread.$(OBJEXT): {$(VPATH)}constant.h
thread.$(OBJEXT): {$(VPATH)}debug.h
thread.$(OBJEXT): {$(VPATH)}debug_counter.h
thread.$(OBJEXT): {$(VPATH)}defines.h
thread.$(OBJEXT): {$(VPATH)}encindex.h
thread.$(OBJEXT): {$(VPATH)}encoding.h
thread.$(OBJEXT): {$(VPATH)}eval_intern.h
thread.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
@ -17576,6 +17642,7 @@ time.$(OBJEXT): $(top_srcdir)/internal/serial.h
time.$(OBJEXT): $(top_srcdir)/internal/set_table.h
time.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
time.$(OBJEXT): $(top_srcdir)/internal/string.h
time.$(OBJEXT): $(top_srcdir)/internal/struct.h
time.$(OBJEXT): $(top_srcdir)/internal/time.h
time.$(OBJEXT): $(top_srcdir)/internal/variable.h
time.$(OBJEXT): $(top_srcdir)/internal/vm.h
@ -17595,6 +17662,7 @@ time.$(OBJEXT): {$(VPATH)}builtin.h
time.$(OBJEXT): {$(VPATH)}config.h
time.$(OBJEXT): {$(VPATH)}constant.h
time.$(OBJEXT): {$(VPATH)}defines.h
time.$(OBJEXT): {$(VPATH)}encindex.h
time.$(OBJEXT): {$(VPATH)}encoding.h
time.$(OBJEXT): {$(VPATH)}id.h
time.$(OBJEXT): {$(VPATH)}id_table.h
@ -17797,6 +17865,7 @@ transcode.$(OBJEXT): {$(VPATH)}config.h
transcode.$(OBJEXT): {$(VPATH)}constant.h
transcode.$(OBJEXT): {$(VPATH)}debug_counter.h
transcode.$(OBJEXT): {$(VPATH)}defines.h
transcode.$(OBJEXT): {$(VPATH)}encindex.h
transcode.$(OBJEXT): {$(VPATH)}encoding.h
transcode.$(OBJEXT): {$(VPATH)}id.h
transcode.$(OBJEXT): {$(VPATH)}id_table.h
@ -18178,6 +18247,7 @@ variable.$(OBJEXT): {$(VPATH)}config.h
variable.$(OBJEXT): {$(VPATH)}constant.h
variable.$(OBJEXT): {$(VPATH)}debug_counter.h
variable.$(OBJEXT): {$(VPATH)}defines.h
variable.$(OBJEXT): {$(VPATH)}encindex.h
variable.$(OBJEXT): {$(VPATH)}encoding.h
variable.$(OBJEXT): {$(VPATH)}id.h
variable.$(OBJEXT): {$(VPATH)}id_table.h
@ -18654,6 +18724,7 @@ vm.$(OBJEXT): {$(VPATH)}constant.h
vm.$(OBJEXT): {$(VPATH)}debug_counter.h
vm.$(OBJEXT): {$(VPATH)}defines.h
vm.$(OBJEXT): {$(VPATH)}defs/opt_operand.def
vm.$(OBJEXT): {$(VPATH)}encindex.h
vm.$(OBJEXT): {$(VPATH)}encoding.h
vm.$(OBJEXT): {$(VPATH)}eval_intern.h
vm.$(OBJEXT): {$(VPATH)}id.h
@ -18875,6 +18946,7 @@ vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/string.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/struct.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/variable.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/vm.h
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -18917,6 +18989,7 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}constant.h
vm_backtrace.$(OBJEXT): {$(VPATH)}debug.h
vm_backtrace.$(OBJEXT): {$(VPATH)}debug_counter.h
vm_backtrace.$(OBJEXT): {$(VPATH)}defines.h
vm_backtrace.$(OBJEXT): {$(VPATH)}encindex.h
vm_backtrace.$(OBJEXT): {$(VPATH)}encoding.h
vm_backtrace.$(OBJEXT): {$(VPATH)}eval_intern.h
vm_backtrace.$(OBJEXT): {$(VPATH)}id.h
@ -19108,6 +19181,7 @@ vm_dump.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/set_table.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/struct.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/vm.h
vm_dump.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -19555,6 +19629,7 @@ vm_trace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/struct.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/symbol.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/thread.h
vm_trace.$(OBJEXT): $(top_srcdir)/internal/variable.h
@ -20007,6 +20082,7 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
yjit.$(OBJEXT): $(top_srcdir)/internal/set_table.h
yjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
yjit.$(OBJEXT): $(top_srcdir)/internal/string.h
yjit.$(OBJEXT): $(top_srcdir)/internal/struct.h
yjit.$(OBJEXT): $(top_srcdir)/internal/variable.h
yjit.$(OBJEXT): $(top_srcdir)/internal/vm.h
yjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -20050,6 +20126,7 @@ yjit.$(OBJEXT): {$(VPATH)}constant.h
yjit.$(OBJEXT): {$(VPATH)}debug.h
yjit.$(OBJEXT): {$(VPATH)}debug_counter.h
yjit.$(OBJEXT): {$(VPATH)}defines.h
yjit.$(OBJEXT): {$(VPATH)}encindex.h
yjit.$(OBJEXT): {$(VPATH)}encoding.h
yjit.$(OBJEXT): {$(VPATH)}id.h
yjit.$(OBJEXT): {$(VPATH)}id_table.h
@ -20261,6 +20338,7 @@ zjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
zjit.$(OBJEXT): $(top_srcdir)/internal/set_table.h
zjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
zjit.$(OBJEXT): $(top_srcdir)/internal/string.h
zjit.$(OBJEXT): $(top_srcdir)/internal/struct.h
zjit.$(OBJEXT): $(top_srcdir)/internal/variable.h
zjit.$(OBJEXT): $(top_srcdir)/internal/vm.h
zjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@ -20304,6 +20382,7 @@ zjit.$(OBJEXT): {$(VPATH)}constant.h
zjit.$(OBJEXT): {$(VPATH)}debug.h
zjit.$(OBJEXT): {$(VPATH)}debug_counter.h
zjit.$(OBJEXT): {$(VPATH)}defines.h
zjit.$(OBJEXT): {$(VPATH)}encindex.h
zjit.$(OBJEXT): {$(VPATH)}encoding.h
zjit.$(OBJEXT): {$(VPATH)}id.h
zjit.$(OBJEXT): {$(VPATH)}id_table.h

14
dir.rb
View File

@ -31,7 +31,7 @@
# A \Dir object is in some ways array-like:
#
# - It has instance methods #children, #each, and #each_child.
# - It includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here].
# - It includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here].
#
# == \Dir As Stream-Like
#
@ -85,8 +85,8 @@
#
# First, what's elsewhere. Class \Dir:
#
# - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
# - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
# - Inherits from {class Object}[rdoc-ref:Object@Whats+Here].
# - Includes {module Enumerable}[rdoc-ref:Enumerable@Whats+Here],
# which provides dozens of additional methods.
#
# Here, class \Dir provides methods that are useful for:
@ -319,14 +319,14 @@ class Dir
#
# Dir.glob('io.?') # => ["io.c"]
#
# - <tt>'[_set_]'</tt>: Matches any one character in the string _set_;
# - <tt>'[set]'</tt>: Matches any one character in the string _set_;
# behaves like a {Regexp character class}[rdoc-ref:Regexp@Character+Classes],
# including set negation (<tt>'[^a-z]'</tt>):
#
# Dir.glob('*.[a-z][a-z]').take(3)
# # => ["CONTRIBUTING.md", "COPYING.ja", "KNOWNBUGS.rb"]
#
# - <tt>'{_abc_,_xyz_}'</tt>:
# - <tt>'{abc,xyz}'</tt>:
# Matches either string _abc_ or string _xyz_;
# behaves like {Regexp alternation}[rdoc-ref:Regexp@Alternation]:
#
@ -388,10 +388,10 @@ class Dir
#
# - File::FNM_EXTGLOB:
# enables the pattern extension
# <tt>'{_a_,_b_}'</tt>, which matches pattern _a_ and pattern _b_;
# <tt>'{a,b}'</tt>, which matches pattern _a_ and pattern _b_;
# behaves like a
# {regexp union}[rdoc-ref:Regexp.union]
# (e.g., <tt>'(?:_a_|_b_)'</tt>):
# (e.g., <tt>'(?:a|b)'</tt>):
#
# pattern = '{LEGAL,BSDL}'
# Dir.glob(pattern) # => ["LEGAL", "BSDL"]

802
doc/NEWS/NEWS-4.0.0.md Normal file
View File

@ -0,0 +1,802 @@
# NEWS for Ruby 4.0.0
This document is a list of user-visible feature changes
since the **3.4.0** release, except for bug fixes.
Note that each entry is kept to a minimum, see links for details.
## Language changes
* `*nil` no longer calls `nil.to_a`, similar to how `**nil` does
not call `nil.to_hash`. [[Feature #21047]]
* Logical binary operators (`||`, `&&`, `and` and `or`) at the
beginning of a line continue the previous line, like fluent dot.
The following code examples are equal:
```ruby
if condition1
&& condition2
...
end
```
Previously:
```ruby
if condition1 && condition2
...
end
```
```ruby
if condition1 &&
condition2
...
end
```
[[Feature #20925]]
## Core classes updates
Note: We're only listing outstanding class updates.
* Array
* `Array#rfind` has been added as a more efficient alternative to `array.reverse_each.find` [[Feature #21678]]
* `Array#find` has been added as a more efficient override of `Enumerable#find` [[Feature #21678]]
* Binding
* `Binding#local_variables` does no longer include numbered parameters.
Also, `Binding#local_variable_get`, `Binding#local_variable_set`, and
`Binding#local_variable_defined?` reject to handle numbered parameters.
[[Bug #21049]]
* `Binding#implicit_parameters`, `Binding#implicit_parameter_get`, and
`Binding#implicit_parameter_defined?` have been added to access
numbered parameters and "it" parameter. [[Bug #21049]]
* Enumerator
* `Enumerator.produce` now accepts an optional `size` keyword argument
to specify the size of the enumerator. It can be an integer,
`Float::INFINITY`, a callable object (such as a lambda), or `nil` to
indicate unknown size. When not specified, the size defaults to
`Float::INFINITY`.
```ruby
# Infinite enumerator
enum = Enumerator.produce(1, size: Float::INFINITY, &:succ)
enum.size # => Float::INFINITY
# Finite enumerator with known/computable size
abs_dir = File.expand_path("./baz") # => "/foo/bar/baz"
traverser = Enumerator.produce(abs_dir, size: -> { abs_dir.count("/") + 1 }) {
raise StopIteration if it == "/"
File.dirname(it)
}
traverser.size # => 4
```
[[Feature #21701]]
* ErrorHighlight
* When an ArgumentError is raised, it now displays code snippets for
both the method call (caller) and the method definition (callee).
[[Feature #21543]]
```
test.rb:1:in 'Object#add': wrong number of arguments (given 1, expected 2) (ArgumentError)
caller: test.rb:3
| add(1)
^^^
callee: test.rb:1
| def add(x, y) = x + y
^^^
from test.rb:3:in '<main>'
```
* Fiber
* Introduce support for `Fiber#raise(cause:)` argument similar to
`Kernel#raise`. [[Feature #21360]]
* Fiber::Scheduler
* Introduce `Fiber::Scheduler#fiber_interrupt` to interrupt a fiber with a
given exception. The initial use case is to interrupt a fiber that is
waiting on a blocking IO operation when the IO operation is closed.
[[Feature #21166]]
* Introduce `Fiber::Scheduler#yield` to allow the fiber scheduler to
continue processing when signal exceptions are disabled.
[[Bug #21633]]
* Reintroduce the `Fiber::Scheduler#io_close` hook for asynchronous `IO#close`.
* Invoke `Fiber::Scheduler#io_write` when flushing the IO write buffer.
[[Bug #21789]]
* File
* `File::Stat#birthtime` is now available on Linux via the statx
system call when supported by the kernel and filesystem.
[[Feature #21205]]
* IO
* `IO.select` accepts `Float::INFINITY` as a timeout argument.
[[Feature #20610]]
* A deprecated behavior, process creation by `IO` class methods
with a leading `|`, was removed. [[Feature #19630]]
* Kernel
* `Kernel#inspect` now checks for the existence of a `#instance_variables_to_inspect` method,
allowing control over which instance variables are displayed in the `#inspect` string:
```ruby
class DatabaseConfig
def initialize(host, user, password)
@host = host
@user = user
@password = password
end
private def instance_variables_to_inspect = [:@host, :@user]
end
conf = DatabaseConfig.new("localhost", "root", "hunter2")
conf.inspect #=> #<DatabaseConfig:0x0000000104def350 @host="localhost", @user="root">
```
[[Feature #21219]]
* A deprecated behavior, process creation by `Kernel#open` with a
leading `|`, was removed. [[Feature #19630]]
* Math
* `Math.log1p` and `Math.expm1` are added. [[Feature #21527]]
* Pathname
* Pathname has been promoted from a default gem to a core class of Ruby.
[[Feature #17473]]
* Proc
* `Proc#parameters` now shows anonymous optional parameters as `[:opt]`
instead of `[:opt, nil]`, making the output consistent with when the
anonymous parameter is required. [[Bug #20974]]
* Ractor
* `Ractor::Port` class was added for a new synchronization mechanism
to communicate between Ractors. [[Feature #21262]]
```ruby
port1 = Ractor::Port.new
port2 = Ractor::Port.new
Ractor.new port1, port2 do |port1, port2|
port1 << 1
port2 << 11
port1 << 2
port2 << 12
end
2.times{ p port1.receive } #=> 1, 2
2.times{ p port2.receive } #=> 11, 12
```
`Ractor::Port` provides the following methods:
* `Ractor::Port#receive`
* `Ractor::Port#send` (or `Ractor::Port#<<`)
* `Ractor::Port#close`
* `Ractor::Port#closed?`
As a result, `Ractor.yield` and `Ractor#take` were removed.
* `Ractor#join` and `Ractor#value` were added to wait for the
termination of a Ractor. These are similar to `Thread#join`
and `Thread#value`.
* `Ractor#monitor` and `Ractor#unmonitor` were added as low-level
interfaces used internally to implement `Ractor#join`.
* `Ractor.select` now only accepts Ractors and Ports. If Ractors are given,
it returns when a Ractor terminates.
* `Ractor#default_port` was added. Each `Ractor` has a default port,
which is used by `Ractor.send`, `Ractor.receive`.
* `Ractor#close_incoming` and `Ractor#close_outgoing` were removed.
* `Ractor.shareable_proc` and `Ractor.shareable_lambda` are introduced
to make shareable Proc or lambda.
[[Feature #21550]], [[Feature #21557]]
* Range
* `Range#to_set` now performs size checks to prevent issues with
endless ranges. [[Bug #21654]]
* `Range#overlap?` now correctly handles infinite (unbounded) ranges.
[[Bug #21185]]
* `Range#max` behavior on beginless integer ranges has been fixed.
[[Bug #21174]] [[Bug #21175]]
* Ruby
* A new toplevel module `Ruby` has been defined, which contains
Ruby-related constants. This module was reserved in Ruby 3.4
and is now officially defined. [[Feature #20884]]
* Ruby::Box
* A new (experimental) feature to provide separation about definitions.
For the detail of "Ruby Box", see [doc/language/box.md](doc/language/box.md).
[[Feature #21311]] [[Misc #21385]]
* Set
* `Set` is now a core class, instead of an autoloaded stdlib class.
[[Feature #21216]]
* `Set#inspect` now uses a simpler display, similar to literal arrays.
(e.g., `Set[1, 2, 3]` instead of `#<Set: {1, 2, 3}>`). [[Feature #21389]]
* Passing arguments to `Set#to_set` and `Enumerable#to_set` is now deprecated.
[[Feature #21390]]
* Socket
* `Socket.tcp` & `TCPSocket.new` accepts an `open_timeout` keyword argument to specify
the timeout for the initial connection. [[Feature #21347]]
* When a user-specified timeout occurred in `TCPSocket.new`, either `Errno::ETIMEDOUT`
or `IO::TimeoutError` could previously be raised depending on the situation.
This behavior has been unified so that `IO::TimeoutError` is now consistently raised.
(Please note that, in `Socket.tcp`, there are still cases where `Errno::ETIMEDOUT`
may be raised in similar situations, and that in both cases `Errno::ETIMEDOUT` may be
raised when the timeout occurs at the OS level.)
* String
* Update Unicode to Version 17.0.0 and Emoji Version 17.0.
[[Feature #19908]][[Feature #20724]][[Feature #21275]] (also applies to Regexp)
* `String#strip`, `strip!`, `lstrip`, `lstrip!`, `rstrip`, and `rstrip!`
are extended to accept `*selectors` arguments. [[Feature #21552]]
* Thread
* Introduce support for `Thread#raise(cause:)` argument similar to
`Kernel#raise`. [[Feature #21360]]
## Stdlib updates
We only list stdlib changes that are notable feature changes.
Other changes are listed in the following sections. We also listed release
history from the previous bundled version that is Ruby 3.4.0 if it has GitHub
releases.
The following bundled gems are promoted from default gems.
* ostruct 0.6.3
* 0.6.1 to [v0.6.2][ostruct-v0.6.2], [v0.6.3][ostruct-v0.6.3]
* pstore 0.2.0
* 0.1.4 to [v0.2.0][pstore-v0.2.0]
* benchmark 0.5.0
* 0.4.0 to [v0.4.1][benchmark-v0.4.1], [v0.5.0][benchmark-v0.5.0]
* logger 1.7.0
* 1.6.4 to [v1.6.5][logger-v1.6.5], [v1.6.6][logger-v1.6.6], [v1.7.0][logger-v1.7.0]
* rdoc 7.0.3
* 6.14.0 to [v6.14.1][rdoc-v6.14.1], [v6.14.2][rdoc-v6.14.2], [v6.15.0][rdoc-v6.15.0], [v6.15.1][rdoc-v6.15.1], [v6.16.0][rdoc-v6.16.0], [v6.16.1][rdoc-v6.16.1], [v6.17.0][rdoc-v6.17.0], [v7.0.0][rdoc-v7.0.0], [v7.0.1][rdoc-v7.0.1], [v7.0.2][rdoc-v7.0.2], [v7.0.3][rdoc-v7.0.3]
* win32ole 1.9.2
* 1.9.1 to [v1.9.2][win32ole-v1.9.2]
* irb 1.16.0
* 1.14.3 to [v1.15.0][irb-v1.15.0], [v1.15.1][irb-v1.15.1], [v1.15.2][irb-v1.15.2], [v1.15.3][irb-v1.15.3], [v1.16.0][irb-v1.16.0]
* reline 0.6.3
* 0.6.0 to [v0.6.1][reline-v0.6.1], [v0.6.2][reline-v0.6.2], [v0.6.3][reline-v0.6.3]
* readline 0.0.4
* fiddle 1.1.8
* 1.1.6 to [v1.1.7][fiddle-v1.1.7], [v1.1.8][fiddle-v1.1.8]
The following default gem is added.
* win32-registry 0.1.2
The following default gems are updated.
* RubyGems 4.0.3
* bundler 4.0.3
* date 3.5.1
* 3.4.1 to [v3.5.0][date-v3.5.0], [v3.5.1][date-v3.5.1]
* delegate 0.6.1
* 0.4.0 to [v0.5.0][delegate-v0.5.0], [v0.6.0][delegate-v0.6.0], [v0.6.1][delegate-v0.6.1]
* digest 3.2.1
* 3.2.0 to [v3.2.1][digest-v3.2.1]
* english 0.8.1
* 0.8.0 to [v0.8.1][english-v0.8.1]
* erb 6.0.1
* 4.0.4 to [v5.1.2][erb-v5.1.2], [v5.1.3][erb-v5.1.3], [v6.0.0][erb-v6.0.0], [v6.0.1][erb-v6.0.1]
* error_highlight 0.7.1
* etc 1.4.6
* fcntl 1.3.0
* 1.2.0 to [v1.3.0][fcntl-v1.3.0]
* fileutils 1.8.0
* 1.7.3 to [v1.8.0][fileutils-v1.8.0]
* forwardable 1.4.0
* 1.3.3 to [v1.4.0][forwardable-v1.4.0]
* io-console 0.8.2
* 0.8.1 to [v0.8.2][io-console-v0.8.2]
* io-nonblock 0.3.2
* io-wait 0.4.0
* 0.3.2 to [v0.3.3][io-wait-v0.3.3], [v0.3.5.test1][io-wait-v0.3.5.test1], [v0.3.5][io-wait-v0.3.5], [v0.3.6][io-wait-v0.3.6], [v0.4.0][io-wait-v0.4.0]
* ipaddr 1.2.8
* json 2.18.0
* 2.9.1 to [v2.10.0][json-v2.10.0], [v2.10.1][json-v2.10.1], [v2.10.2][json-v2.10.2], [v2.11.0][json-v2.11.0], [v2.11.1][json-v2.11.1], [v2.11.2][json-v2.11.2], [v2.11.3][json-v2.11.3], [v2.12.0][json-v2.12.0], [v2.12.1][json-v2.12.1], [v2.12.2][json-v2.12.2], [v2.13.0][json-v2.13.0], [v2.13.1][json-v2.13.1], [v2.13.2][json-v2.13.2], [v2.14.0][json-v2.14.0], [v2.14.1][json-v2.14.1], [v2.15.0][json-v2.15.0], [v2.15.1][json-v2.15.1], [v2.15.2][json-v2.15.2], [v2.16.0][json-v2.16.0], [v2.17.0][json-v2.17.0], [v2.17.1][json-v2.17.1], [v2.18.0][json-v2.18.0]
* net-http 0.9.1
* 0.6.0 to [v0.7.0][net-http-v0.7.0], [v0.8.0][net-http-v0.8.0], [v0.9.0][net-http-v0.9.0], [v0.9.1][net-http-v0.9.1]
* openssl 4.0.0
* 3.3.1 to [v3.3.2][openssl-v3.3.2], [v4.0.0][openssl-v4.0.0]
* optparse 0.8.1
* 0.6.0 to [v0.7.0][optparse-v0.7.0], [v0.8.0][optparse-v0.8.0], [v0.8.1][optparse-v0.8.1]
* pp 0.6.3
* 0.6.2 to [v0.6.3][pp-v0.6.3]
* prism 1.7.0
* 1.5.2 to [v1.6.0][prism-v1.6.0], [v1.7.0][prism-v1.7.0]
* psych 5.3.1
* 5.2.2 to [v5.2.3][psych-v5.2.3], [v5.2.4][psych-v5.2.4], [v5.2.5][psych-v5.2.5], [v5.2.6][psych-v5.2.6], [v5.3.0][psych-v5.3.0], [v5.3.1][psych-v5.3.1]
* resolv 0.7.0
* 0.6.2 to [v0.6.3][resolv-v0.6.3], [v0.7.0][resolv-v0.7.0]
* stringio 3.2.0
* 3.1.2 to [v3.1.3][stringio-v3.1.3], [v3.1.4][stringio-v3.1.4], [v3.1.5][stringio-v3.1.5], [v3.1.6][stringio-v3.1.6], [v3.1.7][stringio-v3.1.7], [v3.1.8][stringio-v3.1.8], [v3.1.9][stringio-v3.1.9], [v3.2.0][stringio-v3.2.0]
* strscan 3.1.6
* 3.1.2 to [v3.1.3][strscan-v3.1.3], [v3.1.4][strscan-v3.1.4], [v3.1.5][strscan-v3.1.5], [v3.1.6][strscan-v3.1.6]
* time 0.4.2
* 0.4.1 to [v0.4.2][time-v0.4.2]
* timeout 0.6.0
* 0.4.3 to [v0.4.4][timeout-v0.4.4], [v0.5.0][timeout-v0.5.0], [v0.6.0][timeout-v0.6.0]
* uri 1.1.1
* 1.0.4 to [v1.1.0][uri-v1.1.0], [v1.1.1][uri-v1.1.1]
* weakref 0.1.4
* 0.1.3 to [v0.1.4][weakref-v0.1.4]
* zlib 3.2.2
* 3.2.1 to [v3.2.2][zlib-v3.2.2]
The following bundled gems are updated.
* minitest 6.0.0
* power_assert 3.0.1
* 2.0.5 to [v3.0.0][power_assert-v3.0.0], [v3.0.1][power_assert-v3.0.1]
* rake 13.3.1
* 13.2.1 to [v13.3.0][rake-v13.3.0], [v13.3.1][rake-v13.3.1]
* test-unit 3.7.5
* 3.6.7 to [3.6.8][test-unit-3.6.8], [3.6.9][test-unit-3.6.9], [3.7.0][test-unit-3.7.0], [3.7.1][test-unit-3.7.1], [3.7.2][test-unit-3.7.2], [3.7.3][test-unit-3.7.3], [3.7.4][test-unit-3.7.4], [3.7.5][test-unit-3.7.5]
* rexml 3.4.4
* rss 0.3.2
* 0.3.1 to [0.3.2][rss-0.3.2]
* net-ftp 0.3.9
* 0.3.8 to [v0.3.9][net-ftp-v0.3.9]
* net-imap 0.6.2
* 0.5.8 to [v0.5.9][net-imap-v0.5.9], [v0.5.10][net-imap-v0.5.10], [v0.5.11][net-imap-v0.5.11], [v0.5.12][net-imap-v0.5.12], [v0.5.13][net-imap-v0.5.13], [v0.6.0][net-imap-v0.6.0], [v0.6.1][net-imap-v0.6.1], [v0.6.2][net-imap-v0.6.2]
* net-smtp 0.5.1
* 0.5.0 to [v0.5.1][net-smtp-v0.5.1]
* matrix 0.4.3
* 0.4.2 to [v0.4.3][matrix-v0.4.3]
* prime 0.1.4
* 0.1.3 to [v0.1.4][prime-v0.1.4]
* rbs 3.10.0
* 3.8.0 to [v3.8.1][rbs-v3.8.1], [v3.9.0.dev.1][rbs-v3.9.0.dev.1], [v3.9.0.pre.1][rbs-v3.9.0.pre.1], [v3.9.0.pre.2][rbs-v3.9.0.pre.2], [v3.9.0][rbs-v3.9.0], [v3.9.1][rbs-v3.9.1], [v3.9.2][rbs-v3.9.2], [v3.9.3][rbs-v3.9.3], [v3.9.4][rbs-v3.9.4], [v3.9.5][rbs-v3.9.5], [v3.10.0.pre.1][rbs-v3.10.0.pre.1], [v3.10.0.pre.2][rbs-v3.10.0.pre.2], [v3.10.0][rbs-v3.10.0]
* typeprof 0.31.1
* debug 1.11.1
* 1.11.0 to [v1.11.1][debug-v1.11.1]
* base64 0.3.0
* 0.2.0 to [v0.3.0][base64-v0.3.0]
* bigdecimal 4.0.1
* 3.1.8 to [v3.2.0][bigdecimal-v3.2.0], [v3.2.1][bigdecimal-v3.2.1], [v3.2.2][bigdecimal-v3.2.2], [v3.2.3][bigdecimal-v3.2.3], [v3.3.0][bigdecimal-v3.3.0], [v3.3.1][bigdecimal-v3.3.1], [v4.0.0][bigdecimal-v4.0.0], [v4.0.1][bigdecimal-v4.0.1]
* drb 2.2.3
* 2.2.1 to [v2.2.3][drb-v2.2.3]
* syslog 0.3.0
* 0.2.0 to [v0.3.0][syslog-v0.3.0]
* csv 3.3.5
* 3.3.2 to [v3.3.3][csv-v3.3.3], [v3.3.4][csv-v3.3.4], [v3.3.5][csv-v3.3.5]
* repl_type_completor 0.1.12
### RubyGems and Bundler
Ruby 4.0 bundled RubyGems and Bundler version 4. see the following links for details.
* [Upgrading to RubyGems/Bundler 4 - RubyGems Blog](https://blog.rubygems.org/2025/12/03/upgrade-to-rubygems-bundler-4.html)
* [4.0.0 Released - RubyGems Blog](https://blog.rubygems.org/2025/12/03/4.0.0-released.html)
* [4.0.1 Released - RubyGems Blog](https://blog.rubygems.org/2025/12/09/4.0.1-released.html)
* [4.0.2 Released - RubyGems Blog](https://blog.rubygems.org/2025/12/17/4.0.2-released.html)
* [4.0.3 Released - RubyGems Blog](https://blog.rubygems.org/2025/12/23/4.0.3-released.html)
## Supported platforms
* Windows
* Dropped support for MSVC versions older than 14.0 (_MSC_VER 1900).
This means Visual Studio 2015 or later is now required.
## Compatibility issues
* The following methods were removed from Ractor due to the addition of `Ractor::Port`:
* `Ractor.yield`
* `Ractor#take`
* `Ractor#close_incoming`
* `Ractor#close_outgoing`
[[Feature #21262]]
* `ObjectSpace._id2ref` is deprecated. [[Feature #15408]]
* `Process::Status#&` and `Process::Status#>>` have been removed.
They were deprecated in Ruby 3.3. [[Bug #19868]]
* `rb_path_check` has been removed. This function was used for
`$SAFE` path checking which was removed in Ruby 2.7,
and was already deprecated.
[[Feature #20971]]
* A backtrace for `ArgumentError` of "wrong number of arguments" now
include the receiver's class or module name (e.g., in `Foo#bar`
instead of in `bar`). [[Bug #21698]]
* Backtraces no longer display `internal` frames.
These methods now appear as if it is in the Ruby source file,
consistent with other C-implemented methods. [[Bug #20968]]
Before:
```
ruby -e '[1].fetch_values(42)'
<internal:array>:211:in 'Array#fetch': index 42 outside of array bounds: -1...1 (IndexError)
from <internal:array>:211:in 'block in Array#fetch_values'
from <internal:array>:211:in 'Array#map!'
from <internal:array>:211:in 'Array#fetch_values'
from -e:1:in '<main>'
```
After:
```
$ ruby -e '[1].fetch_values(42)'
-e:1:in 'Array#fetch_values': index 42 outside of array bounds: -1...1 (IndexError)
from -e:1:in '<main>'
```
## Stdlib compatibility issues
* CGI library is removed from the default gems. Now we only provide `cgi/escape` for
the following methods:
* `CGI.escape` and `CGI.unescape`
* `CGI.escapeHTML` and `CGI.unescapeHTML`
* `CGI.escapeURIComponent` and `CGI.unescapeURIComponent`
* `CGI.escapeElement` and `CGI.unescapeElement`
[[Feature #21258]]
* With the move of `Set` from stdlib to core class, `set/sorted_set.rb` has
been removed, and `SortedSet` is no longer an autoloaded constant. Please
install the `sorted_set` gem and `require 'sorted_set'` to use `SortedSet`.
[[Feature #21287]]
* Net::HTTP
* The default behavior of automatically setting the `Content-Type` header
to `application/x-www-form-urlencoded` for requests with a body
(e.g., `POST`, `PUT`) when the header was not explicitly set has been
removed. If your application relied on this automatic default, your
requests will now be sent without a Content-Type header, potentially
breaking compatibility with certain servers.
[[GH-net-http #205]]
## C API updates
* IO
* `rb_thread_fd_close` is deprecated and now a no-op. If you need to expose
file descriptors from C extensions to Ruby code, create an `IO` instance
using `RUBY_IO_MODE_EXTERNAL` and use `rb_io_close(io)` to close it (this
also interrupts and waits for all pending operations on the `IO`
instance). Directly closing file descriptors does not interrupt pending
operations, and may lead to undefined behaviour. In other words, if two
`IO` objects share the same file descriptor, closing one does not affect
the other. [[Feature #18455]]
* GVL
* `rb_thread_call_with_gvl` now works with or without the GVL.
This allows gems to avoid checking `ruby_thread_has_gvl_p`.
Please still be diligent about the GVL. [[Feature #20750]]
* Set
* A C API for `Set` has been added. The following methods are supported:
[[Feature #21459]]
* `rb_set_foreach`
* `rb_set_new`
* `rb_set_new_capa`
* `rb_set_lookup`
* `rb_set_add`
* `rb_set_clear`
* `rb_set_delete`
* `rb_set_size`
## Implementation improvements
* `Class#new` (ex. `Object.new`) is faster in all cases, but especially when passing keyword arguments. This has also been integrated into YJIT and ZJIT. [[Feature #21254]]
* GC heaps of different size pools now grow independently, reducing memory usage when only some pools contain long-lived objects
* GC sweeping is faster on pages of large objects
* "Generic ivar" objects (String, Array, `TypedData`, etc.) now use a new internal "fields" object for faster instance variable access
* The GC avoids maintaining an internal `id2ref` table until it is first used, making `object_id` allocation and GC sweeping faster
* `object_id` and `hash` are faster on Class and Module objects
* Larger bignum Integers can remain embedded using variable width allocation
* `Random`, `Enumerator::Product`, `Enumerator::Chain`, `Addrinfo`,
`StringScanner`, and some internal objects are now write-barrier protected,
which reduces GC overhead.
### Ractor
A lot of work has gone into making Ractors more stable, performant, and usable. These improvements bring Ractor implementation closer to leaving experimental status.
* Performance improvements
* Frozen strings and the symbol table internally use a lock-free hash set [[Feature #21268]]
* Method cache lookups avoid locking in most cases
* Class (and generic ivar) instance variable access is faster and avoids locking
* CPU cache contention is avoided in object allocation by using a per-ractor counter
* CPU cache contention is avoided in xmalloc/xfree by using a thread-local counter
* `object_id` avoids locking in most cases
* Bug fixes and stability
* Fixed possible deadlocks when combining Ractors and Threads
* Fixed issues with require and autoload in a Ractor
* Fixed encoding/transcoding issues across Ractors
* Fixed race conditions in GC operations and method invalidation
* Fixed issues with processes forking after starting a Ractor
* GC allocation counts are now accurate under Ractors
* Fixed TracePoints not working after GC [[Bug #19112]]
## JIT
* ZJIT
* Introduce an [experimental method-based JIT compiler](https://docs.ruby-lang.org/en/master/jit/zjit_md.html).
Where available, ZJIT can be enabled at runtime with the `--zjit` option or by calling `RubyVM::ZJIT.enable`.
When building Ruby, Rust 1.85.0 or later is required to include ZJIT support.
* As of Ruby 4.0.0, ZJIT is faster than the interpreter, but not yet as fast as YJIT.
We encourage experimentation with ZJIT, but advise against deploying it in production for now.
* Our goal is to make ZJIT faster than YJIT and production-ready in Ruby 4.1.
* YJIT
* `RubyVM::YJIT.runtime_stats`
* `ratio_in_yjit` no longer works in the default build.
Use `--enable-yjit=stats` on `configure` to enable it on `--yjit-stats`.
* Add `invalidate_everything` to default stats, which is
incremented when every code is invalidated by TracePoint.
* Add `mem_size:` and `call_threshold:` options to `RubyVM::YJIT.enable`.
* RJIT
* `--rjit` is removed. We will move the implementation of the third-party JIT API
to the [ruby/rjit](https://github.com/ruby/rjit) repository.
[Feature #15408]: https://bugs.ruby-lang.org/issues/15408
[Feature #17473]: https://bugs.ruby-lang.org/issues/17473
[Feature #18455]: https://bugs.ruby-lang.org/issues/18455
[Bug #19112]: https://bugs.ruby-lang.org/issues/19112
[Feature #19630]: https://bugs.ruby-lang.org/issues/19630
[Bug #19868]: https://bugs.ruby-lang.org/issues/19868
[Feature #19908]: https://bugs.ruby-lang.org/issues/19908
[Feature #20610]: https://bugs.ruby-lang.org/issues/20610
[Feature #20724]: https://bugs.ruby-lang.org/issues/20724
[Feature #20750]: https://bugs.ruby-lang.org/issues/20750
[Feature #20884]: https://bugs.ruby-lang.org/issues/20884
[Feature #20925]: https://bugs.ruby-lang.org/issues/20925
[Bug #20968]: https://bugs.ruby-lang.org/issues/20968
[Feature #20971]: https://bugs.ruby-lang.org/issues/20971
[Bug #20974]: https://bugs.ruby-lang.org/issues/20974
[Feature #21047]: https://bugs.ruby-lang.org/issues/21047
[Bug #21049]: https://bugs.ruby-lang.org/issues/21049
[Feature #21166]: https://bugs.ruby-lang.org/issues/21166
[Bug #21174]: https://bugs.ruby-lang.org/issues/21174
[Bug #21175]: https://bugs.ruby-lang.org/issues/21175
[Bug #21185]: https://bugs.ruby-lang.org/issues/21185
[Feature #21205]: https://bugs.ruby-lang.org/issues/21205
[Feature #21216]: https://bugs.ruby-lang.org/issues/21216
[Feature #21219]: https://bugs.ruby-lang.org/issues/21219
[Feature #21254]: https://bugs.ruby-lang.org/issues/21254
[Feature #21258]: https://bugs.ruby-lang.org/issues/21258
[Feature #21268]: https://bugs.ruby-lang.org/issues/21268
[Feature #21262]: https://bugs.ruby-lang.org/issues/21262
[Feature #21275]: https://bugs.ruby-lang.org/issues/21275
[Feature #21287]: https://bugs.ruby-lang.org/issues/21287
[Feature #21311]: https://bugs.ruby-lang.org/issues/21311
[Feature #21347]: https://bugs.ruby-lang.org/issues/21347
[Feature #21360]: https://bugs.ruby-lang.org/issues/21360
[Misc #21385]: https://bugs.ruby-lang.org/issues/21385
[Feature #21389]: https://bugs.ruby-lang.org/issues/21389
[Feature #21390]: https://bugs.ruby-lang.org/issues/21390
[Feature #21459]: https://bugs.ruby-lang.org/issues/21459
[Feature #21527]: https://bugs.ruby-lang.org/issues/21527
[Feature #21543]: https://bugs.ruby-lang.org/issues/21543
[Feature #21550]: https://bugs.ruby-lang.org/issues/21550
[Feature #21552]: https://bugs.ruby-lang.org/issues/21552
[Feature #21557]: https://bugs.ruby-lang.org/issues/21557
[Bug #21633]: https://bugs.ruby-lang.org/issues/21633
[Bug #21654]: https://bugs.ruby-lang.org/issues/21654
[Feature #21678]: https://bugs.ruby-lang.org/issues/21678
[Bug #21698]: https://bugs.ruby-lang.org/issues/21698
[Feature #21701]: https://bugs.ruby-lang.org/issues/21701
[Bug #21789]: https://bugs.ruby-lang.org/issues/21789
[GH-net-http #205]: https://github.com/ruby/net-http/issues/205
[ostruct-v0.6.2]: https://github.com/ruby/ostruct/releases/tag/v0.6.2
[ostruct-v0.6.3]: https://github.com/ruby/ostruct/releases/tag/v0.6.3
[pstore-v0.2.0]: https://github.com/ruby/pstore/releases/tag/v0.2.0
[benchmark-v0.4.1]: https://github.com/ruby/benchmark/releases/tag/v0.4.1
[benchmark-v0.5.0]: https://github.com/ruby/benchmark/releases/tag/v0.5.0
[logger-v1.6.5]: https://github.com/ruby/logger/releases/tag/v1.6.5
[logger-v1.6.6]: https://github.com/ruby/logger/releases/tag/v1.6.6
[logger-v1.7.0]: https://github.com/ruby/logger/releases/tag/v1.7.0
[rdoc-v6.14.1]: https://github.com/ruby/rdoc/releases/tag/v6.14.1
[rdoc-v6.14.2]: https://github.com/ruby/rdoc/releases/tag/v6.14.2
[rdoc-v6.15.0]: https://github.com/ruby/rdoc/releases/tag/v6.15.0
[rdoc-v6.15.1]: https://github.com/ruby/rdoc/releases/tag/v6.15.1
[rdoc-v6.16.0]: https://github.com/ruby/rdoc/releases/tag/v6.16.0
[rdoc-v6.16.1]: https://github.com/ruby/rdoc/releases/tag/v6.16.1
[rdoc-v6.17.0]: https://github.com/ruby/rdoc/releases/tag/v6.17.0
[rdoc-v7.0.0]: https://github.com/ruby/rdoc/releases/tag/v7.0.0
[rdoc-v7.0.1]: https://github.com/ruby/rdoc/releases/tag/v7.0.1
[rdoc-v7.0.2]: https://github.com/ruby/rdoc/releases/tag/v7.0.2
[rdoc-v7.0.3]: https://github.com/ruby/rdoc/releases/tag/v7.0.3
[win32ole-v1.9.2]: https://github.com/ruby/win32ole/releases/tag/v1.9.2
[irb-v1.15.0]: https://github.com/ruby/irb/releases/tag/v1.15.0
[irb-v1.15.1]: https://github.com/ruby/irb/releases/tag/v1.15.1
[irb-v1.15.2]: https://github.com/ruby/irb/releases/tag/v1.15.2
[irb-v1.15.3]: https://github.com/ruby/irb/releases/tag/v1.15.3
[irb-v1.16.0]: https://github.com/ruby/irb/releases/tag/v1.16.0
[reline-v0.6.1]: https://github.com/ruby/reline/releases/tag/v0.6.1
[reline-v0.6.2]: https://github.com/ruby/reline/releases/tag/v0.6.2
[reline-v0.6.3]: https://github.com/ruby/reline/releases/tag/v0.6.3
[fiddle-v1.1.7]: https://github.com/ruby/fiddle/releases/tag/v1.1.7
[fiddle-v1.1.8]: https://github.com/ruby/fiddle/releases/tag/v1.1.8
[date-v3.5.0]: https://github.com/ruby/date/releases/tag/v3.5.0
[date-v3.5.1]: https://github.com/ruby/date/releases/tag/v3.5.1
[delegate-v0.5.0]: https://github.com/ruby/delegate/releases/tag/v0.5.0
[delegate-v0.6.0]: https://github.com/ruby/delegate/releases/tag/v0.6.0
[delegate-v0.6.1]: https://github.com/ruby/delegate/releases/tag/v0.6.1
[digest-v3.2.1]: https://github.com/ruby/digest/releases/tag/v3.2.1
[english-v0.8.1]: https://github.com/ruby/english/releases/tag/v0.8.1
[erb-v5.1.2]: https://github.com/ruby/erb/releases/tag/v5.1.2
[erb-v5.1.3]: https://github.com/ruby/erb/releases/tag/v5.1.3
[erb-v6.0.0]: https://github.com/ruby/erb/releases/tag/v6.0.0
[erb-v6.0.1]: https://github.com/ruby/erb/releases/tag/v6.0.1
[fcntl-v1.3.0]: https://github.com/ruby/fcntl/releases/tag/v1.3.0
[fileutils-v1.8.0]: https://github.com/ruby/fileutils/releases/tag/v1.8.0
[forwardable-v1.4.0]: https://github.com/ruby/forwardable/releases/tag/v1.4.0
[io-console-v0.8.2]: https://github.com/ruby/io-console/releases/tag/v0.8.2
[io-wait-v0.3.3]: https://github.com/ruby/io-wait/releases/tag/v0.3.3
[io-wait-v0.3.5.test1]: https://github.com/ruby/io-wait/releases/tag/v0.3.5.test1
[io-wait-v0.3.5]: https://github.com/ruby/io-wait/releases/tag/v0.3.5
[io-wait-v0.3.6]: https://github.com/ruby/io-wait/releases/tag/v0.3.6
[io-wait-v0.4.0]: https://github.com/ruby/io-wait/releases/tag/v0.4.0
[json-v2.10.0]: https://github.com/ruby/json/releases/tag/v2.10.0
[json-v2.10.1]: https://github.com/ruby/json/releases/tag/v2.10.1
[json-v2.10.2]: https://github.com/ruby/json/releases/tag/v2.10.2
[json-v2.11.0]: https://github.com/ruby/json/releases/tag/v2.11.0
[json-v2.11.1]: https://github.com/ruby/json/releases/tag/v2.11.1
[json-v2.11.2]: https://github.com/ruby/json/releases/tag/v2.11.2
[json-v2.11.3]: https://github.com/ruby/json/releases/tag/v2.11.3
[json-v2.12.0]: https://github.com/ruby/json/releases/tag/v2.12.0
[json-v2.12.1]: https://github.com/ruby/json/releases/tag/v2.12.1
[json-v2.12.2]: https://github.com/ruby/json/releases/tag/v2.12.2
[json-v2.13.0]: https://github.com/ruby/json/releases/tag/v2.13.0
[json-v2.13.1]: https://github.com/ruby/json/releases/tag/v2.13.1
[json-v2.13.2]: https://github.com/ruby/json/releases/tag/v2.13.2
[json-v2.14.0]: https://github.com/ruby/json/releases/tag/v2.14.0
[json-v2.14.1]: https://github.com/ruby/json/releases/tag/v2.14.1
[json-v2.15.0]: https://github.com/ruby/json/releases/tag/v2.15.0
[json-v2.15.1]: https://github.com/ruby/json/releases/tag/v2.15.1
[json-v2.15.2]: https://github.com/ruby/json/releases/tag/v2.15.2
[json-v2.16.0]: https://github.com/ruby/json/releases/tag/v2.16.0
[json-v2.17.0]: https://github.com/ruby/json/releases/tag/v2.17.0
[json-v2.17.1]: https://github.com/ruby/json/releases/tag/v2.17.1
[json-v2.18.0]: https://github.com/ruby/json/releases/tag/v2.18.0
[net-http-v0.7.0]: https://github.com/ruby/net-http/releases/tag/v0.7.0
[net-http-v0.8.0]: https://github.com/ruby/net-http/releases/tag/v0.8.0
[net-http-v0.9.0]: https://github.com/ruby/net-http/releases/tag/v0.9.0
[net-http-v0.9.1]: https://github.com/ruby/net-http/releases/tag/v0.9.1
[openssl-v3.3.2]: https://github.com/ruby/openssl/releases/tag/v3.3.2
[openssl-v4.0.0]: https://github.com/ruby/openssl/releases/tag/v4.0.0
[optparse-v0.7.0]: https://github.com/ruby/optparse/releases/tag/v0.7.0
[optparse-v0.8.0]: https://github.com/ruby/optparse/releases/tag/v0.8.0
[optparse-v0.8.1]: https://github.com/ruby/optparse/releases/tag/v0.8.1
[pp-v0.6.3]: https://github.com/ruby/pp/releases/tag/v0.6.3
[prism-v1.6.0]: https://github.com/ruby/prism/releases/tag/v1.6.0
[prism-v1.7.0]: https://github.com/ruby/prism/releases/tag/v1.7.0
[psych-v5.2.3]: https://github.com/ruby/psych/releases/tag/v5.2.3
[psych-v5.2.4]: https://github.com/ruby/psych/releases/tag/v5.2.4
[psych-v5.2.5]: https://github.com/ruby/psych/releases/tag/v5.2.5
[psych-v5.2.6]: https://github.com/ruby/psych/releases/tag/v5.2.6
[psych-v5.3.0]: https://github.com/ruby/psych/releases/tag/v5.3.0
[psych-v5.3.1]: https://github.com/ruby/psych/releases/tag/v5.3.1
[resolv-v0.6.3]: https://github.com/ruby/resolv/releases/tag/v0.6.3
[resolv-v0.7.0]: https://github.com/ruby/resolv/releases/tag/v0.7.0
[stringio-v3.1.3]: https://github.com/ruby/stringio/releases/tag/v3.1.3
[stringio-v3.1.4]: https://github.com/ruby/stringio/releases/tag/v3.1.4
[stringio-v3.1.5]: https://github.com/ruby/stringio/releases/tag/v3.1.5
[stringio-v3.1.6]: https://github.com/ruby/stringio/releases/tag/v3.1.6
[stringio-v3.1.7]: https://github.com/ruby/stringio/releases/tag/v3.1.7
[stringio-v3.1.8]: https://github.com/ruby/stringio/releases/tag/v3.1.8
[stringio-v3.1.9]: https://github.com/ruby/stringio/releases/tag/v3.1.9
[stringio-v3.2.0]: https://github.com/ruby/stringio/releases/tag/v3.2.0
[strscan-v3.1.3]: https://github.com/ruby/strscan/releases/tag/v3.1.3
[strscan-v3.1.4]: https://github.com/ruby/strscan/releases/tag/v3.1.4
[strscan-v3.1.5]: https://github.com/ruby/strscan/releases/tag/v3.1.5
[strscan-v3.1.6]: https://github.com/ruby/strscan/releases/tag/v3.1.6
[time-v0.4.2]: https://github.com/ruby/time/releases/tag/v0.4.2
[timeout-v0.4.4]: https://github.com/ruby/timeout/releases/tag/v0.4.4
[timeout-v0.5.0]: https://github.com/ruby/timeout/releases/tag/v0.5.0
[timeout-v0.6.0]: https://github.com/ruby/timeout/releases/tag/v0.6.0
[uri-v1.1.0]: https://github.com/ruby/uri/releases/tag/v1.1.0
[uri-v1.1.1]: https://github.com/ruby/uri/releases/tag/v1.1.1
[weakref-v0.1.4]: https://github.com/ruby/weakref/releases/tag/v0.1.4
[zlib-v3.2.2]: https://github.com/ruby/zlib/releases/tag/v3.2.2
[power_assert-v3.0.0]: https://github.com/ruby/power_assert/releases/tag/v3.0.0
[power_assert-v3.0.1]: https://github.com/ruby/power_assert/releases/tag/v3.0.1
[rake-v13.3.0]: https://github.com/ruby/rake/releases/tag/v13.3.0
[rake-v13.3.1]: https://github.com/ruby/rake/releases/tag/v13.3.1
[test-unit-3.6.8]: https://github.com/test-unit/test-unit/releases/tag/3.6.8
[test-unit-3.6.9]: https://github.com/test-unit/test-unit/releases/tag/3.6.9
[test-unit-3.7.0]: https://github.com/test-unit/test-unit/releases/tag/3.7.0
[test-unit-3.7.1]: https://github.com/test-unit/test-unit/releases/tag/3.7.1
[test-unit-3.7.2]: https://github.com/test-unit/test-unit/releases/tag/3.7.2
[test-unit-3.7.3]: https://github.com/test-unit/test-unit/releases/tag/3.7.3
[test-unit-3.7.4]: https://github.com/test-unit/test-unit/releases/tag/3.7.4
[test-unit-3.7.5]: https://github.com/test-unit/test-unit/releases/tag/3.7.5
[rss-0.3.2]: https://github.com/ruby/rss/releases/tag/0.3.2
[net-ftp-v0.3.9]: https://github.com/ruby/net-ftp/releases/tag/v0.3.9
[net-imap-v0.5.9]: https://github.com/ruby/net-imap/releases/tag/v0.5.9
[net-imap-v0.5.10]: https://github.com/ruby/net-imap/releases/tag/v0.5.10
[net-imap-v0.5.11]: https://github.com/ruby/net-imap/releases/tag/v0.5.11
[net-imap-v0.5.12]: https://github.com/ruby/net-imap/releases/tag/v0.5.12
[net-imap-v0.5.13]: https://github.com/ruby/net-imap/releases/tag/v0.5.13
[net-imap-v0.6.0]: https://github.com/ruby/net-imap/releases/tag/v0.6.0
[net-imap-v0.6.1]: https://github.com/ruby/net-imap/releases/tag/v0.6.1
[net-imap-v0.6.2]: https://github.com/ruby/net-imap/releases/tag/v0.6.2
[net-smtp-v0.5.1]: https://github.com/ruby/net-smtp/releases/tag/v0.5.1
[matrix-v0.4.3]: https://github.com/ruby/matrix/releases/tag/v0.4.3
[prime-v0.1.4]: https://github.com/ruby/prime/releases/tag/v0.1.4
[rbs-v3.8.1]: https://github.com/ruby/rbs/releases/tag/v3.8.1
[rbs-v3.9.0.dev.1]: https://github.com/ruby/rbs/releases/tag/v3.9.0.dev.1
[rbs-v3.9.0.pre.1]: https://github.com/ruby/rbs/releases/tag/v3.9.0.pre.1
[rbs-v3.9.0.pre.2]: https://github.com/ruby/rbs/releases/tag/v3.9.0.pre.2
[rbs-v3.9.0]: https://github.com/ruby/rbs/releases/tag/v3.9.0
[rbs-v3.9.1]: https://github.com/ruby/rbs/releases/tag/v3.9.1
[rbs-v3.9.2]: https://github.com/ruby/rbs/releases/tag/v3.9.2
[rbs-v3.9.3]: https://github.com/ruby/rbs/releases/tag/v3.9.3
[rbs-v3.9.4]: https://github.com/ruby/rbs/releases/tag/v3.9.4
[rbs-v3.9.5]: https://github.com/ruby/rbs/releases/tag/v3.9.5
[rbs-v3.10.0.pre.1]: https://github.com/ruby/rbs/releases/tag/v3.10.0.pre.1
[rbs-v3.10.0.pre.2]: https://github.com/ruby/rbs/releases/tag/v3.10.0.pre.2
[rbs-v3.10.0]: https://github.com/ruby/rbs/releases/tag/v3.10.0
[debug-v1.11.1]: https://github.com/ruby/debug/releases/tag/v1.11.1
[base64-v0.3.0]: https://github.com/ruby/base64/releases/tag/v0.3.0
[bigdecimal-v3.2.0]: https://github.com/ruby/bigdecimal/releases/tag/v3.2.0
[bigdecimal-v3.2.1]: https://github.com/ruby/bigdecimal/releases/tag/v3.2.1
[bigdecimal-v3.2.2]: https://github.com/ruby/bigdecimal/releases/tag/v3.2.2
[bigdecimal-v3.2.3]: https://github.com/ruby/bigdecimal/releases/tag/v3.2.3
[bigdecimal-v3.3.0]: https://github.com/ruby/bigdecimal/releases/tag/v3.3.0
[bigdecimal-v3.3.1]: https://github.com/ruby/bigdecimal/releases/tag/v3.3.1
[bigdecimal-v4.0.0]: https://github.com/ruby/bigdecimal/releases/tag/v4.0.0
[bigdecimal-v4.0.1]: https://github.com/ruby/bigdecimal/releases/tag/v4.0.1
[drb-v2.2.3]: https://github.com/ruby/drb/releases/tag/v2.2.3
[syslog-v0.3.0]: https://github.com/ruby/syslog/releases/tag/v0.3.0
[csv-v3.3.3]: https://github.com/ruby/csv/releases/tag/v3.3.3
[csv-v3.3.4]: https://github.com/ruby/csv/releases/tag/v3.3.4
[csv-v3.3.5]: https://github.com/ruby/csv/releases/tag/v3.3.5

View File

@ -414,21 +414,21 @@ Each of these anchors matches a boundary:
Lookahead anchors:
- <tt>(?=_pat_)</tt>: Positive lookahead assertion:
- <tt>(?=pat)</tt>: Positive lookahead assertion:
ensures that the following characters match _pat_,
but doesn't include those characters in the matched substring.
- <tt>(?!_pat_)</tt>: Negative lookahead assertion:
- <tt>(?!pat)</tt>: Negative lookahead assertion:
ensures that the following characters <i>do not</i> match _pat_,
but doesn't include those characters in the matched substring.
Lookbehind anchors:
- <tt>(?<=_pat_)</tt>: Positive lookbehind assertion:
- <tt>(?<=pat)</tt>: Positive lookbehind assertion:
ensures that the preceding characters match _pat_, but
doesn't include those characters in the matched substring.
- <tt>(?<!_pat_)</tt>: Negative lookbehind assertion:
- <tt>(?<!pat)</tt>: Negative lookbehind assertion:
ensures that the preceding characters do not match
_pat_, but doesn't include those characters in the matched substring.
@ -574,7 +574,7 @@ A simple regexp has (at most) one match:
re.match('1943-02-04').size # => 1
re.match('foo') # => nil
Adding one or more pairs of parentheses, <tt>(_subexpression_)</tt>,
Adding one or more pairs of parentheses, <tt>(subexpression)</tt>,
defines _groups_, which may result in multiple matched substrings,
called _captures_:
@ -647,8 +647,8 @@ A regexp may contain any number of groups:
- For a large number of groups:
- The ordinary <tt>\\_n_</tt> notation applies only for _n_ in range (1..9).
- The <tt>MatchData[_n_]</tt> notation applies for any non-negative _n_.
- The ordinary <tt>\\n</tt> notation applies only for _n_ in range (1..9).
- The <tt>MatchData[n]</tt> notation applies for any non-negative _n_.
- <tt>\0</tt> is a special backreference, referring to the entire matched string;
it may not be used within the regexp itself,
@ -661,7 +661,7 @@ A regexp may contain any number of groups:
As seen above, a capture can be referred to by its number.
A capture can also have a name,
prefixed as <tt>?<_name_></tt> or <tt>?'_name_'</tt>,
prefixed as <tt>?<name></tt> or <tt>?'name'</tt>,
and the name (symbolized) may be used as an index in <tt>MatchData[]</tt>:
md = /\$(?<dollars>\d+)\.(?'cents'\d+)/.match("$3.67")
@ -676,7 +676,7 @@ When a regexp contains a named capture, there are no unnamed captures:
/\$(?<dollars>\d+)\.(\d+)/.match("$3.67")
# => #<MatchData "$3.67" dollars:"3">
A named group may be backreferenced as <tt>\k<_name_></tt>:
A named group may be backreferenced as <tt>\k<name></tt>:
/(?<vowel>[aeiou]).\k<vowel>.\k<vowel>/.match('ototomy')
# => #<MatchData "ototo" vowel:"o">
@ -732,10 +732,10 @@ see {Atomic Group}[https://www.regular-expressions.info/atomic.html].
==== Subexpression Calls
As seen above, a backreference number (<tt>\\_n_</tt>) or name (<tt>\k<_name_></tt>)
As seen above, a backreference number (<tt>\\n</tt>) or name (<tt>\k<name></tt>)
gives access to a captured _substring_;
the corresponding regexp _subexpression_ may also be accessed,
via the number (<tt>\\g<i>n</i></tt>) or name (<tt>\g<_name_></tt>):
via the number n (<tt>\\gn</tt>) or name (<tt>\g<name></tt>):
/\A(?<paren>\(\g<paren>*\))*\z/.match('(())')
# ^1
@ -768,12 +768,12 @@ See {Subexpression calls}[https://learnbyexample.github.io/Ruby_Regexp/groupings
==== Conditionals
The conditional construct takes the form <tt>(?(_cond_)_yes_|_no_)</tt>, where:
The conditional construct takes the form <tt>(?(cond)yes|no)</tt>, where:
- _cond_ may be a capture number or name.
- The match to be applied is _yes_ if _cond_ is captured;
otherwise the match to be applied is _no_.
- If not needed, <tt>|_no_</tt> may be omitted.
- If not needed, <tt>|no</tt> may be omitted.
Examples:
@ -802,7 +802,7 @@ The absence operator is a special group that matches anything which does _not_ m
==== Unicode Properties
The <tt>/\p{_property_name_}/</tt> construct (with lowercase +p+)
The <tt>/\p{property_name}/</tt> construct (with lowercase +p+)
matches characters using a Unicode property name,
much like a character class;
property +Alpha+ specifies alphabetic characters:
@ -1033,23 +1033,23 @@ See also {Extended Mode}[rdoc-ref:Regexp@Extended+Mode].
Each of these modifiers sets a mode for the regexp:
- +i+: <tt>/_pattern_/i</tt> sets
- +i+: <tt>/pattern/i</tt> sets
{Case-Insensitive Mode}[rdoc-ref:Regexp@Case-Insensitive+Mode].
- +m+: <tt>/_pattern_/m</tt> sets
- +m+: <tt>/pattern/m</tt> sets
{Multiline Mode}[rdoc-ref:Regexp@Multiline+Mode].
- +x+: <tt>/_pattern_/x</tt> sets
- +x+: <tt>/pattern/x</tt> sets
{Extended Mode}[rdoc-ref:Regexp@Extended+Mode].
- +o+: <tt>/_pattern_/o</tt> sets
- +o+: <tt>/pattern/o</tt> sets
{Interpolation Mode}[rdoc-ref:Regexp@Interpolation+Mode].
Any, all, or none of these may be applied.
Modifiers +i+, +m+, and +x+ may be applied to subexpressions:
- <tt>(?_modifier_)</tt> turns the mode "on" for ensuing subexpressions
- <tt>(?-_modifier_)</tt> turns the mode "off" for ensuing subexpressions
- <tt>(?_modifier_:_subexp_)</tt> turns the mode "on" for _subexp_ within the group
- <tt>(?-_modifier_:_subexp_)</tt> turns the mode "off" for _subexp_ within the group
- <tt>(?modifier)</tt> turns the mode "on" for ensuing subexpressions
- <tt>(?-modifier)</tt> turns the mode "off" for ensuing subexpressions
- <tt>(?modifier:subexp)</tt> turns the mode "on" for _subexp_ within the group
- <tt>(?-modifier:subexp)</tt> turns the mode "off" for _subexp_ within the group
Example:
@ -1166,22 +1166,22 @@ A regular expression containing non-US-ASCII characters
is assumed to use the source encoding.
This can be overridden with one of the following modifiers.
- <tt>/_pat_/n</tt>: US-ASCII if only containing US-ASCII characters,
- <tt>/pat/n</tt>: US-ASCII if only containing US-ASCII characters,
otherwise ASCII-8BIT:
/foo/n.encoding # => #<Encoding:US-ASCII>
/foo\xff/n.encoding # => #<Encoding:ASCII-8BIT>
/foo\x7f/n.encoding # => #<Encoding:US-ASCII>
- <tt>/_pat_/u</tt>: UTF-8
- <tt>/pat/u</tt>: UTF-8
/foo/u.encoding # => #<Encoding:UTF-8>
- <tt>/_pat_/e</tt>: EUC-JP
- <tt>/pat/e</tt>: EUC-JP
/foo/e.encoding # => #<Encoding:EUC-JP>
- <tt>/_pat_/s</tt>: Windows-31J
- <tt>/pat/s</tt>: Windows-31J
/foo/s.encoding # => #<Encoding:Windows-31J>

View File

@ -265,16 +265,16 @@ and _never_ when referring to the class itself.
When writing an explicit link, follow these guidelines.
#### +rdoc-ref+ Scheme
#### `rdoc-ref` Scheme
Use the +rdoc-ref+ scheme for:
Use the `rdoc-ref` scheme for:
- A link in core documentation to other core documentation.
- A link in core documentation to documentation in a standard library package.
- A link in a standard library package to other documentation in that same
standard library package.
See section "+rdoc-ref+ Scheme" in [links].
See section "`rdoc-ref` Scheme" in [links].
#### URL-Based Link
@ -297,7 +297,7 @@ The name of a variable (as specified in its call-seq) should be marked up as
[monofont].
Also, use monofont text for the name of a transient variable
(i.e., one defined and used only in the discussion, such as +n+).
(i.e., one defined and used only in the discussion, such as `n`).
### HTML Tags
@ -491,10 +491,10 @@ Return types:
- If the method can return multiple different types,
separate the types with "or" and, if necessary, commas.
- If the method can return multiple types, use +object+.
- If the method returns the receiver, use +self+.
- If the method can return multiple types, use `object`.
- If the method returns the receiver, use `self`.
- If the method returns an object of the same class,
prefix `new_` if and only if the object is not +self+;
prefix `new_` if and only if the object is not `self`;
example: `new_array`.
Aliases:

View File

@ -7,8 +7,8 @@ text = <<~EOT
Fifth line
EOT
# Russian text.
russian = "\u{442 435 441 442}" # => "тест"
# Japanese text.
japanese = 'こんにちは'
# Binary data.
data = "\u9990\u9991\u9992\u9993\u9994"
@ -16,8 +16,8 @@ data = "\u9990\u9991\u9992\u9993\u9994"
# Text file.
File.write('t.txt', text)
# File with Russian text.
File.write('t.rus', russian)
# File with Japanese text.
File.write('t.ja', japanese)
# File with binary data.
f = File.new('t.dat', 'wb:UTF-16')

View File

@ -72,9 +72,9 @@
# First, what's elsewhere. Class \Float:
#
# - Inherits from
# {class Numeric}[rdoc-ref:Numeric@What-27s+Here]
# and {class Object}[rdoc-ref:Object@What-27s+Here].
# - Includes {module Comparable}[rdoc-ref:Comparable@What-27s+Here].
# {class Numeric}[rdoc-ref:Numeric@Whats+Here]
# and {class Object}[rdoc-ref:Object@Whats+Here].
# - Includes {module Comparable}[rdoc-ref:Comparable@Whats+Here].
#
# Here, class \Float provides methods for:
#

View File

@ -1,3 +1,7 @@
<p align="center">
<img src="https://github.com/user-attachments/assets/27abfe03-3e96-4220-b6f1-278bb0c87684" width="400">
</p>
# ZJIT: ADVANCED RUBY JIT PROTOTYPE
ZJIT is a method-based just-in-time (JIT) compiler for Ruby. It uses profile
@ -45,7 +49,7 @@ ZJIT.
## Build Instructions
Refer to [Building Ruby](rdoc-ref:contributing/building_ruby.md) for general build prerequists.
Refer to [Building Ruby](rdoc-ref:contributing/building_ruby.md) for general build prerequisites.
Additionally, ZJIT requires Rust 1.85.0 or later. Release builds need only `rustc`. Development
builds require `cargo` and may download dependencies. GNU Make is required.

View File

@ -1,6 +1,6 @@
# Ruby Box - Ruby's in-process separation of Classes and Modules
Ruby Box is designed to provide separated spaces in a Ruby process, to isolate application codes, libraries and monkey patches.
Ruby Box is designed to provide separated spaces in a Ruby process, to isolate application code, libraries and monkey patches.
## Known issues
@ -100,7 +100,7 @@ The changed definitions are visible only in the box. In other boxes, builtin cla
class String
BLANK_PATTERN = /\A\s*\z/
def blank?
self =~ BLANK_PATTERN
self.match?(BLANK_PATTERN)
end
end
@ -117,7 +117,7 @@ Foo.foo.blank? #=> false
# in main.rb
box = Ruby::Box.new
box.require('foo')
box.require_relative('foo')
box::Foo.foo_is_blank? #=> false (#blank? called in box)
@ -151,7 +151,7 @@ end
# main.rb
box = Ruby::Box.new
box.require('foo')
box.require_relative('foo')
box::String.foo # NoMethodError
```
@ -174,7 +174,7 @@ Array.const_get(:V) #=> "FOO"
# main.rb
box = Ruby::Box.new
box.require('foo')
box.require_relative('foo')
Array.instance_variable_get(:@v) #=> nil
Array.class_variable_get(:@@v) # NameError
@ -197,7 +197,7 @@ p $foo #=> nil
p $VERBOSE #=> false
box = Ruby::Box.new
box.require('foo') # "This appears: 'foo'"
box.require_relative('foo') # "This appears: 'foo'"
p $foo #=> nil
p $VERBOSE #=> false
@ -216,7 +216,7 @@ Object::FOO #=> 100
# main.rb
box = Ruby::Box.new
box.require('foo')
box.require_relative('foo')
box::FOO #=> 100
@ -241,7 +241,7 @@ yay #=> "foo"
# main.rb
box = Ruby::Box.new
box.require('foo')
box.require_relative('foo')
box::Foo.say #=> "foo"

View File

@ -31,7 +31,6 @@ contained in the selector itself:
'abracadabra'.delete('abc') # => "rdr"
'0123456789'.delete('258') # => "0134679"
'!@#$%&*()_+'.delete('+&#') # => "!@$%*()_"
'тест'.delete('т') # => "ес"
'こんにちは'.delete('に') # => "こんちは"
Note that order and repetitions do not matter:

View File

@ -393,7 +393,7 @@ These keyword-value pairs specify encoding options:
- <tt>:replace: nil</tt> (default): Set replacement string to default value:
<tt>"\uFFFD"</tt> ("<22>") for a Unicode encoding, <tt>'?'</tt> otherwise.
- <tt>:replace: _some_string_</tt>: Set replacement string to the given +some_string+;
- <tt>:replace: some_string</tt>: Set replacement string to the given +some_string+;
overrides +:fallback+.
Examples:
@ -407,12 +407,12 @@ These keyword-value pairs specify encoding options:
One of these may be specified:
- <tt>:fallback: nil</tt> (default): No replacement fallback.
- <tt>:fallback: _hash_like_object_</tt>: Set replacement fallback to the given
+hash_like_object+; the replacement string is <tt>_hash_like_object_[X]</tt>.
- <tt>:fallback: _method_</tt>: Set replacement fallback to the given
+method+; the replacement string is <tt>_method_(X)</tt>.
- <tt>:fallback: _proc_</tt>: Set replacement fallback to the given
+proc+; the replacement string is <tt>_proc_[X]</tt>.
- <tt>:fallback: hash_like_object</tt>: Set replacement fallback to the given
+hash_like_object+; the replacement string is <tt>hash_like_object[X]</tt>.
- <tt>:fallback: method</tt>: Set replacement fallback to the given
+method+; the replacement string is <tt>method(X)</tt>.
- <tt>:fallback: proc</tt>: Set replacement fallback to the given
+proc+; the replacement string is <tt>proc[X]</tt>.
Examples:

View File

@ -504,18 +504,18 @@ These methods return backtrace information:
By default, Ruby sets the backtrace of the exception to the location where it
was raised.
The developer might adjust this by either providing +backtrace+ argument
The developer might adjust this by either providing `backtrace` argument
to Kernel#raise, or using Exception#set_backtrace.
Note that:
- by default, both +backtrace+ and +backtrace_locations+ represent the same backtrace;
- by default, both `backtrace` and `backtrace_locations` represent the same backtrace;
- if the developer sets the backtrace by one of the above methods to an array of
Thread::Backtrace::Location, they still represent the same backtrace;
- if the developer sets the backtrace to a string or an array of strings:
- by Kernel#raise: +backtrace_locations+ become +nil+;
- by Exception#set_backtrace: +backtrace_locations+ preserve the original
- by Kernel#raise: `backtrace_locations` become `nil`;
- by Exception#set_backtrace: `backtrace_locations` preserve the original
value;
- if the developer sets the backtrace to +nil+ by Exception#set_backtrace,
+backtrace_locations+ preserve the original value; but if the exception is then
reraised, both +backtrace+ and +backtrace_locations+ become the location of reraise.
- if the developer sets the backtrace to `nil` by Exception#set_backtrace,
`backtrace_locations` preserve the original value; but if the exception is then
reraised, both `backtrace` and `backtrace_locations` become the location of reraise.

View File

@ -21,16 +21,16 @@ require 'English'
### Matched \Data
| Variable | \English | Contains | Initially | Read-Only | Reset By |
|:-------------:|:-------------------:|-----------------------------------|:---------:|:---------:|-----------------|
| `$~` | `$LAST_MATCH_INFO` | \MatchData object or `nil` | `nil` | No | Matcher methods |
| `$&` | `$MATCH` | Matched substring or `nil` | `nil` | No | Matcher methods |
| `` $` `` | `$PRE_MATCH` | Substring left of match or `nil` | `nil` | No | Matcher methods |
| `$'` | `$POST_MATCH` | Substring right of match or `nil` | `nil` | No | Matcher methods |
| `$+` | `$LAST_PAREN_MATCH` | Last group matched or `nil` | `nil` | No | Matcher methods |
| `$1` | | First group matched or `nil` | `nil` | Yes | Matcher methods |
| `$2` | | Second group matched or `nil` | `nil` | Yes | Matcher methods |
| <tt>$_n_</tt> | | <i>n</i>th group matched or `nil` | `nil` | Yes | Matcher methods |
| Variable | \English | Contains | Initially | Read-Only | Reset By |
|:---------:|:-------------------:|-----------------------------------|:---------:|:---------:|-----------------|
| `$~` | `$LAST_MATCH_INFO` | \MatchData object or `nil` | `nil` | No | Matcher methods |
| `$&` | `$MATCH` | Matched substring or `nil` | `nil` | No | Matcher methods |
| `` $` `` | `$PRE_MATCH` | Substring left of match or `nil` | `nil` | No | Matcher methods |
| `$'` | `$POST_MATCH` | Substring right of match or `nil` | `nil` | No | Matcher methods |
| `$+` | `$LAST_PAREN_MATCH` | Last group matched or `nil` | `nil` | No | Matcher methods |
| `$1` | | First group matched or `nil` | `nil` | Yes | Matcher methods |
| `$2` | | Second group matched or `nil` | `nil` | Yes | Matcher methods |
| `$n` | | <i>n</i>th group matched or `nil` | `nil` | Yes | Matcher methods |
### Separators
@ -167,7 +167,7 @@ English - `$LAST_PAREN_MATCH`.
### `$1`, `$2`, \Etc. (Matched Group)
For <tt>$_n_</tt> the <i>n</i>th group of the match.
For <tt>$n</tt> the <i>n</i>th group of the match.
No \English.
@ -282,9 +282,9 @@ by Kernel#load and Kernel#require.
Singleton method `$LOAD_PATH.resolve_feature_path(feature)`
returns:
- <tt>[:rb, _path_]</tt>, where `path` is the path to the Ruby file to be
- <tt>[:rb, path]</tt>, where `path` is the path to the Ruby file to be
loaded for the given `feature`.
- <tt>[:so, _path_]</tt>, where `path` is the path to the shared object file
- <tt>[:so, path]</tt>, where `path` is the path to the shared object file
to be loaded for the given `feature`.
- `nil` if there is no such `feature` and `path`.

View File

@ -640,7 +640,7 @@ Option `--encoding` is an alias for
Option `--external-encoding`
sets the default external encoding for the invoked Ruby program;
for values of +encoding+,
for values of `encoding`,
see {Encoding: Names and Aliases}[rdoc-ref:encodings.rdoc@Names+and+Aliases].
```console
@ -662,7 +662,7 @@ For a shorter help message, use option `-h`.
Option `--internal-encoding`
sets the default internal encoding for the invoked Ruby program;
for values of +encoding+,
for values of `encoding`,
see {Encoding: Names and Aliases}[rdoc-ref:encodings.rdoc@Names+and+Aliases].
```console

View File

@ -457,15 +457,15 @@ for one byte in the input or output string.
"foo ".unpack('A4') # => ["foo"]
"foo".unpack('A4') # => ["foo"]
russian = "\u{442 435 441 442}" # => "тест"
russian.size # => 4
russian.bytesize # => 8
[russian].pack('A') # => "\xD1"
[russian].pack('A*') # => "\xD1\x82\xD0\xB5\xD1\x81\xD1\x82"
russian.unpack('A') # => ["\xD1"]
russian.unpack('A2') # => ["\xD1\x82"]
russian.unpack('A4') # => ["\xD1\x82\xD0\xB5"]
russian.unpack('A*') # => ["\xD1\x82\xD0\xB5\xD1\x81\xD1\x82"]
japanese = 'こんにちは'
japanese.size # => 5
japanese.bytesize # => 15
[japanese].pack('A') # => "\xE3"
[japanese].pack('A*') # => "\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1\xE3\x81\xAF"
japanese.unpack('A') # => ["\xE3"]
japanese.unpack('A2') # => ["\xE3\x81"]
japanese.unpack('A4') # => ["\xE3\x81\x93\xE3"]
japanese.unpack('A*') # => ["\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1\xE3\x81\xAF"]
- <tt>'a'</tt> - Arbitrary binary string (null padded; count is width):

View File

@ -50,6 +50,10 @@ consensus on ruby-core/ruby-dev.
* *No maintainer*
#### lib/pathname.rb
* Tanaka Akira ([akr])
#### lib/rubygems.rb, lib/rubygems/*
* Hiroshi SHIBATA ([hsbt])
@ -269,12 +273,6 @@ consensus on ruby-core/ruby-dev.
* https://github.com/ruby/tmpdir
* https://rubygems.org/gems/tmpdir
#### lib/tsort.rb
* Tanaka Akira ([akr])
* https://github.com/ruby/tsort
* https://rubygems.org/gems/tsort
#### lib/un.rb
* WATANABE Hirofumi ([eban])
@ -356,12 +354,6 @@ consensus on ruby-core/ruby-dev.
* https://github.com/ruby/openssl
* https://rubygems.org/gems/openssl
#### ext/pathname
* Tanaka Akira ([akr])
* https://github.com/ruby/pathname
* https://rubygems.org/gems/pathname
#### ext/psych
* Aaron Patterson ([tenderlove])
@ -628,6 +620,12 @@ It may needs to make consensus on ruby-core/ruby-dev before making major changes
* https://github.com/ruby/repl_type_completor
* https://rubygems.org/gems/repl_type_completor
#### tsort
* Tanaka Akira ([akr])
* https://github.com/ruby/tsort
* https://rubygems.org/gems/tsort
## Platform Maintainers
### mswin64 (Microsoft Windows)

View File

@ -10,12 +10,12 @@ returns the offset of the beginning of the <tt>n</tt>th match:
m[3] # => "113"
m.begin(3) # => 3
m = /(т)(е)(с)/.match('тест')
# => #<MatchData "тес" 1:"т" 2:"е" 3:"с">
m[0] # => "тес"
m.begin(0) # => 0
m[3] # => "с"
m.begin(3) # => 2
m = /(ん)(に)(ち)/.match('こんにちは')
# => #<MatchData "んにち" 1:"ん" 2:"に" 3:"ち">
m[0] # => "んにち"
m.begin(0) # => 1
m[3] # => ""
m.begin(3) # => 3
When string or symbol argument +name+ is given,
returns the offset of the beginning for the named match:

View File

@ -10,12 +10,12 @@ returns the offset of the beginning of the <tt>n</tt>th match:
m[3] # => "113"
m.bytebegin(3) # => 3
m = /(т)(е)(с)/.match('тест')
# => #<MatchData "тес" 1:"т" 2:"е" 3:"с">
m[0] # => "тес"
m.bytebegin(0) # => 0
m[3] # => "с"
m.bytebegin(3) # => 4
m = /(ん)(に)(ち)/.match('こんにちは')
# => #<MatchData "んにち" 1:"ん" 2:"に" 3:"ち">
m[0] # => "んにち"
m.bytebegin(0) # => 3
m[3] # => "ち"
m.bytebegin(3) # => 9
When string or symbol argument +name+ is given,
returns the offset of the beginning for the named match:

View File

@ -10,12 +10,12 @@ returns the offset of the end of the <tt>n</tt>th match:
m[3] # => "113"
m.byteend(3) # => 6
m = /(т)(е)(с)/.match('тест')
# => #<MatchData "тес" 1:"т" 2:"е" 3:"с">
m[0] # => "тес"
m.byteend(0) # => 6
m[3] # => "с"
m.byteend(3) # => 6
m = /(ん)(に)(ち)/.match('こんにちは')
# => #<MatchData "んにち" 1:"ん" 2:"に" 3:"ち">
m[0] # => "んにち"
m.byteend(0) # => 12
m[3] # => "ち"
m.byteend(3) # => 12
When string or symbol argument +name+ is given,
returns the offset of the end for the named match:

View File

@ -10,12 +10,12 @@ returns the offset of the end of the <tt>n</tt>th match:
m[3] # => "113"
m.end(3) # => 6
m = /(т)(е)(с)/.match('тест')
# => #<MatchData "тес" 1:"т" 2:"е" 3:"с">
m[0] # => "тес"
m.end(0) # => 3
m[3] # => "с"
m.end(3) # => 3
m = /(ん)(に)(ち)/.match('こんにちは')
# => #<MatchData "んにち" 1:"ん" 2:"に" 3:"ち">
m[0] # => "んにち"
m.end(0) # => 4
m[3] # => ""
m.end(3) # => 4
When string or symbol argument +name+ is given,
returns the offset of the end for the named match:

View File

@ -11,12 +11,12 @@ returns the starting and ending offsets of the <tt>n</tt>th match:
m[3] # => "113"
m.offset(3) # => [3, 6]
m = /(т)(е)(с)/.match('тест')
# => #<MatchData "тес" 1:"т" 2:"е" 3:"с">
m[0] # => "тес"
m.offset(0) # => [0, 3]
m[3] # => "с"
m.offset(3) # => [2, 3]
m = /(ん)(に)(ち)/.match('こんにちは')
# => #<MatchData "んにち" 1:"ん" 2:"に" 3:"ち">
m[0] # => "んにち"
m.offset(0) # => [1, 4]
m[3] # => ""
m.offset(3) # => [3, 4]
When string or symbol argument +name+ is given,
returns the starting and ending offsets for the named match:

View File

@ -13,25 +13,3 @@ These methods include:
- {\`command` (backtick method)}[rdoc-ref:Kernel#`]
(also called by the expression <tt>%x[command]</tt>).
- IO.popen (when called with other than <tt>"-"</tt>).
Some methods execute a system command only if the given path name starts
with a <tt>|</tt>:
- Kernel.open(command).
- IO.read(command).
- IO.write(command).
- IO.binread(command).
- IO.binwrite(command).
- IO.readlines(command).
- IO.foreach(command).
- URI.open(command).
Note that some of these methods do not execute commands when called
from subclass +File+:
- File.read(path).
- File.write(path).
- File.binread(path).
- File.binwrite(path).
- File.readlines(path).
- File.foreach(path).

View File

@ -11,6 +11,7 @@ of each.
- `MakeMakefile`: A module used to generate a Makefile for C extensions
- `RbConfig`: Information about your Ruby configuration and build
- `Gem`: A package management framework for Ruby
- `Pathname`: Representation of the name of a file or directory on the filesystem. Pathname is a core class, but only methods that depend on other libraries are provided as a library.
## Extensions
@ -58,7 +59,6 @@ of each.
- Time ([GitHub][time]): Extends the Time class with methods for parsing and conversion
- Timeout ([GitHub][timeout]): Auto-terminate potentially long-running operations in Ruby
- TmpDir ([GitHub][tmpdir]): Extends the Dir class to manage the OS temporary file path
- TSort ([GitHub][tsort]): Topological sorting using Tarjan's algorithm
- UN ([GitHub][un]): Utilities to replace common UNIX commands
- URI ([GitHub][uri]): A Ruby module providing support for Uniform Resource Identifiers
- YAML ([GitHub][yaml]): The Ruby client library for the Psych YAML implementation
@ -75,7 +75,6 @@ of each.
- IO#wait ([GitHub][io-wait]): Provides the feature for waiting until IO is readable or writable without blocking.
- JSON ([GitHub][json]): Implements JavaScript Object Notation for Ruby
- OpenSSL ([GitHub][openssl]): Provides SSL, TLS, and general-purpose cryptography for Ruby
- Pathname ([GitHub][pathname]): Representation of the name of a file or directory on the filesystem
- Psych ([GitHub][psych]): A YAML parser and emitter for Ruby
- StringIO ([GitHub][stringio]): Pseudo-I/O on String objects
- StringScanner ([GitHub][strscan]): Provides lexical scanning operations on a String
@ -126,6 +125,7 @@ of each.
- [reline][reline-doc] ([GitHub][reline]): GNU Readline and Editline in a pure Ruby implementation
- [readline]: Wrapper for the Readline extension and Reline
- [fiddle]: A libffi wrapper for Ruby
- [tsort]: Topological sorting using Tarjan's algorithm
## Tools

View File

@ -163,8 +163,8 @@
#
# First, what's elsewhere. Class +String+:
#
# - Inherits from the {Object class}[rdoc-ref:Object@What-27s+Here].
# - Includes the {Comparable module}[rdoc-ref:Comparable@What-27s+Here].
# - Inherits from the {Object class}[rdoc-ref:Object@Whats+Here].
# - Includes the {Comparable module}[rdoc-ref:Comparable@Whats+Here].
#
# Here, class +String+ provides methods that are useful for:
#

View File

@ -1,31 +1,30 @@
Returns the substring of +self+ specified by the arguments.
<b>Form <tt>self[index]</tt></b>
<b>Form <tt>self[offset]</tt></b>
With non-negative integer argument +index+ given,
returns the 1-character substring found in self at character offset index:
With non-negative integer argument +offset+ given,
returns the 1-character substring found in self at character offset +offset+:
'hello'[0] # => "h"
'hello'[4] # => "o"
'hello'[5] # => nil
'Привет'[2] # => "и"
'こんにちは'[4] # => "は"
With negative integer argument +index+ given,
With negative integer argument +offset+ given,
counts backward from the end of +self+:
'hello'[-1] # => "o"
'hello'[-5] # => "h"
'hello'[-6] # => nil
<b>Form <tt>self[start, length]</tt></b>
<b>Form <tt>self[offset, size]</tt></b>
With integer arguments +start+ and +length+ given,
returns a substring of size +length+ characters (as available)
beginning at character offset specified by +start+.
With integer arguments +offset+ and +size+ given,
returns a substring of size +size+ characters (as available)
beginning at character offset specified by +offset+.
If argument +start+ is non-negative,
the offset is +start+:
If argument +offset+ is non-negative,
the offset is +offset+:
'hello'[0, 1] # => "h"
'hello'[0, 5] # => "hello"
@ -34,7 +33,7 @@ the offset is +start+:
'hello'[2, 0] # => ""
'hello'[2, -1] # => nil
If argument +start+ is negative,
If argument +offset+ is negative,
counts backward from the end of +self+:
'hello'[-1, 1] # => "o"
@ -42,7 +41,7 @@ counts backward from the end of +self+:
'hello'[-1, 0] # => ""
'hello'[-6, 5] # => nil
Special case: if +start+ equals the length of +self+,
Special case: if +offset+ equals the size of +self+,
returns a new empty string:
'hello'[5, 3] # => ""
@ -92,7 +91,6 @@ returns the matching substring of +self+, if found:
'hello'['ell'] # => "ell"
'hello'[''] # => ""
'hello'['nosuch'] # => nil
'Привет'['ив'] # => "ив"
'こんにちは'['んにち'] # => "んにち"
Related: see {Converting to New String}[rdoc-ref:String@Converting+to+New+String].

View File

@ -170,10 +170,6 @@ With string argument +substring+ given:
s['ll'] = 'foo' # => "foo"
s # => "hefooo"
s = 'Привет'
s['ив'] = 'foo' # => "foo"
s # => "Прfooет"
s = 'こんにちは'
s['んにち'] = 'foo' # => "foo"
s # => "こfooは"

View File

@ -1,7 +1,6 @@
Returns an array of the bytes in +self+:
'hello'.bytes # => [104, 101, 108, 108, 111]
'Привет'.bytes # => [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
'こんにちは'.bytes
# => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]

View File

@ -5,9 +5,6 @@ Note that the byte count may be different from the character count (returned by
s = 'foo'
s.bytesize # => 3
s.size # => 3
s = 'Привет'
s.bytesize # => 12
s.size # => 6
s = 'こんにちは'
s.bytesize # => 15
s.size # => 5

View File

@ -10,8 +10,6 @@ Examples:
'HELLO'.capitalize # => "Hello"
'straße'.capitalize # => "Straße" # Lowercase 'ß' not changed.
'STRAẞE'.capitalize # => "Straße" # Uppercase 'ẞ' downcased to 'ß'.
'привет'.capitalize # => "Привет"
'ПРИВЕТ'.capitalize # => "Привет"
Some characters (and some character sets) do not have upcase and downcase versions;
see {Case Mapping}[rdoc-ref:case_mapping.rdoc]:

View File

@ -9,7 +9,6 @@ centered and padded on one or both ends with +pad_string+:
'hello'.center(20, '-|') # => "-|-|-|-hello-|-|-|-|" # Some padding repeated.
'hello'.center(10, 'abcdefg') # => "abhelloabc" # Some padding not used.
' hello '.center(13) # => " hello "
'Привет'.center(10) # => " Привет "
'こんにちは'.center(10) # => " こんにちは " # Multi-byte characters.
If +size+ is less than or equal to the size of +self+, returns an unpadded copy of +self+:

View File

@ -1,7 +1,6 @@
Returns an array of the characters in +self+:
'hello'.chars # => ["h", "e", "l", "l", "o"]
'Привет'.chars # => ["П", "р", "и", "в", "е", "т"]
'こんにちは'.chars # => ["こ", "ん", "に", "ち", "は"]
''.chars # => []

View File

@ -9,7 +9,6 @@ if they are <tt>"\r"</tt>, <tt>"\n"</tt>, or <tt>"\r\n"</tt>
"abc\n".chomp # => "abc"
"abc\r\n".chomp # => "abc"
"abc\n\r".chomp # => "abc\n"
"тест\r\n".chomp # => "тест"
"こんにちは\r\n".chomp # => "こんにちは"
When +line_sep+ is <tt>''</tt> (an empty string),

View File

@ -3,13 +3,11 @@ Returns a new string copied from +self+, with trailing characters possibly remov
Removes <tt>"\r\n"</tt> if those are the last two characters.
"abc\r\n".chop # => "abc"
"тест\r\n".chop # => "тест"
"こんにちは\r\n".chop # => "こんにちは"
Otherwise removes the last character if it exists.
'abcd'.chop # => "abc"
'тест'.chop # => "тес"
'こんにちは'.chop # => "こんにち"
''.chop # => ""

View File

@ -1,7 +1,6 @@
Returns a string containing the first character of +self+:
'hello'.chr # => "h"
'тест'.chr # => "т"
'こんにちは'.chr # => "こ"
''.chr # => ""

View File

@ -2,7 +2,6 @@ Returns an array of the codepoints in +self+;
each codepoint is the integer value for a character:
'hello'.codepoints # => [104, 101, 108, 108, 111]
'тест'.codepoints # => [1090, 1077, 1089, 1090]
'こんにちは'.codepoints # => [12371, 12435, 12395, 12385, 12399]
''.codepoints # => []

View File

@ -6,7 +6,6 @@ For each given object +object+ that is an integer,
the value is considered a codepoint and converted to a character before concatenation:
'foo'.concat(32, 'bar', 32, 'baz') # => "foo bar baz" # Embeds spaces.
'те'.concat(1089, 1090) # => "тест"
'こん'.concat(12395, 12385, 12399) # => "こんにちは"
Related: see {Converting to New String}[rdoc-ref:String@Converting+to+New+String].

View File

@ -9,10 +9,6 @@ returns the count of instances of that character:
s.count('x') # => 0
s.count('') # => 0
s = 'тест'
s.count('т') # => 2
s.count('е') # => 1
s = 'よろしくお願いします'
s.count('よ') # => 1
s.count('し') # => 2

View File

@ -10,10 +10,6 @@ removes all instances of that character:
s.delete('x') # => "abracadabra"
s.delete('') # => "abracadabra"
s = 'тест'
s.delete('т') # => "ес"
s.delete('е') # => "тст"
s = 'よろしくお願いします'
s.delete('よ') # => "ろしくお願いします"
s.delete('し') # => "よろくお願います"

View File

@ -4,7 +4,6 @@ Returns a copy of +self+ with leading substring +prefix+ removed:
'oof'.delete_prefix('oo') # => "f"
'oof'.delete_prefix('oof') # => ""
'oof'.delete_prefix('x') # => "oof"
'тест'.delete_prefix('те') # => "ст"
'こんにちは'.delete_prefix('こん') # => "にちは"
Related: see {Converting to New String}[rdoc-ref:String@Converting+to+New+String].

View File

@ -5,7 +5,6 @@ Returns a copy of +self+ with trailing substring <tt>suffix</tt> removed:
'foo'.delete_suffix('foo') # => ""
'foo'.delete_suffix('f') # => "foo"
'foo'.delete_suffix('x') # => "foo"
'тест'.delete_suffix('ст') # => "те"
'こんにちは'.delete_suffix('ちは') # => "こんに"
Related: see {Converting to New String}[rdoc-ref:String@Converting+to+New+String].

View File

@ -69,10 +69,6 @@ and so contains both outer double-quotes and escaped inner double-quotes:
If +self+ is encoded in UTF-8 and contains Unicode characters,
each Unicode character is dumped as a Unicode escape sequence:
String: тест
Dumped: "\u0442\u0435\u0441\u0442"
Undumped: тест
String: こんにちは
Dumped: "\u3053\u3093\u306B\u3061\u306F"
Undumped: こんにちは
@ -88,10 +84,6 @@ where <tt><encoding></tt> is <tt>self.encoding.name</tt>:
Dumped: "\xFE\xFF\x00h\x00e\x00l\x00l\x00o".dup.force_encoding("UTF-16")
Undumped: hello
String: тест
Dumped: "\xFE\xFF\x04B\x045\x04A\x04B".dup.force_encoding("UTF-16")
Undumped: тест
String: こんにちは
Dumped: "\xFE\xFF0S0\x930k0a0o".dup.force_encoding("UTF-16")
Undumped: こんにちは

View File

@ -5,9 +5,6 @@ returns +self+:
'hello'.each_byte {|byte| a.push(byte) } # Five 1-byte characters.
a # => [104, 101, 108, 108, 111]
a = []
'тест'.each_byte {|byte| a.push(byte) } # Four 2-byte characters.
a # => [209, 130, 208, 181, 209, 129, 209, 130]
a = []
'こんにちは'.each_byte {|byte| a.push(byte) } # Five 3-byte characters.
a # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]

Some files were not shown because too many files have changed in this diff Show More