From bfa6a8ddc84fffe0aef5a0f91b417167e124dbbf Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Wed, 10 Aug 2022 13:02:19 -0700 Subject: [PATCH 01/44] Only allow procs created by Symbol#to_proc to call public methods Fixes [Bug #18826] Co-authored-by: Nobuyoshi Nakada --- .../core/kernel/fixtures/warn_core_method.rb | 2 +- spec/ruby/core/symbol/to_proc_spec.rb | 27 ++++++++++++++ vm_insnhelper.c | 36 +++++++++++++++---- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/spec/ruby/core/kernel/fixtures/warn_core_method.rb b/spec/ruby/core/kernel/fixtures/warn_core_method.rb index f5dee6b668aaed..fd825624047afa 100644 --- a/spec/ruby/core/kernel/fixtures/warn_core_method.rb +++ b/spec/ruby/core/kernel/fixtures/warn_core_method.rb @@ -1,6 +1,6 @@ raise 'should be run without RubyGems' if defined?(Gem) -def deprecated(n=1) +public def deprecated(n=1) # puts nil, caller(0), nil warn "use X instead", uplevel: n end diff --git a/spec/ruby/core/symbol/to_proc_spec.rb b/spec/ruby/core/symbol/to_proc_spec.rb index 47f2a939ab2d75..81939e0046c540 100644 --- a/spec/ruby/core/symbol/to_proc_spec.rb +++ b/spec/ruby/core/symbol/to_proc_spec.rb @@ -46,6 +46,33 @@ end end + ruby_version_is "3.2" do + it "only calls public methods" do + body = proc do + public def pub; @a << :pub end + protected def pro; @a << :pro end + private def pri; @a << :pri end + attr_reader :a + end + + @a = [] + singleton_class.class_eval(&body) + tap(&:pub) + proc{tap(&:pro)}.should raise_error(NoMethodError) + proc{tap(&:pri)}.should raise_error(NoMethodError) + @a.should == [:pub] + + @a = [] + c = Class.new(&body) + o = c.new + o.instance_variable_set(:@a, []) + o.tap(&:pub) + proc{tap(&:pro)}.should raise_error(NoMethodError) + proc{o.tap(&:pri)}.should raise_error(NoMethodError) + o.a.should == [:pub] + end + end + it "raises an ArgumentError when calling #call on the Proc without receiver" do -> { :object_id.to_proc.call diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 2c0a369a439001..1812f7ce71aead 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -3182,9 +3182,11 @@ ci_missing_reason(const struct rb_callinfo *ci) return stat; } +static VALUE vm_call_method_missing(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling); + static VALUE vm_call_symbol(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, - struct rb_calling_info *calling, const struct rb_callinfo *ci, VALUE symbol) + struct rb_calling_info *calling, const struct rb_callinfo *ci, VALUE symbol, int flags) { ASSUME(calling->argc >= 0); /* Also assumes CALLER_SETUP_ARG is already done. */ @@ -3194,9 +3196,7 @@ vm_call_symbol(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, VALUE recv = calling->recv; VALUE klass = CLASS_OF(recv); ID mid = rb_check_id(&symbol); - int flags = VM_CALL_FCALL | - VM_CALL_OPT_SEND | - (calling->kw_splat ? VM_CALL_KW_SPLAT : 0); + flags |= VM_CALL_OPT_SEND | (calling->kw_splat ? VM_CALL_KW_SPLAT : 0); if (UNLIKELY(! mid)) { mid = idMethodMissing; @@ -3243,7 +3243,29 @@ vm_call_symbol(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, { .method_missing_reason = missing_reason }, rb_callable_method_entry_with_refinements(klass, mid, NULL)); - return vm_call_method(ec, reg_cfp, calling); + if (flags & VM_CALL_FCALL) { + return vm_call_method(ec, reg_cfp, calling); + } + + const struct rb_callcache *cc = calling->cc; + VM_ASSERT(callable_method_entry_p(vm_cc_cme(cc))); + + if (vm_cc_cme(cc) != NULL) { + switch (METHOD_ENTRY_VISI(vm_cc_cme(cc))) { + case METHOD_VISI_PUBLIC: /* likely */ + return vm_call_method_each_type(ec, reg_cfp, calling); + case METHOD_VISI_PRIVATE: + vm_cc_method_missing_reason_set(cc, MISSING_PRIVATE); + case METHOD_VISI_PROTECTED: + vm_cc_method_missing_reason_set(cc, MISSING_PROTECTED); + break; + default: + VM_UNREACHABLE(vm_call_method); + } + return vm_call_method_missing(ec, reg_cfp, calling); + } + + return vm_call_method_nome(ec, reg_cfp, calling); } static VALUE @@ -3283,7 +3305,7 @@ vm_call_opt_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, struct calling->argc -= 1; DEC_SP(1); - return vm_call_symbol(ec, reg_cfp, calling, calling->ci, sym); + return vm_call_symbol(ec, reg_cfp, calling, calling->ci, sym, VM_CALL_FCALL); } } @@ -4097,7 +4119,7 @@ vm_invoke_symbol_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, VALUE symbol = VM_BH_TO_SYMBOL(block_handler); CALLER_SETUP_ARG(reg_cfp, calling, ci); calling->recv = TOPN(--calling->argc); - return vm_call_symbol(ec, reg_cfp, calling, ci, symbol); + return vm_call_symbol(ec, reg_cfp, calling, ci, symbol, 0); } } From ff42e2359bdbf37e1721a82b4cfd95b31f494f3f Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 3 Jun 2022 18:15:56 -0700 Subject: [PATCH 02/44] Revert "Add {Method,UnboundMethod}#{public?,private?,protected?}" This reverts commit 27278150685e738f84105d09843d3ba371146c7a and 58dc8bf8f15df9a33d191074e8a5d4946a3d59d5. Visibility is an attribute of the method entry in a class, not an attribute of the Method object. Fixes [#18729] Fixes [#18751] Fixes [#18435] --- proc.c | 60 +--------------------------------------- test/ruby/test_method.rb | 53 ++--------------------------------- 2 files changed, 3 insertions(+), 110 deletions(-) diff --git a/proc.c b/proc.c index a525562230b3c8..c234ed3f9365b7 100644 --- a/proc.c +++ b/proc.c @@ -40,7 +40,6 @@ struct METHOD { const VALUE iclass; const rb_method_entry_t * const me; /* for bound methods, `me' should be rb_callable_method_entry_t * */ - rb_method_visibility_t visibility; }; VALUE rb_cUnboundMethod; @@ -1664,7 +1663,6 @@ mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass) me = rb_method_entry_create(id, klass, METHOD_VISI_UNDEF, def); RB_OBJ_WRITE(method, &data->me, me); - data->visibility = METHOD_ENTRY_VISI(me); return method; } @@ -1722,7 +1720,6 @@ mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass, RB_OBJ_WRITE(method, &data->klass, klass); RB_OBJ_WRITE(method, &data->iclass, iclass); RB_OBJ_WRITE(method, &data->me, me); - data->visibility = visi; return method; } @@ -1820,7 +1817,6 @@ method_eq(VALUE method, VALUE other) if (!rb_method_entry_eq(m1->me, m2->me) || klass1 != klass2 || - m1->visibility != m2->visibility || m1->klass != m2->klass || m1->recv != m2->recv) { return Qfalse; @@ -1874,7 +1870,6 @@ method_unbind(VALUE obj) RB_OBJ_WRITE(method, &data->klass, orig->klass); RB_OBJ_WRITE(method, &data->iclass, orig->iclass); RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me)); - data->visibility = orig->visibility; return method; } @@ -2390,7 +2385,6 @@ method_clone(VALUE self) RB_OBJ_WRITE(clone, &data->klass, orig->klass); RB_OBJ_WRITE(clone, &data->iclass, orig->iclass); RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me)); - data->visibility = orig->visibility; return clone; } @@ -2641,7 +2635,6 @@ umethod_bind(VALUE method, VALUE recv) RB_OBJ_WRITE(method, &bound->klass, klass); RB_OBJ_WRITE(method, &bound->iclass, iclass); RB_OBJ_WRITE(method, &bound->me, me); - bound->visibility = data->visibility; return method; } @@ -2677,7 +2670,7 @@ umethod_bind_call(int argc, VALUE *argv, VALUE method) VALUE methclass, klass, iclass; const rb_method_entry_t *me; convert_umethod_to_method_components(data, recv, &methclass, &klass, &iclass, &me); - struct METHOD bound = { recv, klass, 0, me, METHOD_ENTRY_VISI(me) }; + struct METHOD bound = { recv, klass, 0, me }; return call_method_data(ec, &bound, argc, argv, passed_procval, RB_PASS_CALLED_KEYWORDS); } @@ -3354,51 +3347,6 @@ method_super_method(VALUE method) return mnew_internal(me, me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE); } -/* - * call-seq: - * meth.public? -> true or false - * - * Returns whether the method is public. - */ - -static VALUE -method_public_p(VALUE method) -{ - const struct METHOD *data; - TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); - return RBOOL(data->visibility == METHOD_VISI_PUBLIC); -} - -/* - * call-seq: - * meth.protected? -> true or false - * - * Returns whether the method is protected. - */ - -static VALUE -method_protected_p(VALUE method) -{ - const struct METHOD *data; - TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); - return RBOOL(data->visibility == METHOD_VISI_PROTECTED); -} - -/* - * call-seq: - * meth.private? -> true or false - * - * Returns whether the method is private. - */ - -static VALUE -method_private_p(VALUE method) -{ - const struct METHOD *data; - TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); - return RBOOL(data->visibility == METHOD_VISI_PRIVATE); -} - /* * call-seq: * local_jump_error.exit_value -> obj @@ -4339,9 +4287,6 @@ Init_Proc(void) rb_define_method(rb_cMethod, "source_location", rb_method_location, 0); rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0); rb_define_method(rb_cMethod, "super_method", method_super_method, 0); - rb_define_method(rb_cMethod, "public?", method_public_p, 0); - rb_define_method(rb_cMethod, "protected?", method_protected_p, 0); - rb_define_method(rb_cMethod, "private?", method_private_p, 0); rb_define_method(rb_mKernel, "method", rb_obj_method, 1); rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1); rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1); @@ -4365,9 +4310,6 @@ Init_Proc(void) rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0); rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0); rb_define_method(rb_cUnboundMethod, "super_method", method_super_method, 0); - rb_define_method(rb_cUnboundMethod, "public?", method_public_p, 0); - rb_define_method(rb_cUnboundMethod, "protected?", method_protected_p, 0); - rb_define_method(rb_cUnboundMethod, "private?", method_private_p, 0); /* Module#*_method */ rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1); diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index 83e499913a4bb4..56e94493d9860c 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -199,11 +199,6 @@ def m.foo; end assert_equal(o.method(:foo), o.method(:foo)) assert_equal(o.method(:foo), o.method(:bar)) assert_not_equal(o.method(:foo), o.method(:baz)) - - class << o - private :bar - end - assert_not_equal(o.method(:foo), o.method(:bar)) end def test_hash @@ -330,8 +325,8 @@ class << PUBLIC_SINGLETON_TEST def PUBLIC_SINGLETON_TEST.def; end end def test_define_singleton_method_public - assert_equal(true, PUBLIC_SINGLETON_TEST.method(:dsm).public?) - assert_equal(true, PUBLIC_SINGLETON_TEST.method(:def).public?) + assert_nil(PUBLIC_SINGLETON_TEST.dsm) + assert_nil(PUBLIC_SINGLETON_TEST.def) end def test_define_singleton_method_no_proc @@ -1197,50 +1192,6 @@ def foo assert_nil(super_method) end - def test_method_visibility_predicates - v = Visibility.new - assert_equal(true, v.method(:mv1).public?) - assert_equal(true, v.method(:mv2).private?) - assert_equal(true, v.method(:mv3).protected?) - assert_equal(false, v.method(:mv2).public?) - assert_equal(false, v.method(:mv3).private?) - assert_equal(false, v.method(:mv1).protected?) - end - - def test_unbound_method_visibility_predicates - assert_equal(true, Visibility.instance_method(:mv1).public?) - assert_equal(true, Visibility.instance_method(:mv2).private?) - assert_equal(true, Visibility.instance_method(:mv3).protected?) - assert_equal(false, Visibility.instance_method(:mv2).public?) - assert_equal(false, Visibility.instance_method(:mv3).private?) - assert_equal(false, Visibility.instance_method(:mv1).protected?) - end - - class VisibilitySub < Visibility - protected :mv1 - public :mv2 - private :mv3 - end - - def test_method_visibility_predicates_with_subclass_visbility_change - v = VisibilitySub.new - assert_equal(false, v.method(:mv1).public?) - assert_equal(false, v.method(:mv2).private?) - assert_equal(false, v.method(:mv3).protected?) - assert_equal(true, v.method(:mv2).public?) - assert_equal(true, v.method(:mv3).private?) - assert_equal(true, v.method(:mv1).protected?) - end - - def test_unbound_method_visibility_predicates_with_subclass_visbility_change - assert_equal(false, VisibilitySub.instance_method(:mv1).public?) - assert_equal(false, VisibilitySub.instance_method(:mv2).private?) - assert_equal(false, VisibilitySub.instance_method(:mv3).protected?) - assert_equal(true, VisibilitySub.instance_method(:mv2).public?) - assert_equal(true, VisibilitySub.instance_method(:mv3).private?) - assert_equal(true, VisibilitySub.instance_method(:mv1).protected?) - end - def rest_parameter(*rest) rest end From 9fc401b689e64dde5fc7cc56c734d5cddd6aa6e1 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Wed, 10 Aug 2022 16:18:27 -0500 Subject: [PATCH 03/44] [ruby/rdoc] Treat text markup (italic, bold, monofont) as blocks (https://github.com/ruby/rdoc/pull/911) https://github.com/ruby/rdoc/commit/dc88f1b425 --- doc/rdoc/markup_reference.rb | 367 ++++++++++++++++++++++++----------- 1 file changed, 253 insertions(+), 114 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index c59f12cfe3c59e..b3d1d97f4f61be 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -51,23 +51,37 @@ # # === Blocks # -# It's convenient to think of markup input as a sequence of _blocks_, -# such as: -# -# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. -# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. -# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. -# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. -# - {Bullet lists}[rdoc-ref:RDoc::MarkupReference@Bullet+Lists]. -# - {Numbered lists}[rdoc-ref:RDoc::MarkupReference@Numbered+Lists]. -# - {Lettered lists}[rdoc-ref:RDoc::MarkupReference@Lettered+Lists]. -# - {Labeled lists}[rdoc-ref:RDoc::MarkupReference@Labeled+Lists]. -# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. -# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. -# - {Directives}[rdoc-ref:RDoc::MarkupReference@Directives]. -# -# All of these except paragraph blocks are distinguished by indentation, -# or by unusual initial or embedded characters. +# It's convenient to think of \RDoc markup input as a sequence of _blocks_ +# of various types (details at the links): +# +# - {Paragraph}[rdoc-ref:RDoc::MarkupReference@Paragraphs]: +# an ordinary paragraph. +# - {Verbatim text block}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]: +# a block of text to be rendered literally. +# - {Code block}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]: +# a verbatim text block containing Ruby code, +# to be rendered with code highlighting. +# - {Block quote}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]: +# a longish quoted passage, to be rendered with indentation +# instead of quote marks. +# - {List}[rdoc-ref:RDoc::MarkupReference@Lists]: items for +# a bullet list, numbered list, lettered list, or labeled list. +# - {Heading}[rdoc-ref:RDoc::MarkupReference@Headings]: +# a section heading. +# - {Horizontal rule}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]: +# a line across the rendered page. +# - {Directive}[rdoc-ref:RDoc::MarkupReference@Directives]: +# various special directions for the rendering. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]: +# text to be rendered in italic, bold, or monofont. +# +# About the blocks: +# +# - Except for a paragraph, a block is distinguished by its indentation, +# or by unusual initial or embedded characters. +# - Any block may appear independently +# (that is, not nested in another block); +# some blocks may be nested, as detailed below. # # ==== Paragraphs # @@ -98,12 +112,13 @@ # # A paragraph may contain nested blocks, including: # -# - Verbatim text blocks. -# - Code blocks. -# - Block quotes. -# - Lists of any type. -# - Headings. -# - Horizontal rules. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. +# - {Lists}[rdoc-ref:RDoc::MarkupReference@Lists]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. # # ==== Verbatim Text Blocks # @@ -140,6 +155,9 @@ # # This is not verbatim text. # +# A verbatim text block may not contain nested blocks of any kind +# -- it's verbatim. +# # ==== Code Blocks # # A special case of verbatim text is the code block, @@ -173,6 +191,9 @@ # Pro tip: If your indented Ruby code does not get highlighted, # it may contain a syntax error. # +# A code block may not contain nested blocks of any kind +# -- it's verbatim. +# # ==== Block Quotes # # You can use the characters >>> (unindented), @@ -181,6 +202,7 @@ # # Example input: # +# Here's a block quote: # >>> # Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer # commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. @@ -194,27 +216,30 @@ # Rendered HTML: # # >>> -# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer -# commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. -# Quisque turpis erat, pharetra eu dui at, sollicitudin accumsan nulla. +# Here's a block quote: +# >>> +# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer +# commodo quam iaculis massa posuere, dictum fringilla justo pulvinar. +# Quisque turpis erat, pharetra eu dui at, sollicitudin accumsan nulla. # -# Aenean congue ligula eu ligula molestie, eu pellentesque purus -# faucibus. In id leo non ligula condimentum lobortis. Duis vestibulum, -# diam in pellentesque aliquet, mi tellus placerat sapien, id euismod -# purus magna ut tortor. +# Aenean congue ligula eu ligula molestie, eu pellentesque purus +# faucibus. In id leo non ligula condimentum lobortis. Duis vestibulum, +# diam in pellentesque aliquet, mi tellus placerat sapien, id euismod +# purus magna ut tortor. +# +# Note that, unlike verbatim text, single newlines are not honored, +# but that a double newline begins a new paragraph in the block quote. # # A block quote may contain nested blocks, including: # # - Other block quotes. -# - Paragraphs. -# - Verbatim text blocks. -# - Code blocks. -# - Lists of any type. -# - Headings. -# - Horizontal rules. -# -# Note that, unlike verbatim text, single newlines are not honored, -# but that a double newline begins a new paragraph in the block quote. +# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Lists}[rdoc-ref:RDoc::MarkupReference@Lists]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. # # ==== Lists # @@ -240,12 +265,13 @@ # A list item may contain nested blocks, including: # # - Other lists of any type. -# - Paragraphs. -# - Verbatim text blocks. -# - Code blocks. -# - Block quotes. -# - Headings. -# - Horizontal rules. +# - {Paragraphs}[rdoc-ref:RDoc::MarkupReference@Paragraphs]. +# - {Verbatim text blocks}[rdoc-ref:RDoc::MarkupReference@Verbatim+Text+Blocks]. +# - {Code blocks}[rdoc-ref:RDoc::MarkupReference@Code+Blocks]. +# - {Block quotes}[rdoc-ref:RDoc::MarkupReference@Block+Quotes]. +# - {Headings}[rdoc-ref:RDoc::MarkupReference@Headings]. +# - {Horizontal rules}[rdoc-ref:RDoc::MarkupReference@Horizontal+Rules]. +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. # # ===== Bullet Lists # @@ -370,30 +396,29 @@ # # ============Still a Heading (Level 6) # # \== Not a Heading # +# A heading may contain only one type of nested block: +# +# - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]. +# # ==== Horizontal Rules # -# A horizontal rule begins with three or more hyphens. +# A horizontal rule consists of a line with three or more hyphens +# and nothing more. # # Example input: # -# # ------ -# # Stuff between. -# # -# # \--- Not a horizontal rule. -# # -# # -- Also not a horizontal rule. -# # -# # --- +# --- +# --- Not a horizontal rule. +# +# -- Also not a horizontal rule. +# --- # # Rendered HTML: # >>> -# ------ -# Stuff between. -# -# \--- Not a horizontal rule. +# --- +# --- Not a horizontal rule. # # -- Also not a horizontal rule. -# # --- # # ==== Directives @@ -584,83 +609,197 @@ # # For C code, the directive may appear in a stand-alone comment # -# === Text Markup +# ==== Text Markup # -# Text in a paragraph, list item (any type), or heading -# may have markup formatting. +# Text markup is metatext that marks text as: # -# ==== Italic +# - Italic. +# - Bold. +# - Monofont. # -# A single word may be italicized by prefixed and suffixed underscores. +# Text markup may contain only one type of nested block: # -# Examples: +# - More text markup: +# italic, bold, monofont. # -# # _Word_ in paragraph. -# # - _Word_ in bullet list item. -# # 1. _Word_ in numbered list item. -# # a. _Word_ in lettered list item. -# # [_word_] _Word_ in labeled list item. -# # ====== _Word_ in heading +# ===== Italic # -# Any text may be italicized via HTML tag +i+ or +em+. +# Text may be marked as italic via HTML tag or . # -# Examples: +# Example input: # -# # Two words in paragraph. -# # - Two words in bullet list item. -# # 1. Two words in numbered list item. -# # a. Two words in lettered list item. -# # [Two words] Two words in labeled list item. -# # ====== Two words in heading +# Two words in a paragraph. # -# ==== Bold +# >>> +# Two words in a block quote. # -# A single word may be made bold by prefixed and suffixed asterisks. +# - Two words in a bullet list item. # -# Examples: +# ====== Two words in a Heading # -# # *Word* in paragraph. -# # - *Word* in bullet list item. -# # 1. *Word* in numbered list item. -# # a. *Word* in lettered list item. -# # [*word*] *Word* in labeled list item. -# # ====== *Word* in heading +# Italicized passage containing *bold* and +monofont+. # -# Any text may be made bold via HTML tag +b+. +# Rendered HTML: +# >>> +# Two words in a paragraph. # -# Examples: +# >>> +# Two words in a block quote. # -# # Two words in paragraph. -# # - Two words in bullet list item. -# # 1. Two words in numbered list item. -# # a. Two words in lettered list item. -# # [Two words] Two words in labeled list item. -# # ====== Two words in heading +# - Two words in a bullet list item. # -# ==== Monofont +# ====== Two words in a Heading # -# A single word may be made monofont -- sometimes called "typewriter font" -- -# by prefixed and suffixed plus-signs. +# Italicized passage containing *bold* and +monofont+. # -# Examples: +# A single word may be italicized via a shorthand: +# prefixed and suffixed underscores. # -# # +Word+ in paragraph. -# # - +Word+ in bullet list item. -# # 1. +Word+ in numbered list item. -# # a. +Word+ in lettered list item. -# # [+word+] +Word+ in labeled list item. -# # ====== +Word+ in heading +# Example input: # -# Any text may be made monofont via HTML tag +tt+ or +code+. +# _Word_ in a paragraph. # -# Examples: +# >>> +# _Word_ in a block quote. +# +# - _Word_ in a bullet list item. +# +# [_word_] _Word_ in a labeled list item. +# +# ====== _Word_ in a Heading +# +# Rendered HTML: +# >>> +# _Word_ in a paragraph. +# +# >>> +# _Word_ in a block quote. +# +# - _Word_ in a bullet list item. +# +# [_word_] _Word_ in a labeled list item. +# +# ====== _Word_ in a Heading +# +# ===== Bold +# +# Text may be marked as bold via HTML tag . +# +# Example input: +# +# Two words in a paragraph. +# +# >>> +# Two words in a block quote. +# +# - Two words in a bullet list item. +# +# ====== Two words in a Heading +# +# Bold passage containing _italics_ and +monofont+. +# +# Rendered HTML: +# +# >>> +# Two words in a paragraph. +# +# >>> +# Two words in a block quote. +# +# - Two words in a bullet list item. +# +# ====== Two words in a Heading +# +# Bold passage containing _italics_ and +monofont+. +# +# A single word may be made bold via a shorthand: +# prefixed and suffixed asterisks. +# +# Example input: +# +# *Word* in a paragraph. +# +# >>> +# *Word* in a block quote. +# +# - *Word* in a bullet list item. +# +# [*word*] *Word* in a labeled list item. +# +# ===== *Word* in a Heading +# +# Rendered HTML: +# +# >>> +# *Word* in a paragraph. +# +# >>> +# *Word* in a block quote. +# +# - *Word* in a bullet list item. +# +# [*word*] *Word* in a labeled list item. +# +# ===== *Word* in a Heading +# +# ===== Monofont +# +# Text may be marked as monofont +# -- sometimes called 'typewriter font' -- +# via HTML tag or . +# +# Example input: +# +# Two words in a paragraph. +# +# >>> +# Two words in a block quote. +# +# - Two words in a bullet list item. +# +# ====== Two words in heading +# +# Monofont passage containing _italics_ and *bold*. +# +# Rendered HTML: +# +# >>> +# Two words in a paragraph. +# +# >>> +# Two words in a block quote. +# +# - Two words in a bullet list item. +# +# ====== Two words in heading +# +# Monofont passage containing _italics_ and *bold*. +# +# A single word may be made monofont by a shorthand: +# prefixed and suffixed plus-signs. +# +# Example input: +# +# +Word+ in a paragraph. +# +# >>> +# +Word+ in a block quote. +# +# - +Word+ in a bullet list item. +# +# ====== +Word+ in a Heading +# +# Rendered HTML: +# +# >>> +# +Word+ in a paragraph. +# +# >>> +# +Word+ in a block quote. +# +# - +Word+ in a bullet list item. # -# # Two words in paragraph. -# # - Two words in bullet list item. -# # 1. Two words in numbered list item. -# # a. Two words in lettered list item. -# # [Two words] Two words in labeled list item. -# # ====== Two words in heading +# ====== +Word+ in a Heading # # ==== Escaping Text Markup # From 74d95744bdb9cf47b8fa07b9a9938c323658d9b9 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 11:02:28 +0900 Subject: [PATCH 04/44] Add `--enable-devel` configure option Since `RUBY_DEVEL` in cppflags has no effect in the configure script and makefiles. --- .github/workflows/compilers.yml | 2 +- configure.ac | 10 +++++++--- template/Makefile.in | 4 +++- win32/configure.bat | 12 ++++++++++++ win32/setup.mak | 4 +++- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml index bd082039b316b1..8ef04f1ef233d2 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -147,6 +147,7 @@ jobs: - { name: disable-dln, env: { append_configure: '--disable-dln' } } - { name: enable-mkmf-verbose, env: { append_configure: '--enable-mkmf-verbose' } } - { name: disable-rubygems, env: { append_configure: '--disable-rubygems' } } + - { name: RUBY_DEVEL, env: { append_configure: '--enable-devel' } } - { name: OPT_THREADED_CODE=1, env: { cppflags: '-DOPT_THREADED_CODE=1' } } - { name: OPT_THREADED_CODE=2, env: { cppflags: '-DOPT_THREADED_CODE=2' } } @@ -154,7 +155,6 @@ jobs: - { name: NDEBUG, env: { cppflags: '-DNDEBUG' } } - { name: RUBY_DEBUG, env: { cppflags: '-DRUBY_DEBUG' } } - - { name: RUBY_DEVEL, env: { cppflags: '-DRUBY_DEVEL' } } # - { name: ARRAY_DEBUG, env: { cppflags: '-DARRAY_DEBUG' } } # - { name: BIGNUM_DEBUG, env: { cppflags: '-DBIGNUM_DEBUG' } } # - { name: CCAN_LIST_DEBUG, env: { cppflags: '-DCCAN_LIST_DEBUG' } } diff --git a/configure.ac b/configure.ac index 575bdf663155fd..bc21c262922161 100644 --- a/configure.ac +++ b/configure.ac @@ -622,8 +622,13 @@ AS_IF([test "$fdeclspec" = yes], [ RUBY_APPEND_OPTIONS(CXXFLAGS, -fdeclspec) ]) -AS_IF([test "x$RUBY_DEVEL" != xyes], [RUBY_DEVEL=no]) -particular_werror_flags=$RUBY_DEVEL +AC_ARG_ENABLE(devel, + AS_HELP_STRING([--enable-devel], [enable development build]), + [RUBY_DEVEL=$enableval], + [AS_IF([test "x${RUBY_DEVEL-no}" != xyes], [RUBY_DEVEL=])] +)dnl +AC_SUBST(RUBY_DEVEL) +particular_werror_flags=${RUBY_DEVEL:-no} AC_ARG_ENABLE(werror, AS_HELP_STRING([--disable-werror], [don't make warnings into errors @@ -867,7 +872,6 @@ AS_IF([test "$GCC" = yes], [ test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-g3, [debugflags=-g3])} ]) test $ac_cv_prog_cc_g = yes && : ${debugflags=-g} -AS_IF([test "x$RUBY_DEVEL" = xyes], [RUBY_APPEND_OPTION(XCFLAGS, -DRUBY_DEVEL=1)]) AS_IF([test "$GCC" = ""], [ AS_CASE(["$target_os"],[aix*],[warnflags="$warnflags -qinfo=por" rb_cv_warnflags="$rb_cv_warnflags -qinfo=por"]) diff --git a/template/Makefile.in b/template/Makefile.in index a8581260b99147..756af363e4ba8e 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -89,7 +89,9 @@ optflags = @optflags@ debugflags = @debugflags@ warnflags = @warnflags@ @strict_warnflags@ cppflags = @cppflags@ -XCFLAGS = @XCFLAGS@ $(INCFLAGS) +RUBY_DEVEL = @RUBY_DEVEL@ # "yes" or empty +_RUBY_DEVEL_enabled = $(RUBY_DEVEL:no=) +XCFLAGS = @XCFLAGS@ $(INCFLAGS) $(_RUBY_DEVEL_enabled:yes=-DRUBY_DEVEL=1) USE_RUBYGEMS = @USE_RUBYGEMS@ USE_RUBYGEMS_ = $(USE_RUBYGEMS:yes=) CPPFLAGS = @CPPFLAGS@ $(USE_RUBYGEMS_:no=-DDISABLE_RUBYGEMS=1) diff --git a/win32/configure.bat b/win32/configure.bat index 573f8bf0e581c3..4602b41ec599a2 100755 --- a/win32/configure.bat +++ b/win32/configure.bat @@ -34,6 +34,8 @@ if "%1" == "--enable-install-static-library" goto :enable-lib if "%1" == "--disable-install-static-library" goto :disable-lib if "%1" == "--enable-debug-env" goto :enable-debug-env if "%1" == "--disable-debug-env" goto :disable-debug-env +if "%1" == "--enable-devel" goto :enable-devel +if "%1" == "--disable-devel" goto :disable-devel if "%1" == "--enable-rubygems" goto :enable-rubygems if "%1" == "--disable-rubygems" goto :disable-rubygems if "%1" == "--enable-mjit-support" goto :enable-mjit-support @@ -143,6 +145,16 @@ goto :loop ; echo>>confargs.tmp %1 \ shift goto :loop ; +:enable-devel + echo>> ~tmp~.mak "RUBY_DEVEL=yes" \ + echo>>confargs.tmp %1 \ + shift +goto :loop ; +:disable-devel + echo>> ~tmp~.mak "RUBY_DEVEL=no" \ + echo>>confargs.tmp %1 \ + shift +goto :loop ; :enable-rubygems echo>> ~tmp~.mak "USE_RUBYGEMS=yes" \ echo>>confargs.tmp %1 \ diff --git a/win32/setup.mak b/win32/setup.mak index c84d4066eabbdc..39323c61c2464f 100644 --- a/win32/setup.mak +++ b/win32/setup.mak @@ -80,6 +80,9 @@ $(BANG)else HAVE_BASERUBY = no $(BANG)endif << +!if "$(RUBY_DEVEL)" == "yes" + RUBY_DEVEL = yes +!endif !if "$(GIT)" != "" @echo GIT = $(GIT)>> $(MAKEFILE) !endif @@ -197,7 +200,6 @@ echo MINOR = RUBY_VERSION_MINOR echo TEENY = RUBY_VERSION_TEENY echo ABI_VERSION = RUBY_ABI_VERSION #if defined RUBY_PATCHLEVEL && RUBY_PATCHLEVEL < 0 -echo RUBY_DEVEL = yes #endif set /a MSC_VER = _MSC_VER #if _MSC_VER >= 1920 From 26054c74619d36b2781e872fad15a1a0bfab1be1 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 15:21:03 +0900 Subject: [PATCH 05/44] Fix paths of exts.mk to clean exts.mk files are one level under the top of extension directories. --- template/exts.mk.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/exts.mk.tmpl b/template/exts.mk.tmpl index c5f8478d76d79c..5595a08da1d1dd 100644 --- a/template/exts.mk.tmpl +++ b/template/exts.mk.tmpl @@ -154,7 +154,7 @@ ext/extinit.<%=objext%>: % end $(Q)<%= submake %><%=mflags%> V=$(V) $(@F) % if /^(dist|real)clean$/ =~ tgt - $(Q)$(RM) $(@D)/exts.mk + $(Q)$(RM) <%=t[%r[\A(?:\.[^/]+/)?(?:[^/]+/){2}]]%>exts.mk $(Q)$(RMDIRS) $(@D) % end % end From 0c9803b0fdfd17981bd9f59767adab0207c3a74d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 17:09:17 +0900 Subject: [PATCH 06/44] The "gems" build directory was rename as ".bundle" --- common.mk | 12 ++++++------ template/Makefile.in | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/common.mk b/common.mk index 7e7e0bb67a8ad2..9f89e0ec8af26c 100644 --- a/common.mk +++ b/common.mk @@ -687,18 +687,18 @@ realclean-platform: distclean-platform realclean-spec: distclean-spec realclean-rubyspec: realclean-spec -clean-ext:: ext/clean gems/clean timestamp/clean -distclean-ext:: ext/distclean gems/distclean timestamp/distclean -realclean-ext:: ext/realclean gems/realclean timestamp/realclean +clean-ext:: ext/clean .bundle/clean timestamp/clean +distclean-ext:: ext/distclean .bundle/distclean timestamp/distclean +realclean-ext:: ext/realclean .bundle/realclean timestamp/realclean ext/clean.mk ext/distclean.mk ext/realclean.mk:: ext/clean:: ext/clean.mk ext/distclean:: ext/distclean.mk ext/realclean:: ext/realclean.mk -timestamp/clean:: ext/clean gems/clean -timestamp/distclean:: ext/distclean gems/distclean -timestamp/realclean:: ext/realclean gems/realclean +timestamp/clean:: ext/clean .bundle/clean +timestamp/distclean:: ext/distclean .bundle/distclean +timestamp/realclean:: ext/realclean .bundle/realclean timestamp/clean timestamp/distclean timestamp/realclean:: $(Q)$(RM) $(TIMESTAMPDIR)/.*.time $(TIMESTAMPDIR)/$(arch)/.time diff --git a/template/Makefile.in b/template/Makefile.in index 756af363e4ba8e..09d69c8d9ccc13 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -532,12 +532,12 @@ ext/clean.mk ext/distclean.mk ext/realclean.mk:: ext/clean:: ext/clean.sub ext/distclean:: ext/distclean.sub ext/realclean:: ext/realclean.sub -gems/clean:: gems/clean.sub -gems/distclean:: gems/distclean.sub -gems/realclean:: gems/realclean.sub +.bundle/clean:: .bundle/clean.sub +.bundle/distclean:: .bundle/distclean.sub +.bundle/realclean:: .bundle/realclean.sub ext/clean.sub ext/distclean.sub ext/realclean.sub \ -gems/clean.sub gems/distclean.sub gems/realclean.sub:: +.bundle/clean.sub .bundle/distclean.sub .bundle/realclean.sub:: $(Q) set dummy `echo "${EXTS}" | tr , ' '`; shift; \ test "$$#" = 0 && set .; \ set dummy `\ @@ -553,7 +553,7 @@ gems/clean.sub gems/distclean.sub gems/realclean.sub:: fi; \ done || true -ext/distclean ext/realclean gems/distclean gems/realclean:: +ext/distclean ext/realclean .bundle/distclean .bundle/realclean:: $(Q) set dummy `echo "${EXTS}" | tr , ' '`; shift; \ test "$$#" = 0 && set .; \ cd $(@D) 2>/dev/null && \ From 32d1ce96e09773e809d575c17b916012d88d6ffc Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 17:42:56 +0900 Subject: [PATCH 07/44] Fix race conditions when cleaning extensions Clean built directories by `make distclean`, and then clean leftover makefiles for skipped extensions. --- template/Makefile.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/template/Makefile.in b/template/Makefile.in index 09d69c8d9ccc13..7968619f9a1a16 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -536,6 +536,10 @@ ext/realclean:: ext/realclean.sub .bundle/distclean:: .bundle/distclean.sub .bundle/realclean:: .bundle/realclean.sub +ext/clean.sub .bundle/clean.sub:: ext/clean.mk +ext/distclean.sub .bundle/distclean.sub:: ext/distclean.mk +ext/realclean.sub .bundle/realclean.sub:: ext/realclean.mk + ext/clean.sub ext/distclean.sub ext/realclean.sub \ .bundle/clean.sub .bundle/distclean.sub .bundle/realclean.sub:: $(Q) set dummy `echo "${EXTS}" | tr , ' '`; shift; \ From cfb9624460a295e4e1723301486d89058c228e07 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Thu, 11 Aug 2022 03:16:49 -0700 Subject: [PATCH 08/44] Fix Array#[] with ArithmeticSequence with negative steps (#5739) * Fix Array#[] with ArithmeticSequence with negative steps Previously, Array#[] when called with an ArithmeticSequence with a negative step did not handle all cases correctly, especially cases involving infinite ranges, inverted ranges, and/or exclusive ends. Fixes [Bug #18247] * Add Array#slice tests for ArithmeticSequence with negative step to test_array Add tests of rb_arithmetic_sequence_beg_len_step C-API function. * Fix ext/-test-/arith_seq/beg_len_step/depend * Rename local variables * Fix a variable name Co-authored-by: Kenta Murata <3959+mrkn@users.noreply.github.com> --- array.c | 5 +- enumerator.c | 7 + .../arith_seq/beg_len_step/beg_len_step.c | 19 +++ ext/-test-/arith_seq/beg_len_step/depend | 161 ++++++++++++++++++ ext/-test-/arith_seq/beg_len_step/extconf.rb | 2 + spec/ruby/core/array/shared/slice.rb | 96 +++++++++++ .../arith_seq/test_arith_seq_beg_len_step.rb | 52 ++++++ test/ruby/test_array.rb | 90 ++++++++++ 8 files changed, 431 insertions(+), 1 deletion(-) create mode 100644 ext/-test-/arith_seq/beg_len_step/beg_len_step.c create mode 100644 ext/-test-/arith_seq/beg_len_step/depend create mode 100644 ext/-test-/arith_seq/beg_len_step/extconf.rb create mode 100644 test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb diff --git a/array.c b/array.c index b2ebf3c0e9ebee..793a53f17b24b2 100644 --- a/array.c +++ b/array.c @@ -1373,13 +1373,16 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step) const VALUE *values = RARRAY_CONST_PTR_TRANSIENT(ary); const long orig_len = len; - if ((step > 0 && step >= len) || (step < 0 && (step < -len))) { + if (step > 0 && step >= len) { VALUE result = ary_new(klass, 1); VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result); RB_OBJ_WRITE(result, ptr, values[offset]); ARY_SET_EMBED_LEN(result, 1); return result; } + else if (step < 0 && step < -len) { + step = -len; + } long ustep = (step < 0) ? -step : step; len = (len + ustep - 1) / ustep; diff --git a/enumerator.c b/enumerator.c index d7546ee9e82aa5..2c9858cda6d0f5 100644 --- a/enumerator.c +++ b/enumerator.c @@ -3802,6 +3802,13 @@ rb_arithmetic_sequence_beg_len_step(VALUE obj, long *begp, long *lenp, long *ste *stepp = step; if (step < 0) { + if (aseq.exclude_end && !NIL_P(aseq.end)) { + /* Handle exclusion before range reversal */ + aseq.end = LONG2NUM(NUM2LONG(aseq.end) + 1); + + /* Don't exclude the previous beginning */ + aseq.exclude_end = 0; + } VALUE tmp = aseq.begin; aseq.begin = aseq.end; aseq.end = tmp; diff --git a/ext/-test-/arith_seq/beg_len_step/beg_len_step.c b/ext/-test-/arith_seq/beg_len_step/beg_len_step.c new file mode 100644 index 00000000000000..40c8cbee82b9fa --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/beg_len_step.c @@ -0,0 +1,19 @@ +#include "ruby/ruby.h" + +static VALUE +arith_seq_s_beg_len_step(VALUE mod, VALUE obj, VALUE len, VALUE err) +{ + VALUE r; + long beg, len2, step; + + r = rb_arithmetic_sequence_beg_len_step(obj, &beg, &len2, &step, NUM2LONG(len), NUM2INT(err)); + + return rb_ary_new_from_args(4, r, LONG2NUM(beg), LONG2NUM(len2), LONG2NUM(step)); +} + +void +Init_beg_len_step(void) +{ + VALUE cArithSeq = rb_path2class("Enumerator::ArithmeticSequence"); + rb_define_singleton_method(cArithSeq, "__beg_len_step__", arith_seq_s_beg_len_step, 3); +} diff --git a/ext/-test-/arith_seq/beg_len_step/depend b/ext/-test-/arith_seq/beg_len_step/depend new file mode 100644 index 00000000000000..36a2c4c71b1214 --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/depend @@ -0,0 +1,161 @@ +# AUTOGENERATED DEPENDENCIES START +beg_len_step.o: $(RUBY_EXTCONF_H) +beg_len_step.o: $(arch_hdrdir)/ruby/config.h +beg_len_step.o: $(hdrdir)/ruby/assert.h +beg_len_step.o: $(hdrdir)/ruby/backward.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/assume.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/attributes.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/bool.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/inttypes.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/limits.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/long_long.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/stdalign.h +beg_len_step.o: $(hdrdir)/ruby/backward/2/stdarg.h +beg_len_step.o: $(hdrdir)/ruby/defines.h +beg_len_step.o: $(hdrdir)/ruby/intern.h +beg_len_step.o: $(hdrdir)/ruby/internal/abi.h +beg_len_step.o: $(hdrdir)/ruby/internal/anyargs.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/char.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/double.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/int.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/long.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/short.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +beg_len_step.o: $(hdrdir)/ruby/internal/assume.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/artificial.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/cold.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/const.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/constexpr.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/deprecated.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/forceinline.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/format.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noalias.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noexcept.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noinline.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/nonnull.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/noreturn.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/pure.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/restrict.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/warning.h +beg_len_step.o: $(hdrdir)/ruby/internal/attr/weakref.h +beg_len_step.o: $(hdrdir)/ruby/internal/cast.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +beg_len_step.o: $(hdrdir)/ruby/internal/compiler_since.h +beg_len_step.o: $(hdrdir)/ruby/internal/config.h +beg_len_step.o: $(hdrdir)/ruby/internal/constant_p.h +beg_len_step.o: $(hdrdir)/ruby/internal/core.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rarray.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rbasic.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rbignum.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rclass.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rdata.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rfile.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rhash.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/robject.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rregexp.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rstring.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rstruct.h +beg_len_step.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +beg_len_step.o: $(hdrdir)/ruby/internal/ctype.h +beg_len_step.o: $(hdrdir)/ruby/internal/dllexport.h +beg_len_step.o: $(hdrdir)/ruby/internal/dosish.h +beg_len_step.o: $(hdrdir)/ruby/internal/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/eval.h +beg_len_step.o: $(hdrdir)/ruby/internal/event.h +beg_len_step.o: $(hdrdir)/ruby/internal/fl_type.h +beg_len_step.o: $(hdrdir)/ruby/internal/gc.h +beg_len_step.o: $(hdrdir)/ruby/internal/glob.h +beg_len_step.o: $(hdrdir)/ruby/internal/globals.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/builtin.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/c_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/extension.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/feature.h +beg_len_step.o: $(hdrdir)/ruby/internal/has/warning.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/array.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/bignum.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/class.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/compar.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/complex.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/cont.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/dir.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/enum.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/enumerator.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/error.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/eval.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/file.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/gc.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/hash.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/io.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/load.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/marshal.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/numeric.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/object.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/parse.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/proc.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/process.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/random.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/range.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/rational.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/re.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/ruby.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/select.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/signal.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/sprintf.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/string.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/struct.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/thread.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/time.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/variable.h +beg_len_step.o: $(hdrdir)/ruby/internal/intern/vm.h +beg_len_step.o: $(hdrdir)/ruby/internal/interpreter.h +beg_len_step.o: $(hdrdir)/ruby/internal/iterator.h +beg_len_step.o: $(hdrdir)/ruby/internal/memory.h +beg_len_step.o: $(hdrdir)/ruby/internal/method.h +beg_len_step.o: $(hdrdir)/ruby/internal/module.h +beg_len_step.o: $(hdrdir)/ruby/internal/newobj.h +beg_len_step.o: $(hdrdir)/ruby/internal/rgengc.h +beg_len_step.o: $(hdrdir)/ruby/internal/scan_args.h +beg_len_step.o: $(hdrdir)/ruby/internal/special_consts.h +beg_len_step.o: $(hdrdir)/ruby/internal/static_assert.h +beg_len_step.o: $(hdrdir)/ruby/internal/stdalign.h +beg_len_step.o: $(hdrdir)/ruby/internal/stdbool.h +beg_len_step.o: $(hdrdir)/ruby/internal/symbol.h +beg_len_step.o: $(hdrdir)/ruby/internal/value.h +beg_len_step.o: $(hdrdir)/ruby/internal/value_type.h +beg_len_step.o: $(hdrdir)/ruby/internal/variable.h +beg_len_step.o: $(hdrdir)/ruby/internal/warning_push.h +beg_len_step.o: $(hdrdir)/ruby/internal/xmalloc.h +beg_len_step.o: $(hdrdir)/ruby/missing.h +beg_len_step.o: $(hdrdir)/ruby/ruby.h +beg_len_step.o: $(hdrdir)/ruby/st.h +beg_len_step.o: $(hdrdir)/ruby/subst.h +beg_len_step.o: beg_len_step.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/arith_seq/beg_len_step/extconf.rb b/ext/-test-/arith_seq/beg_len_step/extconf.rb new file mode 100644 index 00000000000000..e72b3ad01f9c09 --- /dev/null +++ b/ext/-test-/arith_seq/beg_len_step/extconf.rb @@ -0,0 +1,2 @@ +# frozen_string_literal: false +create_makefile("-test-/arith_seq/beg_len_step") diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb index 3b09fdcbc6fc2c..8fb33738b9ce6f 100644 --- a/spec/ruby/core/array/shared/slice.rb +++ b/spec/ruby/core/array/shared/slice.rb @@ -784,6 +784,102 @@ def to.to_int() -2 end a.send(@method, (...-9)).should == [] end + ruby_version_is "3.2" do + describe "can be sliced with Enumerator::ArithmeticSequence" do + it "with infinite/inverted ranges and negative steps" do + @array = [0, 1, 2, 3, 4, 5] + @array.send(@method, (2..).step(-1)).should == [2, 1, 0] + @array.send(@method, (2..).step(-2)).should == [2, 0] + @array.send(@method, (2..).step(-3)).should == [2] + @array.send(@method, (2..).step(-4)).should == [2] + + @array.send(@method, (-3..).step(-1)).should == [3, 2, 1, 0] + @array.send(@method, (-3..).step(-2)).should == [3, 1] + @array.send(@method, (-3..).step(-3)).should == [3, 0] + @array.send(@method, (-3..).step(-4)).should == [3] + @array.send(@method, (-3..).step(-5)).should == [3] + + @array.send(@method, (..0).step(-1)).should == [5, 4, 3, 2, 1, 0] + @array.send(@method, (..0).step(-2)).should == [5, 3, 1] + @array.send(@method, (..0).step(-3)).should == [5, 2] + @array.send(@method, (..0).step(-4)).should == [5, 1] + @array.send(@method, (..0).step(-5)).should == [5, 0] + @array.send(@method, (..0).step(-6)).should == [5] + @array.send(@method, (..0).step(-7)).should == [5] + + @array.send(@method, (...0).step(-1)).should == [5, 4, 3, 2, 1] + @array.send(@method, (...0).step(-2)).should == [5, 3, 1] + @array.send(@method, (...0).step(-3)).should == [5, 2] + @array.send(@method, (...0).step(-4)).should == [5, 1] + @array.send(@method, (...0).step(-5)).should == [5] + @array.send(@method, (...0).step(-6)).should == [5] + + @array.send(@method, (...1).step(-1)).should == [5, 4, 3, 2] + @array.send(@method, (...1).step(-2)).should == [5, 3] + @array.send(@method, (...1).step(-3)).should == [5, 2] + @array.send(@method, (...1).step(-4)).should == [5] + @array.send(@method, (...1).step(-5)).should == [5] + + @array.send(@method, (..-5).step(-1)).should == [5, 4, 3, 2, 1] + @array.send(@method, (..-5).step(-2)).should == [5, 3, 1] + @array.send(@method, (..-5).step(-3)).should == [5, 2] + @array.send(@method, (..-5).step(-4)).should == [5, 1] + @array.send(@method, (..-5).step(-5)).should == [5] + @array.send(@method, (..-5).step(-6)).should == [5] + + @array.send(@method, (...-5).step(-1)).should == [5, 4, 3, 2] + @array.send(@method, (...-5).step(-2)).should == [5, 3] + @array.send(@method, (...-5).step(-3)).should == [5, 2] + @array.send(@method, (...-5).step(-4)).should == [5] + @array.send(@method, (...-5).step(-5)).should == [5] + + @array.send(@method, (4..1).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (4..1).step(-2)).should == [4, 2] + @array.send(@method, (4..1).step(-3)).should == [4, 1] + @array.send(@method, (4..1).step(-4)).should == [4] + @array.send(@method, (4..1).step(-5)).should == [4] + + @array.send(@method, (4...1).step(-1)).should == [4, 3, 2] + @array.send(@method, (4...1).step(-2)).should == [4, 2] + @array.send(@method, (4...1).step(-3)).should == [4] + @array.send(@method, (4...1).step(-4)).should == [4] + + @array.send(@method, (-2..1).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (-2..1).step(-2)).should == [4, 2] + @array.send(@method, (-2..1).step(-3)).should == [4, 1] + @array.send(@method, (-2..1).step(-4)).should == [4] + @array.send(@method, (-2..1).step(-5)).should == [4] + + @array.send(@method, (-2...1).step(-1)).should == [4, 3, 2] + @array.send(@method, (-2...1).step(-2)).should == [4, 2] + @array.send(@method, (-2...1).step(-3)).should == [4] + @array.send(@method, (-2...1).step(-4)).should == [4] + + @array.send(@method, (4..-5).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (4..-5).step(-2)).should == [4, 2] + @array.send(@method, (4..-5).step(-3)).should == [4, 1] + @array.send(@method, (4..-5).step(-4)).should == [4] + @array.send(@method, (4..-5).step(-5)).should == [4] + + @array.send(@method, (4...-5).step(-1)).should == [4, 3, 2] + @array.send(@method, (4...-5).step(-2)).should == [4, 2] + @array.send(@method, (4...-5).step(-3)).should == [4] + @array.send(@method, (4...-5).step(-4)).should == [4] + + @array.send(@method, (-2..-5).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (-2..-5).step(-2)).should == [4, 2] + @array.send(@method, (-2..-5).step(-3)).should == [4, 1] + @array.send(@method, (-2..-5).step(-4)).should == [4] + @array.send(@method, (-2..-5).step(-5)).should == [4] + + @array.send(@method, (-2...-5).step(-1)).should == [4, 3, 2] + @array.send(@method, (-2...-5).step(-2)).should == [4, 2] + @array.send(@method, (-2...-5).step(-3)).should == [4] + @array.send(@method, (-2...-5).step(-4)).should == [4] + end + end + end + it "can accept nil...nil ranges" do a = [0, 1, 2, 3, 4, 5] a.send(@method, eval("(nil...nil)")).should == a diff --git a/test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb b/test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb new file mode 100644 index 00000000000000..4320c1f20dc233 --- /dev/null +++ b/test/-ext-/arith_seq/test_arith_seq_beg_len_step.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: false +require 'test/unit' + +class Test_ArithSeq < Test::Unit::TestCase + def test_beg_len_step + assert_separately([], <<-"end;") #do + require '-test-/arith_seq/beg_len_step' + + r, = Enumerator::ArithmeticSequence.__beg_len_step__([1, 2, 3], 0, 0) + assert_equal(false, r) + + r, = Enumerator::ArithmeticSequence.__beg_len_step__([1, 2, 3], 1, 0) + assert_equal(false, r) + + r, = Enumerator::ArithmeticSequence.__beg_len_step__([1, 2, 3], 3, 0) + assert_equal(false, r) + + r, = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 0, 0) + assert_equal(nil, r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 1, 0) + assert_equal([true, 1, 0, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 2, 0) + assert_equal([true, 1, 1, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 3, 0) + assert_equal([true, 1, 2, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 4, 0) + assert_equal([true, 1, 3, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 5, 0) + assert_equal([true, 1, 3, 1], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__((-10..10).step(2), 24, 0) + assert_equal([true, 14, 0, 2], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__((-10..10).step(3), 24, 0) + assert_equal([true, 14, 0, 3], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__((-10..10).step(3), 22, 0) + assert_equal([true, 12, 0, 3], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__((-10..10).step(-3), 22, 0) + assert_equal([true, 10, 3, -3], r) + + r = Enumerator::ArithmeticSequence.__beg_len_step__(1..3, 0, 1) + assert_equal([true, 1, 3, 1], r) + end; + end +end diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index e376d76a169d86..6ee468eaef29c7 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1580,6 +1580,96 @@ def test_slice assert_equal_instance(a.values_at(*idx), a.slice((3..90)%2)) idx = 90.step(3, -2).to_a assert_equal_instance(a.values_at(*idx), a.slice((90 .. 3)% -2)) + + a = [0, 1, 2, 3, 4, 5] + assert_equal([2, 1, 0], a.slice((2..).step(-1))) + assert_equal([2, 0], a.slice((2..).step(-2))) + assert_equal([2], a.slice((2..).step(-3))) + assert_equal([2], a.slice((2..).step(-4))) + + assert_equal([3, 2, 1, 0], a.slice((-3..).step(-1))) + assert_equal([3, 1], a.slice((-3..).step(-2))) + assert_equal([3, 0], a.slice((-3..).step(-3))) + assert_equal([3], a.slice((-3..).step(-4))) + assert_equal([3], a.slice((-3..).step(-5))) + + assert_equal([5, 4, 3, 2, 1, 0], a.slice((..0).step(-1))) + assert_equal([5, 3, 1], a.slice((..0).step(-2))) + assert_equal([5, 2], a.slice((..0).step(-3))) + assert_equal([5, 1], a.slice((..0).step(-4))) + assert_equal([5, 0], a.slice((..0).step(-5))) + assert_equal([5], a.slice((..0).step(-6))) + assert_equal([5], a.slice((..0).step(-7))) + + assert_equal([5, 4, 3, 2, 1], a.slice((...0).step(-1))) + assert_equal([5, 3, 1], a.slice((...0).step(-2))) + assert_equal([5, 2], a.slice((...0).step(-3))) + assert_equal([5, 1], a.slice((...0).step(-4))) + assert_equal([5], a.slice((...0).step(-5))) + assert_equal([5], a.slice((...0).step(-6))) + + assert_equal([5, 4, 3, 2], a.slice((...1).step(-1))) + assert_equal([5, 3], a.slice((...1).step(-2))) + assert_equal([5, 2], a.slice((...1).step(-3))) + assert_equal([5], a.slice((...1).step(-4))) + assert_equal([5], a.slice((...1).step(-5))) + + assert_equal([5, 4, 3, 2, 1], a.slice((..-5).step(-1))) + assert_equal([5, 3, 1], a.slice((..-5).step(-2))) + assert_equal([5, 2], a.slice((..-5).step(-3))) + assert_equal([5, 1], a.slice((..-5).step(-4))) + assert_equal([5], a.slice((..-5).step(-5))) + assert_equal([5], a.slice((..-5).step(-6))) + + assert_equal([5, 4, 3, 2], a.slice((...-5).step(-1))) + assert_equal([5, 3], a.slice((...-5).step(-2))) + assert_equal([5, 2], a.slice((...-5).step(-3))) + assert_equal([5], a.slice((...-5).step(-4))) + assert_equal([5], a.slice((...-5).step(-5))) + + assert_equal([4, 3, 2, 1], a.slice((4..1).step(-1))) + assert_equal([4, 2], a.slice((4..1).step(-2))) + assert_equal([4, 1], a.slice((4..1).step(-3))) + assert_equal([4], a.slice((4..1).step(-4))) + assert_equal([4], a.slice((4..1).step(-5))) + + assert_equal([4, 3, 2], a.slice((4...1).step(-1))) + assert_equal([4, 2], a.slice((4...1).step(-2))) + assert_equal([4], a.slice((4...1).step(-3))) + assert_equal([4], a.slice((4...1).step(-4))) + + assert_equal([4, 3, 2, 1], a.slice((-2..1).step(-1))) + assert_equal([4, 2], a.slice((-2..1).step(-2))) + assert_equal([4, 1], a.slice((-2..1).step(-3))) + assert_equal([4], a.slice((-2..1).step(-4))) + assert_equal([4], a.slice((-2..1).step(-5))) + + assert_equal([4, 3, 2], a.slice((-2...1).step(-1))) + assert_equal([4, 2], a.slice((-2...1).step(-2))) + assert_equal([4], a.slice((-2...1).step(-3))) + assert_equal([4], a.slice((-2...1).step(-4))) + + assert_equal([4, 3, 2, 1], a.slice((4..-5).step(-1))) + assert_equal([4, 2], a.slice((4..-5).step(-2))) + assert_equal([4, 1], a.slice((4..-5).step(-3))) + assert_equal([4], a.slice((4..-5).step(-4))) + assert_equal([4], a.slice((4..-5).step(-5))) + + assert_equal([4, 3, 2], a.slice((4...-5).step(-1))) + assert_equal([4, 2], a.slice((4...-5).step(-2))) + assert_equal([4], a.slice((4...-5).step(-3))) + assert_equal([4], a.slice((4...-5).step(-4))) + + assert_equal([4, 3, 2, 1], a.slice((-2..-5).step(-1))) + assert_equal([4, 2], a.slice((-2..-5).step(-2))) + assert_equal([4, 1], a.slice((-2..-5).step(-3))) + assert_equal([4], a.slice((-2..-5).step(-4))) + assert_equal([4], a.slice((-2..-5).step(-5))) + + assert_equal([4, 3, 2], a.slice((-2...-5).step(-1))) + assert_equal([4, 2], a.slice((-2...-5).step(-2))) + assert_equal([4], a.slice((-2...-5).step(-3))) + assert_equal([4], a.slice((-2...-5).step(-4))) end def test_slice_out_of_range From c361cf44c03275405989022054d7c20efcc2a2ce Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 11 Aug 2022 08:51:04 -0500 Subject: [PATCH 09/44] [ruby/rdoc] [DOC] Make example formats explicit and consistent (https://github.com/ruby/rdoc/pull/913) https://github.com/ruby/rdoc/commit/7e6ef6c855 --- doc/rdoc/markup_reference.rb | 153 ++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index b3d1d97f4f61be..059511f478e009 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -29,16 +29,37 @@ # see :nodoc:, :doc:, and :notnew. # - \RDoc directives in single-line comments; # see other {Directives}[rdoc-ref:RDoc::MarkupReference@Directives]. -# - The Ruby code itself; -# see {Documentation Derived from Ruby Code}[rdoc-ref:RDoc::MarkupReference@Documentation+Derived+from+Ruby+Code] +# - The Ruby code itself (but not from C code); +# see {Documentation Derived from Ruby Code}[rdoc-ref:RDoc::MarkupReference@Documentation+Derived+from+Ruby+Code]. # # == Markup in Comments # -# A single-line or multi-line comment that immediately precedes -# the definition of a class, module, method, alias, constant, or attribute -# becomes the documentation for that defined object. +# The treatment of markup in comments varies according to the type of file: # -# (\RDoc ignores other such comments that do not precede definitions.) +# - .rb (Ruby code file): markup is parsed from Ruby comments. +# - .c (C code file): markup is parsed from C comments. +# - .rdoc (RDoc text file): markup is parsed from the entire file. +# +# The comment associated with +# a Ruby class, module, method, alias, constant, or attribute +# becomes the documentation for that defined object: +# +# - In a Ruby file, that comment immediately precedes +# the definition of the object. +# - In a C file, that comment immediately precedes +# the function that implements a method, +# or otherwise immediately precedes the definition of the object. +# +# In either a Ruby or a C file, +# \RDoc ignores comments that do not precede object definitions. +# +# In an \RDoc file, the text is not associated with any code object, +# but may (depending on how the documentation is built), +# become a separate page. +# +# Almost all examples on this page are all RDoc-like; +# that is, they have no comment markers like Ruby # +# or C /* ... */. # # === Margins # @@ -96,11 +117,11 @@ # # Example input: # -# # \RDoc produces HTML and command-line documentation for Ruby projects. -# # \RDoc includes the rdoc and ri tools for generating and displaying -# # documentation from the command-line. -# # -# # You'll love it. +# \RDoc produces HTML and command-line documentation for Ruby projects. +# \RDoc includes the rdoc and ri tools for generating and displaying +# documentation from the command-line. +# +# You'll love it. # # Rendered HTML: # >>> @@ -133,15 +154,15 @@ # # Example input: # -# # This is not verbatim text. -# # -# # This is verbatim text. -# # Whitespace is honored. # See? -# # Whitespace is honored. # See? -# # -# # This is still the same verbatim text block. -# # -# # This is not verbatim text. +# This is not verbatim text. +# +# This is verbatim text. +# Whitespace is honored. # See? +# Whitespace is honored. # See? +# +# This is still the same verbatim text block. +# +# This is not verbatim text. # # Rendered HTML: # >>> @@ -279,13 +300,13 @@ # # Example input: # -# # - An item. -# # - Another. -# # - An item spanning -# # multiple lines. -# # -# # * Yet another. -# # - Last one. +# - An item. +# - Another. +# - An item spanning +# multiple lines. +# +# * Yet another. +# - Last one. # # Rendered HTML: # >>> @@ -305,13 +326,13 @@ # # Example input: # -# # 100. An item. -# # 10. Another. -# # 1. An item spanning -# # multiple lines. -# # -# # 1. Yet another. -# # 1000. Last one. +# 100. An item. +# 10. Another. +# 1. An item spanning +# multiple lines. +# +# 1. Yet another. +# 1000. Last one. # # Rendered HTML: # >>> @@ -331,13 +352,13 @@ # # Example input: # -# # z. An item. -# # y. Another. -# # x. An item spanning -# # multiple lines. -# # -# # x. Yet another. -# # a. Last one. +# z. An item. +# y. Another. +# x. An item spanning +# multiple lines. +# +# x. Yet another. +# a. Last one. # # Rendered HTML: # >>> @@ -356,13 +377,13 @@ # # Example input: # -# # [foo] An item. -# # bat:: Another. -# # [bag] An item spanning -# # multiple lines. -# # -# # [bar baz] Yet another. -# # bam:: Last one. +# [foo] An item. +# bat:: Another. +# [bag] An item spanning +# multiple lines. +# +# [bar baz] Yet another. +# bam:: Last one. # # Rendered HTML: # >>> @@ -381,20 +402,20 @@ # # Examples: # -# # = Section 1 -# # == Section 1.1 -# # === Section 1.1.1 -# # === Section 1.1.2 -# # == Section 1.2 -# # = Section 2 -# # = Foo -# # == Bar -# # === Baz -# # ==== Bam -# # ===== Bat -# # ====== Bad -# # ============Still a Heading (Level 6) -# # \== Not a Heading +# = Section 1 +# == Section 1.1 +# === Section 1.1.1 +# === Section 1.1.2 +# == Section 1.2 +# = Section 2 +# = Foo +# == Bar +# === Baz +# ==== Bam +# ===== Bat +# ====== Bad +# ============Still a Heading (Level 6) +# \== Not a Heading # # A heading may contain only one type of nested block: # @@ -1147,10 +1168,10 @@ def dummy_instance_method(foo, bar); end; # # Here is the :call-seq: directive given for the method: # - # # :call-seq: - # # call_seq_directive(foo, bar) - # # Can be anything -> bar - # # Also anything more -> baz or bat + # :call-seq: + # call_seq_directive(foo, bar) + # Can be anything -> bar + # Also anything more -> baz or bat # def call_seq_directive nil From 49517b3bb436456407e0ee099c7442f3ab5ac53d Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 26 Feb 2021 12:14:48 -0800 Subject: [PATCH 10/44] Fix inspect for unicode codepoint 0x85 This is an inelegant hack, by manually checking for this specific code point in rb_str_inspect. Some testing indicates that this is the only code point affected. It's possible a better fix would be inside of lower-level encoding code, such that rb_enc_isprint would return false and not true for codepoint 0x85. Fixes [Bug #16842] --- string.c | 10 +++++++++- test/ruby/test_string.rb | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/string.c b/string.c index 85819e26a393a3..e74783cf923652 100644 --- a/string.c +++ b/string.c @@ -6777,7 +6777,15 @@ rb_str_inspect(VALUE str) prev = p; continue; } - if ((enc == resenc && rb_enc_isprint(c, enc)) || + /* The special casing of 0x85 (NEXT_LINE) here is because + * Oniguruma historically treats it as printable, but it + * doesn't match the print POSIX bracket class or character + * property in regexps. + * + * See Ruby Bug #16842 for details: + * https://bugs.ruby-lang.org/issues/16842 + */ + if ((enc == resenc && rb_enc_isprint(c, enc) && c != 0x85) || (asciicompat && rb_enc_isascii(c, enc) && ISPRINT(c))) { continue; } diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index d37924dec1904e..ab14a3c17bb7f2 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -2614,6 +2614,11 @@ def test_inspect_nul assert_equal '"\x0012"', s.inspect, bug8290 end + def test_inspect_next_line + bug16842 = '[ruby-core:98231]' + assert_equal '"\\u0085"', 0x85.chr(Encoding::UTF_8).inspect, bug16842 + end + def test_partition assert_equal(%w(he l lo), S("hello").partition(/l/)) assert_equal(%w(he l lo), S("hello").partition("l")) From a677aa0fcf6b43668b1e6ceac67b4a4121afd818 Mon Sep 17 00:00:00 2001 From: git Date: Fri, 12 Aug 2022 00:47:48 +0900 Subject: [PATCH 11/44] * 2022-08-12 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 780a93e8dcc0de..1b561623e94b58 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 11 +#define RUBY_RELEASE_DAY 12 #include "ruby/version.h" #include "ruby/internal/abi.h" From 8a3f401b24e1b5f3e3a0f44c568a3e66ed595d42 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 11 Aug 2022 11:43:39 -0500 Subject: [PATCH 12/44] [ruby/rdoc] Improvements to Text Markup examples (https://github.com/ruby/rdoc/pull/915) https://github.com/ruby/rdoc/commit/d00ddfe57c --- doc/rdoc/markup_reference.rb | 104 ++++++++++++++++------------------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index 059511f478e009..c7578f3581107f 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -649,27 +649,27 @@ # # Example input: # -# Two words in a paragraph. +# Italicized words in a paragraph. # # >>> -# Two words in a block quote. +# Italicized words in a block quote. # -# - Two words in a bullet list item. +# - Italicized words in a list item. # -# ====== Two words in a Heading +# ====== Italicized words in a Heading # # Italicized passage containing *bold* and +monofont+. # # Rendered HTML: # >>> -# Two words in a paragraph. +# Italicized words in a paragraph. # # >>> -# Two words in a block quote. +# Italicized words in a block quote. # -# - Two words in a bullet list item. +# - Italicized words in a list item. # -# ====== Two words in a Heading +# ====== Italicized words in a Heading # # Italicized passage containing *bold* and +monofont+. # @@ -678,29 +678,25 @@ # # Example input: # -# _Word_ in a paragraph. +# _Italic_ in a paragraph. # # >>> -# _Word_ in a block quote. +# _Italic_ in a block quote. # -# - _Word_ in a bullet list item. +# - _Italic_ in a list item. # -# [_word_] _Word_ in a labeled list item. -# -# ====== _Word_ in a Heading +# ====== _Italic_ in a Heading # # Rendered HTML: # >>> -# _Word_ in a paragraph. +# _Italic_ in a paragraph. # # >>> -# _Word_ in a block quote. -# -# - _Word_ in a bullet list item. +# _Italic_ in a block quote. # -# [_word_] _Word_ in a labeled list item. +# - _Italic_ in a list item. # -# ====== _Word_ in a Heading +# ====== _Italic_ in a Heading # # ===== Bold # @@ -708,28 +704,28 @@ # # Example input: # -# Two words in a paragraph. +# Bold words in a paragraph. # # >>> -# Two words in a block quote. +# Bold words in a block quote. # -# - Two words in a bullet list item. +# - Bold words in a list item. # -# ====== Two words in a Heading +# ====== Bold words in a Heading # # Bold passage containing _italics_ and +monofont+. # # Rendered HTML: # # >>> -# Two words in a paragraph. +# Bold words in a paragraph. # # >>> -# Two words in a block quote. +# Bold words in a block quote. # -# - Two words in a bullet list item. +# - Bold words in a list item. # -# ====== Two words in a Heading +# ====== Bold words in a Heading # # Bold passage containing _italics_ and +monofont+. # @@ -738,30 +734,26 @@ # # Example input: # -# *Word* in a paragraph. +# *Bold* in a paragraph. # # >>> -# *Word* in a block quote. +# *Bold* in a block quote. # -# - *Word* in a bullet list item. +# - *Bold* in a list item. # -# [*word*] *Word* in a labeled list item. -# -# ===== *Word* in a Heading +# ===== *Bold* in a Heading # # Rendered HTML: # # >>> -# *Word* in a paragraph. +# *Bold* in a paragraph. # # >>> -# *Word* in a block quote. -# -# - *Word* in a bullet list item. +# *Bold* in a block quote. # -# [*word*] *Word* in a labeled list item. +# - *Bold* in a list item. # -# ===== *Word* in a Heading +# ===== *Bold* in a Heading # # ===== Monofont # @@ -771,28 +763,28 @@ # # Example input: # -# Two words in a paragraph. +# Monofont words in a paragraph. # # >>> -# Two words in a block quote. +# Monofont words in a block quote. # -# - Two words in a bullet list item. +# - Monofont words in a list item. # -# ====== Two words in heading +# ====== Monofont words in heading # # Monofont passage containing _italics_ and *bold*. # # Rendered HTML: # # >>> -# Two words in a paragraph. +# Monofont words in a paragraph. # # >>> -# Two words in a block quote. +# Monofont words in a block quote. # -# - Two words in a bullet list item. +# - Monofont words in a list item. # -# ====== Two words in heading +# ====== Monofont words in heading # # Monofont passage containing _italics_ and *bold*. # @@ -801,26 +793,26 @@ # # Example input: # -# +Word+ in a paragraph. +# +Monofont+ in a paragraph. # # >>> -# +Word+ in a block quote. +# +Monofont+ in a block quote. # -# - +Word+ in a bullet list item. +# - +Monofont+ in a list item. # -# ====== +Word+ in a Heading +# ====== +Monofont+ in a Heading # # Rendered HTML: # # >>> -# +Word+ in a paragraph. +# +Monofont+ in a paragraph. # # >>> -# +Word+ in a block quote. +# +Monofont+ in a block quote. # -# - +Word+ in a bullet list item. +# - +Monofont+ in a list item. # -# ====== +Word+ in a Heading +# ====== +Monofont+ in a Heading # # ==== Escaping Text Markup # From 5e3e4bc9840160f2a6f85cba2e05279d7668b014 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 11 Aug 2022 15:08:57 -0500 Subject: [PATCH 13/44] [ruby/rdoc] Mods to section Text Markup (https://github.com/ruby/rdoc/pull/916) https://github.com/ruby/rdoc/commit/5506d4d67e --- doc/rdoc/markup_reference.rb | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index c7578f3581107f..04e90aad23c420 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -94,7 +94,7 @@ # - {Directive}[rdoc-ref:RDoc::MarkupReference@Directives]: # various special directions for the rendering. # - {Text Markup}[rdoc-ref:RDoc:MarkupReference@Text+Markup]: -# text to be rendered in italic, bold, or monofont. +# text to be rendered in a special way. # # About the blocks: # @@ -632,18 +632,24 @@ # # ==== Text Markup # -# Text markup is metatext that marks text as: +# Text markup is metatext that affects HTML rendering: # -# - Italic. -# - Bold. -# - Monofont. +# - Typeface: italic, bold, monofont. +# - Character conversions: copyright, trademark, certain punctuation. +# - Links. +# - Escapes: marking text as "not markup." # -# Text markup may contain only one type of nested block: +# ===== Typeface Markup # -# - More text markup: +# Typeface markup can specify that text is to be rendered +# as italic, bold, or monofont. +# +# Typeface markup may contain only one type of nested block: +# +# - More typeface markup: # italic, bold, monofont. # -# ===== Italic +# ====== Italic # # Text may be marked as italic via HTML tag or . # @@ -698,7 +704,7 @@ # # ====== _Italic_ in a Heading # -# ===== Bold +# ====== Bold # # Text may be marked as bold via HTML tag . # @@ -755,7 +761,7 @@ # # ===== *Bold* in a Heading # -# ===== Monofont +# ====== Monofont # # Text may be marked as monofont # -- sometimes called 'typewriter font' -- From d9f1b8baa3a21b2a65af7fcab6a45c30b3f9efee Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Fri, 12 Aug 2022 14:04:04 +0900 Subject: [PATCH 14/44] [ruby/error_highlight] Add a note about the current limitation of ErrorHighlight.spot https://github.com/ruby/error_highlight/commit/489ce80a62 --- lib/error_highlight/base.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/error_highlight/base.rb b/lib/error_highlight/base.rb index dbd173a5cd4768..4c115cc8285c6b 100644 --- a/lib/error_highlight/base.rb +++ b/lib/error_highlight/base.rb @@ -22,6 +22,14 @@ module ErrorHighlight # snippet: String, # script_lines: [String], # } | nil + # + # Limitations: + # + # Currently, ErrorHighlight.spot only supports a single-line code fragment. + # Therefore, if the return value is not nil, first_lineno and last_lineno will have + # the same value. If the relevant code fragment spans multiple lines + # (e.g., Array#[] of +ary[(newline)expr(newline)]+), the method will return nil. + # This restriction may be removed in the future. def self.spot(obj, **opts) case obj when Exception From 04815ea968ebef616cfdb316840158f6c87a7277 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 12 Aug 2022 13:38:21 +0900 Subject: [PATCH 15/44] All extensions in bundled gems are built by build-ext now `RbInstall::GemInstaller#build_extensions` has nothing to do. --- tool/rbinstall.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb index ba0d911fc23130..e6fff940eee4c3 100755 --- a/tool/rbinstall.rb +++ b/tool/rbinstall.rb @@ -904,11 +904,8 @@ def install RbInstall.no_write(options) {super} end - if RbConfig::CONFIG["LIBRUBY_RELATIVE"] == "yes" || RbConfig::CONFIG["CROSS_COMPILING"] == "yes" || ENV["DESTDIR"] - # TODO: always build extensions in bundled gems by build-ext and - # install the built binaries. - def build_extensions - end + # Now build-ext builds all extensions including bundled gems. + def build_extensions end def generate_bin_script(filename, bindir) From a3a6d2d9a390697dfd0ae9f808cb301680a6f24a Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 12 Aug 2022 13:40:36 +0900 Subject: [PATCH 16/44] No bundled gems to be installed from gem now --- tool/rbinstall.rb | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb index e6fff940eee4c3..e6d0f592f5e330 100755 --- a/tool/rbinstall.rb +++ b/tool/rbinstall.rb @@ -1071,28 +1071,8 @@ def install_default_gem(dir, srcdir, bindir) prepare "bundled gem cache", gem_dir+"/cache" install installed_gems, gem_dir+"/cache" end - next if gems.empty? - if defined?(Zlib) - silent = Gem::SilentUI.new - gems.each do |gem| - package = Gem::Package.new(gem) - inst = RbInstall::GemInstaller.new(package, options) - inst.spec.extension_dir = "#{extensions_dir}/#{inst.spec.full_name}" - begin - Gem::DefaultUserInteraction.use_ui(silent) {inst.install} - rescue Gem::InstallError - next - end - gemname = File.basename(gem) - puts "#{INDENT}#{gemname}" - end - # fix directory permissions - # TODO: Gem.install should accept :dir_mode option or something - File.chmod($dir_mode, *Dir.glob(install_dir+"/**/")) - # fix .gemspec permissions - File.chmod($data_mode, *Dir.glob(install_dir+"/specifications/*.gemspec")) - else - puts "skip installing bundled gems because of lacking zlib" + unless gems.empty? + puts "skipped bundled gems: #{gems.join(' ')}" end end From 9a11d50dc7542cda4fc21352807df9f86b0d1093 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 12 Aug 2022 10:18:38 +0900 Subject: [PATCH 17/44] [DOC] Use `true`/`false` for `@retval`s which are `bool` --- include/ruby/internal/encoding/ctype.h | 86 +++++++++++++------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/include/ruby/internal/encoding/ctype.h b/include/ruby/internal/encoding/ctype.h index 64aaf0a990898a..70b6cc7909e7db 100644 --- a/include/ruby/internal/encoding/ctype.h +++ b/include/ruby/internal/encoding/ctype.h @@ -36,8 +36,8 @@ RBIMPL_SYMBOL_EXPORT_BEGIN() * @param[in] p Pointer to a possibly-middle of a character. * @param[in] end End of the string. * @param[in] enc Encoding. - * @retval 0 It isn't. - * @retval otherwise It is. + * @retval false It isn't. + * @retval true It is. */ static inline bool rb_enc_is_newline(const char *p, const char *e, rb_encoding *enc) @@ -53,11 +53,11 @@ rb_enc_is_newline(const char *p, const char *e, rb_encoding *enc) * encoding. The "character type" here is a set of macros defined in onigmo.h, * like `ONIGENC_CTYPE_PUNCT`. * - * @param[in] c An `OnigCodePoint` value. - * @param[in] t An `OnigCtype` value. - * @param[in] enc A `rb_encoding*` value. - * @retval 1 `c` is of `t` in `enc`. - * @retval 0 Otherwise. + * @param[in] c An `OnigCodePoint` value. + * @param[in] t An `OnigCtype` value. + * @param[in] enc A `rb_encoding*` value. + * @retval true `c` is of `t` in `enc`. + * @retval false Otherwise. */ static inline bool rb_enc_isctype(OnigCodePoint c, OnigCtype t, rb_encoding *enc) @@ -68,10 +68,10 @@ rb_enc_isctype(OnigCodePoint c, OnigCtype t, rb_encoding *enc) /** * Identical to rb_isascii(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 0 `c` is out of range of ASCII character set in `enc`. - * @retval 1 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval false `c` is out of range of ASCII character set in `enc`. + * @retval true Otherwise. * * @internal * @@ -87,10 +87,10 @@ rb_enc_isascii(OnigCodePoint c, rb_encoding *enc) /** * Identical to rb_isalpha(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 1 `enc` classifies `c` as "ALPHA". - * @retval 0 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "ALPHA". + * @retval false Otherwise. */ static inline bool rb_enc_isalpha(OnigCodePoint c, rb_encoding *enc) @@ -101,10 +101,10 @@ rb_enc_isalpha(OnigCodePoint c, rb_encoding *enc) /** * Identical to rb_islower(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 1 `enc` classifies `c` as "LOWER". - * @retval 0 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "LOWER". + * @retval false Otherwise. */ static inline bool rb_enc_islower(OnigCodePoint c, rb_encoding *enc) @@ -115,10 +115,10 @@ rb_enc_islower(OnigCodePoint c, rb_encoding *enc) /** * Identical to rb_isupper(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 1 `enc` classifies `c` as "UPPER". - * @retval 0 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "UPPER". + * @retval false Otherwise. */ static inline bool rb_enc_isupper(OnigCodePoint c, rb_encoding *enc) @@ -129,10 +129,10 @@ rb_enc_isupper(OnigCodePoint c, rb_encoding *enc) /** * Identical to rb_ispunct(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 1 `enc` classifies `c` as "PUNCT". - * @retval 0 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "PUNCT". + * @retval false Otherwise. */ static inline bool rb_enc_ispunct(OnigCodePoint c, rb_encoding *enc) @@ -143,10 +143,10 @@ rb_enc_ispunct(OnigCodePoint c, rb_encoding *enc) /** * Identical to rb_isalnum(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 1 `enc` classifies `c` as "ANUM". - * @retval 0 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "ANUM". + * @retval false Otherwise. */ static inline bool rb_enc_isalnum(OnigCodePoint c, rb_encoding *enc) @@ -157,10 +157,10 @@ rb_enc_isalnum(OnigCodePoint c, rb_encoding *enc) /** * Identical to rb_isprint(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 1 `enc` classifies `c` as "PRINT". - * @retval 0 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "PRINT". + * @retval false Otherwise. */ static inline bool rb_enc_isprint(OnigCodePoint c, rb_encoding *enc) @@ -171,10 +171,10 @@ rb_enc_isprint(OnigCodePoint c, rb_encoding *enc) /** * Identical to rb_isspace(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 1 `enc` classifies `c` as "PRINT". - * @retval 0 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "PRINT". + * @retval false Otherwise. */ static inline bool rb_enc_isspace(OnigCodePoint c, rb_encoding *enc) @@ -185,10 +185,10 @@ rb_enc_isspace(OnigCodePoint c, rb_encoding *enc) /** * Identical to rb_isdigit(), except it additionally takes an encoding. * - * @param[in] c A code point. - * @param[in] enc An encoding. - * @retval 1 `enc` classifies `c` as "DIGIT". - * @retval 0 Otherwise. + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "DIGIT". + * @retval false Otherwise. */ static inline bool rb_enc_isdigit(OnigCodePoint c, rb_encoding *enc) From a201cfd0cdb9f613f687dc6fee1908ec54e63c72 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 12 Aug 2022 13:36:11 +0900 Subject: [PATCH 18/44] Add missing `rb_enc_iscntrl` --- include/ruby/internal/encoding/ctype.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/ruby/internal/encoding/ctype.h b/include/ruby/internal/encoding/ctype.h index 70b6cc7909e7db..05c314aeb3d487 100644 --- a/include/ruby/internal/encoding/ctype.h +++ b/include/ruby/internal/encoding/ctype.h @@ -126,6 +126,20 @@ rb_enc_isupper(OnigCodePoint c, rb_encoding *enc) return ONIGENC_IS_CODE_UPPER(enc, c); } +/** + * Identical to rb_iscntrl(), except it additionally takes an encoding. + * + * @param[in] c A code point. + * @param[in] enc An encoding. + * @retval true `enc` classifies `c` as "CNTRL". + * @retval false Otherwise. + */ +static inline bool +rb_enc_iscntrl(OnigCodePoint c, rb_encoding *enc) +{ + return ONIGENC_IS_CODE_CNTRL(enc, c); +} + /** * Identical to rb_ispunct(), except it additionally takes an encoding. * @@ -235,6 +249,7 @@ RBIMPL_SYMBOL_EXPORT_END() #define rb_enc_isdigit rb_enc_isdigit #define rb_enc_islower rb_enc_islower #define rb_enc_isprint rb_enc_isprint +#define rb_enc_iscntrl rb_enc_iscntrl #define rb_enc_ispunct rb_enc_ispunct #define rb_enc_isspace rb_enc_isspace #define rb_enc_isupper rb_enc_isupper From cd1a0b3caaa5446e9258c192cf483b6dfe8d7819 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 12 Jul 2022 16:44:57 +0900 Subject: [PATCH 19/44] Stop defining `RUBY_ABI_VERSION` if released versions As commented in include/ruby/internal/abi.h, since teeny versions of Ruby should guarantee ABI compatibility, `RUBY_ABI_VERSION` has no role in released versions of Ruby. --- configure.ac | 6 ++++++ ext/-test-/abi/extconf.rb | 1 + include/ruby/internal/abi.h | 6 +++++- test/-ext-/test_abi.rb | 2 ++ version.h | 11 +++++++++-- win32/Makefile.sub | 8 +++++++- win32/setup.mak | 4 +++- 7 files changed, 33 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index bc21c262922161..0f4a31af7e7dce 100644 --- a/configure.ac +++ b/configure.ac @@ -88,7 +88,9 @@ AC_SUBST(GIT) AC_SUBST(HAVE_GIT) eval `sed -n -e ['s/^@%:@define RUBY_[A-Z_]*VERSION_\([A-Z][A-Z][A-Z_0-9]*\) \([0-9][0-9]*\)$/\1=\2/p'] \ + -e ['s/^@%:@define \(RUBY_ABI_VERSION\) \([0-9][0-9]*\).*/\1=\2/p'] \ -e ['s/^@%:@define \(RUBY_PATCHLEVEL\) \(.*\)/\1=\2/p'] \ + $srcdir/include/ruby/internal/abi.h \ $srcdir/include/ruby/version.h $srcdir/version.h` for v in MAJOR MINOR TEENY; do AS_IF([eval "test \"\$$v\" = ''"], [ @@ -100,6 +102,9 @@ AC_SUBST(MINOR) AC_SUBST(TEENY) AC_SUBST(RUBY_API_VERSION, '$(MAJOR).$(MINOR)') AC_SUBST(RUBY_PROGRAM_VERSION, '$(MAJOR).$(MINOR).$(TEENY)') +AS_CASE([$RUBY_PATCHLEVEL], [-*], [ + AC_DEFINE_UNQUOTED(RUBY_ABI_VERSION, [${RUBY_ABI_VERSION}]) +], [RUBY_ABI_VERSION=]) AS_IF([test "$program_prefix" = NONE], [ program_prefix= @@ -4118,6 +4123,7 @@ AS_CASE(["$ruby_version"], AS_IF([test ${RUBY_LIB_VERSION_STYLE+set}], [ { echo "#define RUBY_LIB_VERSION_STYLE $RUBY_LIB_VERSION_STYLE" + echo '@%:@include "confdefs.h"' echo '#define STRINGIZE(x) x' test -f revision.h -o -f "${srcdir}/revision.h" || echo '#define RUBY_REVISION 0' echo '#include "version.h"' diff --git a/ext/-test-/abi/extconf.rb b/ext/-test-/abi/extconf.rb index d786b15db98c7f..3b090b75531d90 100644 --- a/ext/-test-/abi/extconf.rb +++ b/ext/-test-/abi/extconf.rb @@ -1,3 +1,4 @@ # frozen_string_literal: false +return unless RUBY_PATCHLEVEL < 0 require_relative "../auto_ext.rb" auto_ext(inc: true) diff --git a/include/ruby/internal/abi.h b/include/ruby/internal/abi.h index e42a1777ff5eae..fe1977a9a181a0 100644 --- a/include/ruby/internal/abi.h +++ b/include/ruby/internal/abi.h @@ -1,6 +1,8 @@ #ifndef RUBY_ABI_H #define RUBY_ABI_H +#ifdef RUBY_ABI_VERSION /* should match the definition in config.h */ + /* This number represents Ruby's ABI version. * * In development Ruby, it should be bumped every time an ABI incompatible @@ -19,7 +21,7 @@ * - Backwards compatible refactors. * - Editing comments. * - * In released versions of Ruby, this number should not be changed since teeny + * In released versions of Ruby, this number is not defined since teeny * versions of Ruby should guarantee ABI compatibility. */ #define RUBY_ABI_VERSION 2 @@ -49,3 +51,5 @@ ruby_abi_version(void) #endif #endif + +#endif diff --git a/test/-ext-/test_abi.rb b/test/-ext-/test_abi.rb index 59e70107a5dd57..d3ea6bb9b105fe 100644 --- a/test/-ext-/test_abi.rb +++ b/test/-ext-/test_abi.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +return unless RUBY_PATCHLEVEL < 0 + class TestABI < Test::Unit::TestCase def test_require_lib_with_incorrect_abi_on_dev_ruby omit "ABI is not checked" unless abi_checking_supported? diff --git a/version.h b/version.h index 1b561623e94b58..d79ba396f78b2e 100644 --- a/version.h +++ b/version.h @@ -38,18 +38,25 @@ #define RUBY_RELEASE_DAY_STR STRINGIZE(RUBY_RELEASE_DAY) #endif +#ifdef RUBY_ABI_VERSION +# define RUBY_ABI_VERSION_SUFFIX "+"STRINGIZE(RUBY_ABI_VERSION) +#else +# define RUBY_ABI_VERSION_SUFFIX "" +#endif #if !defined RUBY_LIB_VERSION && defined RUBY_LIB_VERSION_STYLE # if RUBY_LIB_VERSION_STYLE == 3 # define RUBY_LIB_VERSION STRINGIZE(RUBY_API_VERSION_MAJOR)"."STRINGIZE(RUBY_API_VERSION_MINOR) \ - "."STRINGIZE(RUBY_API_VERSION_TEENY)"+"STRINGIZE(RUBY_ABI_VERSION) + "."STRINGIZE(RUBY_API_VERSION_TEENY) RUBY_ABI_VERSION_SUFFIX # elif RUBY_LIB_VERSION_STYLE == 2 # define RUBY_LIB_VERSION STRINGIZE(RUBY_API_VERSION_MAJOR)"."STRINGIZE(RUBY_API_VERSION_MINOR) \ - "+"STRINGIZE(RUBY_ABI_VERSION) + RUBY_ABI_VERSION_SUFFIX # endif #endif #if RUBY_PATCHLEVEL == -1 #define RUBY_PATCHLEVEL_STR "dev" +#elif defined RUBY_ABI_VERSION +#error RUBY_ABI_VERSION is defined in non-development branch #else #define RUBY_PATCHLEVEL_STR "" #endif diff --git a/win32/Makefile.sub b/win32/Makefile.sub index 9dc5ee6f515f2e..bea24450ed0390 100644 --- a/win32/Makefile.sub +++ b/win32/Makefile.sub @@ -148,7 +148,10 @@ PLATFORM_DIR = win32 arch = $(ARCH)-$(PLATFORM) sitearch = $(ARCH)-$(RT) !if !defined(ruby_version) -ruby_version = $(MAJOR).$(MINOR).0+$(ABI_VERSION) +ruby_version = $(MAJOR).$(MINOR).0 +!endif +!if defined(ABI_VERSION) +ruby_version = $(ruby_version)+$(ABI_VERSION) !endif !if !defined(RUBY_VERSION_NAME) RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) @@ -624,6 +627,9 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub #endif !endif #define RUBY_MSVCRT_VERSION $(RT_VER) +!if defined(ABI_VERSION) +#define RUBY_ABI_VERSION $(ABI_VERSION) +!endif #define STDC_HEADERS 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_STAT_H 1 diff --git a/win32/setup.mak b/win32/setup.mak index 39323c61c2464f..fd804a84cec6d5 100644 --- a/win32/setup.mak +++ b/win32/setup.mak @@ -178,6 +178,7 @@ main(void) -version-: nul verconf.mk verconf.mk: nul + @findstr /R /C:"^#define RUBY_ABI_VERSION " $(srcdir:/=\)\include\ruby\internal\abi.h > $(@) @$(CPP) -I$(srcdir) -I$(srcdir)/include <<"Creating $(@)" > $(*F).bat && cmd /c $(*F).bat > $(@) @echo off #define RUBY_REVISION 0 @@ -198,8 +199,9 @@ echo RUBY_RELEASE_DAY = %ruby_release_day:~-2% echo MAJOR = RUBY_VERSION_MAJOR echo MINOR = RUBY_VERSION_MINOR echo TEENY = RUBY_VERSION_TEENY -echo ABI_VERSION = RUBY_ABI_VERSION #if defined RUBY_PATCHLEVEL && RUBY_PATCHLEVEL < 0 +#include "$(@F)" +echo ABI_VERSION = RUBY_ABI_VERSION #endif set /a MSC_VER = _MSC_VER #if _MSC_VER >= 1920 From 4165fd0e763439421296fbc95d754ad53e6ae84f Mon Sep 17 00:00:00 2001 From: Kouhei Yanagita Date: Fri, 27 May 2022 15:46:46 +0900 Subject: [PATCH 20/44] Add Numeric#ceildiv and Integer#ceildiv --- complex.c | 1 + numeric.c | 49 +++++++++++++++++++++++++++++++++++++++ test/ruby/test_complex.rb | 1 + test/ruby/test_integer.rb | 17 ++++++++++++++ test/ruby/test_numeric.rb | 14 +++++++++++ 5 files changed, 82 insertions(+) diff --git a/complex.c b/complex.c index d625ced7fa865b..865466c499ba4a 100644 --- a/complex.c +++ b/complex.c @@ -2335,6 +2335,7 @@ Init_Complex(void) rb_undef_method(rb_cComplex, "%"); rb_undef_method(rb_cComplex, "div"); rb_undef_method(rb_cComplex, "divmod"); + rb_undef_method(rb_cComplex, "ceildiv"); rb_undef_method(rb_cComplex, "floor"); rb_undef_method(rb_cComplex, "ceil"); rb_undef_method(rb_cComplex, "modulo"); diff --git a/numeric.c b/numeric.c index 4f927f00fb655b..df0c016b9e5bac 100644 --- a/numeric.c +++ b/numeric.c @@ -656,6 +656,31 @@ num_div(VALUE x, VALUE y) return rb_funcall(num_funcall1(x, '/', y), rb_intern("floor"), 0); } +/* + * call-seq: + * ceildiv(other) -> integer + * + * Returns the quotient self/other as an integer, rounding up to the nearest integer. + * This method uses method +/+ in the derived class of +self+. + * (\Numeric itself does not define method +/+.) + * + * Of the Core and Standard Library classes, + * Float and Rational use this implementation. + * + * 3.0.ceildiv(3.0) # => 1 + * 4.0.ceildiv(3.0) # => 2 + * + * 4.0.ceildiv(-3.0) # => -1 + * -4.0.ceildiv(3.0) # => -1 + * -4.0.ceildiv(-3.0) # => 2 + */ +static VALUE +num_ceildiv(VALUE x, VALUE y) +{ + VALUE tmp = num_div(x, num_uminus(y)); + return num_uminus(tmp); +} + /* * call-seq: * self % other -> real_numeric @@ -4269,6 +4294,28 @@ rb_int_idiv(VALUE x, VALUE y) return num_div(x, y); } +/* + * call-seq: + * ceildiv(other) -> integer + * + * Returns the result of division +self+ by +other+. The result is rounded up to the nearest integer. + * + * 3.ceildiv(3) # => 1 + * 4.ceildiv(3) # => 2 + * + * 4.ceildiv(-3) # => -1 + * -4.ceildiv(3) # => -1 + * -4.ceildiv(-3) # => 2 + * + * 3.ceildiv(1.2) # => 3 + */ +VALUE +rb_int_ceildiv(VALUE x, VALUE y) +{ + VALUE tmp = rb_int_idiv(x, num_uminus(y)); + return num_uminus(tmp); +} + static VALUE fix_mod(VALUE x, VALUE y) { @@ -6200,6 +6247,7 @@ Init_Numeric(void) rb_define_method(rb_cNumeric, "<=>", num_cmp, 1); rb_define_method(rb_cNumeric, "eql?", num_eql, 1); rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1); + rb_define_method(rb_cNumeric, "ceildiv", num_ceildiv, 1); rb_define_method(rb_cNumeric, "div", num_div, 1); rb_define_method(rb_cNumeric, "divmod", num_divmod, 1); rb_define_method(rb_cNumeric, "%", num_modulo, 1); @@ -6255,6 +6303,7 @@ Init_Numeric(void) rb_define_method(rb_cInteger, "remainder", int_remainder, 1); rb_define_method(rb_cInteger, "divmod", rb_int_divmod, 1); rb_define_method(rb_cInteger, "fdiv", rb_int_fdiv, 1); + rb_define_method(rb_cInteger, "ceildiv", rb_int_ceildiv, 1); rb_define_method(rb_cInteger, "**", rb_int_pow, 1); rb_define_method(rb_cInteger, "pow", rb_int_powm, -1); /* in bignum.c */ diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb index a3a75465755240..5cf52e812ed626 100644 --- a/test/ruby/test_complex.rb +++ b/test/ruby/test_complex.rb @@ -915,6 +915,7 @@ def test_respond assert_not_respond_to(c, :%) assert_not_respond_to(c, :div) assert_not_respond_to(c, :divmod) + assert_not_respond_to(c, :ceildiv) assert_not_respond_to(c, :floor) assert_not_respond_to(c, :ceil) assert_not_respond_to(c, :modulo) diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb index a2b181c6422c84..c3e11498bec528 100644 --- a/test/ruby/test_integer.rb +++ b/test/ruby/test_integer.rb @@ -704,4 +704,21 @@ def o.to_int; 1; end def o.to_int; Object.new; end assert_raise_with_message(TypeError, /can't convert Object to Integer/) {Integer.try_convert(o)} end + + def test_ceildiv + assert_equal(0, 0.ceildiv(3)) + assert_equal(1, 1.ceildiv(3)) + assert_equal(1, 3.ceildiv(3)) + assert_equal(2, 4.ceildiv(3)) + + assert_equal(-1, 4.ceildiv(-3)) + assert_equal(-1, -4.ceildiv(3)) + assert_equal(2, -4.ceildiv(-3)) + + assert_equal(3, 3.ceildiv(1.2)) + assert_equal(3, 3.ceildiv(6/5r)) + + assert_equal(10, (10**100-11).ceildiv(10**99-1)) + assert_equal(11, (10**100-9).ceildiv(10**99-1)) + end end diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index 0593cb535d48b6..068f9a56eb2f43 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -482,4 +482,18 @@ def test_pow assert_equal(0, -2.pow(3, 1)) end + def test_ceildiv + assert_equal(0, 0.0.ceildiv(3.0)) + assert_equal(1, 1.0.ceildiv(3.0)) + assert_equal(1, 3.0.ceildiv(3.0)) + assert_equal(2, 4.0.ceildiv(3.0)) + + assert_equal(-1, 4.0.ceildiv(-3.0)) + assert_equal(-1, -4.0.ceildiv(3.0)) + assert_equal(2, -4.0.ceildiv(-3.0)) + + assert_equal(3, 3.0.ceildiv(1.2)) + assert_equal(3, 3.0.ceildiv(6/5r)) + assert_equal(3, (7r/2).ceildiv(6/5r)) + end end From 24e33b84b5adb29d1d2f541acfba65e225b91b55 Mon Sep 17 00:00:00 2001 From: Kouhei Yanagita Date: Thu, 21 Jul 2022 18:57:13 +0900 Subject: [PATCH 21/44] Remove Numeric#ceildiv --- complex.c | 1 - numeric.c | 26 -------------------------- test/ruby/test_complex.rb | 1 - test/ruby/test_numeric.rb | 14 -------------- 4 files changed, 42 deletions(-) diff --git a/complex.c b/complex.c index 865466c499ba4a..d625ced7fa865b 100644 --- a/complex.c +++ b/complex.c @@ -2335,7 +2335,6 @@ Init_Complex(void) rb_undef_method(rb_cComplex, "%"); rb_undef_method(rb_cComplex, "div"); rb_undef_method(rb_cComplex, "divmod"); - rb_undef_method(rb_cComplex, "ceildiv"); rb_undef_method(rb_cComplex, "floor"); rb_undef_method(rb_cComplex, "ceil"); rb_undef_method(rb_cComplex, "modulo"); diff --git a/numeric.c b/numeric.c index df0c016b9e5bac..9574bfe024bfa0 100644 --- a/numeric.c +++ b/numeric.c @@ -656,31 +656,6 @@ num_div(VALUE x, VALUE y) return rb_funcall(num_funcall1(x, '/', y), rb_intern("floor"), 0); } -/* - * call-seq: - * ceildiv(other) -> integer - * - * Returns the quotient self/other as an integer, rounding up to the nearest integer. - * This method uses method +/+ in the derived class of +self+. - * (\Numeric itself does not define method +/+.) - * - * Of the Core and Standard Library classes, - * Float and Rational use this implementation. - * - * 3.0.ceildiv(3.0) # => 1 - * 4.0.ceildiv(3.0) # => 2 - * - * 4.0.ceildiv(-3.0) # => -1 - * -4.0.ceildiv(3.0) # => -1 - * -4.0.ceildiv(-3.0) # => 2 - */ -static VALUE -num_ceildiv(VALUE x, VALUE y) -{ - VALUE tmp = num_div(x, num_uminus(y)); - return num_uminus(tmp); -} - /* * call-seq: * self % other -> real_numeric @@ -6247,7 +6222,6 @@ Init_Numeric(void) rb_define_method(rb_cNumeric, "<=>", num_cmp, 1); rb_define_method(rb_cNumeric, "eql?", num_eql, 1); rb_define_method(rb_cNumeric, "fdiv", num_fdiv, 1); - rb_define_method(rb_cNumeric, "ceildiv", num_ceildiv, 1); rb_define_method(rb_cNumeric, "div", num_div, 1); rb_define_method(rb_cNumeric, "divmod", num_divmod, 1); rb_define_method(rb_cNumeric, "%", num_modulo, 1); diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb index 5cf52e812ed626..a3a75465755240 100644 --- a/test/ruby/test_complex.rb +++ b/test/ruby/test_complex.rb @@ -915,7 +915,6 @@ def test_respond assert_not_respond_to(c, :%) assert_not_respond_to(c, :div) assert_not_respond_to(c, :divmod) - assert_not_respond_to(c, :ceildiv) assert_not_respond_to(c, :floor) assert_not_respond_to(c, :ceil) assert_not_respond_to(c, :modulo) diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index 068f9a56eb2f43..0593cb535d48b6 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -482,18 +482,4 @@ def test_pow assert_equal(0, -2.pow(3, 1)) end - def test_ceildiv - assert_equal(0, 0.0.ceildiv(3.0)) - assert_equal(1, 1.0.ceildiv(3.0)) - assert_equal(1, 3.0.ceildiv(3.0)) - assert_equal(2, 4.0.ceildiv(3.0)) - - assert_equal(-1, 4.0.ceildiv(-3.0)) - assert_equal(-1, -4.0.ceildiv(3.0)) - assert_equal(2, -4.0.ceildiv(-3.0)) - - assert_equal(3, 3.0.ceildiv(1.2)) - assert_equal(3, 3.0.ceildiv(6/5r)) - assert_equal(3, (7r/2).ceildiv(6/5r)) - end end From 803a07263001e5466bba0f53fcc85784f4b5c686 Mon Sep 17 00:00:00 2001 From: Kouhei Yanagita Date: Fri, 22 Jul 2022 12:05:16 +0900 Subject: [PATCH 22/44] Improve performance of Integer#ceildiv This patch is suggested by nobu. Benchmark result: ``` require 'benchmark' n = 10 ** 7 Benchmark.bm do |x| x.report("Fixnum/Fixnum") { a, b = 5, 2; n.times { a.ceildiv(b) } } x.report("Bignum/Bignum") { a, b = 10**100, 10**99 - 1; n.times { a.ceildiv(b) } } x.report("Bignum/Fixnum") { a, b = 10**100, 3; n.times { a.ceildiv(b) } } end ``` Original: ``` user system total real Fixnum/Fixnum 3.340009 0.043029 3.383038 ( 3.384022) Bignum/Bignum 8.229500 0.118543 8.348043 ( 8.349574) Bignum/Fixnum 8.328971 0.097842 8.426813 ( 8.426952) ``` Improved: ``` user system total real Fixnum/Fixnum 0.699140 0.000961 0.700101 ( 0.700199) Bignum/Bignum 5.076165 0.083160 5.159325 ( 5.159360) Bignum/Fixnum 5.548684 0.115372 5.664056 ( 5.666735) ``` --- numeric.c | 23 ----------------------- numeric.rb | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/numeric.c b/numeric.c index 9574bfe024bfa0..4f927f00fb655b 100644 --- a/numeric.c +++ b/numeric.c @@ -4269,28 +4269,6 @@ rb_int_idiv(VALUE x, VALUE y) return num_div(x, y); } -/* - * call-seq: - * ceildiv(other) -> integer - * - * Returns the result of division +self+ by +other+. The result is rounded up to the nearest integer. - * - * 3.ceildiv(3) # => 1 - * 4.ceildiv(3) # => 2 - * - * 4.ceildiv(-3) # => -1 - * -4.ceildiv(3) # => -1 - * -4.ceildiv(-3) # => 2 - * - * 3.ceildiv(1.2) # => 3 - */ -VALUE -rb_int_ceildiv(VALUE x, VALUE y) -{ - VALUE tmp = rb_int_idiv(x, num_uminus(y)); - return num_uminus(tmp); -} - static VALUE fix_mod(VALUE x, VALUE y) { @@ -6277,7 +6255,6 @@ Init_Numeric(void) rb_define_method(rb_cInteger, "remainder", int_remainder, 1); rb_define_method(rb_cInteger, "divmod", rb_int_divmod, 1); rb_define_method(rb_cInteger, "fdiv", rb_int_fdiv, 1); - rb_define_method(rb_cInteger, "ceildiv", rb_int_ceildiv, 1); rb_define_method(rb_cInteger, "**", rb_int_pow, 1); rb_define_method(rb_cInteger, "pow", rb_int_powm, -1); /* in bignum.c */ diff --git a/numeric.rb b/numeric.rb index 9f2200d2a87642..c2091465f88fd5 100644 --- a/numeric.rb +++ b/numeric.rb @@ -227,6 +227,23 @@ def zero? Primitive.attr! 'inline' Primitive.cexpr! 'rb_int_zero_p(self)' end + + # call-seq: + # ceildiv(other) -> integer + # + # Returns the result of division +self+ by +other+. The result is rounded up to the nearest integer. + # + # 3.ceildiv(3) # => 1 + # 4.ceildiv(3) # => 2 + # + # 4.ceildiv(-3) # => -1 + # -4.ceildiv(3) # => -1 + # -4.ceildiv(-3) # => 2 + # + # 3.ceildiv(1.2) # => 3 + def ceildiv(other) + -div(-other) + end end # call-seq: From 844a0edbae6e74293e3d0cb1ceeeb66a4371d06d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 11 Aug 2022 22:24:47 +0900 Subject: [PATCH 23/44] [Bug #18962] Do not read again once reached EOF `Ripper::Lexer#parse` re-parses the source code with syntax errors when `raise_errors: false`. Co-Authored-By: tompng --- parse.y | 1 + test/ripper/test_lexer.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/parse.y b/parse.y index b4c3106b8cf141..d0f37a18ccb1ac 100644 --- a/parse.y +++ b/parse.y @@ -9299,6 +9299,7 @@ parser_yylex(struct parser_params *p) case '\004': /* ^D */ case '\032': /* ^Z */ case -1: /* end of script. */ + p->eofp = 1; return 0; /* white spaces */ diff --git a/test/ripper/test_lexer.rb b/test/ripper/test_lexer.rb index 83130668be79b0..4f3f4657efe4df 100644 --- a/test/ripper/test_lexer.rb +++ b/test/ripper/test_lexer.rb @@ -100,6 +100,20 @@ def test_stack_at_on_heredoc_beg assert_equal expect, Ripper.lex(src).map {|e| e[1]} end + def test_end_of_script_char + all_assertions do |all| + ["a", %w"[a ]", %w"{, }", "if"].each do |src, append| + expected = Ripper.lex(src).map {|e| e[1]} + ["\0b", "\4b", "\32b"].each do |eof| + c = "#{src}#{eof}#{append}" + all.for(c) do + assert_equal expected, Ripper.lex(c).map {|e| e[1]} + end + end + end + end + end + def test_slice assert_equal "string\#{nil}\n", Ripper.slice(%(< Date: Thu, 14 Jul 2022 17:39:03 +0900 Subject: [PATCH 24/44] Short-circuit `Process._fork` --- process.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/process.c b/process.c index 0e4dbc40f4d26c..57df2dc06fbf89 100644 --- a/process.c +++ b/process.c @@ -4328,12 +4328,30 @@ rb_fork_ruby(int *status) return pid; } +static rb_pid_t +proc_fork_pid(void) +{ + rb_pid_t pid = rb_fork_ruby(NULL); + + if (pid == -1) { + rb_sys_fail("fork(2)"); + } + + return pid; +} + rb_pid_t rb_call_proc__fork(void) { - VALUE pid = rb_funcall(rb_mProcess, rb_intern("_fork"), 0); - - return NUM2PIDT(pid); + ID id__fork; + CONST_ID(id__fork, "_fork"); + if (rb_method_basic_definition_p(CLASS_OF(rb_mProcess), id__fork)) { + return proc_fork_pid(); + } + else { + VALUE pid = rb_funcall(rb_mProcess, id__fork, 0); + return NUM2PIDT(pid); + } } #endif @@ -4360,12 +4378,7 @@ rb_call_proc__fork(void) VALUE rb_proc__fork(VALUE _obj) { - rb_pid_t pid = rb_fork_ruby(NULL); - - if (pid == -1) { - rb_sys_fail("fork(2)"); - } - + rb_pid_t pid = proc_fork_pid(); return PIDT2NUM(pid); } From 77fdb3a47d420eb66761d50db2244a10b1d7272a Mon Sep 17 00:00:00 2001 From: S-H-GAMELINKS Date: Tue, 9 Aug 2022 13:22:21 +0900 Subject: [PATCH 25/44] Introduce with_warn_vsprintf macro --- error.c | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/error.c b/error.c index 21a532a8faedc4..07fa04627e8d5d 100644 --- a/error.c +++ b/error.c @@ -357,47 +357,42 @@ warn_vsprintf(rb_encoding *enc, const char *file, int line, const char *fmt, va_ return rb_str_cat2(str, "\n"); } +#define with_warn_vsprintf(file, line, fmt) \ + VALUE str; \ + va_list args; \ + va_start(args, fmt); \ + str = warn_vsprintf(NULL, file, line, fmt, args); \ + va_end(args); + void rb_compile_warn(const char *file, int line, const char *fmt, ...) { - VALUE str; - va_list args; - - if (NIL_P(ruby_verbose)) return; - - va_start(args, fmt); - str = warn_vsprintf(NULL, file, line, fmt, args); - va_end(args); - rb_write_warning_str(str); + if (!NIL_P(ruby_verbose)) { + with_warn_vsprintf(file, line, fmt) { + rb_write_warning_str(str); + } + } } /* rb_compile_warning() reports only in verbose mode */ void rb_compile_warning(const char *file, int line, const char *fmt, ...) { - VALUE str; - va_list args; - - if (!RTEST(ruby_verbose)) return; - - va_start(args, fmt); - str = warn_vsprintf(NULL, file, line, fmt, args); - va_end(args); - rb_write_warning_str(str); + if (RTEST(ruby_verbose)) { + with_warn_vsprintf(file, line, fmt) { + rb_write_warning_str(str); + } + } } void rb_category_compile_warn(rb_warning_category_t category, const char *file, int line, const char *fmt, ...) { - VALUE str; - va_list args; - - if (NIL_P(ruby_verbose)) return; - - va_start(args, fmt); - str = warn_vsprintf(NULL, file, line, fmt, args); - va_end(args); - rb_warn_category(str, rb_warning_category_to_name(category)); + if (!NIL_P(ruby_verbose)) { + with_warn_vsprintf(file, line, fmt) { + rb_warn_category(str, rb_warning_category_to_name(category)); + } + } } RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0) From b1799267bf39bbca58a160c00c1581a694ca6ad9 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 12 Aug 2022 22:07:32 +0900 Subject: [PATCH 26/44] Bundle unreleased debug --- gems/bundled_gems | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gems/bundled_gems b/gems/bundled_gems index a053812f0a8146..8b71308f627ae6 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -13,4 +13,4 @@ matrix 0.4.2 https://github.com/ruby/matrix prime 0.1.2 https://github.com/ruby/prime rbs 2.6.0 https://github.com/ruby/rbs 5202d4eeed3257448f19004b4baac4bcf4127717 typeprof 0.21.3 https://github.com/ruby/typeprof -debug 1.6.2 https://github.com/ruby/debug +debug 1.6.2 https://github.com/ruby/debug e7c37486ff9579251e5d25645b8d38ec96708f12 From e44445596fb8ba70a2a9fc602458bfe10d493146 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 12 Aug 2022 23:51:55 +0900 Subject: [PATCH 27/44] Preserve each column positions in gems/bundled_gems --- tool/update-bundled_gems.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tool/update-bundled_gems.rb b/tool/update-bundled_gems.rb index 5b9c6b6974edaa..bed1cfc52bc3f1 100755 --- a/tool/update-bundled_gems.rb +++ b/tool/update-bundled_gems.rb @@ -16,5 +16,7 @@ $F[3..-1] = [] end end - $_ = [gem.name, gem.version, uri, *$F[3..-1]].join(" ") + f = [gem.name, gem.version.to_s, uri, *$F[3..-1]] + $_.gsub!(/\S+\s*/) {|s| f.shift.ljust(s.size)} + $_ = [$_, *f].join(" ") unless f.empty? end From 3a6405db1b987f658291e0047ae05f7f93d21b87 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 12 Aug 2022 23:52:48 +0900 Subject: [PATCH 28/44] Adjust columns in gems/bundled_gems [ci skip] --- gems/bundled_gems | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/gems/bundled_gems b/gems/bundled_gems index 8b71308f627ae6..5faa75c5e228ca 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -1,16 +1,16 @@ # gem-name version-to-bundle repository-url [optional-commit-hash-to-test-or-defaults-to-v-version] -minitest 5.16.2 https://github.com/seattlerb/minitest -power_assert 2.0.1 https://github.com/ruby/power_assert -rake 13.0.6 https://github.com/ruby/rake -test-unit 3.5.3 https://github.com/test-unit/test-unit -rexml 3.2.5 https://github.com/ruby/rexml -rss 0.2.9 https://github.com/ruby/rss -net-ftp 0.1.3 https://github.com/ruby/net-ftp -net-imap 0.2.3 https://github.com/ruby/net-imap -net-pop 0.1.1 https://github.com/ruby/net-pop -net-smtp 0.3.1 https://github.com/ruby/net-smtp -matrix 0.4.2 https://github.com/ruby/matrix -prime 0.1.2 https://github.com/ruby/prime -rbs 2.6.0 https://github.com/ruby/rbs 5202d4eeed3257448f19004b4baac4bcf4127717 -typeprof 0.21.3 https://github.com/ruby/typeprof -debug 1.6.2 https://github.com/ruby/debug e7c37486ff9579251e5d25645b8d38ec96708f12 +minitest 5.16.2 https://github.com/seattlerb/minitest +power_assert 2.0.1 https://github.com/ruby/power_assert +rake 13.0.6 https://github.com/ruby/rake +test-unit 3.5.3 https://github.com/test-unit/test-unit +rexml 3.2.5 https://github.com/ruby/rexml +rss 0.2.9 https://github.com/ruby/rss +net-ftp 0.1.3 https://github.com/ruby/net-ftp +net-imap 0.2.3 https://github.com/ruby/net-imap +net-pop 0.1.1 https://github.com/ruby/net-pop +net-smtp 0.3.1 https://github.com/ruby/net-smtp +matrix 0.4.2 https://github.com/ruby/matrix +prime 0.1.2 https://github.com/ruby/prime +rbs 2.6.0 https://github.com/ruby/rbs 5202d4eeed3257448f19004b4baac4bcf4127717 +typeprof 0.21.3 https://github.com/ruby/typeprof +debug 1.6.2 https://github.com/ruby/debug e7c37486ff9579251e5d25645b8d38ec96708f12 From fa65800ee54961e04acf65c54a84abb9c0f6210b Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Fri, 12 Aug 2022 19:00:10 -0500 Subject: [PATCH 29/44] [ruby/rdoc] [DOC] Enhances text about escapes (https://github.com/ruby/rdoc/pull/917) https://github.com/ruby/rdoc/commit/c40bac829c --- doc/rdoc/markup_reference.rb | 118 ++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 31 deletions(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index 04e90aad23c420..92fe2e7cc36129 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -820,37 +820,6 @@ # # ====== +Monofont+ in a Heading # -# ==== Escaping Text Markup -# -# Text markup can be escaped with a backslash, as in \, which was obtained -# with \\. Except in verbatim sections and between \ tags, -# to produce a backslash you have to double it unless it is followed by a -# space, tab or newline. Otherwise, the HTML formatter will discard it, as it -# is used to escape potential links: -# -# * The \ must be doubled if not followed by white space: \\. -# * But not in \ tags: in a Regexp, \S matches non-space. -# * This is a link to {ruby-lang}[https://www.ruby-lang.org]. -# * This is not a link, however: \{ruby-lang.org}[https://www.ruby-lang.org]. -# * This will not be linked to \RDoc::RDoc#document -# -# generates: -# -# * The \ must be doubled if not followed by white space: \\. -# * But not in \ tags: in a Regexp, \S matches non-space. -# * This is a link to {ruby-lang}[https://www.ruby-lang.org] -# * This is not a link, however: \{ruby-lang.org}[https://www.ruby-lang.org] -# * This will not be linked to \RDoc::RDoc#document -# -# Inside \ tags, more precisely, leading backslashes are removed only if -# followed by a markup character (<*_+), a backslash, or a known link -# reference (a known class or method). So in the example above, the backslash -# of \S would be removed if there was a class or module named +S+ in -# the current context. -# -# This behavior is inherited from RDoc version 1, and has been kept for -# compatibility with existing RDoc documentation. -# # ==== Character Conversions # # Certain combinations of characters may be converted to special characters; @@ -1074,6 +1043,93 @@ # # {rdoc-image:https://www.ruby-lang.org/images/header-ruby-logo@2x.png}[./Alias.html] # +# === Escaping Text +# +# Text that would otherwise be interpreted as markup +# can be "escaped," so that it is not interpreted as markup; +# the escape character is the backslash ('\\'). +# +# In a verbatim text block or a code block, +# the escape character is always preserved: +# +# Example input: +# +# This is not verbatim text. +# +# This is verbatim text, with an escape character \. +# +# This is not a code block. +# +# def foo +# 'String with an escape character.' +# end +# +# Rendered HTML: +# +# >>> +# This is not verbatim text. +# +# This is verbatim text, with an escape character \. +# +# This is not a code block. +# +# def foo +# 'This is a code block with an escape character \.' +# end +# +# In typeface markup (italic, bold, or monofont), +# an escape character is preserved unless it is immediately +# followed by nested typeface markup. +# +# Example input: +# +# This list is about escapes; it contains: +# +# - Monofont text with unescaped nested _italic_. +# - Monofont text with escaped nested \_italic_. +# - Monofont text with an escape character \. +# +# Rendered HTML: +# +# >>> +# This list is about escapes; it contains: +# +# - Monofont text with unescaped nested _italic_. +# - Monofont text with escaped nested \_italic_. +# - Monofont text with an escape character \ . +# +# In other text-bearing blocks +# (paragraphs, block quotes, list items, headings): +# +# - A single escape character immediately followed by markup +# escapes the markup. +# - A single escape character followed by whitespace is preserved. +# - A single escape character anywhere else is ignored. +# - A double escape character is rendered as a single backslash. +# +# Example input: +# +# This list is about escapes; it contains: +# +# - An unescaped class name, RDoc, that will become a link. +# - An escaped class name, \RDoc, that will not become a link. +# - An escape character followed by whitespace \ . +# - An escape character \that is ignored. +# - A double escape character \\ that is rendered +# as a single backslash. +# +# Rendered HTML: +# +# >>> +# This list is about escapes; it contains: +# +# - An unescaped class name, RDoc, that will become a link. +# - An escaped class name, \RDoc, that will not become a link. +# - An escape character followed by whitespace \ . +# - An escape character \that is ignored. +# - A double escape character \\ that is rendered +# as a single backslash. +# # == Documentation Derived from Ruby Code # # [Class] From f9382a3bcba24d2b57d9dcb890928100a8e5f604 Mon Sep 17 00:00:00 2001 From: git Date: Sat, 13 Aug 2022 09:00:35 +0900 Subject: [PATCH 30/44] * 2022-08-13 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index d79ba396f78b2e..9d5c6428f2054e 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 12 +#define RUBY_RELEASE_DAY 13 #include "ruby/version.h" #include "ruby/internal/abi.h" From d1d1c9ba7a678124eb32833d5be0628c915bde06 Mon Sep 17 00:00:00 2001 From: Kouhei Yanagita Date: Sat, 13 Aug 2022 08:07:49 +0900 Subject: [PATCH 31/44] Add a NEWS entry about Integer#ceildiv [ci skip] --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index b391702821b654..6a6ed90e50cefd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -104,6 +104,9 @@ Note: We're only listing outstanding class updates. empty, instead of returning the default value or calling the default proc. [[Bug #16908]] +* Integer + * Integer#ceildiv has been added. [[Feature #18809]] + * Kernel * Kernel#binding raises RuntimeError if called from a non-Ruby frame (such as a method defined in C). [[Bug #18487]] From 0617cba197cdff626ee9c74cece480df31d384ef Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 13 Aug 2022 11:23:47 +0900 Subject: [PATCH 32/44] [DOC] Add the link to [Feature #18809] --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 6a6ed90e50cefd..6498621712270b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -279,3 +279,4 @@ The following deprecated APIs are removed. [Feature #18685]: https://bugs.ruby-lang.org/issues/18685 [Bug #18782]: https://bugs.ruby-lang.org/issues/18782 [Feature #18788]: https://bugs.ruby-lang.org/issues/18788 +[Feature #18809]: https://bugs.ruby-lang.org/issues/18809 From a58a429f8b85d9a68a9439ba58c76996750946da Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 14 Aug 2022 01:02:33 +0900 Subject: [PATCH 33/44] Silent configure does not output cached configurations --- template/Makefile.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/template/Makefile.in b/template/Makefile.in index 7968619f9a1a16..facbf062f42a6a 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -397,12 +397,13 @@ uncommon.mk: $(srcdir)/common.mk reconfig-args = $(srcdir)/$(CONFIGURE) $(yes_silence:yes=--silent) $(configure_args) config.status-args = ./config.status $(yes_silence:yes=--silent) --recheck reconfig-exec-0 = test -t 1 && { : $${CONFIGURE_TTY=yes}; export CONFIGURE_TTY; }; exec 3>&1; exit `exec 4>&1; { "$$@" 3>&- 4>&-; echo $$? 1>&4; } | fgrep -v '(cached)' 1>&3 3>&- 4>&-` -reconfig-exec-1 = set -x; "$$@" +reconfig-exec-1 = set -x; exec "$$@" +reconfig-exec-yes = $(reconfig-exec-1) reconfig config.status: $(srcdir)/$(CONFIGURE) $(srcdir)/enc/Makefile.in \ $(hdrdir)/ruby/version.h $(ABI_VERSION_HDR) @PWD= MINIRUBY="$(MINIRUBY)"; export MINIRUBY; \ - set $(SHELL) $($@-args); $(reconfig-exec-$(V)) + set $(SHELL) $($@-args); $(reconfig-exec-$(silence:no=$(V))) $(srcdir)/$(CONFIGURE): $(srcdir)/configure.ac $(CHDIR) $(srcdir) && exec $(AUTOCONF) -o $(@F) From a9abf60c971a6d42fd5ca0566c796162960454d2 Mon Sep 17 00:00:00 2001 From: git Date: Sun, 14 Aug 2022 14:45:07 +0900 Subject: [PATCH 34/44] * 2022-08-14 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 9d5c6428f2054e..ee6404291f14b3 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 13 +#define RUBY_RELEASE_DAY 14 #include "ruby/version.h" #include "ruby/internal/abi.h" From cb12d7c71bb5b5ef4ebfc7a2008f66dd8410ccd2 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sun, 14 Aug 2022 19:25:56 +0900 Subject: [PATCH 35/44] Update dependencies --- common.mk | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/common.mk b/common.mk index 9f89e0ec8af26c..ec5e4ae2522ef1 100644 --- a/common.mk +++ b/common.mk @@ -13822,7 +13822,6 @@ signal.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h signal.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h signal.$(OBJEXT): $(CCAN_DIR)/list/list.h signal.$(OBJEXT): $(CCAN_DIR)/str/str.h -signal.$(OBJEXT): $(hdrdir)/ruby.h signal.$(OBJEXT): $(hdrdir)/ruby/ruby.h signal.$(OBJEXT): $(top_srcdir)/internal/array.h signal.$(OBJEXT): $(top_srcdir)/internal/compilers.h @@ -14008,7 +14007,6 @@ signal.$(OBJEXT): {$(VPATH)}internal/warning_push.h signal.$(OBJEXT): {$(VPATH)}internal/xmalloc.h signal.$(OBJEXT): {$(VPATH)}method.h signal.$(OBJEXT): {$(VPATH)}missing.h -signal.$(OBJEXT): {$(VPATH)}mjit.h signal.$(OBJEXT): {$(VPATH)}node.h signal.$(OBJEXT): {$(VPATH)}onigmo.h signal.$(OBJEXT): {$(VPATH)}oniguruma.h @@ -14024,7 +14022,6 @@ signal.$(OBJEXT): {$(VPATH)}thread_native.h signal.$(OBJEXT): {$(VPATH)}vm_core.h signal.$(OBJEXT): {$(VPATH)}vm_debug.h signal.$(OBJEXT): {$(VPATH)}vm_opts.h -signal.$(OBJEXT): {$(VPATH)}yjit.h sprintf.$(OBJEXT): $(hdrdir)/ruby/ruby.h sprintf.$(OBJEXT): $(top_srcdir)/internal/bignum.h sprintf.$(OBJEXT): $(top_srcdir)/internal/bits.h @@ -17593,16 +17590,14 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/array.h yjit.$(OBJEXT): $(top_srcdir)/internal/class.h yjit.$(OBJEXT): $(top_srcdir)/internal/compile.h yjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h +yjit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h yjit.$(OBJEXT): $(top_srcdir)/internal/gc.h yjit.$(OBJEXT): $(top_srcdir)/internal/hash.h yjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h -yjit.$(OBJEXT): $(top_srcdir)/internal/object.h -yjit.$(OBJEXT): $(top_srcdir)/internal/re.h yjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h yjit.$(OBJEXT): $(top_srcdir)/internal/serial.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 @@ -17620,6 +17615,7 @@ yjit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h yjit.$(OBJEXT): {$(VPATH)}builtin.h yjit.$(OBJEXT): {$(VPATH)}config.h yjit.$(OBJEXT): {$(VPATH)}constant.h +yjit.$(OBJEXT): {$(VPATH)}debug.h yjit.$(OBJEXT): {$(VPATH)}debug_counter.h yjit.$(OBJEXT): {$(VPATH)}defines.h yjit.$(OBJEXT): {$(VPATH)}encoding.h @@ -17798,6 +17794,7 @@ yjit.$(OBJEXT): {$(VPATH)}thread_native.h yjit.$(OBJEXT): {$(VPATH)}vm_callinfo.h yjit.$(OBJEXT): {$(VPATH)}vm_core.h yjit.$(OBJEXT): {$(VPATH)}vm_debug.h +yjit.$(OBJEXT): {$(VPATH)}vm_insnhelper.h yjit.$(OBJEXT): {$(VPATH)}vm_opts.h yjit.$(OBJEXT): {$(VPATH)}vm_sync.h yjit.$(OBJEXT): {$(VPATH)}yjit.c From 89aa09afaf77920fd748aefaba99fe4b0f19e684 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 6 Aug 2021 15:36:33 -0700 Subject: [PATCH 36/44] [ruby/rinda] Handle situations where IPv4 multicast is not available Fixes [Bug #13864] https://github.com/ruby/rinda/commit/3cd620f38c --- test/rinda/test_rinda.rb | 71 +++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/test/rinda/test_rinda.rb b/test/rinda/test_rinda.rb index d8340e0fc48dff..dbe414b783fefd 100644 --- a/test/rinda/test_rinda.rb +++ b/test/rinda/test_rinda.rb @@ -583,6 +583,22 @@ def test_take_bug_8215 end end +module RingIPv4 + def ipv4_mc(rf) + begin + v4mc = rf.make_socket('239.0.0.1') + rescue Errno::ENETUNREACH, Errno::ENOBUFS, Errno::ENODEV + omit 'IPv4 multicast not available' + end + + begin + yield v4mc + ensure + v4mc.close + end + end +end + module RingIPv6 def prepare_ipv6(r) begin @@ -625,6 +641,7 @@ def ipv6_mc(rf, hops = nil) end class TestRingServer < Test::Unit::TestCase + include RingIPv4 def setup @port = Rinda::Ring_PORT @@ -697,27 +714,23 @@ def test_make_socket_unicast end def test_make_socket_ipv4_multicast - begin - v4mc = @rs.make_socket('239.0.0.1') - rescue Errno::ENOBUFS => e - omit "Missing multicast support in OS: #{e.message}" - end - - begin - if Socket.const_defined?(:SO_REUSEPORT) then - assert(v4mc.getsockopt(:SOCKET, :SO_REUSEPORT).bool) - else - assert(v4mc.getsockopt(:SOCKET, :SO_REUSEADDR).bool) - end - rescue TypeError - if /aix/ =~ RUBY_PLATFORM - omit "Known bug in getsockopt(2) on AIX" + ipv4_mc(@rs) do |v4mc| + begin + if Socket.const_defined?(:SO_REUSEPORT) then + assert(v4mc.getsockopt(:SOCKET, :SO_REUSEPORT).bool) + else + assert(v4mc.getsockopt(:SOCKET, :SO_REUSEADDR).bool) + end + rescue TypeError + if /aix/ =~ RUBY_PLATFORM + omit "Known bug in getsockopt(2) on AIX" + end + raise $! end - raise $! - end - assert_equal('0.0.0.0', v4mc.local_address.ip_address) - assert_equal(@port, v4mc.local_address.ip_port) + assert_equal('0.0.0.0', v4mc.local_address.ip_address) + assert_equal(@port, v4mc.local_address.ip_port) + end end def test_make_socket_ipv6_multicast @@ -746,7 +759,7 @@ def test_ring_server_ipv4_multicast @rs.shutdown begin @rs = Rinda::RingServer.new(@ts, [['239.0.0.1', '0.0.0.0']], @port) - rescue Errno::ENOBUFS => e + rescue Errno::ENOBUFS, Errno::ENODEV => e omit "Missing multicast support in OS: #{e.message}" end @@ -848,6 +861,7 @@ def wait_for(n) class TestRingFinger < Test::Unit::TestCase include RingIPv6 + include RingIPv4 def setup @rf = Rinda::RingFinger.new @@ -867,12 +881,10 @@ def test_make_socket_unicast end def test_make_socket_ipv4_multicast - v4mc = @rf.make_socket('239.0.0.1') - - assert_equal(1, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_LOOP).ipv4_multicast_loop) - assert_equal(1, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL).ipv4_multicast_ttl) - ensure - v4mc.close if v4mc + ipv4_mc(@rf) do |v4mc| + assert_equal(1, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_LOOP).ipv4_multicast_loop) + assert_equal(1, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL).ipv4_multicast_ttl) + end end def test_make_socket_ipv6_multicast @@ -884,10 +896,9 @@ def test_make_socket_ipv6_multicast def test_make_socket_ipv4_multicast_hops @rf.multicast_hops = 2 - v4mc = @rf.make_socket('239.0.0.1') - assert_equal(2, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL).ipv4_multicast_ttl) - ensure - v4mc.close if v4mc + ipv4_mc(@rf) do |v4mc| + assert_equal(2, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL).ipv4_multicast_ttl) + end end def test_make_socket_ipv6_multicast_hops From cbcf2dad399352fecfd3a670279972a3e058510d Mon Sep 17 00:00:00 2001 From: git Date: Mon, 15 Aug 2022 14:12:08 +0900 Subject: [PATCH 37/44] * 2022-08-15 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index ee6404291f14b3..428100b2f921ba 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 14 +#define RUBY_RELEASE_DAY 15 #include "ruby/version.h" #include "ruby/internal/abi.h" From e77c8397c21d77901891bd7e65dfba6478b9b6c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 11 Aug 2022 20:32:38 +0200 Subject: [PATCH 38/44] [rubygems/rubygems] Fix Ruby platform incorrectly removed on `bundle update` https://github.com/rubygems/rubygems/commit/0d321c9e3a --- lib/bundler/definition.rb | 2 +- .../install/gemfile/specific_platform_spec.rb | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 21c06e55bab503..0ab0451695b36e 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -888,7 +888,7 @@ def remove_ruby_from_platforms_if_necessary!(dependencies) Bundler.local_platform == Gem::Platform::RUBY || !platforms.include?(Gem::Platform::RUBY) || (@new_platform && platforms.last == Gem::Platform::RUBY) || - !@originally_locked_specs.incomplete_ruby_specs?(dependencies) + !@originally_locked_specs.incomplete_ruby_specs?(expand_dependencies(dependencies)) remove_platform(Gem::Platform::RUBY) add_current_platform diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index fe1c3b71fe1913..bb5526203fc376 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -445,6 +445,47 @@ L end + it "does not remove ruby if gems for other platforms, and not present in the lockfile, exist in the Gemfile" do + build_repo4 do + build_gem "nokogiri", "1.13.8" + build_gem "nokogiri", "1.13.8" do |s| + s.platform = Gem::Platform.local + end + end + + gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + + gem "nokogiri" + + gem "tzinfo", "~> 1.2", platform: :#{not_local_tag} + G + + original_lockfile = <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + nokogiri (1.13.8) + nokogiri (1.13.8-#{Gem::Platform.local}) + + PLATFORMS + #{lockfile_platforms_for([specific_local_platform, "ruby"])} + + DEPENDENCIES + nokogiri + tzinfo (~> 1.2) + + BUNDLED WITH + #{Bundler::VERSION} + L + + lockfile original_lockfile + + bundle "lock --update" + + expect(lockfile).to eq(original_lockfile) + end + it "can fallback to a source gem when platform gems are incompatible with current ruby version" do setup_multiplatform_gem_with_source_gem From 8d40ede2e005439cbc84abfd50c98932a33448f4 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Mon, 15 Aug 2022 08:16:13 -0500 Subject: [PATCH 39/44] [ruby/date] [DOC] Enhanced intro for Date (https://github.com/ruby/date/pull/72) https://github.com/ruby/date/commit/59a6673221 --- ext/date/date_core.c | 184 ++++++++++++------------------------------- 1 file changed, 51 insertions(+), 133 deletions(-) diff --git a/ext/date/date_core.c b/ext/date/date_core.c index c68f70e5f88f95..83d493c794842a 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -4505,6 +4505,9 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass) * Note: * This method recognizes many forms in +string+, * but it is not a validator. + * For formats, see + * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings] + * * If +string+ does not specify a valid date, * the result is unpredictable; * consider using Date._strptime instead. @@ -4537,6 +4540,8 @@ date_s__parse(int argc, VALUE *argv, VALUE klass) * Note: * This method recognizes many forms in +string+, * but it is not a validator. + * For formats, see + * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings] * If +string+ does not specify a valid date, * the result is unpredictable; * consider using Date._strptime instead. @@ -4671,7 +4676,7 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass) * Date._rfc3339(string, limit: 128) -> hash * * Returns a hash of values parsed from +string+, which should be a valid - * {RFC 3339 format}[https://datatracker.ietf.org/doc/html/rfc3339]: + * {RFC 3339 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+3339+Format]: * * d = Date.new(2001, 2, 3) * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" @@ -4699,7 +4704,7 @@ date_s__rfc3339(int argc, VALUE *argv, VALUE klass) * * Returns a new \Date object with values parsed from +string+, * which should be a valid - * {RFC 3339 format}[https://datatracker.ietf.org/doc/html/rfc3339]: + * {RFC 3339 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+3339+Format]: * * d = Date.new(2001, 2, 3) * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" @@ -4811,7 +4816,7 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass) * Date._rfc2822(string, limit: 128) -> hash * * Returns a hash of values parsed from +string+, which should be a valid - * {RFC 2822 date format}[https://datatracker.ietf.org/doc/html/rfc2822]: + * {RFC 2822 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+2822+Format]: * * d = Date.new(2001, 2, 3) * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" @@ -4841,7 +4846,7 @@ date_s__rfc2822(int argc, VALUE *argv, VALUE klass) * * Returns a new \Date object with values parsed from +string+, * which should be a valid - * {RFC 2822 date format}[https://datatracker.ietf.org/doc/html/rfc2822]: + * {RFC 2822 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+2822+Format]: * * d = Date.new(2001, 2, 3) * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" @@ -4885,7 +4890,7 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass) * Date._httpdate(string, limit: 128) -> hash * * Returns a hash of values parsed from +string+, which should be a valid - * HTTP date format: + * {HTTP date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-HTTP+Format]: * * d = Date.new(2001, 2, 3) * s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" @@ -4911,7 +4916,7 @@ date_s__httpdate(int argc, VALUE *argv, VALUE klass) * * Returns a new \Date object with values parsed from +string+, * which should be a valid - * {RFC 2616 date format}[https://datatracker.ietf.org/doc/html/rfc2616]: + * {HTTP date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-HTTP+Format]: * * d = Date.new(2001, 2, 3) s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" @@ -4953,7 +4958,7 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass) * Date._jisx0301(string, limit: 128) -> hash * * Returns a hash of values parsed from +string+, which should be a valid - * JIS X 0301 date format: + * {JIS X 0301 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-JIS+X+0301+Format]: * * d = Date.new(2001, 2, 3) * s = d.jisx0301 # => "H13.02.03" @@ -4979,7 +4984,7 @@ date_s__jisx0301(int argc, VALUE *argv, VALUE klass) * Date.jisx0301(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date * * Returns a new \Date object with values parsed from +string+, - * which should be a valid JIS X 0301 format: + * which should be a valid {JIS X 0301 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-JIS+X+0301+Format]: * * d = Date.new(2001, 2, 3) * s = d.jisx0301 # => "H13.02.03" @@ -9383,151 +9388,65 @@ Init_date_core(void) negative_inf = -INFINITY; /* - * date and datetime class - Tadayoshi Funaba 1998-2011 - * - * 'date' provides two classes: Date and DateTime. - * - * == Terms and Definitions - * - * Some terms and definitions are based on ISO 8601 and JIS X 0301. - * - * === Calendar Date - * - * The calendar date is a particular day of a calendar year, - * identified by its ordinal number within a calendar month within - * that year. + * \Class \Date provides methods for storing and manipulating + * calendar dates. * - * In those classes, this is so-called "civil". + * Consider using + * {class Time}[https://docs.ruby-lang.org/en/master/Time.html] + * instead of class \Date if: * - * === Ordinal Date + * - You need both dates and times; \Date handles only dates. + * - You need only Gregorian dates (and not Julian dates); + * see {Julian and Gregorian Calendars}[rdoc-ref:calendars.rdoc]. * - * The ordinal date is a particular day of a calendar year identified - * by its ordinal number within the year. + * A \Date object, once created, is immutable, and cannot be modified. * - * In those classes, this is so-called "ordinal". + * == Creating a \Date * - * === Week Date + * You can create a date for the current date, using Date.today: * - * The week date is a date identified by calendar week and day numbers. + * Date.today # => # * - * The calendar week is a seven day period within a calendar year, - * starting on a Monday and identified by its ordinal number within - * the year; the first calendar week of the year is the one that - * includes the first Thursday of that year. In the Gregorian - * calendar, this is equivalent to the week which includes January 4. + * You can create a specific date from various combinations of arguments: * - * In those classes, this is so-called "commercial". + * - Date.new takes integer year, month, and day-of-month: * - * === Julian Day Number + * Date.new(1999, 12, 31) # => # * - * The Julian day number is in elapsed days since noon (Greenwich Mean - * Time) on January 1, 4713 BCE (in the Julian calendar). + * - Date.ordinal takes integer year and day-of-year: * - * In this document, the astronomical Julian day number is the same as - * the original Julian day number. And the chronological Julian day - * number is a variation of the Julian day number. Its days begin at - * midnight on local time. + * Date.ordinal(1999, 365) # => # * - * In this document, when the term "Julian day number" simply appears, - * it just refers to "chronological Julian day number", not the - * original. + * - Date.jd takes integer Julian day: * - * In those classes, those are so-called "ajd" and "jd". + * Date.jd(2451544) # => # * - * === Modified Julian Day Number + * - Date.commercial takes integer commercial data (year, week, day-of-week): * - * The modified Julian day number is in elapsed days since midnight - * (Coordinated Universal Time) on November 17, 1858 CE (in the - * Gregorian calendar). + * Date.commercial(1999, 52, 5) # => # * - * In this document, the astronomical modified Julian day number is - * the same as the original modified Julian day number. And the - * chronological modified Julian day number is a variation of the - * modified Julian day number. Its days begin at midnight on local - * time. + * - Date.parse takes a string, which it parses heuristically: * - * In this document, when the term "modified Julian day number" simply - * appears, it just refers to "chronological modified Julian day - * number", not the original. + * Date.parse('1999-12-31') # => # + * Date.parse('31-12-1999') # => # + * Date.parse('1999-365') # => # + * Date.parse('1999-W52-5') # => # * - * In those classes, those are so-called "amjd" and "mjd". - * - * == Date - * - * A subclass of Object that includes the Comparable module and - * easily handles date. - * - * A Date object is created with Date::new, Date::jd, Date::ordinal, - * Date::commercial, Date::parse, Date::strptime, Date::today, - * Time#to_date, etc. - * - * require 'date' + * - Date.strptime takes a date string and a format string, + * then parses the date string according to the format string: * - * Date.new(2001,2,3) - * #=> # - * Date.jd(2451944) - * #=> # - * Date.ordinal(2001,34) - * #=> # - * Date.commercial(2001,5,6) - * #=> # - * Date.parse('2001-02-03') - * #=> # - * Date.strptime('03-02-2001', '%d-%m-%Y') - * #=> # - * Time.new(2001,2,3).to_date - * #=> # + * Date.strptime('1999-12-31', '%Y-%m-%d') # => # + * Date.strptime('31-12-1999', '%d-%m-%Y') # => # + * Date.strptime('1999-365', '%Y-%j') # => # + * Date.strptime('1999-W52-5', '%G-W%V-%u') # => # + * Date.strptime('1999 52 5', '%Y %U %w') # => # + * Date.strptime('1999 52 5', '%Y %W %u') # => # + * Date.strptime('fri31dec99', '%a%d%b%y') # => # * - * All date objects are immutable; hence cannot modify themselves. + * See also the specialized methods in + * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings] * - * The concept of a date object can be represented as a tuple - * of the day count, the offset and the day of calendar reform. - * - * The day count denotes the absolute position of a temporal - * dimension. The offset is relative adjustment, which determines - * decoded local time with the day count. The day of calendar - * reform denotes the start day of the new style. The old style - * of the West is the Julian calendar which was adopted by - * Caesar. The new style is the Gregorian calendar, which is the - * current civil calendar of many countries. - * - * The day count is virtually the astronomical Julian day number. - * The offset in this class is usually zero, and cannot be - * specified directly. - * - * A Date object can be created with an optional argument, - * the day of calendar reform as a Julian day number, which - * should be 2298874 to 2426355 or negative/positive infinity. - * The default value is +Date::ITALY+ (2299161=1582-10-15). - * See also sample/cal.rb. - * - * $ ruby sample/cal.rb -c it 10 1582 - * October 1582 - * S M Tu W Th F S - * 1 2 3 4 15 16 - * 17 18 19 20 21 22 23 - * 24 25 26 27 28 29 30 - * 31 - * - * $ ruby sample/cal.rb -c gb 9 1752 - * September 1752 - * S M Tu W Th F S - * 1 2 14 15 16 - * 17 18 19 20 21 22 23 - * 24 25 26 27 28 29 30 - * - * A Date object has various methods. See each reference. - * - * d = Date.parse('3rd Feb 2001') - * #=> # - * d.year #=> 2001 - * d.mon #=> 2 - * d.mday #=> 3 - * d.wday #=> 6 - * d += 1 #=> # - * d.strftime('%a %d %b %Y') #=> "Sun 04 Feb 2001" - * - * === Argument +limit+ + * == Argument +limit+ * * Certain singleton methods in \Date that parse string arguments * also take optional keyword argument +limit+, @@ -9541,7 +9460,6 @@ Init_date_core(void) * - Other non-numeric: raises TypeError. * */ - cDate = rb_define_class("Date", rb_cObject); /* Exception for invalid date/time */ From 0264424d58e0eb3ff6fc42b7b4164b6e3b8ea8ca Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 15 Aug 2022 09:14:35 -0400 Subject: [PATCH 40/44] Add test for GC thrashing of young object creation This test will prevent performance regressions like [Bug #18929]. --- test/ruby/test_gc.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index a5d7f4dbaa83a9..a1e782daa93a21 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -402,6 +402,28 @@ def test_expand_heap eom end + def test_thrashing_for_young_objects + # This test prevents bugs like [Bug #18929] + + assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-RUBY + # Warmup to make sure heap stabilizes + 1_000_000.times { Object.new } + + before_stats = GC.stat + + 1_000_000.times { Object.new } + + after_stats = GC.stat + + # Should not be thrashing in page creation + assert_equal before_stats[:heap_allocated_pages], after_stats[:heap_allocated_pages] + assert_equal 0, after_stats[:heap_tomb_pages] + assert_equal 0, after_stats[:total_freed_pages] + # Only young objects, so should not trigger major GC + assert_equal before_stats[:major_gc_count], after_stats[:major_gc_count] + RUBY + end + def test_gc_internals assert_not_nil GC::INTERNAL_CONSTANTS[:HEAP_PAGE_OBJ_LIMIT] assert_not_nil GC::INTERNAL_CONSTANTS[:RVALUE_SIZE] From ee864beb7c6730083da656b55f4a9eeaed78bfa8 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 16 Aug 2022 02:05:12 +0900 Subject: [PATCH 41/44] Simplify around `USE_YJIT` macro (#6240) * Simplify around `USE_YJIT` macro - Use `USE_YJIT` macro only instead of `YJIT_BUILD`. - An intermediate macro `YJIT_SUPPORTED_P` is no longer used. * Bail out if YJIT is enabled on unsupported platforms --- iseq.c | 6 +++--- ruby.c | 20 ++++++++++---------- vm.c | 2 +- vm_core.h | 1 - yjit.h | 23 +++++++---------------- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/iseq.c b/iseq.c index 3d40b88a0de1bc..f17a2d49b61278 100644 --- a/iseq.c +++ b/iseq.c @@ -175,7 +175,7 @@ rb_iseq_free(const rb_iseq_t *iseq) iseq_clear_ic_references(iseq); struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); mjit_free_iseq(iseq); /* Notify MJIT */ -#if YJIT_BUILD +#if USE_YJIT rb_yjit_iseq_free(body->yjit_payload); #endif ruby_xfree((void *)body->iseq_encoded); @@ -438,7 +438,7 @@ rb_iseq_update_references(rb_iseq_t *iseq) #if USE_MJIT mjit_update_references(iseq); #endif -#if YJIT_BUILD +#if USE_YJIT rb_yjit_iseq_update_references(body->yjit_payload); #endif } @@ -526,7 +526,7 @@ rb_iseq_mark(const rb_iseq_t *iseq) #if USE_MJIT mjit_mark_cc_entries(body); #endif -#if YJIT_BUILD +#if USE_YJIT rb_yjit_iseq_mark(body->yjit_payload); #endif } diff --git a/ruby.c b/ruby.c index 7c6742cac47905..66feeb797e6cf6 100644 --- a/ruby.c +++ b/ruby.c @@ -111,7 +111,7 @@ void rb_warning_category_update(unsigned int mask, unsigned int bits); enum feature_flag_bits { EACH_FEATURES(DEFINE_FEATURE, COMMA), feature_debug_flag_first, -#if defined(MJIT_FORCE_ENABLE) || !YJIT_BUILD +#if defined(MJIT_FORCE_ENABLE) || !USE_YJIT DEFINE_FEATURE(jit) = feature_mjit, #else DEFINE_FEATURE(jit) = feature_yjit, @@ -248,7 +248,7 @@ usage(const char *name, int help, int highlight, int columns) #define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc) -#if YJIT_BUILD +#if USE_YJIT # define PLATFORM_JIT_OPTION "--yjit" #else # define PLATFORM_JIT_OPTION "--mjit" @@ -278,7 +278,7 @@ usage(const char *name, int help, int highlight, int columns) #if USE_MJIT M("--mjit", "", "enable C compiler-based JIT compiler (experimental)"), #endif -#if YJIT_BUILD +#if USE_YJIT M("--yjit", "", "enable in-process JIT compiler (experimental)"), #endif M("-h", "", "show this message, --help for more info"), @@ -312,7 +312,7 @@ usage(const char *name, int help, int highlight, int columns) #if USE_MJIT M("mjit", "", "C compiler-based JIT compiler (default: disabled)"), #endif -#if YJIT_BUILD +#if USE_YJIT M("yjit", "", "in-process JIT compiler (default: disabled)"), #endif }; @@ -323,7 +323,7 @@ usage(const char *name, int help, int highlight, int columns) #if USE_MJIT extern const struct ruby_opt_message mjit_option_messages[]; #endif -#if YJIT_BUILD +#if USE_YJIT static const struct ruby_opt_message yjit_options[] = { #if YJIT_STATS M("--yjit-stats", "", "Enable collecting YJIT statistics"), @@ -365,7 +365,7 @@ usage(const char *name, int help, int highlight, int columns) for (i = 0; mjit_option_messages[i].str; ++i) SHOW(mjit_option_messages[i]); #endif -#if YJIT_BUILD +#if USE_YJIT printf("%s""YJIT options (experimental):%s\n", sb, se); for (i = 0; i < numberof(yjit_options); ++i) SHOW(yjit_options[i]); @@ -1047,7 +1047,7 @@ set_option_encoding_once(const char *type, VALUE *name, const char *e, long elen #define yjit_opt_match_arg(s, l, name) \ opt_match(s, l, name) && (*(s) && *(s+1) ? 1 : (rb_raise(rb_eRuntimeError, "--yjit-" name " needs an argument"), 0)) -#if YJIT_BUILD +#if USE_YJIT static bool setup_yjit_options(const char *s) { @@ -1452,7 +1452,7 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt) #endif } else if (is_option_with_optarg("yjit", '-', true, false, false)) { -#if YJIT_BUILD +#if USE_YJIT FEATURE_SET(opt->features, FEATURE_BIT(yjit)); setup_yjit_options(s); #else @@ -1831,7 +1831,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt) rb_warning("-K is specified; it is for 1.8 compatibility and may cause odd behavior"); if (!(FEATURE_SET_BITS(opt->features) & feature_jit_mask)) { -#if YJIT_BUILD +#if USE_YJIT if (!FEATURE_USED_P(opt->features, yjit) && getenv("RUBY_YJIT_ENABLE")) { FEATURE_SET(opt->features, FEATURE_BIT(yjit)); } @@ -1847,7 +1847,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt) opt->mjit.on = TRUE; /* set mjit.on for ruby_show_version() API and check to call mjit_init() */ } #endif -#if YJIT_BUILD +#if USE_YJIT if (FEATURE_SET_P(opt->features, yjit)) { rb_yjit_init(); } diff --git a/vm.c b/vm.c index 3bba390e7cba18..4b1a30e7cae45a 100644 --- a/vm.c +++ b/vm.c @@ -3938,7 +3938,7 @@ Init_vm_objects(void) } /* Stub for builtin function when not building YJIT units*/ -#if !YJIT_BUILD +#if !USE_YJIT void Init_builtin_yjit(void) {} #endif diff --git a/vm_core.h b/vm_core.h index c394862ecbab79..717f1168006ab3 100644 --- a/vm_core.h +++ b/vm_core.h @@ -495,7 +495,6 @@ struct rb_iseq_constant_body { #if USE_YJIT // YJIT stores some data on each iseq. - // Note: Cannot use YJIT_BUILD here since yjit.h includes this header. void *yjit_payload; #endif }; diff --git a/yjit.h b/yjit.h index cf420df251791d..1f507f1b519fae 100644 --- a/yjit.h +++ b/yjit.h @@ -15,24 +15,15 @@ # define YJIT_STATS RUBY_DEBUG #endif -// We generate x86 assembly -#if (defined(__x86_64__) && !defined(_WIN32)) || (defined(_WIN32) && defined(_M_AMD64)) // x64 platforms without mingw/msys -# define YJIT_SUPPORTED_P 1 -#else -# define YJIT_SUPPORTED_P 0 -#endif +#if USE_YJIT -// Is the output binary going to include YJIT? -#if USE_MJIT && USE_YJIT && YJIT_SUPPORTED_P -# define YJIT_BUILD 1 +// We generate x86 assembly +#if defined(_WIN32) ? defined(_M_AMD64) : defined(__x86_64__) +// x86_64 platforms without mingw/msys or x64-mswin #else -# define YJIT_BUILD 0 +# error YJIT unsupported platform #endif -#undef YJIT_SUPPORTED_P - -#if YJIT_BUILD - // Expose these as declarations since we are building YJIT. bool rb_yjit_enabled_p(void); unsigned rb_yjit_call_threshold(void); @@ -54,7 +45,7 @@ void rb_yjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic); void rb_yjit_tracing_invalidate_all(void); #else -// !YJIT_BUILD +// !USE_YJIT // In these builds, YJIT could never be turned on. Provide dummy implementations. static inline bool rb_yjit_enabled_p(void) { return false; } @@ -76,6 +67,6 @@ static inline void rb_yjit_before_ractor_spawn(void) {} static inline void rb_yjit_constant_ic_update(const rb_iseq_t *const iseq, IC ic) {} static inline void rb_yjit_tracing_invalidate_all(void) {} -#endif // #if YJIT_BUILD +#endif // #if USE_YJIT #endif // #ifndef YJIT_H From e34720dcf4dcde543a0d9eabd4dd92bcdcb41c1f Mon Sep 17 00:00:00 2001 From: git Date: Tue, 16 Aug 2022 02:05:28 +0900 Subject: [PATCH 42/44] * 2022-08-16 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 428100b2f921ba..729809a0e63f05 100644 --- a/version.h +++ b/version.h @@ -15,7 +15,7 @@ #define RUBY_RELEASE_YEAR 2022 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 15 +#define RUBY_RELEASE_DAY 16 #include "ruby/version.h" #include "ruby/internal/abi.h" From 4e66b3f47b2ad0d6cca1f2227dd38fdf117c0d3c Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 15 Aug 2022 09:35:49 -0400 Subject: [PATCH 43/44] [ruby/rdoc] [DOC] Remove duplicated line in RDoc::MarkupReference https://github.com/ruby/rdoc/commit/488f89aee4 --- doc/rdoc/markup_reference.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/rdoc/markup_reference.rb b/doc/rdoc/markup_reference.rb index 92fe2e7cc36129..66ec6786c07aa4 100644 --- a/doc/rdoc/markup_reference.rb +++ b/doc/rdoc/markup_reference.rb @@ -866,7 +866,6 @@ # # - On-page: ::dummy_singleton_method links to ::dummy_singleton_method. # - Off-pageRDoc::TokenStream::to_html links to RDoc::TokenStream::to_html. -# to \RDoc::TokenStream::to_html. # # Note: Occasionally \RDoc is not linked to a method whose name # has only special characters. Check whether the links you were expecting From 0e74ffef98566b85743a82b77164184feda0ca5e Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Tue, 16 Aug 2022 12:51:16 -0700 Subject: [PATCH 44/44] Allow aarch64 to build YJIT --- yjit.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yjit.h b/yjit.h index 1f507f1b519fae..c9dc52c9b670e3 100644 --- a/yjit.h +++ b/yjit.h @@ -17,8 +17,8 @@ #if USE_YJIT -// We generate x86 assembly -#if defined(_WIN32) ? defined(_M_AMD64) : defined(__x86_64__) +// We generate x86 or arm64 assembly +#if defined(_WIN32) ? defined(_M_AMD64) : (defined(__x86_64__) || defined(__aarch64__)) // x86_64 platforms without mingw/msys or x64-mswin #else # error YJIT unsupported platform