Now ISeq#to_a includes the node_id list for each bytecode instruction.
I want a way to retrieve the AST::Node instance corresponding to an
instruction for a research purpose including TypeProf-based LSP server.
This fixes an error when output is redirected:
```
$ run_ruby -rreline -e '$stderr.puts Reline::Unicode.calculate_width("\u221a").inspect' </dev/null >/dev/null
/home/jeremy/tmp/ruby/lib/reline/ansi.rb:189:in `raw': Operation not supported by device (Errno::ENODEV)
```
The @@encoding -> defined?(@@encoding) changes is necessary because
without that part of the commit, the following error would be raised
by the above command:
```
/home/jeremy/tmp/reline/lib/reline/general_io.rb:10:in `encoding': uninitialized class variable @@encoding in Reline::GeneralIO (NameError)
```
Problem reported and initial patch for Windows provided by
Richard Sharman.
I tested this only on OpenBSD, but hopefully it works for other
operating systems.
Fixes [Bug #17493]
https://github.com/ruby/reline/commit/c001971bb3
This change ensures we use `Reline::IOGate`'s `encoding` when converting
characters from their integer values.
This fixes an issue that may occur if you have UTF characters in your
`.inputrc`, but your default encoding isn't set.
For example:
```
> 127864.ord.chr
RangeError: 127864 out of char range
from (pry):1:in `chr'
> Reline::IOGate.encoding
=> #<Encoding:UTF-8>
> 127864.ord.chr(Reline::IOGate.encoding)
=> "🍸"
```
https://github.com/ruby/reline/commit/cf372fc0fc
"code" here is too ambiguous. TracePoint events only occur if there
is a new statement or expression on that line, not if the line
is a continuation of a previous statement or expression and there
is no new statement or expression on the line.
For example:
```
[
foo, # start of expression, line event
bar # continuation of expression, no line event
]
[
foo, # start of expression, line event
(bar) # new expression, line event
]
foo( # start of expression, line event
bar # continuation of expression, no line event
)
foo( # start of expression, line event
(bar) # new expression, line event
)
```
Fixes [Bug #15634]
Redo of 34a2acdac788602c14bf05fb616215187badd504 and
931138b00696419945dc03e10f033b1f53cd50f3 which were reverted.
GitHub PR #4340.
This change implements a cache for class variables. Previously there was
no cache for cvars. Cvar access is slow due to needing to travel all the
way up th ancestor tree before returning the cvar value. The deeper the
ancestor tree the slower cvar access will be.
The benefits of the cache are more visible with a higher number of
included modules due to the way Ruby looks up class variables. The
benchmark here includes 26 modules and shows with the cache, this branch
is 6.5x faster when accessing class variables.
```
compare-ruby: ruby 3.1.0dev (2021-03-15T06:22:34Z master 9e5105c) [x86_64-darwin19]
built-ruby: ruby 3.1.0dev (2021-03-15T12:12:44Z add-cache-for-clas.. c6be009) [x86_64-darwin19]
| |compare-ruby|built-ruby|
|:--------|-----------:|---------:|
|vm_cvar | 5.681M| 36.980M|
| | -| 6.51x|
```
Benchmark.ips calling `ActiveRecord::Base.logger` from within a Rails
application. ActiveRecord::Base.logger has 71 ancestors. The more
ancestors a tree has, the more clear the speed increase. IE if Base had
only one ancestor we'd see no improvement. This benchmark is run on a
vanilla Rails application.
Benchmark code:
```ruby
require "benchmark/ips"
require_relative "config/environment"
Benchmark.ips do |x|
x.report "logger" do
ActiveRecord::Base.logger
end
end
```
Ruby 3.0 master / Rails 6.1:
```
Warming up --------------------------------------
logger 155.251k i/100ms
Calculating -------------------------------------
```
Ruby 3.0 with cvar cache / Rails 6.1:
```
Warming up --------------------------------------
logger 1.546M i/100ms
Calculating -------------------------------------
logger 14.857M (± 4.8%) i/s - 74.198M in 5.006202s
```
Lastly we ran a benchmark to demonstate the difference between master
and our cache when the number of modules increases. This benchmark
measures 1 ancestor, 30 ancestors, and 100 ancestors.
Ruby 3.0 master:
```
Warming up --------------------------------------
1 module 1.231M i/100ms
30 modules 432.020k i/100ms
100 modules 145.399k i/100ms
Calculating -------------------------------------
1 module 12.210M (± 2.1%) i/s - 61.553M in 5.043400s
30 modules 4.354M (± 2.7%) i/s - 22.033M in 5.063839s
100 modules 1.434M (± 2.9%) i/s - 7.270M in 5.072531s
Comparison:
1 module: 12209958.3 i/s
30 modules: 4354217.8 i/s - 2.80x (± 0.00) slower
100 modules: 1434447.3 i/s - 8.51x (± 0.00) slower
```
Ruby 3.0 with cvar cache:
```
Warming up --------------------------------------
1 module 1.641M i/100ms
30 modules 1.655M i/100ms
100 modules 1.620M i/100ms
Calculating -------------------------------------
1 module 16.279M (± 3.8%) i/s - 82.038M in 5.046923s
30 modules 15.891M (± 3.9%) i/s - 79.459M in 5.007958s
100 modules 16.087M (± 3.6%) i/s - 81.005M in 5.041931s
Comparison:
1 module: 16279458.0 i/s
100 modules: 16087484.6 i/s - same-ish: difference falls within error
30 modules: 15891406.2 i/s - same-ish: difference falls within error
```
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
I'm not sure that this is section is complete (may be missing
requirements), or accurate (minimum automake or bison versions
may not be correct). However, I think it's useful, and we can
adjust it in the future to add requirements or adjust
requirement versions.
Fixes [Bug #14409]
RubyVM::AST.of(Thread::Backtrace::Location) returns a node that
corresponds to the location. Typically, the node is a method call, but
not always.
This change also includes iseq's dump/load support of node_ids for each
instructions.
Previously Backtrace::Location had two possible states:
LOCATION_TYPE_ISEQ and LOCATION_TYPE_ISEQ_CALCED. The former had the
location information as PC, and the latter had it as lineno.
Once lineno was caluculated, the state was changed to
LOCATION_TYPE_ISEQ_CALCED and the caluculated result was kept.
This change removes LOCATION_TYPE_ISEQ_CALCED, so lineno is calculated
whenever it is needed. It will be slow a little, but lineno is typically
needed only when its backtrace is shown, so I believe that it does not
matter.
This is a preparation to add column information to Backtrace::Location
because PC is needed to caluculate node_id for AST::Node even after
lineno is calculated. This change is approved by ko1.
by merging `rb_ast_body_t#line_count` and `#script_lines`.
Fortunately `line_count == RARRAY_LEN(script_lines)` was always
satisfied. When script_lines is saved, it has an array of lines, and
when not saved, it has a Fixnum that represents the old line_count.
This option makes the parser keep the original source as an array of
the original code lines. This feature exploits the mechanism of
`SCRIPT_LINES__` but records only the specified code that is passed to
RubyVM::AST.of or .parse, instead of recording all parsed program texts.
heap_set_increment essentially only calls heap_allocatable_pages_set.
They only differ in behaviour when `additional_pages == 0`. However,
this is only possible because heap_extend_pages may return 0. This
commit also changes heap_extend_pages to always return at least 1.
In ruby/ruby test actions, number of "leaked tempfile" messages
are shown on Windows.
As Windows disallows removing open files, `Tempfile#unlink` fails
silently before `#close`.
Close then unlink by `#close!` instead.
https://github.com/rubygems/rubygems/commit/fe0b88ac30
Tabs were expanded because the file did not have any tab indentation in unedited lines.
Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook.
Currently this has a fairly minor effect as strings are not used heavily
inside the builtins (outside of warnings, requires, and errors).
Hopefully this allows us to use strings in the future where appropriate.