11cb0ef41Sopenharmony_ci// Copyright 2014 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 V8_UTIL_H_
61cb0ef41Sopenharmony_ci#define V8_UTIL_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <assert.h>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include <map>
111cb0ef41Sopenharmony_ci#include <vector>
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci#include "v8-function-callback.h"  // NOLINT(build/include_directory)
141cb0ef41Sopenharmony_ci#include "v8-persistent-handle.h"  // NOLINT(build/include_directory)
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci/**
171cb0ef41Sopenharmony_ci * Support for Persistent containers.
181cb0ef41Sopenharmony_ci *
191cb0ef41Sopenharmony_ci * C++11 embedders can use STL containers with Global values,
201cb0ef41Sopenharmony_ci * but pre-C++11 does not support the required move semantic and hence
211cb0ef41Sopenharmony_ci * may want these container classes.
221cb0ef41Sopenharmony_ci */
231cb0ef41Sopenharmony_cinamespace v8 {
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_citemplate <typename K, typename V, typename Traits>
261cb0ef41Sopenharmony_ciclass GlobalValueMap;
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_citypedef uintptr_t PersistentContainerValue;
291cb0ef41Sopenharmony_cistatic const uintptr_t kPersistentContainerNotFound = 0;
301cb0ef41Sopenharmony_cienum PersistentContainerCallbackType {
311cb0ef41Sopenharmony_ci  kNotWeak,
321cb0ef41Sopenharmony_ci  // These correspond to v8::WeakCallbackType
331cb0ef41Sopenharmony_ci  kWeakWithParameter,
341cb0ef41Sopenharmony_ci  kWeakWithInternalFields
351cb0ef41Sopenharmony_ci};
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci/**
381cb0ef41Sopenharmony_ci * A default trait implementation for PersistentValueMap which uses std::map
391cb0ef41Sopenharmony_ci * as a backing map.
401cb0ef41Sopenharmony_ci *
411cb0ef41Sopenharmony_ci * Users will have to implement their own weak callbacks & dispose traits.
421cb0ef41Sopenharmony_ci */
431cb0ef41Sopenharmony_citemplate<typename K, typename V>
441cb0ef41Sopenharmony_ciclass StdMapTraits {
451cb0ef41Sopenharmony_ci public:
461cb0ef41Sopenharmony_ci  // STL map & related:
471cb0ef41Sopenharmony_ci  typedef std::map<K, PersistentContainerValue> Impl;
481cb0ef41Sopenharmony_ci  typedef typename Impl::iterator Iterator;
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  static bool Empty(Impl* impl) { return impl->empty(); }
511cb0ef41Sopenharmony_ci  static size_t Size(Impl* impl) { return impl->size(); }
521cb0ef41Sopenharmony_ci  static void Swap(Impl& a, Impl& b) { std::swap(a, b); }
531cb0ef41Sopenharmony_ci  static Iterator Begin(Impl* impl) { return impl->begin(); }
541cb0ef41Sopenharmony_ci  static Iterator End(Impl* impl) { return impl->end(); }
551cb0ef41Sopenharmony_ci  static K Key(Iterator it) { return it->first; }
561cb0ef41Sopenharmony_ci  static PersistentContainerValue Value(Iterator it) { return it->second; }
571cb0ef41Sopenharmony_ci  static PersistentContainerValue Set(Impl* impl, K key,
581cb0ef41Sopenharmony_ci      PersistentContainerValue value) {
591cb0ef41Sopenharmony_ci    std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
601cb0ef41Sopenharmony_ci    PersistentContainerValue old_value = kPersistentContainerNotFound;
611cb0ef41Sopenharmony_ci    if (!res.second) {
621cb0ef41Sopenharmony_ci      old_value = res.first->second;
631cb0ef41Sopenharmony_ci      res.first->second = value;
641cb0ef41Sopenharmony_ci    }
651cb0ef41Sopenharmony_ci    return old_value;
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci  static PersistentContainerValue Get(Impl* impl, K key) {
681cb0ef41Sopenharmony_ci    Iterator it = impl->find(key);
691cb0ef41Sopenharmony_ci    if (it == impl->end()) return kPersistentContainerNotFound;
701cb0ef41Sopenharmony_ci    return it->second;
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci  static PersistentContainerValue Remove(Impl* impl, K key) {
731cb0ef41Sopenharmony_ci    Iterator it = impl->find(key);
741cb0ef41Sopenharmony_ci    if (it == impl->end()) return kPersistentContainerNotFound;
751cb0ef41Sopenharmony_ci    PersistentContainerValue value = it->second;
761cb0ef41Sopenharmony_ci    impl->erase(it);
771cb0ef41Sopenharmony_ci    return value;
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci};
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci/**
831cb0ef41Sopenharmony_ci * A default trait implementation for PersistentValueMap, which inherits
841cb0ef41Sopenharmony_ci * a std:map backing map from StdMapTraits and holds non-weak persistent
851cb0ef41Sopenharmony_ci * objects and has no special Dispose handling.
861cb0ef41Sopenharmony_ci *
871cb0ef41Sopenharmony_ci * You should not derive from this class, since MapType depends on the
881cb0ef41Sopenharmony_ci * surrounding class, and hence a subclass cannot simply inherit the methods.
891cb0ef41Sopenharmony_ci */
901cb0ef41Sopenharmony_citemplate<typename K, typename V>
911cb0ef41Sopenharmony_ciclass DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
921cb0ef41Sopenharmony_ci public:
931cb0ef41Sopenharmony_ci  // Weak callback & friends:
941cb0ef41Sopenharmony_ci  static const PersistentContainerCallbackType kCallbackType = kNotWeak;
951cb0ef41Sopenharmony_ci  typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
961cb0ef41Sopenharmony_ci      MapType;
971cb0ef41Sopenharmony_ci  typedef void WeakCallbackDataType;
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  static WeakCallbackDataType* WeakCallbackParameter(
1001cb0ef41Sopenharmony_ci      MapType* map, const K& key, Local<V> value) {
1011cb0ef41Sopenharmony_ci    return nullptr;
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci  static MapType* MapFromWeakCallbackInfo(
1041cb0ef41Sopenharmony_ci      const WeakCallbackInfo<WeakCallbackDataType>& data) {
1051cb0ef41Sopenharmony_ci    return nullptr;
1061cb0ef41Sopenharmony_ci  }
1071cb0ef41Sopenharmony_ci  static K KeyFromWeakCallbackInfo(
1081cb0ef41Sopenharmony_ci      const WeakCallbackInfo<WeakCallbackDataType>& data) {
1091cb0ef41Sopenharmony_ci    return K();
1101cb0ef41Sopenharmony_ci  }
1111cb0ef41Sopenharmony_ci  static void DisposeCallbackData(WeakCallbackDataType* data) { }
1121cb0ef41Sopenharmony_ci  static void Dispose(Isolate* isolate, Global<V> value, K key) {}
1131cb0ef41Sopenharmony_ci};
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_citemplate <typename K, typename V>
1171cb0ef41Sopenharmony_ciclass DefaultGlobalMapTraits : public StdMapTraits<K, V> {
1181cb0ef41Sopenharmony_ci private:
1191cb0ef41Sopenharmony_ci  template <typename T>
1201cb0ef41Sopenharmony_ci  struct RemovePointer;
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci public:
1231cb0ef41Sopenharmony_ci  // Weak callback & friends:
1241cb0ef41Sopenharmony_ci  static const PersistentContainerCallbackType kCallbackType = kNotWeak;
1251cb0ef41Sopenharmony_ci  typedef GlobalValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
1261cb0ef41Sopenharmony_ci  typedef void WeakCallbackDataType;
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
1291cb0ef41Sopenharmony_ci                                                     Local<V> value) {
1301cb0ef41Sopenharmony_ci    return nullptr;
1311cb0ef41Sopenharmony_ci  }
1321cb0ef41Sopenharmony_ci  static MapType* MapFromWeakCallbackInfo(
1331cb0ef41Sopenharmony_ci      const WeakCallbackInfo<WeakCallbackDataType>& data) {
1341cb0ef41Sopenharmony_ci    return nullptr;
1351cb0ef41Sopenharmony_ci  }
1361cb0ef41Sopenharmony_ci  static K KeyFromWeakCallbackInfo(
1371cb0ef41Sopenharmony_ci      const WeakCallbackInfo<WeakCallbackDataType>& data) {
1381cb0ef41Sopenharmony_ci    return K();
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci  static void DisposeCallbackData(WeakCallbackDataType* data) {}
1411cb0ef41Sopenharmony_ci  static void OnWeakCallback(
1421cb0ef41Sopenharmony_ci      const WeakCallbackInfo<WeakCallbackDataType>& data) {}
1431cb0ef41Sopenharmony_ci  static void Dispose(Isolate* isolate, Global<V> value, K key) {}
1441cb0ef41Sopenharmony_ci  // This is a second pass callback, so SetSecondPassCallback cannot be called.
1451cb0ef41Sopenharmony_ci  static void DisposeWeak(const WeakCallbackInfo<WeakCallbackDataType>& data) {}
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci private:
1481cb0ef41Sopenharmony_ci  template <typename T>
1491cb0ef41Sopenharmony_ci  struct RemovePointer<T*> {
1501cb0ef41Sopenharmony_ci    typedef T Type;
1511cb0ef41Sopenharmony_ci  };
1521cb0ef41Sopenharmony_ci};
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci/**
1561cb0ef41Sopenharmony_ci * A map wrapper that allows using Global as a mapped value.
1571cb0ef41Sopenharmony_ci * C++11 embedders don't need this class, as they can use Global
1581cb0ef41Sopenharmony_ci * directly in std containers.
1591cb0ef41Sopenharmony_ci *
1601cb0ef41Sopenharmony_ci * The map relies on a backing map, whose type and accessors are described
1611cb0ef41Sopenharmony_ci * by the Traits class. The backing map will handle values of type
1621cb0ef41Sopenharmony_ci * PersistentContainerValue, with all conversion into and out of V8
1631cb0ef41Sopenharmony_ci * handles being transparently handled by this class.
1641cb0ef41Sopenharmony_ci */
1651cb0ef41Sopenharmony_citemplate <typename K, typename V, typename Traits>
1661cb0ef41Sopenharmony_ciclass PersistentValueMapBase {
1671cb0ef41Sopenharmony_ci public:
1681cb0ef41Sopenharmony_ci  Isolate* GetIsolate() { return isolate_; }
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  /**
1711cb0ef41Sopenharmony_ci   * Return size of the map.
1721cb0ef41Sopenharmony_ci   */
1731cb0ef41Sopenharmony_ci  size_t Size() { return Traits::Size(&impl_); }
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci  /**
1761cb0ef41Sopenharmony_ci   * Return whether the map holds weak persistents.
1771cb0ef41Sopenharmony_ci   */
1781cb0ef41Sopenharmony_ci  bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci  /**
1811cb0ef41Sopenharmony_ci   * Get value stored in map.
1821cb0ef41Sopenharmony_ci   */
1831cb0ef41Sopenharmony_ci  Local<V> Get(const K& key) {
1841cb0ef41Sopenharmony_ci    V* p = FromVal(Traits::Get(&impl_, key));
1851cb0ef41Sopenharmony_ci#ifdef V8_ENABLE_DIRECT_LOCAL
1861cb0ef41Sopenharmony_ci    if (p == nullptr) return Local<V>();
1871cb0ef41Sopenharmony_ci#endif
1881cb0ef41Sopenharmony_ci    return Local<V>::New(isolate_, p);
1891cb0ef41Sopenharmony_ci  }
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ci  /**
1921cb0ef41Sopenharmony_ci   * Check whether a value is contained in the map.
1931cb0ef41Sopenharmony_ci   */
1941cb0ef41Sopenharmony_ci  bool Contains(const K& key) {
1951cb0ef41Sopenharmony_ci    return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
1961cb0ef41Sopenharmony_ci  }
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci  /**
1991cb0ef41Sopenharmony_ci   * Get value stored in map and set it in returnValue.
2001cb0ef41Sopenharmony_ci   * Return true if a value was found.
2011cb0ef41Sopenharmony_ci   */
2021cb0ef41Sopenharmony_ci  bool SetReturnValue(const K& key,
2031cb0ef41Sopenharmony_ci      ReturnValue<Value> returnValue) {
2041cb0ef41Sopenharmony_ci    return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
2051cb0ef41Sopenharmony_ci  }
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci  /**
2081cb0ef41Sopenharmony_ci   * Return value for key and remove it from the map.
2091cb0ef41Sopenharmony_ci   */
2101cb0ef41Sopenharmony_ci  Global<V> Remove(const K& key) {
2111cb0ef41Sopenharmony_ci    return Release(Traits::Remove(&impl_, key)).Pass();
2121cb0ef41Sopenharmony_ci  }
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci  /**
2151cb0ef41Sopenharmony_ci  * Traverses the map repeatedly,
2161cb0ef41Sopenharmony_ci  * in case side effects of disposal cause insertions.
2171cb0ef41Sopenharmony_ci  **/
2181cb0ef41Sopenharmony_ci  void Clear() {
2191cb0ef41Sopenharmony_ci    typedef typename Traits::Iterator It;
2201cb0ef41Sopenharmony_ci    HandleScope handle_scope(isolate_);
2211cb0ef41Sopenharmony_ci    // TODO(dcarney): figure out if this swap and loop is necessary.
2221cb0ef41Sopenharmony_ci    while (!Traits::Empty(&impl_)) {
2231cb0ef41Sopenharmony_ci      typename Traits::Impl impl;
2241cb0ef41Sopenharmony_ci      Traits::Swap(impl_, impl);
2251cb0ef41Sopenharmony_ci      for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
2261cb0ef41Sopenharmony_ci        Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
2271cb0ef41Sopenharmony_ci                        Traits::Key(i));
2281cb0ef41Sopenharmony_ci      }
2291cb0ef41Sopenharmony_ci    }
2301cb0ef41Sopenharmony_ci  }
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci  /**
2331cb0ef41Sopenharmony_ci   * Helper class for GetReference/SetWithReference. Do not use outside
2341cb0ef41Sopenharmony_ci   * that context.
2351cb0ef41Sopenharmony_ci   */
2361cb0ef41Sopenharmony_ci  class PersistentValueReference {
2371cb0ef41Sopenharmony_ci   public:
2381cb0ef41Sopenharmony_ci    PersistentValueReference() : value_(kPersistentContainerNotFound) { }
2391cb0ef41Sopenharmony_ci    PersistentValueReference(const PersistentValueReference& other)
2401cb0ef41Sopenharmony_ci        : value_(other.value_) { }
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci    Local<V> NewLocal(Isolate* isolate) const {
2431cb0ef41Sopenharmony_ci      return Local<V>::New(
2441cb0ef41Sopenharmony_ci          isolate, internal::ValueHelper::SlotAsValue<V>(FromVal(value_)));
2451cb0ef41Sopenharmony_ci    }
2461cb0ef41Sopenharmony_ci    bool IsEmpty() const {
2471cb0ef41Sopenharmony_ci      return value_ == kPersistentContainerNotFound;
2481cb0ef41Sopenharmony_ci    }
2491cb0ef41Sopenharmony_ci    template<typename T>
2501cb0ef41Sopenharmony_ci    bool SetReturnValue(ReturnValue<T> returnValue) {
2511cb0ef41Sopenharmony_ci      return SetReturnValueFromVal(&returnValue, value_);
2521cb0ef41Sopenharmony_ci    }
2531cb0ef41Sopenharmony_ci    void Reset() {
2541cb0ef41Sopenharmony_ci      value_ = kPersistentContainerNotFound;
2551cb0ef41Sopenharmony_ci    }
2561cb0ef41Sopenharmony_ci    void operator=(const PersistentValueReference& other) {
2571cb0ef41Sopenharmony_ci      value_ = other.value_;
2581cb0ef41Sopenharmony_ci    }
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci   private:
2611cb0ef41Sopenharmony_ci    friend class PersistentValueMapBase;
2621cb0ef41Sopenharmony_ci    friend class PersistentValueMap<K, V, Traits>;
2631cb0ef41Sopenharmony_ci    friend class GlobalValueMap<K, V, Traits>;
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci    explicit PersistentValueReference(PersistentContainerValue value)
2661cb0ef41Sopenharmony_ci        : value_(value) { }
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci    void operator=(PersistentContainerValue value) {
2691cb0ef41Sopenharmony_ci      value_ = value;
2701cb0ef41Sopenharmony_ci    }
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci    PersistentContainerValue value_;
2731cb0ef41Sopenharmony_ci  };
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci  /**
2761cb0ef41Sopenharmony_ci   * Get a reference to a map value. This enables fast, repeated access
2771cb0ef41Sopenharmony_ci   * to a value stored in the map while the map remains unchanged.
2781cb0ef41Sopenharmony_ci   *
2791cb0ef41Sopenharmony_ci   * Careful: This is potentially unsafe, so please use with care.
2801cb0ef41Sopenharmony_ci   * The value will become invalid if the value for this key changes
2811cb0ef41Sopenharmony_ci   * in the underlying map, as a result of Set or Remove for the same
2821cb0ef41Sopenharmony_ci   * key; as a result of the weak callback for the same key; or as a
2831cb0ef41Sopenharmony_ci   * result of calling Clear() or destruction of the map.
2841cb0ef41Sopenharmony_ci   */
2851cb0ef41Sopenharmony_ci  PersistentValueReference GetReference(const K& key) {
2861cb0ef41Sopenharmony_ci    return PersistentValueReference(Traits::Get(&impl_, key));
2871cb0ef41Sopenharmony_ci  }
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci protected:
2901cb0ef41Sopenharmony_ci  explicit PersistentValueMapBase(Isolate* isolate)
2911cb0ef41Sopenharmony_ci      : isolate_(isolate), label_(nullptr) {}
2921cb0ef41Sopenharmony_ci  PersistentValueMapBase(Isolate* isolate, const char* label)
2931cb0ef41Sopenharmony_ci      : isolate_(isolate), label_(label) {}
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  ~PersistentValueMapBase() { Clear(); }
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci  Isolate* isolate() { return isolate_; }
2981cb0ef41Sopenharmony_ci  typename Traits::Impl* impl() { return &impl_; }
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci  static V* FromVal(PersistentContainerValue v) {
3011cb0ef41Sopenharmony_ci    return reinterpret_cast<V*>(v);
3021cb0ef41Sopenharmony_ci  }
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
3051cb0ef41Sopenharmony_ci    V* v = persistent->template value<V>();
3061cb0ef41Sopenharmony_ci    persistent->Clear();
3071cb0ef41Sopenharmony_ci    return reinterpret_cast<PersistentContainerValue>(v);
3081cb0ef41Sopenharmony_ci  }
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  static PersistentContainerValue Leak(Global<V>* persistent) {
3111cb0ef41Sopenharmony_ci    return reinterpret_cast<PersistentContainerValue>(persistent->slot());
3121cb0ef41Sopenharmony_ci  }
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci  /**
3151cb0ef41Sopenharmony_ci   * Return a container value as Global and make sure the weak
3161cb0ef41Sopenharmony_ci   * callback is properly disposed of. All remove functionality should go
3171cb0ef41Sopenharmony_ci   * through this.
3181cb0ef41Sopenharmony_ci   */
3191cb0ef41Sopenharmony_ci  static Global<V> Release(PersistentContainerValue v) {
3201cb0ef41Sopenharmony_ci    Global<V> p;
3211cb0ef41Sopenharmony_ci    p.slot() = reinterpret_cast<internal::Address*>(FromVal(v));
3221cb0ef41Sopenharmony_ci    if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
3231cb0ef41Sopenharmony_ci      Traits::DisposeCallbackData(
3241cb0ef41Sopenharmony_ci          p.template ClearWeak<typename Traits::WeakCallbackDataType>());
3251cb0ef41Sopenharmony_ci    }
3261cb0ef41Sopenharmony_ci    return p.Pass();
3271cb0ef41Sopenharmony_ci  }
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci  void RemoveWeak(const K& key) {
3301cb0ef41Sopenharmony_ci    Global<V> p;
3311cb0ef41Sopenharmony_ci    p.slot() = reinterpret_cast<internal::Address*>(
3321cb0ef41Sopenharmony_ci        FromVal(Traits::Remove(&impl_, key)));
3331cb0ef41Sopenharmony_ci    p.Reset();
3341cb0ef41Sopenharmony_ci  }
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_ci  void AnnotateStrongRetainer(Global<V>* persistent) {
3371cb0ef41Sopenharmony_ci    persistent->AnnotateStrongRetainer(label_);
3381cb0ef41Sopenharmony_ci  }
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci private:
3411cb0ef41Sopenharmony_ci  PersistentValueMapBase(PersistentValueMapBase&);
3421cb0ef41Sopenharmony_ci  void operator=(PersistentValueMapBase&);
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci  static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
3451cb0ef41Sopenharmony_ci                                    PersistentContainerValue value) {
3461cb0ef41Sopenharmony_ci    bool hasValue = value != kPersistentContainerNotFound;
3471cb0ef41Sopenharmony_ci    if (hasValue) {
3481cb0ef41Sopenharmony_ci      returnValue->SetInternal(
3491cb0ef41Sopenharmony_ci          *reinterpret_cast<internal::Address*>(FromVal(value)));
3501cb0ef41Sopenharmony_ci    }
3511cb0ef41Sopenharmony_ci    return hasValue;
3521cb0ef41Sopenharmony_ci  }
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ci  Isolate* isolate_;
3551cb0ef41Sopenharmony_ci  typename Traits::Impl impl_;
3561cb0ef41Sopenharmony_ci  const char* label_;
3571cb0ef41Sopenharmony_ci};
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_citemplate <typename K, typename V, typename Traits>
3601cb0ef41Sopenharmony_ciclass PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
3611cb0ef41Sopenharmony_ci public:
3621cb0ef41Sopenharmony_ci  explicit PersistentValueMap(Isolate* isolate)
3631cb0ef41Sopenharmony_ci      : PersistentValueMapBase<K, V, Traits>(isolate) {}
3641cb0ef41Sopenharmony_ci  PersistentValueMap(Isolate* isolate, const char* label)
3651cb0ef41Sopenharmony_ci      : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci  typedef
3681cb0ef41Sopenharmony_ci      typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
3691cb0ef41Sopenharmony_ci          PersistentValueReference;
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  /**
3721cb0ef41Sopenharmony_ci   * Put value into map. Depending on Traits::kIsWeak, the value will be held
3731cb0ef41Sopenharmony_ci   * by the map strongly or weakly.
3741cb0ef41Sopenharmony_ci   * Returns old value as Global.
3751cb0ef41Sopenharmony_ci   */
3761cb0ef41Sopenharmony_ci  Global<V> Set(const K& key, Local<V> value) {
3771cb0ef41Sopenharmony_ci    Global<V> persistent(this->isolate(), value);
3781cb0ef41Sopenharmony_ci    return SetUnique(key, &persistent);
3791cb0ef41Sopenharmony_ci  }
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ci  /**
3821cb0ef41Sopenharmony_ci   * Put value into map, like Set(const K&, Local<V>).
3831cb0ef41Sopenharmony_ci   */
3841cb0ef41Sopenharmony_ci  Global<V> Set(const K& key, Global<V> value) {
3851cb0ef41Sopenharmony_ci    return SetUnique(key, &value);
3861cb0ef41Sopenharmony_ci  }
3871cb0ef41Sopenharmony_ci
3881cb0ef41Sopenharmony_ci  /**
3891cb0ef41Sopenharmony_ci   * Put the value into the map, and set the 'weak' callback when demanded
3901cb0ef41Sopenharmony_ci   * by the Traits class.
3911cb0ef41Sopenharmony_ci   */
3921cb0ef41Sopenharmony_ci  Global<V> SetUnique(const K& key, Global<V>* persistent) {
3931cb0ef41Sopenharmony_ci    if (Traits::kCallbackType == kNotWeak) {
3941cb0ef41Sopenharmony_ci      this->AnnotateStrongRetainer(persistent);
3951cb0ef41Sopenharmony_ci    } else {
3961cb0ef41Sopenharmony_ci      WeakCallbackType callback_type =
3971cb0ef41Sopenharmony_ci          Traits::kCallbackType == kWeakWithInternalFields
3981cb0ef41Sopenharmony_ci              ? WeakCallbackType::kInternalFields
3991cb0ef41Sopenharmony_ci              : WeakCallbackType::kParameter;
4001cb0ef41Sopenharmony_ci      auto value = Local<V>::New(this->isolate(), *persistent);
4011cb0ef41Sopenharmony_ci      persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
4021cb0ef41Sopenharmony_ci          Traits::WeakCallbackParameter(this, key, value), WeakCallback,
4031cb0ef41Sopenharmony_ci          callback_type);
4041cb0ef41Sopenharmony_ci    }
4051cb0ef41Sopenharmony_ci    PersistentContainerValue old_value =
4061cb0ef41Sopenharmony_ci        Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
4071cb0ef41Sopenharmony_ci    return this->Release(old_value).Pass();
4081cb0ef41Sopenharmony_ci  }
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ci  /**
4111cb0ef41Sopenharmony_ci   * Put a value into the map and update the reference.
4121cb0ef41Sopenharmony_ci   * Restrictions of GetReference apply here as well.
4131cb0ef41Sopenharmony_ci   */
4141cb0ef41Sopenharmony_ci  Global<V> Set(const K& key, Global<V> value,
4151cb0ef41Sopenharmony_ci                PersistentValueReference* reference) {
4161cb0ef41Sopenharmony_ci    *reference = this->Leak(&value);
4171cb0ef41Sopenharmony_ci    return SetUnique(key, &value);
4181cb0ef41Sopenharmony_ci  }
4191cb0ef41Sopenharmony_ci
4201cb0ef41Sopenharmony_ci private:
4211cb0ef41Sopenharmony_ci  static void WeakCallback(
4221cb0ef41Sopenharmony_ci      const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
4231cb0ef41Sopenharmony_ci    if (Traits::kCallbackType != kNotWeak) {
4241cb0ef41Sopenharmony_ci      PersistentValueMap<K, V, Traits>* persistentValueMap =
4251cb0ef41Sopenharmony_ci          Traits::MapFromWeakCallbackInfo(data);
4261cb0ef41Sopenharmony_ci      K key = Traits::KeyFromWeakCallbackInfo(data);
4271cb0ef41Sopenharmony_ci      Traits::Dispose(data.GetIsolate(),
4281cb0ef41Sopenharmony_ci                      persistentValueMap->Remove(key).Pass(), key);
4291cb0ef41Sopenharmony_ci      Traits::DisposeCallbackData(data.GetParameter());
4301cb0ef41Sopenharmony_ci    }
4311cb0ef41Sopenharmony_ci  }
4321cb0ef41Sopenharmony_ci};
4331cb0ef41Sopenharmony_ci
4341cb0ef41Sopenharmony_ci
4351cb0ef41Sopenharmony_citemplate <typename K, typename V, typename Traits>
4361cb0ef41Sopenharmony_ciclass GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
4371cb0ef41Sopenharmony_ci public:
4381cb0ef41Sopenharmony_ci  explicit GlobalValueMap(Isolate* isolate)
4391cb0ef41Sopenharmony_ci      : PersistentValueMapBase<K, V, Traits>(isolate) {}
4401cb0ef41Sopenharmony_ci  GlobalValueMap(Isolate* isolate, const char* label)
4411cb0ef41Sopenharmony_ci      : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
4421cb0ef41Sopenharmony_ci
4431cb0ef41Sopenharmony_ci  typedef
4441cb0ef41Sopenharmony_ci      typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
4451cb0ef41Sopenharmony_ci          PersistentValueReference;
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_ci  /**
4481cb0ef41Sopenharmony_ci   * Put value into map. Depending on Traits::kIsWeak, the value will be held
4491cb0ef41Sopenharmony_ci   * by the map strongly or weakly.
4501cb0ef41Sopenharmony_ci   * Returns old value as Global.
4511cb0ef41Sopenharmony_ci   */
4521cb0ef41Sopenharmony_ci  Global<V> Set(const K& key, Local<V> value) {
4531cb0ef41Sopenharmony_ci    Global<V> persistent(this->isolate(), value);
4541cb0ef41Sopenharmony_ci    return SetUnique(key, &persistent);
4551cb0ef41Sopenharmony_ci  }
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci  /**
4581cb0ef41Sopenharmony_ci   * Put value into map, like Set(const K&, Local<V>).
4591cb0ef41Sopenharmony_ci   */
4601cb0ef41Sopenharmony_ci  Global<V> Set(const K& key, Global<V> value) {
4611cb0ef41Sopenharmony_ci    return SetUnique(key, &value);
4621cb0ef41Sopenharmony_ci  }
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_ci  /**
4651cb0ef41Sopenharmony_ci   * Put the value into the map, and set the 'weak' callback when demanded
4661cb0ef41Sopenharmony_ci   * by the Traits class.
4671cb0ef41Sopenharmony_ci   */
4681cb0ef41Sopenharmony_ci  Global<V> SetUnique(const K& key, Global<V>* persistent) {
4691cb0ef41Sopenharmony_ci    if (Traits::kCallbackType == kNotWeak) {
4701cb0ef41Sopenharmony_ci      this->AnnotateStrongRetainer(persistent);
4711cb0ef41Sopenharmony_ci    } else {
4721cb0ef41Sopenharmony_ci      WeakCallbackType callback_type =
4731cb0ef41Sopenharmony_ci          Traits::kCallbackType == kWeakWithInternalFields
4741cb0ef41Sopenharmony_ci              ? WeakCallbackType::kInternalFields
4751cb0ef41Sopenharmony_ci              : WeakCallbackType::kParameter;
4761cb0ef41Sopenharmony_ci      auto value = Local<V>::New(this->isolate(), *persistent);
4771cb0ef41Sopenharmony_ci      persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
4781cb0ef41Sopenharmony_ci          Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
4791cb0ef41Sopenharmony_ci          callback_type);
4801cb0ef41Sopenharmony_ci    }
4811cb0ef41Sopenharmony_ci    PersistentContainerValue old_value =
4821cb0ef41Sopenharmony_ci        Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
4831cb0ef41Sopenharmony_ci    return this->Release(old_value).Pass();
4841cb0ef41Sopenharmony_ci  }
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci  /**
4871cb0ef41Sopenharmony_ci   * Put a value into the map and update the reference.
4881cb0ef41Sopenharmony_ci   * Restrictions of GetReference apply here as well.
4891cb0ef41Sopenharmony_ci   */
4901cb0ef41Sopenharmony_ci  Global<V> Set(const K& key, Global<V> value,
4911cb0ef41Sopenharmony_ci                PersistentValueReference* reference) {
4921cb0ef41Sopenharmony_ci    *reference = this->Leak(&value);
4931cb0ef41Sopenharmony_ci    return SetUnique(key, &value);
4941cb0ef41Sopenharmony_ci  }
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_ci private:
4971cb0ef41Sopenharmony_ci  static void OnWeakCallback(
4981cb0ef41Sopenharmony_ci      const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
4991cb0ef41Sopenharmony_ci    if (Traits::kCallbackType != kNotWeak) {
5001cb0ef41Sopenharmony_ci      auto map = Traits::MapFromWeakCallbackInfo(data);
5011cb0ef41Sopenharmony_ci      K key = Traits::KeyFromWeakCallbackInfo(data);
5021cb0ef41Sopenharmony_ci      map->RemoveWeak(key);
5031cb0ef41Sopenharmony_ci      Traits::OnWeakCallback(data);
5041cb0ef41Sopenharmony_ci      data.SetSecondPassCallback(SecondWeakCallback);
5051cb0ef41Sopenharmony_ci    }
5061cb0ef41Sopenharmony_ci  }
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ci  static void SecondWeakCallback(
5091cb0ef41Sopenharmony_ci      const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
5101cb0ef41Sopenharmony_ci    Traits::DisposeWeak(data);
5111cb0ef41Sopenharmony_ci  }
5121cb0ef41Sopenharmony_ci};
5131cb0ef41Sopenharmony_ci
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci/**
5161cb0ef41Sopenharmony_ci * A map that uses Global as value and std::map as the backing
5171cb0ef41Sopenharmony_ci * implementation. Persistents are held non-weak.
5181cb0ef41Sopenharmony_ci *
5191cb0ef41Sopenharmony_ci * C++11 embedders don't need this class, as they can use
5201cb0ef41Sopenharmony_ci * Global directly in std containers.
5211cb0ef41Sopenharmony_ci */
5221cb0ef41Sopenharmony_citemplate<typename K, typename V,
5231cb0ef41Sopenharmony_ci    typename Traits = DefaultPersistentValueMapTraits<K, V> >
5241cb0ef41Sopenharmony_ciclass StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
5251cb0ef41Sopenharmony_ci public:
5261cb0ef41Sopenharmony_ci  explicit StdPersistentValueMap(Isolate* isolate)
5271cb0ef41Sopenharmony_ci      : PersistentValueMap<K, V, Traits>(isolate) {}
5281cb0ef41Sopenharmony_ci};
5291cb0ef41Sopenharmony_ci
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci/**
5321cb0ef41Sopenharmony_ci * A map that uses Global as value and std::map as the backing
5331cb0ef41Sopenharmony_ci * implementation. Globals are held non-weak.
5341cb0ef41Sopenharmony_ci *
5351cb0ef41Sopenharmony_ci * C++11 embedders don't need this class, as they can use
5361cb0ef41Sopenharmony_ci * Global directly in std containers.
5371cb0ef41Sopenharmony_ci */
5381cb0ef41Sopenharmony_citemplate <typename K, typename V,
5391cb0ef41Sopenharmony_ci          typename Traits = DefaultGlobalMapTraits<K, V> >
5401cb0ef41Sopenharmony_ciclass StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
5411cb0ef41Sopenharmony_ci public:
5421cb0ef41Sopenharmony_ci  explicit StdGlobalValueMap(Isolate* isolate)
5431cb0ef41Sopenharmony_ci      : GlobalValueMap<K, V, Traits>(isolate) {}
5441cb0ef41Sopenharmony_ci};
5451cb0ef41Sopenharmony_ci
5461cb0ef41Sopenharmony_ciclass DefaultPersistentValueVectorTraits {
5471cb0ef41Sopenharmony_ci public:
5481cb0ef41Sopenharmony_ci  typedef std::vector<PersistentContainerValue> Impl;
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci  static void Append(Impl* impl, PersistentContainerValue value) {
5511cb0ef41Sopenharmony_ci    impl->push_back(value);
5521cb0ef41Sopenharmony_ci  }
5531cb0ef41Sopenharmony_ci  static bool IsEmpty(const Impl* impl) {
5541cb0ef41Sopenharmony_ci    return impl->empty();
5551cb0ef41Sopenharmony_ci  }
5561cb0ef41Sopenharmony_ci  static size_t Size(const Impl* impl) {
5571cb0ef41Sopenharmony_ci    return impl->size();
5581cb0ef41Sopenharmony_ci  }
5591cb0ef41Sopenharmony_ci  static PersistentContainerValue Get(const Impl* impl, size_t i) {
5601cb0ef41Sopenharmony_ci    return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
5611cb0ef41Sopenharmony_ci  }
5621cb0ef41Sopenharmony_ci  static void ReserveCapacity(Impl* impl, size_t capacity) {
5631cb0ef41Sopenharmony_ci    impl->reserve(capacity);
5641cb0ef41Sopenharmony_ci  }
5651cb0ef41Sopenharmony_ci  static void Clear(Impl* impl) {
5661cb0ef41Sopenharmony_ci    impl->clear();
5671cb0ef41Sopenharmony_ci  }
5681cb0ef41Sopenharmony_ci};
5691cb0ef41Sopenharmony_ci
5701cb0ef41Sopenharmony_ci/**
5711cb0ef41Sopenharmony_ci * A vector wrapper that safely stores Global values.
5721cb0ef41Sopenharmony_ci * C++11 embedders don't need this class, as they can use Global
5731cb0ef41Sopenharmony_ci * directly in std containers.
5741cb0ef41Sopenharmony_ci *
5751cb0ef41Sopenharmony_ci * This class relies on a backing vector implementation, whose type and methods
5761cb0ef41Sopenharmony_ci * are described by the Traits class. The backing map will handle values of type
5771cb0ef41Sopenharmony_ci * PersistentContainerValue, with all conversion into and out of V8
5781cb0ef41Sopenharmony_ci * handles being transparently handled by this class.
5791cb0ef41Sopenharmony_ci */
5801cb0ef41Sopenharmony_citemplate <typename V, typename Traits = DefaultPersistentValueVectorTraits>
5811cb0ef41Sopenharmony_ciclass V8_DEPRECATE_SOON("Use std::vector<Global<V>>.") PersistentValueVector {
5821cb0ef41Sopenharmony_ci public:
5831cb0ef41Sopenharmony_ci  explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_ci  ~PersistentValueVector() {
5861cb0ef41Sopenharmony_ci    Clear();
5871cb0ef41Sopenharmony_ci  }
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci  /**
5901cb0ef41Sopenharmony_ci   * Append a value to the vector.
5911cb0ef41Sopenharmony_ci   */
5921cb0ef41Sopenharmony_ci  void Append(Local<V> value) {
5931cb0ef41Sopenharmony_ci    Global<V> persistent(isolate_, value);
5941cb0ef41Sopenharmony_ci    Traits::Append(&impl_, ClearAndLeak(&persistent));
5951cb0ef41Sopenharmony_ci  }
5961cb0ef41Sopenharmony_ci
5971cb0ef41Sopenharmony_ci  /**
5981cb0ef41Sopenharmony_ci   * Append a persistent's value to the vector.
5991cb0ef41Sopenharmony_ci   */
6001cb0ef41Sopenharmony_ci  void Append(Global<V> persistent) {
6011cb0ef41Sopenharmony_ci    Traits::Append(&impl_, ClearAndLeak(&persistent));
6021cb0ef41Sopenharmony_ci  }
6031cb0ef41Sopenharmony_ci
6041cb0ef41Sopenharmony_ci  /**
6051cb0ef41Sopenharmony_ci   * Are there any values in the vector?
6061cb0ef41Sopenharmony_ci   */
6071cb0ef41Sopenharmony_ci  bool IsEmpty() const {
6081cb0ef41Sopenharmony_ci    return Traits::IsEmpty(&impl_);
6091cb0ef41Sopenharmony_ci  }
6101cb0ef41Sopenharmony_ci
6111cb0ef41Sopenharmony_ci  /**
6121cb0ef41Sopenharmony_ci   * How many elements are in the vector?
6131cb0ef41Sopenharmony_ci   */
6141cb0ef41Sopenharmony_ci  size_t Size() const {
6151cb0ef41Sopenharmony_ci    return Traits::Size(&impl_);
6161cb0ef41Sopenharmony_ci  }
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci  /**
6191cb0ef41Sopenharmony_ci   * Retrieve the i-th value in the vector.
6201cb0ef41Sopenharmony_ci   */
6211cb0ef41Sopenharmony_ci  Local<V> Get(size_t index) const {
6221cb0ef41Sopenharmony_ci    return Local<V>::New(isolate_, internal::ValueHelper::SlotAsValue<V>(
6231cb0ef41Sopenharmony_ci                                       FromVal(Traits::Get(&impl_, index))));
6241cb0ef41Sopenharmony_ci  }
6251cb0ef41Sopenharmony_ci
6261cb0ef41Sopenharmony_ci  /**
6271cb0ef41Sopenharmony_ci   * Remove all elements from the vector.
6281cb0ef41Sopenharmony_ci   */
6291cb0ef41Sopenharmony_ci  void Clear() {
6301cb0ef41Sopenharmony_ci    size_t length = Traits::Size(&impl_);
6311cb0ef41Sopenharmony_ci    for (size_t i = 0; i < length; i++) {
6321cb0ef41Sopenharmony_ci      Global<V> p;
6331cb0ef41Sopenharmony_ci      p.slot() =
6341cb0ef41Sopenharmony_ci          reinterpret_cast<internal::Address>(FromVal(Traits::Get(&impl_, i)));
6351cb0ef41Sopenharmony_ci    }
6361cb0ef41Sopenharmony_ci    Traits::Clear(&impl_);
6371cb0ef41Sopenharmony_ci  }
6381cb0ef41Sopenharmony_ci
6391cb0ef41Sopenharmony_ci  /**
6401cb0ef41Sopenharmony_ci   * Reserve capacity in the vector.
6411cb0ef41Sopenharmony_ci   * (Efficiency gains depend on the backing implementation.)
6421cb0ef41Sopenharmony_ci   */
6431cb0ef41Sopenharmony_ci  void ReserveCapacity(size_t capacity) {
6441cb0ef41Sopenharmony_ci    Traits::ReserveCapacity(&impl_, capacity);
6451cb0ef41Sopenharmony_ci  }
6461cb0ef41Sopenharmony_ci
6471cb0ef41Sopenharmony_ci private:
6481cb0ef41Sopenharmony_ci  static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
6491cb0ef41Sopenharmony_ci    auto slot = persistent->slot();
6501cb0ef41Sopenharmony_ci    persistent->Clear();
6511cb0ef41Sopenharmony_ci    return reinterpret_cast<PersistentContainerValue>(slot);
6521cb0ef41Sopenharmony_ci  }
6531cb0ef41Sopenharmony_ci
6541cb0ef41Sopenharmony_ci  static V* FromVal(PersistentContainerValue v) {
6551cb0ef41Sopenharmony_ci    return reinterpret_cast<V*>(v);
6561cb0ef41Sopenharmony_ci  }
6571cb0ef41Sopenharmony_ci
6581cb0ef41Sopenharmony_ci  Isolate* isolate_;
6591cb0ef41Sopenharmony_ci  typename Traits::Impl impl_;
6601cb0ef41Sopenharmony_ci};
6611cb0ef41Sopenharmony_ci
6621cb0ef41Sopenharmony_ci}  // namespace v8
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci#endif  // V8_UTIL_H
665