how to use RubyVM to compile ruby code to bytecode with require source files?

Viewed 212

I have 2 ruby source files, for example:

A.rb

require "B"

foo

B.rb

 def foo()
  ..
 end

now I use the code to compile A to bytecode (Ruby v2.3.3):

byte_code = RubyVM::InstructionSequence.compile_file "A.rb"
File.binwrite "A.byte", byte_code.to_binary

and when I run the bytecode:

byte_code_in_binary = IO.binread "A.byte"
instruction_from_byte_code = RubyVM::InstructionSequence.load_from_binary byte_code_in_binary
instruction_from_byte_code.eval

then message was:

   .... in `require': cannot load such file -- B (LoadError)

if I compile the B.rb to bytecode then how can A.byte load B.byte ? or is there another way to compile the full ruby project to bytecode and run ? does Jruby or some tools can make it happen ? thanks.

1 Answers

the problem temporary solved. the answer is: make a "code shell" to load binary file, it looks like:

filelist.rb

$folder="some_folder"
$main_entry = "main.rb"
$reqiured_file=
[
  "file_1.rb",
  "file_2.rb",
  ...
]

now in compiling source code, it looks like:

def write_code(fname, load_filename)
    str = 
'byte_code_in_binary = IO.binread("'+load_filename+'")
instruction_from_byte_code = RubyVM::InstructionSequence.load_from_binary byte_code_in_binary
instruction_from_byte_code.eval'
    f = open(fname, "wb")
    f.write(str)
    f.close()
end

$LOAD_PATH.unshift(File.dirname(__FILE__))
require "filelist"
Dir.mkdir($folder)
byte_code = RubyVM::InstructionSequence.compile_file $main_entry
File.binwrite $folder + "/some_binary_file_name", byte_code.to_binary

$required_files.each do |f|
    write_code($folder + "/" + f, some_required_binary_names)
    byte_code = RubyVM::InstructionSequence.compile_file f
    File.binwrite $folder + "/" + some_required_binary_names, byte_code.to_binary
end

OK now require ruby script file looks like:

file_1.rb <-- this file in source code has been "required"

byte_code_in_binary = IO.binread("file_1_binary_name") <-- it was real compiled binary file_1.rb
instruction_from_byte_code = RubyVM::InstructionSequence.load_from_binary byte_code_in_binary
instruction_from_byte_code.eval

now we can load the require files with "VM binary mode".

Related