Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: include/v8-util.h

Issue 863443005: Support old and new weak handle API (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Undo cast that was not needed. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/v8.h ('k') | src/api.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: include/v8-util.h
diff --git a/include/v8-util.h b/include/v8-util.h
index 1eaf1ab68f6be618a6690c25b7e10a297e88ee6e..ca36b6c58bcf0cdc762f2aa01a259cc67334a986 100644
--- a/include/v8-util.h
+++ b/include/v8-util.h
@@ -105,6 +105,43 @@ class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
};
+template <typename K, typename V>
+class DefaultPhantomPersistentValueMapTraits : public StdMapTraits<K, V> {
+ private:
+ template <typename T>
+ struct RemovePointer;
+
+ public:
+ // Weak callback & friends:
+ static const PersistentContainerCallbackType kCallbackType = kNotWeak;
+ typedef PersistentValueMap<
+ K, V, DefaultPhantomPersistentValueMapTraits<K, V> > MapType;
+ typedef void PhantomCallbackDataType;
+
+ static PhantomCallbackDataType* PhantomCallbackParameter(MapType* map,
+ const K& key,
+ Local<V> value) {
+ return NULL;
+ }
+ static MapType* MapFromPhantomCallbackData(
+ const PhantomCallbackData<PhantomCallbackDataType>& data) {
+ return NULL;
+ }
+ static K KeyFromPhantomCallbackData(
+ const PhantomCallbackData<PhantomCallbackDataType>& data) {
+ return K();
+ }
+ static void DisposeCallbackData(PhantomCallbackDataType* data) {}
+ static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) {}
+
+ private:
+ template <typename T>
+ struct RemovePointer<T*> {
+ typedef T Type;
+ };
+};
+
+
/**
* A map wrapper that allows using UniquePersistent as a mapped value.
* C++11 embedders don't need this class, as they can use UniquePersistent
@@ -115,13 +152,9 @@ class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
-template<typename K, typename V, typename Traits>
-class PersistentValueMap {
+template <typename K, typename V, typename Traits>
+class PersistentValueMapBase {
public:
- explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {}
-
- ~PersistentValueMap() { Clear(); }
-
Isolate* GetIsolate() { return isolate_; }
/**
@@ -168,23 +201,6 @@ class PersistentValueMap {
}
/**
- * Put value into map. Depending on Traits::kIsWeak, the value will be held
- * by the map strongly or weakly.
- * Returns old value as UniquePersistent.
- */
- UniquePersistent<V> Set(const K& key, Local<V> value) {
- UniquePersistent<V> persistent(isolate_, value);
- return SetUnique(key, &persistent);
- }
-
- /**
- * Put value into map, like Set(const K&, Local<V>).
- */
- UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) {
- return SetUnique(key, &value);
- }
-
- /**
* Return value for key and remove it from the map.
*/
UniquePersistent<V> Remove(const K& key) {
@@ -237,7 +253,9 @@ class PersistentValueMap {
}
private:
- friend class PersistentValueMap;
+ friend class PersistentValueMapBase;
+ friend class PersistentValueMap<K, V, Traits>;
+ friend class PhantomPersistentValueMap<K, V, Traits>;
explicit PersistentValueReference(PersistentContainerValue value)
: value_(value) { }
@@ -263,19 +281,89 @@ class PersistentValueMap {
return PersistentValueReference(Traits::Get(&impl_, key));
}
+ protected:
+ explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {}
+
+ ~PersistentValueMapBase() { Clear(); }
+
+ Isolate* isolate() { return isolate_; }
+ typename Traits::Impl* impl() { return &impl_; }
+
+ static V* FromVal(PersistentContainerValue v) {
+ return reinterpret_cast<V*>(v);
+ }
+
+ static PersistentContainerValue ClearAndLeak(
+ UniquePersistent<V>* persistent) {
+ V* v = persistent->val_;
+ persistent->val_ = 0;
+ return reinterpret_cast<PersistentContainerValue>(v);
+ }
+
+ static PersistentContainerValue Leak(UniquePersistent<V>* persistent) {
+ return reinterpret_cast<PersistentContainerValue>(persistent->val_);
+ }
+
/**
- * Put a value into the map and update the reference.
- * Restrictions of GetReference apply here as well.
+ * Return a container value as UniquePersistent and make sure the weak
+ * callback is properly disposed of. All remove functionality should go
+ * through this.
*/
- UniquePersistent<V> Set(const K& key, UniquePersistent<V> value,
- PersistentValueReference* reference) {
- *reference = Leak(&value);
- return SetUnique(key, &value);
+ static UniquePersistent<V> Release(PersistentContainerValue v) {
+ UniquePersistent<V> p;
+ p.val_ = FromVal(v);
+ if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
+ Traits::DisposeCallbackData(
+ p.template ClearWeak<typename Traits::WeakCallbackDataType>());
+ }
+ return p.Pass();
}
private:
- PersistentValueMap(PersistentValueMap&);
- void operator=(PersistentValueMap&);
+ PersistentValueMapBase(PersistentValueMapBase&);
+ void operator=(PersistentValueMapBase&);
+
+ static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
+ PersistentContainerValue value) {
+ bool hasValue = value != kPersistentContainerNotFound;
+ if (hasValue) {
+ returnValue->SetInternal(
+ *reinterpret_cast<internal::Object**>(FromVal(value)));
+ }
+ return hasValue;
+ }
+
+ Isolate* isolate_;
+ typename Traits::Impl impl_;
+};
+
+
+template <typename K, typename V, typename Traits>
+class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
+ public:
+ explicit PersistentValueMap(Isolate* isolate)
+ : PersistentValueMapBase<K, V, Traits>(isolate) {}
+
+ typedef
+ typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
+ PersistentValueReference;
+
+ /**
+ * Put value into map. Depending on Traits::kIsWeak, the value will be held
+ * by the map strongly or weakly.
+ * Returns old value as UniquePersistent.
+ */
+ UniquePersistent<V> Set(const K& key, Local<V> value) {
+ UniquePersistent<V> persistent(this->isolate(), value);
+ return SetUnique(key, &persistent);
+ }
+
+ /**
+ * Put value into map, like Set(const K&, Local<V>).
+ */
+ UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) {
+ return SetUnique(key, &value);
+ }
/**
* Put the value into the map, and set the 'weak' callback when demanded
@@ -283,15 +371,26 @@ class PersistentValueMap {
*/
UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
- Local<V> value(Local<V>::New(isolate_, *persistent));
+ Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), WeakCallback);
}
PersistentContainerValue old_value =
- Traits::Set(&impl_, key, ClearAndLeak(persistent));
- return Release(old_value).Pass();
+ Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
+ return this->Release(old_value).Pass();
+ }
+
+ /**
+ * Put a value into the map and update the reference.
+ * Restrictions of GetReference apply here as well.
+ */
+ UniquePersistent<V> Set(const K& key, UniquePersistent<V> value,
+ PersistentValueReference* reference) {
+ *reference = this->Leak(&value);
+ return SetUnique(key, &value);
}
+ private:
static void WeakCallback(
const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
@@ -303,50 +402,73 @@ class PersistentValueMap {
Traits::DisposeCallbackData(data.GetParameter());
}
}
+};
- static V* FromVal(PersistentContainerValue v) {
- return reinterpret_cast<V*>(v);
- }
- static bool SetReturnValueFromVal(
- ReturnValue<Value>* returnValue, PersistentContainerValue value) {
- bool hasValue = value != kPersistentContainerNotFound;
- if (hasValue) {
- returnValue->SetInternal(
- *reinterpret_cast<internal::Object**>(FromVal(value)));
- }
- return hasValue;
- }
+template <typename K, typename V, typename Traits>
+class PhantomPersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
+ public:
+ explicit PhantomPersistentValueMap(Isolate* isolate)
+ : PersistentValueMapBase<K, V, Traits>(isolate) {}
- static PersistentContainerValue ClearAndLeak(
- UniquePersistent<V>* persistent) {
- V* v = persistent->val_;
- persistent->val_ = 0;
- return reinterpret_cast<PersistentContainerValue>(v);
+ typedef
+ typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
+ PersistentValueReference;
+
+ /**
+ * Put value into map. Depending on Traits::kIsWeak, the value will be held
+ * by the map strongly or weakly.
+ * Returns old value as UniquePersistent.
+ */
+ UniquePersistent<V> Set(const K& key, Local<V> value) {
+ UniquePersistent<V> persistent(this->isolate(), value);
+ return SetUnique(key, &persistent);
}
- static PersistentContainerValue Leak(
- UniquePersistent<V>* persistent) {
- return reinterpret_cast<PersistentContainerValue>(persistent->val_);
+ /**
+ * Put value into map, like Set(const K&, Local<V>).
+ */
+ UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) {
+ return SetUnique(key, &value);
}
/**
- * Return a container value as UniquePersistent and make sure the weak
- * callback is properly disposed of. All remove functionality should go
- * through this.
+ * Put the value into the map, and set the 'weak' callback when demanded
+ * by the Traits class.
*/
- static UniquePersistent<V> Release(PersistentContainerValue v) {
- UniquePersistent<V> p;
- p.val_ = FromVal(v);
- if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
- Traits::DisposeCallbackData(
- p.template ClearWeak<typename Traits::WeakCallbackDataType>());
+ UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
+ if (Traits::kCallbackType != kNotWeak) {
+ Local<V> value(Local<V>::New(this->isolate(), *persistent));
+ persistent->template SetPhantom<typename Traits::WeakCallbackDataType>(
+ Traits::WeakCallbackParameter(this, key, value), WeakCallback, 0, 1);
}
- return p.Pass();
+ PersistentContainerValue old_value =
+ Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
+ return this->Release(old_value).Pass();
}
- Isolate* isolate_;
- typename Traits::Impl impl_;
+ /**
+ * Put a value into the map and update the reference.
+ * Restrictions of GetReference apply here as well.
+ */
+ UniquePersistent<V> Set(const K& key, UniquePersistent<V> value,
+ PersistentValueReference* reference) {
+ *reference = this->Leak(&value);
+ return SetUnique(key, &value);
+ }
+
+ private:
+ static void WeakCallback(
+ const PhantomCallbackData<typename Traits::WeakCallbackDataType>& data) {
+ if (Traits::kCallbackType != kNotWeak) {
+ PhantomPersistentValueMap<K, V, Traits>* persistentValueMap =
+ Traits::MapFromPhantomCallbackData(data);
+ K key = Traits::KeyFromPhantomCallbackData(data);
+ Traits::Dispose(data.GetIsolate(), persistentValueMap->Remove(key).Pass(),
+ key);
+ Traits::DisposeCallbackData(data.GetParameter());
+ }
+ }
};
« no previous file with comments | « include/v8.h ('k') | src/api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698