3 #ifndef LLVM_EXECUTIONENGINE_ORC_RPCCHANNEL_H
4 #define LLVM_EXECUTIONENGINE_ORC_RPCCHANNEL_H
7 #include "llvm/ADT/ArrayRef.h"
8 #include "llvm/Support/Endian.h"
10 #include <system_error>
17 /// Interface for byte-streams to be used with RPC.
20 virtual ~RPCChannel() {}
22 /// Read Size bytes from the stream into *Dst.
23 virtual std::error_code readBytes(char *Dst, unsigned Size) = 0;
25 /// Read size bytes from *Src and append them to the stream.
26 virtual std::error_code appendBytes(const char *Src, unsigned Size) = 0;
28 /// Flush the stream if possible.
29 virtual std::error_code send() = 0;
32 /// RPC channel that reads from and writes from file descriptors.
33 class FDRPCChannel : public RPCChannel {
35 FDRPCChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {}
37 std::error_code readBytes(char *Dst, unsigned Size) override {
38 assert(Dst && "Attempt to read into null.");
39 ssize_t ReadResult = ::read(InFD, Dst, Size);
40 if (ReadResult != Size)
41 return std::error_code(errno, std::generic_category());
42 return std::error_code();
45 std::error_code appendBytes(const char *Src, unsigned Size) override {
46 assert(Src && "Attempt to append from null.");
47 ssize_t WriteResult = ::write(OutFD, Src, Size);
48 if (WriteResult != Size)
49 std::error_code(errno, std::generic_category());
50 return std::error_code();
53 std::error_code send() override { return std::error_code(); }
59 /// RPC channel serialization for a variadic list of arguments.
60 template <typename T, typename... Ts>
61 std::error_code serialize_seq(RPCChannel &C, const T &Arg, const Ts &... Args) {
62 if (auto EC = serialize(C, Arg))
64 return serialize_seq(C, Args...);
67 /// RPC channel serialization for an (empty) variadic list of arguments.
68 inline std::error_code serialize_seq(RPCChannel &C) {
69 return std::error_code();
72 /// RPC channel deserialization for a variadic list of arguments.
73 template <typename T, typename... Ts>
74 std::error_code deserialize_seq(RPCChannel &C, T &Arg, Ts &... Args) {
75 if (auto EC = deserialize(C, Arg))
77 return deserialize_seq(C, Args...);
80 /// RPC channel serialization for an (empty) variadic list of arguments.
81 inline std::error_code deserialize_seq(RPCChannel &C) {
82 return std::error_code();
85 /// RPC channel serialization for integer primitives.
87 typename std::enable_if<
88 std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
89 std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
90 std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
91 std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value,
92 std::error_code>::type
93 serialize(RPCChannel &C, T V) {
94 support::endian::byte_swap<T, support::big>(V);
95 return C.appendBytes(reinterpret_cast<const char *>(&V), sizeof(T));
98 /// RPC channel deserialization for integer primitives.
100 typename std::enable_if<
101 std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
102 std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
103 std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
104 std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value,
105 std::error_code>::type
106 deserialize(RPCChannel &C, T &V) {
107 if (auto EC = C.readBytes(reinterpret_cast<char *>(&V), sizeof(T)))
109 support::endian::byte_swap<T, support::big>(V);
110 return std::error_code();
113 /// RPC channel serialization for enums.
114 template <typename T>
115 typename std::enable_if<std::is_enum<T>::value, std::error_code>::type
116 serialize(RPCChannel &C, T V) {
117 return serialize(C, static_cast<typename std::underlying_type<T>::type>(V));
120 /// RPC channel deserialization for enums.
121 template <typename T>
122 typename std::enable_if<std::is_enum<T>::value, std::error_code>::type
123 deserialize(RPCChannel &C, T &V) {
124 typename std::underlying_type<T>::type Tmp;
125 std::error_code EC = deserialize(C, Tmp);
126 V = static_cast<T>(Tmp);
130 /// RPC channel serialization for bools.
131 inline std::error_code serialize(RPCChannel &C, bool V) {
132 uint8_t VN = V ? 1 : 0;
133 return C.appendBytes(reinterpret_cast<const char *>(&VN), 1);
136 /// RPC channel deserialization for bools.
137 inline std::error_code deserialize(RPCChannel &C, bool &V) {
139 if (auto EC = C.readBytes(reinterpret_cast<char *>(&VN), 1))
142 V = (VN != 0) ? true : false;
143 return std::error_code();
146 /// RPC channel serialization for StringRefs.
147 /// Note: There is no corresponding deseralization for this, as StringRef
148 /// doesn't own its memory and so can't hold the deserialized data.
149 inline std::error_code serialize(RPCChannel &C, StringRef S) {
150 if (auto EC = serialize(C, static_cast<uint64_t>(S.size())))
152 return C.appendBytes((const char *)S.bytes_begin(), S.size());
155 /// RPC channel serialization for std::strings.
156 inline std::error_code serialize(RPCChannel &C, const std::string &S) {
157 return serialize(C, StringRef(S));
160 /// RPC channel deserialization for std::strings.
161 inline std::error_code deserialize(RPCChannel &C, std::string &S) {
163 if (auto EC = deserialize(C, Count))
166 return C.readBytes(&S[0], Count);
169 /// RPC channel serialization for ArrayRef<T>.
170 template <typename T>
171 std::error_code serialize(RPCChannel &C, const ArrayRef<T> &A) {
172 if (auto EC = serialize(C, static_cast<uint64_t>(A.size())))
175 for (const auto &E : A)
176 if (auto EC = serialize(C, E))
179 return std::error_code();
182 /// RPC channel serialization for std::array<T>.
183 template <typename T>
184 std::error_code serialize(RPCChannel &C, const std::vector<T> &V) {
185 return serialize(C, ArrayRef<T>(V));
188 /// RPC channel deserialization for std::array<T>.
189 template <typename T>
190 std::error_code deserialize(RPCChannel &C, std::vector<T> &V) {
192 if (auto EC = deserialize(C, Count))
197 if (auto EC = deserialize(C, E))
200 return std::error_code();
203 } // end namespace remote
204 } // end namespace orc
205 } // end namespace llvm