//===- executionengine.go - Bindings for executionengine ------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines bindings for the executionengine component. // //===----------------------------------------------------------------------===// package llvm /* #include "llvm-c/Core.h" #include "llvm-c/ExecutionEngine.h" #include */ import "C" import "unsafe" import "errors" func LinkInMCJIT() { C.LLVMLinkInMCJIT() } func LinkInInterpreter() { C.LLVMLinkInInterpreter() } type GenericValue struct { C C.LLVMGenericValueRef } type ExecutionEngine struct { C C.LLVMExecutionEngineRef } type MCJITCompilerOptions struct { C C.struct_LLVMMCJITCompilerOptions } func (options *MCJITCompilerOptions) SetMCJITOptimizationLevel(level uint) { options.C.OptLevel = C.uint(level) } func (options *MCJITCompilerOptions) SetMCJITNoFramePointerElim(nfp bool) { options.C.NoFramePointerElim = boolToLLVMBool(nfp) } func (options *MCJITCompilerOptions) SetMCJITEnableFastISel(fastisel bool) { options.C.EnableFastISel = boolToLLVMBool(fastisel) } func (options *MCJITCompilerOptions) SetMCJITCodeModel(CodeModel CodeModel) { options.C.CodeModel = C.LLVMCodeModel(CodeModel) } // helpers func llvmGenericValueRefPtr(t *GenericValue) *C.LLVMGenericValueRef { return (*C.LLVMGenericValueRef)(unsafe.Pointer(t)) } //------------------------------------------------------------------------- // llvm.GenericValue //------------------------------------------------------------------------- func NewGenericValueFromInt(t Type, n uint64, signed bool) (g GenericValue) { g.C = C.LLVMCreateGenericValueOfInt(t.C, C.ulonglong(n), boolToLLVMBool(signed)) return } func NewGenericValueFromPointer(p unsafe.Pointer) (g GenericValue) { g.C = C.LLVMCreateGenericValueOfPointer(p) return } func NewGenericValueFromFloat(t Type, n float64) (g GenericValue) { g.C = C.LLVMCreateGenericValueOfFloat(t.C, C.double(n)) return } func (g GenericValue) IntWidth() int { return int(C.LLVMGenericValueIntWidth(g.C)) } func (g GenericValue) Int(signed bool) uint64 { return uint64(C.LLVMGenericValueToInt(g.C, boolToLLVMBool(signed))) } func (g GenericValue) Float(t Type) float64 { return float64(C.LLVMGenericValueToFloat(t.C, g.C)) } func (g GenericValue) Pointer() unsafe.Pointer { return C.LLVMGenericValueToPointer(g.C) } func (g GenericValue) Dispose() { C.LLVMDisposeGenericValue(g.C) } //------------------------------------------------------------------------- // llvm.ExecutionEngine //------------------------------------------------------------------------- func NewExecutionEngine(m Module) (ee ExecutionEngine, err error) { var cmsg *C.char fail := C.LLVMCreateExecutionEngineForModule(&ee.C, m.C, &cmsg) if fail != 0 { ee.C = nil err = errors.New(C.GoString(cmsg)) C.LLVMDisposeMessage(cmsg) } return } func NewInterpreter(m Module) (ee ExecutionEngine, err error) { var cmsg *C.char fail := C.LLVMCreateInterpreterForModule(&ee.C, m.C, &cmsg) if fail != 0 { ee.C = nil err = errors.New(C.GoString(cmsg)) C.LLVMDisposeMessage(cmsg) } return } func NewMCJITCompilerOptions() MCJITCompilerOptions { var options C.struct_LLVMMCJITCompilerOptions C.LLVMInitializeMCJITCompilerOptions(&options, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{}))) return MCJITCompilerOptions{options} } func NewMCJITCompiler(m Module, options MCJITCompilerOptions) (ee ExecutionEngine, err error) { var cmsg *C.char fail := C.LLVMCreateMCJITCompilerForModule(&ee.C, m.C, &options.C, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{})), &cmsg) if fail != 0 { ee.C = nil err = errors.New(C.GoString(cmsg)) C.LLVMDisposeMessage(cmsg) } return } func (ee ExecutionEngine) Dispose() { C.LLVMDisposeExecutionEngine(ee.C) } func (ee ExecutionEngine) RunStaticConstructors() { C.LLVMRunStaticConstructors(ee.C) } func (ee ExecutionEngine) RunStaticDestructors() { C.LLVMRunStaticDestructors(ee.C) } func (ee ExecutionEngine) RunFunction(f Value, args []GenericValue) (g GenericValue) { nargs := len(args) var argptr *GenericValue if nargs > 0 { argptr = &args[0] } g.C = C.LLVMRunFunction(ee.C, f.C, C.unsigned(nargs), llvmGenericValueRefPtr(argptr)) return } func (ee ExecutionEngine) FreeMachineCodeForFunction(f Value) { C.LLVMFreeMachineCodeForFunction(ee.C, f.C) } func (ee ExecutionEngine) AddModule(m Module) { C.LLVMAddModule(ee.C, m.C) } func (ee ExecutionEngine) RemoveModule(m Module) { var modtmp C.LLVMModuleRef C.LLVMRemoveModule(ee.C, m.C, &modtmp, nil) } func (ee ExecutionEngine) FindFunction(name string) (f Value) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) C.LLVMFindFunction(ee.C, cname, &f.C) return } func (ee ExecutionEngine) RecompileAndRelinkFunction(f Value) unsafe.Pointer { return C.LLVMRecompileAndRelinkFunction(ee.C, f.C) } func (ee ExecutionEngine) TargetData() (td TargetData) { td.C = C.LLVMGetExecutionEngineTargetData(ee.C) return } func (ee ExecutionEngine) AddGlobalMapping(global Value, addr unsafe.Pointer) { C.LLVMAddGlobalMapping(ee.C, global.C, addr) } func (ee ExecutionEngine) PointerToGlobal(global Value) unsafe.Pointer { return C.LLVMGetPointerToGlobal(ee.C, global.C) }