aboutsummaryrefslogtreecommitdiffstats
path: root/test/lib/iseq_loader_checker.rb
blob: 0c372ca6382ca542059a75bfca230ebba31332f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
require '-test-/iseq_load/iseq_load'
require 'tempfile'

class RubyVM::InstructionSequence
  def disasm_if_possible
    begin
      self.disasm
    rescue Encoding::CompatibilityError, EncodingError, SecurityError
      nil
    end
  end

  def self.compare_dump_and_load i1, dumper, loader
    dump = dumper.call(i1)
    return i1 unless dump
    i2 = loader.call(dump)

    # compare disassembled result
    d1 = i1.disasm_if_possible
    d2 = i2.disasm_if_possible

    if d1 != d2
      p i1
      return

      STDERR.puts "expected:"
      STDERR.puts d1
      STDERR.puts "actual:"
      STDERR.puts d2

      t1 = Tempfile.new("expected"); t1.puts d1; t1.close
      t2 = Tempfile.new("actual"); t2.puts d2; t2.close
      system("diff -u #{t1.path} #{t2.path}") # use diff if available
      exit(1)
    end
    i2
  end

  def self.translate i1
    # check to_a/load_iseq
    i2 = compare_dump_and_load(i1,
                               proc{|iseq|
                                 ary = iseq.to_a
                                 ary[9] == :top ? ary : nil
                               },
                               proc{|ary|
                                 RubyVM::InstructionSequence.iseq_load(ary)
                               })
    # return value
    i1
  end
end

#require_relative 'x'; exit(1)