diff options
| author | Alan Wu <XrXr@users.noreply.github.com> | 2025-11-18 17:46:52 -0500 |
|---|---|---|
| committer | Alan Wu <XrXr@users.noreply.github.com> | 2025-11-19 18:14:01 -0500 |
| commit | 2cd792a1cfefeaee948b321bbc14cb86acc2d456 (patch) | |
| tree | 3f07444d0526b4d4463e6c1af5ffa378614e2525 | |
| parent | 4107a41020003d7106883b78891560e05d299310 (diff) | |
ZJIT: Fix assertion failure when profiling VM_BLOCK_HANDLER_NONE
As can be seen in vm_block_handler_verify(), VM_BLOCK_HANDLER_NONE is
not a valid argument for vm_block_handler(). Store nil in the profiler
when seen instead of crashing.
| -rw-r--r-- | vm_insnhelper.c | 3 | ||||
| -rw-r--r-- | zjit/src/profile.rs | 14 |
2 files changed, 17 insertions, 0 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 8495ee59ef..7626d46135 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -6041,11 +6041,14 @@ vm_define_method(const rb_execution_context_t *ec, VALUE obj, ID id, VALUE iseqv } // Return the untagged block handler: +// * If it's VM_BLOCK_HANDLER_NONE, return nil // * If it's an ISEQ or an IFUNC, fetch it from its rb_captured_block // * If it's a PROC or SYMBOL, return it as is static VALUE rb_vm_untag_block_handler(VALUE block_handler) { + if (VM_BLOCK_HANDLER_NONE == block_handler) return Qnil; + switch (vm_block_handler_type(block_handler)) { case block_handler_type_iseq: case block_handler_type_ifunc: { diff --git a/zjit/src/profile.rs b/zjit/src/profile.rs index 47bae3ac63..8c8190609d 100644 --- a/zjit/src/profile.rs +++ b/zjit/src/profile.rs @@ -361,3 +361,17 @@ impl IseqProfile { } } } + +#[cfg(test)] +mod tests { + use crate::cruby::*; + + #[test] + fn can_profile_block_handler() { + with_rubyvm(|| eval(" + def foo = yield + foo rescue 0 + foo rescue 0 + ")); + } +} |
