This commit is contained in:
Takashi Kokubun 2023-03-10 13:19:05 -08:00
Родитель 6440d159b3
Коммит 76808b1ee4
3 изменённых файлов: 84 добавлений и 7 удалений

Просмотреть файл

@ -58,19 +58,20 @@ module RubyVM::RJIT
(@mem_block...(@mem_block + @mem_size)).include?(addr)
end
private
def dump_disasm(from, to)
def dump_disasm(from, to, io: STDOUT, color: true)
C.dump_disasm(from, to).each do |address, mnemonic, op_str|
@comments.fetch(address, []).each do |comment|
puts colorize(" # #{comment}", bold: true)
io.puts colorize(" # #{comment}", bold: true, color:)
end
puts colorize(" 0x#{format("%x", address)}: #{mnemonic} #{op_str}")
io.puts colorize(" 0x#{format("%x", address)}: #{mnemonic} #{op_str}", color:)
end
puts
io.puts
end
def colorize(text, bold: false)
private
def colorize(text, bold: false, color:)
return text unless color
buf = +''
buf << "\e[1m" if bold
buf << "\e[34m" if @outlined

Просмотреть файл

@ -474,6 +474,16 @@ module RubyVM::RJIT # :nodoc: all
Primitive.cexpr! '(VALUE)NUM2PTR(value)'
end
def HAVE_LIBCAPSTONE
Primitive.cstmt! %{
#ifdef HAVE_LIBCAPSTONE
return Qtrue;
#else
return Qfalse;
#endif
}
end
#
# Utilities: Not used by RJIT, but useful for debugging
#

Просмотреть файл

@ -0,0 +1,66 @@
require 'test/unit'
require_relative '../../lib/jit_support'
return unless JITSupport.rjit_supported?
return unless RubyVM::RJIT.enabled?
return unless RubyVM::RJIT::C.HAVE_LIBCAPSTONE
require 'stringio'
require 'ruby_vm/rjit/assembler'
module RubyVM::RJIT
class TestAssembler < Test::Unit::TestCase
MEM_SIZE = 16 * 1024
def setup
@mem_block ||= C.mmap(MEM_SIZE)
@cb = CodeBlock.new(mem_block: @mem_block, mem_size: MEM_SIZE)
end
def test_add
asm = Assembler.new
asm.add(:rax, 255)
assert_compile(asm, '0x0: add rax, 0xff')
end
def test_jmp
asm = Assembler.new
label = asm.new_label('label')
asm.jmp(label)
asm.write_label(label)
asm.jmp(label)
assert_compile(asm, <<~EOS)
0x0: jmp 0x2
0x2: jmp 0x2
EOS
end
private
def assert_compile(asm, expected)
actual = compile(asm)
assert_equal expected, actual, "---\n#{actual}---"
end
def compile(asm)
start_addr = @cb.write_addr
@cb.write(asm)
end_addr = @cb.write_addr
io = StringIO.new
@cb.dump_disasm(start_addr, end_addr, io:, color: false)
io.seek(0)
disasm = io.read
disasm.gsub!(/^ /, '')
disasm.sub!(/\n\z/, '')
if disasm.lines.size == 1
disasm.rstrip!
end
(start_addr...end_addr).each do |addr|
disasm.gsub!("0x#{addr.to_s(16)}", "0x#{(addr - start_addr).to_s(16)}")
end
disasm
end
end
end