/// <inheritdoc/> public void Dispose( ) { if (EngineHandle != default) { LLVMDisposeExecutionEngine(EngineHandle); } OwnedModules.Clear( ); EngineHandle = default; }
/// <summary>Add a module to the engine</summary> /// <param name="module">The module to add to the engine</param> /// <remarks> /// <note type="warning"> /// The input <paramref name="module"/> is disconnected from the underlying LLVM /// module as the module is considered fully owned by the engine. Thus, upon return /// the <see cref="BitcodeModule.IsDisposed"/> property is <see langword="true"/> /// </note> /// </remarks> /// <returns>Handle for the module in the engine</returns> public int AddModule(BitcodeModule module) { int handle = System.Threading.Interlocked.Increment(ref NextHandleValue) - 1; lock ( OwnedModules ) { OwnedModules.Add(handle, module.ModuleHandle); } if (handle == 0) { CreateEngine(module); } LLVMAddModule(EngineHandle, module.ModuleHandle); module.Detach( ); return(handle); }
/// <summary>Removes a module from the engine</summary> /// <param name="handle"><see cref="AddModule(BitcodeModule)"/> to remove</param> /// <remarks> /// This effectively transfers ownership of the module back to the caller. /// </remarks> public void RemoveModule(int handle) { if (!OwnedModules.TryGetValue(handle, out LLVMModuleRef module)) { throw new ArgumentException("Unknown handle value"); } // Current LLVM-C API is a bit brain dead on this one. The return is hardcoded to 0 // and the out error message is never used. Furthermore, the return from the C++ // ExecutionEngine::removeModule() is ultimately ignored. if (LLVMRemoveModule(EngineHandle, module, out LLVMModuleRef baseModule, out string errMsg).Failed) { throw new InternalCodeGeneratorException("Failed to remove module from engine"); } // MCJIT engine doesn't cleanup after a remove LLVMExecutionEngineClearGlobalMappingsFromModule(EngineHandle, baseModule); LLVMDisposeModule(module); }