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_CONTEXT_H_
61cb0ef41Sopenharmony_ci#define INCLUDE_V8_CONTEXT_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <stdint.h>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include <vector>
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include "v8-data.h"          // NOLINT(build/include_directory)
131cb0ef41Sopenharmony_ci#include "v8-local-handle.h"  // NOLINT(build/include_directory)
141cb0ef41Sopenharmony_ci#include "v8-maybe.h"         // NOLINT(build/include_directory)
151cb0ef41Sopenharmony_ci#include "v8-snapshot.h"      // NOLINT(build/include_directory)
161cb0ef41Sopenharmony_ci#include "v8config.h"         // NOLINT(build/include_directory)
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cinamespace v8 {
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ciclass Function;
211cb0ef41Sopenharmony_ciclass MicrotaskQueue;
221cb0ef41Sopenharmony_ciclass Object;
231cb0ef41Sopenharmony_ciclass ObjectTemplate;
241cb0ef41Sopenharmony_ciclass Value;
251cb0ef41Sopenharmony_ciclass String;
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci/**
281cb0ef41Sopenharmony_ci * A container for extension names.
291cb0ef41Sopenharmony_ci */
301cb0ef41Sopenharmony_ciclass V8_EXPORT ExtensionConfiguration {
311cb0ef41Sopenharmony_ci public:
321cb0ef41Sopenharmony_ci  ExtensionConfiguration() : name_count_(0), names_(nullptr) {}
331cb0ef41Sopenharmony_ci  ExtensionConfiguration(int name_count, const char* names[])
341cb0ef41Sopenharmony_ci      : name_count_(name_count), names_(names) {}
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci  const char** begin() const { return &names_[0]; }
371cb0ef41Sopenharmony_ci  const char** end() const { return &names_[name_count_]; }
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci private:
401cb0ef41Sopenharmony_ci  const int name_count_;
411cb0ef41Sopenharmony_ci  const char** names_;
421cb0ef41Sopenharmony_ci};
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci/**
451cb0ef41Sopenharmony_ci * A sandboxed execution context with its own set of built-in objects
461cb0ef41Sopenharmony_ci * and functions.
471cb0ef41Sopenharmony_ci */
481cb0ef41Sopenharmony_ciclass V8_EXPORT Context : public Data {
491cb0ef41Sopenharmony_ci public:
501cb0ef41Sopenharmony_ci  /**
511cb0ef41Sopenharmony_ci   * Returns the global proxy object.
521cb0ef41Sopenharmony_ci   *
531cb0ef41Sopenharmony_ci   * Global proxy object is a thin wrapper whose prototype points to actual
541cb0ef41Sopenharmony_ci   * context's global object with the properties like Object, etc. This is done
551cb0ef41Sopenharmony_ci   * that way for security reasons (for more details see
561cb0ef41Sopenharmony_ci   * https://wiki.mozilla.org/Gecko:SplitWindow).
571cb0ef41Sopenharmony_ci   *
581cb0ef41Sopenharmony_ci   * Please note that changes to global proxy object prototype most probably
591cb0ef41Sopenharmony_ci   * would break VM---v8 expects only global object as a prototype of global
601cb0ef41Sopenharmony_ci   * proxy object.
611cb0ef41Sopenharmony_ci   */
621cb0ef41Sopenharmony_ci  Local<Object> Global();
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  /**
651cb0ef41Sopenharmony_ci   * Detaches the global object from its context before
661cb0ef41Sopenharmony_ci   * the global object can be reused to create a new context.
671cb0ef41Sopenharmony_ci   */
681cb0ef41Sopenharmony_ci  void DetachGlobal();
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  /**
711cb0ef41Sopenharmony_ci   * Creates a new context and returns a handle to the newly allocated
721cb0ef41Sopenharmony_ci   * context.
731cb0ef41Sopenharmony_ci   *
741cb0ef41Sopenharmony_ci   * \param isolate The isolate in which to create the context.
751cb0ef41Sopenharmony_ci   *
761cb0ef41Sopenharmony_ci   * \param extensions An optional extension configuration containing
771cb0ef41Sopenharmony_ci   * the extensions to be installed in the newly created context.
781cb0ef41Sopenharmony_ci   *
791cb0ef41Sopenharmony_ci   * \param global_template An optional object template from which the
801cb0ef41Sopenharmony_ci   * global object for the newly created context will be created.
811cb0ef41Sopenharmony_ci   *
821cb0ef41Sopenharmony_ci   * \param global_object An optional global object to be reused for
831cb0ef41Sopenharmony_ci   * the newly created context. This global object must have been
841cb0ef41Sopenharmony_ci   * created by a previous call to Context::New with the same global
851cb0ef41Sopenharmony_ci   * template. The state of the global object will be completely reset
861cb0ef41Sopenharmony_ci   * and only object identify will remain.
871cb0ef41Sopenharmony_ci   */
881cb0ef41Sopenharmony_ci  static Local<Context> New(
891cb0ef41Sopenharmony_ci      Isolate* isolate, ExtensionConfiguration* extensions = nullptr,
901cb0ef41Sopenharmony_ci      MaybeLocal<ObjectTemplate> global_template = MaybeLocal<ObjectTemplate>(),
911cb0ef41Sopenharmony_ci      MaybeLocal<Value> global_object = MaybeLocal<Value>(),
921cb0ef41Sopenharmony_ci      DeserializeInternalFieldsCallback internal_fields_deserializer =
931cb0ef41Sopenharmony_ci          DeserializeInternalFieldsCallback(),
941cb0ef41Sopenharmony_ci      MicrotaskQueue* microtask_queue = nullptr);
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  /**
971cb0ef41Sopenharmony_ci   * Create a new context from a (non-default) context snapshot. There
981cb0ef41Sopenharmony_ci   * is no way to provide a global object template since we do not create
991cb0ef41Sopenharmony_ci   * a new global object from template, but we can reuse a global object.
1001cb0ef41Sopenharmony_ci   *
1011cb0ef41Sopenharmony_ci   * \param isolate See v8::Context::New.
1021cb0ef41Sopenharmony_ci   *
1031cb0ef41Sopenharmony_ci   * \param context_snapshot_index The index of the context snapshot to
1041cb0ef41Sopenharmony_ci   * deserialize from. Use v8::Context::New for the default snapshot.
1051cb0ef41Sopenharmony_ci   *
1061cb0ef41Sopenharmony_ci   * \param embedder_fields_deserializer Optional callback to deserialize
1071cb0ef41Sopenharmony_ci   * internal fields. It should match the SerializeInternalFieldCallback used
1081cb0ef41Sopenharmony_ci   * to serialize.
1091cb0ef41Sopenharmony_ci   *
1101cb0ef41Sopenharmony_ci   * \param extensions See v8::Context::New.
1111cb0ef41Sopenharmony_ci   *
1121cb0ef41Sopenharmony_ci   * \param global_object See v8::Context::New.
1131cb0ef41Sopenharmony_ci   */
1141cb0ef41Sopenharmony_ci  static MaybeLocal<Context> FromSnapshot(
1151cb0ef41Sopenharmony_ci      Isolate* isolate, size_t context_snapshot_index,
1161cb0ef41Sopenharmony_ci      DeserializeInternalFieldsCallback embedder_fields_deserializer =
1171cb0ef41Sopenharmony_ci          DeserializeInternalFieldsCallback(),
1181cb0ef41Sopenharmony_ci      ExtensionConfiguration* extensions = nullptr,
1191cb0ef41Sopenharmony_ci      MaybeLocal<Value> global_object = MaybeLocal<Value>(),
1201cb0ef41Sopenharmony_ci      MicrotaskQueue* microtask_queue = nullptr);
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  /**
1231cb0ef41Sopenharmony_ci   * Returns an global object that isn't backed by an actual context.
1241cb0ef41Sopenharmony_ci   *
1251cb0ef41Sopenharmony_ci   * The global template needs to have access checks with handlers installed.
1261cb0ef41Sopenharmony_ci   * If an existing global object is passed in, the global object is detached
1271cb0ef41Sopenharmony_ci   * from its context.
1281cb0ef41Sopenharmony_ci   *
1291cb0ef41Sopenharmony_ci   * Note that this is different from a detached context where all accesses to
1301cb0ef41Sopenharmony_ci   * the global proxy will fail. Instead, the access check handlers are invoked.
1311cb0ef41Sopenharmony_ci   *
1321cb0ef41Sopenharmony_ci   * It is also not possible to detach an object returned by this method.
1331cb0ef41Sopenharmony_ci   * Instead, the access check handlers need to return nothing to achieve the
1341cb0ef41Sopenharmony_ci   * same effect.
1351cb0ef41Sopenharmony_ci   *
1361cb0ef41Sopenharmony_ci   * It is possible, however, to create a new context from the global object
1371cb0ef41Sopenharmony_ci   * returned by this method.
1381cb0ef41Sopenharmony_ci   */
1391cb0ef41Sopenharmony_ci  static MaybeLocal<Object> NewRemoteContext(
1401cb0ef41Sopenharmony_ci      Isolate* isolate, Local<ObjectTemplate> global_template,
1411cb0ef41Sopenharmony_ci      MaybeLocal<Value> global_object = MaybeLocal<Value>());
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  /**
1441cb0ef41Sopenharmony_ci   * Sets the security token for the context.  To access an object in
1451cb0ef41Sopenharmony_ci   * another context, the security tokens must match.
1461cb0ef41Sopenharmony_ci   */
1471cb0ef41Sopenharmony_ci  void SetSecurityToken(Local<Value> token);
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  /** Restores the security token to the default value. */
1501cb0ef41Sopenharmony_ci  void UseDefaultSecurityToken();
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  /** Returns the security token of this context.*/
1531cb0ef41Sopenharmony_ci  Local<Value> GetSecurityToken();
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci  /**
1561cb0ef41Sopenharmony_ci   * Enter this context.  After entering a context, all code compiled
1571cb0ef41Sopenharmony_ci   * and run is compiled and run in this context.  If another context
1581cb0ef41Sopenharmony_ci   * is already entered, this old context is saved so it can be
1591cb0ef41Sopenharmony_ci   * restored when the new context is exited.
1601cb0ef41Sopenharmony_ci   */
1611cb0ef41Sopenharmony_ci  void Enter();
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci  /**
1641cb0ef41Sopenharmony_ci   * Exit this context.  Exiting the current context restores the
1651cb0ef41Sopenharmony_ci   * context that was in place when entering the current context.
1661cb0ef41Sopenharmony_ci   */
1671cb0ef41Sopenharmony_ci  void Exit();
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci  /**
1701cb0ef41Sopenharmony_ci   * Delegate to help with Deep freezing embedder-specific objects (such as
1711cb0ef41Sopenharmony_ci   * JSApiObjects) that can not be frozen natively.
1721cb0ef41Sopenharmony_ci   */
1731cb0ef41Sopenharmony_ci  class DeepFreezeDelegate {
1741cb0ef41Sopenharmony_ci   public:
1751cb0ef41Sopenharmony_ci    /**
1761cb0ef41Sopenharmony_ci     * Performs embedder-specific operations to freeze the provided embedder
1771cb0ef41Sopenharmony_ci     * object. The provided object *will* be frozen by DeepFreeze after this
1781cb0ef41Sopenharmony_ci     * function returns, so only embedder-specific objects need to be frozen.
1791cb0ef41Sopenharmony_ci     * This function *may not* create new JS objects or perform JS allocations.
1801cb0ef41Sopenharmony_ci     * Any v8 objects reachable from the provided embedder object that should
1811cb0ef41Sopenharmony_ci     * also be considered for freezing should be added to the children_out
1821cb0ef41Sopenharmony_ci     * parameter. Returns true if the operation completed successfully.
1831cb0ef41Sopenharmony_ci     */
1841cb0ef41Sopenharmony_ci    virtual bool FreezeEmbedderObjectAndGetChildren(
1851cb0ef41Sopenharmony_ci        Local<Object> obj, std::vector<Local<Object>>& children_out) = 0;
1861cb0ef41Sopenharmony_ci  };
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  /**
1891cb0ef41Sopenharmony_ci   * Attempts to recursively freeze all objects reachable from this context.
1901cb0ef41Sopenharmony_ci   * Some objects (generators, iterators, non-const closures) can not be frozen
1911cb0ef41Sopenharmony_ci   * and will cause this method to throw an error. An optional delegate can be
1921cb0ef41Sopenharmony_ci   * provided to help freeze embedder-specific objects.
1931cb0ef41Sopenharmony_ci   *
1941cb0ef41Sopenharmony_ci   * Freezing occurs in two steps:
1951cb0ef41Sopenharmony_ci   * 1. "Marking" where we iterate through all objects reachable by this
1961cb0ef41Sopenharmony_ci   *    context, accumulating a list of objects that need to be frozen and
1971cb0ef41Sopenharmony_ci   *    looking for objects that can't be frozen. This step is separated because
1981cb0ef41Sopenharmony_ci   *    it is more efficient when we can assume there is no garbage collection.
1991cb0ef41Sopenharmony_ci   * 2. "Freezing" where we go through the list of objects and freezing them.
2001cb0ef41Sopenharmony_ci   *    This effectively requires copying them so it may trigger garbage
2011cb0ef41Sopenharmony_ci   *    collection.
2021cb0ef41Sopenharmony_ci   */
2031cb0ef41Sopenharmony_ci  Maybe<void> DeepFreeze(DeepFreezeDelegate* delegate = nullptr);
2041cb0ef41Sopenharmony_ci
2051cb0ef41Sopenharmony_ci  /** Returns the isolate associated with a current context. */
2061cb0ef41Sopenharmony_ci  Isolate* GetIsolate();
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  /** Returns the microtask queue associated with a current context. */
2091cb0ef41Sopenharmony_ci  MicrotaskQueue* GetMicrotaskQueue();
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci  /** Sets the microtask queue associated with the current context. */
2121cb0ef41Sopenharmony_ci  void SetMicrotaskQueue(MicrotaskQueue* queue);
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci  /**
2151cb0ef41Sopenharmony_ci   * The field at kDebugIdIndex used to be reserved for the inspector.
2161cb0ef41Sopenharmony_ci   * It now serves no purpose.
2171cb0ef41Sopenharmony_ci   */
2181cb0ef41Sopenharmony_ci  enum EmbedderDataFields { kDebugIdIndex = 0 };
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci  /**
2211cb0ef41Sopenharmony_ci   * Return the number of fields allocated for embedder data.
2221cb0ef41Sopenharmony_ci   */
2231cb0ef41Sopenharmony_ci  uint32_t GetNumberOfEmbedderDataFields();
2241cb0ef41Sopenharmony_ci
2251cb0ef41Sopenharmony_ci  /**
2261cb0ef41Sopenharmony_ci   * Gets the embedder data with the given index, which must have been set by a
2271cb0ef41Sopenharmony_ci   * previous call to SetEmbedderData with the same index.
2281cb0ef41Sopenharmony_ci   */
2291cb0ef41Sopenharmony_ci  V8_INLINE Local<Value> GetEmbedderData(int index);
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_ci  /**
2321cb0ef41Sopenharmony_ci   * Gets the binding object used by V8 extras. Extra natives get a reference
2331cb0ef41Sopenharmony_ci   * to this object and can use it to "export" functionality by adding
2341cb0ef41Sopenharmony_ci   * properties. Extra natives can also "import" functionality by accessing
2351cb0ef41Sopenharmony_ci   * properties added by the embedder using the V8 API.
2361cb0ef41Sopenharmony_ci   */
2371cb0ef41Sopenharmony_ci  Local<Object> GetExtrasBindingObject();
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci  /**
2401cb0ef41Sopenharmony_ci   * Sets the embedder data with the given index, growing the data as
2411cb0ef41Sopenharmony_ci   * needed. Note that index 0 currently has a special meaning for Chrome's
2421cb0ef41Sopenharmony_ci   * debugger.
2431cb0ef41Sopenharmony_ci   */
2441cb0ef41Sopenharmony_ci  void SetEmbedderData(int index, Local<Value> value);
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_ci  /**
2471cb0ef41Sopenharmony_ci   * Gets a 2-byte-aligned native pointer from the embedder data with the given
2481cb0ef41Sopenharmony_ci   * index, which must have been set by a previous call to
2491cb0ef41Sopenharmony_ci   * SetAlignedPointerInEmbedderData with the same index. Note that index 0
2501cb0ef41Sopenharmony_ci   * currently has a special meaning for Chrome's debugger.
2511cb0ef41Sopenharmony_ci   */
2521cb0ef41Sopenharmony_ci  V8_INLINE void* GetAlignedPointerFromEmbedderData(int index);
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci  /**
2551cb0ef41Sopenharmony_ci   * Sets a 2-byte-aligned native pointer in the embedder data with the given
2561cb0ef41Sopenharmony_ci   * index, growing the data as needed. Note that index 0 currently has a
2571cb0ef41Sopenharmony_ci   * special meaning for Chrome's debugger.
2581cb0ef41Sopenharmony_ci   */
2591cb0ef41Sopenharmony_ci  void SetAlignedPointerInEmbedderData(int index, void* value);
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ci  /**
2621cb0ef41Sopenharmony_ci   * Control whether code generation from strings is allowed. Calling
2631cb0ef41Sopenharmony_ci   * this method with false will disable 'eval' and the 'Function'
2641cb0ef41Sopenharmony_ci   * constructor for code running in this context. If 'eval' or the
2651cb0ef41Sopenharmony_ci   * 'Function' constructor are used an exception will be thrown.
2661cb0ef41Sopenharmony_ci   *
2671cb0ef41Sopenharmony_ci   * If code generation from strings is not allowed the
2681cb0ef41Sopenharmony_ci   * V8::AllowCodeGenerationFromStrings callback will be invoked if
2691cb0ef41Sopenharmony_ci   * set before blocking the call to 'eval' or the 'Function'
2701cb0ef41Sopenharmony_ci   * constructor. If that callback returns true, the call will be
2711cb0ef41Sopenharmony_ci   * allowed, otherwise an exception will be thrown. If no callback is
2721cb0ef41Sopenharmony_ci   * set an exception will be thrown.
2731cb0ef41Sopenharmony_ci   */
2741cb0ef41Sopenharmony_ci  void AllowCodeGenerationFromStrings(bool allow);
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  /**
2771cb0ef41Sopenharmony_ci   * Returns true if code generation from strings is allowed for the context.
2781cb0ef41Sopenharmony_ci   * For more details see AllowCodeGenerationFromStrings(bool) documentation.
2791cb0ef41Sopenharmony_ci   */
2801cb0ef41Sopenharmony_ci  bool IsCodeGenerationFromStringsAllowed() const;
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_ci  /**
2831cb0ef41Sopenharmony_ci   * Sets the error description for the exception that is thrown when
2841cb0ef41Sopenharmony_ci   * code generation from strings is not allowed and 'eval' or the 'Function'
2851cb0ef41Sopenharmony_ci   * constructor are called.
2861cb0ef41Sopenharmony_ci   */
2871cb0ef41Sopenharmony_ci  void SetErrorMessageForCodeGenerationFromStrings(Local<String> message);
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci  /**
2901cb0ef41Sopenharmony_ci   * Sets the error description for the exception that is thrown when
2911cb0ef41Sopenharmony_ci   * wasm code generation is not allowed.
2921cb0ef41Sopenharmony_ci   */
2931cb0ef41Sopenharmony_ci  void SetErrorMessageForWasmCodeGeneration(Local<String> message);
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  /**
2961cb0ef41Sopenharmony_ci   * Return data that was previously attached to the context snapshot via
2971cb0ef41Sopenharmony_ci   * SnapshotCreator, and removes the reference to it.
2981cb0ef41Sopenharmony_ci   * Repeated call with the same index returns an empty MaybeLocal.
2991cb0ef41Sopenharmony_ci   */
3001cb0ef41Sopenharmony_ci  template <class T>
3011cb0ef41Sopenharmony_ci  V8_INLINE MaybeLocal<T> GetDataFromSnapshotOnce(size_t index);
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ci  /**
3041cb0ef41Sopenharmony_ci   * If callback is set, abort any attempt to execute JavaScript in this
3051cb0ef41Sopenharmony_ci   * context, call the specified callback, and throw an exception.
3061cb0ef41Sopenharmony_ci   * To unset abort, pass nullptr as callback.
3071cb0ef41Sopenharmony_ci   */
3081cb0ef41Sopenharmony_ci  using AbortScriptExecutionCallback = void (*)(Isolate* isolate,
3091cb0ef41Sopenharmony_ci                                                Local<Context> context);
3101cb0ef41Sopenharmony_ci  void SetAbortScriptExecution(AbortScriptExecutionCallback callback);
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci  /**
3131cb0ef41Sopenharmony_ci   * Returns the value that was set or restored by
3141cb0ef41Sopenharmony_ci   * SetContinuationPreservedEmbedderData(), if any.
3151cb0ef41Sopenharmony_ci   */
3161cb0ef41Sopenharmony_ci  Local<Value> GetContinuationPreservedEmbedderData() const;
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci  /**
3191cb0ef41Sopenharmony_ci   * Sets a value that will be stored on continuations and reset while the
3201cb0ef41Sopenharmony_ci   * continuation runs.
3211cb0ef41Sopenharmony_ci   */
3221cb0ef41Sopenharmony_ci  void SetContinuationPreservedEmbedderData(Local<Value> context);
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci  /**
3251cb0ef41Sopenharmony_ci   * Set or clear hooks to be invoked for promise lifecycle operations.
3261cb0ef41Sopenharmony_ci   * To clear a hook, set it to an empty v8::Function. Each function will
3271cb0ef41Sopenharmony_ci   * receive the observed promise as the first argument. If a chaining
3281cb0ef41Sopenharmony_ci   * operation is used on a promise, the init will additionally receive
3291cb0ef41Sopenharmony_ci   * the parent promise as the second argument.
3301cb0ef41Sopenharmony_ci   */
3311cb0ef41Sopenharmony_ci  void SetPromiseHooks(Local<Function> init_hook, Local<Function> before_hook,
3321cb0ef41Sopenharmony_ci                       Local<Function> after_hook,
3331cb0ef41Sopenharmony_ci                       Local<Function> resolve_hook);
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ci  bool HasTemplateLiteralObject(Local<Value> object);
3361cb0ef41Sopenharmony_ci  /**
3371cb0ef41Sopenharmony_ci   * Stack-allocated class which sets the execution context for all
3381cb0ef41Sopenharmony_ci   * operations executed within a local scope.
3391cb0ef41Sopenharmony_ci   */
3401cb0ef41Sopenharmony_ci  class V8_NODISCARD Scope {
3411cb0ef41Sopenharmony_ci   public:
3421cb0ef41Sopenharmony_ci    explicit V8_INLINE Scope(Local<Context> context) : context_(context) {
3431cb0ef41Sopenharmony_ci      context_->Enter();
3441cb0ef41Sopenharmony_ci    }
3451cb0ef41Sopenharmony_ci    V8_INLINE ~Scope() { context_->Exit(); }
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci   private:
3481cb0ef41Sopenharmony_ci    Local<Context> context_;
3491cb0ef41Sopenharmony_ci  };
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ci  /**
3521cb0ef41Sopenharmony_ci   * Stack-allocated class to support the backup incumbent settings object
3531cb0ef41Sopenharmony_ci   * stack.
3541cb0ef41Sopenharmony_ci   * https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack
3551cb0ef41Sopenharmony_ci   */
3561cb0ef41Sopenharmony_ci  class V8_EXPORT V8_NODISCARD BackupIncumbentScope final {
3571cb0ef41Sopenharmony_ci   public:
3581cb0ef41Sopenharmony_ci    /**
3591cb0ef41Sopenharmony_ci     * |backup_incumbent_context| is pushed onto the backup incumbent settings
3601cb0ef41Sopenharmony_ci     * object stack.
3611cb0ef41Sopenharmony_ci     */
3621cb0ef41Sopenharmony_ci    explicit BackupIncumbentScope(Local<Context> backup_incumbent_context);
3631cb0ef41Sopenharmony_ci    ~BackupIncumbentScope();
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ci   private:
3661cb0ef41Sopenharmony_ci    friend class internal::Isolate;
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci    uintptr_t JSStackComparableAddressPrivate() const {
3691cb0ef41Sopenharmony_ci      return js_stack_comparable_address_;
3701cb0ef41Sopenharmony_ci    }
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci    Local<Context> backup_incumbent_context_;
3731cb0ef41Sopenharmony_ci    uintptr_t js_stack_comparable_address_ = 0;
3741cb0ef41Sopenharmony_ci    const BackupIncumbentScope* prev_ = nullptr;
3751cb0ef41Sopenharmony_ci  };
3761cb0ef41Sopenharmony_ci
3771cb0ef41Sopenharmony_ci  V8_INLINE static Context* Cast(Data* data);
3781cb0ef41Sopenharmony_ci
3791cb0ef41Sopenharmony_ci private:
3801cb0ef41Sopenharmony_ci  friend class Value;
3811cb0ef41Sopenharmony_ci  friend class Script;
3821cb0ef41Sopenharmony_ci  friend class Object;
3831cb0ef41Sopenharmony_ci  friend class Function;
3841cb0ef41Sopenharmony_ci
3851cb0ef41Sopenharmony_ci  static void CheckCast(Data* obj);
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ci  internal::Address* GetDataFromSnapshotOnce(size_t index);
3881cb0ef41Sopenharmony_ci  Local<Value> SlowGetEmbedderData(int index);
3891cb0ef41Sopenharmony_ci  void* SlowGetAlignedPointerFromEmbedderData(int index);
3901cb0ef41Sopenharmony_ci};
3911cb0ef41Sopenharmony_ci
3921cb0ef41Sopenharmony_ci// --- Implementation ---
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ciLocal<Value> Context::GetEmbedderData(int index) {
3951cb0ef41Sopenharmony_ci#ifndef V8_ENABLE_CHECKS
3961cb0ef41Sopenharmony_ci  using A = internal::Address;
3971cb0ef41Sopenharmony_ci  using I = internal::Internals;
3981cb0ef41Sopenharmony_ci  A ctx = internal::ValueHelper::ValueAsAddress(this);
3991cb0ef41Sopenharmony_ci  A embedder_data =
4001cb0ef41Sopenharmony_ci      I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
4011cb0ef41Sopenharmony_ci  int value_offset =
4021cb0ef41Sopenharmony_ci      I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);
4031cb0ef41Sopenharmony_ci  A value = I::ReadRawField<A>(embedder_data, value_offset);
4041cb0ef41Sopenharmony_ci#ifdef V8_COMPRESS_POINTERS
4051cb0ef41Sopenharmony_ci  // We read the full pointer value and then decompress it in order to avoid
4061cb0ef41Sopenharmony_ci  // dealing with potential endiannes issues.
4071cb0ef41Sopenharmony_ci  value = I::DecompressTaggedField(embedder_data, static_cast<uint32_t>(value));
4081cb0ef41Sopenharmony_ci#endif
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ci  auto isolate = reinterpret_cast<v8::Isolate*>(
4111cb0ef41Sopenharmony_ci      internal::IsolateFromNeverReadOnlySpaceObject(ctx));
4121cb0ef41Sopenharmony_ci  return Local<Value>::New(isolate, value);
4131cb0ef41Sopenharmony_ci#else
4141cb0ef41Sopenharmony_ci  return SlowGetEmbedderData(index);
4151cb0ef41Sopenharmony_ci#endif
4161cb0ef41Sopenharmony_ci}
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_civoid* Context::GetAlignedPointerFromEmbedderData(int index) {
4191cb0ef41Sopenharmony_ci#if !defined(V8_ENABLE_CHECKS)
4201cb0ef41Sopenharmony_ci  using A = internal::Address;
4211cb0ef41Sopenharmony_ci  using I = internal::Internals;
4221cb0ef41Sopenharmony_ci  A ctx = internal::ValueHelper::ValueAsAddress(this);
4231cb0ef41Sopenharmony_ci  A embedder_data =
4241cb0ef41Sopenharmony_ci      I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
4251cb0ef41Sopenharmony_ci  int value_offset = I::kEmbedderDataArrayHeaderSize +
4261cb0ef41Sopenharmony_ci                     (I::kEmbedderDataSlotSize * index) +
4271cb0ef41Sopenharmony_ci                     I::kEmbedderDataSlotExternalPointerOffset;
4281cb0ef41Sopenharmony_ci  Isolate* isolate = I::GetIsolateForSandbox(ctx);
4291cb0ef41Sopenharmony_ci  return reinterpret_cast<void*>(
4301cb0ef41Sopenharmony_ci      I::ReadExternalPointerField<internal::kEmbedderDataSlotPayloadTag>(
4311cb0ef41Sopenharmony_ci          isolate, embedder_data, value_offset));
4321cb0ef41Sopenharmony_ci#else
4331cb0ef41Sopenharmony_ci  return SlowGetAlignedPointerFromEmbedderData(index);
4341cb0ef41Sopenharmony_ci#endif
4351cb0ef41Sopenharmony_ci}
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_citemplate <class T>
4381cb0ef41Sopenharmony_ciMaybeLocal<T> Context::GetDataFromSnapshotOnce(size_t index) {
4391cb0ef41Sopenharmony_ci  auto slot = GetDataFromSnapshotOnce(index);
4401cb0ef41Sopenharmony_ci  if (slot) {
4411cb0ef41Sopenharmony_ci    internal::PerformCastCheck(internal::ValueHelper::SlotAsValue<T>(slot));
4421cb0ef41Sopenharmony_ci  }
4431cb0ef41Sopenharmony_ci  return Local<T>::FromSlot(slot);
4441cb0ef41Sopenharmony_ci}
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ciContext* Context::Cast(v8::Data* data) {
4471cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_CHECKS
4481cb0ef41Sopenharmony_ci  CheckCast(data);
4491cb0ef41Sopenharmony_ci#endif
4501cb0ef41Sopenharmony_ci  return static_cast<Context*>(data);
4511cb0ef41Sopenharmony_ci}
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_ci}  // namespace v8
4541cb0ef41Sopenharmony_ci
4551cb0ef41Sopenharmony_ci#endif  // INCLUDE_V8_CONTEXT_H_
456