Skip to content

Commit c784bfc

Browse files
committed
ZJIT: Treat getblockparam as a write in locals_written_in_block
1 parent b82975b commit c784bfc

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

zjit/src/hir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6271,7 +6271,7 @@ fn locals_written_in_block(parent_iseq: IseqPtr, blockiseq: IseqPtr, target_dept
62716271
let opcode = unsafe { rb_vm_insn_decode(*pc) } as u32;
62726272

62736273
match opcode {
6274-
YARVINSN_setlocal | YARVINSN_setblockparam
6274+
YARVINSN_setlocal | YARVINSN_setblockparam | YARVINSN_getblockparam
62756275
if get_arg(pc, 1).as_u32() == target_depth =>
62766276
{
62776277
let ep_offset = get_arg(pc, 0).as_u32();

zjit/src/hir/tests.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4340,6 +4340,46 @@ pub mod hir_build_tests {
43404340
Return v34
43414341
");
43424342
}
4343+
4344+
#[test]
4345+
fn reload_block_param_read_in_nested_block() {
4346+
// getblockparam writes to the local slot (materializes the Proc),
4347+
// so reading &block in a nested block is effectively a write
4348+
// that locals_written_in_block must detect.
4349+
eval(r#"
4350+
def test(&block)
4351+
tap { block }
4352+
block
4353+
end
4354+
"#);
4355+
assert_contains_opcode("test", YARVINSN_send);
4356+
assert_snapshot!(hir_string("test"), @r"
4357+
fn test@<compiled>:3:
4358+
bb0():
4359+
EntryPoint interpreter
4360+
v1:BasicObject = LoadSelf
4361+
v2:BasicObject = GetLocal :block, l0, SP@4
4362+
Jump bb2(v1, v2)
4363+
bb1(v5:BasicObject, v6:BasicObject):
4364+
EntryPoint JIT(0)
4365+
Jump bb2(v5, v6)
4366+
bb2(v8:BasicObject, v9:BasicObject):
4367+
v14:BasicObject = Send v8, 0x1000, :tap # SendFallbackReason: Uncategorized(send)
4368+
v15:BasicObject = GetLocal :block, l0, EP@3
4369+
v19:CBool = IsBlockParamModified l0
4370+
IfTrue v19, bb3(v8, v15)
4371+
Jump bb4(v8, v15)
4372+
bb3(v20:BasicObject, v21:BasicObject):
4373+
v28:BasicObject = GetLocal :block, l0, EP@3
4374+
Jump bb5(v20, v28, v28)
4375+
bb4(v23:BasicObject, v24:BasicObject):
4376+
v30:BasicObject = GetBlockParam :block, l0, EP@3
4377+
Jump bb5(v23, v30, v30)
4378+
bb5(v32:BasicObject, v33:BasicObject, v34:BasicObject):
4379+
CheckInterrupts
4380+
Return v34
4381+
");
4382+
}
43434383
}
43444384

43454385
/// Test successor and predecessor set computations.

0 commit comments

Comments
 (0)