Project

General

Profile

Actions

Bug #12082

closed

Tail-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

Added by rhenium (Kazuki Yamaguchi) over 9 years ago. Updated over 9 years ago.

Status:
Closed
Target version:
-
[ruby-core:73871]

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) over 9 years ago Actions #1 [ruby-core:73873]

  • Assignee set to ko1 (Koichi Sasada)

Updated by rhenium (Kazuki Yamaguchi) over 9 years ago Actions #2 [ruby-core:74240]

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 9 years ago Actions #4 [ruby-core:74874]

Thank you for reporting and patches.

Nobu's patch seems good. Could you commit it?

Updated by nobu (Nobuyoshi Nakada) over 9 years ago Actions #5

  • 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 9 years ago Actions #6 [ruby-core:75103]

  • 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 9 years ago Actions #7 [ruby-core:75120]

  • 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 9 years ago Actions #8 [ruby-core:75142]

  • 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

Also available in: PDF Atom