Skip to content

Instantly share code, notes, and snippets.

@emdeeeks
Forked from barnaby/compiler.rb
Created April 12, 2020 21:21
Show Gist options
  • Save emdeeeks/edf3dc18986cd9b73489b3b002e702bd to your computer and use it in GitHub Desktop.
Save emdeeeks/edf3dc18986cd9b73489b3b002e702bd to your computer and use it in GitHub Desktop.
Compile & execute Ruby as bytecode. Works in 1.9.3
#
#
# Compile & execute Ruby as bytecode
#
#
require 'rbconfig'
require 'dl'
require 'fiddle'
require 'strscan'
# This monkey patch allows us to load arbitrary byte code with
# Ruby's VM. Originally from: https://gist.github.com/cstrahan/3552903
class RubyVM
class InstructionSequence
handle = DL::Handle::DEFAULT
address = handle['rb_iseq_load']
func = Fiddle::Function.new(address, [DL::TYPE_VOIDP] * 3,
DL::TYPE_VOIDP)
define_singleton_method(:load) do |data, parent = nil, opt = nil|
func.call(DL.dlwrap(data), parent, opt).to_value
end
end
end
class Compiler
class << self
# Compile .rb file to .rbc file
def compile input, output
seq = RubyVM::InstructionSequence.compile(open(input).read)
File.write(output, Marshal.dump(seq.to_a))
end
# Require a .rbc file
def require_compiled file
seq = Marshal.load(File.read(file))
RubyVM::InstructionSequence.load(seq).eval
end
end
end
Compiler.compile('in.rb', 'out.rbc')
Compiler.require_compiled('out.rbc')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment