675 Commits
Author SHA1 Message Date
Luke Gruber 25eb737f03 eliminate cross-TU calls to rb_vm_empty_cc()
rb_vm_empty_cc(), rb_vm_empty_cc_for_super() and rb_vm_uncached_cc()
shouldn't be real function calls. rb_iseq_mark_and_move was calling
these as real functions in a loop.
2026-10-27 09:49:20 -04:00
Luke Gruber ae2c6841c4 Don't create CCs for methods we assume are cold
The assumption is that we're usually calling these methods on boot, and they don't
need CCs. CCs scale with the number of classes that use these methods in the app, so
if you have 10k classes and these classes use 3 of these methods on average, then that
saves 30k CC objects.

Methods on Module that are marked cold are:

public, protected, private, module_function, ruby2_keywords, alias_method, undef_method,
remove_method, attr_reader, attr_writer, attr_accessor, include, prepend.

If these methods ever get redefined, they get new method definitions that are not
marked uncacheable (CCs will get created).

In one of our apps (not the largest), we observed this difference after boot:

| method            | before | after | delta       |
|-------------------|-------:|------:|------------:|
| `include`         |   4518 |     2 |       -4516 |
| `alias_method`    |   3921 |     0 |       -3921 |
| `ruby2_keywords`  |   3784 |     0 |       -3784 |
| `private`         |   3519 |     3 |       -3516 |
| `attr_reader`     |   2738 |     0 |       -2738 |
| `attr_accessor`   |   2288 |     0 |       -2288 |
| `prepend`         |    354 |     1 |        -353 |
| `protected`       |    303 |     0 |        -303 |
| `public`          |    302 |     0 |        -302 |
| `undef_method`    |    178 |     0 |        -178 |
| `attr_writer`     |    124 |     0 |        -124 |
| `module_function` |     42 |     0 |         -42 |
| `remove_method`   |     24 |     0 |         -24 |
| **total**         |        |       | **-22,089** |

NOTE: CC tables and ccs (the malloced struct) are still being created, so this only reduces
the CC objects themselves. I will tackle that in a follow-up.
2026-10-27 09:49:20 -04:00
Kevin Newton 568ff20b0d [PRISM] Update to handle pm_string_t being just a view 2026-10-20 16:00:01 -04:00
Peter Zhu 054385feb1 Fix ifunc block handler leak from method_missing
[Bug #22436]

The check_funcall_exec function incorrectly restored the pending block
handler which causes it to leak.

For example, the following code crashes:

    o = Object.new
    def o.method_missing(*) = nil   # Array#zip calls o.each via method_missing

    out = Object.new
    def out.write(*) = nil
    def out.puts(*) = yield         # receives a block it was never given
    $stdout = out

    [1].zip(o)
    puts 1                          # Kernel#puts -> $stdout.puts gets a stale ifunc block
2026-10-15 12:44:59 +09:00
Benoit DalozeandClaude Opus 5 091399f637 Move prism_compile.h include out of iseq.h
iseq.h does not reference any of the pm_* types or functions declared in
prism_compile.h, so include the latter from the files that actually use
it instead. Only 6 of the 19 files including iseq.h need the prism
declarations, so this keeps prism/prism.h out of the include closure of
ast.c, box.c, builtin.c, cont.c, eval.c, jit.c, proc.c, thread.c,
vm_dump.c, vm_trace.c, yjit.c, zjit.c and internal/jit.h.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-14 16:20:26 +02:00
Hiroshi SHIBATAandClaude Opus 5 975c2a45f1 Use rb_len_t for Array and String lengths in the VM
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>
2026-10-09 14:00:15 +09:00
Earlopain f19c5dcd3f [Bug #22253] Fix UB in prism eval with numbered params
locals are just zero-allocated. This leaves their source NULL,
which may later be `memcpy`d

We don't have to care about numbered params because of https://github.com/ruby/prism/commit/a218a0f265a71aecefe43a1b646917ca37f25547

We don't have to care about invalid encodings because of https://github.com/ruby/ruby/commit/2bcb155b49bb421ee82c0d5980546a5071113407

Fixes https://bugs.ruby-lang.org/issues/22253
2026-10-04 17:34:38 -04:00
Peter Zhu c56fa9401b Don't record EP escape in JIT when not enabled
We shouldn't record JIT information before the JIT is actually enabled.

This change doesn't seem to affect ZJIT or YJIT performance beyond the
margin of error:

    ZJIT:

      --------------  ------------  ------------  --------------  -------------
      bench            master (ms)   branch (ms)  branch 1st itr  master/branch
      activerecord     50.1 ± 7.4%   49.0 ± 5.7%           0.948          1.022
      chunky-png      164.2 ± 2.1%  166.8 ± 2.8%           0.985          0.985
      erubi-rails     247.0 ± 2.8%  264.6 ± 2.2%           0.945          0.934
      hexapdf         571.3 ± 1.0%  565.4 ± 1.2%           0.959          1.010
      liquid-c        17.6 ± 13.1%  19.2 ± 12.9%           0.976          0.920
      liquid-compile  15.7 ± 11.0%   15.6 ± 7.5%           0.978          1.003
      liquid-il        79.8 ± 2.0%   78.2 ± 2.2%           0.993          1.021
      liquid-render    32.3 ± 6.8%   32.3 ± 6.3%           1.001          0.999
      lobsters        243.8 ± 4.9%  242.8 ± 4.7%           0.976          1.004
      mail             38.8 ± 3.1%   39.5 ± 5.1%           0.993          0.982
      psych-load      612.4 ± 1.5%  610.0 ± 1.9%           1.001          1.004
      railsbench      343.8 ± 2.9%  350.8 ± 2.2%           0.991          0.980
      rubocop         50.0 ± 10.6%  51.2 ± 12.0%           1.019          0.978
      ruby-lsp         42.9 ± 3.8%   43.2 ± 3.7%           0.974          0.993
      sequel           18.5 ± 6.6%   18.7 ± 6.6%           1.021          0.991
      shipit          344.3 ± 1.3%  339.8 ± 3.4%           0.981          1.013
      --------------  ------------  ------------  --------------  -------------

    YJIT:

      --------------  ------------  ------------  --------------  -------------
      bench            master (ms)   branch (ms)  branch 1st itr  master/branch
      activerecord     42.6 ± 7.7%   40.6 ± 5.5%           1.099          1.048
      chunky-png      164.7 ± 1.3%  164.8 ± 1.1%           1.060          0.999
      erubi-rails     256.7 ± 3.3%  241.3 ± 2.3%           1.035          1.064
      hexapdf         445.6 ± 1.0%  444.6 ± 1.0%           1.012          1.002
      liquid-c        16.4 ± 11.2%  16.7 ± 13.3%           1.037          0.986
      liquid-compile  14.5 ± 11.5%   14.3 ± 7.8%           0.990          1.011
      liquid-il        74.9 ± 2.6%   73.4 ± 3.6%           0.993          1.021
      liquid-render    23.1 ± 8.9%   23.3 ± 8.7%           1.001          0.992
      lobsters        239.9 ± 9.9%  238.7 ± 9.3%           0.989          1.005
      mail             29.2 ± 4.6%   30.0 ± 5.8%           0.977          0.973
      psych-load      515.5 ± 1.2%  511.5 ± 0.7%           0.973          1.008
      railsbench      317.4 ± 2.2%  317.9 ± 2.5%           1.008          0.998
      rubocop         42.1 ± 18.5%  42.0 ± 14.4%           1.052          1.004
      ruby-lsp         41.5 ± 3.8%   41.6 ± 3.8%           1.013          0.998
      sequel           18.5 ± 6.6%   18.2 ± 5.4%           1.150          1.018
      shipit          282.8 ± 3.8%  285.5 ± 5.2%           1.000          0.991
      --------------  ------------  ------------  --------------  -------------
2026-08-27 11:25:39 +09:00
Peter Zhu 05cb652056 Reduce memory for proc objects
We know the type of the proc object at allocation time, so we can allocate
exactly the amount of memory needed for that type.

We can also shrink the type from a 4 byte enum since there are only 4 types
of procs. This allows us to put some flags after it, which saves us 8 bytes.

This commit reduces symbol and proc procs by 24 bytes (80 bytes to 56 bytes).
It also reduces iseq and ifunc procs by 8 bytes (80 bytes to 72 bytes).
2026-08-24 09:13:41 +09:00
Shugo MaedaandClaude Opus 5 39e43e1c20 [Feature #22213] Allow no-argument and chained calls of Proc#refined
Since `prc.refined(*ms).refined(*ns)` is behaviorally equivalent to
`prc.refined(*ms, *ns)`, the copy of the block is deferred until
the first call and the memo is shared by these behaviorally
equivalent Procs.  A Proc that is never called is no longer copied
at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 16:57:31 +09:00
Hiroshi SHIBATA 23e969c789 [DOC] Use __LINE__ in the second Module#module_eval lineno example
The example passing lineno 10 evaluated __FILE__, which prints the
filename instead of 10.
2026-08-05 19:38:31 +09:00
Claude Fable 5 5dec40dc5f [DOC] Fix typos in C comments
- vm_eval.c: contant -> constant (RDoc for Module#module_eval;
  the sentence two lines above spells it correctly)
- include/ruby/internal/intern/thread.h: funciton -> function
- include/ruby/st.h, parser_st.h: Optionnally -> Optionally
2026-07-23 12:08:25 +09:00
Shugo MaedaandClaude Fable 5 79d4e720f8 Make locals read after longjmp volatile in more setjmp users
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>
2026-07-23 10:37:13 +09:00
Takashi Kokubun 156b4794e3 vm_eval.c: Preserve rb_iterate0 locals across longjmp
Clang 17 at -O1 with -fPIC can incorrectly rematerialize cfp after longjmp when a nearby stack layout changes, even though cfp is not modified in the tag region. This makes rb_iterate0 miss the matching escape frame and propagate TAG_BREAK as an unexpected break.

Copy the ec argument into a volatile local and make the saved cfp volatile so both values are reloaded from their pre-setjmp storage. This keeps the direct ZJIT fields added by #17953.

This is the rb_iterate0 portion of #17931.
2026-07-22 03:01:29 -04:00
Shugo MaedaandClaude Opus 4.8 cce7041630 [Feature #22097] Add Proc#refined
Add Proc#refined(mod, ...), which returns a new Proc that behaves like
the receiver but with the refinements activated by the given modules in
effect inside its body, without affecting the original Proc.  This is
an alternative to the previously proposed Proc#using
(https://bugs.ruby-lang.org/issues/16461) that does not modify the
existing block and needs no `using Proc::Refinements` declaration.

Refinements are resolved at run time through the cref, so a refined
proc gets two pieces of its own:

* A cref carrying the additional refinements, built by activating the
  modules (rb_using_module_recursive, under the VM lock) on a duplicate
  of the block's captured cref.  It is stored in a hidden ivar on the
  Proc and injected into the block frame on every proc-invocation path
  (Proc#call, yield from C methods, invokeblock/opt_call, and
  instance_eval/instance_exec/module_eval/class_eval via yield_under).
  The captured environment stays shared, so closure variables are still
  shared with the original Proc.  `using` inside the body is rejected
  (CREF_REFINED_PROC), so the cref's refinements never change after
  publication.

* A recursive deep copy of the block's instruction sequences
  (rb_iseq_dup_with_independent_caches) so the new Proc has its own
  inline method caches.  This is required for correctness: the VM
  caches refinement method resolution per call site assuming a single
  lexical cref per iseq, so sharing the iseq would leak the refined
  methods into the original Proc.  Coverage keeps measuring the copied
  iseq.

The copy and the cref are memoized in a hidden identity Hash keyed by
the source iseq (one slot per iseq, matched by the captured cref and
the module arguments, accessed under the VM lock), so repeated calls at
the same site reuse one copy and procs refined with the same modules
share the iseq and the cref.  A differing module set or a ruby2_keywords
flag mismatch rebuilds the entry (with a performance warning).  The
refinements table of the memoized cref is frozen and marked shareable so
the memo also serves other Ractors.

Procs without an iseq block (Symbol#to_proc, C-function procs), procs
created from methods, and procs that already have refinements are
rejected with ArgumentError.

The YJIT/ZJIT Rust bindings are regenerated for the new rb_proc_t field.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:21:01 +09:00
e0083cffa3 Refactor RObject to use T_IMEMO/fields_obj on overflow
Instead of spilling into a raw buffer, `RObject` now spills
into an `IMEMO/fields` object like other types.

From an instance variable layout standpoint, an extended `RObject`
is now identical to a `RTypedData`, as in they both store the
reference to their `IMEMO/fields` at the same offset (`VALUE * 2`).

One positive consequence of this is that the only case where a `T_OBJECT`
needs sweeping is if a finalizer was registered.

YJIT now side exit when it need to write a new ivar into a `RObject`
that is out of space. This is unlikely to cause a performance regression
as this codepath isn't supposed to happen after warmup given `max_iv_count`
is recorded on classes, so future objects should be large enough.
Hence it's best not to waste executable memory for such codepath.

ZJIT lost support for writting into extended `RObject`.
Most of the code to support it is there it's just missing an
implementation of `RBASIC_SET_SHAPE_ID`, which recently changed
to strip some bits out of the shape (see comments).
I will leave it to the ZJIT team to implement it (sorry).

There are a few future cleanups planned that I keep for followups:

  - We can now get rid of the `ROBJECT_HEAP` flag, it's redundant with
    the shape layout bits.
  - `imemo_fields` can now embed the `st_table` when complex.

Co-Authored-By: John Hawthorn <john@hawthorn.email>
Co-authored-by: Randy Stauner <randy@r4s6.net>
2026-07-14 10:44:39 +02:00
Peter Zhu c1f48f4a1b [DOC] Improve docs for Module#module_eval 2026-05-15 17:45:04 -04:00
Nobuyoshi Nakada 5d439f2991 mswin: Suppress quirky warning
Passing an array of const pointers within a struct as an argument
seems to be too complex for cl.exe:

```
vm_eval.c(501): warning C4090: 'function': different 'const' qualifiers
```
2026-05-04 11:50:34 +09:00
Jean Boussier 53099633e2 Make ruby_xfree_sized and ruby_xrealloc_sized public
[Feature #21861]
2026-04-01 08:10:07 +01:00
Takashi Kokubun ee60b99b2f Rename rb_cfp_iseq to CFP_ISEQ and rb_cfp_pc to CFP_PC
Rename for consistency with ISEQ_BODY naming convention. Remove the
separate rb_cfp_has_iseq/rb_cfp_has_pc wrappers — CFP_ISEQ and CFP_PC
return NULL for missing values, which works directly in if conditions.
2026-03-27 16:26:12 -07:00
Takashi Kokubun 226f37059e Rename cfp->iseq to cfp->_iseq and rb_zjit_cfp_iseq to rb_cfp_iseq
Per tenderlove's review, every cfp->iseq read should go through an
accessor that accounts for JITFrame. Rename the field to _iseq so
direct access causes a compile error, and rename the accessors to
drop the zjit prefix (rb_cfp_iseq, rb_cfp_has_iseq, rb_cfp_pc,
rb_cfp_has_pc).
2026-03-27 16:26:12 -07:00
Takashi KokubunandAlan Wu c8f97943ef ZJIT: Lightweight Frames
Co-authored-by: Alan Wu <alanwu@ruby-lang.org>
2026-03-27 16:26:12 -07:00
Kevin Newton e10f2521a2 [PRISM] Use a flat lookup table for locals instead of an st_table 2026-03-20 20:37:26 -04:00
Kevin Newton 78ab3a7ced Leverage new Prism APIs
Prism changed structure quite a bit. Most of the previously-public
structs are now opaque. This requires quite a bit of changes
internally.

It also triggered some unrelated changes, which were necessary
because Prism's main header used to pull in standard headers. So
box.c and jit.c are now no longer transitively getting all the
headers they needed.
2026-03-20 09:37:43 -04:00
Kevin Newton 84611ce5dc Update constant pool API calls 2026-03-17 11:14:11 -04:00
Jean Boussier 14eb083152 Speedup repeated calls to rb_gccct_clear_table
Profiling of `ruby --disable-all -e 1` shows between 5 and 10%
of the time is spent in `_platform_memset`, called from `rb_gccct_clear_table()`,
itself called from `clear_method_cache_by_id_in_class()`.

Which makes sense, during boot we define numerous methods, and after
each we have to invalidate the `gccct`, which is done by zeroing
1023 pointers, so roughtly 8kiB of memory.

By keeping track of whether the table was used since the last clear,
we can save a lot of useless memory writes.

This may also be beneficial when loading user defined code, as it's unlikely
the `gccct` would be dirtied between two `def`.

NB: profiling such a short lived process gives a lot of variance, but
with a very high sampling rate and multiple attempts, `clear_method_cache_by_id_in_class`
is always in the top 2 hotspots.
2026-03-16 20:53:49 +01:00
Kevin Newton 45250a4169 [PRISM] Use arena allocator for nodes 2026-03-05 11:49:50 -05:00
Earlopain 91be23cd96 [Bug #21868] Use ruby allocator for prism
If we wan't prism to use the ruby allocator, we should
include it as early as possible.
2026-02-18 09:19:56 +01:00
Jean Boussier 62da480632 vm_eval.c,vm_trace.c: Use ruby_sized_xfree 2026-02-01 15:32:28 +01:00
Jean Boussier 91619f0230 gc.c: Verify provided size in rb_gc_impl_free
For now the provided size is just for GC statistics, but in the future
we may want to forward it to C23's `free_sized` and passing an incorrect
size to it is undefined behavior.
2026-01-29 23:32:04 +01:00
Peter Zhu 887913efc0 [DOC] Improve docs for eval 2026-01-23 17:36:06 -05:00
Nobuyoshi Nakada 8c7b1401a5 Remove rb_iterate deprecated since 1.9 2025-12-26 17:53:23 +09:00
Jean Boussier ff831eb057 thead_sync.c: directly pass the execution context to yield
Saves one more call to GET_EC()
2025-12-12 10:08:05 +01:00
Nobuyoshi Nakada 7f41c3e7b1 Add rb_eval_cmd_call_kw to shortcut 2025-12-04 18:07:49 +09:00
Satoshi Tagomori d2a587c791 renaming internal data structures and functions from namespace to box 2025-11-07 13:14:54 +09:00
Alan Wu b6f00701cb [DOC] Mention on top of vm_*.c files the VM translation unit they're in (#15048)
vm_method.c already mentions it.
2025-11-04 17:46:00 +00:00
Andre Muta 244a37bd53 Fixes [Bug #21522] eval isolation in Ractors for Prism 2025-10-30 09:17:58 -04:00
Satoshi Tagomori cad692de63 Remove useless comments
Namespace frame exists, but it is used only for Namespace#eval now.
2025-10-14 22:59:14 +09:00
Takashi Kokubun 4f030951f2 ZJIT: Invalidate local variables on EP escape (#14448) 2025-09-05 11:26:01 -07:00
Jean Boussier fc5e1541e4 Use rb_gc_mark_weak for cc->klass.
One of the biggest remaining contention point is `RClass.cc_table`.
The logical solution would be to turn it into a managed object, so
we can use an RCU strategy, given it's read heavy.

However, that's not currently possible because the table can't
be freed before the owning class, given the class free function
MUST go over all the CC entries to invalidate them.

However if the `CC->klass` reference is weak marked, then the
GC will take care of setting the reference to `Qundef`.
2025-08-01 10:42:04 +02:00
Luke Gruber a02dcbfd46 Remove accidentally committed method Module.gccct_clear_table
This was probably meant to be only for debugging. It was introduced in
the big namespace on read commit: 382645d440
2025-07-11 10:15:08 +09:00
Nobuyoshi Nakada 2e3f81838c Align styles [ci skip] 2025-05-15 17:48:40 +09:00
Satoshi Tagomori 382645d440 namespace on read 2025-05-11 23:32:50 +09:00
Nobuyoshi Nakada 5dc155351a Do not allocate new objects at machine stack overflow 2025-04-24 17:28:18 +09:00
Nobuyoshi Nakada c218862d3c Fix style [ci skip] 2025-04-19 22:02:10 +09:00
Yusuke Endoh 993fd96ce6 reject numbered parameters from Binding#local_variables
Also, Binding#local_variable_get and #local_variable_set rejects an
access to numbered parameters.

[Bug #20965] [Bug #21049]
2025-02-18 16:23:24 +09:00
Kevin Newton cb419e3912 [PRISM] Handle forwarding inside eval
Fixes [Bug #21031]
2025-01-14 18:41:50 -05:00
Kevin NewtonandNobuyoshi Nakada 1a06bee027 Do not intern invalid symbols in eval parse
When the inner code cannot represent the name of the locals in the
outer code, do not bother putting them into the constant pool as
they will not be referenced.

Fixes [Bug #20992]

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2025-01-07 22:30:16 -05:00
Peter Zhu 5b22f14e53 GC guard the iseq in eval for prism
We need to GC guard the iseq because the code above it malloc memory which
could trigger a GC. Since we only use ISEQ_BODY, the compiler may optimize
out the iseq local variable so we need to GC guard it.

Fixes: http://ci.rvm.jp/results/trunk_asan@ruby-sp1/5484752
2024-12-23 16:44:30 -05:00
Peter Zhu e23a60b929 Fix GC compaction crash when using local variables in eval
If we have local variables outside of the eval, the local variables names
are IDs. We convert these IDs to char * using rb_id2name. However, these
char * are actually Ruby strings, which may be embedded. This means that
it is not safe to rb_id2name and call any potential GC entrypoints because
if a GC compaction runs, the embedded string may move and the pointer will
change.

For example, if you compile with `-DRGENGC_CHECK_MODE=1`, then the following
script will crash:

    GC.auto_compact = :empty
    GC.stress = true

    o = Object.new

    eval("def o.m(k: 0) k end")

The crash message is:

    test.rb:6: [BUG] Local with constant_id 1 does not exist
    ruby 3.4.0dev (2024-12-17T18:34:57Z prism-local-compac.. 434346726c) +PRISM [arm64-darwin24]

    -- C level backtrace information -------------------------------------------
    miniruby(rb_print_backtrace+0x24) [0x10312fec4] vm_dump.c:823
    miniruby(rb_print_backtrace) (null):0
    miniruby(rb_vm_bugreport+0x2d4) [0x1031301b8] vm_dump.c:1155
    miniruby(rb_bug_without_die_internal+0xa8) [0x102dd6a94] error.c:1097
    miniruby(rb_bug+0x28) [0x102dd6b00] error.c:1115
    miniruby(pm_lookup_local_index+0xec) [0x102d61e4c] prism_compile.c:1237
    miniruby(pm_compile_node+0x45d0) [0x102d252f4] prism_compile.c:9334
    miniruby(pm_compile_node+0x1864) [0x102d22588] prism_compile.c:8650
    miniruby(pm_compile_node+0x65ec) [0x102d27310] prism_compile.c:9897
    miniruby(pm_compile_scope_node+0x3008) [0x102d77bcc] prism_compile.c:6584
    miniruby(pm_compile_node+0x5ec4) [0x102d26be8] prism_compile.c:9768
    miniruby(pm_iseq_compile_node+0xac) [0x102d20bf0] prism_compile.c:10069
    miniruby(pm_iseq_new_with_opt_try+0x2c) [0x102e7d088] iseq.c:1029
    miniruby(rb_protect+0x108) [0x102dea9bc] eval.c:1033
    miniruby(pm_iseq_new_with_opt+0x264) [0x102e7c444] iseq.c:1082
    miniruby(pm_iseq_new_eval+0xec) [0x102e7c8e0] iseq.c:961
    miniruby(pm_eval_make_iseq+0x594) [0x1031209cc] vm_eval.c:1770
    miniruby(eval_make_iseq+0x54) [0x103120068] vm_eval.c:1799
2024-12-20 08:24:54 -05:00