OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_UTIL_H_ | 5 #ifndef V8_UTIL_H_ |
6 #define V8_UTIL_H_ | 6 #define V8_UTIL_H_ |
7 | 7 |
8 #include "v8.h" | 8 #include "v8.h" |
9 #include <map> | 9 #include <map> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 /** | 12 /** |
13 * Support for Persistent containers. | 13 * Support for Persistent containers. |
14 * | 14 * |
15 * C++11 embedders can use STL containers with UniquePersistent values, | 15 * C++11 embedders can use STL containers with Global values, |
16 * but pre-C++11 does not support the required move semantic and hence | 16 * but pre-C++11 does not support the required move semantic and hence |
17 * may want these container classes. | 17 * may want these container classes. |
18 */ | 18 */ |
19 namespace v8 { | 19 namespace v8 { |
20 | 20 |
21 typedef uintptr_t PersistentContainerValue; | 21 typedef uintptr_t PersistentContainerValue; |
22 static const uintptr_t kPersistentContainerNotFound = 0; | 22 static const uintptr_t kPersistentContainerNotFound = 0; |
23 enum PersistentContainerCallbackType { | 23 enum PersistentContainerCallbackType { |
24 kNotWeak, | 24 kNotWeak, |
25 kWeak | 25 // These correspond to v8::WeakCallbackType |
| 26 kWeakWithParameter, |
| 27 kWeakWithInternalFields, |
| 28 kWeak = kWeakWithParameter // For backwards compatibility. Deprecate. |
26 }; | 29 }; |
27 | 30 |
28 | 31 |
29 /** | 32 /** |
30 * A default trait implemenation for PersistentValueMap which uses std::map | 33 * A default trait implemenation for PersistentValueMap which uses std::map |
31 * as a backing map. | 34 * as a backing map. |
32 * | 35 * |
33 * Users will have to implement their own weak callbacks & dispose traits. | 36 * Users will have to implement their own weak callbacks & dispose traits. |
34 */ | 37 */ |
35 template<typename K, typename V> | 38 template<typename K, typename V> |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 } | 97 } |
95 static MapType* MapFromWeakCallbackData( | 98 static MapType* MapFromWeakCallbackData( |
96 const WeakCallbackData<V, WeakCallbackDataType>& data) { | 99 const WeakCallbackData<V, WeakCallbackDataType>& data) { |
97 return NULL; | 100 return NULL; |
98 } | 101 } |
99 static K KeyFromWeakCallbackData( | 102 static K KeyFromWeakCallbackData( |
100 const WeakCallbackData<V, WeakCallbackDataType>& data) { | 103 const WeakCallbackData<V, WeakCallbackDataType>& data) { |
101 return K(); | 104 return K(); |
102 } | 105 } |
103 static void DisposeCallbackData(WeakCallbackDataType* data) { } | 106 static void DisposeCallbackData(WeakCallbackDataType* data) { } |
104 static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { } | 107 static void Dispose(Isolate* isolate, Global<V> value, K key) {} |
105 }; | 108 }; |
106 | 109 |
107 | 110 |
108 template <typename K, typename V> | 111 template <typename K, typename V> |
109 class DefaultPhantomPersistentValueMapTraits : public StdMapTraits<K, V> { | 112 class DefaultGlobalMapTraits : public StdMapTraits<K, V> { |
110 private: | 113 private: |
111 template <typename T> | 114 template <typename T> |
112 struct RemovePointer; | 115 struct RemovePointer; |
113 | 116 |
114 public: | 117 public: |
115 // Weak callback & friends: | 118 // Weak callback & friends: |
116 static const PersistentContainerCallbackType kCallbackType = kNotWeak; | 119 static const PersistentContainerCallbackType kCallbackType = kNotWeak; |
117 typedef PersistentValueMap< | 120 typedef PersistentValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType; |
118 K, V, DefaultPhantomPersistentValueMapTraits<K, V> > MapType; | 121 typedef void WeakCallbackInfoType; |
119 typedef void PhantomCallbackDataType; | |
120 | 122 |
121 static PhantomCallbackDataType* PhantomCallbackParameter(MapType* map, | 123 static WeakCallbackInfoType* WeakCallbackParameter(MapType* map, const K& key, |
122 const K& key, | 124 Local<V> value) { |
123 Local<V> value) { | 125 return nullptr; |
124 return NULL; | |
125 } | 126 } |
126 static MapType* MapFromPhantomCallbackData( | 127 static MapType* MapFromWeakCallbackInfo( |
127 const PhantomCallbackData<PhantomCallbackDataType>& data) { | 128 const WeakCallbackInfo<WeakCallbackInfoType>& data) { |
128 return NULL; | 129 return nullptr; |
129 } | 130 } |
130 static K KeyFromPhantomCallbackData( | 131 static K KeyFromWeakCallbackInfo( |
131 const PhantomCallbackData<PhantomCallbackDataType>& data) { | 132 const WeakCallbackInfo<WeakCallbackInfoType>& data) { |
132 return K(); | 133 return K(); |
133 } | 134 } |
134 static void DisposeCallbackData(PhantomCallbackDataType* data) {} | 135 static void DisposeCallbackData(WeakCallbackInfoType* data) {} |
135 static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) {} | 136 static void Dispose(Isolate* isolate, Global<V> value, K key) {} |
136 | 137 |
137 private: | 138 private: |
138 template <typename T> | 139 template <typename T> |
139 struct RemovePointer<T*> { | 140 struct RemovePointer<T*> { |
140 typedef T Type; | 141 typedef T Type; |
141 }; | 142 }; |
142 }; | 143 }; |
143 | 144 |
144 | 145 |
145 /** | 146 /** |
146 * A map wrapper that allows using UniquePersistent as a mapped value. | 147 * A map wrapper that allows using Global as a mapped value. |
147 * C++11 embedders don't need this class, as they can use UniquePersistent | 148 * C++11 embedders don't need this class, as they can use Global |
148 * directly in std containers. | 149 * directly in std containers. |
149 * | 150 * |
150 * The map relies on a backing map, whose type and accessors are described | 151 * The map relies on a backing map, whose type and accessors are described |
151 * by the Traits class. The backing map will handle values of type | 152 * by the Traits class. The backing map will handle values of type |
152 * PersistentContainerValue, with all conversion into and out of V8 | 153 * PersistentContainerValue, with all conversion into and out of V8 |
153 * handles being transparently handled by this class. | 154 * handles being transparently handled by this class. |
154 */ | 155 */ |
155 template <typename K, typename V, typename Traits> | 156 template <typename K, typename V, typename Traits> |
156 class PersistentValueMapBase { | 157 class PersistentValueMapBase { |
157 public: | 158 public: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 void SetReference(const K& key, | 197 void SetReference(const K& key, |
197 const Persistent<Object>& parent) { | 198 const Persistent<Object>& parent) { |
198 GetIsolate()->SetReference( | 199 GetIsolate()->SetReference( |
199 reinterpret_cast<internal::Object**>(parent.val_), | 200 reinterpret_cast<internal::Object**>(parent.val_), |
200 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key)))); | 201 reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key)))); |
201 } | 202 } |
202 | 203 |
203 /** | 204 /** |
204 * Return value for key and remove it from the map. | 205 * Return value for key and remove it from the map. |
205 */ | 206 */ |
206 UniquePersistent<V> Remove(const K& key) { | 207 Global<V> Remove(const K& key) { |
207 return Release(Traits::Remove(&impl_, key)).Pass(); | 208 return Release(Traits::Remove(&impl_, key)).Pass(); |
208 } | 209 } |
209 | 210 |
210 /** | 211 /** |
211 * Traverses the map repeatedly, | 212 * Traverses the map repeatedly, |
212 * in case side effects of disposal cause insertions. | 213 * in case side effects of disposal cause insertions. |
213 **/ | 214 **/ |
214 void Clear() { | 215 void Clear() { |
215 typedef typename Traits::Iterator It; | 216 typedef typename Traits::Iterator It; |
216 HandleScope handle_scope(isolate_); | 217 HandleScope handle_scope(isolate_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 void Reset() { | 249 void Reset() { |
249 value_ = kPersistentContainerNotFound; | 250 value_ = kPersistentContainerNotFound; |
250 } | 251 } |
251 void operator=(const PersistentValueReference& other) { | 252 void operator=(const PersistentValueReference& other) { |
252 value_ = other.value_; | 253 value_ = other.value_; |
253 } | 254 } |
254 | 255 |
255 private: | 256 private: |
256 friend class PersistentValueMapBase; | 257 friend class PersistentValueMapBase; |
257 friend class PersistentValueMap<K, V, Traits>; | 258 friend class PersistentValueMap<K, V, Traits>; |
258 friend class PhantomPersistentValueMap<K, V, Traits>; | 259 friend class GlobalValueMap<K, V, Traits>; |
259 | 260 |
260 explicit PersistentValueReference(PersistentContainerValue value) | 261 explicit PersistentValueReference(PersistentContainerValue value) |
261 : value_(value) { } | 262 : value_(value) { } |
262 | 263 |
263 void operator=(PersistentContainerValue value) { | 264 void operator=(PersistentContainerValue value) { |
264 value_ = value; | 265 value_ = value; |
265 } | 266 } |
266 | 267 |
267 PersistentContainerValue value_; | 268 PersistentContainerValue value_; |
268 }; | 269 }; |
(...skipping 17 matching lines...) Expand all Loading... |
286 | 287 |
287 ~PersistentValueMapBase() { Clear(); } | 288 ~PersistentValueMapBase() { Clear(); } |
288 | 289 |
289 Isolate* isolate() { return isolate_; } | 290 Isolate* isolate() { return isolate_; } |
290 typename Traits::Impl* impl() { return &impl_; } | 291 typename Traits::Impl* impl() { return &impl_; } |
291 | 292 |
292 static V* FromVal(PersistentContainerValue v) { | 293 static V* FromVal(PersistentContainerValue v) { |
293 return reinterpret_cast<V*>(v); | 294 return reinterpret_cast<V*>(v); |
294 } | 295 } |
295 | 296 |
296 static PersistentContainerValue ClearAndLeak( | 297 static PersistentContainerValue ClearAndLeak(Global<V>* persistent) { |
297 UniquePersistent<V>* persistent) { | |
298 V* v = persistent->val_; | 298 V* v = persistent->val_; |
299 persistent->val_ = 0; | 299 persistent->val_ = 0; |
300 return reinterpret_cast<PersistentContainerValue>(v); | 300 return reinterpret_cast<PersistentContainerValue>(v); |
301 } | 301 } |
302 | 302 |
303 static PersistentContainerValue Leak(UniquePersistent<V>* persistent) { | 303 static PersistentContainerValue Leak(Global<V>* persistent) { |
304 return reinterpret_cast<PersistentContainerValue>(persistent->val_); | 304 return reinterpret_cast<PersistentContainerValue>(persistent->val_); |
305 } | 305 } |
306 | 306 |
307 /** | 307 /** |
308 * Return a container value as UniquePersistent and make sure the weak | 308 * Return a container value as Global and make sure the weak |
309 * callback is properly disposed of. All remove functionality should go | 309 * callback is properly disposed of. All remove functionality should go |
310 * through this. | 310 * through this. |
311 */ | 311 */ |
312 static UniquePersistent<V> Release(PersistentContainerValue v) { | 312 static Global<V> Release(PersistentContainerValue v) { |
313 UniquePersistent<V> p; | 313 Global<V> p; |
314 p.val_ = FromVal(v); | 314 p.val_ = FromVal(v); |
315 if (Traits::kCallbackType != kNotWeak && p.IsWeak()) { | 315 if (Traits::kCallbackType != kNotWeak && p.IsWeak()) { |
316 Traits::DisposeCallbackData( | 316 Traits::DisposeCallbackData( |
317 p.template ClearWeak<typename Traits::WeakCallbackDataType>()); | 317 p.template ClearWeak<typename Traits::WeakCallbackDataType>()); |
318 } | 318 } |
319 return p.Pass(); | 319 return p.Pass(); |
320 } | 320 } |
321 | 321 |
322 private: | 322 private: |
323 PersistentValueMapBase(PersistentValueMapBase&); | 323 PersistentValueMapBase(PersistentValueMapBase&); |
(...skipping 20 matching lines...) Expand all Loading... |
344 explicit PersistentValueMap(Isolate* isolate) | 344 explicit PersistentValueMap(Isolate* isolate) |
345 : PersistentValueMapBase<K, V, Traits>(isolate) {} | 345 : PersistentValueMapBase<K, V, Traits>(isolate) {} |
346 | 346 |
347 typedef | 347 typedef |
348 typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference | 348 typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference |
349 PersistentValueReference; | 349 PersistentValueReference; |
350 | 350 |
351 /** | 351 /** |
352 * Put value into map. Depending on Traits::kIsWeak, the value will be held | 352 * Put value into map. Depending on Traits::kIsWeak, the value will be held |
353 * by the map strongly or weakly. | 353 * by the map strongly or weakly. |
354 * Returns old value as UniquePersistent. | 354 * Returns old value as Global. |
355 */ | 355 */ |
356 UniquePersistent<V> Set(const K& key, Local<V> value) { | 356 Global<V> Set(const K& key, Local<V> value) { |
357 UniquePersistent<V> persistent(this->isolate(), value); | 357 Global<V> persistent(this->isolate(), value); |
358 return SetUnique(key, &persistent); | 358 return SetUnique(key, &persistent); |
359 } | 359 } |
360 | 360 |
361 /** | 361 /** |
362 * Put value into map, like Set(const K&, Local<V>). | 362 * Put value into map, like Set(const K&, Local<V>). |
363 */ | 363 */ |
364 UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) { | 364 Global<V> Set(const K& key, Global<V> value) { |
365 return SetUnique(key, &value); | 365 return SetUnique(key, &value); |
366 } | 366 } |
367 | 367 |
368 /** | 368 /** |
369 * Put the value into the map, and set the 'weak' callback when demanded | 369 * Put the value into the map, and set the 'weak' callback when demanded |
370 * by the Traits class. | 370 * by the Traits class. |
371 */ | 371 */ |
372 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) { | 372 Global<V> SetUnique(const K& key, Global<V>* persistent) { |
373 if (Traits::kCallbackType != kNotWeak) { | 373 if (Traits::kCallbackType != kNotWeak) { |
374 Local<V> value(Local<V>::New(this->isolate(), *persistent)); | 374 Local<V> value(Local<V>::New(this->isolate(), *persistent)); |
375 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( | 375 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( |
376 Traits::WeakCallbackParameter(this, key, value), WeakCallback); | 376 Traits::WeakCallbackParameter(this, key, value), WeakCallback); |
377 } | 377 } |
378 PersistentContainerValue old_value = | 378 PersistentContainerValue old_value = |
379 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); | 379 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); |
380 return this->Release(old_value).Pass(); | 380 return this->Release(old_value).Pass(); |
381 } | 381 } |
382 | 382 |
383 /** | 383 /** |
384 * Put a value into the map and update the reference. | 384 * Put a value into the map and update the reference. |
385 * Restrictions of GetReference apply here as well. | 385 * Restrictions of GetReference apply here as well. |
386 */ | 386 */ |
387 UniquePersistent<V> Set(const K& key, UniquePersistent<V> value, | 387 Global<V> Set(const K& key, Global<V> value, |
388 PersistentValueReference* reference) { | 388 PersistentValueReference* reference) { |
389 *reference = this->Leak(&value); | 389 *reference = this->Leak(&value); |
390 return SetUnique(key, &value); | 390 return SetUnique(key, &value); |
391 } | 391 } |
392 | 392 |
393 private: | 393 private: |
394 static void WeakCallback( | 394 static void WeakCallback( |
395 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { | 395 const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) { |
396 if (Traits::kCallbackType != kNotWeak) { | 396 if (Traits::kCallbackType != kNotWeak) { |
397 PersistentValueMap<K, V, Traits>* persistentValueMap = | 397 PersistentValueMap<K, V, Traits>* persistentValueMap = |
398 Traits::MapFromWeakCallbackData(data); | 398 Traits::MapFromWeakCallbackData(data); |
399 K key = Traits::KeyFromWeakCallbackData(data); | 399 K key = Traits::KeyFromWeakCallbackData(data); |
400 Traits::Dispose(data.GetIsolate(), | 400 Traits::Dispose(data.GetIsolate(), |
401 persistentValueMap->Remove(key).Pass(), key); | 401 persistentValueMap->Remove(key).Pass(), key); |
402 Traits::DisposeCallbackData(data.GetParameter()); | 402 Traits::DisposeCallbackData(data.GetParameter()); |
403 } | 403 } |
404 } | 404 } |
405 }; | 405 }; |
406 | 406 |
407 | 407 |
408 template <typename K, typename V, typename Traits> | 408 template <typename K, typename V, typename Traits> |
409 class PhantomPersistentValueMap : public PersistentValueMapBase<K, V, Traits> { | 409 class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> { |
410 public: | 410 public: |
411 explicit PhantomPersistentValueMap(Isolate* isolate) | 411 explicit GlobalValueMap(Isolate* isolate) |
412 : PersistentValueMapBase<K, V, Traits>(isolate) {} | 412 : PersistentValueMapBase<K, V, Traits>(isolate) {} |
413 | 413 |
414 typedef | 414 typedef |
415 typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference | 415 typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference |
416 PersistentValueReference; | 416 PersistentValueReference; |
417 | 417 |
418 /** | 418 /** |
419 * Put value into map. Depending on Traits::kIsWeak, the value will be held | 419 * Put value into map. Depending on Traits::kIsWeak, the value will be held |
420 * by the map strongly or weakly. | 420 * by the map strongly or weakly. |
421 * Returns old value as UniquePersistent. | 421 * Returns old value as Global. |
422 */ | 422 */ |
423 UniquePersistent<V> Set(const K& key, Local<V> value) { | 423 Global<V> Set(const K& key, Local<V> value) { |
424 UniquePersistent<V> persistent(this->isolate(), value); | 424 Global<V> persistent(this->isolate(), value); |
425 return SetUnique(key, &persistent); | 425 return SetUnique(key, &persistent); |
426 } | 426 } |
427 | 427 |
428 /** | 428 /** |
429 * Put value into map, like Set(const K&, Local<V>). | 429 * Put value into map, like Set(const K&, Local<V>). |
430 */ | 430 */ |
431 UniquePersistent<V> Set(const K& key, UniquePersistent<V> value) { | 431 Global<V> Set(const K& key, Global<V> value) { |
432 return SetUnique(key, &value); | 432 return SetUnique(key, &value); |
433 } | 433 } |
434 | 434 |
435 /** | 435 /** |
436 * Put the value into the map, and set the 'weak' callback when demanded | 436 * Put the value into the map, and set the 'weak' callback when demanded |
437 * by the Traits class. | 437 * by the Traits class. |
438 */ | 438 */ |
439 UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) { | 439 Global<V> SetUnique(const K& key, Global<V>* persistent) { |
440 if (Traits::kCallbackType != kNotWeak) { | 440 if (Traits::kCallbackType != kNotWeak) { |
| 441 WeakCallbackType callback_type = |
| 442 Traits::kCallbackType == kWeakWithInternalFields |
| 443 ? WeakCallbackType::kInternalFields |
| 444 : WeakCallbackType::kParameter; |
441 Local<V> value(Local<V>::New(this->isolate(), *persistent)); | 445 Local<V> value(Local<V>::New(this->isolate(), *persistent)); |
442 persistent->template SetPhantom<typename Traits::WeakCallbackDataType>( | 446 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( |
443 Traits::WeakCallbackParameter(this, key, value), WeakCallback, 0, 1); | 447 Traits::WeakCallbackParameter(this, key, value), WeakCallback, |
| 448 callback_type); |
444 } | 449 } |
445 PersistentContainerValue old_value = | 450 PersistentContainerValue old_value = |
446 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); | 451 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); |
447 return this->Release(old_value).Pass(); | 452 return this->Release(old_value).Pass(); |
448 } | 453 } |
449 | 454 |
450 /** | 455 /** |
451 * Put a value into the map and update the reference. | 456 * Put a value into the map and update the reference. |
452 * Restrictions of GetReference apply here as well. | 457 * Restrictions of GetReference apply here as well. |
453 */ | 458 */ |
454 UniquePersistent<V> Set(const K& key, UniquePersistent<V> value, | 459 Global<V> Set(const K& key, Global<V> value, |
455 PersistentValueReference* reference) { | 460 PersistentValueReference* reference) { |
456 *reference = this->Leak(&value); | 461 *reference = this->Leak(&value); |
457 return SetUnique(key, &value); | 462 return SetUnique(key, &value); |
458 } | 463 } |
459 | 464 |
460 private: | 465 private: |
461 static void WeakCallback( | 466 static void WeakCallback( |
462 const PhantomCallbackData<typename Traits::WeakCallbackDataType>& data) { | 467 const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) { |
463 if (Traits::kCallbackType != kNotWeak) { | 468 if (Traits::kCallbackType != kNotWeak) { |
464 PhantomPersistentValueMap<K, V, Traits>* persistentValueMap = | 469 GlobalValueMap<K, V, Traits>* persistentValueMap = |
465 Traits::MapFromPhantomCallbackData(data); | 470 Traits::MapFromWeakCallbackInfo(data); |
466 K key = Traits::KeyFromPhantomCallbackData(data); | 471 K key = Traits::KeyFromWeakCallbackInfo(data); |
467 Traits::Dispose(data.GetIsolate(), persistentValueMap->Remove(key).Pass(), | 472 Traits::Dispose(data.GetIsolate(), persistentValueMap->Remove(key).Pass(), |
468 key); | 473 key); |
469 Traits::DisposeCallbackData(data.GetParameter()); | 474 Traits::DisposeCallbackData(data.GetParameter()); |
470 } | 475 } |
471 } | 476 } |
472 }; | 477 }; |
473 | 478 |
474 | 479 |
475 /** | 480 /** |
476 * A map that uses UniquePersistent as value and std::map as the backing | 481 * A map that uses Global as value and std::map as the backing |
477 * implementation. Persistents are held non-weak. | 482 * implementation. Persistents are held non-weak. |
478 * | 483 * |
479 * C++11 embedders don't need this class, as they can use | 484 * C++11 embedders don't need this class, as they can use |
480 * UniquePersistent directly in std containers. | 485 * Global directly in std containers. |
481 */ | 486 */ |
482 template<typename K, typename V, | 487 template<typename K, typename V, |
483 typename Traits = DefaultPersistentValueMapTraits<K, V> > | 488 typename Traits = DefaultPersistentValueMapTraits<K, V> > |
484 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> { | 489 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> { |
485 public: | 490 public: |
486 explicit StdPersistentValueMap(Isolate* isolate) | 491 explicit StdPersistentValueMap(Isolate* isolate) |
487 : PersistentValueMap<K, V, Traits>(isolate) {} | 492 : PersistentValueMap<K, V, Traits>(isolate) {} |
488 }; | 493 }; |
489 | 494 |
490 | 495 |
(...skipping 16 matching lines...) Expand all Loading... |
507 static void ReserveCapacity(Impl* impl, size_t capacity) { | 512 static void ReserveCapacity(Impl* impl, size_t capacity) { |
508 impl->reserve(capacity); | 513 impl->reserve(capacity); |
509 } | 514 } |
510 static void Clear(Impl* impl) { | 515 static void Clear(Impl* impl) { |
511 impl->clear(); | 516 impl->clear(); |
512 } | 517 } |
513 }; | 518 }; |
514 | 519 |
515 | 520 |
516 /** | 521 /** |
517 * A vector wrapper that safely stores UniquePersistent values. | 522 * A vector wrapper that safely stores Global values. |
518 * C++11 embedders don't need this class, as they can use UniquePersistent | 523 * C++11 embedders don't need this class, as they can use Global |
519 * directly in std containers. | 524 * directly in std containers. |
520 * | 525 * |
521 * This class relies on a backing vector implementation, whose type and methods | 526 * This class relies on a backing vector implementation, whose type and methods |
522 * are described by the Traits class. The backing map will handle values of type | 527 * are described by the Traits class. The backing map will handle values of type |
523 * PersistentContainerValue, with all conversion into and out of V8 | 528 * PersistentContainerValue, with all conversion into and out of V8 |
524 * handles being transparently handled by this class. | 529 * handles being transparently handled by this class. |
525 */ | 530 */ |
526 template<typename V, typename Traits = DefaultPersistentValueVectorTraits> | 531 template<typename V, typename Traits = DefaultPersistentValueVectorTraits> |
527 class PersistentValueVector { | 532 class PersistentValueVector { |
528 public: | 533 public: |
529 explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { } | 534 explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { } |
530 | 535 |
531 ~PersistentValueVector() { | 536 ~PersistentValueVector() { |
532 Clear(); | 537 Clear(); |
533 } | 538 } |
534 | 539 |
535 /** | 540 /** |
536 * Append a value to the vector. | 541 * Append a value to the vector. |
537 */ | 542 */ |
538 void Append(Local<V> value) { | 543 void Append(Local<V> value) { |
539 UniquePersistent<V> persistent(isolate_, value); | 544 Global<V> persistent(isolate_, value); |
540 Traits::Append(&impl_, ClearAndLeak(&persistent)); | 545 Traits::Append(&impl_, ClearAndLeak(&persistent)); |
541 } | 546 } |
542 | 547 |
543 /** | 548 /** |
544 * Append a persistent's value to the vector. | 549 * Append a persistent's value to the vector. |
545 */ | 550 */ |
546 void Append(UniquePersistent<V> persistent) { | 551 void Append(Global<V> persistent) { |
547 Traits::Append(&impl_, ClearAndLeak(&persistent)); | 552 Traits::Append(&impl_, ClearAndLeak(&persistent)); |
548 } | 553 } |
549 | 554 |
550 /** | 555 /** |
551 * Are there any values in the vector? | 556 * Are there any values in the vector? |
552 */ | 557 */ |
553 bool IsEmpty() const { | 558 bool IsEmpty() const { |
554 return Traits::IsEmpty(&impl_); | 559 return Traits::IsEmpty(&impl_); |
555 } | 560 } |
556 | 561 |
(...skipping 10 matching lines...) Expand all Loading... |
567 Local<V> Get(size_t index) const { | 572 Local<V> Get(size_t index) const { |
568 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index))); | 573 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index))); |
569 } | 574 } |
570 | 575 |
571 /** | 576 /** |
572 * Remove all elements from the vector. | 577 * Remove all elements from the vector. |
573 */ | 578 */ |
574 void Clear() { | 579 void Clear() { |
575 size_t length = Traits::Size(&impl_); | 580 size_t length = Traits::Size(&impl_); |
576 for (size_t i = 0; i < length; i++) { | 581 for (size_t i = 0; i < length; i++) { |
577 UniquePersistent<V> p; | 582 Global<V> p; |
578 p.val_ = FromVal(Traits::Get(&impl_, i)); | 583 p.val_ = FromVal(Traits::Get(&impl_, i)); |
579 } | 584 } |
580 Traits::Clear(&impl_); | 585 Traits::Clear(&impl_); |
581 } | 586 } |
582 | 587 |
583 /** | 588 /** |
584 * Reserve capacity in the vector. | 589 * Reserve capacity in the vector. |
585 * (Efficiency gains depend on the backing implementation.) | 590 * (Efficiency gains depend on the backing implementation.) |
586 */ | 591 */ |
587 void ReserveCapacity(size_t capacity) { | 592 void ReserveCapacity(size_t capacity) { |
588 Traits::ReserveCapacity(&impl_, capacity); | 593 Traits::ReserveCapacity(&impl_, capacity); |
589 } | 594 } |
590 | 595 |
591 private: | 596 private: |
592 static PersistentContainerValue ClearAndLeak( | 597 static PersistentContainerValue ClearAndLeak(Global<V>* persistent) { |
593 UniquePersistent<V>* persistent) { | |
594 V* v = persistent->val_; | 598 V* v = persistent->val_; |
595 persistent->val_ = 0; | 599 persistent->val_ = 0; |
596 return reinterpret_cast<PersistentContainerValue>(v); | 600 return reinterpret_cast<PersistentContainerValue>(v); |
597 } | 601 } |
598 | 602 |
599 static V* FromVal(PersistentContainerValue v) { | 603 static V* FromVal(PersistentContainerValue v) { |
600 return reinterpret_cast<V*>(v); | 604 return reinterpret_cast<V*>(v); |
601 } | 605 } |
602 | 606 |
603 Isolate* isolate_; | 607 Isolate* isolate_; |
604 typename Traits::Impl impl_; | 608 typename Traits::Impl impl_; |
605 }; | 609 }; |
606 | 610 |
607 } // namespace v8 | 611 } // namespace v8 |
608 | 612 |
609 #endif // V8_UTIL_H_ | 613 #endif // V8_UTIL_H |
OLD | NEW |