Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/deps/v8/include/v8-util.h
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 3 // found in the LICENSE file. 4 5 #ifndef V8_UTIL_H_ 6 #define V8_UTIL_H_ 7 8 #include <assert.h> 9 10 #include <map> 11 #include <vector> 12 13 #include "v8-function-callback.h" // NOLINT(build/include_directory) 14 #include "v8-persistent-handle.h" // NOLINT(build/include_directory) 15 16 /** 17 * Support for Persistent containers. 18 * 19 * C++11 embedders can use STL containers with Global values, 20 * but pre-C++11 does not support the required move semantic and hence 21 * may want these container classes. 22 */ 23 namespace v8 { 24 25 template <typename K, typename V, typename Traits> 26 class GlobalValueMap; 27 28 typedef uintptr_t PersistentContainerValue; 29 static const uintptr_t kPersistentContainerNotFound = 0; 30 enum PersistentContainerCallbackType { 31 kNotWeak, 32 // These correspond to v8::WeakCallbackType 33 kWeakWithParameter, 34 kWeakWithInternalFields 35 }; 36 37 /** 38 * A default trait implementation for PersistentValueMap which uses std::map 39 * as a backing map. 40 * 41 * Users will have to implement their own weak callbacks & dispose traits. 42 */ 43 template<typename K, typename V> 44 class StdMapTraits { 45 public: 46 // STL map & related: 47 typedef std::map<K, PersistentContainerValue> Impl; 48 typedef typename Impl::iterator Iterator; 49 50 static bool Empty(Impl* impl) { return impl->empty(); } 51 static size_t Size(Impl* impl) { return impl->size(); } 52 static void Swap(Impl& a, Impl& b) { std::swap(a, b); } 53 static Iterator Begin(Impl* impl) { return impl->begin(); } 54 static Iterator End(Impl* impl) { return impl->end(); } 55 static K Key(Iterator it) { return it->first; } 56 static PersistentContainerValue Value(Iterator it) { return it->second; } 57 static PersistentContainerValue Set(Impl* impl, K key, 58 PersistentContainerValue value) { 59 std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value)); 60 PersistentContainerValue old_value = kPersistentContainerNotFound; 61 if (!res.second) { 62 old_value = res.first->second; 63 res.first->second = value; 64 } 65 return old_value; 66 } 67 static PersistentContainerValue Get(Impl* impl, K key) { 68 Iterator it = impl->find(key); 69 if (it == impl->end()) return kPersistentContainerNotFound; 70 return it->second; 71 } 72 static PersistentContainerValue Remove(Impl* impl, K key) { 73 Iterator it = impl->find(key); 74 if (it == impl->end()) return kPersistentContainerNotFound; 75 PersistentContainerValue value = it->second; 76 impl->erase(it); 77 return value; 78 } 79 }; 80 81 82 /** 83 * A default trait implementation for PersistentValueMap, which inherits 84 * a std:map backing map from StdMapTraits and holds non-weak persistent 85 * objects and has no special Dispose handling. 86 * 87 * You should not derive from this class, since MapType depends on the 88 * surrounding class, and hence a subclass cannot simply inherit the methods. 89 */ 90 template<typename K, typename V> 91 class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> { 92 public: 93 // Weak callback & friends: 94 static const PersistentContainerCallbackType kCallbackType = kNotWeak; 95 typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> > 96 MapType; 97 typedef void WeakCallbackDataType; 98 99 static WeakCallbackDataType* WeakCallbackParameter( 100 MapType* map, const K& key, Local<V> value) { 101 return nullptr; 102 } 103 static MapType* MapFromWeakCallbackInfo( 104 const WeakCallbackInfo<WeakCallbackDataType>& data) { 105 return nullptr; 106 } 107 static K KeyFromWeakCallbackInfo( 108 const WeakCallbackInfo<WeakCallbackDataType>& data) { 109 return K(); 110 } 111 static void DisposeCallbackData(WeakCallbackDataType* data) { } 112 static void Dispose(Isolate* isolate, Global<V> value, K key) {} 113 }; 114 115 116 template <typename K, typename V> 117 class DefaultGlobalMapTraits : public StdMapTraits<K, V> { 118 private: 119 template <typename T> 120 struct RemovePointer; 121 122 public: 123 // Weak callback & friends: 124 static const PersistentContainerCallbackType kCallbackType = kNotWeak; 125 typedef GlobalValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType; 126 typedef void WeakCallbackDataType; 127 128 static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key, 129 Local<V> value) { 130 return nullptr; 131 } 132 static MapType* MapFromWeakCallbackInfo( 133 const WeakCallbackInfo<WeakCallbackDataType>& data) { 134 return nullptr; 135 } 136 static K KeyFromWeakCallbackInfo( 137 const WeakCallbackInfo<WeakCallbackDataType>& data) { 138 return K(); 139 } 140 static void DisposeCallbackData(WeakCallbackDataType* data) {} 141 static void OnWeakCallback( 142 const WeakCallbackInfo<WeakCallbackDataType>& data) {} 143 static void Dispose(Isolate* isolate, Global<V> value, K key) {} 144 // This is a second pass callback, so SetSecondPassCallback cannot be called. 145 static void DisposeWeak(const WeakCallbackInfo<WeakCallbackDataType>& data) {} 146 147 private: 148 template <typename T> 149 struct RemovePointer<T*> { 150 typedef T Type; 151 }; 152 }; 153 154 155 /** 156 * A map wrapper that allows using Global as a mapped value. 157 * C++11 embedders don't need this class, as they can use Global 158 * directly in std containers. 159 * 160 * The map relies on a backing map, whose type and accessors are described 161 * by the Traits class. The backing map will handle values of type 162 * PersistentContainerValue, with all conversion into and out of V8 163 * handles being transparently handled by this class. 164 */ 165 template <typename K, typename V, typename Traits> 166 class PersistentValueMapBase { 167 public: 168 Isolate* GetIsolate() { return isolate_; } 169 170 /** 171 * Return size of the map. 172 */ 173 size_t Size() { return Traits::Size(&impl_); } 174 175 /** 176 * Return whether the map holds weak persistents. 177 */ 178 bool IsWeak() { return Traits::kCallbackType != kNotWeak; } 179 180 /** 181 * Get value stored in map. 182 */ 183 Local<V> Get(const K& key) { 184 V* p = FromVal(Traits::Get(&impl_, key)); 185 #ifdef V8_ENABLE_DIRECT_LOCAL 186 if (p == nullptr) return Local<V>(); 187 #endif 188 return Local<V>::New(isolate_, p); 189 } 190 191 /** 192 * Check whether a value is contained in the map. 193 */ 194 bool Contains(const K& key) { 195 return Traits::Get(&impl_, key) != kPersistentContainerNotFound; 196 } 197 198 /** 199 * Get value stored in map and set it in returnValue. 200 * Return true if a value was found. 201 */ 202 bool SetReturnValue(const K& key, 203 ReturnValue<Value> returnValue) { 204 return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key)); 205 } 206 207 /** 208 * Return value for key and remove it from the map. 209 */ 210 Global<V> Remove(const K& key) { 211 return Release(Traits::Remove(&impl_, key)).Pass(); 212 } 213 214 /** 215 * Traverses the map repeatedly, 216 * in case side effects of disposal cause insertions. 217 **/ 218 void Clear() { 219 typedef typename Traits::Iterator It; 220 HandleScope handle_scope(isolate_); 221 // TODO(dcarney): figure out if this swap and loop is necessary. 222 while (!Traits::Empty(&impl_)) { 223 typename Traits::Impl impl; 224 Traits::Swap(impl_, impl); 225 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) { 226 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), 227 Traits::Key(i)); 228 } 229 } 230 } 231 232 /** 233 * Helper class for GetReference/SetWithReference. Do not use outside 234 * that context. 235 */ 236 class PersistentValueReference { 237 public: 238 PersistentValueReference() : value_(kPersistentContainerNotFound) { } 239 PersistentValueReference(const PersistentValueReference& other) 240 : value_(other.value_) { } 241 242 Local<V> NewLocal(Isolate* isolate) const { 243 return Local<V>::New(isolate, 244 internal::ValueHelper::SlotAsValue<V>( 245 reinterpret_cast<internal::Address*>(value_))); 246 } 247 bool IsEmpty() const { 248 return value_ == kPersistentContainerNotFound; 249 } 250 template<typename T> 251 bool SetReturnValue(ReturnValue<T> returnValue) { 252 return SetReturnValueFromVal(&returnValue, value_); 253 } 254 void Reset() { 255 value_ = kPersistentContainerNotFound; 256 } 257 void operator=(const PersistentValueReference& other) { 258 value_ = other.value_; 259 } 260 261 private: 262 friend class PersistentValueMapBase; 263 friend class PersistentValueMap<K, V, Traits>; 264 friend class GlobalValueMap<K, V, Traits>; 265 266 explicit PersistentValueReference(PersistentContainerValue value) 267 : value_(value) { } 268 269 void operator=(PersistentContainerValue value) { 270 value_ = value; 271 } 272 273 PersistentContainerValue value_; 274 }; 275 276 /** 277 * Get a reference to a map value. This enables fast, repeated access 278 * to a value stored in the map while the map remains unchanged. 279 * 280 * Careful: This is potentially unsafe, so please use with care. 281 * The value will become invalid if the value for this key changes 282 * in the underlying map, as a result of Set or Remove for the same 283 * key; as a result of the weak callback for the same key; or as a 284 * result of calling Clear() or destruction of the map. 285 */ 286 PersistentValueReference GetReference(const K& key) { 287 return PersistentValueReference(Traits::Get(&impl_, key)); 288 } 289 290 protected: 291 explicit PersistentValueMapBase(Isolate* isolate) 292 : isolate_(isolate), label_(nullptr) {} 293 PersistentValueMapBase(Isolate* isolate, const char* label) 294 : isolate_(isolate), label_(label) {} 295 296 ~PersistentValueMapBase() { Clear(); } 297 298 Isolate* isolate() { return isolate_; } 299 typename Traits::Impl* impl() { return &impl_; } 300 301 static V* FromVal(PersistentContainerValue v) { 302 return internal::ValueHelper::SlotAsValue<V>( 303 reinterpret_cast<internal::Address*>(v)); 304 } 305 306 static PersistentContainerValue ClearAndLeak(Global<V>* persistent) { 307 internal::Address* address = persistent->slot(); 308 persistent->Clear(); 309 return reinterpret_cast<PersistentContainerValue>(address); 310 } 311 312 static PersistentContainerValue Leak(Global<V>* persistent) { 313 return reinterpret_cast<PersistentContainerValue>(persistent->slot()); 314 } 315 316 /** 317 * Return a container value as Global and make sure the weak 318 * callback is properly disposed of. All remove functionality should go 319 * through this. 320 */ 321 static Global<V> Release(PersistentContainerValue v) { 322 Global<V> p; 323 p.slot() = reinterpret_cast<internal::Address*>(v); 324 if (Traits::kCallbackType != kNotWeak && p.IsWeak()) { 325 Traits::DisposeCallbackData( 326 p.template ClearWeak<typename Traits::WeakCallbackDataType>()); 327 } 328 return p.Pass(); 329 } 330 331 void RemoveWeak(const K& key) { 332 Global<V> p; 333 p.slot() = 334 reinterpret_cast<internal::Address*>(Traits::Remove(&impl_, key)); 335 p.Reset(); 336 } 337 338 void AnnotateStrongRetainer(Global<V>* persistent) { 339 persistent->AnnotateStrongRetainer(label_); 340 } 341 342 private: 343 PersistentValueMapBase(PersistentValueMapBase&); 344 void operator=(PersistentValueMapBase&); 345 346 static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue, 347 PersistentContainerValue value) { 348 bool hasValue = value != kPersistentContainerNotFound; 349 if (hasValue) { 350 returnValue->SetInternal(*reinterpret_cast<internal::Address*>(value)); 351 } 352 return hasValue; 353 } 354 355 Isolate* isolate_; 356 typename Traits::Impl impl_; 357 const char* label_; 358 }; 359 360 template <typename K, typename V, typename Traits> 361 class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> { 362 public: 363 explicit PersistentValueMap(Isolate* isolate) 364 : PersistentValueMapBase<K, V, Traits>(isolate) {} 365 PersistentValueMap(Isolate* isolate, const char* label) 366 : PersistentValueMapBase<K, V, Traits>(isolate, label) {} 367 368 typedef 369 typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference 370 PersistentValueReference; 371 372 /** 373 * Put value into map. Depending on Traits::kIsWeak, the value will be held 374 * by the map strongly or weakly. 375 * Returns old value as Global. 376 */ 377 Global<V> Set(const K& key, Local<V> value) { 378 Global<V> persistent(this->isolate(), value); 379 return SetUnique(key, &persistent); 380 } 381 382 /** 383 * Put value into map, like Set(const K&, Local<V>). 384 */ 385 Global<V> Set(const K& key, Global<V> value) { 386 return SetUnique(key, &value); 387 } 388 389 /** 390 * Put the value into the map, and set the 'weak' callback when demanded 391 * by the Traits class. 392 */ 393 Global<V> SetUnique(const K& key, Global<V>* persistent) { 394 if (Traits::kCallbackType == kNotWeak) { 395 this->AnnotateStrongRetainer(persistent); 396 } else { 397 WeakCallbackType callback_type = 398 Traits::kCallbackType == kWeakWithInternalFields 399 ? WeakCallbackType::kInternalFields 400 : WeakCallbackType::kParameter; 401 auto value = Local<V>::New(this->isolate(), *persistent); 402 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( 403 Traits::WeakCallbackParameter(this, key, value), WeakCallback, 404 callback_type); 405 } 406 PersistentContainerValue old_value = 407 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); 408 return this->Release(old_value).Pass(); 409 } 410 411 /** 412 * Put a value into the map and update the reference. 413 * Restrictions of GetReference apply here as well. 414 */ 415 Global<V> Set(const K& key, Global<V> value, 416 PersistentValueReference* reference) { 417 *reference = this->Leak(&value); 418 return SetUnique(key, &value); 419 } 420 421 private: 422 static void WeakCallback( 423 const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) { 424 if (Traits::kCallbackType != kNotWeak) { 425 PersistentValueMap<K, V, Traits>* persistentValueMap = 426 Traits::MapFromWeakCallbackInfo(data); 427 K key = Traits::KeyFromWeakCallbackInfo(data); 428 Traits::Dispose(data.GetIsolate(), 429 persistentValueMap->Remove(key).Pass(), key); 430 Traits::DisposeCallbackData(data.GetParameter()); 431 } 432 } 433 }; 434 435 436 template <typename K, typename V, typename Traits> 437 class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> { 438 public: 439 explicit GlobalValueMap(Isolate* isolate) 440 : PersistentValueMapBase<K, V, Traits>(isolate) {} 441 GlobalValueMap(Isolate* isolate, const char* label) 442 : PersistentValueMapBase<K, V, Traits>(isolate, label) {} 443 444 typedef 445 typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference 446 PersistentValueReference; 447 448 /** 449 * Put value into map. Depending on Traits::kIsWeak, the value will be held 450 * by the map strongly or weakly. 451 * Returns old value as Global. 452 */ 453 Global<V> Set(const K& key, Local<V> value) { 454 Global<V> persistent(this->isolate(), value); 455 return SetUnique(key, &persistent); 456 } 457 458 /** 459 * Put value into map, like Set(const K&, Local<V>). 460 */ 461 Global<V> Set(const K& key, Global<V> value) { 462 return SetUnique(key, &value); 463 } 464 465 /** 466 * Put the value into the map, and set the 'weak' callback when demanded 467 * by the Traits class. 468 */ 469 Global<V> SetUnique(const K& key, Global<V>* persistent) { 470 if (Traits::kCallbackType == kNotWeak) { 471 this->AnnotateStrongRetainer(persistent); 472 } else { 473 WeakCallbackType callback_type = 474 Traits::kCallbackType == kWeakWithInternalFields 475 ? WeakCallbackType::kInternalFields 476 : WeakCallbackType::kParameter; 477 auto value = Local<V>::New(this->isolate(), *persistent); 478 persistent->template SetWeak<typename Traits::WeakCallbackDataType>( 479 Traits::WeakCallbackParameter(this, key, value), OnWeakCallback, 480 callback_type); 481 } 482 PersistentContainerValue old_value = 483 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); 484 return this->Release(old_value).Pass(); 485 } 486 487 /** 488 * Put a value into the map and update the reference. 489 * Restrictions of GetReference apply here as well. 490 */ 491 Global<V> Set(const K& key, Global<V> value, 492 PersistentValueReference* reference) { 493 *reference = this->Leak(&value); 494 return SetUnique(key, &value); 495 } 496 497 private: 498 static void OnWeakCallback( 499 const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) { 500 if (Traits::kCallbackType != kNotWeak) { 501 auto map = Traits::MapFromWeakCallbackInfo(data); 502 K key = Traits::KeyFromWeakCallbackInfo(data); 503 map->RemoveWeak(key); 504 Traits::OnWeakCallback(data); 505 data.SetSecondPassCallback(SecondWeakCallback); 506 } 507 } 508 509 static void SecondWeakCallback( 510 const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) { 511 Traits::DisposeWeak(data); 512 } 513 }; 514 515 516 /** 517 * A map that uses Global as value and std::map as the backing 518 * implementation. Persistents are held non-weak. 519 * 520 * C++11 embedders don't need this class, as they can use 521 * Global directly in std containers. 522 */ 523 template<typename K, typename V, 524 typename Traits = DefaultPersistentValueMapTraits<K, V> > 525 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> { 526 public: 527 explicit StdPersistentValueMap(Isolate* isolate) 528 : PersistentValueMap<K, V, Traits>(isolate) {} 529 }; 530 531 532 /** 533 * A map that uses Global as value and std::map as the backing 534 * implementation. Globals are held non-weak. 535 * 536 * C++11 embedders don't need this class, as they can use 537 * Global directly in std containers. 538 */ 539 template <typename K, typename V, 540 typename Traits = DefaultGlobalMapTraits<K, V> > 541 class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> { 542 public: 543 explicit StdGlobalValueMap(Isolate* isolate) 544 : GlobalValueMap<K, V, Traits>(isolate) {} 545 }; 546 547 class DefaultPersistentValueVectorTraits { 548 public: 549 typedef std::vector<PersistentContainerValue> Impl; 550 551 static void Append(Impl* impl, PersistentContainerValue value) { 552 impl->push_back(value); 553 } 554 static bool IsEmpty(const Impl* impl) { 555 return impl->empty(); 556 } 557 static size_t Size(const Impl* impl) { 558 return impl->size(); 559 } 560 static PersistentContainerValue Get(const Impl* impl, size_t i) { 561 return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound; 562 } 563 static void ReserveCapacity(Impl* impl, size_t capacity) { 564 impl->reserve(capacity); 565 } 566 static void Clear(Impl* impl) { 567 impl->clear(); 568 } 569 }; 570 571 /** 572 * A vector wrapper that safely stores Global values. 573 * C++11 embedders don't need this class, as they can use Global 574 * directly in std containers. 575 * 576 * This class relies on a backing vector implementation, whose type and methods 577 * are described by the Traits class. The backing map will handle values of type 578 * PersistentContainerValue, with all conversion into and out of V8 579 * handles being transparently handled by this class. 580 */ 581 template <typename V, typename Traits = DefaultPersistentValueVectorTraits> 582 class V8_DEPRECATE_SOON("Use std::vector<Global<V>>.") PersistentValueVector { 583 public: 584 explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { } 585 586 ~PersistentValueVector() { 587 Clear(); 588 } 589 590 /** 591 * Append a value to the vector. 592 */ 593 void Append(Local<V> value) { 594 Global<V> persistent(isolate_, value); 595 Traits::Append(&impl_, ClearAndLeak(&persistent)); 596 } 597 598 /** 599 * Append a persistent's value to the vector. 600 */ 601 void Append(Global<V> persistent) { 602 Traits::Append(&impl_, ClearAndLeak(&persistent)); 603 } 604 605 /** 606 * Are there any values in the vector? 607 */ 608 bool IsEmpty() const { 609 return Traits::IsEmpty(&impl_); 610 } 611 612 /** 613 * How many elements are in the vector? 614 */ 615 size_t Size() const { 616 return Traits::Size(&impl_); 617 } 618 619 /** 620 * Retrieve the i-th value in the vector. 621 */ 622 Local<V> Get(size_t index) const { 623 return Local<V>::New(isolate_, internal::ValueHelper::SlotAsValue<V>( 624 Traits::Get(&impl_, index))); 625 } 626 627 /** 628 * Remove all elements from the vector. 629 */ 630 void Clear() { 631 size_t length = Traits::Size(&impl_); 632 for (size_t i = 0; i < length; i++) { 633 Global<V> p; 634 p.slot() = reinterpret_cast<internal::Address>(Traits::Get(&impl_, i)); 635 } 636 Traits::Clear(&impl_); 637 } 638 639 /** 640 * Reserve capacity in the vector. 641 * (Efficiency gains depend on the backing implementation.) 642 */ 643 void ReserveCapacity(size_t capacity) { 644 Traits::ReserveCapacity(&impl_, capacity); 645 } 646 647 private: 648 static PersistentContainerValue ClearAndLeak(Global<V>* persistent) { 649 auto slot = persistent->slot(); 650 persistent->Clear(); 651 return reinterpret_cast<PersistentContainerValue>(slot); 652 } 653 654 static V* FromVal(PersistentContainerValue v) { 655 return internal::ValueHelper::SlotAsValue<V>( 656 reinterpret_cast<internal::Address*>(v)); 657 } 658 659 Isolate* isolate_; 660 typename Traits::Impl impl_; 661 }; 662 663 } // namespace v8 664 665 #endif // V8_UTIL_H