@@ -6647,6 +6647,7 @@ fn jit_rb_f_block_given_p(
66476647 true
66486648}
66496649
6650+ /// Codegen for `block_given?` and `defined?(yield)`
66506651fn gen_block_given (
66516652 jit : & mut JITState ,
66526653 asm : & mut Assembler ,
@@ -6656,15 +6657,24 @@ fn gen_block_given(
66566657) {
66576658 asm_comment ! ( asm, "block_given?" ) ;
66586659
6659- // Same as rb_vm_frame_block_handler
6660+ // VM_ENV_FLAGS(ep, VM_FRAME_MAGIC_MASK)
66606661 let ep_opnd = gen_get_lep ( jit, asm) ;
6661- let block_handler = asm. load (
6662- Opnd :: mem ( 64 , ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL )
6663- ) ;
6662+ let flags = Opnd :: mem ( 64 , ep_opnd, VM_ENV_DATA_INDEX_FLAGS as i32 * SIZEOF_VALUE_I32 ) ;
6663+ let frame_type = asm. and ( flags, VM_FRAME_MAGIC_MASK . into ( ) ) ;
6664+
6665+ // Return false_opnd if VM_ENV_NAMESPACED_P(ep)
6666+ asm. cmp ( frame_type, VM_FRAME_MAGIC_CLASS . into ( ) ) ;
6667+ let block_given = asm. csel_ne ( true_opnd, false_opnd) ;
6668+ asm. cmp ( frame_type, VM_FRAME_MAGIC_TOP . into ( ) ) ;
6669+ let block_given = asm. csel_ne ( block_given, false_opnd) ;
6670+
6671+ // VM_ENV_BLOCK_HANDLER(VM_CF_LEP(cfp))
6672+ let ep_opnd = gen_get_lep ( jit, asm) ; // Reload ep_opnd to avoid register spill
6673+ let block_handler = Opnd :: mem ( 64 , ep_opnd, VM_ENV_DATA_INDEX_SPECVAL * SIZEOF_VALUE_I32 ) ;
66646674
66656675 // Return `block_handler != VM_BLOCK_HANDLER_NONE`
66666676 asm. cmp ( block_handler, VM_BLOCK_HANDLER_NONE . into ( ) ) ;
6667- let block_given = asm. csel_ne ( true_opnd , false_opnd) ;
6677+ let block_given = asm. csel_ne ( block_given , false_opnd) ;
66686678 asm. mov ( out_opnd, block_given) ;
66696679}
66706680
0 commit comments