1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_UTIL_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_UTIL_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "v8.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <map> 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <vector> 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/** 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Support for Persistent containers. 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * C++11 embedders can use STL containers with UniquePersistent values, 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * but pre-C++11 does not support the required move semantic and hence 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * may want these container classes. 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef uintptr_t PersistentContainerValue; 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const uintptr_t kPersistentContainerNotFound = 0; 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum PersistentContainerCallbackType { 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kNotWeak, 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kWeak 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/** 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * A default trait implemenation for PersistentValueMap which uses std::map 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * as a backing map. 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Users will have to implement their own weak callbacks & dispose traits. 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename K, typename V> 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StdMapTraits { 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // STL map & related: 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef std::map<K, PersistentContainerValue> Impl; 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef typename Impl::iterator Iterator; 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool Empty(Impl* impl) { return impl->empty(); } 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static size_t Size(Impl* impl) { return impl->size(); } 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Iterator Begin(Impl* impl) { return impl->begin(); } 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Iterator End(Impl* impl) { return impl->end(); } 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static K Key(Iterator it) { return it->first; } 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PersistentContainerValue Value(Iterator it) { return it->second; } 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PersistentContainerValue Set(Impl* impl, K key, 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentContainerValue value) { 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value)); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentContainerValue old_value = kPersistentContainerNotFound; 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!res.second) { 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch old_value = res.first->second; 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch res.first->second = value; 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return old_value; 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PersistentContainerValue Get(Impl* impl, K key) { 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Iterator it = impl->find(key); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it == impl->end()) return kPersistentContainerNotFound; 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return it->second; 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PersistentContainerValue Remove(Impl* impl, K key) { 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Iterator it = impl->find(key); 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it == impl->end()) return kPersistentContainerNotFound; 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentContainerValue value = it->second; 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch impl->erase(it); 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/** 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * A default trait implementation for PersistentValueMap, which inherits 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * a std:map backing map from StdMapTraits and holds non-weak persistent 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * objects and has no special Dispose handling. 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * You should not derive from this class, since MapType depends on the 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * surrounding class, and hence a subclass cannot simply inherit the methods. 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename K, typename V> 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DefaultPersistentValueMapTraits : public StdMapTraits<K, V> { 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Weak callback & friends: 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const PersistentContainerCallbackType kCallbackType = kNotWeak; 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> > 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapType; 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef void WeakCallbackDataType; 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static WeakCallbackDataType* WeakCallbackParameter( 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MapType* map, const K& key, Local<V> value) { 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static MapType* MapFromWeakCallbackData( 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const WeakCallbackData<V, WeakCallbackDataType>& data) { 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static K KeyFromWeakCallbackData( 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const WeakCallbackData<V, WeakCallbackDataType>& data) { 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return K(); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void DisposeCallbackData(WeakCallbackDataType* data) { } 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { } 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/** 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * A map wrapper that allows using UniquePersistent as a mapped value. 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * C++11 embedders don't need this class, as they can use UniquePersistent 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * directly in std containers. 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * The map relies on a backing map, whose type and accessors are described 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * by the Traits class. The backing map will handle values of type 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * PersistentContainerValue, with all conversion into and out of V8 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * handles being transparently handled by this class. 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename K, typename V, typename Traits> 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PersistentValueMap { 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {} 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~PersistentValueMap() { Clear(); } 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* GetIsolate() { return isolate_; } 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Return size of the map. 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t Size() { return Traits::Size(&impl_); } 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Return whether the map holds weak persistents. 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsWeak() { return Traits::kCallbackType != kNotWeak; } 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Get value stored in map. 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Local<V> Get(const K& key) { 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key))); 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Check whether a value is contained in the map. 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool Contains(const K& key) { 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Traits::Get(&impl_, key) != kPersistentContainerNotFound; 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Get value stored in map and set it in returnValue. 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Return true if a value was found. 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool SetReturnValue(const K& key, 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReturnValue<Value> returnValue) { 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key)); 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Call Isolate::SetReference with the given parent and the map value. 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetReference(const K& key, 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Persistent<Object>& parent) { 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetIsolate()->SetReference( 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<internal::Object**>(parent.val_), 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key)))); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Put value into map. Depending on Traits::kIsWeak, the value will be held 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * by the map strongly or weakly. 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Returns old value as UniquePersistent. 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> Set(const K& key, Local<V> value) { 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> persistent(isolate_, value); 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SetUnique(key, &persistent); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Put value into map, like Set(const K&, Local<V>). 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) { 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SetUnique(key, &value); 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Return value for key and remove it from the map. 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> Remove(const K& key) { 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Release(Traits::Remove(&impl_, key)).Pass(); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Traverses the map repeatedly, 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * in case side effects of disposal cause insertions. 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch **/ 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Clear() { 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef typename Traits::Iterator It; 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope handle_scope(isolate_); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(dcarney): figure out if this swap and loop is necessary. 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!Traits::Empty(&impl_)) { 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename Traits::Impl impl; 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::Swap(impl_, impl); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) { 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::Key(i)); 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Helper class for GetReference/SetWithReference. Do not use outside 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * that context. 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class PersistentValueReference { 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentValueReference() : value_(kPersistentContainerNotFound) { } 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentValueReference(const PersistentValueReference& other) 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : value_(other.value_) { } 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Local<V> NewLocal(Isolate* isolate) const { 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Local<V>::New(isolate, FromVal(value_)); 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsEmpty() const { 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value_ == kPersistentContainerNotFound; 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<typename T> 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool SetReturnValue(ReturnValue<T> returnValue) { 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SetReturnValueFromVal(&returnValue, value_); 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Reset() { 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ = kPersistentContainerNotFound; 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void operator=(const PersistentValueReference& other) { 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ = other.value_; 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class PersistentValueMap; 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit PersistentValueReference(PersistentContainerValue value) 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : value_(value) { } 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void operator=(PersistentContainerValue value) { 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ = value; 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentContainerValue value_; 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Get a reference to a map value. This enables fast, repeated access 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * to a value stored in the map while the map remains unchanged. 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Careful: This is potentially unsafe, so please use with care. 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * The value will become invalid if the value for this key changes 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * in the underlying map, as a result of Set or Remove for the same 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * key; as a result of the weak callback for the same key; or as a 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * result of calling Clear() or destruction of the map. 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentValueReference GetReference(const K& key) { 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return PersistentValueReference(Traits::Get(&impl_, key)); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Put a value into the map and update the reference. 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Restrictions of GetReference apply here as well. 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> Set(const K& key, UniquePersistent<V> value, 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentValueReference* reference) { 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reference = Leak(&value); 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SetUnique(key, &value); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentValueMap(PersistentValueMap&); 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void operator=(PersistentValueMap&); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Put the value into the map, and set the 'weak' callback when demanded 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * by the Traits class. 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) { 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Traits::kCallbackType != kNotWeak) { 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Local<V> value(Local<V>::New(isolate_, *persistent)); 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch persistent->template SetWeak<typename Traits::WeakCallbackDataType>( 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::WeakCallbackParameter(this, key, value), WeakCallback); 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentContainerValue old_value = 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::Set(&impl_, key, ClearAndLeak(persistent)); 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Release(old_value).Pass(); 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void WeakCallback( 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Traits::kCallbackType != kNotWeak) { 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PersistentValueMap<K, V, Traits>* persistentValueMap = 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::MapFromWeakCallbackData(data); 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch K key = Traits::KeyFromWeakCallbackData(data); 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::Dispose(data.GetIsolate(), 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch persistentValueMap->Remove(key).Pass(), key); 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::DisposeCallbackData(data.GetParameter()); 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static V* FromVal(PersistentContainerValue v) { 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<V*>(v); 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool SetReturnValueFromVal( 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ReturnValue<Value>* returnValue, PersistentContainerValue value) { 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool hasValue = value != kPersistentContainerNotFound; 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (hasValue) { 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch returnValue->SetInternal( 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reinterpret_cast<internal::Object**>(FromVal(value))); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return hasValue; 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PersistentContainerValue ClearAndLeak( 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V>* persistent) { 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V* v = persistent->val_; 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch persistent->val_ = 0; 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<PersistentContainerValue>(v); 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PersistentContainerValue Leak( 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V>* persistent) { 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<PersistentContainerValue>(persistent->val_); 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Return a container value as UniquePersistent and make sure the weak 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * callback is properly disposed of. All remove functionality should go 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * through this. 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static UniquePersistent<V> Release(PersistentContainerValue v) { 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> p; 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p.val_ = FromVal(v); 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (Traits::kCallbackType != kNotWeak && p.IsWeak()) { 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::DisposeCallbackData( 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p.template ClearWeak<typename Traits::WeakCallbackDataType>()); 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return p.Pass(); 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate_; 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename Traits::Impl impl_; 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/** 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * A map that uses UniquePersistent as value and std::map as the backing 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * implementation. Persistents are held non-weak. 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * C++11 embedders don't need this class, as they can use 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * UniquePersistent directly in std containers. 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename K, typename V, 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename Traits = DefaultPersistentValueMapTraits<K, V> > 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StdPersistentValueMap : public PersistentValueMap<K, V, Traits> { 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit StdPersistentValueMap(Isolate* isolate) 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PersistentValueMap<K, V, Traits>(isolate) {} 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DefaultPersistentValueVectorTraits { 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef std::vector<PersistentContainerValue> Impl; 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Append(Impl* impl, PersistentContainerValue value) { 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch impl->push_back(value); 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsEmpty(const Impl* impl) { 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return impl->empty(); 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static size_t Size(const Impl* impl) { 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return impl->size(); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PersistentContainerValue Get(const Impl* impl, size_t i) { 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound; 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ReserveCapacity(Impl* impl, size_t capacity) { 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch impl->reserve(capacity); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void Clear(Impl* impl) { 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch impl->clear(); 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/** 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * A vector wrapper that safely stores UniquePersistent values. 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * C++11 embedders don't need this class, as they can use UniquePersistent 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * directly in std containers. 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * This class relies on a backing vector implementation, whose type and methods 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * are described by the Traits class. The backing map will handle values of type 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * PersistentContainerValue, with all conversion into and out of V8 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * handles being transparently handled by this class. 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename V, typename Traits = DefaultPersistentValueVectorTraits> 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PersistentValueVector { 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { } 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~PersistentValueVector() { 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Clear(); 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Append a value to the vector. 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Append(Local<V> value) { 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> persistent(isolate_, value); 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::Append(&impl_, ClearAndLeak(&persistent)); 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Append a persistent's value to the vector. 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Append(UniquePersistent<V> persistent) { 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::Append(&impl_, ClearAndLeak(&persistent)); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Are there any values in the vector? 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsEmpty() const { 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Traits::IsEmpty(&impl_); 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * How many elements are in the vector? 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t Size() const { 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Traits::Size(&impl_); 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Retrieve the i-th value in the vector. 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Local<V> Get(size_t index) const { 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index))); 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Remove all elements from the vector. 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Clear() { 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t length = Traits::Size(&impl_); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < length; i++) { 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V> p; 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p.val_ = FromVal(Traits::Get(&impl_, i)); 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::Clear(&impl_); 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch /** 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * Reserve capacity in the vector. 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch * (Efficiency gains depend on the backing implementation.) 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch */ 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ReserveCapacity(size_t capacity) { 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Traits::ReserveCapacity(&impl_, capacity); 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static PersistentContainerValue ClearAndLeak( 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UniquePersistent<V>* persistent) { 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V* v = persistent->val_; 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch persistent->val_ = 0; 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<PersistentContainerValue>(v); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static V* FromVal(PersistentContainerValue v) { 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<V*>(v); 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate_; 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typename Traits::Impl impl_; 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_UTIL_H_ 488