1//===---- SimplePackedSerialization.h - simple serialization ----*- C++ -*-===//
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
7//===----------------------------------------------------------------------===//
9// The behavior of the utilities in this header must be synchronized with the
10// behavior of the utilities in
11// compiler-rt/lib/orc/simple_packed_serialization.h.
13// The Simple Packed Serialization (SPS) utilities are used to generate
14// argument and return buffers for wrapper functions using the following
15// serialization scheme:
17// Primitives (signed types should be two's complement):
18// bool, char, int8_t, uint8_t -- 8-bit (0=false, 1=true)
19// int16_t, uint16_t -- 16-bit little endian
20// int32_t, uint32_t -- 32-bit little endian
21// int64_t, int64_t -- 64-bit little endian
24// Serialized as the sequence length (as a uint64_t) followed by the
25// serialization of each of the elements without padding.
28// Serialized as each of the element types from T1 to TN without padding.
30//===----------------------------------------------------------------------===//
32#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEPACKEDSERIALIZATION_H
33#define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEPACKEDSERIALIZATION_H
54/// Output char buffer with overflow check.
58 : Buffer(Buffer), Remaining(Remaining) {}
70 char *Buffer =
nullptr;
74/// Input char buffer with underflow check.
79 : Buffer(Buffer), Remaining(Remaining) {}
89 const char *
data()
const {
return Buffer; }
99 const char *Buffer =
nullptr;
100 size_t Remaining = 0;
103/// Specialize to describe how to serialize/deserialize to/from the given
105template <
typename SPSTagT,
typename ConcreteT,
typename _ =
void>
108/// A utility class for serializing to a blob from a variadic list.
111// Empty list specialization for SPSArgList.
114 static size_t size() {
return 0; }
126// Non-empty list specialization for SPSArgList.
127template <
typename SPSTagT,
typename... SPSTagTs>
130 // FIXME: This typedef is here to enable SPS arg serialization from
131 // JITLink. It can be removed once JITLink can access SPS directly.
134 template <
typename ArgT,
typename... ArgTs>
135 static size_t size(
const ArgT &Arg,
const ArgTs &...Args) {
140 template <
typename ArgT,
typename... ArgTs>
142 const ArgTs &...Args) {
147 template <
typename ArgT,
typename... ArgTs>
154/// SPS serialization for integral types, bool, and char.
155template <
typename SPSTagT>
158 std::enable_if_t<std::is_same<SPSTagT, bool>::value ||
159 std::is_same<SPSTagT, char>::value ||
160 std::is_same<SPSTagT, int8_t>::value ||
161 std::is_same<SPSTagT, int16_t>::value ||
162 std::is_same<SPSTagT, int32_t>::value ||
163 std::is_same<SPSTagT, int64_t>::value ||
164 std::is_same<SPSTagT, uint8_t>::value ||
165 std::is_same<SPSTagT, uint16_t>::value ||
166 std::is_same<SPSTagT, uint32_t>::value ||
167 std::is_same<SPSTagT, uint64_t>::value>> {
169 static size_t size(
const SPSTagT &
Value) {
return sizeof(SPSTagT); }
175 return OB.write(
reinterpret_cast<const char *
>(&Tmp),
sizeof(Tmp));
180 if (!IB.read(
reinterpret_cast<char *
>(&Tmp),
sizeof(Tmp)))
189// Any empty placeholder suitable as a substitute for void when deserializing
192/// SPS tag type for tuples.
194/// A blob tuple should be serialized by serializing each of the elements in
198 /// Convenience typedef of the corresponding arg list.
202/// SPS tag type for optionals.
204/// SPSOptionals should be serialized as a bool with true indicating that an
205/// SPSTagT value is present, and false indicating that there is no value.
206/// If the boolean is true then the serialized SPSTagT will follow immediately
210/// SPS tag type for sequences.
212/// SPSSequences should be serialized as a uint64_t sequence length,
213/// followed by the serialization of each of the elements.
216/// SPS tag type for strings, which are equivalent to sequences of chars.
219/// SPS tag type for maps.
221/// SPS maps are just sequences of (Key, Value) tuples.
222template <
typename SPSTagT1,
typename SPSTagT2>
225/// Serialization for SPSEmpty type.
235/// Specialize this to implement 'trivial' sequence serialization for
236/// a concrete sequence type.
238/// Trivial sequence serialization uses the sequence's 'size' member to get the
239/// length of the sequence, and uses a range-based for loop to iterate over the
242/// Specializing this template class means that you do not need to provide a
243/// specialization of SPSSerializationTraits for your type.
244template <
typename SPSElementTagT,
typename ConcreteSequenceT>
250/// Specialize this to implement 'trivial' sequence deserialization for
251/// a concrete sequence type.
253/// Trivial deserialization calls a static 'reserve(SequenceT&)' method on your
254/// specialization (you must implement this) to reserve space, and then calls
255/// a static 'append(SequenceT&, ElementT&) method to append each of the
256/// deserialized elements.
258/// Specializing this template class means that you do not need to provide a
259/// specialization of SPSSerializationTraits for your type.
260template <
typename SPSElementTagT,
typename ConcreteSequenceT>
266/// Trivial std::string -> SPSSequence<char> serialization.
272/// Trivial SPSSequence<char> -> std::string deserialization.
286/// Trivial std::vector<T> -> SPSSequence<SPSElementTagT> serialization.
287template <
typename SPSElementTagT,
typename T>
293/// Trivial SPSSequence<SPSElementTagT> -> std::vector<T> deserialization.
294template <
typename SPSElementTagT,
typename T>
303 V.push_back(std::move(
E));
308/// Trivial SmallVectorImpl<T> -> SPSSequence<char> serialization.
309template <
typename SPSElementTagT,
typename T>
315/// Trivial SPSSequence<SPSElementTagT> -> SmallVectorImpl<T> deserialization.
316template <
typename SPSElementTagT,
typename T>
325 V.push_back(std::move(
E));
330/// Trivial SmallVectorImpl<T> -> SPSSequence<char> serialization.
331template <
typename SPSElementTagT,
typename T,
unsigned N>
334 SmallVectorImpl<T>> {};
336/// Trivial SPSSequence<SPSElementTagT> -> SmallVectorImpl<T> deserialization.
337template <
typename SPSElementTagT,
typename T,
unsigned N>
340 SmallVectorImpl<T>> {};
342/// Trivial ArrayRef<T> -> SPSSequence<SPSElementTagT> serialization.
343template <
typename SPSElementTagT,
typename T>
349/// Specialized SPSSequence<char> -> ArrayRef<char> serialization.
351/// On deserialize, points directly into the input buffer.
362 if (
A.empty())
// Empty ArrayRef may have null data, so bail out early.
364 return OB.write(
A.data(),
A.size());
371 if (
Size > std::numeric_limits<size_t>::max())
373 A = {
Size ? IB.data() :
nullptr,
static_cast<size_t>(
Size)};
374 return IB.skip(
Size);
378/// 'Trivial' sequence serialization: Sequence is serialized as a uint64_t size
379/// followed by a for-earch loop over the elements of the sequence to serialize
381template <
typename SPSElementTagT,
typename SequenceT>
383 std::enable_if_t<TrivialSPSSequenceSerialization<
384 SPSElementTagT, SequenceT>::available>> {
386 static size_t size(
const SequenceT &S) {
388 for (
const auto &
E : S)
396 for (
const auto &
E : S)
407 TBSD::reserve(S,
Size);
408 for (
size_t I = 0;
I !=
Size; ++
I) {
409 typename TBSD::element_type
E;
412 if (!TBSD::append(S, std::move(
E)))
419/// SPSTuple serialization for std::tuple.
420template <
typename... SPSTagTs,
typename... Ts>
423 using TupleArgList =
typename SPSTuple<SPSTagTs...>::AsArgList;
424 using ArgIndices = std::make_index_sequence<
sizeof...(Ts)>;
426 template <std::size_t...
I>
427 static size_t size(
const std::tuple<Ts...> &
T, std::index_sequence<I...>) {
428 return TupleArgList::size(std::get<I>(
T)...);
431 template <std::size_t...
I>
433 std::index_sequence<I...>) {
434 return TupleArgList::serialize(OB, std::get<I>(
T)...);
437 template <std::size_t...
I>
439 std::index_sequence<I...>) {
440 return TupleArgList::deserialize(IB, std::get<I>(
T)...);
444 static size_t size(
const std::tuple<Ts...> &
T) {
445 return size(
T, ArgIndices{});
449 return serialize(OB,
T, ArgIndices{});
453 return deserialize(IB,
T, ArgIndices{});
457/// SPSTuple serialization for std::pair.
458template <
typename SPSTagT1,
typename SPSTagT2,
typename T1,
typename T2>
461 static size_t size(
const std::pair<T1, T2> &
P) {
477/// SPSOptional serialization for std::optional.
478template <
typename SPSTagT,
typename T>
504 Value = std::optional<T>();
509/// Serialization for StringRefs.
511/// Serialization is as for regular strings. Deserialization points directly
523 if (S.
empty())
// Empty StringRef may have null data, so bail out early.
525 return OB.write(S.
data(), S.
size());
529 const char *
Data =
nullptr;
541/// Serialization for StringMap<ValueT>s.
542template <
typename SPSValueT,
typename ValueT>
566 assert(M.empty() &&
"M already contains elements");
576 if (!M.insert(std::make_pair(S, V)).second)
584/// SPS tag type for errors.
587/// SPS tag type for expecteds, which are either a T or a string representing
593/// Helper type for serializing Errors.
595/// llvm::Errors are move-only, and not inspectable except by consuming them.
596/// This makes them unsuitable for direct serialization via
597/// SPSSerializationTraits, which needs to inspect values twice (once to
598/// determine the amount of space to reserve, and then again to serialize).
600/// The SPSSerializableError type is a helper that can be
601/// constructed from an llvm::Error, but inspected more than once.
607/// Helper type for serializing Expected<T>s.
609/// See SPSSerializableError for more details.
611// FIXME: Use std::variant for storage once we have c++17.
620 return {
true,
toString(std::move(Err))};
633 return {
true, std::move(*
E), {}};
641 return std::move(BSE.
Value);
646}
// end namespace detail
648/// Serialize to a SPSError from a detail::SPSSerializableError.
681/// Serialize to a SPSExpected<SPSTagT> from a
682/// detail::SPSSerializableExpected<T>.
683template <
typename SPSTagT,
typename T>
685 detail::SPSSerializableExpected<T>> {
719/// Serialize to a SPSExpected<SPSTagT> from a detail::SPSSerializableError.
720template <
typename SPSTagT>
722 detail::SPSSerializableError> {
725 assert(BSE.
HasError &&
"Cannot serialize expected from a success value");
732 assert(BSE.
HasError &&
"Cannot serialize expected from a success value");
739/// Serialize to a SPSExpected<SPSTagT> from a T.
740template <
typename SPSTagT,
typename T>
754}
// end namespace shared
755}
// end namespace orc
756}
// end namespace llvm
758#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEPACKEDSERIALIZATION_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
LLVM Value Representation.
static bool deserialize(SPSInputBuffer &IB, ArgT &Arg, ArgTs &...Args)
static bool serialize(SPSOutputBuffer &OB, const ArgT &Arg, const ArgTs &...Args)
static size_t size(const ArgT &Arg, const ArgTs &...Args)
SPSOutputBuffer OutputBuffer
static bool deserializeFromSmallVector(const SmallVectorImpl< char > &V)
static bool serializeToSmallVector(SmallVectorImpl< char > &V)
static bool serialize(SPSOutputBuffer &OB)
static bool deserialize(SPSInputBuffer &IB)
A utility class for serializing to a blob from a variadic list.
SPS tag type for expecteds, which are either a T or a string representing an error.
SPS tag type for optionals.
Output char buffer with overflow check.
bool write(const char *Data, size_t Size)
SPSOutputBuffer(char *Buffer, size_t Remaining)
SPS tag type for sequences.
static size_t size(const SPSEmpty &EP)
static bool serialize(SPSOutputBuffer &OB, const SPSEmpty &BE)
static bool deserialize(SPSInputBuffer &IB, SPSEmpty &BE)
static size_t size(const detail::SPSSerializableError &BSE)
static bool deserialize(SPSInputBuffer &IB, detail::SPSSerializableError &BSE)
static bool serialize(SPSOutputBuffer &OB, const detail::SPSSerializableError &BSE)
static bool serialize(SPSOutputBuffer &OB, const T &Value)
static size_t size(const T &Value)
static bool deserialize(SPSInputBuffer &IB, detail::SPSSerializableExpected< T > &BSE)
static bool serialize(SPSOutputBuffer &OB, const detail::SPSSerializableExpected< T > &BSE)
static size_t size(const detail::SPSSerializableExpected< T > &BSE)
static size_t size(const detail::SPSSerializableError &BSE)
static bool serialize(SPSOutputBuffer &OB, const detail::SPSSerializableError &BSE)
static bool deserialize(SPSInputBuffer &IB, std::optional< T > &Value)
static size_t size(const std::optional< T > &Value)
static bool serialize(SPSOutputBuffer &OB, const std::optional< T > &Value)
static bool deserialize(SPSInputBuffer &IB, SequenceT &S)
static size_t size(const SequenceT &S)
static bool serialize(SPSOutputBuffer &OB, const SequenceT &S)
static bool deserialize(SPSInputBuffer &IB, StringMap< ValueT > &M)
static size_t size(const StringMap< ValueT > &M)
static bool serialize(SPSOutputBuffer &OB, const StringMap< ValueT > &M)
static bool deserialize(SPSInputBuffer &IB, ArrayRef< char > &A)
static size_t size(const ArrayRef< char > &A)
static bool serialize(SPSOutputBuffer &OB, const ArrayRef< char > &A)
static bool serialize(SPSOutputBuffer &OB, StringRef S)
static size_t size(const StringRef &S)
static bool deserialize(SPSInputBuffer &IB, StringRef &S)
llvm::orc::shared::SPSSerializationTraits< SPSTagT, SPSTagT, std::enable_if_t< std::is_same< SPSTagT, bool >::value||std::is_same< SPSTagT, char >::value||std::is_same< SPSTagT, int8_t >::value||std::is_same< SPSTagT, int16_t >::value||std::is_same< SPSTagT, int32_t >::value||std::is_same< SPSTagT, int64_t >::value||std::is_same< SPSTagT, uint8_t >::value||std::is_same< SPSTagT, uint16_t >::value||std::is_same< SPSTagT, uint32_t >::value||std::is_same< SPSTagT, uint64_t >::value > >::deserialize static bool deserialize(SPSInputBuffer &IB, SPSTagT &Value)
llvm::orc::shared::SPSSerializationTraits< SPSTagT, SPSTagT, std::enable_if_t< std::is_same< SPSTagT, bool >::value||std::is_same< SPSTagT, char >::value||std::is_same< SPSTagT, int8_t >::value||std::is_same< SPSTagT, int16_t >::value||std::is_same< SPSTagT, int32_t >::value||std::is_same< SPSTagT, int64_t >::value||std::is_same< SPSTagT, uint8_t >::value||std::is_same< SPSTagT, uint16_t >::value||std::is_same< SPSTagT, uint32_t >::value||std::is_same< SPSTagT, uint64_t >::value > >::size static size_t size(const SPSTagT &Value)
llvm::orc::shared::SPSSerializationTraits< SPSTagT, SPSTagT, std::enable_if_t< std::is_same< SPSTagT, bool >::value||std::is_same< SPSTagT, char >::value||std::is_same< SPSTagT, int8_t >::value||std::is_same< SPSTagT, int16_t >::value||std::is_same< SPSTagT, int32_t >::value||std::is_same< SPSTagT, int64_t >::value||std::is_same< SPSTagT, uint8_t >::value||std::is_same< SPSTagT, uint16_t >::value||std::is_same< SPSTagT, uint32_t >::value||std::is_same< SPSTagT, uint64_t >::value > >::serialize static bool serialize(SPSOutputBuffer &OB, const SPSTagT &Value)
static bool deserialize(SPSInputBuffer &IB, std::pair< T1, T2 > &P)
static size_t size(const std::pair< T1, T2 > &P)
static bool serialize(SPSOutputBuffer &OB, const std::pair< T1, T2 > &P)
static size_t size(const std::tuple< Ts... > &T)
static bool deserialize(SPSInputBuffer &IB, std::tuple< Ts... > &T)
static bool serialize(SPSOutputBuffer &OB, const std::tuple< Ts... > &T)
Specialize to describe how to serialize/deserialize to/from the given concrete type.
SPSArgList< SPSTagTs... > AsArgList
typename SmallVectorImpl< T >::value_type element_type
static void reserve(SmallVectorImpl< T > &V, uint64_t Size)
static bool append(SmallVectorImpl< T > &V, T E)
static constexpr bool available
static bool append(std::vector< T > &V, T E)
static void reserve(std::vector< T > &V, uint64_t Size)
typename std::vector< T >::value_type element_type
static constexpr bool available
static constexpr bool available
static bool append(std::string &S, char C)
static void reserve(std::string &S, uint64_t Size)
Specialize this to implement 'trivial' sequence deserialization for a concrete sequence type.
static constexpr bool available
static constexpr bool available
static constexpr bool available
static constexpr bool available
static constexpr bool available
Specialize this to implement 'trivial' sequence serialization for a concrete sequence type.
static constexpr bool available
@ C
The default llvm calling convention, compatible with C.
SPSSerializableError toSPSSerializable(Error Err)
Error fromSPSSerializable(SPSSerializableError BSE)
SPSSequence< SPSTuple< SPSTagT1, SPSTagT2 > > SPSMap
SPS tag type for maps.
SPSSequence< char > SPSString
SPS tag type for strings, which are equivalent to sequences of chars.
constexpr bool IsBigEndianHost
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
detail::ValueMatchesPoly< M > HasValue(M Matcher)
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
Implement std::hash so that hash_code can be used in STL containers.
Helper type for serializing Errors.
Helper type for serializing Expected<T>s.