Index: Source/bindings/v8/DOMWrapperMap.h |
diff --git a/Source/bindings/v8/DOMWrapperMap.h b/Source/bindings/v8/DOMWrapperMap.h |
index 20fe7625f0422e27be900690c3e6efb90f0c9a62..c2a29bcd746067b25bd0860993127b19f933ad16 100644 |
--- a/Source/bindings/v8/DOMWrapperMap.h |
+++ b/Source/bindings/v8/DOMWrapperMap.h |
@@ -32,104 +32,171 @@ |
#define DOMWrapperMap_h |
#include "bindings/v8/UnsafePersistent.h" |
+#include "bindings/v8/V8NPObject.h" |
#include "bindings/v8/WrapperTypeInfo.h" |
#include <v8.h> |
#include "wtf/HashMap.h" |
+#include <stdio.h> |
namespace WebCore { |
template<class KeyType> |
class DOMWrapperMap { |
public: |
- typedef HashMap<KeyType*, UnsafePersistent<v8::Object> > MapType; |
- |
explicit DOMWrapperMap(v8::Isolate* isolate) |
: m_isolate(isolate) |
+ , m_map(isolate) |
{ |
} |
v8::Handle<v8::Object> newLocal(KeyType* key, v8::Isolate* isolate) |
{ |
- return m_map.get(key).newLocal(isolate); |
+ return v8::Local<v8::Object>::New(isolate, m_map.Get(key)); |
dcarney
2014/03/07 09:38:24
Get already returns a local, no need to double wra
vogelheim
2014/03/07 18:01:34
Done.
|
} |
bool setReturnValueFrom(v8::ReturnValue<v8::Value> returnValue, KeyType* key) |
{ |
- typename MapType::iterator it = m_map.find(key); |
- if (it == m_map.end()) |
- return false; |
- returnValue.Set(*(it->value.persistent())); |
- return true; |
+ v8::Local<v8::Object> value = m_map.Get(key); |
dcarney
2014/03/07 09:38:24
we don't want to create a local for setting a retu
vogelheim
2014/03/07 18:01:34
Done.
|
+ bool hasValue = !value.IsEmpty(); |
+ if (hasValue) { |
+ returnValue.Set(value); |
+ } |
+ return hasValue; |
} |
void setReference(const v8::Persistent<v8::Object>& parent, KeyType* key, v8::Isolate* isolate) |
{ |
- m_map.get(key).setReferenceFrom(parent, isolate); |
+ v8::Persistent<v8::Object> ref(isolate, m_map.Get(key)); |
dcarney
2014/03/07 09:38:24
push to PersistentValueMap
vogelheim
2014/03/07 18:01:34
Done.
|
+ isolate->SetReference(parent, ref); |
} |
bool containsKey(KeyType* key) |
{ |
- return m_map.find(key) != m_map.end(); |
+ return !m_map.Get(key).IsEmpty(); |
dcarney
2014/03/07 09:38:24
too expensive - push to PersistentValueMap
vogelheim
2014/03/07 18:01:34
Done.
|
} |
bool containsKeyAndValue(KeyType* key, v8::Handle<v8::Object> value) |
{ |
- typename MapType::iterator it = m_map.find(key); |
- if (it == m_map.end()) |
- return false; |
- return *(it->value.persistent()) == value; |
+ v8::Local<v8::Object> mapValue = m_map.Get(key); |
dcarney
2014/03/07 09:38:24
this function is stupid and only used in an assert
vogelheim
2014/03/07 18:01:34
Done.
Actually, it drops out with this change, si
|
+ return !mapValue.IsEmpty() && (mapValue == value); |
} |
void set(KeyType* key, v8::Handle<v8::Object> wrapper, const WrapperConfiguration& configuration) |
{ |
ASSERT(static_cast<KeyType*>(toNative(wrapper)) == key); |
- v8::Persistent<v8::Object> persistent(m_isolate, wrapper); |
- configuration.configureWrapper(&persistent); |
- persistent.SetWeak(this, &setWeakCallback); |
- typename MapType::AddResult result = m_map.add(key, UnsafePersistent<v8::Object>()); |
- ASSERT(result.isNewEntry); |
- // FIXME: Stop handling this case once duplicate wrappers are guaranteed not to be created. |
- if (!result.isNewEntry) |
- result.storedValue->value.dispose(); |
- result.storedValue->value = UnsafePersistent<v8::Object>(persistent); |
+ ASSERT(!wrapper.IsEmpty()); |
dcarney
2014/03/07 09:38:24
this is asserted in the line above, drop
vogelheim
2014/03/07 18:01:34
Done.
|
+ m_map.SetWithConfig(key, v8::Local<v8::Object>::New(m_isolate, wrapper), |
dcarney
2014/03/07 09:38:24
no need for local::new
vogelheim
2014/03/07 18:01:34
Done.
|
+ configuration.classId, configuration.lifetime); |
} |
void clear() |
{ |
- v8::HandleScope scope(m_isolate); |
- while (!m_map.isEmpty()) { |
- // Swap out m_map on each iteration to ensure any wrappers added due to side effects of the loop are cleared. |
- MapType map; |
- map.swap(m_map); |
- for (typename MapType::iterator it = map.begin(); it != map.end(); ++it) { |
- releaseObject(it->value.newLocal(m_isolate)); |
- it->value.dispose(); |
- } |
- } |
+ m_map.Clear(); |
} |
void removeAndDispose(KeyType* key) |
{ |
- typename MapType::iterator it = m_map.find(key); |
- ASSERT_WITH_SECURITY_IMPLICATION(it != m_map.end()); |
- it->value.dispose(); |
- m_map.remove(it); |
+ m_map.Remove(key); |
} |
private: |
- static void setWeakCallback(const v8::WeakCallbackData<v8::Object, DOMWrapperMap<KeyType> >&); |
+ class PersistentValueMapTraits { |
+ public: |
+ typedef HashMap<KeyType*, v8::PersistentContainerValue> Impl; |
+ typedef typename Impl::iterator Iterator; |
+ |
+ class WeakCallbackDataType { |
dcarney
2014/03/07 09:38:24
WeakCallbackDataType should just be a point to the
vogelheim
2014/03/07 18:01:34
Done.
I find this a weird design, though. This cl
|
+ public: |
+ WeakCallbackDataType(Impl* impl, KeyType* key, v8::Local<v8::Object>& value) |
+ : m_impl(impl) |
+ , m_key(key) |
+ , m_value(value) |
+ { } |
+ Impl* m_impl; |
+ KeyType* m_key; |
+ v8::Local<v8::Object> m_value; |
+ }; |
+ |
+ static const bool kIsWeak = true; |
+ |
+ // Container API: Size/Empty/Swap/Begin/End/Value/Set/Get/Remove |
+ static size_t Size(const Impl* impl) { return impl->size(); } |
+ static bool Empty(Impl* impl) { return impl->isEmpty(); } |
+ static void Swap(Impl& impl, Impl& other) { impl.swap(other); } |
+ |
+ static Iterator Begin(Impl* impl) { return impl->begin(); } |
+ static Iterator End(Impl* impl) { return impl->end(); } |
+ static v8::PersistentContainerValue Value(Iterator& iter) |
+ { |
+ return iter->value; |
+ } |
+ static KeyType* Key(Iterator& iter) { return iter->key; } |
+ |
+ static v8::PersistentContainerValue Set( |
+ Impl* impl, KeyType* key, v8::PersistentContainerValue value) |
+ { |
+ v8::PersistentContainerValue oldValue = Get(impl, key); |
dcarney
2014/03/07 09:38:24
this function seems inefficient - is there a way t
vogelheim
2014/03/07 18:01:34
Done.
|
+ impl->add(key, value); |
+ return oldValue; |
+ } |
+ |
+ static v8::PersistentContainerValue Get(const Impl* impl, KeyType* key) |
+ { |
+ return impl->get(key); |
+ } |
+ |
+ static v8::PersistentContainerValue Remove(Impl* impl, KeyType* key) |
+ { |
+ return impl->take(key); |
+ } |
+ |
+ // Dispose callbacks: |
+ static void DisposeByValue(v8::UniquePersistent<v8::Object> value, v8::Isolate* isolate) { } |
+ static void DisposeByKey(Impl* impl, KeyType* key) { } |
+ |
+ // WeakCallbackDataType, create/dispose, conversion, callback. |
+ static WeakCallbackDataType* WeakCallbackParameter(Impl* impl, KeyType* key, v8::Local<v8::Object>& value) |
+ { |
+ // ??? value is unused? |
+ return new WeakCallbackDataType(impl, key, value); |
dcarney
2014/03/07 09:38:24
just return 'this'
vogelheim
2014/03/07 18:01:34
Done.
(Actually impl, but hat's probably what you
|
+ } |
+ |
+ static void DisposeCallbackData(WeakCallbackDataType* callbackData) |
+ { |
+ delete callbackData; |
dcarney
2014/03/07 09:38:24
should be empty
vogelheim
2014/03/07 18:01:34
Done.
|
+ } |
+ |
+ static Impl* ImplFromWeakCallbackData( |
+ v8::WeakCallbackData<v8::Object, WeakCallbackDataType> data) |
+ { |
+ return data.GetParameter()->m_impl; |
+ } |
+ |
+ static KeyType* KeyFromWeakCallbackData( |
+ v8::WeakCallbackData<v8::Object, WeakCallbackDataType> data) |
+ { |
+ return data.GetParameter()->m_key; |
+ } |
+ }; |
v8::Isolate* m_isolate; |
- MapType m_map; |
+ v8::PersistentValueMap<KeyType*, v8::Object, PersistentValueMapTraits> m_map; |
}; |
-template<> |
-inline void DOMWrapperMap<void>::setWeakCallback(const v8::WeakCallbackData<v8::Object, DOMWrapperMap<void> >& data) |
+template <> |
+inline void DOMWrapperMap<void>::PersistentValueMapTraits::DisposeByValue( |
+ v8::UniquePersistent<v8::Object> value, |
+ v8::Isolate* isolate) |
+{ |
+ releaseObject(v8::Local<v8::Object>::New(isolate, value)); |
+} |
+ |
+template <> |
+inline void DOMWrapperMap<NPObject>::PersistentValueMapTraits::DisposeByKey( |
+ DOMWrapperMap<NPObject>::PersistentValueMapTraits::Impl* impl, |
+ NPObject* key) |
dcarney
2014/03/07 09:38:24
this needs to go to the file where it's currently
vogelheim
2014/03/07 18:01:34
Done.
For my understanding: Why? I thought it rat
|
{ |
- void* key = static_cast<void*>(toNative(data.GetValue())); |
- ASSERT(*data.GetParameter()->m_map.get(key).persistent() == data.GetValue()); |
- data.GetParameter()->removeAndDispose(key); |
- releaseObject(data.GetValue()); |
+ DOMWrapperMapDisposeHelper(key); |
} |
} // namespace WebCore |