Actions
Bug #12082
closedTail-calling method can't catch exception raised by tail-called method
Description
The following code doesn't work as expected, on all versions of Ruby with tail call optimization (1.9.1 to 2.3.0).
def do_raise
raise "should be rescued"
end
options = {
tailcall_optimization: true,
trace_instruction: false,
}
RubyVM::InstructionSequence.compile(<<EOF, __FILE__, __FILE__, __LINE__, options).eval
def test_rescue
return do_raise
1 + 2
rescue
:ok
end
EOF
p test_rescue # should print :ok, but raises "should be rescued"
Looks like nop
instruction is (also) used to avoid this optimization (compile.c), but when doing early return, no nop
is inserted.
I attached a (dirty) fix for this. Maybe there is a cleaner way.
Files
Updated by ko1 (Koichi Sasada) almost 9 years ago
- Assignee set to ko1 (Koichi Sasada)
Updated by rhenium (Kazuki Yamaguchi) almost 9 years ago
- File 0001-compile.c-don-t-do-tail-call-optimization-if-covered-v2.patch 0001-compile.c-don-t-do-tail-call-optimization-if-covered-v2.patch added
Updating my patch, because it breaks such code:
def errinfo
$!
end
RubyVM::InstructionSequence.compile(<<EOF, __FILE__, __FILE__, __LINE__, tailcall_optimization: true).eval
def test_rescue
raise "a"
rescue
errinfo
end
EOF
p test_rescue # should return a RuntimeError
Updated by ko1 (Koichi Sasada) over 8 years ago
Thank you for reporting and patches.
Nobu's patch seems good. Could you commit it?
Updated by nobu (Nobuyoshi Nakada) over 8 years ago
- Status changed from Open to Closed
Applied in changeset r54542.
compile.c: disable tco with rescue
- compile.c (iseq_optimize): disable tail call optimization in
rescued, rescue, and ensure blocks.
[ruby-core:73871] [Bug #12082]
Updated by usa (Usaku NAKAMURA) over 8 years ago
- Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: WONTFIX, 2.2: REQUIRED, 2.3: REQUIRED
Updated by usa (Usaku NAKAMURA) over 8 years ago
- Backport changed from 2.1: WONTFIX, 2.2: REQUIRED, 2.3: REQUIRED to 2.1: WONTFIX, 2.2: DONE, 2.3: REQUIRED
ruby_2_2 r54698 merged revision(s) 54542,54548.
Updated by nagachika (Tomoyuki Chikanaga) over 8 years ago
- Backport changed from 2.1: WONTFIX, 2.2: DONE, 2.3: REQUIRED to 2.1: WONTFIX, 2.2: DONE, 2.3: DONE
ruby_2_3 r54715 merged revision(s) 54141,54542,54548.
Actions
Like0
Like0Like0Like0Like0Like0Like0Like0Like0