#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
#include "llvm/Support/Error.h"
#include <atomic>
#include <mutex>
#include <string>
#include <thread>
namespace llvm {
namespace orc {
namespace SimpleRemoteEPCDefaultBootstrapSymbolNames {
extern const char *ExecutorSessionObjectName;
extern const char *DispatchFnName;
}
enum class SimpleRemoteEPCOpcode : uint8_t {
Setup,
Hangup,
Result,
CallWrapper,
LastOpC = CallWrapper
};
struct SimpleRemoteEPCExecutorInfo {
std::string TargetTriple;
uint64_t PageSize;
StringMap<ExecutorAddr> BootstrapSymbols;
};
using SimpleRemoteEPCArgBytesVector = SmallVector<char, 128>;
class SimpleRemoteEPCTransportClient {
public:
enum HandleMessageAction { ContinueSession, EndSession };
virtual ~SimpleRemoteEPCTransportClient();
virtual Expected<HandleMessageAction>
handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
SimpleRemoteEPCArgBytesVector ArgBytes) = 0;
virtual void handleDisconnect(Error Err) = 0;
};
class SimpleRemoteEPCTransport {
public:
virtual ~SimpleRemoteEPCTransport();
virtual Error start() = 0;
virtual Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) = 0;
virtual void disconnect() = 0;
};
class FDSimpleRemoteEPCTransport : public SimpleRemoteEPCTransport {
public:
static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
Create(SimpleRemoteEPCTransportClient &C, int InFD, int OutFD);
static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
Create(SimpleRemoteEPCTransportClient &C, int FD) {
return Create(C, FD, FD);
}
~FDSimpleRemoteEPCTransport() override;
Error start() override;
Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) override;
void disconnect() override;
private:
FDSimpleRemoteEPCTransport(SimpleRemoteEPCTransportClient &C, int InFD,
int OutFD)
: C(C), InFD(InFD), OutFD(OutFD) {}
Error readBytes(char *Dst, size_t Size, bool *IsEOF = nullptr);
int writeBytes(const char *Src, size_t Size);
void listenLoop();
std::mutex M;
SimpleRemoteEPCTransportClient &C;
std::thread ListenerThread;
int InFD, OutFD;
std::atomic<bool> Disconnected{false};
};
struct RemoteSymbolLookupSetElement {
std::string Name;
bool Required;
};
using RemoteSymbolLookupSet = std::vector<RemoteSymbolLookupSetElement>;
struct RemoteSymbolLookup {
uint64_t H;
RemoteSymbolLookupSet Symbols;
};
namespace shared {
using SPSRemoteSymbolLookupSetElement = SPSTuple<SPSString, bool>;
using SPSRemoteSymbolLookupSet = SPSSequence<SPSRemoteSymbolLookupSetElement>;
using SPSRemoteSymbolLookup = SPSTuple<uint64_t, SPSRemoteSymbolLookupSet>;
using SPSSimpleRemoteEPCExecutorInfo =
SPSTuple<SPSString, uint64_t,
SPSSequence<SPSTuple<SPSString, SPSExecutorAddr>>>;
template <>
class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
RemoteSymbolLookupSetElement> {
public:
static size_t size(const RemoteSymbolLookupSetElement &V) {
return SPSArgList<SPSString, bool>::size(V.Name, V.Required);
}
static size_t serialize(SPSOutputBuffer &OB,
const RemoteSymbolLookupSetElement &V) {
return SPSArgList<SPSString, bool>::serialize(OB, V.Name, V.Required);
}
static size_t deserialize(SPSInputBuffer &IB,
RemoteSymbolLookupSetElement &V) {
return SPSArgList<SPSString, bool>::deserialize(IB, V.Name, V.Required);
}
};
template <>
class SPSSerializationTraits<SPSRemoteSymbolLookup, RemoteSymbolLookup> {
public:
static size_t size(const RemoteSymbolLookup &V) {
return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::size(V.H, V.Symbols);
}
static size_t serialize(SPSOutputBuffer &OB, const RemoteSymbolLookup &V) {
return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::serialize(OB, V.H,
V.Symbols);
}
static size_t deserialize(SPSInputBuffer &IB, RemoteSymbolLookup &V) {
return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::deserialize(
IB, V.H, V.Symbols);
}
};
template <>
class SPSSerializationTraits<SPSSimpleRemoteEPCExecutorInfo,
SimpleRemoteEPCExecutorInfo> {
public:
static size_t size(const SimpleRemoteEPCExecutorInfo &SI) {
return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::size(
SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
}
static bool serialize(SPSOutputBuffer &OB,
const SimpleRemoteEPCExecutorInfo &SI) {
return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::serialize(
OB, SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
}
static bool deserialize(SPSInputBuffer &IB, SimpleRemoteEPCExecutorInfo &SI) {
return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::deserialize(
IB, SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
}
};
using SPSLoadDylibSignature = SPSExpected<SPSExecutorAddr>(SPSExecutorAddr,
SPSString, uint64_t);
using SPSLookupSymbolsSignature =
SPSExpected<SPSSequence<SPSSequence<SPSExecutorAddr>>>(
SPSExecutorAddr, SPSSequence<SPSRemoteSymbolLookup>);
} } }
#endif