LLVM  14.0.0git
MsgPackReader.cpp
Go to the documentation of this file.
1 //===- MsgPackReader.cpp - Simple MsgPack reader ----------------*- 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 /// \file
10 /// This file implements a MessagePack reader.
11 ///
12 //===----------------------------------------------------------------------===//
13 
16 #include "llvm/Support/Endian.h"
18 
19 using namespace llvm;
20 using namespace llvm::support;
21 using namespace msgpack;
22 
23 Reader::Reader(MemoryBufferRef InputBuffer)
24  : InputBuffer(InputBuffer), Current(InputBuffer.getBufferStart()),
25  End(InputBuffer.getBufferEnd()) {}
26 
27 Reader::Reader(StringRef Input) : Reader({Input, "MsgPack"}) {}
28 
30  if (Current == End)
31  return false;
32 
33  uint8_t FB = static_cast<uint8_t>(*Current++);
34 
35  switch (FB) {
36  case FirstByte::Nil:
37  Obj.Kind = Type::Nil;
38  return true;
39  case FirstByte::True:
40  Obj.Kind = Type::Boolean;
41  Obj.Bool = true;
42  return true;
43  case FirstByte::False:
44  Obj.Kind = Type::Boolean;
45  Obj.Bool = false;
46  return true;
47  case FirstByte::Int8:
48  Obj.Kind = Type::Int;
49  return readInt<int8_t>(Obj);
50  case FirstByte::Int16:
51  Obj.Kind = Type::Int;
52  return readInt<int16_t>(Obj);
53  case FirstByte::Int32:
54  Obj.Kind = Type::Int;
55  return readInt<int32_t>(Obj);
56  case FirstByte::Int64:
57  Obj.Kind = Type::Int;
58  return readInt<int64_t>(Obj);
59  case FirstByte::UInt8:
60  Obj.Kind = Type::UInt;
61  return readUInt<uint8_t>(Obj);
62  case FirstByte::UInt16:
63  Obj.Kind = Type::UInt;
64  return readUInt<uint16_t>(Obj);
65  case FirstByte::UInt32:
66  Obj.Kind = Type::UInt;
67  return readUInt<uint32_t>(Obj);
68  case FirstByte::UInt64:
69  Obj.Kind = Type::UInt;
70  return readUInt<uint64_t>(Obj);
71  case FirstByte::Float32:
72  Obj.Kind = Type::Float;
73  if (sizeof(float) > remainingSpace())
74  return make_error<StringError>(
75  "Invalid Float32 with insufficient payload",
76  std::make_error_code(std::errc::invalid_argument));
77  Obj.Float = BitsToFloat(endian::read<uint32_t, Endianness>(Current));
78  Current += sizeof(float);
79  return true;
80  case FirstByte::Float64:
81  Obj.Kind = Type::Float;
82  if (sizeof(double) > remainingSpace())
83  return make_error<StringError>(
84  "Invalid Float64 with insufficient payload",
85  std::make_error_code(std::errc::invalid_argument));
86  Obj.Float = BitsToDouble(endian::read<uint64_t, Endianness>(Current));
87  Current += sizeof(double);
88  return true;
89  case FirstByte::Str8:
90  Obj.Kind = Type::String;
91  return readRaw<uint8_t>(Obj);
92  case FirstByte::Str16:
93  Obj.Kind = Type::String;
94  return readRaw<uint16_t>(Obj);
95  case FirstByte::Str32:
96  Obj.Kind = Type::String;
97  return readRaw<uint32_t>(Obj);
98  case FirstByte::Bin8:
99  Obj.Kind = Type::Binary;
100  return readRaw<uint8_t>(Obj);
101  case FirstByte::Bin16:
102  Obj.Kind = Type::Binary;
103  return readRaw<uint16_t>(Obj);
104  case FirstByte::Bin32:
105  Obj.Kind = Type::Binary;
106  return readRaw<uint32_t>(Obj);
107  case FirstByte::Array16:
108  Obj.Kind = Type::Array;
109  return readLength<uint16_t>(Obj);
110  case FirstByte::Array32:
111  Obj.Kind = Type::Array;
112  return readLength<uint32_t>(Obj);
113  case FirstByte::Map16:
114  Obj.Kind = Type::Map;
115  return readLength<uint16_t>(Obj);
116  case FirstByte::Map32:
117  Obj.Kind = Type::Map;
118  return readLength<uint32_t>(Obj);
119  case FirstByte::FixExt1:
120  Obj.Kind = Type::Extension;
121  return createExt(Obj, FixLen::Ext1);
122  case FirstByte::FixExt2:
123  Obj.Kind = Type::Extension;
124  return createExt(Obj, FixLen::Ext2);
125  case FirstByte::FixExt4:
126  Obj.Kind = Type::Extension;
127  return createExt(Obj, FixLen::Ext4);
128  case FirstByte::FixExt8:
129  Obj.Kind = Type::Extension;
130  return createExt(Obj, FixLen::Ext8);
131  case FirstByte::FixExt16:
132  Obj.Kind = Type::Extension;
133  return createExt(Obj, FixLen::Ext16);
134  case FirstByte::Ext8:
135  Obj.Kind = Type::Extension;
136  return readExt<uint8_t>(Obj);
137  case FirstByte::Ext16:
138  Obj.Kind = Type::Extension;
139  return readExt<uint16_t>(Obj);
140  case FirstByte::Ext32:
141  Obj.Kind = Type::Extension;
142  return readExt<uint32_t>(Obj);
143  }
144 
145  if ((FB & FixBitsMask::NegativeInt) == FixBits::NegativeInt) {
146  Obj.Kind = Type::Int;
147  int8_t I;
148  static_assert(sizeof(I) == sizeof(FB), "Unexpected type sizes");
149  memcpy(&I, &FB, sizeof(FB));
150  Obj.Int = I;
151  return true;
152  }
153 
154  if ((FB & FixBitsMask::PositiveInt) == FixBits::PositiveInt) {
155  Obj.Kind = Type::UInt;
156  Obj.UInt = FB;
157  return true;
158  }
159 
160  if ((FB & FixBitsMask::String) == FixBits::String) {
161  Obj.Kind = Type::String;
162  uint8_t Size = FB & ~FixBitsMask::String;
163  return createRaw(Obj, Size);
164  }
165 
166  if ((FB & FixBitsMask::Array) == FixBits::Array) {
167  Obj.Kind = Type::Array;
168  Obj.Length = FB & ~FixBitsMask::Array;
169  return true;
170  }
171 
172  if ((FB & FixBitsMask::Map) == FixBits::Map) {
173  Obj.Kind = Type::Map;
174  Obj.Length = FB & ~FixBitsMask::Map;
175  return true;
176  }
177 
178  return make_error<StringError>(
179  "Invalid first byte", std::make_error_code(std::errc::invalid_argument));
180 }
181 
182 template <class T> Expected<bool> Reader::readRaw(Object &Obj) {
183  if (sizeof(T) > remainingSpace())
184  return make_error<StringError>(
185  "Invalid Raw with insufficient payload",
186  std::make_error_code(std::errc::invalid_argument));
187  T Size = endian::read<T, Endianness>(Current);
188  Current += sizeof(T);
189  return createRaw(Obj, Size);
190 }
191 
192 template <class T> Expected<bool> Reader::readInt(Object &Obj) {
193  if (sizeof(T) > remainingSpace())
194  return make_error<StringError>(
195  "Invalid Int with insufficient payload",
196  std::make_error_code(std::errc::invalid_argument));
197  Obj.Int = static_cast<int64_t>(endian::read<T, Endianness>(Current));
198  Current += sizeof(T);
199  return true;
200 }
201 
202 template <class T> Expected<bool> Reader::readUInt(Object &Obj) {
203  if (sizeof(T) > remainingSpace())
204  return make_error<StringError>(
205  "Invalid Int with insufficient payload",
206  std::make_error_code(std::errc::invalid_argument));
207  Obj.UInt = static_cast<uint64_t>(endian::read<T, Endianness>(Current));
208  Current += sizeof(T);
209  return true;
210 }
211 
212 template <class T> Expected<bool> Reader::readLength(Object &Obj) {
213  if (sizeof(T) > remainingSpace())
214  return make_error<StringError>(
215  "Invalid Map/Array with invalid length",
216  std::make_error_code(std::errc::invalid_argument));
217  Obj.Length = static_cast<size_t>(endian::read<T, Endianness>(Current));
218  Current += sizeof(T);
219  return true;
220 }
221 
222 template <class T> Expected<bool> Reader::readExt(Object &Obj) {
223  if (sizeof(T) > remainingSpace())
224  return make_error<StringError>(
225  "Invalid Ext with invalid length",
226  std::make_error_code(std::errc::invalid_argument));
227  T Size = endian::read<T, Endianness>(Current);
228  Current += sizeof(T);
229  return createExt(Obj, Size);
230 }
231 
232 Expected<bool> Reader::createRaw(Object &Obj, uint32_t Size) {
233  if (Size > remainingSpace())
234  return make_error<StringError>(
235  "Invalid Raw with insufficient payload",
236  std::make_error_code(std::errc::invalid_argument));
237  Obj.Raw = StringRef(Current, Size);
238  Current += Size;
239  return true;
240 }
241 
242 Expected<bool> Reader::createExt(Object &Obj, uint32_t Size) {
243  if (Current == End)
244  return make_error<StringError>(
245  "Invalid Ext with no type",
246  std::make_error_code(std::errc::invalid_argument));
247  Obj.Extension.Type = *Current++;
248  if (Size > remainingSpace())
249  return make_error<StringError>(
250  "Invalid Ext with insufficient payload",
251  std::make_error_code(std::errc::invalid_argument));
252  Obj.Extension.Bytes = StringRef(Current, Size);
253  Current += Size;
254  return true;
255 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MathExtras.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
T
double
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double
Definition: README-SSE.txt:85
llvm::msgpack::Type::Array
@ Array
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::msgpack::Type::Binary
@ Binary
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::msgpack::Type::Int
@ Int
llvm::msgpack::Type::Map
@ Map
llvm::msgpack::Type::UInt
@ UInt
llvm::msgpack::Object::Int
int64_t Int
Value for Type::Int.
Definition: MsgPackReader.h:81
llvm::pdb::Int8
@ Int8
Definition: PDBTypes.h:396
llvm::msgpack::Type::String
@ String
llvm::msgpack::Reader::Reader
Reader(MemoryBufferRef InputBuffer)
Construct a reader, keeping a reference to the InputBuffer.
Definition: MsgPackReader.cpp:23
llvm::msgpack::Reader::read
Expected< bool > read(Object &Obj)
Read one object from the input buffer, advancing past it.
Definition: MsgPackReader.cpp:29
llvm::msgpack::Object::Bool
bool Bool
Value for Type::Boolean.
Definition: MsgPackReader.h:85
uint64_t
I
#define I(x, y, z)
Definition: MD5.cpp:59
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::msgpack::Object::Raw
StringRef Raw
Value for Type::String and Type::Binary.
Definition: MsgPackReader.h:89
llvm::msgpack::Object::UInt
uint64_t UInt
Value for Type::Uint.
Definition: MsgPackReader.h:83
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
uint32_t
llvm::BitsToFloat
float BitsToFloat(uint32_t Bits)
This function takes a 32-bit integer and returns the bit equivalent float.
Definition: MathExtras.h:643
llvm::msgpack::Reader
Reads MessagePack objects from memory, one at a time.
Definition: MsgPackReader.h:100
llvm::make_error_code
std::error_code make_error_code(BitcodeError E)
Definition: BitcodeReader.h:270
llvm::msgpack::Type::Extension
@ Extension
llvm::msgpack::Object::Kind
Type Kind
Definition: MsgPackReader.h:78
llvm::msgpack::Type::Boolean
@ Boolean
llvm::support
Definition: Endian.h:25
llvm::msgpack::Type::Float
@ Float
llvm::BitsToDouble
double BitsToDouble(uint64_t Bits)
This function takes a 64-bit integer and returns the bit equivalent double.
Definition: MathExtras.h:635
MsgPackReader.h
llvm::msgpack::Object::Float
double Float
Value for Type::Float.
Definition: MsgPackReader.h:87
MsgPack.h
llvm::msgpack::Object
MessagePack object, represented as a tagged union of C++ types.
Definition: MsgPackReader.h:77
llvm::msgpack::Type::Nil
@ Nil
llvm::msgpack::Object::Length
size_t Length
Value for Type::Array and Type::Map.
Definition: MsgPackReader.h:91
llvm::pdb::UInt8
@ UInt8
Definition: PDBTypes.h:402
Endian.h