//===- EPCGenericMemoryAccess.h - Generic EPC MemoryAccess impl -*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// // // Implements the MemoryAccess interface by making calls to // ExecutorProcessControl::callWrapperAsync. // // This simplifies the implementaton of new ExecutorProcessControl instances, // as this implementation will always work (at the cost of some performance // overhead for the calls). // //===----------------------------------------------------------------------===// #ifndef LLVM_EXECUTIONENGINE_ORC_EPCGENERICMEMORYACCESS_H #define LLVM_EXECUTIONENGINE_ORC_EPCGENERICMEMORYACCESS_H #include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/MemoryAccess.h" namespace llvm { namespace orc { class EPCGenericMemoryAccess : public MemoryAccess { public: /// Function addresses for memory access. struct FuncAddrs { ExecutorAddr WriteUInt8s; ExecutorAddr WriteUInt16s; ExecutorAddr WriteUInt32s; ExecutorAddr WriteUInt64s; ExecutorAddr WritePointers; ExecutorAddr WriteBuffers; ExecutorAddr ReadUInt8s; ExecutorAddr ReadUInt16s; ExecutorAddr ReadUInt32s; ExecutorAddr ReadUInt64s; ExecutorAddr ReadPointers; ExecutorAddr ReadBuffers; ExecutorAddr ReadStrings; }; /// Create an EPCGenericMemoryAccess instance from a given set of /// function addrs. EPCGenericMemoryAccess(ExecutorProcessControl &EPC, FuncAddrs FAs) : EPC(EPC), FAs(FAs) {} void writeUInt8sAsync(ArrayRef Ws, WriteResultFn OnWriteComplete) override { using namespace shared; EPC.callSPSWrapperAsync)>( FAs.WriteUInt8s, std::move(OnWriteComplete), Ws); } void writeUInt16sAsync(ArrayRef Ws, WriteResultFn OnWriteComplete) override { using namespace shared; EPC.callSPSWrapperAsync)>( FAs.WriteUInt16s, std::move(OnWriteComplete), Ws); } void writeUInt32sAsync(ArrayRef Ws, WriteResultFn OnWriteComplete) override { using namespace shared; EPC.callSPSWrapperAsync)>( FAs.WriteUInt32s, std::move(OnWriteComplete), Ws); } void writeUInt64sAsync(ArrayRef Ws, WriteResultFn OnWriteComplete) override { using namespace shared; EPC.callSPSWrapperAsync)>( FAs.WriteUInt64s, std::move(OnWriteComplete), Ws); } void writePointersAsync(ArrayRef Ws, WriteResultFn OnWriteComplete) override { using namespace shared; EPC.callSPSWrapperAsync)>( FAs.WritePointers, std::move(OnWriteComplete), Ws); } void writeBuffersAsync(ArrayRef Ws, WriteResultFn OnWriteComplete) override { using namespace shared; EPC.callSPSWrapperAsync)>( FAs.WriteBuffers, std::move(OnWriteComplete), Ws); } void readUInt8sAsync(ArrayRef Rs, OnReadUIntsCompleteFn OnComplete) override { using namespace shared; EPC.callSPSWrapperAsync(SPSSequence)>( FAs.ReadUInt8s, [OnComplete = std::move(OnComplete)]( Error Err, ReadUIntsResult Result) mutable { if (Err) OnComplete(std::move(Err)); else OnComplete(std::move(Result)); }, Rs); } void readUInt16sAsync(ArrayRef Rs, OnReadUIntsCompleteFn OnComplete) override { using namespace shared; EPC.callSPSWrapperAsync( SPSSequence)>( FAs.ReadUInt16s, [OnComplete = std::move(OnComplete)]( Error Err, ReadUIntsResult Result) mutable { if (Err) OnComplete(std::move(Err)); else OnComplete(std::move(Result)); }, Rs); } void readUInt32sAsync(ArrayRef Rs, OnReadUIntsCompleteFn OnComplete) override { using namespace shared; EPC.callSPSWrapperAsync( SPSSequence)>( FAs.ReadUInt32s, [OnComplete = std::move(OnComplete)]( Error Err, ReadUIntsResult Result) mutable { if (Err) OnComplete(std::move(Err)); else OnComplete(std::move(Result)); }, Rs); } void readUInt64sAsync(ArrayRef Rs, OnReadUIntsCompleteFn OnComplete) override { using namespace shared; EPC.callSPSWrapperAsync( SPSSequence)>( FAs.ReadUInt64s, [OnComplete = std::move(OnComplete)]( Error Err, ReadUIntsResult Result) mutable { if (Err) OnComplete(std::move(Err)); else OnComplete(std::move(Result)); }, Rs); } void readPointersAsync(ArrayRef Rs, OnReadPointersCompleteFn OnComplete) override { using namespace shared; using SPSSig = SPSSequence(SPSSequence); EPC.callSPSWrapperAsync( FAs.ReadPointers, [OnComplete = std::move(OnComplete)]( Error Err, ReadPointersResult Result) mutable { if (Err) OnComplete(std::move(Err)); else OnComplete(std::move(Result)); }, Rs); } void readBuffersAsync(ArrayRef Rs, OnReadBuffersCompleteFn OnComplete) override { using namespace shared; using SPSSig = SPSSequence>(SPSSequence); EPC.callSPSWrapperAsync( FAs.ReadBuffers, [OnComplete = std::move(OnComplete)](Error Err, ReadBuffersResult Result) mutable { if (Err) OnComplete(std::move(Err)); else OnComplete(std::move(Result)); }, Rs); } void readStringsAsync(ArrayRef Rs, OnReadStringsCompleteFn OnComplete) override { using namespace shared; using SPSSig = SPSSequence(SPSSequence); EPC.callSPSWrapperAsync( FAs.ReadStrings, [OnComplete = std::move(OnComplete)](Error Err, ReadStringsResult Result) mutable { if (Err) OnComplete(std::move(Err)); else OnComplete(std::move(Result)); }, Rs); } private: ExecutorProcessControl &EPC; FuncAddrs FAs; }; } // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_EPCGENERICMEMORYACCESS_H