diff options
| author | Alan Wu <XrXr@users.noreply.github.com> | 2025-08-13 12:39:06 -0400 |
|---|---|---|
| committer | Alan Wu <XrXr@users.noreply.github.com> | 2025-08-14 17:01:11 -0400 |
| commit | 38558dd95e6443a8412304718ad77a331c185f5d (patch) | |
| tree | faa5367e63f0862ab88c801e3cd2ffaa7ed9f289 /test/ruby/test_method_cache.rb | |
| parent | b080fcd3cd14aa79e8f116962e5fa6826e9b5026 (diff) | |
YJIT: Fix `defined?(yield)` and `block_given?` at top level
Previously, YJIT returned truthy for the block given query at the top
level. That's incorrect because the top level script never receives a
block, and `yield` is a syntax error there.
Inside methods, the number of hops to get from `iseq` to
`iseq->body->local_iseq` is the same as the number of
`VM_ENV_PREV_EP(ep)` hops to get to an environment with
`VM_ENV_FLAG_LOCAL`. YJIT and the interpreter both rely on this as can
be seen in get_lvar_level(). However, this identity does not hold for
the top level frame because of vm_set_eval_stack(), which sets up
`TOPLEVEL_BINDING`.
Since only methods can take a block that `yield` goes to, have ISEQs
that are the child of a non-method ISEQ return falsy for the block given
query. This fixes the issue for the top level script and is an
optimization for non-method contexts such as inside `ISEQ_TYPE_CLASS`.
Diffstat (limited to 'test/ruby/test_method_cache.rb')
0 files changed, 0 insertions, 0 deletions
