summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTakashi Kokubun <[email protected]>2022-12-11 21:42:25 -0800
committerTakashi Kokubun <[email protected]>2023-03-05 22:11:20 -0800
commitfd04e1b4dbbb0dae130f3de79d69ca94ecdf883e (patch)
tree5d55a3c9c6650ef0116b2378eab5d35547798b49 /lib
parentbaa120ee8008a30c11066daa30cb03fcedc2e02f (diff)
Implement a no-op JIT compiler
Diffstat (limited to 'lib')
-rw-r--r--lib/mjit/x86_64/assembler.rb35
-rw-r--r--lib/ruby_vm/mjit/compiler.rb24
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