mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
4cf0918e8e
instruction. for example, at the following script def m() p:xyzzy 1 2 end compiler ignores `1' because there is no effect. However, `trace(line)' instruction remains in bytecode. This modification removes such redundant trace(line) instruction. * test/ruby/test_iseq.rb: add a test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
120 lines
3 KiB
Ruby
120 lines
3 KiB
Ruby
require 'test/unit'
|
|
require_relative 'envutil'
|
|
|
|
class TestISeq < Test::Unit::TestCase
|
|
ISeq = RubyVM::InstructionSequence
|
|
|
|
def test_no_linenum
|
|
bug5894 = '[ruby-dev:45130]'
|
|
assert_normal_exit('p RubyVM::InstructionSequence.compile("1", "mac", "", 0).to_a', bug5894)
|
|
end
|
|
|
|
def lines src
|
|
body = RubyVM::InstructionSequence.new(src).to_a[13]
|
|
lines = body.find_all{|e| e.kind_of? Fixnum}
|
|
end
|
|
|
|
def test_to_a_lines
|
|
src = <<-EOS
|
|
p __LINE__ # 1
|
|
p __LINE__ # 2
|
|
# 3
|
|
p __LINE__ # 4
|
|
EOS
|
|
assert_equal [1, 2, 4], lines(src)
|
|
|
|
src = <<-EOS
|
|
# 1
|
|
p __LINE__ # 2
|
|
# 3
|
|
p __LINE__ # 4
|
|
# 5
|
|
EOS
|
|
assert_equal [2, 4], lines(src)
|
|
|
|
src = <<-EOS
|
|
1 # should be optimized out
|
|
2 # should be optimized out
|
|
p __LINE__ # 3
|
|
p __LINE__ # 4
|
|
5 # should be optimized out
|
|
6 # should be optimized out
|
|
p __LINE__ # 7
|
|
8 # should be optimized out
|
|
9
|
|
EOS
|
|
assert_equal [3, 4, 7, 9], lines(src)
|
|
end
|
|
|
|
def test_unsupport_type
|
|
ary = RubyVM::InstructionSequence.compile("p").to_a
|
|
ary[9] = :foobar
|
|
e = assert_raise(TypeError) {RubyVM::InstructionSequence.load(ary)}
|
|
assert_match(/:foobar/, e.message)
|
|
end if defined?(RubyVM::InstructionSequence.load)
|
|
|
|
def test_disasm_encoding
|
|
src = "\u{3042} = 1; \u{3042}"
|
|
enc, Encoding.default_internal = Encoding.default_internal, src.encoding
|
|
assert_equal(src.encoding, RubyVM::InstructionSequence.compile(src).disasm.encoding)
|
|
src.encode!(Encoding::Shift_JIS)
|
|
assert_equal(true, RubyVM::InstructionSequence.compile(src).disasm.ascii_only?)
|
|
ensure
|
|
Encoding.default_internal = enc
|
|
end
|
|
|
|
LINE_BEFORE_METHOD = __LINE__
|
|
def method_test_line_trace
|
|
|
|
a = 1
|
|
|
|
b = 2
|
|
|
|
end
|
|
|
|
def test_line_trace
|
|
iseq = ISeq.compile \
|
|
%q{ a = 1
|
|
b = 2
|
|
c = 3
|
|
# d = 4
|
|
e = 5
|
|
# f = 6
|
|
g = 7
|
|
|
|
}
|
|
assert_equal([1, 2, 3, 5, 7], iseq.line_trace_all)
|
|
iseq.line_trace_specify(1, true) # line 2
|
|
iseq.line_trace_specify(3, true) # line 5
|
|
|
|
result = []
|
|
TracePoint.new(:specified_line){|tp|
|
|
result << tp.lineno
|
|
}.enable{
|
|
iseq.eval
|
|
}
|
|
assert_equal([2, 5], result)
|
|
|
|
iseq = ISeq.of(self.class.instance_method(:method_test_line_trace))
|
|
assert_equal([LINE_BEFORE_METHOD + 3, LINE_BEFORE_METHOD + 5], iseq.line_trace_all)
|
|
end if false # TODO: now, it is only for C APIs.
|
|
|
|
LINE_OF_HERE = __LINE__
|
|
def test_location
|
|
iseq = ISeq.of(method(:test_location))
|
|
|
|
assert_equal(__FILE__, iseq.path)
|
|
assert(/#{__FILE__}/ =~ iseq.absolute_path)
|
|
assert_equal("test_location", iseq.label)
|
|
assert_equal("test_location", iseq.base_label)
|
|
assert_equal(LINE_OF_HERE+1, iseq.first_lineno)
|
|
|
|
line = __LINE__
|
|
iseq = ISeq.of(Proc.new{})
|
|
assert_equal(__FILE__, iseq.path)
|
|
assert(/#{__FILE__}/ =~ iseq.absolute_path)
|
|
assert_equal("test_location", iseq.base_label)
|
|
assert_equal("block in test_location", iseq.label)
|
|
assert_equal(line+1, iseq.first_lineno)
|
|
end
|
|
end
|