2022-12-17 13:39:35 -08:00
|
|
|
module RubyVM::MJIT
|
2022-12-20 21:54:54 -08:00
|
|
|
# ec: rdi
|
|
|
|
# cfp: rsi
|
|
|
|
# sp: rbx
|
|
|
|
# scratch regs: rax
|
2022-12-30 22:16:07 -08:00
|
|
|
#
|
|
|
|
# 4/101
|
2022-12-26 14:09:45 -08:00
|
|
|
class InsnCompiler
|
2022-12-30 22:16:07 -08:00
|
|
|
# @param ocb [CodeBlock]
|
|
|
|
def initialize(ocb)
|
|
|
|
@ocb = ocb
|
2022-12-30 21:27:12 -08:00
|
|
|
@exit_compiler = ExitCompiler.new
|
|
|
|
freeze
|
|
|
|
end
|
2022-12-28 13:50:24 -08:00
|
|
|
|
|
|
|
# nop
|
|
|
|
# getlocal
|
|
|
|
# setlocal
|
|
|
|
# getblockparam
|
|
|
|
# setblockparam
|
|
|
|
# getblockparamproxy
|
|
|
|
# getspecial
|
|
|
|
# setspecial
|
|
|
|
# getinstancevariable
|
|
|
|
# setinstancevariable
|
|
|
|
# getclassvariable
|
|
|
|
# setclassvariable
|
|
|
|
# opt_getconstant_path
|
|
|
|
# getconstant
|
|
|
|
# setconstant
|
|
|
|
# getglobal
|
|
|
|
# setglobal
|
|
|
|
|
2022-12-26 14:09:45 -08:00
|
|
|
# @param jit [RubyVM::MJIT::JITState]
|
2022-12-23 14:17:32 -08:00
|
|
|
# @param ctx [RubyVM::MJIT::Context]
|
2022-12-30 22:16:07 -08:00
|
|
|
# @param asm [RubyVM::MJIT::Assembler]
|
2022-12-26 14:09:45 -08:00
|
|
|
def putnil(jit, ctx, asm)
|
2022-12-28 13:16:14 -08:00
|
|
|
asm.mov([SP, C.VALUE.size * ctx.stack_size], Qnil)
|
2022-12-23 14:17:32 -08:00
|
|
|
ctx.stack_size += 1
|
2022-12-17 13:39:35 -08:00
|
|
|
KeepCompiling
|
|
|
|
end
|
|
|
|
|
2022-12-28 13:50:24 -08:00
|
|
|
# putself
|
2022-12-28 14:43:04 -08:00
|
|
|
|
|
|
|
# @param jit [RubyVM::MJIT::JITState]
|
|
|
|
# @param ctx [RubyVM::MJIT::Context]
|
2022-12-30 22:16:07 -08:00
|
|
|
# @param asm [RubyVM::MJIT::Assembler]
|
2022-12-28 14:43:04 -08:00
|
|
|
def putobject(jit, ctx, asm)
|
|
|
|
# Get operands
|
|
|
|
val = jit.operand(0)
|
|
|
|
|
|
|
|
# Push it to the stack
|
|
|
|
# TODO: GC offsets
|
|
|
|
if asm.imm32?(val)
|
|
|
|
asm.mov([SP, C.VALUE.size * ctx.stack_size], val)
|
|
|
|
else # 64-bit immediates can't be directly written to memory
|
|
|
|
asm.mov(:rax, val)
|
|
|
|
asm.mov([SP, C.VALUE.size * ctx.stack_size], :rax)
|
|
|
|
end
|
|
|
|
|
|
|
|
ctx.stack_size += 1
|
|
|
|
KeepCompiling
|
|
|
|
end
|
|
|
|
|
2022-12-28 13:50:24 -08:00
|
|
|
# putspecialobject
|
|
|
|
# putstring
|
|
|
|
# concatstrings
|
|
|
|
# anytostring
|
|
|
|
# toregexp
|
|
|
|
# intern
|
|
|
|
# newarray
|
|
|
|
# newarraykwsplat
|
|
|
|
# duparray
|
|
|
|
# duphash
|
|
|
|
# expandarray
|
|
|
|
# concatarray
|
|
|
|
# splatarray
|
|
|
|
# newhash
|
|
|
|
# newrange
|
|
|
|
# pop
|
|
|
|
# dup
|
|
|
|
# dupn
|
|
|
|
# swap
|
|
|
|
# opt_reverse
|
|
|
|
# topn
|
|
|
|
# setn
|
|
|
|
# adjuststack
|
|
|
|
# defined
|
|
|
|
# checkmatch
|
|
|
|
# checkkeyword
|
|
|
|
# checktype
|
|
|
|
# defineclass
|
|
|
|
# definemethod
|
|
|
|
# definesmethod
|
|
|
|
# send
|
|
|
|
# opt_send_without_block
|
|
|
|
# objtostring
|
|
|
|
# opt_str_freeze
|
|
|
|
# opt_nil_p
|
|
|
|
# opt_str_uminus
|
|
|
|
# opt_newarray_max
|
|
|
|
# opt_newarray_min
|
|
|
|
# invokesuper
|
|
|
|
# invokeblock
|
|
|
|
|
2022-12-26 14:09:45 -08:00
|
|
|
# @param jit [RubyVM::MJIT::JITState]
|
2022-12-23 14:17:32 -08:00
|
|
|
# @param ctx [RubyVM::MJIT::Context]
|
2022-12-30 22:16:07 -08:00
|
|
|
# @param asm [RubyVM::MJIT::Assembler]
|
2022-12-26 14:09:45 -08:00
|
|
|
def leave(jit, ctx, asm)
|
2022-12-23 14:17:32 -08:00
|
|
|
assert_eq!(ctx.stack_size, 1)
|
2022-12-26 14:09:45 -08:00
|
|
|
|
2022-12-28 13:16:02 -08:00
|
|
|
asm.comment('RUBY_VM_CHECK_INTS(ec)')
|
2022-12-26 14:09:45 -08:00
|
|
|
asm.mov(:eax, [EC, C.rb_execution_context_t.offsetof(:interrupt_flag)])
|
|
|
|
asm.test(:eax, :eax)
|
2022-12-30 22:16:07 -08:00
|
|
|
asm.jnz(compile_side_exit(jit, ctx))
|
2022-12-23 14:17:32 -08:00
|
|
|
|
2022-12-28 13:16:02 -08:00
|
|
|
asm.comment('pop stack frame')
|
2022-12-23 16:23:21 -08:00
|
|
|
asm.add(CFP, C.rb_control_frame_t.size) # cfp = cfp + 1
|
|
|
|
asm.mov([EC, C.rb_execution_context_t.offsetof(:cfp)], CFP) # ec->cfp = cfp
|
2022-12-17 13:39:35 -08:00
|
|
|
|
2022-12-23 14:46:39 -08:00
|
|
|
# Return a value
|
2022-12-23 16:23:21 -08:00
|
|
|
asm.mov(:rax, [SP])
|
2022-12-23 14:46:39 -08:00
|
|
|
|
|
|
|
# Restore callee-saved registers
|
2022-12-23 16:23:21 -08:00
|
|
|
asm.pop(SP)
|
2022-12-23 14:46:39 -08:00
|
|
|
|
2022-12-17 13:39:35 -08:00
|
|
|
asm.ret
|
|
|
|
EndBlock
|
|
|
|
end
|
2022-12-23 14:17:32 -08:00
|
|
|
|
2022-12-28 13:50:24 -08:00
|
|
|
# throw
|
|
|
|
# jump
|
|
|
|
# branchif
|
|
|
|
# branchunless
|
|
|
|
# branchnil
|
|
|
|
# once
|
|
|
|
# opt_case_dispatch
|
|
|
|
# opt_plus
|
|
|
|
# opt_minus
|
|
|
|
# opt_mult
|
|
|
|
# opt_div
|
|
|
|
# opt_mod
|
|
|
|
# opt_eq
|
|
|
|
# opt_neq
|
|
|
|
# opt_lt
|
|
|
|
# opt_le
|
|
|
|
# opt_gt
|
|
|
|
# opt_ge
|
|
|
|
# opt_ltlt
|
|
|
|
# opt_and
|
|
|
|
# opt_or
|
|
|
|
# opt_aref
|
|
|
|
# opt_aset
|
|
|
|
# opt_aset_with
|
|
|
|
# opt_aref_with
|
|
|
|
# opt_length
|
|
|
|
# opt_size
|
|
|
|
# opt_empty_p
|
|
|
|
# opt_succ
|
|
|
|
# opt_not
|
|
|
|
# opt_regexpmatch2
|
|
|
|
# invokebuiltin
|
|
|
|
# opt_invokebuiltin_delegate
|
|
|
|
# opt_invokebuiltin_delegate_leave
|
|
|
|
|
|
|
|
# @param jit [RubyVM::MJIT::JITState]
|
|
|
|
# @param ctx [RubyVM::MJIT::Context]
|
2022-12-30 22:16:07 -08:00
|
|
|
# @param asm [RubyVM::MJIT::Assembler]
|
2022-12-28 13:50:24 -08:00
|
|
|
def getlocal_WC_0(jit, ctx, asm)
|
|
|
|
# Get operands
|
|
|
|
idx = jit.operand(0)
|
|
|
|
level = 0
|
|
|
|
|
|
|
|
# Get EP
|
|
|
|
asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:ep)])
|
|
|
|
|
|
|
|
# Get a local variable
|
|
|
|
asm.mov(:rax, [:rax, -idx * C.VALUE.size])
|
|
|
|
|
|
|
|
# Push it to the stack
|
|
|
|
asm.mov([SP, C.VALUE.size * ctx.stack_size], :rax)
|
|
|
|
ctx.stack_size += 1
|
|
|
|
KeepCompiling
|
|
|
|
end
|
|
|
|
|
|
|
|
# getlocal_WC_1
|
|
|
|
# setlocal_WC_0
|
|
|
|
# setlocal_WC_1
|
|
|
|
# putobject_INT2FIX_0_
|
|
|
|
# putobject_INT2FIX_1_
|
|
|
|
|
2022-12-23 14:17:32 -08:00
|
|
|
private
|
|
|
|
|
|
|
|
def assert_eq!(left, right)
|
|
|
|
if left != right
|
|
|
|
raise "'#{left.inspect}' was not '#{right.inspect}'"
|
|
|
|
end
|
|
|
|
end
|
2022-12-30 22:16:07 -08:00
|
|
|
|
|
|
|
# @param jit [RubyVM::MJIT::JITState]
|
|
|
|
# @param ctx [RubyVM::MJIT::Context]
|
|
|
|
def compile_side_exit(jit, ctx)
|
|
|
|
asm = Assembler.new
|
|
|
|
@exit_compiler.compile_exit(jit, ctx, asm)
|
|
|
|
@ocb.write(asm)
|
|
|
|
end
|
2022-12-17 13:39:35 -08:00
|
|
|
end
|
|
|
|
end
|