[Bug #21313] Handle it
in rescue and ensure blocks.
The following is crashing for me: ```shell ruby --yjit --yjit-call-threshold=1 -e '1.tap { raise rescue p it }' ruby: YJIT has panicked. More info to follow... thread '<unnamed>' panicked at ./yjit/src/codegen.rs:2402:14: ... ``` It seems `it` sometimes points to the wrong value: ```shell ruby -e '1.tap { raise rescue p it }' false ruby -e '1.tap { begin; raise; ensure; p it; end } rescue nil' false ``` But only when `$!` is set: ```shell ruby -e '1.tap { begin; nil; ensure; p it; end }' 1 ruby -e '1.tap { begin; nil; rescue; ensure; p it; end }' 1 ruby -e '1.tap { begin; raise; rescue; ensure; p it; end }' 1 ```
This commit is contained in:
parent
097d742a1e
commit
4921845b61
Notes:
git
2025-05-16 15:17:35 +00:00
@ -9640,7 +9640,19 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||||||
// -> { it }
|
// -> { it }
|
||||||
// ^^
|
// ^^
|
||||||
if (!popped) {
|
if (!popped) {
|
||||||
PUSH_GETLOCAL(ret, location, scope_node->local_table_for_iseq_size, 0);
|
pm_scope_node_t *current_scope_node = scope_node;
|
||||||
|
int level = 0;
|
||||||
|
|
||||||
|
while (current_scope_node) {
|
||||||
|
if (current_scope_node->parameters && PM_NODE_TYPE_P(current_scope_node->parameters, PM_IT_PARAMETERS_NODE)) {
|
||||||
|
PUSH_GETLOCAL(ret, location, current_scope_node->local_table_for_iseq_size, level);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_scope_node = current_scope_node->previous;
|
||||||
|
level++;
|
||||||
|
}
|
||||||
|
rb_bug("Local `it` does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1946,6 +1946,14 @@ eom
|
|||||||
end
|
end
|
||||||
assert_valid_syntax('proc {def foo(_);end;it}')
|
assert_valid_syntax('proc {def foo(_);end;it}')
|
||||||
assert_syntax_error('p { [it **2] }', /unexpected \*\*/)
|
assert_syntax_error('p { [it **2] }', /unexpected \*\*/)
|
||||||
|
assert_equal(1, eval('1.then { raise rescue it }'))
|
||||||
|
assert_equal(2, eval('1.then { 2.then { raise rescue it } }'))
|
||||||
|
assert_equal(3, eval('3.then { begin; raise; rescue; it; end }'))
|
||||||
|
assert_equal(4, eval('4.tap { begin; raise ; rescue; raise rescue it; end; }'))
|
||||||
|
assert_equal(5, eval('a = 0; 5.then { begin; nil; ensure; a = it; end }; a'))
|
||||||
|
assert_equal(6, eval('a = 0; 6.then { begin; nil; rescue; ensure; a = it; end }; a'))
|
||||||
|
assert_equal(7, eval('a = 0; 7.then { begin; raise; ensure; a = it; end } rescue a'))
|
||||||
|
assert_equal(8, eval('a = 0; 8.then { begin; raise; rescue; ensure; a = it; end }; a'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_value_expr_in_condition
|
def test_value_expr_in_condition
|
||||||
|
Loading…
x
Reference in New Issue
Block a user