зеркало из https://github.com/github/ruby.git
RJIT: Start testing Assembler
This commit is contained in:
Родитель
6440d159b3
Коммит
76808b1ee4
|
@ -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
|
||||
|
|
10
rjit_c.rb
10
rjit_c.rb
|
@ -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
|
Загрузка…
Ссылка в новой задаче