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

Side by Side Diff: include/v8-util.h

Issue 203553002: Revert "First attempt at providing default traits for PersistentValueMap." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_UTIL_H_ 28 #ifndef V8_UTIL_H_
29 #define V8_UTIL_H_ 29 #define V8_UTIL_H_
30 30
31 #include "v8.h" 31 #include "v8.h"
32 #include <map>
33 32
34 /** 33 /**
35 * Support for Persistent containers. 34 * Support for Persistent containers.
36 * 35 *
37 * C++11 embedders can use STL containers with UniquePersistent values, 36 * C++11 embedders can use STL containers with UniquePersistent values,
38 * but pre-C++11 does not support the required move semantic and hence 37 * but pre-C++11 does not support the required move semantic and hence
39 * may want these container classes. 38 * may want these container classes.
40 */ 39 */
41 namespace v8 { 40 namespace v8 {
42 41
43 typedef uintptr_t PersistentContainerValue; 42 typedef uintptr_t PersistentContainerValue;
44 static const uintptr_t kPersistentContainerNotFound = 0; 43 static const uintptr_t kPersistentContainerNotFound = 0;
45 44
46
47 /**
48 * A default trait implemenation for PersistentValueMap which uses std::map
49 * as a backing map.
50 *
51 * Users will have to implement their own weak callbacks & dispose traits.
52 */
53 template<typename K, typename V>
54 class StdMapTraits {
55 public:
56 // STL map & related:
57 typedef std::map<K, v8::PersistentContainerValue> Impl;
58 typedef typename Impl::iterator Iterator;
59
60 static bool Empty(Impl* impl) { return impl->empty(); }
61 static size_t Size(Impl* impl) { return impl->size(); }
62 static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
63 static Iterator Begin(Impl* impl) { return impl->begin(); }
64 static Iterator End(Impl* impl) { return impl->end(); }
65 static K Key(Iterator it) { return it->first; }
66 static v8::PersistentContainerValue Value(Iterator it) { return it->second; }
67 static v8::PersistentContainerValue Set(Impl* impl, K key,
68 v8::PersistentContainerValue value) {
69 std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
70 v8::PersistentContainerValue old_value = v8::kPersistentContainerNotFound;
71 if (!res.second) {
72 old_value = res.first->second;
73 res.first->second = value;
74 }
75 return old_value;
76 }
77 static v8::PersistentContainerValue Get(Impl* impl, K key) {
78 Iterator it = impl->find(key);
79 if (it == impl->end()) return v8::kPersistentContainerNotFound;
80 return it->second;
81 }
82 static v8::PersistentContainerValue Remove(Impl* impl, K key) {
83 Iterator it = impl->find(key);
84 if (it == impl->end()) return v8::kPersistentContainerNotFound;
85 v8::PersistentContainerValue value = it->second;
86 impl->erase(it);
87 return value;
88 }
89 };
90
91
92 /**
93 * A default trait implementation for PersistentValueMap, which inherits
94 * a std:map backing map from StdMapTraits and holds non-weak persistent
95 * objects.
96 *
97 * Users have to implement their own dispose trait.
98 */
99 template<typename K, typename V>
100 class StrongMapTraits : public StdMapTraits<K, V> {
101 public:
102 // Weak callback & friends:
103 static const bool kIsWeak = false;
104 typedef typename StdMapTraits<K, V>::Impl Impl;
105 typedef void WeakCallbackDataType;
106 static WeakCallbackDataType* WeakCallbackParameter(
107 Impl* impl, const K& key, Local<V> value);
108 static Impl* ImplFromWeakCallbackData(
109 const v8::WeakCallbackData<V, WeakCallbackDataType>& data);
110 static K KeyFromWeakCallbackData(
111 const v8::WeakCallbackData<V, WeakCallbackDataType>& data);
112 static void DisposeCallbackData(WeakCallbackDataType* data);
113 };
114
115
116 /**
117 * A default trait implementation for PersistentValueMap, with a std::map
118 * backing map, non-weak persistents as values, and no special dispose
119 * handling. Can be used as-is.
120 */
121 template<typename K, typename V>
122 class DefaultPersistentValueMapTraits : public StrongMapTraits<K, V> {
123 public:
124 typedef typename StrongMapTraits<K, V>::Impl Impl;
125 static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<V> value,
126 Impl* impl, K key) { }
127 };
128
129
130 /** 45 /**
131 * A map wrapper that allows using UniquePersistent as a mapped value. 46 * A map wrapper that allows using UniquePersistent as a mapped value.
132 * C++11 embedders don't need this class, as they can use UniquePersistent 47 * C++11 embedders don't need this class, as they can use UniquePersistent
133 * directly in std containers. 48 * directly in std containers.
134 * 49 *
135 * The map relies on a backing map, whose type and accessors are described 50 * The map relies on a backing map, whose type and accessors are described
136 * by the Traits class. The backing map will handle values of type 51 * by the Traits class. The backing map will handle values of type
137 * PersistentContainerValue, with all conversion into and out of V8 52 * PersistentContainerValue, with all conversion into and out of V8
138 * handles being transparently handled by this class. 53 * handles being transparently handled by this class.
139 */ 54 */
140 template<typename K, typename V, typename Traits> 55 template<class K, class V, class Traits>
141 class PersistentValueMap { 56 class PersistentValueMap {
142 public: 57 public:
143 V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {} 58 V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {}
144 59
145 V8_INLINE ~PersistentValueMap() { Clear(); } 60 V8_INLINE ~PersistentValueMap() { Clear(); }
146 61
147 V8_INLINE Isolate* GetIsolate() { return isolate_; } 62 V8_INLINE Isolate* GetIsolate() { return isolate_; }
148 63
149 /** 64 /**
150 * Return size of the map. 65 * Return size of the map.
151 */ 66 */
152 V8_INLINE size_t Size() { return Traits::Size(&impl_); } 67 V8_INLINE size_t Size() { return Traits::Size(&impl_); }
153 68
154 /** 69 /**
155 * Return whether the map holds weak persistents.
156 */
157 V8_INLINE bool IsWeak() { return Traits::kIsWeak; }
158
159 /**
160 * Get value stored in map. 70 * Get value stored in map.
161 */ 71 */
162 V8_INLINE Local<V> Get(const K& key) { 72 V8_INLINE Local<V> Get(const K& key) {
163 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key))); 73 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
164 } 74 }
165 75
166 /** 76 /**
167 * Check whether a value is contained in the map. 77 * Check whether a value is contained in the map.
168 */ 78 */
169 V8_INLINE bool Contains(const K& key) { 79 V8_INLINE bool Contains(const K& key) {
170 return Traits::Get(&impl_, key) != 0; 80 return Traits::Get(&impl_, key) != 0;
171 } 81 }
172 82
173 /** 83 /**
174 * Get value stored in map and set it in returnValue. 84 * Get value stored in map and set it in returnValue.
175 * Return true if a value was found. 85 * Return true if a value was found.
176 */ 86 */
177 V8_INLINE bool SetReturnValue(const K& key, 87 V8_INLINE bool SetReturnValue(const K& key,
178 ReturnValue<Value>& returnValue) { 88 ReturnValue<Value>& returnValue);
179 PersistentContainerValue value = Traits::Get(&impl_, key);
180 bool hasValue = value != 0;
181 if (hasValue) {
182 returnValue.SetInternal(
183 *reinterpret_cast<internal::Object**>(FromVal(value)));
184 }
185 return hasValue;
186 }
187 89
188 /** 90 /**
189 * Call Isolate::SetReference with the given parent and the map value. 91 * Call Isolate::SetReference with the given parent and the map value.
190 */ 92 */
191 V8_INLINE void SetReference(const K& key, 93 V8_INLINE void SetReference(const K& key,
192 const v8::Persistent<v8::Object>& parent) { 94 const v8::Persistent<v8::Object>& parent) {
193 GetIsolate()->SetReference( 95 GetIsolate()->SetReference(
194 reinterpret_cast<internal::Object**>(parent.val_), 96 reinterpret_cast<internal::Object**>(parent.val_),
195 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key)))); 97 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
196 } 98 }
(...skipping 19 matching lines...) Expand all
216 * Return value for key and remove it from the map. 118 * Return value for key and remove it from the map.
217 */ 119 */
218 V8_INLINE UniquePersistent<V> Remove(const K& key) { 120 V8_INLINE UniquePersistent<V> Remove(const K& key) {
219 return Release(Traits::Remove(&impl_, key)).Pass(); 121 return Release(Traits::Remove(&impl_, key)).Pass();
220 } 122 }
221 123
222 /** 124 /**
223 * Traverses the map repeatedly, 125 * Traverses the map repeatedly,
224 * in case side effects of disposal cause insertions. 126 * in case side effects of disposal cause insertions.
225 **/ 127 **/
226 void Clear() { 128 void Clear();
227 typedef typename Traits::Iterator It;
228 HandleScope handle_scope(isolate_);
229 // TODO(dcarney): figure out if this swap and loop is necessary.
230 while (!Traits::Empty(&impl_)) {
231 typename Traits::Impl impl;
232 Traits::Swap(impl_, impl);
233 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
234 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl,
235 Traits::Key(i));
236 }
237 }
238 }
239 129
240 private: 130 private:
241 PersistentValueMap(PersistentValueMap&); 131 PersistentValueMap(PersistentValueMap&);
242 void operator=(PersistentValueMap&); 132 void operator=(PersistentValueMap&);
243 133
244 /** 134 /**
245 * Put the value into the map, and set the 'weak' callback when demanded 135 * Put the value into the map, and set the 'weak' callback when demanded
246 * by the Traits class. 136 * by the Traits class.
247 */ 137 */
248 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) { 138 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
249 if (Traits::kIsWeak) { 139 if (Traits::kIsWeak) {
250 Local<V> value(Local<V>::New(isolate_, *persistent)); 140 Local<V> value(Local<V>::New(isolate_, *persistent));
251 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( 141 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
252 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback); 142 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback);
253 } 143 }
254 PersistentContainerValue old_value = 144 PersistentContainerValue old_value =
255 Traits::Set(&impl_, key, ClearAndLeak(persistent)); 145 Traits::Set(&impl_, key, ClearAndLeak(persistent));
256 return Release(old_value).Pass(); 146 return Release(old_value).Pass();
257 } 147 }
258 148
259 static void WeakCallback( 149 static void WeakCallback(
260 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { 150 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data);
261 if (Traits::kIsWeak) {
262 typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data);
263 K key = Traits::KeyFromWeakCallbackData(data);
264 PersistentContainerValue value = Traits::Remove(impl, key);
265 Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key);
266 }
267 }
268
269 V8_INLINE static V* FromVal(PersistentContainerValue v) { 151 V8_INLINE static V* FromVal(PersistentContainerValue v) {
270 return reinterpret_cast<V*>(v); 152 return reinterpret_cast<V*>(v);
271 } 153 }
272
273 V8_INLINE static PersistentContainerValue ClearAndLeak( 154 V8_INLINE static PersistentContainerValue ClearAndLeak(
274 UniquePersistent<V>* persistent) { 155 UniquePersistent<V>* persistent) {
275 V* v = persistent->val_; 156 V* v = persistent->val_;
276 persistent->val_ = 0; 157 persistent->val_ = 0;
277 return reinterpret_cast<PersistentContainerValue>(v); 158 return reinterpret_cast<PersistentContainerValue>(v);
278 } 159 }
279 160
280 /** 161 /**
281 * Return a container value as UniquePersistent and make sure the weak 162 * Return a container value as UniquePersistent and make sure the weak
282 * callback is properly disposed of. All remove functionality should go 163 * callback is properly disposed of. All remove functionality should go
283 * through this. 164 * through this.
284 */ 165 */
285 V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) { 166 V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) {
286 UniquePersistent<V> p; 167 UniquePersistent<V> p;
287 p.val_ = FromVal(v); 168 p.val_ = FromVal(v);
288 if (Traits::kIsWeak && !p.IsEmpty()) { 169 if (Traits::kIsWeak && !p.IsEmpty()) {
289 Traits::DisposeCallbackData( 170 Traits::DisposeCallbackData(
290 p.template ClearWeak<typename Traits::WeakCallbackDataType>()); 171 p.template ClearWeak<typename Traits::WeakCallbackDataType>());
291 } 172 }
292 return p.Pass(); 173 return p.Pass();
293 } 174 }
294 175
295 Isolate* isolate_; 176 Isolate* isolate_;
296 typename Traits::Impl impl_; 177 typename Traits::Impl impl_;
297 }; 178 };
298 179
180 template <class K, class V, class Traits>
181 bool PersistentValueMap<K, V, Traits>::SetReturnValue(const K& key,
182 ReturnValue<Value>& returnValue) {
183 PersistentContainerValue value = Traits::Get(&impl_, key);
184 bool hasValue = value != 0;
185 if (hasValue) {
186 returnValue.SetInternal(
187 *reinterpret_cast<internal::Object**>(FromVal(value)));
188 }
189 return hasValue;
190 }
299 191
300 /** 192 template <class K, class V, class Traits>
301 * A map that uses UniquePersistent as value and std::map as the backing 193 void PersistentValueMap<K, V, Traits>::Clear() {
302 * implementation. Persistents are held non-weak. 194 typedef typename Traits::Iterator It;
303 * 195 HandleScope handle_scope(isolate_);
304 * C++11 embedders don't need this class, as they can use 196 // TODO(dcarney): figure out if this swap and loop is necessary.
305 * UniquePersistent directly in std containers. 197 while (!Traits::Empty(&impl_)) {
306 */ 198 typename Traits::Impl impl;
307 template<typename K, typename V, 199 Traits::Swap(impl_, impl);
308 typename Traits = DefaultPersistentValueMapTraits<K, V> > 200 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
309 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> { 201 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl,
310 public: 202 Traits::Key(i));
311 explicit StdPersistentValueMap(v8::Isolate* isolate) 203 }
312 : PersistentValueMap<K, V, Traits>(isolate) {} 204 }
313 }; 205 }
206
207
208 template <class K, class V, class Traits>
209 void PersistentValueMap<K, V, Traits>::WeakCallback(
210 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
211 typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data);
212 K key = Traits::KeyFromWeakCallbackData(data);
213 PersistentContainerValue value = Traits::Remove(impl, key);
214 Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key);
215 }
314 216
315 } // namespace v8 217 } // namespace v8
316 218
317 #endif // V8_UTIL_H_ 219 #endif // V8_UTIL_H_
OLDNEW
« no previous file with comments | « no previous file | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698