Skip to content

Commit

Permalink
Merge pull request #112 from ruby-llvm/read-write-ir
Browse files Browse the repository at this point in the history
Parse and Write IR for LLVM::Module
  • Loading branch information
thoughtafter committed Mar 26, 2023
2 parents ce2c0cc + 6c24cf5 commit a136f57
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
14 changes: 14 additions & 0 deletions lib/llvm/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ module C
# @return [Bool]
# @scope class
attach_function :is_literal_struct, :LLVMIsLiteralStruct, [:pointer], :bool

# /**
# * Read LLVM IR from a memory buffer and convert it into an in-memory Module
# * object. Returns 0 on success.
# * Optionally returns a human-readable description of any errors that
# * occurred during parsing IR. OutMessage must be disposed with
# * LLVMDisposeMessage.
# *
# * @see llvm::ParseIR()
# */
# LLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef,
# LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
# char **OutMessage);
attach_function :parse_ir_in_context, :LLVMParseIRInContext, [:pointer, :pointer, :pointer, :pointer], :bool
end

# Yields a pointer suitable for storing an LLVM output message.
Expand Down
22 changes: 22 additions & 0 deletions lib/llvm/core/bitcode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,28 @@ def write_bitcode(path_or_io)
end
status == 0
end

def self.parse_ir(path_or_memory_buffer, context = Context.global)
memory_buffer = case path_or_memory_buffer
when MemoryBuffer then path_or_memory_buffer
else MemoryBuffer.from_file(path_or_memory_buffer)
end
FFI::MemoryPointer.new(:pointer) do |mod_ref|
FFI::MemoryPointer.new(:pointer) do |msg_ref|
status = C.parse_ir_in_context(context, memory_buffer, mod_ref, msg_ref)
raise msg_ref.get_pointer(0).get_string(0) if status
return from_ptr(mod_ref.get_pointer(0))
end
end
end

def write_ir!(filename)
FFI::MemoryPointer.new(:pointer) do |msg_ref|
status = C.print_module_to_file(self, filename, msg_ref)
raise msg_ref.get_pointer(0).get_string(0) if status != 0
end
self
end
end

# @private
Expand Down
6 changes: 6 additions & 0 deletions test/bitcode_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,11 @@ def test_bitcode
result = run_function_on_module(new_module, "test_function").to_i
assert_equal 1, result
end
Tempfile.open("ir") do |tmp|
assert test_module.write_ir!(tmp.path)
new_module = LLVM::Module.parse_ir(tmp.path)
result = run_function_on_module(new_module, "test_function").to_i
assert_equal 1, result
end
end
end

0 comments on commit a136f57

Please sign in to comment.