Commit graph

16449 commits

Author SHA1 Message Date
Jean Boussier
324d57df0b TestClass#test_subclass_gc reduce the number of iteration by 10x
The test was taking 10 seconds on my machine and did timeout
on CI once.
2021-12-03 20:27:29 +09:00
Nobuyoshi Nakada
e4c7c5468e
Add tests of string argument to Time.at 2021-12-03 18:35:35 +09:00
John Hawthorn
733500e9d0
Lazily create singletons on instance_{exec,eval} (#5146)
* Lazily create singletons on instance_{exec,eval}

Previously when instance_exec or instance_eval was called on an object,
that object would be given a singleton class so that method
definitions inside the block would be added to the object rather than
its class.

This commit aims to improve performance by delaying the creation of the
singleton class unless/until one is needed for method definition. Most
of the time instance_eval is used without any method definition.

This was implemented by adding a flag to the cref indicating that it
represents a singleton of the object rather than a class itself. In this
case CREF_CLASS returns the object's existing class, but in cases that
we are defining a method (either via definemethod or
VM_SPECIAL_OBJECT_CBASE which is used for undef and alias).

This also happens to fix what I believe is a bug. Previously
instance_eval behaved differently with regards to constant access for
true/false/nil than for all other objects. I don't think this was
intentional.

    String::Foo = "foo"
    "".instance_eval("Foo")   # => "foo"
    Integer::Foo = "foo"
    123.instance_eval("Foo")  # => "foo"
    TrueClass::Foo = "foo"
    true.instance_eval("Foo") # NameError: uninitialized constant Foo

This also slightly changes the error message when trying to define a method
through instance_eval on an object which can't have a singleton class.

Before:

    $ ruby -e '123.instance_eval { def foo; end }'
    -e:1:in `block in <main>': no class/module to add method (TypeError)

After:

    $ ./ruby -e '123.instance_eval { def foo; end }'
    -e:1:in `block in <main>': can't define singleton (TypeError)

IMO this error is a small improvement on the original and better matches
the (both old and new) message when definging a method using `def self.`

    $ ruby -e '123.instance_eval{ def self.foo; end }'
    -e:1:in `block in <main>': can't define singleton (TypeError)

Co-authored-by: Matthew Draper <matthew@trebex.net>

* Remove "under" argument from yield_under

* Move CREF_SINGLETON_SET into vm_cref_new

* Simplify vm_get_const_base

* Fix leaf VM_SPECIAL_OBJECT_CONST_BASE

Co-authored-by: Matthew Draper <matthew@trebex.net>
2021-12-02 15:53:39 -08:00
Kaíque Kandy Koga
6b64e78823 [ruby/irb] Examine indentation of in keyword when trying to type include
Use in_keyword_case_scope?

Return fast

8acc7f8dc7
2021-12-03 00:56:43 +09:00
schneems
2b22c93533 Compatibility with IRB
Instead of accessing the struct as an array, access it via methods. There are other places inside of this file already using this API (for example e0a5c3d2b7/lib/irb/ruby-lex.rb (L829-L830)).

This commit moves all struct array-ish calls to use their method calls instead. It is also ~1.23 faster accessing values via a method instead of as an array according to this microbenchmark:

```ruby
Elem = Struct.new(:pos, :event, :tok, :state, :message) do
  def initialize(pos, event, tok, state, message = nil)
    super(pos, event, tok, State.new(state), message)
  end

  # ...

  def to_a
    a = super
    a.pop unless a.empty?
    a
  end
end

class ElemClass
  attr_accessor :pos, :event, :tok, :state, :message

  def initialize(pos, event, tok, state, message = nil)
    @pos = pos
    @event = event
    @tok = tok
    @state = State.new(state)
    @message = message
  end

  def to_a
    if @message
      [@pos, @event, @tok, @state, @message]
    else
      [@pos, @event, @tok, @state]
    end
  end
end

# stub state class creation for now
class State; def initialize(val); end; end
```

```ruby
Benchmark.ips do |x|
  x.report("struct") { struct[1] }
  x.report("class ") { from_class.event }
  x.compare!
end; nil
```

```
Warming up --------------------------------------
              struct     1.624M i/100ms
              class      1.958M i/100ms
Calculating -------------------------------------
              struct     17.139M (± 2.6%) i/s -     86.077M in   5.025801s
              class      21.104M (± 3.4%) i/s -    105.709M in   5.015193s

Comparison:
              class : 21103826.3 i/s
              struct: 17139201.5 i/s - 1.23x  (± 0.00) slower
```
2021-12-02 15:55:42 +09:00
Jeremy Evans
fe1725236c Don't call + and < in Integer.times for !FIXNUM
The methods aren't called for FIXNUM, and it's best to have
consistent behavior.

Fixes [Bug #18377]
2021-12-01 16:21:50 -08:00
Alan Wu
9121e57a5f Rework tracing for blocks running as methods
The main impetus for this change is to fix [Bug #13392]. Previously, we
fired the "return" TracePoint event after popping the stack frame for
the block running as method (BMETHOD). This gave undesirable source
location outputs as the return event normally fires right before the
frame going away.

The iseq for each block can run both as a block and as a method. To
accommodate that, this commit makes vm_trace() fire call/return events for
instructions that have b_call/b_return events attached when the iseq is
running as a BMETHOD. The logic for rewriting to "trace_*" instruction
is tweaked so that when the user listens to call/return events,
instructions with b_call/b_return become trace variants.

To continue to provide the return value for non-local returns done using
the "return" or "break" keyword inside BMETHODs, the stack unwinding
code is tweaked. b_return events now provide the same return value as
return events for these non-local cases. A pre-existing test deemed not
providing a return value for these b_return events as a limitation.

This commit removes the checks for call/return TracePoint events that
happen when calling into BMETHODs when no TracePoints are active.
Technically, migrating just the return event is enough to fix the bug,
but migrating both call and return removes our reliance on
`VM_FRAME_FLAG_FINISH` and re-entering the interpreter when the caller
is already in the interpreter.
2021-12-01 17:42:33 -05:00
Vít Ondruch
94ee88b38c [rubygems/rubygems] Provide distinguished name which will be correctly parsed.
It seems that since ruby openssl 2.1.0 [[1]], the distinguished name
submitted to `OpenSSL::X509::Name.parse` is not correctly parsed if it
does not contain the first slash:

~~~
$ ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]

$ gem list | grep openssl
openssl (default: 2.2.0)

$ irb -r openssl
irb(main):001:0> OpenSSL::X509::Name.parse("CN=nobody/DC=example").to_s(OpenSSL::X509::Name::ONELINE)
=> "CN = nobody/DC=example"
irb(main):002:0> OpenSSL::X509::Name.parse("/CN=nobody/DC=example").to_s(OpenSSL::X509::Name::ONELINE)
=> "CN = nobody, DC = example"
~~~

Instead, use `OpenSSL::X509::Name.new` directly as suggested by upstream
maintainer.

[1]: 19c67cd10c

09ca0c2dae

Co-authored-by: Kazuki Yamaguchi <k@rhe.jp>
2021-12-02 04:43:06 +09:00
Hiroshi SHIBATA
0b53a8895f
Merge rubygems master fd676ac464491afaa0baf5435cb11b3f86229cbd 2021-12-01 11:00:10 +09:00
David Rodríguez
7fd88da935 [rubygems/rubygems] Fix race condition when reading & writing gemspecs concurrently
When bundler parallel installer installs gems concurrently, one can get
confusing warnings like the following:

```
"[/home/runner/work/rubygems/rubygems/bundler/tmp/2/gems/system/specifications/zeitwerk-2.4.2.gemspec] isn't a Gem::Specification (NilClass instead).
```

I've got these warnings several times in the past, but I never managed
to reproduce them, and never look deeply into the root cause, but this
time a got a cause that reproduced quite frequently, so I looked into
it.

The problem is one thread reading a gemspec while another thread is
writing it. The write of the gemspec was not protected, so
`Gem::Specification.load` could end up seeing a truncated gemspec and
thus throw this warning.

The fix involve two changes:

* Change the methods that write gemspecs to use `Gem.binary_write` which
  is protected by a lock.

* Fix `Gem.binary_write` to create the file lock at file creation time,
  not when the file already exists after.

The realworld user problem caused by this issue happens in bundler, but
I'm fixing it in rubygems first, and then I'll backport to bundler
whatever needs backporting to fix the issue on the bundler side.

a672e7555c
2021-11-30 20:54:05 +09:00
David Rodríguez
d7f6cb0f78 [rubygems/rubygems] Revert "Remove spec file before building"
This reverts commit af604436d8141c34cb2e1e645b9b0d47bfd55a55.

The issue that led to introducing it was never reproduced. I tried to
repro with this patch and it still works just fine. Since this removal
is getting in the middle for some race conditions I'm facing, I'm
reverting the patch.

2dd267f0e4
2021-11-30 20:54:05 +09:00
David Rodríguez
2b1f048714 [rubygems/rubygems] Run hooks tests on gemspecs not already installed
The current `setup_base_installer` ends up using the `quick_gem` helper,
which leaves the created specification installed. Instead, make sure to
use the `util_spec` helper, which does a similar thing but doesn't leave
the specification installed.

The idea is that tests do not rely on the installer removing existing
gemspecs, bacause I plan to stop doing that.

843f1a0abc
2021-11-30 20:54:04 +09:00
Naohisa Goto
f8f2885bd0 Revert "test/socket/test_socket.rb: skip on Solaris"
This reverts commit 27fb9d272d.

The test failure on Solaris 10 is due to incomplete IPv6 configuration
on the CI server, that have already been fixed.

Reference for the fix: https://centrify.force.com/support/Article/KB-1179-X11-Forwarding-fails-with-Centrify-OpenSSH-5-0-Solaris/
2021-11-30 00:07:30 +09:00
Lars Kanis
95a6212a43 Simplify platform check for Windows-UCRT
RUBY_PLATFORM can be used since commit 576b2e64cd .
2021-11-29 23:07:16 +09:00
Koichi Sasada
e984c2a9ea fix to choose correct callcache
It should retun general `cc`, not for overloaded (mandatory only)
method call cache.

This issue is reported by @shugo and @ktou
https://twitter.com/shugomaeda/status/1463699797182119936
2021-11-26 10:56:03 +09:00
John Hawthorn
de9a1e4a96
YJIT: Implement new struct accessors (#5161)
* YJIT: Implement optimized_method_struct_aref

* YJIT: Implement struct_aref without method call

Struct member reads can be compiled directly into a memory read (with
either one or two levels of indirection).

* YJIT: Implement optimized struct aset

* YJIT: Update tests for struct access

* YJIT: Add counters for remaining optimized methods

* Check for INT32_MAX overflow

It only takes a struct with 0x7fffffff/8+1 members. Also add some
cheap compile time checks.

* Add tests for non-embedded struct aref/aset

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2021-11-25 11:56:58 -08:00
Peter Zhu
b0bbcaedc7 Revert "Add GC.stat_size_pool to get stats for a size pool"
This reverts commit 6157619bb6.

We'll wait for comments in the open ticket: https://bugs.ruby-lang.org/issues/18364
2021-11-25 11:01:50 -05:00
Peter Zhu
6157619bb6 Add GC.stat_size_pool to get stats for a size pool
GC.stat_size_pool will return stats for a particular size pool. This is
used for the Variable Width Allocation feature.
2021-11-25 10:33:17 -05:00
Nobuyoshi Nakada
270c48507d
[ruby/win32ole] Scale timeout in win32ole
7e04d0eb3e
2021-11-25 23:53:15 +09:00
Nobuyoshi Nakada
ae95939784
[ruby/win32ole] Fix typos [ci skip]
8d46bd0c93
2021-11-25 23:53:15 +09:00
Yusuke Endoh
b5aa161383 test/ruby/test_iseq.rb: Avoid pollution of method namespace
20211125T003004Z.log.html.gz
```
[ 4780/21204] TestISeq#test_super_with_anonymous_block/home/chkbuild/chkbuild/tmp/build/20211125T003004Z/ruby/test/ruby/test_iseq.rb:141: warning: method redefined; discarding old touch3
/home/chkbuild/chkbuild/tmp/build/20211125T003004Z/ruby/test/ruby/test_iseq.rb:121: warning: previous definition of touch3 was here
 = 0.00 s
```
2021-11-25 11:01:27 +09:00
Peter Zhu
c51b92c18d [ruby/zlib] [Bug #18358] Fix crash in zlib when in progress
When Zlib::Inflate#inflate or Zlib::Deflate#deflate is called
recursively inside the block, a crash can occur because of an
use-after-free bug.

50fb8a0338
2021-11-24 23:01:41 +09:00
Nobuyoshi Nakada
0f31b3f465 [ruby/cgi] When parsing cookies, only decode the values
052eb3a828
2021-11-24 19:59:00 +09:00
Yusuke Endoh
3454a456d1 test/ruby/test_iseq.rb: Use __LINE__ to make the error log easy to see 2021-11-24 15:42:00 +09:00
Eileen M. Uchitelle
459f9e3df8
Add setclassvariable to yjit (#5127)
Implements setclassvariable in yjit. Note that this version is not
faster than the standard version because we aren't handling the inline
cache in assembly. This is still important to implement because it will
prevent yjit from exiting in methods that call both a cvar setter and
other code that yjit can compile.

Co-authored-by: Aaron Patterson tenderlove@ruby-lang.org
2021-11-23 14:09:24 -05:00
Jean Boussier
eb301d8aec Add an extra failing test case for [Bug #18250]
The parameter being called `req` specifically causes an assertion error:

```
Assertion failed: (key != 0), function hash_table_raw_insert, file id_table.c, line 153.
```

Renaming the parameter or removing the `*` doesn't reproduce.
2021-11-23 21:03:19 +09:00
Jean Boussier
c0c2b31a35 Add Class#subclasses
Implements [Feature #18273]

Returns an array containing the receiver's direct subclasses without
singleton classes.
2021-11-23 10:50:44 +01:00
Nobuyoshi Nakada
a88b19d3d0
Suppress the “experimental" warnings for IO::Buffer
As this warning is emitted just once per processes, needs in each
files when parallel testing.
2021-11-23 16:08:53 +09:00
Alan Wu
f5d2041138
Avoid assert failure when NULL EC is expected
After 5680c38c75, postponed job APIs now
expect to be called on native threads not managed by Ruby and handles
getting a NULL execution context. However, in debug builds the change
runs into an assertion failure with GET_EC() which asserts that EC is
non-NULL. Avoid the assertion failure by passing `false` for `expect_ec`
instead as the intention is to handle when there is no EC.

Add a test from John Crepezzi and John Hawthorn to exercise this
situation.

See GH-4108
See GH-5094

[Bug #17573]

Co-authored-by: John Hawthorn <john@hawthorn.email>
Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2021-11-22 19:29:29 -05:00
ima1zumi
f5829e2935 [ruby/reline] Correct padding space calculation
fix https://github.com/ruby/irb/issues/308

This bug occurred when `dialog.width - calculate_width(s, true)` was negative.

When `dialog.width` is shorter than `old_dialog.width`, it calculates how much padding it has to do. However, there are cases where `s` is longer than `dialog.width`, as in the issue. In that case, `padding_space_with_escape_sequences` will crash.

Here, `old_dialog.width` is longer than `dialog.width`, so I changed the padding width to `old_dialog.width - dialog.width`.

c581c31e0f
2021-11-21 13:56:26 +09:00
Nobuyoshi Nakada
8f3432cd44
Fix setting struct member by public_send 2021-11-21 00:31:51 +09:00
Adam Hess
73388aff5e
Add YJIT codegen for objtostring (#5149)
This is the minimal correct objtostring implementation in YJIT.
For correctness, it is important that to_string not get called on strings or subclasses of string.
There is a new test for this behavior.

A follow up should implement an optimized version for other types as performed in `vm_objtostring`.

Co-authored-by: John Hawthorn <jhawthorn@github.com>

Co-authored-by: John Hawthorn <jhawthorn@github.com>
2021-11-19 16:57:09 -05:00
Jeremy Evans
3c92516519 Fix test_super_with_anonymous_block test to use anonymous block 2021-11-19 11:05:09 -08:00
Koichi Sasada
82ea287018 optimize Struct getter/setter
Introduce new optimized method type
`OPTIMIZED_METHOD_TYPE_STRUCT_AREF/ASET` with index information.
2021-11-19 08:32:39 +09:00
Jeremy Evans
b08dacfea3
Optimize dynamic string interpolation for symbol/true/false/nil/0-9
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.

Speedups (using included benchmarks):
:symbol        :: 60%
0-9            :: 50%
Class/Module   :: 50%
nil/true/false :: 20%
integer        :: 10%
[]             :: 10%
""             :: 3%

One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.

Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.

This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.

This disables 4 YJIT tests.  Those tests should be reenabled after
YJIT optimizes the new objtostring insn.

Implements [Feature #13715]

Co-authored-by: Eric Wong <e@80x24.org>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
2021-11-18 15:10:20 -08:00
Jeremy Evans
4adb012926 Anonymous block forwarding allows a method to forward a passed
block to another method without having to provide a name for the
block parameter.

Implements [Feature #11256]

Co-authored-by: Yusuke Endoh mame@ruby-lang.org
Co-authored-by: Nobuyoshi Nakada nobu@ruby-lang.org
2021-11-18 14:17:57 -08:00
Jeremy Evans
75ecbda438 Make Module#{public,private,protected,module_function} return arguments
Previously, each of these methods returned self, but it is
more useful to return arguments, to allow for simpler method
decorators, such as:

```ruby
cached private def foo; some_long_calculation; end
```

Where cached sets up caching for the method.

For each of these methods, the following behavior is used:

1) No arguments returns nil
2) Single argument is returned
3) Multiple arguments are returned as an array

The single argument case is really the case we are trying to
optimize for, for the same reason that def was changed to return
a symbol for the method.

Idea and initial patch from Herwin Quarantainenet.

Implements [Feature #12495]
2021-11-18 09:47:40 -08:00
Nobuyoshi Nakada
89b440bf72
Expect bool as sort: option at glob [Feature #18287] 2021-11-18 21:47:18 +09:00
Jeremy Evans
b35b7a1ef2 Allow Kernel#load to load code into a specified module
Instead of always using a new anonymous module for Kernel#load if
the wrap argument is not false/nil, use the given module if a module
is provided.

Implements [Feature #6210]
2021-11-17 22:43:40 -08:00
David Rodríguez
d8dde444e9 [rubygems/rubygems] Gem::Specification.reset already clears loaded spec cache
Plus, that method is supposed to be private.

f8a01ddb9f
2021-11-18 04:37:26 +09:00
Peter Zhu
1454906d4e Add tests for cme NULL crash
Tests for GitHub PR #5122. Originally in GitHub PR #5121.
2021-11-17 13:20:31 -05:00
Jeremy Evans
a5cff7cc5d Make Enumerable#each_cons return object if over size
This behavior changed in dfb47bbd17,
but only for normal exit, not for early exit.  Fix it for early
exit as well.

While here, fix example code in documentation so that it doesn't
indicate that the method returns nil.
2021-11-16 19:31:35 -08:00
Jeremy Evans
d1cbec9b52 Add a test for bug 18343
This already passes in master, 3.0, and 2.7, but would fail in
ruby 2.6 as it segfaults instead of raising an exception. I think
it's good to have a test for this to catch possible future
regressions.
2021-11-16 19:28:45 -08:00
Samuel Williams
5190926e40 Validate string type when constructing IO::Buffer for string mapping. 2021-11-17 10:39:54 +13:00
Jean Boussier
1af8ed5f0a Primitive.mandatory_only? consider splat args
`vm_ci_argc` gives the number of arguments, but `*[1, 2, 3]` only
counts for one.
2021-11-17 06:38:03 +09:00
Jean Boussier
a87c56f820 [ruby/date] check_limit: also handle symbols
376c65942b
2021-11-16 22:51:41 +09:00
Jean Boussier
fa674cf723 [ruby/date] Date._<format>(nil) should return an empty Hash
Fix: https://github.com/ruby/date/issues/39

This is how versions previous to 3.2.1 behaved and Active Support
currently rely on this behavior.

90357af080/activesupport/lib/active_support/values/time_zone.rb (L383-L384)

Any Rails application upgrading to date `3.2.1` might run into unexpected errors.

8f2d7a0c7e
2021-11-16 22:51:40 +09:00
Yusuke Endoh
489c8cebf5 [ruby/date] Add length limit option for methods that parses date strings
`Date.parse` now raises an ArgumentError when a given date string is
longer than 128. You can configure the limit by giving `limit` keyword
arguments like `Date.parse(str, limit: 1000)`. If you pass `limit: nil`,
the limit is disabled.

Not only `Date.parse` but also the following methods are changed.

* Date._parse
* Date.parse
* DateTime.parse
* Date._iso8601
* Date.iso8601
* DateTime.iso8601
* Date._rfc3339
* Date.rfc3339
* DateTime.rfc3339
* Date._xmlschema
* Date.xmlschema
* DateTime.xmlschema
* Date._rfc2822
* Date.rfc2822
* DateTime.rfc2822
* Date._rfc822
* Date.rfc822
* DateTime.rfc822
* Date._jisx0301
* Date.jisx0301
* DateTime.jisx0301

3959accef8
2021-11-16 20:56:56 +09:00
Nobuyoshi Nakada
dc5512243b [ruby/io-wait] Disable ractor test which is meaningless on earlier versions
e8e1e99d4c
2021-11-16 20:25:44 +09:00
Nobuyoshi Nakada
d305ae5f04 [ruby/io-wait] Use omit as per test-unit
1f59f7b02f
2021-11-16 20:25:41 +09:00