Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/nodejs/deps/v8/include/v8-util.h
$ 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
9 10 #include
11 #include
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
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
44 class StdMapTraits { 45 public: 46 // STL map & related: 47 typedef std::map
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
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
91 class DefaultPersistentValueMapTraits : public StdMapTraits
{ 92 public: 93 // Weak callback & friends: 94 static const PersistentContainerCallbackType kCallbackType = kNotWeak; 95 typedef PersistentValueMap
> 96 MapType; 97 typedef void WeakCallbackDataType; 98 99 static WeakCallbackDataType* WeakCallbackParameter( 100 MapType* map, const K& key, Local
value) { 101 return nullptr; 102 } 103 static MapType* MapFromWeakCallbackInfo( 104 const WeakCallbackInfo
& data) { 105 return nullptr; 106 } 107 static K KeyFromWeakCallbackInfo( 108 const WeakCallbackInfo
& data) { 109 return K(); 110 } 111 static void DisposeCallbackData(WeakCallbackDataType* data) { } 112 static void Dispose(Isolate* isolate, Global
value, K key) {} 113 }; 114 115 116 template
117 class DefaultGlobalMapTraits : public StdMapTraits
{ 118 private: 119 template
120 struct RemovePointer; 121 122 public: 123 // Weak callback & friends: 124 static const PersistentContainerCallbackType kCallbackType = kNotWeak; 125 typedef GlobalValueMap
> MapType; 126 typedef void WeakCallbackDataType; 127 128 static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key, 129 Local
value) { 130 return nullptr; 131 } 132 static MapType* MapFromWeakCallbackInfo( 133 const WeakCallbackInfo
& data) { 134 return nullptr; 135 } 136 static K KeyFromWeakCallbackInfo( 137 const WeakCallbackInfo
& data) { 138 return K(); 139 } 140 static void DisposeCallbackData(WeakCallbackDataType* data) {} 141 static void OnWeakCallback( 142 const WeakCallbackInfo
& data) {} 143 static void Dispose(Isolate* isolate, Global
value, K key) {} 144 // This is a second pass callback, so SetSecondPassCallback cannot be called. 145 static void DisposeWeak(const WeakCallbackInfo
& data) {} 146 147 private: 148 template
149 struct RemovePointer
{ 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
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
Get(const K& key) { 184 return Local
::New(isolate_, FromVal(Traits::Get(&impl_, key))); 185 } 186 187 /** 188 * Check whether a value is contained in the map. 189 */ 190 bool Contains(const K& key) { 191 return Traits::Get(&impl_, key) != kPersistentContainerNotFound; 192 } 193 194 /** 195 * Get value stored in map and set it in returnValue. 196 * Return true if a value was found. 197 */ 198 bool SetReturnValue(const K& key, 199 ReturnValue
returnValue) { 200 return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key)); 201 } 202 203 /** 204 * Return value for key and remove it from the map. 205 */ 206 Global
Remove(const K& key) { 207 return Release(Traits::Remove(&impl_, key)).Pass(); 208 } 209 210 /** 211 * Traverses the map repeatedly, 212 * in case side effects of disposal cause insertions. 213 **/ 214 void Clear() { 215 typedef typename Traits::Iterator It; 216 HandleScope handle_scope(isolate_); 217 // TODO(dcarney): figure out if this swap and loop is necessary. 218 while (!Traits::Empty(&impl_)) { 219 typename Traits::Impl impl; 220 Traits::Swap(impl_, impl); 221 for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) { 222 Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), 223 Traits::Key(i)); 224 } 225 } 226 } 227 228 /** 229 * Helper class for GetReference/SetWithReference. Do not use outside 230 * that context. 231 */ 232 class PersistentValueReference { 233 public: 234 PersistentValueReference() : value_(kPersistentContainerNotFound) { } 235 PersistentValueReference(const PersistentValueReference& other) 236 : value_(other.value_) { } 237 238 Local
NewLocal(Isolate* isolate) const { 239 return Local
::New(isolate, FromVal(value_)); 240 } 241 bool IsEmpty() const { 242 return value_ == kPersistentContainerNotFound; 243 } 244 template
245 bool SetReturnValue(ReturnValue
returnValue) { 246 return SetReturnValueFromVal(&returnValue, value_); 247 } 248 void Reset() { 249 value_ = kPersistentContainerNotFound; 250 } 251 void operator=(const PersistentValueReference& other) { 252 value_ = other.value_; 253 } 254 255 private: 256 friend class PersistentValueMapBase; 257 friend class PersistentValueMap
; 258 friend class GlobalValueMap
; 259 260 explicit PersistentValueReference(PersistentContainerValue value) 261 : value_(value) { } 262 263 void operator=(PersistentContainerValue value) { 264 value_ = value; 265 } 266 267 PersistentContainerValue value_; 268 }; 269 270 /** 271 * Get a reference to a map value. This enables fast, repeated access 272 * to a value stored in the map while the map remains unchanged. 273 * 274 * Careful: This is potentially unsafe, so please use with care. 275 * The value will become invalid if the value for this key changes 276 * in the underlying map, as a result of Set or Remove for the same 277 * key; as a result of the weak callback for the same key; or as a 278 * result of calling Clear() or destruction of the map. 279 */ 280 PersistentValueReference GetReference(const K& key) { 281 return PersistentValueReference(Traits::Get(&impl_, key)); 282 } 283 284 protected: 285 explicit PersistentValueMapBase(Isolate* isolate) 286 : isolate_(isolate), label_(nullptr) {} 287 PersistentValueMapBase(Isolate* isolate, const char* label) 288 : isolate_(isolate), label_(label) {} 289 290 ~PersistentValueMapBase() { Clear(); } 291 292 Isolate* isolate() { return isolate_; } 293 typename Traits::Impl* impl() { return &impl_; } 294 295 static V* FromVal(PersistentContainerValue v) { 296 return reinterpret_cast
(v); 297 } 298 299 static PersistentContainerValue ClearAndLeak(Global
* persistent) { 300 V* v = persistent->val_; 301 persistent->val_ = nullptr; 302 return reinterpret_cast
(v); 303 } 304 305 static PersistentContainerValue Leak(Global
* persistent) { 306 return reinterpret_cast
(persistent->val_); 307 } 308 309 /** 310 * Return a container value as Global and make sure the weak 311 * callback is properly disposed of. All remove functionality should go 312 * through this. 313 */ 314 static Global
Release(PersistentContainerValue v) { 315 Global
p; 316 p.val_ = FromVal(v); 317 if (Traits::kCallbackType != kNotWeak && p.IsWeak()) { 318 Traits::DisposeCallbackData( 319 p.template ClearWeak
()); 320 } 321 return p.Pass(); 322 } 323 324 void RemoveWeak(const K& key) { 325 Global
p; 326 p.val_ = FromVal(Traits::Remove(&impl_, key)); 327 p.Reset(); 328 } 329 330 void AnnotateStrongRetainer(Global
* persistent) { 331 persistent->AnnotateStrongRetainer(label_); 332 } 333 334 private: 335 PersistentValueMapBase(PersistentValueMapBase&); 336 void operator=(PersistentValueMapBase&); 337 338 static bool SetReturnValueFromVal(ReturnValue
* returnValue, 339 PersistentContainerValue value) { 340 bool hasValue = value != kPersistentContainerNotFound; 341 if (hasValue) { 342 returnValue->SetInternal( 343 *reinterpret_cast
(FromVal(value))); 344 } 345 return hasValue; 346 } 347 348 Isolate* isolate_; 349 typename Traits::Impl impl_; 350 const char* label_; 351 }; 352 353 template
354 class PersistentValueMap : public PersistentValueMapBase
{ 355 public: 356 explicit PersistentValueMap(Isolate* isolate) 357 : PersistentValueMapBase
(isolate) {} 358 PersistentValueMap(Isolate* isolate, const char* label) 359 : PersistentValueMapBase
(isolate, label) {} 360 361 typedef 362 typename PersistentValueMapBase
::PersistentValueReference 363 PersistentValueReference; 364 365 /** 366 * Put value into map. Depending on Traits::kIsWeak, the value will be held 367 * by the map strongly or weakly. 368 * Returns old value as Global. 369 */ 370 Global
Set(const K& key, Local
value) { 371 Global
persistent(this->isolate(), value); 372 return SetUnique(key, &persistent); 373 } 374 375 /** 376 * Put value into map, like Set(const K&, Local
). 377 */ 378 Global
Set(const K& key, Global
value) { 379 return SetUnique(key, &value); 380 } 381 382 /** 383 * Put the value into the map, and set the 'weak' callback when demanded 384 * by the Traits class. 385 */ 386 Global
SetUnique(const K& key, Global
* persistent) { 387 if (Traits::kCallbackType == kNotWeak) { 388 this->AnnotateStrongRetainer(persistent); 389 } else { 390 WeakCallbackType callback_type = 391 Traits::kCallbackType == kWeakWithInternalFields 392 ? WeakCallbackType::kInternalFields 393 : WeakCallbackType::kParameter; 394 Local
value(Local
::New(this->isolate(), *persistent)); 395 persistent->template SetWeak
( 396 Traits::WeakCallbackParameter(this, key, value), WeakCallback, 397 callback_type); 398 } 399 PersistentContainerValue old_value = 400 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); 401 return this->Release(old_value).Pass(); 402 } 403 404 /** 405 * Put a value into the map and update the reference. 406 * Restrictions of GetReference apply here as well. 407 */ 408 Global
Set(const K& key, Global
value, 409 PersistentValueReference* reference) { 410 *reference = this->Leak(&value); 411 return SetUnique(key, &value); 412 } 413 414 private: 415 static void WeakCallback( 416 const WeakCallbackInfo
& data) { 417 if (Traits::kCallbackType != kNotWeak) { 418 PersistentValueMap
* persistentValueMap = 419 Traits::MapFromWeakCallbackInfo(data); 420 K key = Traits::KeyFromWeakCallbackInfo(data); 421 Traits::Dispose(data.GetIsolate(), 422 persistentValueMap->Remove(key).Pass(), key); 423 Traits::DisposeCallbackData(data.GetParameter()); 424 } 425 } 426 }; 427 428 429 template
430 class GlobalValueMap : public PersistentValueMapBase
{ 431 public: 432 explicit GlobalValueMap(Isolate* isolate) 433 : PersistentValueMapBase
(isolate) {} 434 GlobalValueMap(Isolate* isolate, const char* label) 435 : PersistentValueMapBase
(isolate, label) {} 436 437 typedef 438 typename PersistentValueMapBase
::PersistentValueReference 439 PersistentValueReference; 440 441 /** 442 * Put value into map. Depending on Traits::kIsWeak, the value will be held 443 * by the map strongly or weakly. 444 * Returns old value as Global. 445 */ 446 Global
Set(const K& key, Local
value) { 447 Global
persistent(this->isolate(), value); 448 return SetUnique(key, &persistent); 449 } 450 451 /** 452 * Put value into map, like Set(const K&, Local
). 453 */ 454 Global
Set(const K& key, Global
value) { 455 return SetUnique(key, &value); 456 } 457 458 /** 459 * Put the value into the map, and set the 'weak' callback when demanded 460 * by the Traits class. 461 */ 462 Global
SetUnique(const K& key, Global
* persistent) { 463 if (Traits::kCallbackType == kNotWeak) { 464 this->AnnotateStrongRetainer(persistent); 465 } else { 466 WeakCallbackType callback_type = 467 Traits::kCallbackType == kWeakWithInternalFields 468 ? WeakCallbackType::kInternalFields 469 : WeakCallbackType::kParameter; 470 Local
value(Local
::New(this->isolate(), *persistent)); 471 persistent->template SetWeak
( 472 Traits::WeakCallbackParameter(this, key, value), OnWeakCallback, 473 callback_type); 474 } 475 PersistentContainerValue old_value = 476 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); 477 return this->Release(old_value).Pass(); 478 } 479 480 /** 481 * Put a value into the map and update the reference. 482 * Restrictions of GetReference apply here as well. 483 */ 484 Global
Set(const K& key, Global
value, 485 PersistentValueReference* reference) { 486 *reference = this->Leak(&value); 487 return SetUnique(key, &value); 488 } 489 490 private: 491 static void OnWeakCallback( 492 const WeakCallbackInfo
& data) { 493 if (Traits::kCallbackType != kNotWeak) { 494 auto map = Traits::MapFromWeakCallbackInfo(data); 495 K key = Traits::KeyFromWeakCallbackInfo(data); 496 map->RemoveWeak(key); 497 Traits::OnWeakCallback(data); 498 data.SetSecondPassCallback(SecondWeakCallback); 499 } 500 } 501 502 static void SecondWeakCallback( 503 const WeakCallbackInfo
& data) { 504 Traits::DisposeWeak(data); 505 } 506 }; 507 508 509 /** 510 * A map that uses Global as value and std::map as the backing 511 * implementation. Persistents are held non-weak. 512 * 513 * C++11 embedders don't need this class, as they can use 514 * Global directly in std containers. 515 */ 516 template
> 518 class StdPersistentValueMap : public PersistentValueMap
{ 519 public: 520 explicit StdPersistentValueMap(Isolate* isolate) 521 : PersistentValueMap
(isolate) {} 522 }; 523 524 525 /** 526 * A map that uses Global as value and std::map as the backing 527 * implementation. Globals are held non-weak. 528 * 529 * C++11 embedders don't need this class, as they can use 530 * Global directly in std containers. 531 */ 532 template
> 534 class StdGlobalValueMap : public GlobalValueMap
{ 535 public: 536 explicit StdGlobalValueMap(Isolate* isolate) 537 : GlobalValueMap
(isolate) {} 538 }; 539 540 541 class DefaultPersistentValueVectorTraits { 542 public: 543 typedef std::vector
Impl; 544 545 static void Append(Impl* impl, PersistentContainerValue value) { 546 impl->push_back(value); 547 } 548 static bool IsEmpty(const Impl* impl) { 549 return impl->empty(); 550 } 551 static size_t Size(const Impl* impl) { 552 return impl->size(); 553 } 554 static PersistentContainerValue Get(const Impl* impl, size_t i) { 555 return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound; 556 } 557 static void ReserveCapacity(Impl* impl, size_t capacity) { 558 impl->reserve(capacity); 559 } 560 static void Clear(Impl* impl) { 561 impl->clear(); 562 } 563 }; 564 565 566 /** 567 * A vector wrapper that safely stores Global values. 568 * C++11 embedders don't need this class, as they can use Global 569 * directly in std containers. 570 * 571 * This class relies on a backing vector implementation, whose type and methods 572 * are described by the Traits class. The backing map will handle values of type 573 * PersistentContainerValue, with all conversion into and out of V8 574 * handles being transparently handled by this class. 575 */ 576 template
577 class PersistentValueVector { 578 public: 579 explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { } 580 581 ~PersistentValueVector() { 582 Clear(); 583 } 584 585 /** 586 * Append a value to the vector. 587 */ 588 void Append(Local
value) { 589 Global
persistent(isolate_, value); 590 Traits::Append(&impl_, ClearAndLeak(&persistent)); 591 } 592 593 /** 594 * Append a persistent's value to the vector. 595 */ 596 void Append(Global
persistent) { 597 Traits::Append(&impl_, ClearAndLeak(&persistent)); 598 } 599 600 /** 601 * Are there any values in the vector? 602 */ 603 bool IsEmpty() const { 604 return Traits::IsEmpty(&impl_); 605 } 606 607 /** 608 * How many elements are in the vector? 609 */ 610 size_t Size() const { 611 return Traits::Size(&impl_); 612 } 613 614 /** 615 * Retrieve the i-th value in the vector. 616 */ 617 Local
Get(size_t index) const { 618 return Local
::New(isolate_, FromVal(Traits::Get(&impl_, index))); 619 } 620 621 /** 622 * Remove all elements from the vector. 623 */ 624 void Clear() { 625 size_t length = Traits::Size(&impl_); 626 for (size_t i = 0; i < length; i++) { 627 Global
p; 628 p.val_ = FromVal(Traits::Get(&impl_, i)); 629 } 630 Traits::Clear(&impl_); 631 } 632 633 /** 634 * Reserve capacity in the vector. 635 * (Efficiency gains depend on the backing implementation.) 636 */ 637 void ReserveCapacity(size_t capacity) { 638 Traits::ReserveCapacity(&impl_, capacity); 639 } 640 641 private: 642 static PersistentContainerValue ClearAndLeak(Global
* persistent) { 643 V* v = persistent->val_; 644 persistent->val_ = nullptr; 645 return reinterpret_cast
(v); 646 } 647 648 static V* FromVal(PersistentContainerValue v) { 649 return reinterpret_cast
(v); 650 } 651 652 Isolate* isolate_; 653 typename Traits::Impl impl_; 654 }; 655 656 } // namespace v8 657 658 #endif // V8_UTIL_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™