aboutsummaryrefslogtreecommitdiffstats
path: root/tool/lib/iseq_loader_checker.rb
diff options
context:
space:
mode:
Diffstat (limited to 'tool/lib/iseq_loader_checker.rb')
-rw-r--r--tool/lib/iseq_loader_checker.rb75
1 files changed, 75 insertions, 0 deletions
diff --git a/tool/lib/iseq_loader_checker.rb b/tool/lib/iseq_loader_checker.rb
new file mode 100644
index 0000000000..1a1a694834
--- /dev/null
+++ b/tool/lib/iseq_loader_checker.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+begin
+ require '-test-/iseq_load/iseq_load'
+rescue LoadError
+end
+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
+ 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
+
+ CHECK_TO_A = ENV['RUBY_ISEQ_DUMP_DEBUG'] == 'to_a'
+ CHECK_TO_BINARY = ENV['RUBY_ISEQ_DUMP_DEBUG'] == 'to_binary'
+
+ def self.translate i1
+ # check to_a/load_iseq
+ compare_dump_and_load(i1,
+ proc{|iseq|
+ ary = iseq.to_a
+ ary[9] == :top ? ary : nil
+ },
+ proc{|ary|
+ RubyVM::InstructionSequence.iseq_load(ary)
+ }) if CHECK_TO_A && defined?(RubyVM::InstructionSequence.iseq_load)
+
+ # check to_binary
+ i2_bin = compare_dump_and_load(i1,
+ proc{|iseq|
+ begin
+ iseq.to_binary
+ rescue RuntimeError # not a toplevel
+ # STDERR.puts [:failed, $!, iseq].inspect
+ nil
+ end
+ },
+ proc{|bin|
+ iseq = RubyVM::InstructionSequence.load_from_binary(bin)
+ # STDERR.puts iseq.inspect
+ iseq
+ }) if CHECK_TO_BINARY
+ # return value
+ i2_bin if CHECK_TO_BINARY
+ end if CHECK_TO_A || CHECK_TO_BINARY
+end
+
+#require_relative 'x'; exit(1)