Chromium Code Reviews| Index: include/v8-util.h |
| diff --git a/include/v8-util.h b/include/v8-util.h |
| index 5cee46704af332d97443c903b59f92384e7f490c..d99ce94ad26bdc9d71a2dcea7d944a17b69593da 100644 |
| --- a/include/v8-util.h |
| +++ b/include/v8-util.h |
| @@ -43,6 +43,63 @@ typedef uintptr_t PersistentContainerValue; |
| static const uintptr_t kPersistentContainerNotFound = 0; |
| /** |
| + * A default trait implemenation for PersistentValueMap, which uses std::map |
| + * as a backing map and is not weak. |
| + */ |
| +template<typename K, typename V> |
| +class DefaultPersistentValueMapTraits { |
| + public: |
| + // STL map & related: |
| + typedef std::map<K, v8::PersistentContainerValue> Impl; |
| + typedef typename Impl::iterator Iterator; |
| + |
| + static bool Empty(Impl* impl) { return impl->empty(); } |
| + static size_t Size(Impl* impl) { return impl->size(); } |
| + static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT |
| + static Iterator Begin(Impl* impl) { return impl->begin(); } |
| + static Iterator End(Impl* impl) { return impl->end(); } |
| + static K Key(Iterator it) { return it->first; } |
| + static v8::PersistentContainerValue Value(Iterator it) { return it->second; } |
| + static v8::PersistentContainerValue Set(Impl* impl, K key, |
| + v8::PersistentContainerValue value) { |
| + std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value)); |
| + v8::PersistentContainerValue old_value = v8::kPersistentContainerNotFound; |
| + if (!res.second) { |
| + old_value = res.first->second; |
| + res.first->second = value; |
| + } |
| + return old_value; |
| + } |
| + static v8::PersistentContainerValue Get(Impl* impl, K key) { |
| + Iterator it = impl->find(key); |
| + if (it == impl->end()) return v8::kPersistentContainerNotFound; |
| + return it->second; |
| + } |
| + static v8::PersistentContainerValue Remove(Impl* impl, K key) { |
| + Iterator it = impl->find(key); |
| + if (it == impl->end()) return v8::kPersistentContainerNotFound; |
| + v8::PersistentContainerValue value = it->second; |
| + impl->erase(it); |
| + return value; |
| + } |
| + |
| + // Dispose: |
| + static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<V> value, |
|
dcarney
2014/03/18 12:13:19
still have the problem that these are overridden i
vogelheim
2014/03/18 12:55:13
Done.
Now:
- StdMapTraits: std::map as backing im
|
| + Impl* impl, K key) {} |
| + |
| + // Weak callback & friends: |
| + static const bool kIsWeak = false; |
| + typedef void WeakCallbackDataType; |
| + static WeakCallbackDataType* WeakCallbackParameter( |
| + Impl* impl, const K& key, Local<V> value); |
| + static Impl* ImplFromWeakCallbackData( |
| + const v8::WeakCallbackData<V, WeakCallbackDataType>& data); |
| + static K KeyFromWeakCallbackData( |
| + const v8::WeakCallbackData<V, WeakCallbackDataType>& data); |
| + static void DisposeCallbackData(WeakCallbackDataType* data); |
| +}; |
| + |
| +/** |
|
dcarney
2014/03/18 12:13:19
2 lines between definitions.
vogelheim
2014/03/18 12:55:13
Done.
|
| * A map wrapper that allows using UniquePersistent as a mapped value. |
| * C++11 embedders don't need this class, as they can use UniquePersistent |
| * directly in std containers. |
| @@ -52,7 +109,7 @@ static const uintptr_t kPersistentContainerNotFound = 0; |
| * PersistentContainerValue, with all conversion into and out of V8 |
| * handles being transparently handled by this class. |
| */ |
| -template<class K, class V, class Traits> |
| +template<typename K, typename V, typename Traits> |
| class PersistentValueMap { |
| public: |
| V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {} |
| @@ -67,6 +124,11 @@ class PersistentValueMap { |
| V8_INLINE size_t Size() { return Traits::Size(&impl_); } |
| /** |
| + * Return whether the map holds weak persistents. |
| + */ |
| + V8_INLINE bool IsWeak() { return Traits::kIsWeak; } |
| + |
| + /** |
| * Get value stored in map. |
| */ |
| V8_INLINE Local<V> Get(const K& key) { |
| @@ -85,7 +147,15 @@ class PersistentValueMap { |
| * Return true if a value was found. |
| */ |
| V8_INLINE bool SetReturnValue(const K& key, |
| - ReturnValue<Value>& returnValue); |
| + ReturnValue<Value>& returnValue) { |
| + PersistentContainerValue value = Traits::Get(&impl_, key); |
| + bool hasValue = value != 0; |
| + if (hasValue) { |
| + returnValue.SetInternal( |
| + *reinterpret_cast<internal::Object**>(FromVal(value))); |
| + } |
| + return hasValue; |
| + } |
| /** |
| * Call Isolate::SetReference with the given parent and the map value. |
| @@ -125,7 +195,19 @@ class PersistentValueMap { |
| * Traverses the map repeatedly, |
| * in case side effects of disposal cause insertions. |
| **/ |
| - void Clear(); |
| + void Clear() { |
| + typedef typename Traits::Iterator It; |
| + HandleScope handle_scope(isolate_); |
| + // TODO(dcarney): figure out if this swap and loop is necessary. |
| + while (!Traits::Empty(&impl_)) { |
| + typename Traits::Impl impl; |
| + Traits::Swap(impl_, impl); |
| + for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) { |
| + Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl, |
| + Traits::Key(i)); |
| + } |
| + } |
| + } |
| private: |
| PersistentValueMap(PersistentValueMap&); |
| @@ -147,10 +229,17 @@ class PersistentValueMap { |
| } |
| static void WeakCallback( |
| - const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data); |
| + const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { |
| + typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data); |
| + K key = Traits::KeyFromWeakCallbackData(data); |
| + PersistentContainerValue value = Traits::Remove(impl, key); |
| + Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key); |
| + } |
| + |
| V8_INLINE static V* FromVal(PersistentContainerValue v) { |
| return reinterpret_cast<V*>(v); |
| } |
| + |
| V8_INLINE static PersistentContainerValue ClearAndLeak( |
| UniquePersistent<V>* persistent) { |
| V* v = persistent->val_; |
| @@ -177,42 +266,18 @@ class PersistentValueMap { |
| typename Traits::Impl impl_; |
| }; |
| -template <class K, class V, class Traits> |
| -bool PersistentValueMap<K, V, Traits>::SetReturnValue(const K& key, |
| - ReturnValue<Value>& returnValue) { |
| - PersistentContainerValue value = Traits::Get(&impl_, key); |
| - bool hasValue = value != 0; |
| - if (hasValue) { |
| - returnValue.SetInternal( |
| - *reinterpret_cast<internal::Object**>(FromVal(value))); |
| - } |
| - return hasValue; |
| -} |
| - |
| -template <class K, class V, class Traits> |
| -void PersistentValueMap<K, V, Traits>::Clear() { |
| - typedef typename Traits::Iterator It; |
| - HandleScope handle_scope(isolate_); |
| - // TODO(dcarney): figure out if this swap and loop is necessary. |
| - while (!Traits::Empty(&impl_)) { |
| - typename Traits::Impl impl; |
| - Traits::Swap(impl_, impl); |
| - for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) { |
| - Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl, |
| - Traits::Key(i)); |
| - } |
| - } |
| -} |
| - |
| - |
| -template <class K, class V, class Traits> |
| -void PersistentValueMap<K, V, Traits>::WeakCallback( |
| - const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { |
| - typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data); |
| - K key = Traits::KeyFromWeakCallbackData(data); |
| - PersistentContainerValue value = Traits::Remove(impl, key); |
| - Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key); |
| -} |
| +/** |
|
dcarney
2014/03/18 12:13:19
again
vogelheim
2014/03/18 12:55:13
Done.
|
| + * A map that uses UniquePersistent as value and std::map as the backing |
| + * implementation. C++11 embedders don't need this class, as they can use |
| + * UniquePersistent directly in std containers. |
| + */ |
| +template<typename K, typename V, |
| + typename Traits = DefaultPersistentValueMapTraits<K, V> > |
| +class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> { |
| + public: |
| + explicit StdPersistentValueMap(v8::Isolate* isolate) |
| + : PersistentValueMap<K, V, Traits>(isolate) {} |
| +}; |
| } // namespace v8 |