diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index e4283b786f1bd9..91d3aff5324b3f 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -6949,7 +6949,7 @@ fn gen_send_cfunc( return None; } - let block_arg_type = if block_arg { + let mut block_arg_type = if block_arg { Some(asm.ctx.get_opnd_type(StackOpnd(0))) } else { None @@ -6957,33 +6957,25 @@ fn gen_send_cfunc( match block_arg_type { Some(Type::Nil | Type::BlockParamProxy) => { - // We'll handle this later - } - None => { - // Nothing to do - } - _ => { - gen_counter_incr(jit, asm, Counter::send_cfunc_block_arg); - return None; - } - } - - match block_arg_type { - Some(Type::Nil) => { - // We have a nil block arg, so let's pop it off the args + // We don't need the actual stack value for these asm.stack_pop(1); } - Some(Type::BlockParamProxy) => { - // We don't need the actual stack value + Some(Type::Unknown | Type::UnknownImm) if jit.peek_at_stack(&asm.ctx, 0).nil_p() => { + // The sample blockarg is nil, so speculate that's the case. + asm.cmp(asm.stack_opnd(0), Qnil.into()); + asm.jne(Target::side_exit(Counter::guard_send_cfunc_block_not_nil)); + block_arg_type = Some(Type::Nil); asm.stack_pop(1); } None => { // Nothing to do } _ => { - assert!(false); + gen_counter_incr(jit, asm, Counter::send_cfunc_block_arg); + return None; } } + let block_arg_type = block_arg_type; // drop `mut` // Pop the empty kw_splat hash if kw_splat { diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs index 56ecfc5bc16506..3a3965577be125 100644 --- a/yjit/src/stats.rs +++ b/yjit/src/stats.rs @@ -470,6 +470,7 @@ make_counters! { guard_send_str_aref_not_fixnum, guard_send_cfunc_bad_splat_vargs, + guard_send_cfunc_block_not_nil, guard_invokesuper_me_changed,