mirror of
https://github.com/ruby/ruby.git
synced 2025-08-25 14:05:02 +02:00
Compile putnil properly
This commit is contained in:
parent
8deb0438c4
commit
145c937f3f
3 changed files with 65 additions and 37 deletions
|
@ -9,9 +9,6 @@ module RubyVM::MJIT
|
|||
EndBlock = :end_block
|
||||
|
||||
class Compiler
|
||||
# Ruby constants
|
||||
Qundef = Fiddle::Qundef
|
||||
|
||||
attr_accessor :write_pos
|
||||
|
||||
# @param mem_block [Integer] JIT buffer address
|
||||
|
@ -24,7 +21,11 @@ module RubyVM::MJIT
|
|||
# @param iseq [RubyVM::MJIT::CPointer::Struct]
|
||||
def call(iseq)
|
||||
return if iseq.body.location.label == '<main>'
|
||||
iseq.body.jit_func = compile_block(iseq)
|
||||
|
||||
asm = X86Assembler.new
|
||||
compile_prologue(asm)
|
||||
compile_block(asm, iseq)
|
||||
iseq.body.jit_func = compile(asm)
|
||||
rescue Exception => e
|
||||
$stderr.puts e.full_message # TODO: check verbose
|
||||
end
|
||||
|
@ -35,6 +36,32 @@ module RubyVM::MJIT
|
|||
|
||||
private
|
||||
|
||||
# ec: rdi
|
||||
# cfp: rsi
|
||||
def compile_prologue(asm)
|
||||
asm.mov(:rbx, [:rsi, C.rb_control_frame_t.offsetof(:sp)]) # rbx = cfp->sp
|
||||
end
|
||||
|
||||
def compile_block(asm, iseq)
|
||||
index = 0
|
||||
while index < iseq.body.iseq_size
|
||||
insn = decode_insn(iseq.body.iseq_encoded[index])
|
||||
status = compile_insn(asm, insn)
|
||||
if status == EndBlock
|
||||
break
|
||||
end
|
||||
index += insn.len
|
||||
end
|
||||
end
|
||||
|
||||
def compile_insn(asm, insn)
|
||||
case insn.name
|
||||
when :putnil then @insn_compiler.putnil(asm)
|
||||
when :leave then @insn_compiler.leave(asm)
|
||||
else raise NotImplementedError, "insn '#{insn.name}' is not supported yet"
|
||||
end
|
||||
end
|
||||
|
||||
def compile(asm)
|
||||
start_addr = write_addr
|
||||
|
||||
|
@ -49,32 +76,6 @@ module RubyVM::MJIT
|
|||
start_addr
|
||||
end
|
||||
|
||||
# ec -> RDI, cfp -> RSI
|
||||
def compile_block(iseq)
|
||||
addr = write_addr
|
||||
asm = X86Assembler.new
|
||||
|
||||
index = 0
|
||||
while index < iseq.body.iseq_size
|
||||
insn = decode_insn(iseq.body.iseq_encoded[index])
|
||||
status = compile_insn(asm, insn)
|
||||
if status == EndBlock
|
||||
break
|
||||
end
|
||||
index += insn.len
|
||||
end
|
||||
|
||||
compile(asm)
|
||||
end
|
||||
|
||||
def compile_insn(asm, insn)
|
||||
case insn.name
|
||||
when :putnil then @insn_compiler.putnil(asm)
|
||||
when :leave then @insn_compiler.leave(asm)
|
||||
else raise NotImplementedError, "insn '#{insn.name}' is not supported yet"
|
||||
end
|
||||
end
|
||||
|
||||
def decode_insn(encoded)
|
||||
INSNS.fetch(C.rb_vm_insn_decode(encoded))
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue