LCOV - code coverage report
Current view: top level - include - v8-util.h (source / functions) Hit Total Coverage
Test: app.info Lines: 20 20 100.0 %
Date: 2017-04-26 Functions: 13 13 100.0 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_UTIL_H_
       6             : #define V8_UTIL_H_
       7             : 
       8             : #include "v8.h"  // NOLINT(build/include)
       9             : #include <assert.h>
      10             : #include <map>
      11             : #include <vector>
      12             : 
      13             : /**
      14             :  * Support for Persistent containers.
      15             :  *
      16             :  * C++11 embedders can use STL containers with Global values,
      17             :  * but pre-C++11 does not support the required move semantic and hence
      18             :  * may want these container classes.
      19             :  */
      20             : namespace v8 {
      21             : 
      22             : typedef uintptr_t PersistentContainerValue;
      23             : static const uintptr_t kPersistentContainerNotFound = 0;
      24             : enum PersistentContainerCallbackType {
      25             :   kNotWeak,
      26             :   // These correspond to v8::WeakCallbackType
      27             :   kWeakWithParameter,
      28             :   kWeakWithInternalFields,
      29             :   kWeak = kWeakWithParameter  // For backwards compatibility.  Deprecate.
      30             : };
      31             : 
      32             : 
      33             : /**
      34             :  * A default trait implemenation for PersistentValueMap which uses std::map
      35             :  * as a backing map.
      36             :  *
      37             :  * Users will have to implement their own weak callbacks & dispose traits.
      38             :  */
      39             : template<typename K, typename V>
      40             : class StdMapTraits {
      41             :  public:
      42             :   // STL map & related:
      43             :   typedef std::map<K, PersistentContainerValue> Impl;
      44             :   typedef typename Impl::iterator Iterator;
      45             : 
      46             :   static bool Empty(Impl* impl) { return impl->empty(); }
      47             :   static size_t Size(Impl* impl) { return impl->size(); }
      48             :   static void Swap(Impl& a, Impl& b) { std::swap(a, b); }  // NOLINT
      49             :   static Iterator Begin(Impl* impl) { return impl->begin(); }
      50             :   static Iterator End(Impl* impl) { return impl->end(); }
      51             :   static K Key(Iterator it) { return it->first; }
      52             :   static PersistentContainerValue Value(Iterator it) { return it->second; }
      53             :   static PersistentContainerValue Set(Impl* impl, K key,
      54             :       PersistentContainerValue value) {
      55             :     std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
      56             :     PersistentContainerValue old_value = kPersistentContainerNotFound;
      57             :     if (!res.second) {
      58             :       old_value = res.first->second;
      59             :       res.first->second = value;
      60             :     }
      61             :     return old_value;
      62             :   }
      63             :   static PersistentContainerValue Get(Impl* impl, K key) {
      64             :     Iterator it = impl->find(key);
      65             :     if (it == impl->end()) return kPersistentContainerNotFound;
      66             :     return it->second;
      67             :   }
      68             :   static PersistentContainerValue Remove(Impl* impl, K key) {
      69             :     Iterator it = impl->find(key);
      70             :     if (it == impl->end()) return kPersistentContainerNotFound;
      71             :     PersistentContainerValue value = it->second;
      72             :     impl->erase(it);
      73             :     return value;
      74             :   }
      75             : };
      76             : 
      77             : 
      78             : /**
      79             :  * A default trait implementation for PersistentValueMap, which inherits
      80             :  * a std:map backing map from StdMapTraits and holds non-weak persistent
      81             :  * objects and has no special Dispose handling.
      82             :  *
      83             :  * You should not derive from this class, since MapType depends on the
      84             :  * surrounding class, and hence a subclass cannot simply inherit the methods.
      85             :  */
      86             : template<typename K, typename V>
      87             : class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
      88             :  public:
      89             :   // Weak callback & friends:
      90             :   static const PersistentContainerCallbackType kCallbackType = kNotWeak;
      91             :   typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
      92             :       MapType;
      93             :   typedef void WeakCallbackDataType;
      94             : 
      95             :   static WeakCallbackDataType* WeakCallbackParameter(
      96             :       MapType* map, const K& key, Local<V> value) {
      97             :     return NULL;
      98             :   }
      99             :   static MapType* MapFromWeakCallbackInfo(
     100             :       const WeakCallbackInfo<WeakCallbackDataType>& data) {
     101             :     return NULL;
     102             :   }
     103             :   static K KeyFromWeakCallbackInfo(
     104             :       const WeakCallbackInfo<WeakCallbackDataType>& data) {
     105             :     return K();
     106             :   }
     107             :   static void DisposeCallbackData(WeakCallbackDataType* data) { }
     108             :   static void Dispose(Isolate* isolate, Global<V> value, K key) {}
     109             : };
     110             : 
     111             : 
     112             : template <typename K, typename V>
     113             : class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
     114             :  private:
     115             :   template <typename T>
     116             :   struct RemovePointer;
     117             : 
     118             :  public:
     119             :   // Weak callback & friends:
     120             :   static const PersistentContainerCallbackType kCallbackType = kNotWeak;
     121             :   typedef GlobalValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
     122             :   typedef void WeakCallbackDataType;
     123             : 
     124             :   static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
     125             :                                                      Local<V> value) {
     126             :     return nullptr;
     127             :   }
     128             :   static MapType* MapFromWeakCallbackInfo(
     129             :       const WeakCallbackInfo<WeakCallbackDataType>& data) {
     130             :     return nullptr;
     131             :   }
     132             :   static K KeyFromWeakCallbackInfo(
     133             :       const WeakCallbackInfo<WeakCallbackDataType>& data) {
     134             :     return K();
     135             :   }
     136             :   static void DisposeCallbackData(WeakCallbackDataType* data) {}
     137             :   static void OnWeakCallback(
     138             :       const WeakCallbackInfo<WeakCallbackDataType>& data) {}
     139             :   static void Dispose(Isolate* isolate, Global<V> value, K key) {}
     140             :   // This is a second pass callback, so SetSecondPassCallback cannot be called.
     141             :   static void DisposeWeak(const WeakCallbackInfo<WeakCallbackDataType>& data) {}
     142             : 
     143             :  private:
     144             :   template <typename T>
     145             :   struct RemovePointer<T*> {
     146             :     typedef T Type;
     147             :   };
     148             : };
     149             : 
     150             : 
     151             : /**
     152             :  * A map wrapper that allows using Global as a mapped value.
     153             :  * C++11 embedders don't need this class, as they can use Global
     154             :  * directly in std containers.
     155             :  *
     156             :  * The map relies on a backing map, whose type and accessors are described
     157             :  * by the Traits class. The backing map will handle values of type
     158             :  * PersistentContainerValue, with all conversion into and out of V8
     159             :  * handles being transparently handled by this class.
     160             :  */
     161             : template <typename K, typename V, typename Traits>
     162             : class PersistentValueMapBase {
     163             :  public:
     164             :   Isolate* GetIsolate() { return isolate_; }
     165             : 
     166             :   /**
     167             :    * Return size of the map.
     168             :    */
     169             :   size_t Size() { return Traits::Size(&impl_); }
     170             : 
     171             :   /**
     172             :    * Return whether the map holds weak persistents.
     173             :    */
     174             :   bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
     175             : 
     176             :   /**
     177             :    * Get value stored in map.
     178             :    */
     179             :   Local<V> Get(const K& key) {
     180             :     return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
     181             :   }
     182             : 
     183             :   /**
     184             :    * Check whether a value is contained in the map.
     185             :    */
     186             :   bool Contains(const K& key) {
     187             :     return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
     188             :   }
     189             : 
     190             :   /**
     191             :    * Get value stored in map and set it in returnValue.
     192             :    * Return true if a value was found.
     193             :    */
     194             :   bool SetReturnValue(const K& key,
     195             :       ReturnValue<Value> returnValue) {
     196             :     return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
     197             :   }
     198             : 
     199             :   /**
     200             :    * Call Isolate::SetReference with the given parent and the map value.
     201             :    */
     202             :   void SetReference(const K& key,
     203             :       const Persistent<Object>& parent) {
     204             :     GetIsolate()->SetReference(
     205             :       reinterpret_cast<internal::Object**>(parent.val_),
     206             :       reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
     207             :   }
     208             : 
     209             :   /**
     210             :    * Call V8::RegisterExternallyReferencedObject with the map value for given
     211             :    * key.
     212             :    */
     213             :   void RegisterExternallyReferencedObject(K& key) {
     214             :     assert(Contains(key));
     215             :     V8::RegisterExternallyReferencedObject(
     216             :         reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))),
     217             :         reinterpret_cast<internal::Isolate*>(GetIsolate()));
     218             :   }
     219             : 
     220             :   /**
     221             :    * Return value for key and remove it from the map.
     222             :    */
     223             :   Global<V> Remove(const K& key) {
     224             :     return Release(Traits::Remove(&impl_, key)).Pass();
     225             :   }
     226             : 
     227             :   /**
     228             :   * Traverses the map repeatedly,
     229             :   * in case side effects of disposal cause insertions.
     230             :   **/
     231             :   void Clear() {
     232             :     typedef typename Traits::Iterator It;
     233             :     HandleScope handle_scope(isolate_);
     234             :     // TODO(dcarney): figure out if this swap and loop is necessary.
     235             :     while (!Traits::Empty(&impl_)) {
     236             :       typename Traits::Impl impl;
     237             :       Traits::Swap(impl_, impl);
     238             :       for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
     239             :         Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
     240             :                         Traits::Key(i));
     241             :       }
     242             :     }
     243             :   }
     244             : 
     245             :   /**
     246             :    * Helper class for GetReference/SetWithReference. Do not use outside
     247             :    * that context.
     248             :    */
     249             :   class PersistentValueReference {
     250             :    public:
     251             :     PersistentValueReference() : value_(kPersistentContainerNotFound) { }
     252             :     PersistentValueReference(const PersistentValueReference& other)
     253             :         : value_(other.value_) { }
     254             : 
     255             :     Local<V> NewLocal(Isolate* isolate) const {
     256             :       return Local<V>::New(isolate, FromVal(value_));
     257             :     }
     258             :     bool IsEmpty() const {
     259             :       return value_ == kPersistentContainerNotFound;
     260             :     }
     261             :     template<typename T>
     262             :     bool SetReturnValue(ReturnValue<T> returnValue) {
     263             :       return SetReturnValueFromVal(&returnValue, value_);
     264             :     }
     265             :     void Reset() {
     266             :       value_ = kPersistentContainerNotFound;
     267             :     }
     268             :     void operator=(const PersistentValueReference& other) {
     269             :       value_ = other.value_;
     270             :     }
     271             : 
     272             :    private:
     273             :     friend class PersistentValueMapBase;
     274             :     friend class PersistentValueMap<K, V, Traits>;
     275             :     friend class GlobalValueMap<K, V, Traits>;
     276             : 
     277             :     explicit PersistentValueReference(PersistentContainerValue value)
     278             :         : value_(value) { }
     279             : 
     280             :     void operator=(PersistentContainerValue value) {
     281             :       value_ = value;
     282             :     }
     283             : 
     284             :     PersistentContainerValue value_;
     285             :   };
     286             : 
     287             :   /**
     288             :    * Get a reference to a map value. This enables fast, repeated access
     289             :    * to a value stored in the map while the map remains unchanged.
     290             :    *
     291             :    * Careful: This is potentially unsafe, so please use with care.
     292             :    * The value will become invalid if the value for this key changes
     293             :    * in the underlying map, as a result of Set or Remove for the same
     294             :    * key; as a result of the weak callback for the same key; or as a
     295             :    * result of calling Clear() or destruction of the map.
     296             :    */
     297             :   PersistentValueReference GetReference(const K& key) {
     298             :     return PersistentValueReference(Traits::Get(&impl_, key));
     299             :   }
     300             : 
     301             :  protected:
     302             :   explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {}
     303             : 
     304             :   ~PersistentValueMapBase() { Clear(); }
     305             : 
     306             :   Isolate* isolate() { return isolate_; }
     307             :   typename Traits::Impl* impl() { return &impl_; }
     308             : 
     309             :   static V* FromVal(PersistentContainerValue v) {
     310             :     return reinterpret_cast<V*>(v);
     311             :   }
     312             : 
     313             :   static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
     314             :     V* v = persistent->val_;
     315             :     persistent->val_ = 0;
     316             :     return reinterpret_cast<PersistentContainerValue>(v);
     317             :   }
     318             : 
     319             :   static PersistentContainerValue Leak(Global<V>* persistent) {
     320             :     return reinterpret_cast<PersistentContainerValue>(persistent->val_);
     321             :   }
     322             : 
     323             :   /**
     324             :    * Return a container value as Global and make sure the weak
     325             :    * callback is properly disposed of. All remove functionality should go
     326             :    * through this.
     327             :    */
     328             :   static Global<V> Release(PersistentContainerValue v) {
     329             :     Global<V> p;
     330             :     p.val_ = FromVal(v);
     331             :     if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
     332             :       Traits::DisposeCallbackData(
     333             :           p.template ClearWeak<typename Traits::WeakCallbackDataType>());
     334             :     }
     335             :     return p.Pass();
     336             :   }
     337             : 
     338             :   void RemoveWeak(const K& key) {
     339             :     Global<V> p;
     340             :     p.val_ = FromVal(Traits::Remove(&impl_, key));
     341             :     p.Reset();
     342             :   }
     343             : 
     344             :  private:
     345             :   PersistentValueMapBase(PersistentValueMapBase&);
     346             :   void operator=(PersistentValueMapBase&);
     347             : 
     348             :   static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
     349             :                                     PersistentContainerValue value) {
     350             :     bool hasValue = value != kPersistentContainerNotFound;
     351             :     if (hasValue) {
     352             :       returnValue->SetInternal(
     353             :           *reinterpret_cast<internal::Object**>(FromVal(value)));
     354             :     }
     355             :     return hasValue;
     356             :   }
     357             : 
     358             :   Isolate* isolate_;
     359             :   typename Traits::Impl impl_;
     360             : };
     361             : 
     362             : 
     363             : template <typename K, typename V, typename Traits>
     364             : class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
     365             :  public:
     366             :   explicit PersistentValueMap(Isolate* isolate)
     367             :       : PersistentValueMapBase<K, V, Traits>(isolate) {}
     368             : 
     369             :   typedef
     370             :       typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
     371             :           PersistentValueReference;
     372             : 
     373             :   /**
     374             :    * Put value into map. Depending on Traits::kIsWeak, the value will be held
     375             :    * by the map strongly or weakly.
     376             :    * Returns old value as Global.
     377             :    */
     378             :   Global<V> Set(const K& key, Local<V> value) {
     379             :     Global<V> persistent(this->isolate(), value);
     380             :     return SetUnique(key, &persistent);
     381             :   }
     382             : 
     383             :   /**
     384             :    * Put value into map, like Set(const K&, Local<V>).
     385             :    */
     386             :   Global<V> Set(const K& key, Global<V> value) {
     387             :     return SetUnique(key, &value);
     388             :   }
     389             : 
     390             :   /**
     391             :    * Put the value into the map, and set the 'weak' callback when demanded
     392             :    * by the Traits class.
     393             :    */
     394             :   Global<V> SetUnique(const K& key, Global<V>* persistent) {
     395             :     if (Traits::kCallbackType != kNotWeak) {
     396             :       Local<V> value(Local<V>::New(this->isolate(), *persistent));
     397             :       persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
     398             :         Traits::WeakCallbackParameter(this, key, value), WeakCallback);
     399             :     }
     400             :     PersistentContainerValue old_value =
     401             :         Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
     402             :     return this->Release(old_value).Pass();
     403             :   }
     404             : 
     405             :   /**
     406             :    * Put a value into the map and update the reference.
     407             :    * Restrictions of GetReference apply here as well.
     408             :    */
     409             :   Global<V> Set(const K& key, Global<V> value,
     410             :                 PersistentValueReference* reference) {
     411             :     *reference = this->Leak(&value);
     412             :     return SetUnique(key, &value);
     413             :   }
     414             : 
     415             :  private:
     416             :   static void WeakCallback(
     417             :       const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
     418             :     if (Traits::kCallbackType != kNotWeak) {
     419             :       PersistentValueMap<K, V, Traits>* persistentValueMap =
     420             :           Traits::MapFromWeakCallbackInfo(data);
     421             :       K key = Traits::KeyFromWeakCallbackInfo(data);
     422             :       Traits::Dispose(data.GetIsolate(),
     423             :                       persistentValueMap->Remove(key).Pass(), key);
     424             :       Traits::DisposeCallbackData(data.GetParameter());
     425             :     }
     426             :   }
     427             : };
     428             : 
     429             : 
     430             : template <typename K, typename V, typename Traits>
     431             : class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
     432             :  public:
     433             :   explicit GlobalValueMap(Isolate* isolate)
     434             :       : PersistentValueMapBase<K, V, Traits>(isolate) {}
     435             : 
     436             :   typedef
     437             :       typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
     438             :           PersistentValueReference;
     439             : 
     440             :   /**
     441             :    * Put value into map. Depending on Traits::kIsWeak, the value will be held
     442             :    * by the map strongly or weakly.
     443             :    * Returns old value as Global.
     444             :    */
     445             :   Global<V> Set(const K& key, Local<V> value) {
     446             :     Global<V> persistent(this->isolate(), value);
     447             :     return SetUnique(key, &persistent);
     448             :   }
     449             : 
     450             :   /**
     451             :    * Put value into map, like Set(const K&, Local<V>).
     452             :    */
     453             :   Global<V> Set(const K& key, Global<V> value) {
     454             :     return SetUnique(key, &value);
     455             :   }
     456             : 
     457             :   /**
     458             :    * Put the value into the map, and set the 'weak' callback when demanded
     459             :    * by the Traits class.
     460             :    */
     461             :   Global<V> SetUnique(const K& key, Global<V>* persistent) {
     462             :     if (Traits::kCallbackType != kNotWeak) {
     463             :       WeakCallbackType callback_type =
     464             :           Traits::kCallbackType == kWeakWithInternalFields
     465             :               ? WeakCallbackType::kInternalFields
     466             :               : WeakCallbackType::kParameter;
     467             :       Local<V> value(Local<V>::New(this->isolate(), *persistent));
     468             :       persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
     469             :           Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
     470             :           callback_type);
     471             :     }
     472             :     PersistentContainerValue old_value =
     473             :         Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
     474             :     return this->Release(old_value).Pass();
     475             :   }
     476             : 
     477             :   /**
     478             :    * Put a value into the map and update the reference.
     479             :    * Restrictions of GetReference apply here as well.
     480             :    */
     481             :   Global<V> Set(const K& key, Global<V> value,
     482             :                 PersistentValueReference* reference) {
     483             :     *reference = this->Leak(&value);
     484             :     return SetUnique(key, &value);
     485             :   }
     486             : 
     487             :  private:
     488             :   static void OnWeakCallback(
     489             :       const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
     490             :     if (Traits::kCallbackType != kNotWeak) {
     491             :       auto map = Traits::MapFromWeakCallbackInfo(data);
     492             :       K key = Traits::KeyFromWeakCallbackInfo(data);
     493             :       map->RemoveWeak(key);
     494             :       Traits::OnWeakCallback(data);
     495             :       data.SetSecondPassCallback(SecondWeakCallback);
     496             :     }
     497             :   }
     498             : 
     499             :   static void SecondWeakCallback(
     500             :       const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
     501             :     Traits::DisposeWeak(data);
     502             :   }
     503             : };
     504             : 
     505             : 
     506             : /**
     507             :  * A map that uses Global as value and std::map as the backing
     508             :  * implementation. Persistents are held non-weak.
     509             :  *
     510             :  * C++11 embedders don't need this class, as they can use
     511             :  * Global directly in std containers.
     512             :  */
     513             : template<typename K, typename V,
     514             :     typename Traits = DefaultPersistentValueMapTraits<K, V> >
     515             : class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
     516             :  public:
     517             :   explicit StdPersistentValueMap(Isolate* isolate)
     518             :       : PersistentValueMap<K, V, Traits>(isolate) {}
     519             : };
     520             : 
     521             : 
     522             : /**
     523             :  * A map that uses Global as value and std::map as the backing
     524             :  * implementation. Globals are held non-weak.
     525             :  *
     526             :  * C++11 embedders don't need this class, as they can use
     527             :  * Global directly in std containers.
     528             :  */
     529             : template <typename K, typename V,
     530             :           typename Traits = DefaultGlobalMapTraits<K, V> >
     531             : class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
     532             :  public:
     533             :   explicit StdGlobalValueMap(Isolate* isolate)
     534             :       : GlobalValueMap<K, V, Traits>(isolate) {}
     535             : };
     536             : 
     537             : 
     538             : class DefaultPersistentValueVectorTraits {
     539             :  public:
     540             :   typedef std::vector<PersistentContainerValue> Impl;
     541             : 
     542             :   static void Append(Impl* impl, PersistentContainerValue value) {
     543       12142 :     impl->push_back(value);
     544             :   }
     545             :   static bool IsEmpty(const Impl* impl) {
     546             :     return impl->empty();
     547             :   }
     548       21396 :   static size_t Size(const Impl* impl) {
     549             :     return impl->size();
     550             :   }
     551       24296 :   static PersistentContainerValue Get(const Impl* impl, size_t i) {
     552       48592 :     return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
     553             :   }
     554             :   static void ReserveCapacity(Impl* impl, size_t capacity) {
     555             :     impl->reserve(capacity);
     556             :   }
     557             :   static void Clear(Impl* impl) {
     558             :     impl->clear();
     559             :   }
     560             : };
     561             : 
     562             : 
     563             : /**
     564             :  * A vector wrapper that safely stores Global values.
     565             :  * C++11 embedders don't need this class, as they can use Global
     566             :  * directly in std containers.
     567             :  *
     568             :  * This class relies on a backing vector implementation, whose type and methods
     569             :  * are described by the Traits class. The backing map will handle values of type
     570             :  * PersistentContainerValue, with all conversion into and out of V8
     571             :  * handles being transparently handled by this class.
     572             :  */
     573             : template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
     574             : class PersistentValueVector {
     575             :  public:
     576        4533 :   explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
     577             : 
     578        4533 :   ~PersistentValueVector() {
     579        4533 :     Clear();
     580        4533 :   }
     581             : 
     582             :   /**
     583             :    * Append a value to the vector.
     584             :    */
     585       12142 :   void Append(Local<V> value) {
     586       12142 :     Global<V> persistent(isolate_, value);
     587       12142 :     Traits::Append(&impl_, ClearAndLeak(&persistent));
     588       12142 :   }
     589             : 
     590             :   /**
     591             :    * Append a persistent's value to the vector.
     592             :    */
     593             :   void Append(Global<V> persistent) {
     594             :     Traits::Append(&impl_, ClearAndLeak(&persistent));
     595             :   }
     596             : 
     597             :   /**
     598             :    * Are there any values in the vector?
     599             :    */
     600             :   bool IsEmpty() const {
     601             :     return Traits::IsEmpty(&impl_);
     602             :   }
     603             : 
     604             :   /**
     605             :    * How many elements are in the vector?
     606             :    */
     607             :   size_t Size() const {
     608             :     return Traits::Size(&impl_);
     609             :   }
     610             : 
     611             :   /**
     612             :    * Retrieve the i-th value in the vector.
     613             :    */
     614       12160 :   Local<V> Get(size_t index) const {
     615       36480 :     return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
     616             :   }
     617             : 
     618             :   /**
     619             :    * Remove all elements from the vector.
     620             :    */
     621        4727 :   void Clear() {
     622             :     size_t length = Traits::Size(&impl_);
     623       16863 :     for (size_t i = 0; i < length; i++) {
     624             :       Global<V> p;
     625       12136 :       p.val_ = FromVal(Traits::Get(&impl_, i));
     626             :     }
     627             :     Traits::Clear(&impl_);
     628        4727 :   }
     629             : 
     630             :   /**
     631             :    * Reserve capacity in the vector.
     632             :    * (Efficiency gains depend on the backing implementation.)
     633             :    */
     634             :   void ReserveCapacity(size_t capacity) {
     635             :     Traits::ReserveCapacity(&impl_, capacity);
     636             :   }
     637             : 
     638             :  private:
     639             :   static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
     640             :     V* v = persistent->val_;
     641             :     persistent->val_ = 0;
     642       12142 :     return reinterpret_cast<PersistentContainerValue>(v);
     643             :   }
     644             : 
     645             :   static V* FromVal(PersistentContainerValue v) {
     646       24296 :     return reinterpret_cast<V*>(v);
     647             :   }
     648             : 
     649             :   Isolate* isolate_;
     650             :   typename Traits::Impl impl_;
     651             : };
     652             : 
     653             : }  // namespace v8
     654             : 
     655             : #endif  // V8_UTIL_H

Generated by: LCOV version 1.10