Actions
Bug #12082
closedTail-calling method can't catch exception raised by tail-called method
Bug #12082:
Tail-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) about 10 years ago
- Assignee set to ko1 (Koichi Sasada)
Updated by rhenium (Kazuki Yamaguchi) almost 10 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) almost 10 years ago
Thank you for reporting and patches.
Nobu's patch seems good. Could you commit it?
Updated by nobu (Nobuyoshi Nakada) almost 10 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) almost 10 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) almost 10 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) almost 10 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