private void SetupReversePinvokeCalls(LLVMModuleRef pModule) { _dynamicTypes.Clear(); Dictionary <IntPtr, string> mapping = new Dictionary <IntPtr, string>(); var func = LLVM.GetFirstFunction(pModule); do { var attribute = LLVM.GetStringAttributeAtIndex(func, LLVMAttributeIndex.LLVMAttributeFunctionIndex, "external", 8); if (attribute.Pointer != IntPtr.Zero) { //Store the assembly in a dictionary since it seems like accessing the same attribute twice doesn't work? string location; if (!mapping.ContainsKey(attribute.Pointer)) { location = LLVM.GetStringAttributeValue(attribute, out uint length); mapping.Add(attribute.Pointer, location); } else { location = mapping[attribute.Pointer]; } var methodInfo = Utils.KeyAnnotations.ParseExternalAnnotation(location, func); var type = CreateDynamicDelegate(methodInfo); _dynamicTypes.Add(type); var del = methodInfo.CreateDelegate(type); _delegates.Add(del); LLVM.AddGlobalMapping(_engine, func, Marshal.GetFunctionPointerForDelegate(del)); } func = func.GetNextFunction(); } while (func.Pointer != IntPtr.Zero); }
///<summary>Runs the LLVM IR by compiling it and using the given function pointers</summary> public void Run(IReadOnlyDictionary <string, IntPtr> env) { LLVM.BuildRetVoid(Generator.Builder); if (LLVM.VerifyModule(Generator.Module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out var error) != new LLVMBool(0)) { Console.WriteLine($"Error in State.Module: {error}"); } LLVM.LinkInMCJIT(); LLVM.InitializeX86TargetMC(); LLVM.InitializeX86Target(); LLVM.InitializeX86TargetInfo(); LLVM.InitializeX86AsmParser(); LLVM.InitializeX86AsmPrinter(); var options = new LLVMMCJITCompilerOptions { NoFramePointerElim = 1 }; LLVM.InitializeMCJITCompilerOptions(options); if (LLVM.CreateMCJITCompilerForModule(out var engine, Generator.Module, options, out error) != new LLVMBool(0)) { Console.WriteLine($"JIT init error: {error}"); } foreach (var fn in env) { LLVM.AddGlobalMapping(engine, Generator.KnownFunctions[fn.Key], fn.Value); } var jitty = (JitEntryPoint)Marshal.GetDelegateForFunctionPointer(LLVM.GetPointerToGlobal(engine, Generator.EntryPoint), typeof(JitEntryPoint)); //LLVM.DumpModule(Generator.Module); var s = Stopwatch.StartNew(); Console.WriteLine("Call into JITted code..."); jitty(); var t = s.ElapsedMilliseconds; Console.WriteLine("Returned after {0} ms", t); LLVM.DisposeBuilder(Generator.Builder); LLVM.DisposeExecutionEngine(engine); }
public void AddGlobalMapping(Value global, IntPtr addr) => LLVM.AddGlobalMapping(this.Unwrap(), global.Unwrap(), addr);