Loading...
Searching...
No Matches
v8-util.h
Go to the documentation of this file.
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
23namespace v8 {
24
25template <typename K, typename V, typename Traits>
26class GlobalValueMap;
27
28typedef uintptr_t PersistentContainerValue;
29static const uintptr_t kPersistentContainerNotFound = 0;
32 // These correspond to v8::WeakCallbackType
35};
36
43template<typename K, typename V>
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,
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
90template<typename K, typename V>
92 public:
93 // Weak callback & friends:
98
100 MapType* map, const K& key, Local<V> value) {
101 return nullptr;
102 }
105 return nullptr;
106 }
109 return K();
110 }
112 static void Dispose(Isolate* isolate, Global<V> value, K key) {}
113};
114
115
116template <typename K, typename V>
118 private:
119 template <typename T>
120 struct RemovePointer;
121
122 public:
123 // Weak callback & friends:
127
129 Local<V> value) {
130 return nullptr;
131 }
134 return nullptr;
135 }
138 return K();
139 }
141 static void OnWeakCallback(
143 static void Dispose(Isolate* isolate, Global<V> value, K key) {}
144 // This is a second pass callback, so SetSecondPassCallback cannot be called.
146
147 private:
148 template <typename T>
149 struct RemovePointer<T*> {
150 typedef T Type;
151 };
152};
153
154
165template <typename K, typename V, typename Traits>
167 public:
168 Isolate* GetIsolate() { return isolate_; }
169
173 size_t Size() { return Traits::Size(&impl_); }
174
178 bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
179
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
194 bool Contains(const K& key) {
195 return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
196 }
197
202 bool SetReturnValue(const K& key,
203 ReturnValue<Value> returnValue) {
204 return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
205 }
206
210 Global<V> Remove(const K& key) {
211 return Release(Traits::Remove(&impl_, key)).Pass();
212 }
213
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
237 public:
238 PersistentValueReference() : value_(kPersistentContainerNotFound) { }
240 : value_(other.value_) { }
241
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 }
258 value_ = other.value_;
259 }
260
261 private:
263 friend class PersistentValueMap<K, V, Traits>;
264 friend class GlobalValueMap<K, V, Traits>;
265
267 : value_(value) { }
268
270 value_ = value;
271 }
272
274 };
275
287 return PersistentValueReference(Traits::Get(&impl_, key));
288 }
289
290 protected:
292 : isolate_(isolate), label_(nullptr) {}
294 : isolate_(isolate), label_(label) {}
295
297
298 Isolate* isolate() { return isolate_; }
299 typename Traits::Impl* impl() { return &impl_; }
300
302 return internal::ValueHelper::SlotAsValue<V>(
303 reinterpret_cast<internal::Address*>(v));
304 }
305
307 internal::Address* address = persistent->slot();
308 persistent->Clear();
309 return reinterpret_cast<PersistentContainerValue>(address);
310 }
311
313 return reinterpret_cast<PersistentContainerValue>(persistent->slot());
314 }
315
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
339 persistent->AnnotateStrongRetainer(label_);
340 }
341
342 private:
344 void operator=(PersistentValueMapBase&);
345
346 static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
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
360template <typename K, typename V, typename Traits>
361class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
362 public:
364 : PersistentValueMapBase<K, V, Traits>(isolate) {}
365 PersistentValueMap(Isolate* isolate, const char* label)
366 : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
367
368 typedef
371
377 Global<V> Set(const K& key, Local<V> value) {
378 Global<V> persistent(this->isolate(), value);
379 return SetUnique(key, &persistent);
380 }
381
385 Global<V> Set(const K& key, Global<V> value) {
386 return SetUnique(key, &value);
387 }
388
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
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
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(
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
436template <typename K, typename V, typename Traits>
437class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
438 public:
440 : PersistentValueMapBase<K, V, Traits>(isolate) {}
441 GlobalValueMap(Isolate* isolate, const char* label)
442 : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
443
444 typedef
447
453 Global<V> Set(const K& key, Local<V> value) {
454 Global<V> persistent(this->isolate(), value);
455 return SetUnique(key, &persistent);
456 }
457
461 Global<V> Set(const K& key, Global<V> value) {
462 return SetUnique(key, &value);
463 }
464
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
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
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(
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
523template<typename K, typename V,
524 typename Traits = DefaultPersistentValueMapTraits<K, V> >
525class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
526 public:
528 : PersistentValueMap<K, V, Traits>(isolate) {}
529};
530
531
539template <typename K, typename V,
540 typename Traits = DefaultGlobalMapTraits<K, V> >
541class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
542 public:
544 : GlobalValueMap<K, V, Traits>(isolate) {}
545};
546
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
581template <typename V, typename Traits = DefaultPersistentValueVectorTraits>
582class V8_DEPRECATED("Use std::vector<Global<V>>.") PersistentValueVector {
583 public:
584 explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
585
587 Clear();
588 }
589
593 void Append(Local<V> value) {
594 Global<V> persistent(isolate_, value);
595 Traits::Append(&impl_, ClearAndLeak(&persistent));
596 }
597
601 void Append(Global<V> persistent) {
602 Traits::Append(&impl_, ClearAndLeak(&persistent));
603 }
604
608 bool IsEmpty() const {
609 return Traits::IsEmpty(&impl_);
610 }
611
615 size_t Size() const {
616 return Traits::Size(&impl_);
617 }
618
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
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
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
Definition: v8-util.h:117
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition: v8-util.h:140
static void OnWeakCallback(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:141
static K KeyFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:136
GlobalValueMap< K, V, DefaultGlobalMapTraits< K, V > > MapType
Definition: v8-util.h:125
static MapType * MapFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:132
static const PersistentContainerCallbackType kCallbackType
Definition: v8-util.h:124
static void DisposeWeak(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:145
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition: v8-util.h:128
static void Dispose(Isolate *isolate, Global< V > value, K key)
Definition: v8-util.h:143
void WeakCallbackDataType
Definition: v8-util.h:126
Definition: v8-util.h:91
PersistentValueMap< K, V, DefaultPersistentValueMapTraits< K, V > > MapType
Definition: v8-util.h:96
static const PersistentContainerCallbackType kCallbackType
Definition: v8-util.h:94
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition: v8-util.h:99
static void Dispose(Isolate *isolate, Global< V > value, K key)
Definition: v8-util.h:112
void WeakCallbackDataType
Definition: v8-util.h:97
static K KeyFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:107
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition: v8-util.h:111
static MapType * MapFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:103
static size_t Size(const Impl *impl)
Definition: v8-util.h:557
static bool IsEmpty(const Impl *impl)
Definition: v8-util.h:554
static void Clear(Impl *impl)
Definition: v8-util.h:566
static PersistentContainerValue Get(const Impl *impl, size_t i)
Definition: v8-util.h:560
static void Append(Impl *impl, PersistentContainerValue value)
Definition: v8-util.h:551
std::vector< PersistentContainerValue > Impl
Definition: v8-util.h:549
static void ReserveCapacity(Impl *impl, size_t capacity)
Definition: v8-util.h:563
Definition: v8-util.h:437
Global< V > Set(const K &key, Local< V > value)
Definition: v8-util.h:453
GlobalValueMap(Isolate *isolate, const char *label)
Definition: v8-util.h:441
Global< V > Set(const K &key, Global< V > value)
Definition: v8-util.h:461
Global< V > SetUnique(const K &key, Global< V > *persistent)
Definition: v8-util.h:469
GlobalValueMap(Isolate *isolate)
Definition: v8-util.h:439
PersistentValueMapBase< K, V, Traits >::PersistentValueReference PersistentValueReference
Definition: v8-util.h:446
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Definition: v8-util.h:491
Definition: v8-persistent-handle.h:351
Global Pass()
Definition: v8-persistent-handle.h:398
Definition: v8-local-handle.h:99
Definition: v8-isolate.h:210
Definition: v8-local-handle.h:258
static Local< T > New(Isolate *isolate, Local< T > that)
Definition: v8-local-handle.h:338
void Reset()
Definition: v8-persistent-handle.h:453
void AnnotateStrongRetainer(const char *label)
Definition: v8-persistent-handle.h:515
bool IsWeak() const
Definition: v8-persistent-handle.h:446
bool SetReturnValue(ReturnValue< T > returnValue)
Definition: v8-util.h:251
PersistentValueReference(const PersistentValueReference &other)
Definition: v8-util.h:239
bool IsEmpty() const
Definition: v8-util.h:247
Local< V > NewLocal(Isolate *isolate) const
Definition: v8-util.h:242
void operator=(const PersistentValueReference &other)
Definition: v8-util.h:257
Definition: v8-util.h:166
Traits::Impl * impl()
Definition: v8-util.h:299
PersistentValueMapBase(Isolate *isolate)
Definition: v8-util.h:291
void Clear()
Definition: v8-util.h:218
PersistentValueMapBase(Isolate *isolate, const char *label)
Definition: v8-util.h:293
void AnnotateStrongRetainer(Global< V > *persistent)
Definition: v8-util.h:338
PersistentValueReference GetReference(const K &key)
Definition: v8-util.h:286
~PersistentValueMapBase()
Definition: v8-util.h:296
Local< V > Get(const K &key)
Definition: v8-util.h:183
void RemoveWeak(const K &key)
Definition: v8-util.h:331
static PersistentContainerValue ClearAndLeak(Global< V > *persistent)
Definition: v8-util.h:306
bool SetReturnValue(const K &key, ReturnValue< Value > returnValue)
Definition: v8-util.h:202
bool Contains(const K &key)
Definition: v8-util.h:194
bool IsWeak()
Definition: v8-util.h:178
static V * FromVal(PersistentContainerValue v)
Definition: v8-util.h:301
Isolate * isolate()
Definition: v8-util.h:298
Isolate * GetIsolate()
Definition: v8-util.h:168
static PersistentContainerValue Leak(Global< V > *persistent)
Definition: v8-util.h:312
size_t Size()
Definition: v8-util.h:173
static Global< V > Release(PersistentContainerValue v)
Definition: v8-util.h:321
Global< V > Remove(const K &key)
Definition: v8-util.h:210
Definition: v8-util.h:361
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Definition: v8-util.h:415
Global< V > Set(const K &key, Global< V > value)
Definition: v8-util.h:385
Global< V > SetUnique(const K &key, Global< V > *persistent)
Definition: v8-util.h:393
Global< V > Set(const K &key, Local< V > value)
Definition: v8-util.h:377
PersistentValueMapBase< K, V, Traits >::PersistentValueReference PersistentValueReference
Definition: v8-util.h:370
PersistentValueMap(Isolate *isolate)
Definition: v8-util.h:363
PersistentValueMap(Isolate *isolate, const char *label)
Definition: v8-util.h:365
Definition: v8-util.h:582
void Append(Local< V > value)
Definition: v8-util.h:593
~PersistentValueVector()
Definition: v8-util.h:586
Local< V > Get(size_t index) const
Definition: v8-util.h:622
bool IsEmpty() const
Definition: v8-util.h:608
PersistentValueVector(Isolate *isolate)
Definition: v8-util.h:584
void Append(Global< V > persistent)
Definition: v8-util.h:601
void Clear()
Definition: v8-util.h:630
void ReserveCapacity(size_t capacity)
Definition: v8-util.h:643
size_t Size() const
Definition: v8-util.h:615
Definition: v8-function-callback.h:35
Definition: v8-util.h:541
StdGlobalValueMap(Isolate *isolate)
Definition: v8-util.h:543
Definition: v8-util.h:44
static PersistentContainerValue Set(Impl *impl, K key, PersistentContainerValue value)
Definition: v8-util.h:57
static Iterator End(Impl *impl)
Definition: v8-util.h:54
static size_t Size(Impl *impl)
Definition: v8-util.h:51
static bool Empty(Impl *impl)
Definition: v8-util.h:50
static PersistentContainerValue Get(Impl *impl, K key)
Definition: v8-util.h:67
static K Key(Iterator it)
Definition: v8-util.h:55
static Iterator Begin(Impl *impl)
Definition: v8-util.h:53
std::map< K, PersistentContainerValue > Impl
Definition: v8-util.h:47
Impl::iterator Iterator
Definition: v8-util.h:48
static PersistentContainerValue Remove(Impl *impl, K key)
Definition: v8-util.h:72
static PersistentContainerValue Value(Iterator it)
Definition: v8-util.h:56
static void Swap(Impl &a, Impl &b)
Definition: v8-util.h:52
Definition: v8-util.h:525
StdPersistentValueMap(Isolate *isolate)
Definition: v8-util.h:527
Definition: v8-weak-callback-info.h:22
Isolate * GetIsolate() const
Definition: v8-weak-callback-info.h:35
T * GetParameter() const
Definition: v8-weak-callback-info.h:36
void SetSecondPassCallback(Callback callback) const
Definition: v8-weak-callback-info.h:45
internal::Address *const & slot() const
Definition: v8-handle-base.h:79
void Clear()
Definition: v8-handle-base.h:59
uintptr_t Address
Definition: v8-internal.h:31
Definition: libplatform.h:15
WeakCallbackType
Definition: v8-weak-callback-info.h:57
PersistentContainerCallbackType
Definition: v8-util.h:30
@ kWeakWithInternalFields
Definition: v8-util.h:34
@ kWeakWithParameter
Definition: v8-util.h:33
@ kNotWeak
Definition: v8-util.h:31
uintptr_t PersistentContainerValue
Definition: v8-util.h:28
#define V(Name)
#define V8_DEPRECATED(message)
Definition: v8config.h:572