v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
value-serializer.h
Go to the documentation of this file.
1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_OBJECTS_VALUE_SERIALIZER_H_
6#define V8_OBJECTS_VALUE_SERIALIZER_H_
7
8#include <cstdint>
9
12#include "src/base/macros.h"
13#include "src/base/strings.h"
14#include "src/base/vector.h"
18#include "src/zone/zone.h"
19
20namespace v8 {
21namespace internal {
22
23class BigInt;
24class HeapNumber;
25class Isolate;
26class JSArrayBuffer;
27class JSArrayBufferView;
28class JSDate;
29class JSMap;
30class JSPrimitiveWrapper;
31class JSRegExp;
32class JSSet;
33class JSSharedArray;
34class JSSharedStruct;
35class Object;
36class Oddball;
37class SharedObjectConveyorHandles;
38class Smi;
39class WasmMemoryObject;
40class WasmModuleObject;
41
42enum class SerializationTag : uint8_t;
43
51 public:
56
57 /*
58 * Writes out a header, which includes the format version.
59 */
60 void WriteHeader();
61
62 /*
63 * Serializes a V8 object into the buffer.
64 */
66
67 /*
68 * Returns the buffer, allocated via the delegate, and its size.
69 * Caller assumes ownership of the buffer.
70 */
71 std::pair<uint8_t*, size_t> Release();
72
73 /*
74 * Marks an ArrayBuffer as havings its contents transferred out of band.
75 * Pass the corresponding JSArrayBuffer in the deserializing context to
76 * ValueDeserializer::TransferArrayBuffer.
77 */
78 void TransferArrayBuffer(uint32_t transfer_id,
79 DirectHandle<JSArrayBuffer> array_buffer);
80
81 /*
82 * Publicly exposed wire format writing methods.
83 * These are intended for use within the delegate's WriteHostObject method.
84 */
85 void WriteUint32(uint32_t value);
86 void WriteUint64(uint64_t value);
87 void WriteRawBytes(const void* source, size_t length);
88 void WriteDouble(double value);
89 void WriteByte(uint8_t value);
90
91 /*
92 * Indicate whether to treat ArrayBufferView objects as host objects,
93 * i.e. pass them to Delegate::WriteHostObject. This should not be
94 * called when no Delegate was passed.
95 *
96 * The default is not to treat ArrayBufferViews as host objects.
97 */
99
100 private:
101 // Managing allocations of the internal buffer.
102 Maybe<bool> ExpandBuffer(size_t required_capacity);
103
104 // Writing the wire format.
105 void WriteTag(SerializationTag tag);
106 template <typename T>
107 void WriteVarint(T value);
108 template <typename T>
109 void WriteZigZag(T value);
113 Maybe<uint8_t*> ReserveRawBytes(size_t bytes);
114
115 // Writing V8 objects of various kinds.
116 void WriteOddball(Tagged<Oddball> oddball);
117 void WriteSmi(Tagged<Smi> smi);
119 void WriteBigInt(Tagged<BigInt> bigint);
142#if V8_ENABLE_WEBASSEMBLY
143 Maybe<bool> WriteWasmModule(DirectHandle<WasmModuleObject> object)
145 Maybe<bool> WriteWasmMemory(DirectHandle<WasmMemoryObject> object)
147#endif // V8_ENABLE_WEBASSEMBLY
152
153 /*
154 * Reads the specified keys from the object and writes key-value pairs to the
155 * buffer. Returns the number of keys actually written, which may be smaller
156 * if some keys are not own properties when accessed.
157 */
161
163
164 /*
165 * Asks the delegate to handle an error that occurred during data cloning, by
166 * throwing an exception appropriate for the host.
167 */
173
175
178 uint8_t* buffer_ = nullptr;
179 size_t buffer_size_ = 0;
183 bool out_of_memory_ = false;
185
186 // To avoid extra lookups in the identity map, ID+1 is actually stored in the
187 // map (checking if the used identity is zero is the fast way of checking if
188 // the entry is new).
190 uint32_t next_id_ = 0;
191
192 // A similar map, for transferred array buffers.
194
195 // The conveyor used to keep shared objects alive.
197};
198
199/*
200 * Deserializes values from data written with ValueSerializer, or a compatible
201 * implementation.
202 */
204 public:
207 ValueDeserializer(Isolate* isolate, const uint8_t* data, size_t size);
211
212 /*
213 * Runs version detection logic, which may fail if the format is invalid.
214 */
216
217 /*
218 * Reads the underlying wire format version. Likely mostly to be useful to
219 * legacy code reading old wire format versions. Must be called after
220 * ReadHeader.
221 */
222 uint32_t GetWireFormatVersion() const { return version_; }
223
224 /*
225 * Deserializes a V8 object from the buffer.
226 */
228
229 /*
230 * Reads an object, consuming the entire buffer.
231 *
232 * This is required for the legacy "version 0" format, which did not allow
233 * reference deduplication, and instead relied on a "stack" model for
234 * deserializing, with the contents of objects and arrays provided first.
235 */
238
239 /*
240 * Accepts the array buffer corresponding to the one passed previously to
241 * ValueSerializer::TransferArrayBuffer.
242 */
243 void TransferArrayBuffer(uint32_t transfer_id,
244 DirectHandle<JSArrayBuffer> array_buffer);
245
246 /*
247 * Publicly exposed wire format writing methods.
248 * These are intended for use within the delegate's WriteHostObject method.
249 */
250 bool ReadUint32(uint32_t* value) V8_WARN_UNUSED_RESULT;
251 bool ReadUint64(uint64_t* value) V8_WARN_UNUSED_RESULT;
252 bool ReadDouble(double* value) V8_WARN_UNUSED_RESULT;
253 bool ReadRawBytes(size_t length, const void** data) V8_WARN_UNUSED_RESULT;
254 bool ReadByte(uint8_t* value) V8_WARN_UNUSED_RESULT;
255
256 private:
257 // Reading the wire format.
259 void ConsumeTag(SerializationTag peeked_tag);
261 template <typename T>
263 template <typename T>
265 template <typename T>
268 Maybe<base::Vector<const uint8_t>> ReadRawBytes(size_t size)
270 Maybe<base::Vector<const base::uc16>> ReadRawTwoBytes(size_t size)
273
274 // Like ReadObject, but skips logic for special cases in simulating the
275 // "stack machine".
277
278 // Reads a string intended to be part of a more complicated object.
279 // Before v12, these are UTF-8 strings. After, they can be any encoding
280 // permissible for a string (with the relevant tag).
282
283 // Reading V8 objects of specific kinds.
284 // The tag is assumed to have already been read.
302 bool is_shared, bool is_resizable) V8_WARN_UNUSED_RESULT;
308 Tagged<JSArrayBuffer> buffer, uint32_t serialized_flags,
309 bool& is_length_tracking, bool& is_backed_by_rab) V8_WARN_UNUSED_RESULT;
311#if V8_ENABLE_WEBASSEMBLY
312 MaybeDirectHandle<JSObject> ReadWasmModuleTransfer() V8_WARN_UNUSED_RESULT;
314#endif // V8_ENABLE_WEBASSEMBLY
317
318 /*
319 * Reads key-value pairs into the object until the specified end tag is
320 * encountered. If successful, returns the number of properties read.
321 */
323 SerializationTag end_tag,
324 bool can_use_transitions);
325
326 // Manipulating the map from IDs to reified objects.
327 bool HasObjectWithID(uint32_t id);
329 void AddObjectWithID(uint32_t id, DirectHandle<JSReceiver> object);
330
332 v8::ValueDeserializer::Delegate* const delegate_;
333 const uint8_t* position_;
334 const uint8_t* const end_;
335 uint32_t version_ = 0;
336 uint32_t next_id_ = 0;
339
340 // Always global handles.
343
344 // The conveyor used to keep shared objects alive.
346};
347
348} // namespace internal
349} // namespace v8
350
351#endif // V8_OBJECTS_VALUE_SERIALIZER_H_
MaybeDirectHandle< JSReceiver > GetObjectWithID(uint32_t id)
bool ReadByte(uint8_t *value) V8_WARN_UNUSED_RESULT
MaybeDirectHandle< String > ReadString() V8_WARN_UNUSED_RESULT
MaybeDirectHandle< JSArrayBuffer > ReadJSArrayBuffer(bool is_shared, bool is_resizable) V8_WARN_UNUSED_RESULT
MaybeDirectHandle< JSRegExp > ReadJSRegExp() V8_WARN_UNUSED_RESULT
Maybe< double > ReadDouble() V8_WARN_UNUSED_RESULT
MaybeDirectHandle< JSArray > ReadDenseJSArray() V8_WARN_UNUSED_RESULT
const SharedObjectConveyorHandles * shared_object_conveyor_
MaybeDirectHandle< JSArrayBuffer > ReadTransferredJSArrayBuffer() V8_WARN_UNUSED_RESULT
MaybeDirectHandle< Object > ReadObject() V8_WARN_UNUSED_RESULT
MaybeIndirectHandle< SimpleNumberDictionary > array_buffer_transfer_map_
Maybe< bool > ReadHeader() V8_WARN_UNUSED_RESULT
bool ValidateJSArrayBufferViewFlags(Tagged< JSArrayBuffer > buffer, uint32_t serialized_flags, bool &is_length_tracking, bool &is_backed_by_rab) V8_WARN_UNUSED_RESULT
bool ReadUint64(uint64_t *value) V8_WARN_UNUSED_RESULT
MaybeDirectHandle< Object > ReadObjectUsingEntireBufferForLegacyFormat() V8_WARN_UNUSED_RESULT
V8_NOINLINE Maybe< T > ReadVarintLoop() V8_WARN_UNUSED_RESULT
void ConsumeTag(SerializationTag peeked_tag)
MaybeDirectHandle< JSDate > ReadJSDate() V8_WARN_UNUSED_RESULT
Maybe< base::Vector< const base::uc16 > > ReadRawTwoBytes(size_t size) V8_WARN_UNUSED_RESULT
MaybeDirectHandle< BigInt > ReadBigInt() V8_WARN_UNUSED_RESULT
bool ReadRawBytes(size_t length, const void **data) V8_WARN_UNUSED_RESULT
MaybeDirectHandle< JSArrayBufferView > ReadJSArrayBufferView(DirectHandle< JSArrayBuffer > buffer) V8_WARN_UNUSED_RESULT
MaybeDirectHandle< JSArray > ReadSparseJSArray() V8_WARN_UNUSED_RESULT
MaybeDirectHandle< Object > ReadObjectWrapper() V8_WARN_UNUSED_RESULT
MaybeDirectHandle< Object > ReadJSError() V8_WARN_UNUSED_RESULT
bool ReadUint32(uint32_t *value) V8_WARN_UNUSED_RESULT
v8::ValueDeserializer::Delegate *const delegate_
ValueDeserializer(const ValueDeserializer &)=delete
void TransferArrayBuffer(uint32_t transfer_id, DirectHandle< JSArrayBuffer > array_buffer)
MaybeDirectHandle< String > ReadOneByteString(AllocationType allocation=AllocationType::kYoung) V8_WARN_UNUSED_RESULT
MaybeDirectHandle< HeapObject > ReadSharedObject() V8_WARN_UNUSED_RESULT
void AddObjectWithID(uint32_t id, DirectHandle< JSReceiver > object)
Maybe< SerializationTag > ReadTag() V8_WARN_UNUSED_RESULT
MaybeDirectHandle< JSMap > ReadJSMap() V8_WARN_UNUSED_RESULT
IndirectHandle< FixedArray > id_map_
MaybeDirectHandle< JSPrimitiveWrapper > ReadJSPrimitiveWrapper(SerializationTag tag) V8_WARN_UNUSED_RESULT
Maybe< T > ReadZigZag() V8_WARN_UNUSED_RESULT
Maybe< uint32_t > ReadJSObjectProperties(DirectHandle< JSObject > object, SerializationTag end_tag, bool can_use_transitions)
MaybeDirectHandle< JSObject > ReadJSObject() V8_WARN_UNUSED_RESULT
MaybeDirectHandle< String > ReadUtf8String(AllocationType allocation=AllocationType::kYoung) V8_WARN_UNUSED_RESULT
MaybeDirectHandle< JSObject > ReadHostObject() V8_WARN_UNUSED_RESULT
MaybeDirectHandle< Object > ReadObjectInternal() V8_WARN_UNUSED_RESULT
ValueDeserializer & operator=(const ValueDeserializer &)=delete
Maybe< SerializationTag > PeekTag() const V8_WARN_UNUSED_RESULT
MaybeDirectHandle< JSSet > ReadJSSet() V8_WARN_UNUSED_RESULT
ValueDeserializer(Isolate *isolate, base::Vector< const uint8_t > data, v8::ValueDeserializer::Delegate *delegate)
MaybeDirectHandle< String > ReadTwoByteString(AllocationType allocation=AllocationType::kYoung) V8_WARN_UNUSED_RESULT
V8_INLINE Maybe< T > ReadVarint() V8_WARN_UNUSED_RESULT
void WriteTag(SerializationTag tag)
Maybe< uint32_t > WriteJSObjectPropertiesSlow(DirectHandle< JSObject > object, DirectHandle< FixedArray > keys) V8_WARN_UNUSED_RESULT
Maybe< bool > WriteJSArray(DirectHandle< JSArray > array) V8_WARN_UNUSED_RESULT
Maybe< bool > ExpandBuffer(size_t required_capacity)
Maybe< bool > WriteSharedObject(DirectHandle< HeapObject > object) V8_WARN_UNUSED_RESULT
void WriteOddball(Tagged< Oddball > oddball)
Maybe< bool > WriteJSError(DirectHandle< JSObject > error) V8_WARN_UNUSED_RESULT
void WriteTwoByteString(base::Vector< const base::uc16 > chars)
Maybe< bool > WriteJSMap(DirectHandle< JSMap > map) V8_WARN_UNUSED_RESULT
void WriteHeapNumber(Tagged< HeapNumber > number)
void SetTreatArrayBufferViewsAsHostObjects(bool mode)
ValueSerializer(Isolate *isolate, v8::ValueSerializer::Delegate *delegate)
void WriteJSRegExp(DirectHandle< JSRegExp > regexp)
void WriteString(DirectHandle< String > string)
void WriteOneByteString(base::Vector< const uint8_t > chars)
Maybe< bool > WriteJSSharedStruct(DirectHandle< JSSharedStruct > shared_struct) V8_WARN_UNUSED_RESULT
Maybe< bool > WriteHostObject(DirectHandle< JSObject > object) V8_WARN_UNUSED_RESULT
Maybe< bool > WriteJSSet(DirectHandle< JSSet > map) V8_WARN_UNUSED_RESULT
v8::ValueSerializer::Delegate *const delegate_
V8_NOINLINE Maybe< bool > ThrowDataCloneError(MessageTemplate template_index) V8_WARN_UNUSED_RESULT
void WriteJSDate(Tagged< JSDate > date)
ValueSerializer(const ValueSerializer &)=delete
void WriteSmi(Tagged< Smi > smi)
Maybe< bool > WriteJSArrayBufferView(Tagged< JSArrayBufferView > array_buffer)
IdentityMap< uint32_t, ZoneAllocationPolicy > array_buffer_transfer_map_
Maybe< bool > WriteJSArrayBuffer(DirectHandle< JSArrayBuffer > array_buffer) V8_WARN_UNUSED_RESULT
void WriteRawBytes(const void *source, size_t length)
void WriteBigIntContents(Tagged< BigInt > bigint)
Maybe< bool > WriteJSObjectSlow(DirectHandle< JSObject > object) V8_WARN_UNUSED_RESULT
IdentityMap< uint32_t, ZoneAllocationPolicy > id_map_
void TransferArrayBuffer(uint32_t transfer_id, DirectHandle< JSArrayBuffer > array_buffer)
Maybe< bool > WriteJSObject(DirectHandle< JSObject > object) V8_WARN_UNUSED_RESULT
Maybe< bool > WriteJSReceiver(DirectHandle< JSReceiver > receiver) V8_WARN_UNUSED_RESULT
void WriteBigInt(Tagged< BigInt > bigint)
Maybe< bool > WriteJSPrimitiveWrapper(DirectHandle< JSPrimitiveWrapper > value) V8_WARN_UNUSED_RESULT
Maybe< bool > WriteObject(DirectHandle< Object > object) V8_WARN_UNUSED_RESULT
Maybe< bool > IsHostObject(DirectHandle< JSObject > object)
ValueSerializer & operator=(const ValueSerializer &)=delete
Maybe< uint8_t * > ReserveRawBytes(size_t bytes)
SharedObjectConveyorHandles * shared_object_conveyor_
Maybe< bool > WriteJSSharedArray(DirectHandle< JSSharedArray > shared_array) V8_WARN_UNUSED_RESULT
void WriteDouble(double value)
std::pair< uint8_t *, size_t > Release()
TNode< Object > receiver
DateRecord date
JSArrayBuffer::IsDetachableBit is_shared
#define V8_INLINE
Definition v8config.h:500
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671
#define V8_NOINLINE
Definition v8config.h:586