These still held String and Array lengths and indices in long, or cast them to long. rb_len_t is still long everywhere, so the generated code does not change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Argument counts stay `int` or `long`. The int range checks in proc.c and compile.c now depend on SIZEOF_VALUE so that they are kept once rb_len_t widens.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The pattern of allocating an empty hash with `rb_hash_new()` and
then appending to it is relatively wasteful, because every time
we go over the hash capacity, we'll have to `realloc`, rehash etc.
It may even get worse if https://github.com/ruby/ruby/pull/18345
lands, as right now an empty hash starts with a capacity of 8,
but it may very well start with a capacity of 2.
Hence in cases where the final hash size is easy to predict, we
should use `rb_hash_new_capa()`.
Audit of every EC_PUSH_TAG user, following the LLVM 19 longjmp
rematerialization bug worked around in rb_fiber_start: locals and
arguments that are read on the longjmp path but not modified inside
the tag region are made volatile. C99 7.13.2.1p3 guarantees such
unmodified locals, but LLVM 17 and 19 have been observed to
reconstruct their values incorrectly after a longjmp (cfp in
rb_iterate0, fiber in rb_fiber_start). volatile on a parameter may
not be effective (67d0f4821f,
https://bugs.ruby-lang.org/issues/19145), so arguments are copied
into volatile locals instead.
* vm_eval.c (rb_iterate0): cfp is compared against the escaping
frame after a longjmp; clang 17 at -O1 with -fPIC was observed to
clobber it during the development of the ifunc invalidation for
https://bugs.ruby-lang.org/issues/22019. ec is read next to it to
rewind the frame and to rethrow.
* eval_error.c (rb_ec_error_print_detailed0): opt and highlight are
read on the path reached by a longjmp from rb_get_backtrace while
the other locals of the function are already volatile.
* scheduler.c (rb_fiber_scheduler_unblock, fiber_interrupt): ec and
saved_interrupt_mask are read after a longjmp to restore
ec->interrupt_mask; cfp next to them was already volatile.
* eval.c (rb_vrescue2): r_proc and data2 are used when the raise is
handled. args is left as is; a va_list cannot portably be
volatile-qualified and is memory-backed in practice.
* eval.c (rb_protect): pstate is written through after the tag is
popped.
* eval.c (rb_ec_ensure): ec, e_proc and data2 run the ensure proc
after a longjmp; a clobbered e_proc would miscall it.
* vm_eval.c (vm_catch_protect): stateptr is written through after
the pop. tag has its address taken and stays in memory.
* vm_trace.c (exec_hooks_protected): ec and list are passed to
exec_hooks_postcheck after the pop.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Keep exceptions raised by `EXIT` traps until `END` handlers finish.
That leaves them available for reporting during cleanup.
Print `END` handler exceptions without replaying causes already
reported from earlier exit handlers. This keeps the previous handler
exception visible while avoiding duplicate diagnostics.
Before this commit, the test fails with RGENGC_CHECK_MODE enabled:
TestException#test_detailed_message_under_gc_compact_stress [test/ruby/test_exception.rb:1466]:
<"\e[1mfoo (\e[1;4mRuntimeError\e[m\e[1m)\e[m\n" +
"\e[1mbar\e[m\n" +
"\e[1mbaz\e[m"> expected but was
<"\e[1mfoo (\e[1;4mRuntimeError\e[m\e[1m)\e[m\n" +
"\e[1m\x00\x00\x00\x00\x00\x00\x00\e[m">.
Also, the default error printer and Exception#full_message use the
method instead of `Exception#message` to get the message string.
`Exception#detailed_message` calls `Exception#message`, decorates and
returns the result. It adds some escape sequences to highlight, and the
class name of the exception to the end of the first line of the message.
[Feature #18370]
Now, the order is good, old-fashioned style:
```
$ ./local/bin/ruby -e 'def foo; raise; end
def bar; foo; end
def baz; bar; end
def qux; baz; end
qux
'
-e:1:in `foo': unhandled exception
from -e:2:in `bar'
from -e:3:in `baz'
from -e:4:in `qux'
from -e:5:in `<main>'
```
If `emesg` is `Qundef`, it is not a message string and then `elen`
(the length of the message) is 0. So `emesg` cannot be `Qundef` in
the `elen != 0` block. Pointed out by Coverity Scan.
* eval_error.c (print_errinfo): defer escaping control char in
error messages until writing to stderr, instead of quoting at
building the message. [ruby-core:90853] [Bug #15497]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66753 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
By definition, the logarithm of 0 is negative infinity. This is a
pole error (cf: cf: ISO/IEC 9899:1999 section 7.12.1 paragraph 3) and
of course, cannot fit into an `int` value. We have to resort to
INT_MIN.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65743 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Print `cause` of the exception if the exception is not caught and printed
its backtraces and error message [Feature #8257]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65393 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The former states explicitly that the argument must be a literal,
and can optimize away `strlen` on all compilers.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65059 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* eval_error.c (print_errinfo): reset all attributes for each
lines before newlines.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62737 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* eval_error.c (print_errinfo): do not print an empty line at the
end when the message ends with a newline.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62736 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* eval_error.c (print_errinfo): reset in each line, so that
Exception#full_message ends with a newline and puts will not
print an extra newline.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61650 b2dd03c8-39d4-4d8f-98ff-823fe69b080e