22 typedef uintptr_t PersistentContainerValue;
23 static const uintptr_t kPersistentContainerNotFound = 0;
24 enum PersistentContainerCallbackType {
28 kWeakWithInternalFields
37 template<
typename K,
typename V>
41 typedef std::map<K, PersistentContainerValue> Impl;
42 typedef typename Impl::iterator Iterator;
44 static bool Empty(Impl* impl) {
return impl->empty(); }
45 static size_t Size(Impl* impl) {
return impl->size(); }
46 static void Swap(Impl& a, Impl& b) { std::swap(a, b); }
47 static Iterator Begin(Impl* impl) {
return impl->begin(); }
48 static Iterator End(Impl* impl) {
return impl->end(); }
49 static K Key(Iterator it) {
return it->first; }
53 std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
56 old_value = res.first->second;
57 res.first->second = value;
62 Iterator it = impl->find(key);
63 if (it == impl->end())
return kPersistentContainerNotFound;
67 Iterator it = impl->find(key);
68 if (it == impl->end())
return kPersistentContainerNotFound;
84 template<
typename K,
typename V>
88 static const PersistentContainerCallbackType kCallbackType = kNotWeak;
91 typedef void WeakCallbackDataType;
93 static WeakCallbackDataType* WeakCallbackParameter(
97 static MapType* MapFromWeakCallbackInfo(
101 static K KeyFromWeakCallbackInfo(
105 static void DisposeCallbackData(WeakCallbackDataType* data) { }
106 static void Dispose(Isolate* isolate,
Global<V> value, K key) {}
110 template <
typename K,
typename V>
113 template <
typename T>
114 struct RemovePointer;
118 static const PersistentContainerCallbackType kCallbackType = kNotWeak;
120 typedef void WeakCallbackDataType;
122 static WeakCallbackDataType* WeakCallbackParameter(
MapType* map,
const K& key,
126 static MapType* MapFromWeakCallbackInfo(
130 static K KeyFromWeakCallbackInfo(
134 static void DisposeCallbackData(WeakCallbackDataType* data) {}
135 static void OnWeakCallback(
137 static void Dispose(Isolate* isolate,
Global<V> value, K key) {}
142 template <
typename T>
143 struct RemovePointer<
T*> {
159 template <
typename K,
typename V,
typename Traits>
162 Isolate* GetIsolate() {
return isolate_; }
167 size_t Size() {
return Traits::Size(&impl_); }
172 bool IsWeak() {
return Traits::kCallbackType != kNotWeak; }
178 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
185 return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
194 return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
203 V8::RegisterExternallyReferencedObject(
204 reinterpret_cast<internal::Address*>(FromVal(Traits::Get(&impl_, key))),
205 reinterpret_cast<internal::Isolate*>(GetIsolate()));
212 return Release(Traits::Remove(&impl_, key)).Pass();
220 typedef typename Traits::Iterator It;
223 while (!Traits::Empty(&impl_)) {
224 typename Traits::Impl impl;
225 Traits::Swap(impl_, impl);
226 for (It
i = Traits::Begin(&impl);
i != Traits::End(&impl); ++
i) {
227 Traits::Dispose(isolate_,
Release(Traits::Value(
i)).Pass(),
241 : value_(other.value_) { }
243 Local<V> NewLocal(Isolate* isolate)
const {
246 bool IsEmpty()
const {
247 return value_ == kPersistentContainerNotFound;
251 return SetReturnValueFromVal(&returnValue, value_);
254 value_ = kPersistentContainerNotFound;
257 value_ = other.value_;
292 ~PersistentValueMapBase() {
Clear(); }
294 Isolate* isolate() {
return isolate_; }
295 typename Traits::Impl* impl() {
return &impl_; }
297 static V* FromVal(PersistentContainerValue v) {
298 return reinterpret_cast<V*
>(v);
301 static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
302 V* v = persistent->val_;
303 persistent->val_ =
nullptr;
304 return reinterpret_cast<PersistentContainerValue
>(v);
307 static PersistentContainerValue Leak(Global<V>* persistent) {
308 return reinterpret_cast<PersistentContainerValue
>(persistent->val_);
319 if (Traits::kCallbackType != kNotWeak && p.
IsWeak()) {
320 Traits::DisposeCallbackData(
321 p.template ClearWeak<typename Traits::WeakCallbackDataType>());
326 void RemoveWeak(
const K& key) {
328 p.val_ = FromVal(Traits::Remove(&impl_, key));
333 PersistentValueMapBase(PersistentValueMapBase&);
334 void operator=(PersistentValueMapBase&);
336 static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
337 PersistentContainerValue value) {
338 bool hasValue = value != kPersistentContainerNotFound;
340 returnValue->SetInternal(
341 *reinterpret_cast<internal::Address*>(FromVal(value)));
347 typename Traits::Impl impl_;
351 template <
typename K,
typename V,
typename Traits>
367 Global<V> persistent(this->isolate(), value);
383 if (Traits::kCallbackType != kNotWeak) {
384 WeakCallbackType callback_type =
385 Traits::kCallbackType == kWeakWithInternalFields
386 ? WeakCallbackType::kInternalFields
387 : WeakCallbackType::kParameter;
389 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
390 Traits::WeakCallbackParameter(
this, key, value), WeakCallback,
394 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
395 return this->
Release(old_value).Pass();
404 *reference = this->Leak(&value);
409 static void WeakCallback(
411 if (Traits::kCallbackType != kNotWeak) {
413 Traits::MapFromWeakCallbackInfo(data);
414 K key = Traits::KeyFromWeakCallbackInfo(data);
415 Traits::Dispose(data.GetIsolate(),
416 persistentValueMap->
Remove(key).Pass(), key);
417 Traits::DisposeCallbackData(data.GetParameter());
423 template <
typename K,
typename V,
typename Traits>
439 Global<V> persistent(this->isolate(), value);
455 if (Traits::kCallbackType != kNotWeak) {
456 WeakCallbackType callback_type =
457 Traits::kCallbackType == kWeakWithInternalFields
458 ? WeakCallbackType::kInternalFields
459 : WeakCallbackType::kParameter;
461 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
462 Traits::WeakCallbackParameter(
this, key, value), OnWeakCallback,
466 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
467 return this->
Release(old_value).Pass();
476 *reference = this->Leak(&value);
481 static void OnWeakCallback(
483 if (Traits::kCallbackType != kNotWeak) {
484 auto map = Traits::MapFromWeakCallbackInfo(data);
485 K key = Traits::KeyFromWeakCallbackInfo(data);
486 map->RemoveWeak(key);
487 Traits::OnWeakCallback(data);
488 data.SetSecondPassCallback(SecondWeakCallback);
492 static void SecondWeakCallback(
493 const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
494 Traits::DisposeWeak(data);
506 template<
typename K,
typename V,
507 typename Traits = DefaultPersistentValueMapTraits<K, V> >
522 template <
typename K,
typename V,
533 typedef std::vector<PersistentContainerValue> Impl;
536 impl->push_back(value);
538 static bool IsEmpty(
const Impl* impl) {
539 return impl->empty();
541 static size_t Size(
const Impl* impl) {
545 return (i < impl->size()) ? impl->at(
i) : kPersistentContainerNotFound;
547 static void ReserveCapacity(Impl* impl,
size_t capacity) {
548 impl->reserve(capacity);
550 static void Clear(Impl* impl) {
566 template<
typename V,
typename Traits = DefaultPersistentValueVectorTraits>
580 Traits::Append(&impl_, ClearAndLeak(&persistent));
587 Traits::Append(&impl_, ClearAndLeak(&persistent));
594 return Traits::IsEmpty(&impl_);
601 return Traits::Size(&impl_);
608 return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
615 size_t length = Traits::Size(&impl_);
616 for (
size_t i = 0;
i < length;
i++) {
618 p.val_ = FromVal(Traits::Get(&impl_,
i));
620 Traits::Clear(&impl_);
628 Traits::ReserveCapacity(&impl_, capacity);
633 V* v = persistent->val_;
634 persistent->val_ =
nullptr;
638 static V* FromVal(PersistentContainerValue v) {
639 return reinterpret_cast<V*
>(v);
643 typename Traits::Impl impl_;
Global< V > Set(const K &key, Global< V > value)
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Global< V > SetUnique(const K &key, Global< V > *persistent)
V8_INLINE bool IsWeak() const
Global< V > Set(const K &key, Global< V > value)
static Global< V > Release(PersistentContainerValue v)
void ReserveCapacity(size_t capacity)
PersistentValueReference GetReference(const K &key)
Local< V > Get(const K &key)
Global< V > Set(const K &key, Local< V > value)
bool SetReturnValue(const K &key, ReturnValue< Value > returnValue)
void RegisterExternallyReferencedObject(K &key)
Local< V > Get(size_t index) const
Global< V > Set(const K &key, Local< V > value)
static V8_INLINE Local< T > New(Isolate *isolate, Local< T > that)
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
void Append(Local< V > value)
Global< V > Remove(const K &key)
Global< V > SetUnique(const K &key, Global< V > *persistent)
bool Contains(const K &key)
void Append(Global< V > persistent)