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_SNAPSHOT_H_
61cb0ef41Sopenharmony_ci#define INCLUDE_V8_SNAPSHOT_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "v8-internal.h"      // NOLINT(build/include_directory)
91cb0ef41Sopenharmony_ci#include "v8-local-handle.h"  // NOLINT(build/include_directory)
101cb0ef41Sopenharmony_ci#include "v8config.h"         // NOLINT(build/include_directory)
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace v8 {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciclass Object;
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ciclass V8_EXPORT StartupData {
171cb0ef41Sopenharmony_ci public:
181cb0ef41Sopenharmony_ci  /**
191cb0ef41Sopenharmony_ci   * Whether the data created can be rehashed and and the hash seed can be
201cb0ef41Sopenharmony_ci   * recomputed when deserialized.
211cb0ef41Sopenharmony_ci   * Only valid for StartupData returned by SnapshotCreator::CreateBlob().
221cb0ef41Sopenharmony_ci   */
231cb0ef41Sopenharmony_ci  bool CanBeRehashed() const;
241cb0ef41Sopenharmony_ci  /**
251cb0ef41Sopenharmony_ci   * Allows embedders to verify whether the data is valid for the current
261cb0ef41Sopenharmony_ci   * V8 instance.
271cb0ef41Sopenharmony_ci   */
281cb0ef41Sopenharmony_ci  bool IsValid() const;
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  const char* data;
311cb0ef41Sopenharmony_ci  int raw_size;
321cb0ef41Sopenharmony_ci};
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci/**
351cb0ef41Sopenharmony_ci * Callback and supporting data used in SnapshotCreator to implement embedder
361cb0ef41Sopenharmony_ci * logic to serialize internal fields.
371cb0ef41Sopenharmony_ci * Internal fields that directly reference V8 objects are serialized without
381cb0ef41Sopenharmony_ci * calling this callback. Internal fields that contain aligned pointers are
391cb0ef41Sopenharmony_ci * serialized by this callback if it returns non-zero result. Otherwise it is
401cb0ef41Sopenharmony_ci * serialized verbatim.
411cb0ef41Sopenharmony_ci */
421cb0ef41Sopenharmony_cistruct SerializeInternalFieldsCallback {
431cb0ef41Sopenharmony_ci  using CallbackFunction = StartupData (*)(Local<Object> holder, int index,
441cb0ef41Sopenharmony_ci                                           void* data);
451cb0ef41Sopenharmony_ci  SerializeInternalFieldsCallback(CallbackFunction function = nullptr,
461cb0ef41Sopenharmony_ci                                  void* data_arg = nullptr)
471cb0ef41Sopenharmony_ci      : callback(function), data(data_arg) {}
481cb0ef41Sopenharmony_ci  CallbackFunction callback;
491cb0ef41Sopenharmony_ci  void* data;
501cb0ef41Sopenharmony_ci};
511cb0ef41Sopenharmony_ci// Note that these fields are called "internal fields" in the API and called
521cb0ef41Sopenharmony_ci// "embedder fields" within V8.
531cb0ef41Sopenharmony_ciusing SerializeEmbedderFieldsCallback = SerializeInternalFieldsCallback;
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci/**
561cb0ef41Sopenharmony_ci * Callback and supporting data used to implement embedder logic to deserialize
571cb0ef41Sopenharmony_ci * internal fields.
581cb0ef41Sopenharmony_ci */
591cb0ef41Sopenharmony_cistruct DeserializeInternalFieldsCallback {
601cb0ef41Sopenharmony_ci  using CallbackFunction = void (*)(Local<Object> holder, int index,
611cb0ef41Sopenharmony_ci                                    StartupData payload, void* data);
621cb0ef41Sopenharmony_ci  DeserializeInternalFieldsCallback(CallbackFunction function = nullptr,
631cb0ef41Sopenharmony_ci                                    void* data_arg = nullptr)
641cb0ef41Sopenharmony_ci      : callback(function), data(data_arg) {}
651cb0ef41Sopenharmony_ci  void (*callback)(Local<Object> holder, int index, StartupData payload,
661cb0ef41Sopenharmony_ci                   void* data);
671cb0ef41Sopenharmony_ci  void* data;
681cb0ef41Sopenharmony_ci};
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ciusing DeserializeEmbedderFieldsCallback = DeserializeInternalFieldsCallback;
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci/**
731cb0ef41Sopenharmony_ci * Helper class to create a snapshot data blob.
741cb0ef41Sopenharmony_ci *
751cb0ef41Sopenharmony_ci * The Isolate used by a SnapshotCreator is owned by it, and will be entered
761cb0ef41Sopenharmony_ci * and exited by the constructor and destructor, respectively; The destructor
771cb0ef41Sopenharmony_ci * will also destroy the Isolate. Experimental language features, including
781cb0ef41Sopenharmony_ci * those available by default, are not available while creating a snapshot.
791cb0ef41Sopenharmony_ci */
801cb0ef41Sopenharmony_ciclass V8_EXPORT SnapshotCreator {
811cb0ef41Sopenharmony_ci public:
821cb0ef41Sopenharmony_ci  enum class FunctionCodeHandling { kClear, kKeep };
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  /**
851cb0ef41Sopenharmony_ci   * Initialize and enter an isolate, and set it up for serialization.
861cb0ef41Sopenharmony_ci   * The isolate is either created from scratch or from an existing snapshot.
871cb0ef41Sopenharmony_ci   * The caller keeps ownership of the argument snapshot.
881cb0ef41Sopenharmony_ci   * \param existing_blob existing snapshot from which to create this one.
891cb0ef41Sopenharmony_ci   * \param external_references a null-terminated array of external references
901cb0ef41Sopenharmony_ci   *        that must be equivalent to CreateParams::external_references.
911cb0ef41Sopenharmony_ci   * \param owns_isolate whether this SnapshotCreator should call
921cb0ef41Sopenharmony_ci   *        v8::Isolate::Dispose() during its destructor.
931cb0ef41Sopenharmony_ci   */
941cb0ef41Sopenharmony_ci  SnapshotCreator(Isolate* isolate,
951cb0ef41Sopenharmony_ci                  const intptr_t* external_references = nullptr,
961cb0ef41Sopenharmony_ci                  const StartupData* existing_blob = nullptr,
971cb0ef41Sopenharmony_ci                  bool owns_isolate = true);
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  /**
1001cb0ef41Sopenharmony_ci   * Create and enter an isolate, and set it up for serialization.
1011cb0ef41Sopenharmony_ci   * The isolate is either created from scratch or from an existing snapshot.
1021cb0ef41Sopenharmony_ci   * The caller keeps ownership of the argument snapshot.
1031cb0ef41Sopenharmony_ci   * \param existing_blob existing snapshot from which to create this one.
1041cb0ef41Sopenharmony_ci   * \param external_references a null-terminated array of external references
1051cb0ef41Sopenharmony_ci   *        that must be equivalent to CreateParams::external_references.
1061cb0ef41Sopenharmony_ci   */
1071cb0ef41Sopenharmony_ci  SnapshotCreator(const intptr_t* external_references = nullptr,
1081cb0ef41Sopenharmony_ci                  const StartupData* existing_blob = nullptr);
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  /**
1111cb0ef41Sopenharmony_ci   * Destroy the snapshot creator, and exit and dispose of the Isolate
1121cb0ef41Sopenharmony_ci   * associated with it.
1131cb0ef41Sopenharmony_ci   */
1141cb0ef41Sopenharmony_ci  ~SnapshotCreator();
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci  /**
1171cb0ef41Sopenharmony_ci   * \returns the isolate prepared by the snapshot creator.
1181cb0ef41Sopenharmony_ci   */
1191cb0ef41Sopenharmony_ci  Isolate* GetIsolate();
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci  /**
1221cb0ef41Sopenharmony_ci   * Set the default context to be included in the snapshot blob.
1231cb0ef41Sopenharmony_ci   * The snapshot will not contain the global proxy, and we expect one or a
1241cb0ef41Sopenharmony_ci   * global object template to create one, to be provided upon deserialization.
1251cb0ef41Sopenharmony_ci   *
1261cb0ef41Sopenharmony_ci   * \param callback optional callback to serialize internal fields.
1271cb0ef41Sopenharmony_ci   */
1281cb0ef41Sopenharmony_ci  void SetDefaultContext(Local<Context> context,
1291cb0ef41Sopenharmony_ci                         SerializeInternalFieldsCallback callback =
1301cb0ef41Sopenharmony_ci                             SerializeInternalFieldsCallback());
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  /**
1331cb0ef41Sopenharmony_ci   * Add additional context to be included in the snapshot blob.
1341cb0ef41Sopenharmony_ci   * The snapshot will include the global proxy.
1351cb0ef41Sopenharmony_ci   *
1361cb0ef41Sopenharmony_ci   * \param callback optional callback to serialize internal fields.
1371cb0ef41Sopenharmony_ci   *
1381cb0ef41Sopenharmony_ci   * \returns the index of the context in the snapshot blob.
1391cb0ef41Sopenharmony_ci   */
1401cb0ef41Sopenharmony_ci  size_t AddContext(Local<Context> context,
1411cb0ef41Sopenharmony_ci                    SerializeInternalFieldsCallback callback =
1421cb0ef41Sopenharmony_ci                        SerializeInternalFieldsCallback());
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci  /**
1451cb0ef41Sopenharmony_ci   * Attach arbitrary V8::Data to the context snapshot, which can be retrieved
1461cb0ef41Sopenharmony_ci   * via Context::GetDataFromSnapshotOnce after deserialization. This data does
1471cb0ef41Sopenharmony_ci   * not survive when a new snapshot is created from an existing snapshot.
1481cb0ef41Sopenharmony_ci   * \returns the index for retrieval.
1491cb0ef41Sopenharmony_ci   */
1501cb0ef41Sopenharmony_ci  template <class T>
1511cb0ef41Sopenharmony_ci  V8_INLINE size_t AddData(Local<Context> context, Local<T> object);
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  /**
1541cb0ef41Sopenharmony_ci   * Attach arbitrary V8::Data to the isolate snapshot, which can be retrieved
1551cb0ef41Sopenharmony_ci   * via Isolate::GetDataFromSnapshotOnce after deserialization. This data does
1561cb0ef41Sopenharmony_ci   * not survive when a new snapshot is created from an existing snapshot.
1571cb0ef41Sopenharmony_ci   * \returns the index for retrieval.
1581cb0ef41Sopenharmony_ci   */
1591cb0ef41Sopenharmony_ci  template <class T>
1601cb0ef41Sopenharmony_ci  V8_INLINE size_t AddData(Local<T> object);
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  /**
1631cb0ef41Sopenharmony_ci   * Created a snapshot data blob.
1641cb0ef41Sopenharmony_ci   * This must not be called from within a handle scope.
1651cb0ef41Sopenharmony_ci   * \param function_code_handling whether to include compiled function code
1661cb0ef41Sopenharmony_ci   *        in the snapshot.
1671cb0ef41Sopenharmony_ci   * \returns { nullptr, 0 } on failure, and a startup snapshot on success. The
1681cb0ef41Sopenharmony_ci   *        caller acquires ownership of the data array in the return value.
1691cb0ef41Sopenharmony_ci   */
1701cb0ef41Sopenharmony_ci  StartupData CreateBlob(FunctionCodeHandling function_code_handling);
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  // Disallow copying and assigning.
1731cb0ef41Sopenharmony_ci  SnapshotCreator(const SnapshotCreator&) = delete;
1741cb0ef41Sopenharmony_ci  void operator=(const SnapshotCreator&) = delete;
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci private:
1771cb0ef41Sopenharmony_ci  size_t AddData(Local<Context> context, internal::Address object);
1781cb0ef41Sopenharmony_ci  size_t AddData(internal::Address object);
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci  void* data_;
1811cb0ef41Sopenharmony_ci};
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_citemplate <class T>
1841cb0ef41Sopenharmony_cisize_t SnapshotCreator::AddData(Local<Context> context, Local<T> object) {
1851cb0ef41Sopenharmony_ci  return AddData(context, internal::ValueHelper::ValueAsAddress(*object));
1861cb0ef41Sopenharmony_ci}
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_citemplate <class T>
1891cb0ef41Sopenharmony_cisize_t SnapshotCreator::AddData(Local<T> object) {
1901cb0ef41Sopenharmony_ci  return AddData(internal::ValueHelper::ValueAsAddress(*object));
1911cb0ef41Sopenharmony_ci}
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci}  // namespace v8
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci#endif  // INCLUDE_V8_SNAPSHOT_H_
196