Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/llvm.cr
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ module LLVM
string
end

protected def self.assert(error : LibLLVM::ErrorRef)
if error
chars = LibLLVM.get_error_message(error)
raise String.new(chars).tap { LibLLVM.dispose_error_message(chars) }
end
end

{% unless LibLLVM::IS_LT_130 %}
def self.run_passes(module mod : Module, passes : String, target_machine : TargetMachine, options : PassBuilderOptions)
LibLLVM.run_passes(mod, passes, target_machine, options)
Expand Down
3 changes: 3 additions & 0 deletions src/llvm/lib_llvm/error.cr
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
lib LibLLVM
type ErrorRef = Void*

fun get_error_message = LLVMGetErrorMessage(err : ErrorRef) : Char*
fun dispose_error_message = LLVMDisposeErrorMessage(err_msg : Char*)
end
16 changes: 16 additions & 0 deletions src/llvm/lib_llvm/lljit.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% skip_file if LibLLVM::IS_LT_110 %}

lib LibLLVM
alias OrcLLJITBuilderRef = Void*
alias OrcLLJITRef = Void*

fun orc_create_lljit_builder = LLVMOrcCreateLLJITBuilder : OrcLLJITBuilderRef
fun orc_dispose_lljit_builder = LLVMOrcDisposeLLJITBuilder(builder : OrcLLJITBuilderRef)

fun orc_create_lljit = LLVMOrcCreateLLJIT(result : OrcLLJITRef*, builder : OrcLLJITBuilderRef) : ErrorRef
fun orc_dispose_lljit = LLVMOrcDisposeLLJIT(j : OrcLLJITRef) : ErrorRef

fun orc_lljit_get_main_jit_dylib = LLVMOrcLLJITGetMainJITDylib(j : OrcLLJITRef) : OrcJITDylibRef
fun orc_lljit_add_llvm_ir_module = LLVMOrcLLJITAddLLVMIRModule(j : OrcLLJITRef, jd : OrcJITDylibRef, tsm : OrcThreadSafeModuleRef) : ErrorRef
fun orc_lljit_lookup = LLVMOrcLLJITLookup(j : OrcLLJITRef, result : OrcExecutorAddress*, name : Char*) : ErrorRef
end
26 changes: 26 additions & 0 deletions src/llvm/lib_llvm/orc.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% skip_file if LibLLVM::IS_LT_110 %}

lib LibLLVM
# OrcJITTargetAddress before LLVM 13.0 (also an alias of UInt64)
alias OrcExecutorAddress = UInt64
alias OrcSymbolStringPoolEntryRef = Void*
alias OrcJITDylibRef = Void*
alias OrcDefinitionGeneratorRef = Void*
alias OrcSymbolPredicate = Void*, OrcSymbolStringPoolEntryRef -> Int
alias OrcThreadSafeContextRef = Void*
alias OrcThreadSafeModuleRef = Void*

fun orc_create_dynamic_library_search_generator_for_process = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
result : OrcDefinitionGeneratorRef*, global_prefx : Char,
filter : OrcSymbolPredicate, filter_ctx : Void*
) : ErrorRef

fun orc_jit_dylib_add_generator = LLVMOrcJITDylibAddGenerator(jd : OrcJITDylibRef, dg : OrcDefinitionGeneratorRef)

fun orc_create_new_thread_safe_context = LLVMOrcCreateNewThreadSafeContext : OrcThreadSafeContextRef
fun orc_thread_safe_context_get_context = LLVMOrcThreadSafeContextGetContext(ts_ctx : OrcThreadSafeContextRef) : ContextRef
fun orc_dispose_thread_safe_context = LLVMOrcDisposeThreadSafeContext(ts_ctx : OrcThreadSafeContextRef)

fun orc_create_new_thread_safe_module = LLVMOrcCreateNewThreadSafeModule(m : ModuleRef, ts_ctx : OrcThreadSafeContextRef) : OrcThreadSafeModuleRef
fun orc_dispose_thread_safe_module = LLVMOrcDisposeThreadSafeModule(tsm : OrcThreadSafeModuleRef)
end
16 changes: 16 additions & 0 deletions src/llvm/orc/jit_dylib.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% skip_file if LibLLVM::IS_LT_110 %}

@[Experimental("The C API wrapped by this type is marked as experimental by LLVM.")]
class LLVM::Orc::JITDylib
protected def initialize(@unwrap : LibLLVM::OrcJITDylibRef)
end

def to_unsafe
@unwrap
end

def link_symbols_from_current_process : Nil
LLVM.assert LibLLVM.orc_create_dynamic_library_search_generator_for_process(out dg, 0, nil, nil)
LibLLVM.orc_jit_dylib_add_generator(self, dg)
end
end
42 changes: 42 additions & 0 deletions src/llvm/orc/lljit.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% skip_file if LibLLVM::IS_LT_110 %}

@[Experimental("The C API wrapped by this type is marked as experimental by LLVM.")]
class LLVM::Orc::LLJIT
protected def initialize(@unwrap : LibLLVM::OrcLLJITRef)
end

def self.new(builder : LLJITBuilder)
builder.take_ownership { raise "Failed to take ownership of LLVM::Orc::LLJITBuilder" }
LLVM.assert LibLLVM.orc_create_lljit(out unwrap, builder)
new(unwrap)
end

def to_unsafe
@unwrap
end

def dispose : Nil
LLVM.assert LibLLVM.orc_dispose_lljit(self)
@unwrap = LibLLVM::OrcLLJITRef.null
end

def finalize
if @unwrap
LibLLVM.orc_dispose_lljit(self)
end
end

def main_jit_dylib : JITDylib
JITDylib.new(LibLLVM.orc_lljit_get_main_jit_dylib(self))
end

def add_llvm_ir_module(dylib : JITDylib, tsm : ThreadSafeModule) : Nil
tsm.take_ownership { raise "Failed to take ownership of LLVM::Orc::ThreadSafeModule" }
LLVM.assert LibLLVM.orc_lljit_add_llvm_ir_module(self, dylib, tsm)
end

def lookup(name : String) : Void*
LLVM.assert LibLLVM.orc_lljit_lookup(self, out address, name.check_no_null_byte)
Pointer(Void).new(address)
end
end
35 changes: 35 additions & 0 deletions src/llvm/orc/lljit_builder.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{% skip_file if LibLLVM::IS_LT_110 %}

@[Experimental("The C API wrapped by this type is marked as experimental by LLVM.")]
class LLVM::Orc::LLJITBuilder
protected def initialize(@unwrap : LibLLVM::OrcLLJITBuilderRef)
@dispose_on_finalize = true
end

def self.new
new(LibLLVM.orc_create_lljit_builder)
end

def to_unsafe
@unwrap
end

def dispose : Nil
LibLLVM.orc_dispose_lljit_builder(self)
@unwrap = LibLLVM::OrcLLJITBuilderRef.null
end

def finalize
if @dispose_on_finalize && @unwrap
dispose
end
end

def take_ownership(&) : Nil
if @dispose_on_finalize
@dispose_on_finalize = false
else
yield
end
end
end
30 changes: 30 additions & 0 deletions src/llvm/orc/thread_safe_context.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{% skip_file if LibLLVM::IS_LT_110 %}

@[Experimental("The C API wrapped by this type is marked as experimental by LLVM.")]
class LLVM::Orc::ThreadSafeContext
protected def initialize(@unwrap : LibLLVM::OrcThreadSafeContextRef)
end

def self.new
new(LibLLVM.orc_create_new_thread_safe_context)
end

def to_unsafe
@unwrap
end

def dispose : Nil
LibLLVM.orc_dispose_thread_safe_context(self)
@unwrap = LibLLVM::OrcThreadSafeContextRef.null
end

def finalize
if @unwrap
dispose
end
end

def context : LLVM::Context
LLVM::Context.new(LibLLVM.orc_thread_safe_context_get_context(self), false)
end
end
36 changes: 36 additions & 0 deletions src/llvm/orc/thread_safe_module.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{% skip_file if LibLLVM::IS_LT_110 %}

@[Experimental("The C API wrapped by this type is marked as experimental by LLVM.")]
class LLVM::Orc::ThreadSafeModule
protected def initialize(@unwrap : LibLLVM::OrcThreadSafeModuleRef)
@dispose_on_finalize = true
end

def self.new(llvm_mod : LLVM::Module, ts_ctx : ThreadSafeContext)
llvm_mod.take_ownership { raise "Failed to take ownership of LLVM::Module" }
new(LibLLVM.orc_create_new_thread_safe_module(llvm_mod, ts_ctx))
end

def to_unsafe
@unwrap
end

def dispose : Nil
LibLLVM.orc_dispose_thread_safe_module(self)
@unwrap = LibLLVM::OrcThreadSafeModuleRef.null
end

def finalize
if @dispose_on_finalize && @unwrap
dispose
end
end

def take_ownership(&) : Nil
if @dispose_on_finalize
@dispose_on_finalize = false
else
yield
end
end
end