Skip to content

Commit d129669

Browse files
committed
YJIT: Check VM_ENV_NAMESPACED_P in gen_block_given
1 parent b06465c commit d129669

1 file changed

Lines changed: 15 additions & 5 deletions

File tree

yjit/src/codegen.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6647,6 +6647,7 @@ fn jit_rb_f_block_given_p(
66476647
true
66486648
}
66496649

6650+
/// Codegen for `block_given?` and `defined?(yield)`
66506651
fn 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

Comments
 (0)