| 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 |