Chromium Code Reviews| Index: include/v8-util.h |
| diff --git a/include/v8-util.h b/include/v8-util.h |
| index 3f8cc6d269d0a6598944720980771210de49b73c..597fe43d3194e32efd15b4090dcf822e0f0eeac1 100644 |
| --- a/include/v8-util.h |
| +++ b/include/v8-util.h |
| @@ -92,38 +92,34 @@ class StdMapTraits { |
| /** |
| * A default trait implementation for PersistentValueMap, which inherits |
| * a std:map backing map from StdMapTraits and holds non-weak persistent |
| - * objects. |
| + * objects and has no special Dispose handling. |
| * |
| - * Users have to implement their own dispose trait. |
| + * You should not derive from this class, since MapType depends on the |
| + * surrounding class, and hence a subclass cannot simply inherit the methods. |
| */ |
| template<typename K, typename V> |
| -class StrongMapTraits : public StdMapTraits<K, V> { |
| +class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> { |
| public: |
| // Weak callback & friends: |
| static const bool kIsWeak = false; |
| - typedef typename StdMapTraits<K, V>::Impl Impl; |
| + typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> > |
| + MapType; |
| typedef void WeakCallbackDataType; |
| + |
| static WeakCallbackDataType* WeakCallbackParameter( |
| - Impl* impl, const K& key, Local<V> value); |
| - static Impl* ImplFromWeakCallbackData( |
| - const WeakCallbackData<V, WeakCallbackDataType>& data); |
| + MapType* map, const K& key, Local<V> value) { |
| + return NULL; |
| + } |
| + static MapType* MapFromWeakCallbackData( |
| + const WeakCallbackData<V, WeakCallbackDataType>& data) { |
| + return NULL; |
| + } |
| static K KeyFromWeakCallbackData( |
| - const WeakCallbackData<V, WeakCallbackDataType>& data); |
| - static void DisposeCallbackData(WeakCallbackDataType* data); |
| -}; |
| - |
| - |
| -/** |
| - * A default trait implementation for PersistentValueMap, with a std::map |
| - * backing map, non-weak persistents as values, and no special dispose |
| - * handling. Can be used as-is. |
| - */ |
| -template<typename K, typename V> |
| -class DefaultPersistentValueMapTraits : public StrongMapTraits<K, V> { |
| - public: |
| - typedef typename StrongMapTraits<K, V>::Impl Impl; |
| - static void Dispose(Isolate* isolate, UniquePersistent<V> value, |
| - Impl* impl, K key) { } |
| + const WeakCallbackData<V, WeakCallbackDataType>& data) { |
| + return K(); |
| + } |
| + static void DisposeCallbackData(WeakCallbackDataType* data) { } |
| + static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { } |
| }; |
| @@ -167,7 +163,7 @@ class PersistentValueMap { |
| * Check whether a value is contained in the map. |
| */ |
| V8_INLINE bool Contains(const K& key) { |
| - return Traits::Get(&impl_, key) != 0; |
| + return Traits::Get(&impl_, key) != kPersistentContainerNotFound; |
| } |
| /** |
| @@ -175,14 +171,8 @@ class PersistentValueMap { |
| * Return true if a value was found. |
| */ |
| V8_INLINE bool 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; |
| + ReturnValue<Value> returnValue) { |
| + return SetReturnValueFromVal(returnValue, Traits::Get(&impl_, key)); |
| } |
| /** |
| @@ -231,12 +221,71 @@ class PersistentValueMap { |
| 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)); |
| + Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), |
| + Traits::Key(i)); |
| } |
| } |
| } |
| + /** |
| + * Helper class for GetReference/SetWithReference. Do not use outside |
| + * that context. |
| + */ |
| + class PersistentValueReference { |
| + public: |
| + PersistentValueReference() : value_(kPersistentContainerNotFound) { } |
| + Local<V> NewLocal(Isolate* isolate) const { |
| + return Local<V>::New(isolate, FromVal(value_)); |
| + } |
| + bool IsEmpty() const { |
| + return value_ == kPersistentContainerNotFound; |
| + } |
| + template<typename T> |
| + bool SetReturnValue(ReturnValue<T> returnValue) { |
| + return SetReturnValueFromVal(returnValue, value_); |
| + } |
| + void Reset() { |
| + value_ = kPersistentContainerNotFound; |
| + } |
| + void operator=(const PersistentValueReference& other) { |
| + value_ = other.value_; |
| + } |
| + |
| + private: |
| + friend class PersistentValueMap; |
| + explicit PersistentValueReference(PersistentContainerValue value) |
|
dcarney
2014/03/27 07:45:22
expose copy constructor
vogelheim
2014/03/27 14:43:54
Done.
|
| + : value_(value) { } |
| + |
| + PersistentContainerValue value_; |
| + }; |
| + |
| + /** |
| + * Helper for V8ValueCache: Get a reference to a map value. |
|
dcarney
2014/03/27 07:45:22
don't mention v8valuecache
vogelheim
2014/03/27 14:43:54
Done.
|
| + * This enables fast, repeated access to a value stored in the map |
| + * while the map remains unchanged. |
| + * |
| + * Careful: This is potentially unsafe, in that *any* change to the |
|
dcarney
2014/03/27 07:45:22
there are limited actions that invalidates these :
vogelheim
2014/03/27 14:43:54
Done.
I'm not entirely convinced of it, though: T
|
| + * map may invalidate the reference. |
| + */ |
| + V8_INLINE PersistentValueReference GetReference(const K& key) { |
| + return PersistentValueReference(Traits::Get(&impl_, key)); |
| + } |
| + |
| + /** |
| + * Helper for V8ValueCache: Set a new persistent in the map, and |
| + * also return a reference to it. |
| + * This enables fast, repeated access to a value stored in the map |
| + * while the map remains unchanged. |
| + * |
| + * Careful: This is potentially unsafe, in that *any* change to the |
| + * map may invalidate the reference. |
| + */ |
| + V8_INLINE PersistentValueReference SetWithReference( |
|
dcarney
2014/03/27 07:45:22
no need for this function since it calls just Set
vogelheim
2014/03/27 14:43:54
Removed.
|
| + const K& key, UniquePersistent<V> value) { |
| + Set(key, value.Pass()); |
| + return GetReference(key); |
| + } |
| + |
| private: |
| PersistentValueMap(PersistentValueMap&); |
| void operator=(PersistentValueMap&); |
| @@ -249,7 +298,7 @@ class PersistentValueMap { |
| if (Traits::kIsWeak) { |
| Local<V> value(Local<V>::New(isolate_, *persistent)); |
| persistent->template SetWeak<typename Traits::WeakCallbackDataType>( |
| - Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback); |
| + Traits::WeakCallbackParameter(this, key, value), WeakCallback); |
| } |
| PersistentContainerValue old_value = |
| Traits::Set(&impl_, key, ClearAndLeak(persistent)); |
| @@ -259,10 +308,11 @@ class PersistentValueMap { |
| static void WeakCallback( |
| const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { |
| if (Traits::kIsWeak) { |
| - typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data); |
| + PersistentValueMap<K, V, Traits>* persistentValueMap = |
| + Traits::MapFromWeakCallbackData(data); |
| K key = Traits::KeyFromWeakCallbackData(data); |
| - PersistentContainerValue value = Traits::Remove(impl, key); |
| - Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key); |
| + Traits::Dispose(data.GetIsolate(), |
| + persistentValueMap->Remove(key).Pass(), key); |
| } |
| } |
| @@ -270,6 +320,16 @@ class PersistentValueMap { |
| return reinterpret_cast<V*>(v); |
| } |
| + V8_INLINE static bool SetReturnValueFromVal( |
| + ReturnValue<Value>& returnValue, PersistentContainerValue value) { |
| + bool hasValue = value != kPersistentContainerNotFound; |
| + if (hasValue) { |
| + returnValue.SetInternal( |
| + *reinterpret_cast<internal::Object**>(FromVal(value))); |
| + } |
| + return hasValue; |
| + } |
| + |
| V8_INLINE static PersistentContainerValue ClearAndLeak( |
| UniquePersistent<V>* persistent) { |
| V* v = persistent->val_; |
| @@ -312,44 +372,6 @@ class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> { |
| : PersistentValueMap<K, V, Traits>(isolate) {} |
| }; |
| - |
| -/** |
| - * Empty default implementations for StrongTraits methods. |
| - * |
| - * These should not be necessary, since they're only used in code that |
| - * is surrounded by if(Traits::kIsWeak), which for StrongMapTraits is |
| - * compile-time false. Most compilers can live without them; however |
| - * the compiler we use from 64-bit Win differs. |
| - * |
| - * TODO(vogelheim): Remove these once they're no longer necessary. |
| - */ |
| -template<typename K, typename V> |
| -typename StrongMapTraits<K, V>::WeakCallbackDataType* |
| - StrongMapTraits<K, V>::WeakCallbackParameter( |
| - Impl* impl, const K& key, Local<V> value) { |
| - return NULL; |
| -} |
| - |
| - |
| -template<typename K, typename V> |
| -typename StrongMapTraits<K, V>::Impl* |
| - StrongMapTraits<K, V>::ImplFromWeakCallbackData( |
| - const WeakCallbackData<V, WeakCallbackDataType>& data) { |
| - return NULL; |
| -} |
| - |
| - |
| -template<typename K, typename V> |
| -K StrongMapTraits<K, V>::KeyFromWeakCallbackData( |
| - const WeakCallbackData<V, WeakCallbackDataType>& data) { |
| - return K(); |
| -} |
| - |
| - |
| -template<typename K, typename V> |
| -void StrongMapTraits<K, V>::DisposeCallbackData(WeakCallbackDataType* data) { |
| -} |
| - |
| } // namespace v8 |
| #endif // V8_UTIL_H_ |