summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2025-11-18 17:46:52 -0500
committerAlan Wu <XrXr@users.noreply.github.com>2025-11-19 18:14:01 -0500
commit2cd792a1cfefeaee948b321bbc14cb86acc2d456 (patch)
tree3f07444d0526b4d4463e6c1af5ffa378614e2525
parent4107a41020003d7106883b78891560e05d299310 (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.c3
-rw-r--r--zjit/src/profile.rs14
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
+ "));
+ }
+}