Skip to content

Commit 4921845

Browse files
nicholasdowerXrXr
authored andcommitted
[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 ```
1 parent 097d742 commit 4921845

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

prism_compile.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9640,7 +9640,19 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
96409640
// -> { it }
96419641
// ^^
96429642
if (!popped) {
9643-
PUSH_GETLOCAL(ret, location, scope_node->local_table_for_iseq_size, 0);
9643+
pm_scope_node_t *current_scope_node = scope_node;
9644+
int level = 0;
9645+
9646+
while (current_scope_node) {
9647+
if (current_scope_node->parameters && PM_NODE_TYPE_P(current_scope_node->parameters, PM_IT_PARAMETERS_NODE)) {
9648+
PUSH_GETLOCAL(ret, location, current_scope_node->local_table_for_iseq_size, level);
9649+
return;
9650+
}
9651+
9652+
current_scope_node = current_scope_node->previous;
9653+
level++;
9654+
}
9655+
rb_bug("Local `it` does not exist");
96449656
}
96459657

96469658
return;

test/ruby/test_syntax.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,6 +1946,14 @@ def test_it
19461946
end
19471947
assert_valid_syntax('proc {def foo(_);end;it}')
19481948
assert_syntax_error('p { [it **2] }', /unexpected \*\*/)
1949+
assert_equal(1, eval('1.then { raise rescue it }'))
1950+
assert_equal(2, eval('1.then { 2.then { raise rescue it } }'))
1951+
assert_equal(3, eval('3.then { begin; raise; rescue; it; end }'))
1952+
assert_equal(4, eval('4.tap { begin; raise ; rescue; raise rescue it; end; }'))
1953+
assert_equal(5, eval('a = 0; 5.then { begin; nil; ensure; a = it; end }; a'))
1954+
assert_equal(6, eval('a = 0; 6.then { begin; nil; rescue; ensure; a = it; end }; a'))
1955+
assert_equal(7, eval('a = 0; 7.then { begin; raise; ensure; a = it; end } rescue a'))
1956+
assert_equal(8, eval('a = 0; 8.then { begin; raise; rescue; ensure; a = it; end }; a'))
19491957
end
19501958

19511959
def test_value_expr_in_condition

0 commit comments

Comments
 (0)