ZJIT: Add TODOs and omitted test for nested scope local access

This commit is contained in:
Alan Wu 2025-06-26 22:11:35 +09:00
parent b125fb56c9
commit 8e75a36129
2 changed files with 36 additions and 8 deletions

View file

@ -81,6 +81,28 @@ class TestZJIT < Test::Unit::TestCase
}, call_threshold: 3, insns: [:getlocal, :setlocal, :getlocal_WC_0, :setlocal_WC_1] }, call_threshold: 3, insns: [:getlocal, :setlocal, :getlocal_WC_0, :setlocal_WC_1]
end end
def test_read_local_written_by_children_iseqs
omit "This test fails right now because Send doesn't compile."
assert_compiles '[1, 2]', %q{
def test
l1 = nil
l2 = nil
tap do |_|
l1 = 1
tap do |_|
l2 = 2
end
end
[l1, l2]
end
test
test
}, call_threshold: 2
end
def test_send_without_block def test_send_without_block
assert_compiles '[1, 2, 3]', %q{ assert_compiles '[1, 2, 3]', %q{
def foo = 1 def foo = 1

View file

@ -2543,11 +2543,17 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
break; // Don't enqueue the next block as a successor break; // Don't enqueue the next block as a successor
} }
YARVINSN_getlocal_WC_0 => { YARVINSN_getlocal_WC_0 => {
// TODO(alan): This implementation doesn't read from EP, so will miss writes
// from nested ISeqs. This will need to be amended when we add codegen for
// Send.
let ep_offset = get_arg(pc, 0).as_u32(); let ep_offset = get_arg(pc, 0).as_u32();
let val = state.getlocal(ep_offset); let val = state.getlocal(ep_offset);
state.stack_push(val); state.stack_push(val);
} }
YARVINSN_setlocal_WC_0 => { YARVINSN_setlocal_WC_0 => {
// TODO(alan): This implementation doesn't write to EP, where nested scopes
// read, so they'll miss these writes. This will need to be amended when we
// add codegen for Send.
let ep_offset = get_arg(pc, 0).as_u32(); let ep_offset = get_arg(pc, 0).as_u32();
let val = state.stack_pop()?; let val = state.stack_pop()?;
state.setlocal(ep_offset, val); state.setlocal(ep_offset, val);
@ -3527,16 +3533,16 @@ mod tests {
expect![[r#" expect![[r#"
fn block (3 levels) in <compiled>: fn block (3 levels) in <compiled>:
bb0(v0:BasicObject): bb0(v0:BasicObject):
v2:BasicObject = GetLocal l2, 4 v2:BasicObject = GetLocal l2, EP@4
SetLocal l1, 3, v2 SetLocal l1, EP@3, v2
v4:BasicObject = GetLocal l1, 3 v4:BasicObject = GetLocal l1, EP@3
v5:BasicObject = GetLocal l2, 4 v5:BasicObject = GetLocal l2, EP@4
v7:BasicObject = SendWithoutBlock v4, :+, v5 v7:BasicObject = SendWithoutBlock v4, :+, v5
SetLocal l2, 4, v7 SetLocal l2, EP@4, v7
v9:BasicObject = GetLocal l2, 4 v9:BasicObject = GetLocal l2, EP@4
v10:BasicObject = GetLocal l3, 5 v10:BasicObject = GetLocal l3, EP@5
v12:BasicObject = SendWithoutBlock v9, :+, v10 v12:BasicObject = SendWithoutBlock v9, :+, v10
SetLocal l3, 5, v12 SetLocal l3, EP@5, v12
Return v12 Return v12
"#]] "#]]
); );