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