Line data Source code
1 : //===- llvm/ExecutionEngine/Orc/RPCSerialization.h --------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
11 : #define LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
12 :
13 : #include "OrcError.h"
14 : #include "llvm/Support/thread.h"
15 : #include <map>
16 : #include <mutex>
17 : #include <set>
18 : #include <sstream>
19 : #include <string>
20 : #include <vector>
21 :
22 : namespace llvm {
23 : namespace orc {
24 : namespace rpc {
25 :
26 : template <typename T>
27 : class RPCTypeName;
28 :
29 : /// TypeNameSequence is a utility for rendering sequences of types to a string
30 : /// by rendering each type, separated by ", ".
31 : template <typename... ArgTs> class RPCTypeNameSequence {};
32 :
33 : /// Render an empty TypeNameSequence to an ostream.
34 : template <typename OStream>
35 0 : OStream &operator<<(OStream &OS, const RPCTypeNameSequence<> &V) {
36 0 : return OS;
37 : }
38 :
39 : /// Render a TypeNameSequence of a single type to an ostream.
40 : template <typename OStream, typename ArgT>
41 0 : OStream &operator<<(OStream &OS, const RPCTypeNameSequence<ArgT> &V) {
42 464 : OS << RPCTypeName<ArgT>::getName();
43 0 : return OS;
44 : }
45 0 :
46 0 : /// Render a TypeNameSequence of more than one type to an ostream.
47 0 : template <typename OStream, typename ArgT1, typename ArgT2, typename... ArgTs>
48 : OStream&
49 0 : operator<<(OStream &OS, const RPCTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
50 0 : OS << RPCTypeName<ArgT1>::getName() << ", "
51 0 : << RPCTypeNameSequence<ArgT2, ArgTs...>();
52 : return OS;
53 0 : }
54 0 :
55 0 : template <>
56 : class RPCTypeName<void> {
57 0 : public:
58 0 : static const char* getName() { return "void"; }
59 0 : };
60 :
61 0 : template <>
62 0 : class RPCTypeName<int8_t> {
63 0 : public:
64 : static const char* getName() { return "int8_t"; }
65 0 : };
66 0 :
67 0 : template <>
68 0 : class RPCTypeName<uint8_t> {
69 0 : public:
70 0 : static const char* getName() { return "uint8_t"; }
71 0 : };
72 0 :
73 0 : template <>
74 0 : class RPCTypeName<int16_t> {
75 0 : public:
76 0 : static const char* getName() { return "int16_t"; }
77 0 : };
78 0 :
79 0 : template <>
80 0 : class RPCTypeName<uint16_t> {
81 0 : public:
82 0 : static const char* getName() { return "uint16_t"; }
83 0 : };
84 0 :
85 0 : template <>
86 0 : class RPCTypeName<int32_t> {
87 0 : public:
88 0 : static const char* getName() { return "int32_t"; }
89 0 : };
90 0 :
91 0 : template <>
92 0 : class RPCTypeName<uint32_t> {
93 0 : public:
94 0 : static const char* getName() { return "uint32_t"; }
95 0 : };
96 0 :
97 0 : template <>
98 0 : class RPCTypeName<int64_t> {
99 0 : public:
100 0 : static const char* getName() { return "int64_t"; }
101 0 : };
102 0 :
103 0 : template <>
104 0 : class RPCTypeName<uint64_t> {
105 0 : public:
106 0 : static const char* getName() { return "uint64_t"; }
107 0 : };
108 0 :
109 0 : template <>
110 0 : class RPCTypeName<bool> {
111 0 : public:
112 0 : static const char* getName() { return "bool"; }
113 0 : };
114 0 :
115 0 : template <>
116 0 : class RPCTypeName<std::string> {
117 : public:
118 0 : static const char* getName() { return "std::string"; }
119 0 : };
120 0 :
121 0 : template <>
122 : class RPCTypeName<Error> {
123 0 : public:
124 0 : static const char* getName() { return "Error"; }
125 0 : };
126 0 :
127 : template <typename T>
128 0 : class RPCTypeName<Expected<T>> {
129 0 : public:
130 0 : static const char* getName() {
131 0 : std::lock_guard<std::mutex> Lock(NameMutex);
132 : if (Name.empty())
133 0 : raw_string_ostream(Name) << "Expected<"
134 0 : << RPCTypeNameSequence<T>()
135 0 : << ">";
136 0 : return Name.data();
137 : }
138 0 :
139 0 : private:
140 0 : static std::mutex NameMutex;
141 0 : static std::string Name;
142 : };
143 :
144 : template <typename T>
145 : std::mutex RPCTypeName<Expected<T>>::NameMutex;
146 :
147 : template <typename T>
148 : std::string RPCTypeName<Expected<T>>::Name;
149 :
150 : template <typename T1, typename T2>
151 : class RPCTypeName<std::pair<T1, T2>> {
152 : public:
153 : static const char* getName() {
154 : std::lock_guard<std::mutex> Lock(NameMutex);
155 : if (Name.empty())
156 : raw_string_ostream(Name) << "std::pair<" << RPCTypeNameSequence<T1, T2>()
157 : << ">";
158 : return Name.data();
159 : }
160 : private:
161 : static std::mutex NameMutex;
162 : static std::string Name;
163 : };
164 :
165 : template <typename T1, typename T2>
166 : std::mutex RPCTypeName<std::pair<T1, T2>>::NameMutex;
167 : template <typename T1, typename T2>
168 : std::string RPCTypeName<std::pair<T1, T2>>::Name;
169 :
170 48 : template <typename... ArgTs>
171 : class RPCTypeName<std::tuple<ArgTs...>> {
172 48 : public:
173 : static const char* getName() {
174 32 : std::lock_guard<std::mutex> Lock(NameMutex);
175 16 : if (Name.empty())
176 48 : raw_string_ostream(Name) << "std::tuple<"
177 : << RPCTypeNameSequence<ArgTs...>() << ">";
178 16 : return Name.data();
179 : }
180 16 : private:
181 : static std::mutex NameMutex;
182 16 : static std::string Name;
183 8 : };
184 16 :
185 : template <typename... ArgTs>
186 32 : std::mutex RPCTypeName<std::tuple<ArgTs...>>::NameMutex;
187 : template <typename... ArgTs>
188 32 : std::string RPCTypeName<std::tuple<ArgTs...>>::Name;
189 :
190 16 : template <typename T>
191 8 : class RPCTypeName<std::vector<T>> {
192 32 : public:
193 : static const char*getName() {
194 : std::lock_guard<std::mutex> Lock(NameMutex);
195 : if (Name.empty())
196 : raw_string_ostream(Name) << "std::vector<" << RPCTypeName<T>::getName()
197 : << ">";
198 : return Name.data();
199 : }
200 :
201 : private:
202 : static std::mutex NameMutex;
203 : static std::string Name;
204 : };
205 :
206 : template <typename T>
207 : std::mutex RPCTypeName<std::vector<T>>::NameMutex;
208 : template <typename T>
209 8 : std::string RPCTypeName<std::vector<T>>::Name;
210 :
211 8 : template <typename T> class RPCTypeName<std::set<T>> {
212 16 : public:
213 8 : static const char *getName() {
214 8 : std::lock_guard<std::mutex> Lock(NameMutex);
215 : if (Name.empty())
216 : raw_string_ostream(Name)
217 : << "std::set<" << RPCTypeName<T>::getName() << ">";
218 : return Name.data();
219 2 : }
220 :
221 2 : private:
222 : static std::mutex NameMutex;
223 4 : static std::string Name;
224 26 : };
225 2 :
226 24 : template <typename T> std::mutex RPCTypeName<std::set<T>>::NameMutex;
227 : template <typename T> std::string RPCTypeName<std::set<T>>::Name;
228 24 :
229 24 : template <typename K, typename V> class RPCTypeName<std::map<K, V>> {
230 : public:
231 0 : static const char *getName() {
232 : std::lock_guard<std::mutex> Lock(NameMutex);
233 72 : if (Name.empty())
234 : raw_string_ostream(Name)
235 72 : << "std::map<" << RPCTypeNameSequence<K, V>() << ">";
236 0 : return Name.data();
237 72 : }
238 72 :
239 : private:
240 24 : static std::mutex NameMutex;
241 : static std::string Name;
242 24 : };
243 0 :
244 24 : template <typename K, typename V>
245 48 : std::mutex RPCTypeName<std::map<K, V>>::NameMutex;
246 : template <typename K, typename V> std::string RPCTypeName<std::map<K, V>>::Name;
247 48 :
248 : /// The SerializationTraits<ChannelT, T> class describes how to serialize and
249 48 : /// deserialize an instance of type T to/from an abstract channel of type
250 24 : /// ChannelT. It also provides a representation of the type's name via the
251 24 : /// getName method.
252 24 : ///
253 : /// Specializations of this class should provide the following functions:
254 24 : ///
255 : /// @code{.cpp}
256 24 : ///
257 : /// static const char* getName();
258 24 : /// static Error serialize(ChannelT&, const T&);
259 24 : /// static Error deserialize(ChannelT&, T&);
260 : ///
261 : /// @endcode
262 : ///
263 : /// The third argument of SerializationTraits is intended to support SFINAE.
264 : /// E.g.:
265 : ///
266 : /// @code{.cpp}
267 : ///
268 : /// class MyVirtualChannel { ... };
269 : ///
270 : /// template <DerivedChannelT>
271 : /// class SerializationTraits<DerivedChannelT, bool,
272 : /// typename std::enable_if<
273 : /// std::is_base_of<VirtChannel, DerivedChannel>::value
274 48 : /// >::type> {
275 : /// public:
276 48 : /// static const char* getName() { ... };
277 96 : /// }
278 48 : ///
279 48 : /// @endcode
280 : template <typename ChannelT, typename WireType,
281 24 : typename ConcreteType = WireType, typename = void>
282 2 : class SerializationTraits;
283 24 :
284 50 : template <typename ChannelT>
285 28 : class SequenceTraits {
286 26 : public:
287 2 : static Error emitSeparator(ChannelT &C) { return Error::success(); }
288 24 : static Error consumeSeparator(ChannelT &C) { return Error::success(); }
289 : };
290 24 :
291 48 : /// Utility class for serializing sequences of values of varying types.
292 24 : /// Specializations of this class contain 'serialize' and 'deserialize' methods
293 24 : /// for the given channel. The ArgTs... list will determine the "over-the-wire"
294 : /// types to be serialized. The serialize and deserialize methods take a list
295 : /// CArgTs... ("caller arg types") which must be the same length as ArgTs...,
296 : /// but may be different types from ArgTs, provided that for each CArgT there
297 : /// is a SerializationTraits specialization
298 : /// SerializeTraits<ChannelT, ArgT, CArgT> with methods that can serialize the
299 : /// caller argument to over-the-wire value.
300 : template <typename ChannelT, typename... ArgTs>
301 : class SequenceSerialization;
302 2 :
303 : template <typename ChannelT>
304 2 : class SequenceSerialization<ChannelT> {
305 : public:
306 2 : static Error serialize(ChannelT &C) { return Error::success(); }
307 2 : static Error deserialize(ChannelT &C) { return Error::success(); }
308 : };
309 :
310 : template <typename ChannelT, typename ArgT>
311 : class SequenceSerialization<ChannelT, ArgT> {
312 : public:
313 :
314 : template <typename CArgT>
315 : static Error serialize(ChannelT &C, CArgT &&CArg) {
316 : return SerializationTraits<ChannelT, ArgT,
317 : typename std::decay<CArgT>::type>::
318 : serialize(C, std::forward<CArgT>(CArg));
319 : }
320 2 :
321 : template <typename CArgT>
322 2 : static Error deserialize(ChannelT &C, CArgT &CArg) {
323 : return SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg);
324 2 : }
325 2 : };
326 :
327 : template <typename ChannelT, typename ArgT, typename... ArgTs>
328 : class SequenceSerialization<ChannelT, ArgT, ArgTs...> {
329 : public:
330 :
331 : template <typename CArgT, typename... CArgTs>
332 : static Error serialize(ChannelT &C, CArgT &&CArg,
333 : CArgTs &&... CArgs) {
334 : if (auto Err =
335 : SerializationTraits<ChannelT, ArgT, typename std::decay<CArgT>::type>::
336 : serialize(C, std::forward<CArgT>(CArg)))
337 : return Err;
338 : if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
339 : return Err;
340 : return SequenceSerialization<ChannelT, ArgTs...>::
341 : serialize(C, std::forward<CArgTs>(CArgs)...);
342 : }
343 0 :
344 0 : template <typename CArgT, typename... CArgTs>
345 : static Error deserialize(ChannelT &C, CArgT &CArg,
346 : CArgTs &... CArgs) {
347 : if (auto Err =
348 : SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
349 : return Err;
350 : if (auto Err = SequenceTraits<ChannelT>::consumeSeparator(C))
351 : return Err;
352 : return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, CArgs...);
353 : }
354 : };
355 :
356 : template <typename ChannelT, typename... ArgTs>
357 : Error serializeSeq(ChannelT &C, ArgTs &&... Args) {
358 : return SequenceSerialization<ChannelT, typename std::decay<ArgTs>::type...>::
359 0 : serialize(C, std::forward<ArgTs>(Args)...);
360 0 : }
361 :
362 0 : template <typename ChannelT, typename... ArgTs>
363 0 : Error deserializeSeq(ChannelT &C, ArgTs &... Args) {
364 : return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, Args...);
365 : }
366 :
367 : template <typename ChannelT>
368 : class SerializationTraits<ChannelT, Error> {
369 : public:
370 :
371 0 : using WrappedErrorSerializer =
372 : std::function<Error(ChannelT &C, const ErrorInfoBase&)>;
373 :
374 286 : using WrappedErrorDeserializer =
375 : std::function<Error(ChannelT &C, Error &Err)>;
376 0 :
377 0 : template <typename ErrorInfoT, typename SerializeFtor,
378 0 : typename DeserializeFtor>
379 0 : static void registerErrorType(std::string Name, SerializeFtor Serialize,
380 : DeserializeFtor Deserialize) {
381 0 : assert(!Name.empty() &&
382 0 : "The empty string is reserved for the Success value");
383 0 :
384 0 : const std::string *KeyName = nullptr;
385 : {
386 0 : // We're abusing the stability of std::map here: We take a reference to the
387 0 : // key of the deserializers map to save us from duplicating the string in
388 : // the serializer. This should be changed to use a stringpool if we switch
389 0 : // to a map type that may move keys in memory.
390 1353 : std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
391 0 : auto I =
392 0 : Deserializers.insert(Deserializers.begin(),
393 : std::make_pair(std::move(Name),
394 0 : std::move(Deserialize)));
395 0 : KeyName = &I->first;
396 0 : }
397 0 :
398 : {
399 0 : assert(KeyName != nullptr && "No keyname pointer");
400 0 : std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
401 0 : // FIXME: Move capture Serialize once we have C++14.
402 0 : Serializers[ErrorInfoT::classID()] =
403 : [KeyName, Serialize](ChannelT &C, const ErrorInfoBase &EIB) -> Error {
404 0 : assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
405 0 : "Serializer called for wrong error type");
406 0 : if (auto Err = serializeSeq(C, *KeyName))
407 61 : return Err;
408 : return Serialize(C, static_cast<const ErrorInfoT &>(EIB));
409 0 : };
410 0 : }
411 : }
412 0 :
413 574 : static Error serialize(ChannelT &C, Error &&Err) {
414 169 : std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
415 0 :
416 : if (!Err)
417 0 : return serializeSeq(C, std::string());
418 0 :
419 0 : return handleErrors(std::move(Err),
420 574 : [&C](const ErrorInfoBase &EIB) {
421 : auto SI = Serializers.find(EIB.dynamicClassID());
422 0 : if (SI == Serializers.end())
423 184 : return serializeAsStringError(C, EIB);
424 0 : return (SI->second)(C, EIB);
425 189 : });
426 : }
427 0 :
428 0 : static Error deserialize(ChannelT &C, Error &Err) {
429 763 : std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
430 0 :
431 763 : std::string Key;
432 184 : if (auto Err = deserializeSeq(C, Key))
433 0 : return Err;
434 3 :
435 0 : if (Key.empty()) {
436 3 : ErrorAsOutParameter EAO(&Err);
437 0 : Err = Error::success();
438 763 : return Error::success();
439 0 : }
440 526 :
441 : auto DI = Deserializers.find(Key);
442 526 : assert(DI != Deserializers.end() && "No deserializer for error type");
443 999 : return (DI->second)(C, Err);
444 0 : }
445 0 :
446 : private:
447 0 :
448 : static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
449 526 : std::string ErrMsg;
450 : {
451 116 : raw_string_ostream ErrMsgStream(ErrMsg);
452 622 : EIB.log(ErrMsgStream);
453 116 : }
454 622 : return serialize(C, make_error<StringError>(std::move(ErrMsg),
455 : inconvertibleErrorCode()));
456 2 : }
457 0 :
458 2 : static std::recursive_mutex SerializersMutex;
459 0 : static std::recursive_mutex DeserializersMutex;
460 116 : static std::map<const void*, WrappedErrorSerializer> Serializers;
461 622 : static std::map<std::string, WrappedErrorDeserializer> Deserializers;
462 0 : };
463 24 :
464 0 : template <typename ChannelT>
465 26 : std::recursive_mutex SerializationTraits<ChannelT, Error>::SerializersMutex;
466 0 :
467 109 : template <typename ChannelT>
468 : std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
469 10 :
470 0 : template <typename ChannelT>
471 0 : std::map<const void*,
472 24 : typename SerializationTraits<ChannelT, Error>::WrappedErrorSerializer>
473 121 : SerializationTraits<ChannelT, Error>::Serializers;
474 24 :
475 121 : template <typename ChannelT>
476 29 : std::map<std::string,
477 : typename SerializationTraits<ChannelT, Error>::WrappedErrorDeserializer>
478 174 : SerializationTraits<ChannelT, Error>::Deserializers;
479 :
480 174 : /// Registers a serializer and deserializer for the given error type on the
481 : /// given channel type.
482 133 : template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
483 24 : typename DeserializeFtor>
484 16 : void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
485 24 : DeserializeFtor &&Deserialize) {
486 622 : SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
487 198 : std::move(Name),
488 1244 : std::forward<SerializeFtor>(Serialize),
489 : std::forward<DeserializeFtor>(Deserialize));
490 : }
491 123 :
492 : /// Registers serialization/deserialization for StringError.
493 297 : template <typename ChannelT>
494 24 : void registerStringError() {
495 26 : static bool AlreadyRegistered = false;
496 0 : if (!AlreadyRegistered) {
497 48 : registerErrorSerialization<ChannelT, StringError>(
498 2 : "StringError",
499 : [](ChannelT &C, const StringError &SE) {
500 3 : return serializeSeq(C, SE.getMessage());
501 : },
502 30 : [](ChannelT &C, Error &Err) -> Error {
503 : ErrorAsOutParameter EAO(&Err);
504 25 : std::string Msg;
505 0 : if (auto E2 = deserializeSeq(C, Msg))
506 50 : return E2;
507 0 : Err =
508 : make_error<StringError>(std::move(Msg),
509 2 : orcError(
510 : OrcErrorCode::UnknownErrorCodeFromRemote));
511 28 : return Error::success();
512 : });
513 25 : AlreadyRegistered = true;
514 : }
515 49 : }
516 2 :
517 2 : /// SerializationTraits for Expected<T1> from an Expected<T2>.
518 555 : template <typename ChannelT, typename T1, typename T2>
519 : class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
520 584 : public:
521 :
522 0 : static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
523 : if (ValOrErr) {
524 1 : if (auto Err = serializeSeq(C, true))
525 : return Err;
526 1 : return SerializationTraits<ChannelT, T1, T2>::serialize(C, *ValOrErr);
527 550 : }
528 2 : if (auto Err = serializeSeq(C, false))
529 0 : return Err;
530 : return serializeSeq(C, ValOrErr.takeError());
531 763 : }
532 :
533 1526 : static Error deserialize(ChannelT &C, Expected<T2> &ValOrErr) {
534 : ExpectedAsOutParameter<T2> EAO(&ValOrErr);
535 1 : bool HasValue;
536 102 : if (auto Err = deserializeSeq(C, HasValue))
537 1 : return Err;
538 320 : if (HasValue)
539 1 : return SerializationTraits<ChannelT, T1, T2>::deserialize(C, *ValOrErr);
540 671 : Error Err = Error::success();
541 : if (auto E2 = deserializeSeq(C, Err))
542 1342 : return E2;
543 : ValOrErr = std::move(Err);
544 : return Error::success();
545 : }
546 1 : };
547 :
548 1 : /// SerializationTraits for Expected<T1> from a T2.
549 116 : template <typename ChannelT, typename T1, typename T2>
550 178 : class SerializationTraits<ChannelT, Expected<T1>, T2> {
551 232 : public:
552 0 :
553 : static Error serialize(ChannelT &C, T2 &&Val) {
554 526 : return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
555 : }
556 116 : };
557 1 :
558 0 : /// SerializationTraits for Expected<T1> from an Error.
559 551 : template <typename ChannelT, typename T>
560 0 : class SerializationTraits<ChannelT, Expected<T>, Error> {
561 1 : public:
562 :
563 105 : static Error serialize(ChannelT &C, Error &&Err) {
564 : return serializeSeq(C, Expected<T>(std::move(Err)));
565 : }
566 : };
567 0 :
568 1 : /// SerializationTraits default specialization for std::pair.
569 0 : template <typename ChannelT, typename T1, typename T2, typename T3, typename T4>
570 1 : class SerializationTraits<ChannelT, std::pair<T1, T2>, std::pair<T3, T4>> {
571 : public:
572 1 : static Error serialize(ChannelT &C, const std::pair<T3, T4> &V) {
573 : if (auto Err = SerializationTraits<ChannelT, T1, T3>::serialize(C, V.first))
574 : return Err;
575 : return SerializationTraits<ChannelT, T2, T4>::serialize(C, V.second);
576 526 : }
577 :
578 1060 : static Error deserialize(ChannelT &C, std::pair<T3, T4> &V) {
579 1 : if (auto Err =
580 : SerializationTraits<ChannelT, T1, T3>::deserialize(C, V.first))
581 1 : return Err;
582 : return SerializationTraits<ChannelT, T2, T4>::deserialize(C, V.second);
583 1 : }
584 : };
585 :
586 : /// SerializationTraits default specialization for std::tuple.
587 : template <typename ChannelT, typename... ArgTs>
588 0 : class SerializationTraits<ChannelT, std::tuple<ArgTs...>> {
589 : public:
590 559 :
591 : /// RPC channel serialization for std::tuple.
592 1 : static Error serialize(ChannelT &C, const std::tuple<ArgTs...> &V) {
593 : return serializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
594 9 : }
595 :
596 0 : /// RPC channel deserialization for std::tuple.
597 : static Error deserialize(ChannelT &C, std::tuple<ArgTs...> &V) {
598 0 : return deserializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
599 : }
600 :
601 9 : private:
602 : // Serialization helper for std::tuple.
603 527 : template <size_t... Is>
604 : static Error serializeTupleHelper(ChannelT &C, const std::tuple<ArgTs...> &V,
605 1 : llvm::index_sequence<Is...> _) {
606 : return serializeSeq(C, std::get<Is>(V)...);
607 : }
608 :
609 : // Serialization helper for std::tuple.
610 8 : template <size_t... Is>
611 : static Error deserializeTupleHelper(ChannelT &C, std::tuple<ArgTs...> &V,
612 12 : llvm::index_sequence<Is...> _) {
613 : return deserializeSeq(C, std::get<Is>(V)...);
614 0 : }
615 11 : };
616 2 :
617 : /// SerializationTraits default specialization for std::vector.
618 : template <typename ChannelT, typename T>
619 : class SerializationTraits<ChannelT, std::vector<T>> {
620 : public:
621 :
622 : /// Serialize a std::vector<T> from std::vector<T>.
623 0 : static Error serialize(ChannelT &C, const std::vector<T> &V) {
624 27 : if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
625 1 : return Err;
626 :
627 8 : for (const auto &E : V)
628 : if (auto Err = serializeSeq(C, E))
629 : return Err;
630 :
631 7 : return Error::success();
632 : }
633 :
634 8 : /// Deserialize a std::vector<T> to a std::vector<T>.
635 : static Error deserialize(ChannelT &C, std::vector<T> &V) {
636 : assert(V.empty() &&
637 : "Expected default-constructed vector to deserialize into");
638 84 :
639 : uint64_t Count = 0;
640 168 : if (auto Err = deserializeSeq(C, Count))
641 : return Err;
642 :
643 : V.resize(Count);
644 : for (auto &E : V)
645 11 : if (auto Err = deserializeSeq(C, E))
646 : return Err;
647 5 :
648 : return Error::success();
649 2 : }
650 4 : };
651 4 :
652 : template <typename ChannelT, typename T, typename T2>
653 : class SerializationTraits<ChannelT, std::set<T>, std::set<T2>> {
654 12 : public:
655 : /// Serialize a std::set<T> from std::set<T2>.
656 1 : static Error serialize(ChannelT &C, const std::set<T2> &S) {
657 : if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
658 2 : return Err;
659 :
660 : for (const auto &E : S)
661 : if (auto Err = SerializationTraits<ChannelT, T, T2>::serialize(C, E))
662 : return Err;
663 1 :
664 : return Error::success();
665 1 : }
666 :
667 2 : /// Deserialize a std::set<T> to a std::set<T>.
668 : static Error deserialize(ChannelT &C, std::set<T2> &S) {
669 : assert(S.empty() && "Expected default-constructed set to deserialize into");
670 :
671 : uint64_t Count = 0;
672 1 : if (auto Err = deserializeSeq(C, Count))
673 : return Err;
674 1 :
675 : while (Count-- != 0) {
676 2 : T2 Val;
677 : if (auto Err = SerializationTraits<ChannelT, T, T2>::deserialize(C, Val))
678 : return Err;
679 :
680 : auto Added = S.insert(Val).second;
681 1 : if (!Added)
682 : return make_error<StringError>("Duplicate element in deserialized set",
683 1 : orcError(OrcErrorCode::UnknownORCError));
684 : }
685 2 :
686 : return Error::success();
687 : }
688 : };
689 0 :
690 1 : template <typename ChannelT, typename K, typename V, typename K2, typename V2>
691 : class SerializationTraits<ChannelT, std::map<K, V>, std::map<K2, V2>> {
692 1 : public:
693 8 : /// Serialize a std::map<K, V> from std::map<K2, V2>.
694 2 : static Error serialize(ChannelT &C, const std::map<K2, V2> &M) {
695 8 : if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
696 8 : return Err;
697 :
698 : for (const auto &E : M) {
699 1 : if (auto Err =
700 : SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
701 1 : return Err;
702 : if (auto Err =
703 2 : SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
704 : return Err;
705 : }
706 :
707 : return Error::success();
708 1 : }
709 :
710 1 : /// Deserialize a std::map<K, V> to a std::map<K, V>.
711 : static Error deserialize(ChannelT &C, std::map<K2, V2> &M) {
712 10 : assert(M.empty() && "Expected default-constructed map to deserialize into");
713 :
714 8 : uint64_t Count = 0;
715 : if (auto Err = deserializeSeq(C, Count))
716 : return Err;
717 1 :
718 : while (Count-- != 0) {
719 1 : std::pair<K2, V2> Val;
720 : if (auto Err =
721 17 : SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
722 15 : return Err;
723 12 :
724 : if (auto Err =
725 12 : SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
726 1 : return Err;
727 3 :
728 1 : auto Added = M.insert(Val).second;
729 3 : if (!Added)
730 2 : return make_error<StringError>("Duplicate element in deserialized map",
731 10 : orcError(OrcErrorCode::UnknownORCError));
732 10 : }
733 9 :
734 : return Error::success();
735 10 : }
736 : };
737 2 :
738 : } // end namespace rpc
739 3 : } // end namespace orc
740 : } // end namespace llvm
741 5 :
742 5 : #endif // LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
|