1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef DOMWrapperMap_h 32 #define DOMWrapperMap_h 33 34 #include "bindings/v8/UnsafePersistent.h" 35 #include "bindings/v8/V8Utilities.h" 36 #include "bindings/v8/WrapperTypeInfo.h" 37 #include <v8.h> 38 #include "wtf/HashMap.h" 39 40 namespace WebCore { 41 42 template<class KeyType> 43 class DOMWrapperMap { 44 public: 45 typedef HashMap<KeyType*, UnsafePersistent<v8::Object> > MapType; 46 47 explicit DOMWrapperMap(v8::Isolate* isolate) 48 : m_isolate(isolate) 49 { 50 } 51 52 v8::Handle<v8::Object> get(KeyType* key) 53 { 54 return m_map.get(key).deprecatedHandle(); 55 } 56 57 v8::Handle<v8::Object> getNewLocal(v8::Isolate* isolate, KeyType* key) 58 { 59 return m_map.get(key).newLocal(isolate); 60 } 61 62 void set(KeyType* key, v8::Handle<v8::Object> wrapper, const WrapperConfiguration& configuration) 63 { 64 ASSERT(static_cast<KeyType*>(toNative(wrapper)) == key); 65 v8::Persistent<v8::Object> persistent(m_isolate, wrapper); 66 configuration.configureWrapper(&persistent, m_isolate); 67 persistent.MakeWeak(this, &makeWeakCallback); 68 typename MapType::AddResult result = m_map.add(key, UnsafePersistent<v8::Object>()); 69 ASSERT(result.isNewEntry); 70 // FIXME: Stop handling this case once duplicate wrappers are guaranteed not to be created. 71 if (!result.isNewEntry) 72 result.iterator->value.dispose(); 73 result.iterator->value = UnsafePersistent<v8::Object>(persistent); 74 } 75 76 void clear() 77 { 78 while (!m_map.isEmpty()) { 79 // Swap out m_map on each iteration to ensure any wrappers added due to side effects of the loop are cleared. 80 MapType map; 81 map.swap(m_map); 82 for (typename MapType::iterator it = map.begin(); it != map.end(); ++it) { 83 toWrapperTypeInfo(it->value.deprecatedHandle())->derefObject(it->key); 84 it->value.dispose(); 85 } 86 } 87 } 88 89 void removeAndDispose(KeyType* key) 90 { 91 typename MapType::iterator it = m_map.find(key); 92 ASSERT(it != m_map.end()); 93 it->value.dispose(); 94 m_map.remove(it); 95 } 96 97 private: 98 static void makeWeakCallback(v8::Isolate*, v8::Persistent<v8::Object>* wrapper, DOMWrapperMap<KeyType>*); 99 100 v8::Isolate* m_isolate; 101 MapType m_map; 102 }; 103 104 template<> 105 inline void DOMWrapperMap<void>::makeWeakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* wrapper, DOMWrapperMap<void>* map) 106 { 107 WrapperTypeInfo* type = toWrapperTypeInfo(*wrapper); 108 ASSERT(type->derefObjectFunction); 109 void* key = static_cast<void*>(toNative(*wrapper)); 110 ASSERT(map->get(key) == *wrapper); 111 map->removeAndDispose(key); 112 type->derefObject(key); 113 } 114 115 } // namespace WebCore 116 117 #endif // DOMWrapperMap_h 118