2015-12-16 00:07:31 -05:00
|
|
|
# frozen_string_literal: false
|
2014-12-03 17:16:58 -05:00
|
|
|
require 'test/unit'
|
|
|
|
|
|
|
|
class TestIseqLoad < Test::Unit::TestCase
|
2016-01-10 04:43:47 -05:00
|
|
|
require '-test-/iseq_load'
|
2014-12-03 17:16:58 -05:00
|
|
|
ISeq = RubyVM::InstructionSequence
|
|
|
|
|
|
|
|
def test_bug8543
|
2018-01-03 19:26:50 -05:00
|
|
|
assert_iseq_roundtrip "#{<<~"begin;"}\n#{<<~'end;'}"
|
|
|
|
begin;
|
2014-12-03 17:16:58 -05:00
|
|
|
puts "tralivali"
|
|
|
|
def funct(a, b)
|
|
|
|
a**b
|
|
|
|
end
|
|
|
|
3.times { |i| puts "Hello, world#{funct(2,i)}!" }
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
|
2018-07-09 13:47:37 -04:00
|
|
|
def test_stressful_roundtrip
|
2018-12-28 20:53:10 -05:00
|
|
|
assert_separately(%w[-r-test-/iseq_load], "#{<<~"begin;"}\n#{<<~'end;;'}", timeout: 120)
|
2018-08-10 05:22:13 -04:00
|
|
|
begin;
|
2018-12-06 00:29:07 -05:00
|
|
|
ISeq = RubyVM::InstructionSequence
|
|
|
|
def assert_iseq_roundtrip(src, line=caller_locations(1,1)[0].lineno+1)
|
|
|
|
a = ISeq.compile(src, __FILE__, __FILE__, line).to_a
|
|
|
|
b = ISeq.iseq_load(a).to_a
|
|
|
|
assert_equal a, b, proc {diff(a, b)}
|
|
|
|
b = ISeq.iseq_load(b).to_a
|
|
|
|
assert_equal a, b, proc {diff(a, b)}
|
2018-08-10 05:22:13 -04:00
|
|
|
end
|
2018-12-06 00:29:07 -05:00
|
|
|
def test_bug8543
|
|
|
|
assert_iseq_roundtrip "#{<<~"begin;"}\n#{<<~'end;'}"
|
|
|
|
begin;
|
|
|
|
puts "tralivali"
|
|
|
|
def funct(a, b)
|
|
|
|
a**b
|
|
|
|
end
|
|
|
|
3.times { |i| puts "Hello, world#{funct(2,i)}!" }
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
GC.stress = true
|
|
|
|
test_bug8543
|
2018-08-10 05:22:13 -04:00
|
|
|
end;;
|
2018-07-09 13:47:37 -04:00
|
|
|
end
|
|
|
|
|
2014-12-03 17:16:58 -05:00
|
|
|
def test_case_when
|
2018-01-03 19:26:50 -05:00
|
|
|
assert_iseq_roundtrip "#{<<~"begin;"}\n#{<<~'end;'}"
|
|
|
|
begin;
|
2014-12-03 17:16:58 -05:00
|
|
|
def user_mask(target)
|
|
|
|
target.each_char.inject(0) do |mask, chr|
|
|
|
|
case chr
|
|
|
|
when "u"
|
|
|
|
mask | 04700
|
|
|
|
when "g"
|
|
|
|
mask | 02070
|
|
|
|
when "o"
|
|
|
|
mask | 01007
|
|
|
|
when "a"
|
|
|
|
mask | 07777
|
|
|
|
else
|
|
|
|
raise ArgumentError, "invalid `who' symbol in file mode: #{chr}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_splatsplat
|
2018-01-03 19:26:50 -05:00
|
|
|
assert_iseq_roundtrip("#{<<-"begin;"}\n#{<<-'end;'}")
|
|
|
|
begin;
|
|
|
|
def splatsplat(**); end
|
|
|
|
end;
|
2014-12-03 17:16:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_hidden
|
2018-01-03 19:26:50 -05:00
|
|
|
assert_iseq_roundtrip("#{<<~"begin;"}\n#{<<~'end;'}")
|
|
|
|
begin;
|
|
|
|
def x(a, (b, *c), d: false); end
|
|
|
|
end;
|
2014-12-03 17:16:58 -05:00
|
|
|
end
|
|
|
|
|
2018-01-03 19:26:50 -05:00
|
|
|
def assert_iseq_roundtrip(src, line=caller_locations(1,1)[0].lineno+1)
|
|
|
|
a = ISeq.compile(src, __FILE__, __FILE__, line).to_a
|
2014-12-03 17:16:58 -05:00
|
|
|
b = ISeq.iseq_load(a).to_a
|
2018-12-06 00:29:07 -05:00
|
|
|
assert_equal a, b, proc {diff(a, b)}
|
|
|
|
b = ISeq.iseq_load(b).to_a
|
|
|
|
assert_equal a, b, proc {diff(a, b)}
|
2014-12-03 17:16:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_next_in_block_in_block
|
2014-12-28 04:20:21 -05:00
|
|
|
@next_broke = false
|
2018-01-03 19:26:50 -05:00
|
|
|
src, line = "#{<<~"begin;"}#{<<~'end;'}", __LINE__+2
|
|
|
|
begin;
|
2014-12-28 04:20:21 -05:00
|
|
|
3.times { 3.times { next; @next_broke = true } }
|
2014-12-03 17:16:58 -05:00
|
|
|
end;
|
2019-06-29 20:56:30 -04:00
|
|
|
a = EnvUtil.suppress_warning {
|
|
|
|
ISeq.compile(src, __FILE__, __FILE__, line)
|
|
|
|
}.to_a
|
2014-12-28 04:20:21 -05:00
|
|
|
iseq = ISeq.iseq_load(a)
|
|
|
|
iseq.eval
|
|
|
|
assert_equal false, @next_broke
|
|
|
|
skip "failing due to stack_max mismatch"
|
|
|
|
assert_iseq_roundtrip(src)
|
2014-12-03 17:16:58 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_break_ensure
|
2018-01-03 19:26:50 -05:00
|
|
|
src, line = "#{<<~"begin;"}#{<<~'end;'}", __LINE__+2
|
|
|
|
begin;
|
2014-12-28 04:20:21 -05:00
|
|
|
def test_break_ensure_def_method
|
2014-12-03 17:16:58 -05:00
|
|
|
bad = true
|
|
|
|
while true
|
|
|
|
begin
|
|
|
|
break
|
|
|
|
ensure
|
|
|
|
bad = false
|
|
|
|
end
|
|
|
|
end
|
2014-12-28 04:20:21 -05:00
|
|
|
bad
|
2014-12-03 17:16:58 -05:00
|
|
|
end
|
|
|
|
end;
|
2018-01-03 19:26:50 -05:00
|
|
|
a = ISeq.compile(src, __FILE__, __FILE__, line).to_a
|
2014-12-28 04:20:21 -05:00
|
|
|
iseq = ISeq.iseq_load(a)
|
|
|
|
iseq.eval
|
|
|
|
assert_equal false, test_break_ensure_def_method
|
|
|
|
skip "failing due to exception entry sp mismatch"
|
|
|
|
assert_iseq_roundtrip(src)
|
2014-12-03 17:16:58 -05:00
|
|
|
end
|
|
|
|
|
2015-07-07 15:50:49 -04:00
|
|
|
def test_kwarg
|
2018-01-03 19:26:50 -05:00
|
|
|
assert_iseq_roundtrip "#{<<~"begin;"}\n#{<<~'end;'}"
|
|
|
|
begin;
|
2015-07-07 15:50:49 -04:00
|
|
|
def foo(kwarg: :foo)
|
|
|
|
kwarg
|
|
|
|
end
|
|
|
|
foo(kwarg: :bar)
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
|
2014-12-03 17:16:58 -05:00
|
|
|
# FIXME: still failing
|
|
|
|
def test_require_integration
|
|
|
|
skip "iseq loader require integration tests still failing"
|
|
|
|
f = File.expand_path(__FILE__)
|
|
|
|
# $(top_srcdir)/test/ruby/test_....rb
|
|
|
|
3.times { f = File.dirname(f) }
|
2017-02-02 00:43:58 -05:00
|
|
|
all_assertions do |all|
|
|
|
|
Dir[File.join(f, 'ruby', '*.rb')].each do |f|
|
|
|
|
all.for(f) do
|
|
|
|
iseq = ISeq.compile_file(f)
|
|
|
|
orig = iseq.to_a.freeze
|
2014-12-03 17:16:58 -05:00
|
|
|
|
2017-02-02 00:43:58 -05:00
|
|
|
loaded = ISeq.iseq_load(orig).to_a
|
|
|
|
assert loaded == orig, proc {"ISeq unmatch:\n"+diff(orig, loaded)}
|
|
|
|
end
|
2014-12-03 17:16:58 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|