test_optimization.rb: tailcall

* test/ruby/test_optimization.rb (TestRubyOptimization.tailcall):
  helper method to compile methods with tailcall optimization
  enabled.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54141 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2016-03-17 04:31:10 +00:00
parent fdbb82967f
commit 7b2b831959

View File

@ -230,47 +230,54 @@ class TestRubyOptimization < Test::Unit::TestCase
assert_equal true, MyObj.new == nil assert_equal true, MyObj.new == nil
end end
def self.tailcall(klass, src, file = nil, path = nil, line = nil)
unless file
loc, = caller_locations(1, 1)
file = loc.path
line ||= loc.lineno
end
RubyVM::InstructionSequence.new("proc {|_|_.class_eval {#{src}}}",
file, (path || file), line,
tailcall_optimization: true,
trace_instruction: false)
.eval[klass]
end
def tailcall(*args)
self.class.tailcall(singleton_class, *args)
end
def test_tailcall def test_tailcall
bug4082 = '[ruby-core:33289]' bug4082 = '[ruby-core:33289]'
option = { tailcall(<<-EOF)
tailcall_optimization: true, def fact_helper(n, res)
trace_instruction: false, if n == 1
} res
RubyVM::InstructionSequence.new(<<-EOF, "Bug#4082", bug4082, nil, option).eval else
class #{self.class}::Tailcall fact_helper(n - 1, n * res)
def fact_helper(n, res)
if n == 1
res
else
fact_helper(n - 1, n * res)
end
end
def fact(n)
fact_helper(n, 1)
end end
end end
def fact(n)
fact_helper(n, 1)
end
EOF EOF
assert_equal(9131, Tailcall.new.fact(3000).to_s.size, bug4082) assert_equal(9131, fact(3000).to_s.size, bug4082)
end end
def test_tailcall_with_block def test_tailcall_with_block
bug6901 = '[ruby-dev:46065]' bug6901 = '[ruby-dev:46065]'
option = { tailcall(<<-EOF)
tailcall_optimization: true, def identity(val)
trace_instruction: false, val
} end
RubyVM::InstructionSequence.new(<<-EOF, "Bug#6901", bug6901, nil, option).eval
def identity(val)
val
end
def delay def delay
-> { -> {
identity(yield) identity(yield)
} }
end end
EOF EOF
assert_equal(123, delay { 123 }.call, bug6901) assert_equal(123, delay { 123 }.call, bug6901)
end end
@ -280,15 +287,12 @@ class TestRubyOptimization < Test::Unit::TestCase
end end
def test_tailcall_inhibited_by_block def test_tailcall_inhibited_by_block
assert_separately([], <<~'end;') tailcall(<<-EOF)
def just_yield def yield_result
yield just_yield {:ok}
end end
iseq = RubyVM::InstructionSequence EOF
result = iseq.compile("just_yield {:ok}", __FILE__, __FILE__, __LINE__, assert_equal(:ok, yield_result)
tailcall_optimization: true).eval
assert_equal(:ok, result)
end;
end end
class Bug10557 class Bug10557