Project

General

Profile

Bug #12905

tailcall_optimization not working as expected under certain condition order

Added by sunkai612 (Kai Sun) over 4 years ago. Updated over 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:78015]

Description

Below code gets stack too deep error:

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

def run_forever(current, final)
  if current < final
    run_forever(current+1, final)
  else
    nil
  end
end

run_forever(1, Float::INFINITY)

However, below code works as expected:

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

def run_forever(current, final)
  if current >= final
    nil
  else
    run_forever(current+1, final)
  end
end

run_forever(1, Float::INFINITY)

Thanks for looking at this :)

Updated by shugo (Shugo Maeda) over 4 years ago

  • Status changed from Open to Rejected

Kai Sun wrote:

Below code gets stack too deep error:

RubyVM::InstructionSequence.compile_option must be set before
compilation of the target program, so you need eval, load, etc.

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

eval(<<EOF)
def run_forever(current, final)
  if current < final
    run_forever(current+1, final)
  else
    nil
  end
end

run_forever(1, Float::INFINITY)
EOF

Updated by sunkai612 (Kai Sun) over 4 years ago

Shugo Maeda wrote:

Kai Sun wrote:

Below code gets stack too deep error:

RubyVM::InstructionSequence.compile_option must be set before
compilation of the target program, so you need eval, load, etc.

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

eval(<<EOF)
def run_forever(current, final)
  if current < final
    run_forever(current+1, final)
  else
    nil
  end
end

run_forever(1, Float::INFINITY)
EOF

I have tried with eval but seems still getting stack level too deep error.

Updated by sunkai612 (Kai Sun) over 4 years ago

I have also tried below and still get SystemStackError:

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

RubyVM::InstructionSequence.new(<<-EOF).eval
def run_forever(current, final)
  if current < final
    run_forever(current+1, final)
  else
    nil
  end
end
EOF

run_forever(1, Float::INFINITY)

However, if we alter the conditional order, it will work as expected:

RubyVM::InstructionSequence.compile_option = {
  :tailcall_optimization => true,
  :trace_instruction => false
}

RubyVM::InstructionSequence.new(<<-EOF).eval
def run_forever(current, final)
  if current >= final
    nil
  else
    run_forever(current+1, final)
  end
end
EOF

run_forever(1, Float::INFINITY)

Updated by nobu (Nobuyoshi Nakada) over 4 years ago

  • Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED
  • Status changed from Rejected to Closed

It's a bug fixed in the trunk.

Updated by nagachika (Tomoyuki Chikanaga) over 4 years ago

  • Backport changed from 2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED to 2.1: REQUIRED, 2.2: REQUIRED, 2.3: DONE

ruby_2_3 r56715 merged revision(s) 56208,56663.

Also available in: Atom PDF