Turn audio into a shareable video. forked from nypublicradio/audiogram

v8-util.h 20KB

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