Chromium Code Reviews

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

Issue 201643003: First attempt at providing default traits for PersistentValueMap. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add StdPersistentValueMap; minor formatting + style fixes. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | 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 25 matching lines...)
36 * C++11 embedders can use STL containers with UniquePersistent values, 36 * C++11 embedders can use STL containers with UniquePersistent values,
37 * 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
38 * may want these container classes. 38 * may want these container classes.
39 */ 39 */
40 namespace v8 { 40 namespace v8 {
41 41
42 typedef uintptr_t PersistentContainerValue; 42 typedef uintptr_t PersistentContainerValue;
43 static const uintptr_t kPersistentContainerNotFound = 0; 43 static const uintptr_t kPersistentContainerNotFound = 0;
44 44
45 /** 45 /**
46 * A default trait implemenation for PersistentValueMap, which uses std::map
47 * as a backing map and is not weak.
48 */
49 template<typename K, typename V>
50 class DefaultPersistentValueMapTraits {
51 public:
52 // STL map & related:
53 typedef std::map<K, v8::PersistentContainerValue> Impl;
54 typedef typename Impl::iterator Iterator;
55
56 static bool Empty(Impl* impl) { return impl->empty(); }
57 static size_t Size(Impl* impl) { return impl->size(); }
58 static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
59 static Iterator Begin(Impl* impl) { return impl->begin(); }
60 static Iterator End(Impl* impl) { return impl->end(); }
61 static K Key(Iterator it) { return it->first; }
62 static v8::PersistentContainerValue Value(Iterator it) { return it->second; }
63 static v8::PersistentContainerValue Set(Impl* impl, K key,
64 v8::PersistentContainerValue value) {
65 std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
66 v8::PersistentContainerValue old_value = v8::kPersistentContainerNotFound;
67 if (!res.second) {
68 old_value = res.first->second;
69 res.first->second = value;
70 }
71 return old_value;
72 }
73 static v8::PersistentContainerValue Get(Impl* impl, K key) {
74 Iterator it = impl->find(key);
75 if (it == impl->end()) return v8::kPersistentContainerNotFound;
76 return it->second;
77 }
78 static v8::PersistentContainerValue Remove(Impl* impl, K key) {
79 Iterator it = impl->find(key);
80 if (it == impl->end()) return v8::kPersistentContainerNotFound;
81 v8::PersistentContainerValue value = it->second;
82 impl->erase(it);
83 return value;
84 }
85
86 // Dispose:
87 static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<V> value,
dcarney 2014/03/18 12:13:19 still have the problem that these are overridden i
vogelheim 2014/03/18 12:55:13 Done. Now: - StdMapTraits: std::map as backing im
88 Impl* impl, K key) {}
89
90 // Weak callback & friends:
91 static const bool kIsWeak = false;
92 typedef void WeakCallbackDataType;
93 static WeakCallbackDataType* WeakCallbackParameter(
94 Impl* impl, const K& key, Local<V> value);
95 static Impl* ImplFromWeakCallbackData(
96 const v8::WeakCallbackData<V, WeakCallbackDataType>& data);
97 static K KeyFromWeakCallbackData(
98 const v8::WeakCallbackData<V, WeakCallbackDataType>& data);
99 static void DisposeCallbackData(WeakCallbackDataType* data);
100 };
101
102 /**
dcarney 2014/03/18 12:13:19 2 lines between definitions.
vogelheim 2014/03/18 12:55:13 Done.
46 * A map wrapper that allows using UniquePersistent as a mapped value. 103 * A map wrapper that allows using UniquePersistent as a mapped value.
47 * C++11 embedders don't need this class, as they can use UniquePersistent 104 * C++11 embedders don't need this class, as they can use UniquePersistent
48 * directly in std containers. 105 * directly in std containers.
49 * 106 *
50 * The map relies on a backing map, whose type and accessors are described 107 * The map relies on a backing map, whose type and accessors are described
51 * by the Traits class. The backing map will handle values of type 108 * by the Traits class. The backing map will handle values of type
52 * PersistentContainerValue, with all conversion into and out of V8 109 * PersistentContainerValue, with all conversion into and out of V8
53 * handles being transparently handled by this class. 110 * handles being transparently handled by this class.
54 */ 111 */
55 template<class K, class V, class Traits> 112 template<typename K, typename V, typename Traits>
56 class PersistentValueMap { 113 class PersistentValueMap {
57 public: 114 public:
58 V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {} 115 V8_INLINE explicit PersistentValueMap(Isolate* isolate) : isolate_(isolate) {}
59 116
60 V8_INLINE ~PersistentValueMap() { Clear(); } 117 V8_INLINE ~PersistentValueMap() { Clear(); }
61 118
62 V8_INLINE Isolate* GetIsolate() { return isolate_; } 119 V8_INLINE Isolate* GetIsolate() { return isolate_; }
63 120
64 /** 121 /**
65 * Return size of the map. 122 * Return size of the map.
66 */ 123 */
67 V8_INLINE size_t Size() { return Traits::Size(&impl_); } 124 V8_INLINE size_t Size() { return Traits::Size(&impl_); }
68 125
69 /** 126 /**
127 * Return whether the map holds weak persistents.
128 */
129 V8_INLINE bool IsWeak() { return Traits::kIsWeak; }
130
131 /**
70 * Get value stored in map. 132 * Get value stored in map.
71 */ 133 */
72 V8_INLINE Local<V> Get(const K& key) { 134 V8_INLINE Local<V> Get(const K& key) {
73 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key))); 135 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
74 } 136 }
75 137
76 /** 138 /**
77 * Check whether a value is contained in the map. 139 * Check whether a value is contained in the map.
78 */ 140 */
79 V8_INLINE bool Contains(const K& key) { 141 V8_INLINE bool Contains(const K& key) {
80 return Traits::Get(&impl_, key) != 0; 142 return Traits::Get(&impl_, key) != 0;
81 } 143 }
82 144
83 /** 145 /**
84 * Get value stored in map and set it in returnValue. 146 * Get value stored in map and set it in returnValue.
85 * Return true if a value was found. 147 * Return true if a value was found.
86 */ 148 */
87 V8_INLINE bool SetReturnValue(const K& key, 149 V8_INLINE bool SetReturnValue(const K& key,
88 ReturnValue<Value>& returnValue); 150 ReturnValue<Value>& returnValue) {
151 PersistentContainerValue value = Traits::Get(&impl_, key);
152 bool hasValue = value != 0;
153 if (hasValue) {
154 returnValue.SetInternal(
155 *reinterpret_cast<internal::Object**>(FromVal(value)));
156 }
157 return hasValue;
158 }
89 159
90 /** 160 /**
91 * Call Isolate::SetReference with the given parent and the map value. 161 * Call Isolate::SetReference with the given parent and the map value.
92 */ 162 */
93 V8_INLINE void SetReference(const K& key, 163 V8_INLINE void SetReference(const K& key,
94 const v8::Persistent<v8::Object>& parent) { 164 const v8::Persistent<v8::Object>& parent) {
95 GetIsolate()->SetReference( 165 GetIsolate()->SetReference(
96 reinterpret_cast<internal::Object**>(parent.val_), 166 reinterpret_cast<internal::Object**>(parent.val_),
97 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key)))); 167 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
98 } 168 }
(...skipping 19 matching lines...)
118 * Return value for key and remove it from the map. 188 * Return value for key and remove it from the map.
119 */ 189 */
120 V8_INLINE UniquePersistent<V> Remove(const K& key) { 190 V8_INLINE UniquePersistent<V> Remove(const K& key) {
121 return Release(Traits::Remove(&impl_, key)).Pass(); 191 return Release(Traits::Remove(&impl_, key)).Pass();
122 } 192 }
123 193
124 /** 194 /**
125 * Traverses the map repeatedly, 195 * Traverses the map repeatedly,
126 * in case side effects of disposal cause insertions. 196 * in case side effects of disposal cause insertions.
127 **/ 197 **/
128 void Clear(); 198 void Clear() {
199 typedef typename Traits::Iterator It;
200 HandleScope handle_scope(isolate_);
201 // TODO(dcarney): figure out if this swap and loop is necessary.
202 while (!Traits::Empty(&impl_)) {
203 typename Traits::Impl impl;
204 Traits::Swap(impl_, impl);
205 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
206 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl,
207 Traits::Key(i));
208 }
209 }
210 }
129 211
130 private: 212 private:
131 PersistentValueMap(PersistentValueMap&); 213 PersistentValueMap(PersistentValueMap&);
132 void operator=(PersistentValueMap&); 214 void operator=(PersistentValueMap&);
133 215
134 /** 216 /**
135 * Put the value into the map, and set the 'weak' callback when demanded 217 * Put the value into the map, and set the 'weak' callback when demanded
136 * by the Traits class. 218 * by the Traits class.
137 */ 219 */
138 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) { 220 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
139 if (Traits::kIsWeak) { 221 if (Traits::kIsWeak) {
140 Local<V> value(Local<V>::New(isolate_, *persistent)); 222 Local<V> value(Local<V>::New(isolate_, *persistent));
141 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( 223 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
142 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback); 224 Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback);
143 } 225 }
144 PersistentContainerValue old_value = 226 PersistentContainerValue old_value =
145 Traits::Set(&impl_, key, ClearAndLeak(persistent)); 227 Traits::Set(&impl_, key, ClearAndLeak(persistent));
146 return Release(old_value).Pass(); 228 return Release(old_value).Pass();
147 } 229 }
148 230
149 static void WeakCallback( 231 static void WeakCallback(
150 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data); 232 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
233 typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data);
234 K key = Traits::KeyFromWeakCallbackData(data);
235 PersistentContainerValue value = Traits::Remove(impl, key);
236 Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key);
237 }
238
151 V8_INLINE static V* FromVal(PersistentContainerValue v) { 239 V8_INLINE static V* FromVal(PersistentContainerValue v) {
152 return reinterpret_cast<V*>(v); 240 return reinterpret_cast<V*>(v);
153 } 241 }
242
154 V8_INLINE static PersistentContainerValue ClearAndLeak( 243 V8_INLINE static PersistentContainerValue ClearAndLeak(
155 UniquePersistent<V>* persistent) { 244 UniquePersistent<V>* persistent) {
156 V* v = persistent->val_; 245 V* v = persistent->val_;
157 persistent->val_ = 0; 246 persistent->val_ = 0;
158 return reinterpret_cast<PersistentContainerValue>(v); 247 return reinterpret_cast<PersistentContainerValue>(v);
159 } 248 }
160 249
161 /** 250 /**
162 * Return a container value as UniquePersistent and make sure the weak 251 * Return a container value as UniquePersistent and make sure the weak
163 * callback is properly disposed of. All remove functionality should go 252 * callback is properly disposed of. All remove functionality should go
164 * through this. 253 * through this.
165 */ 254 */
166 V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) { 255 V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) {
167 UniquePersistent<V> p; 256 UniquePersistent<V> p;
168 p.val_ = FromVal(v); 257 p.val_ = FromVal(v);
169 if (Traits::kIsWeak && !p.IsEmpty()) { 258 if (Traits::kIsWeak && !p.IsEmpty()) {
170 Traits::DisposeCallbackData( 259 Traits::DisposeCallbackData(
171 p.template ClearWeak<typename Traits::WeakCallbackDataType>()); 260 p.template ClearWeak<typename Traits::WeakCallbackDataType>());
172 } 261 }
173 return p.Pass(); 262 return p.Pass();
174 } 263 }
175 264
176 Isolate* isolate_; 265 Isolate* isolate_;
177 typename Traits::Impl impl_; 266 typename Traits::Impl impl_;
178 }; 267 };
179 268
180 template <class K, class V, class Traits> 269 /**
dcarney 2014/03/18 12:13:19 again
vogelheim 2014/03/18 12:55:13 Done.
181 bool PersistentValueMap<K, V, Traits>::SetReturnValue(const K& key, 270 * A map that uses UniquePersistent as value and std::map as the backing
182 ReturnValue<Value>& returnValue) { 271 * implementation. C++11 embedders don't need this class, as they can use
183 PersistentContainerValue value = Traits::Get(&impl_, key); 272 * UniquePersistent directly in std containers.
184 bool hasValue = value != 0; 273 */
185 if (hasValue) { 274 template<typename K, typename V,
186 returnValue.SetInternal( 275 typename Traits = DefaultPersistentValueMapTraits<K, V> >
187 *reinterpret_cast<internal::Object**>(FromVal(value))); 276 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
188 } 277 public:
189 return hasValue; 278 explicit StdPersistentValueMap(v8::Isolate* isolate)
190 } 279 : PersistentValueMap<K, V, Traits>(isolate) {}
191 280 };
192 template <class K, class V, class Traits>
193 void PersistentValueMap<K, V, Traits>::Clear() {
194 typedef typename Traits::Iterator It;
195 HandleScope handle_scope(isolate_);
196 // TODO(dcarney): figure out if this swap and loop is necessary.
197 while (!Traits::Empty(&impl_)) {
198 typename Traits::Impl impl;
199 Traits::Swap(impl_, impl);
200 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
201 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl,
202 Traits::Key(i));
203 }
204 }
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 }
216 281
217 } // namespace v8 282 } // namespace v8
218 283
219 #endif // V8_UTIL_H_ 284 #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