diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr index 31412035ff74..ae7e9a5cefca 100644 --- a/spec/spec_helper.cr +++ b/spec/spec_helper.cr @@ -284,7 +284,7 @@ def create_spec_compiler compiler end -def run(code, filename = nil, inject_primitives = true, debug = Crystal::Debug::None, flags = nil, *, file = __FILE__) +def run(code, filename : String? = nil, inject_primitives = true, debug = Crystal::Debug::None, flags = nil, *, file = __FILE__) : LLVM::GenericValue | SpecRunOutput if inject_primitives code = %(require "primitives"\n#{code}) end diff --git a/src/compiler/crystal/codegen/codegen.cr b/src/compiler/crystal/codegen/codegen.cr index 67882e9d75dc..f040f87e17f5 100644 --- a/src/compiler/crystal/codegen/codegen.cr +++ b/src/compiler/crystal/codegen/codegen.cr @@ -17,7 +17,7 @@ module Crystal ONCE = "__crystal_once" class Program - def run(code, filename = nil, debug = Debug::Default) + def run(code, filename : String? = nil, debug = Debug::Default) parser = new_parser(code) parser.filename = filename node = parser.parse @@ -79,7 +79,17 @@ module Crystal end def evaluate(node, return_type : T.class, debug = Debug::Default) : T forall T - visitor = CodeGenVisitor.new self, node, single_module: true, debug: debug + llvm_context = + {% if LibLLVM::IS_LT_110 %} + LLVM::Context.new + {% else %} + begin + ts_ctx = LLVM::Orc::ThreadSafeContext.new + ts_ctx.context + end + {% end %} + + visitor = CodeGenVisitor.new self, node, single_module: true, debug: debug, llvm_context: llvm_context visitor.accept node visitor.process_finished_hooks visitor.finish @@ -88,7 +98,6 @@ module Crystal llvm_mod.target = target_machine.triple main = visitor.typed_fun?(llvm_mod, MAIN_NAME).not_nil! - llvm_context = llvm_mod.context # void (*__evaluate_wrapper)(void*) wrapper_type = LLVM::Type.function([llvm_context.void_pointer], llvm_context.void) @@ -111,11 +120,27 @@ module Crystal llvm_mod.verify result = uninitialized T - LLVM::JITCompiler.new(llvm_mod) do |jit| - func_ptr = jit.function_address("__evaluate_wrapper") + + {% if LibLLVM::IS_LT_110 %} + LLVM::JITCompiler.new(llvm_mod) do |jit| + func_ptr = jit.function_address("__evaluate_wrapper") + func = Proc(T*, Nil).new(func_ptr, Pointer(Void).null) + func.call(pointerof(result)) + end + {% else %} + lljit_builder = LLVM::Orc::LLJITBuilder.new + lljit = LLVM::Orc::LLJIT.new(lljit_builder) + + dylib = lljit.main_jit_dylib + dylib.link_symbols_from_current_process(lljit.global_prefix) + tsm = LLVM::Orc::ThreadSafeModule.new(llvm_mod, ts_ctx) + lljit.add_llvm_ir_module(dylib, tsm) + + func_ptr = lljit.lookup("__evaluate_wrapper") func = Proc(T*, Nil).new(func_ptr, Pointer(Void).null) func.call(pointerof(result)) - end + {% end %} + result end @@ -245,9 +270,9 @@ module Crystal def initialize(@program : Program, @node : ASTNode, @single_module : Bool = false, @debug = Debug::Default, - @frame_pointers : FramePointers = :auto) + @frame_pointers : FramePointers = :auto, + @llvm_context : LLVM::Context = LLVM::Context.new) @abi = @program.target_machine.abi - @llvm_context = LLVM::Context.new # LLVM::Context.register(@llvm_context, "main") @llvm_mod = @llvm_context.new_module("main_module") @main_mod = @llvm_mod diff --git a/src/llvm/lib_llvm/lljit.cr b/src/llvm/lib_llvm/lljit.cr index 640973024af4..93c2089c9db0 100644 --- a/src/llvm/lib_llvm/lljit.cr +++ b/src/llvm/lib_llvm/lljit.cr @@ -11,6 +11,7 @@ lib LibLLVM fun orc_dispose_lljit = LLVMOrcDisposeLLJIT(j : OrcLLJITRef) : ErrorRef fun orc_lljit_get_main_jit_dylib = LLVMOrcLLJITGetMainJITDylib(j : OrcLLJITRef) : OrcJITDylibRef + fun orc_lljit_get_global_prefix = LLVMOrcLLJITGetGlobalPrefix(j : OrcLLJITRef) : Char 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 diff --git a/src/llvm/orc/jit_dylib.cr b/src/llvm/orc/jit_dylib.cr index 929dc5e5e6a4..b1050725110b 100644 --- a/src/llvm/orc/jit_dylib.cr +++ b/src/llvm/orc/jit_dylib.cr @@ -9,8 +9,8 @@ class LLVM::Orc::JITDylib @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) + def link_symbols_from_current_process(global_prefix : Char) : Nil + LLVM.assert LibLLVM.orc_create_dynamic_library_search_generator_for_process(out dg, global_prefix.ord.to_u8, nil, nil) LibLLVM.orc_jit_dylib_add_generator(self, dg) end end diff --git a/src/llvm/orc/lljit.cr b/src/llvm/orc/lljit.cr index 6271dea6ea56..62fcc7f0519f 100644 --- a/src/llvm/orc/lljit.cr +++ b/src/llvm/orc/lljit.cr @@ -30,6 +30,10 @@ class LLVM::Orc::LLJIT JITDylib.new(LibLLVM.orc_lljit_get_main_jit_dylib(self)) end + def global_prefix : Char + LibLLVM.orc_lljit_get_global_prefix(self).unsafe_chr + 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)