diff options
author | Takashi Kokubun <[email protected]> | 2022-12-11 21:42:25 -0800 |
---|---|---|
committer | Takashi Kokubun <[email protected]> | 2023-03-05 22:11:20 -0800 |
commit | fd04e1b4dbbb0dae130f3de79d69ca94ecdf883e (patch) | |
tree | 5d55a3c9c6650ef0116b2378eab5d35547798b49 /lib | |
parent | baa120ee8008a30c11066daa30cb03fcedc2e02f (diff) |
Implement a no-op JIT compiler
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mjit/x86_64/assembler.rb | 35 | ||||
-rw-r--r-- | lib/ruby_vm/mjit/compiler.rb | 24 |
2 files changed, 56 insertions, 3 deletions
diff --git a/lib/mjit/x86_64/assembler.rb b/lib/mjit/x86_64/assembler.rb new file mode 100644 index 0000000000..14f414b33b --- /dev/null +++ b/lib/mjit/x86_64/assembler.rb @@ -0,0 +1,35 @@ +class RubyVM::MJIT::Assembler + ByteWriter = RubyVM::MJIT::CType::Immediate.parse('char') + + def initialize + @bytes = [] + end + + def compile(compiler) + RubyVM::MJIT::C.mjit_mark_writable + write_bytes(compiler.write_addr, @bytes) + RubyVM::MJIT::C.mjit_mark_executable + + compiler.write_pos += @bytes.size + @bytes.clear + end + + def mov(_reg, val) + @bytes.push(0xb8, val, 0x00, 0x00, 0x00) + end + + def ret + @bytes.push(0xc3) + end + + private + + def write_bytes(addr, bytes) + writer = ByteWriter.new(addr) + # If you pack bytes containing \x00, Ruby fails to recognize bytes after \x00. + # So writing byte by byte to avoid hitting that situation. + bytes.each_with_index do |byte, index| + writer[index] = byte + end + end +end diff --git a/lib/ruby_vm/mjit/compiler.rb b/lib/ruby_vm/mjit/compiler.rb index cb2930246a..c42f75bf4d 100644 --- a/lib/ruby_vm/mjit/compiler.rb +++ b/lib/ruby_vm/mjit/compiler.rb @@ -1,6 +1,14 @@ +require 'mjit/x86_64/assembler' + class RubyVM::MJIT::Compiler - C = RubyVM::MJIT.const_get(:C, false) - INSNS = RubyVM::MJIT.const_get(:INSNS, false) + # MJIT internals + Assembler = RubyVM::MJIT::Assembler + C = RubyVM::MJIT::C + + # Ruby constants + Qundef = Fiddle::Qundef + + attr_accessor :write_pos # @param mem_block [Integer] JIT buffer address def initialize(mem_block) @@ -10,6 +18,16 @@ class RubyVM::MJIT::Compiler # @param iseq [RubyVM::MJIT::CPointer::Struct] def compile(iseq) - # TODO: implement + return if iseq.body.location.label == '<main>' + + iseq.body.jit_func = write_addr + asm = Assembler.new + asm.mov(:eax, Qundef) + asm.ret + asm.compile(self) + end + + def write_addr + @mem_block + @write_pos end end |