11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef INCLUDE_V8_VALUE_SERIALIZER_H_
61cb0ef41Sopenharmony_ci#define INCLUDE_V8_VALUE_SERIALIZER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <stddef.h>
91cb0ef41Sopenharmony_ci#include <stdint.h>
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include <utility>
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci#include "v8-local-handle.h"  // NOLINT(build/include_directory)
141cb0ef41Sopenharmony_ci#include "v8-maybe.h"         // NOLINT(build/include_directory)
151cb0ef41Sopenharmony_ci#include "v8config.h"         // NOLINT(build/include_directory)
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace v8 {
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciclass ArrayBuffer;
201cb0ef41Sopenharmony_ciclass Isolate;
211cb0ef41Sopenharmony_ciclass Object;
221cb0ef41Sopenharmony_ciclass SharedArrayBuffer;
231cb0ef41Sopenharmony_ciclass String;
241cb0ef41Sopenharmony_ciclass WasmModuleObject;
251cb0ef41Sopenharmony_ciclass Value;
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_cinamespace internal {
281cb0ef41Sopenharmony_cistruct ScriptStreamingData;
291cb0ef41Sopenharmony_ci}  // namespace internal
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci/**
321cb0ef41Sopenharmony_ci * Value serialization compatible with the HTML structured clone algorithm.
331cb0ef41Sopenharmony_ci * The format is backward-compatible (i.e. safe to store to disk).
341cb0ef41Sopenharmony_ci */
351cb0ef41Sopenharmony_ciclass V8_EXPORT ValueSerializer {
361cb0ef41Sopenharmony_ci public:
371cb0ef41Sopenharmony_ci  class V8_EXPORT Delegate {
381cb0ef41Sopenharmony_ci   public:
391cb0ef41Sopenharmony_ci    virtual ~Delegate() = default;
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci    /**
421cb0ef41Sopenharmony_ci     * Handles the case where a DataCloneError would be thrown in the structured
431cb0ef41Sopenharmony_ci     * clone spec. Other V8 embedders may throw some other appropriate exception
441cb0ef41Sopenharmony_ci     * type.
451cb0ef41Sopenharmony_ci     */
461cb0ef41Sopenharmony_ci    virtual void ThrowDataCloneError(Local<String> message) = 0;
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci    /**
491cb0ef41Sopenharmony_ci     * The embedder overrides this method to write some kind of host object, if
501cb0ef41Sopenharmony_ci     * possible. If not, a suitable exception should be thrown and
511cb0ef41Sopenharmony_ci     * Nothing<bool>() returned.
521cb0ef41Sopenharmony_ci     */
531cb0ef41Sopenharmony_ci    virtual Maybe<bool> WriteHostObject(Isolate* isolate, Local<Object> object);
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci    /**
561cb0ef41Sopenharmony_ci     * Called when the ValueSerializer is going to serialize a
571cb0ef41Sopenharmony_ci     * SharedArrayBuffer object. The embedder must return an ID for the
581cb0ef41Sopenharmony_ci     * object, using the same ID if this SharedArrayBuffer has already been
591cb0ef41Sopenharmony_ci     * serialized in this buffer. When deserializing, this ID will be passed to
601cb0ef41Sopenharmony_ci     * ValueDeserializer::GetSharedArrayBufferFromId as |clone_id|.
611cb0ef41Sopenharmony_ci     *
621cb0ef41Sopenharmony_ci     * If the object cannot be serialized, an
631cb0ef41Sopenharmony_ci     * exception should be thrown and Nothing<uint32_t>() returned.
641cb0ef41Sopenharmony_ci     */
651cb0ef41Sopenharmony_ci    virtual Maybe<uint32_t> GetSharedArrayBufferId(
661cb0ef41Sopenharmony_ci        Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer);
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci    virtual Maybe<uint32_t> GetWasmModuleTransferId(
691cb0ef41Sopenharmony_ci        Isolate* isolate, Local<WasmModuleObject> module);
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci    /**
721cb0ef41Sopenharmony_ci     * Returns whether shared values are supported. GetSharedValueId is only
731cb0ef41Sopenharmony_ci     * called if SupportsSharedValues() returns true.
741cb0ef41Sopenharmony_ci     */
751cb0ef41Sopenharmony_ci    virtual bool SupportsSharedValues() const;
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci    /**
781cb0ef41Sopenharmony_ci     * Called when the ValueSerializer serializes a value that is shared across
791cb0ef41Sopenharmony_ci     * Isolates. The embedder must return an ID for the object. This function
801cb0ef41Sopenharmony_ci     * must be idempotent for the same object. When deserializing, the ID will
811cb0ef41Sopenharmony_ci     * be passed to ValueDeserializer::Delegate::GetSharedValueFromId as
821cb0ef41Sopenharmony_ci     * |shared_value_id|.
831cb0ef41Sopenharmony_ci     */
841cb0ef41Sopenharmony_ci    virtual Maybe<uint32_t> GetSharedValueId(Isolate* isolate,
851cb0ef41Sopenharmony_ci                                             Local<Value> shared_value);
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci    /**
881cb0ef41Sopenharmony_ci     * Allocates memory for the buffer of at least the size provided. The actual
891cb0ef41Sopenharmony_ci     * size (which may be greater or equal) is written to |actual_size|. If no
901cb0ef41Sopenharmony_ci     * buffer has been allocated yet, nullptr will be provided.
911cb0ef41Sopenharmony_ci     *
921cb0ef41Sopenharmony_ci     * If the memory cannot be allocated, nullptr should be returned.
931cb0ef41Sopenharmony_ci     * |actual_size| will be ignored. It is assumed that |old_buffer| is still
941cb0ef41Sopenharmony_ci     * valid in this case and has not been modified.
951cb0ef41Sopenharmony_ci     *
961cb0ef41Sopenharmony_ci     * The default implementation uses the stdlib's `realloc()` function.
971cb0ef41Sopenharmony_ci     */
981cb0ef41Sopenharmony_ci    virtual void* ReallocateBufferMemory(void* old_buffer, size_t size,
991cb0ef41Sopenharmony_ci                                         size_t* actual_size);
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci    /**
1021cb0ef41Sopenharmony_ci     * Frees a buffer allocated with |ReallocateBufferMemory|.
1031cb0ef41Sopenharmony_ci     *
1041cb0ef41Sopenharmony_ci     * The default implementation uses the stdlib's `free()` function.
1051cb0ef41Sopenharmony_ci     */
1061cb0ef41Sopenharmony_ci    virtual void FreeBufferMemory(void* buffer);
1071cb0ef41Sopenharmony_ci  };
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci  explicit ValueSerializer(Isolate* isolate);
1101cb0ef41Sopenharmony_ci  ValueSerializer(Isolate* isolate, Delegate* delegate);
1111cb0ef41Sopenharmony_ci  ~ValueSerializer();
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  /**
1141cb0ef41Sopenharmony_ci   * Writes out a header, which includes the format version.
1151cb0ef41Sopenharmony_ci   */
1161cb0ef41Sopenharmony_ci  void WriteHeader();
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci  /**
1191cb0ef41Sopenharmony_ci   * Serializes a JavaScript value into the buffer.
1201cb0ef41Sopenharmony_ci   */
1211cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT Maybe<bool> WriteValue(Local<Context> context,
1221cb0ef41Sopenharmony_ci                                               Local<Value> value);
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  /**
1251cb0ef41Sopenharmony_ci   * Returns the stored data (allocated using the delegate's
1261cb0ef41Sopenharmony_ci   * ReallocateBufferMemory) and its size. This serializer should not be used
1271cb0ef41Sopenharmony_ci   * once the buffer is released. The contents are undefined if a previous write
1281cb0ef41Sopenharmony_ci   * has failed. Ownership of the buffer is transferred to the caller.
1291cb0ef41Sopenharmony_ci   */
1301cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT std::pair<uint8_t*, size_t> Release();
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  /**
1331cb0ef41Sopenharmony_ci   * Marks an ArrayBuffer as havings its contents transferred out of band.
1341cb0ef41Sopenharmony_ci   * Pass the corresponding ArrayBuffer in the deserializing context to
1351cb0ef41Sopenharmony_ci   * ValueDeserializer::TransferArrayBuffer.
1361cb0ef41Sopenharmony_ci   */
1371cb0ef41Sopenharmony_ci  void TransferArrayBuffer(uint32_t transfer_id,
1381cb0ef41Sopenharmony_ci                           Local<ArrayBuffer> array_buffer);
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  /**
1411cb0ef41Sopenharmony_ci   * Indicate whether to treat ArrayBufferView objects as host objects,
1421cb0ef41Sopenharmony_ci   * i.e. pass them to Delegate::WriteHostObject. This should not be
1431cb0ef41Sopenharmony_ci   * called when no Delegate was passed.
1441cb0ef41Sopenharmony_ci   *
1451cb0ef41Sopenharmony_ci   * The default is not to treat ArrayBufferViews as host objects.
1461cb0ef41Sopenharmony_ci   */
1471cb0ef41Sopenharmony_ci  void SetTreatArrayBufferViewsAsHostObjects(bool mode);
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  /**
1501cb0ef41Sopenharmony_ci   * Write raw data in various common formats to the buffer.
1511cb0ef41Sopenharmony_ci   * Note that integer types are written in base-128 varint format, not with a
1521cb0ef41Sopenharmony_ci   * binary copy. For use during an override of Delegate::WriteHostObject.
1531cb0ef41Sopenharmony_ci   */
1541cb0ef41Sopenharmony_ci  void WriteUint32(uint32_t value);
1551cb0ef41Sopenharmony_ci  void WriteUint64(uint64_t value);
1561cb0ef41Sopenharmony_ci  void WriteDouble(double value);
1571cb0ef41Sopenharmony_ci  void WriteRawBytes(const void* source, size_t length);
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci  ValueSerializer(const ValueSerializer&) = delete;
1601cb0ef41Sopenharmony_ci  void operator=(const ValueSerializer&) = delete;
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci private:
1631cb0ef41Sopenharmony_ci  struct PrivateData;
1641cb0ef41Sopenharmony_ci  PrivateData* private_;
1651cb0ef41Sopenharmony_ci};
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci/**
1681cb0ef41Sopenharmony_ci * Deserializes values from data written with ValueSerializer, or a compatible
1691cb0ef41Sopenharmony_ci * implementation.
1701cb0ef41Sopenharmony_ci */
1711cb0ef41Sopenharmony_ciclass V8_EXPORT ValueDeserializer {
1721cb0ef41Sopenharmony_ci public:
1731cb0ef41Sopenharmony_ci  class V8_EXPORT Delegate {
1741cb0ef41Sopenharmony_ci   public:
1751cb0ef41Sopenharmony_ci    virtual ~Delegate() = default;
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci    /**
1781cb0ef41Sopenharmony_ci     * The embedder overrides this method to read some kind of host object, if
1791cb0ef41Sopenharmony_ci     * possible. If not, a suitable exception should be thrown and
1801cb0ef41Sopenharmony_ci     * MaybeLocal<Object>() returned.
1811cb0ef41Sopenharmony_ci     */
1821cb0ef41Sopenharmony_ci    virtual MaybeLocal<Object> ReadHostObject(Isolate* isolate);
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci    /**
1851cb0ef41Sopenharmony_ci     * Get a WasmModuleObject given a transfer_id previously provided
1861cb0ef41Sopenharmony_ci     * by ValueSerializer::Delegate::GetWasmModuleTransferId
1871cb0ef41Sopenharmony_ci     */
1881cb0ef41Sopenharmony_ci    virtual MaybeLocal<WasmModuleObject> GetWasmModuleFromId(
1891cb0ef41Sopenharmony_ci        Isolate* isolate, uint32_t transfer_id);
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ci    /**
1921cb0ef41Sopenharmony_ci     * Get a SharedArrayBuffer given a clone_id previously provided
1931cb0ef41Sopenharmony_ci     * by ValueSerializer::Delegate::GetSharedArrayBufferId
1941cb0ef41Sopenharmony_ci     */
1951cb0ef41Sopenharmony_ci    virtual MaybeLocal<SharedArrayBuffer> GetSharedArrayBufferFromId(
1961cb0ef41Sopenharmony_ci        Isolate* isolate, uint32_t clone_id);
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci    /**
1991cb0ef41Sopenharmony_ci     * Returns whether shared values are supported. GetSharedValueFromId is only
2001cb0ef41Sopenharmony_ci     * called if SupportsSharedValues() returns true.
2011cb0ef41Sopenharmony_ci     */
2021cb0ef41Sopenharmony_ci    virtual bool SupportsSharedValues() const;
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci    /**
2051cb0ef41Sopenharmony_ci     * Get a value shared across Isolates given a shared_value_id provided by
2061cb0ef41Sopenharmony_ci     * ValueSerializer::Delegate::GetSharedValueId.
2071cb0ef41Sopenharmony_ci     */
2081cb0ef41Sopenharmony_ci    virtual MaybeLocal<Value> GetSharedValueFromId(Isolate* isolate,
2091cb0ef41Sopenharmony_ci                                                   uint32_t shared_value_id);
2101cb0ef41Sopenharmony_ci  };
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci  ValueDeserializer(Isolate* isolate, const uint8_t* data, size_t size);
2131cb0ef41Sopenharmony_ci  ValueDeserializer(Isolate* isolate, const uint8_t* data, size_t size,
2141cb0ef41Sopenharmony_ci                    Delegate* delegate);
2151cb0ef41Sopenharmony_ci  ~ValueDeserializer();
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci  /**
2181cb0ef41Sopenharmony_ci   * Reads and validates a header (including the format version).
2191cb0ef41Sopenharmony_ci   * May, for example, reject an invalid or unsupported wire format.
2201cb0ef41Sopenharmony_ci   */
2211cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT Maybe<bool> ReadHeader(Local<Context> context);
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci  /**
2241cb0ef41Sopenharmony_ci   * Deserializes a JavaScript value from the buffer.
2251cb0ef41Sopenharmony_ci   */
2261cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT MaybeLocal<Value> ReadValue(Local<Context> context);
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci  /**
2291cb0ef41Sopenharmony_ci   * Accepts the array buffer corresponding to the one passed previously to
2301cb0ef41Sopenharmony_ci   * ValueSerializer::TransferArrayBuffer.
2311cb0ef41Sopenharmony_ci   */
2321cb0ef41Sopenharmony_ci  void TransferArrayBuffer(uint32_t transfer_id,
2331cb0ef41Sopenharmony_ci                           Local<ArrayBuffer> array_buffer);
2341cb0ef41Sopenharmony_ci
2351cb0ef41Sopenharmony_ci  /**
2361cb0ef41Sopenharmony_ci   * Similar to TransferArrayBuffer, but for SharedArrayBuffer.
2371cb0ef41Sopenharmony_ci   * The id is not necessarily in the same namespace as unshared ArrayBuffer
2381cb0ef41Sopenharmony_ci   * objects.
2391cb0ef41Sopenharmony_ci   */
2401cb0ef41Sopenharmony_ci  void TransferSharedArrayBuffer(uint32_t id,
2411cb0ef41Sopenharmony_ci                                 Local<SharedArrayBuffer> shared_array_buffer);
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci  /**
2441cb0ef41Sopenharmony_ci   * Must be called before ReadHeader to enable support for reading the legacy
2451cb0ef41Sopenharmony_ci   * wire format (i.e., which predates this being shipped).
2461cb0ef41Sopenharmony_ci   *
2471cb0ef41Sopenharmony_ci   * Don't use this unless you need to read data written by previous versions of
2481cb0ef41Sopenharmony_ci   * blink::ScriptValueSerializer.
2491cb0ef41Sopenharmony_ci   */
2501cb0ef41Sopenharmony_ci  void SetSupportsLegacyWireFormat(bool supports_legacy_wire_format);
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  /**
2531cb0ef41Sopenharmony_ci   * Reads the underlying wire format version. Likely mostly to be useful to
2541cb0ef41Sopenharmony_ci   * legacy code reading old wire format versions. Must be called after
2551cb0ef41Sopenharmony_ci   * ReadHeader.
2561cb0ef41Sopenharmony_ci   */
2571cb0ef41Sopenharmony_ci  uint32_t GetWireFormatVersion() const;
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci  /**
2601cb0ef41Sopenharmony_ci   * Reads raw data in various common formats to the buffer.
2611cb0ef41Sopenharmony_ci   * Note that integer types are read in base-128 varint format, not with a
2621cb0ef41Sopenharmony_ci   * binary copy. For use during an override of Delegate::ReadHostObject.
2631cb0ef41Sopenharmony_ci   */
2641cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool ReadUint32(uint32_t* value);
2651cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool ReadUint64(uint64_t* value);
2661cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool ReadDouble(double* value);
2671cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool ReadRawBytes(size_t length, const void** data);
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci  ValueDeserializer(const ValueDeserializer&) = delete;
2701cb0ef41Sopenharmony_ci  void operator=(const ValueDeserializer&) = delete;
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci private:
2731cb0ef41Sopenharmony_ci  struct PrivateData;
2741cb0ef41Sopenharmony_ci  PrivateData* private_;
2751cb0ef41Sopenharmony_ci};
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ci}  // namespace v8
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci#endif  // INCLUDE_V8_VALUE_SERIALIZER_H_
280