v8  7.4.288(node12.0.0)
V8 is Google's open source JavaScript engine
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 "v8.h" // NOLINT(build/include)
9 #include <assert.h>
10 #include <map>
11 #include <vector>
12 
20 namespace v8 {
21 
22 typedef uintptr_t PersistentContainerValue;
23 static const uintptr_t kPersistentContainerNotFound = 0;
26  // These correspond to v8::WeakCallbackType
29 };
30 
37 template<typename K, typename V>
38 class StdMapTraits {
39  public:
40  // STL map & related:
41  typedef std::map<K, PersistentContainerValue> Impl;
42  typedef typename Impl::iterator Iterator;
43 
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); } // NOLINT
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; }
50  static PersistentContainerValue Value(Iterator it) { return it->second; }
51  static PersistentContainerValue Set(Impl* impl, K key,
53  std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
54  PersistentContainerValue old_value = kPersistentContainerNotFound;
55  if (!res.second) {
56  old_value = res.first->second;
57  res.first->second = value;
58  }
59  return old_value;
60  }
61  static PersistentContainerValue Get(Impl* impl, K key) {
62  Iterator it = impl->find(key);
63  if (it == impl->end()) return kPersistentContainerNotFound;
64  return it->second;
65  }
66  static PersistentContainerValue Remove(Impl* impl, K key) {
67  Iterator it = impl->find(key);
68  if (it == impl->end()) return kPersistentContainerNotFound;
69  PersistentContainerValue value = it->second;
70  impl->erase(it);
71  return value;
72  }
73 };
74 
75 
84 template<typename K, typename V>
86  public:
87  // Weak callback & friends:
91  typedef void WeakCallbackDataType;
92 
94  MapType* map, const K& key, Local<V> value) {
95  return nullptr;
96  }
99  return nullptr;
100  }
103  return K();
104  }
106  static void Dispose(Isolate* isolate, Global<V> value, K key) {}
107 };
108 
109 
110 template <typename K, typename V>
111 class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
112  private:
113  template <typename T>
114  struct RemovePointer;
115 
116  public:
117  // Weak callback & friends:
120  typedef void WeakCallbackDataType;
121 
123  Local<V> value) {
124  return nullptr;
125  }
128  return nullptr;
129  }
132  return K();
133  }
135  static void OnWeakCallback(
137  static void Dispose(Isolate* isolate, Global<V> value, K key) {}
138  // This is a second pass callback, so SetSecondPassCallback cannot be called.
140 
141  private:
142  template <typename T>
143  struct RemovePointer<T*> {
144  typedef T Type;
145  };
146 };
147 
148 
159 template <typename K, typename V, typename Traits>
161  public:
162  Isolate* GetIsolate() { return isolate_; }
163 
167  size_t Size() { return Traits::Size(&impl_); }
168 
172  bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
173 
177  Local<V> Get(const K& key) {
178  return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
179  }
180 
184  bool Contains(const K& key) {
185  return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
186  }
187 
192  bool SetReturnValue(const K& key,
193  ReturnValue<Value> returnValue) {
194  return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
195  }
196 
202  "Used TracedGlobal and EmbedderHeapTracer::RegisterEmbedderReference",
203  inline void RegisterExternallyReferencedObject(K& key));
204 
208  Global<V> Remove(const K& key) {
209  return Release(Traits::Remove(&impl_, key)).Pass();
210  }
211 
216  void Clear() {
217  typedef typename Traits::Iterator It;
218  HandleScope handle_scope(isolate_);
219  // TODO(dcarney): figure out if this swap and loop is necessary.
220  while (!Traits::Empty(&impl_)) {
221  typename Traits::Impl impl;
222  Traits::Swap(impl_, impl);
223  for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
224  Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
225  Traits::Key(i));
226  }
227  }
228  }
229 
235  public:
236  PersistentValueReference() : value_(kPersistentContainerNotFound) { }
238  : value_(other.value_) { }
239 
241  return Local<V>::New(isolate, FromVal(value_));
242  }
243  bool IsEmpty() const {
244  return value_ == kPersistentContainerNotFound;
245  }
246  template<typename T>
247  bool SetReturnValue(ReturnValue<T> returnValue) {
248  return SetReturnValueFromVal(&returnValue, value_);
249  }
250  void Reset() {
251  value_ = kPersistentContainerNotFound;
252  }
253  void operator=(const PersistentValueReference& other) {
254  value_ = other.value_;
255  }
256 
257  private:
259  friend class PersistentValueMap<K, V, Traits>;
260  friend class GlobalValueMap<K, V, Traits>;
261 
263  : value_(value) { }
264 
265  void operator=(PersistentContainerValue value) {
266  value_ = value;
267  }
268 
270  };
271 
283  return PersistentValueReference(Traits::Get(&impl_, key));
284  }
285 
286  protected:
288  : isolate_(isolate), label_(nullptr) {}
290  : isolate_(isolate), label_(label) {}
291 
293 
294  Isolate* isolate() { return isolate_; }
295  typename Traits::Impl* impl() { return &impl_; }
296 
298  return reinterpret_cast<V*>(v);
299  }
300 
302  V* v = persistent->val_;
303  persistent->val_ = nullptr;
304  return reinterpret_cast<PersistentContainerValue>(v);
305  }
306 
308  return reinterpret_cast<PersistentContainerValue>(persistent->val_);
309  }
310 
317  Global<V> p;
318  p.val_ = FromVal(v);
319  if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
320  Traits::DisposeCallbackData(
321  p.template ClearWeak<typename Traits::WeakCallbackDataType>());
322  }
323  return p.Pass();
324  }
325 
326  void RemoveWeak(const K& key) {
327  Global<V> p;
328  p.val_ = FromVal(Traits::Remove(&impl_, key));
329  p.Reset();
330  }
331 
332  void AnnotateStrongRetainer(Global<V>* persistent) {
333  persistent->AnnotateStrongRetainer(label_);
334  }
335 
336  private:
338  void operator=(PersistentValueMapBase&);
339 
340  static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
341  PersistentContainerValue value) {
342  bool hasValue = value != kPersistentContainerNotFound;
343  if (hasValue) {
344  returnValue->SetInternal(
345  *reinterpret_cast<internal::Address*>(FromVal(value)));
346  }
347  return hasValue;
348  }
349 
350  Isolate* isolate_;
351  typename Traits::Impl impl_;
352  const char* label_;
353 };
354 
355 template <typename K, typename V, typename Traits>
356 inline void
357 PersistentValueMapBase<K, V, Traits>::RegisterExternallyReferencedObject(
358  K& key) {
359  assert(Contains(key));
360  V8::RegisterExternallyReferencedObject(
361  reinterpret_cast<internal::Address*>(FromVal(Traits::Get(&impl_, key))),
362  reinterpret_cast<internal::Isolate*>(GetIsolate()));
363 }
364 
365 template <typename K, typename V, typename Traits>
366 class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
367  public:
369  : PersistentValueMapBase<K, V, Traits>(isolate) {}
370  PersistentValueMap(Isolate* isolate, const char* label)
371  : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
372 
373  typedef
376 
382  Global<V> Set(const K& key, Local<V> value) {
383  Global<V> persistent(this->isolate(), value);
384  return SetUnique(key, &persistent);
385  }
386 
390  Global<V> Set(const K& key, Global<V> value) {
391  return SetUnique(key, &value);
392  }
393 
398  Global<V> SetUnique(const K& key, Global<V>* persistent) {
399  if (Traits::kCallbackType == kNotWeak) {
400  this->AnnotateStrongRetainer(persistent);
401  } else {
402  WeakCallbackType callback_type =
403  Traits::kCallbackType == kWeakWithInternalFields
406  Local<V> value(Local<V>::New(this->isolate(), *persistent));
407  persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
408  Traits::WeakCallbackParameter(this, key, value), WeakCallback,
409  callback_type);
410  }
411  PersistentContainerValue old_value =
412  Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
413  return this->Release(old_value).Pass();
414  }
415 
420  Global<V> Set(const K& key, Global<V> value,
421  PersistentValueReference* reference) {
422  *reference = this->Leak(&value);
423  return SetUnique(key, &value);
424  }
425 
426  private:
427  static void WeakCallback(
429  if (Traits::kCallbackType != kNotWeak) {
430  PersistentValueMap<K, V, Traits>* persistentValueMap =
431  Traits::MapFromWeakCallbackInfo(data);
432  K key = Traits::KeyFromWeakCallbackInfo(data);
433  Traits::Dispose(data.GetIsolate(),
434  persistentValueMap->Remove(key).Pass(), key);
435  Traits::DisposeCallbackData(data.GetParameter());
436  }
437  }
438 };
439 
440 
441 template <typename K, typename V, typename Traits>
442 class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
443  public:
445  : PersistentValueMapBase<K, V, Traits>(isolate) {}
446  GlobalValueMap(Isolate* isolate, const char* label)
447  : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
448 
449  typedef
452 
458  Global<V> Set(const K& key, Local<V> value) {
459  Global<V> persistent(this->isolate(), value);
460  return SetUnique(key, &persistent);
461  }
462 
466  Global<V> Set(const K& key, Global<V> value) {
467  return SetUnique(key, &value);
468  }
469 
474  Global<V> SetUnique(const K& key, Global<V>* persistent) {
475  if (Traits::kCallbackType == kNotWeak) {
476  this->AnnotateStrongRetainer(persistent);
477  } else {
478  WeakCallbackType callback_type =
479  Traits::kCallbackType == kWeakWithInternalFields
482  Local<V> value(Local<V>::New(this->isolate(), *persistent));
483  persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
484  Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
485  callback_type);
486  }
487  PersistentContainerValue old_value =
488  Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
489  return this->Release(old_value).Pass();
490  }
491 
496  Global<V> Set(const K& key, Global<V> value,
497  PersistentValueReference* reference) {
498  *reference = this->Leak(&value);
499  return SetUnique(key, &value);
500  }
501 
502  private:
503  static void OnWeakCallback(
505  if (Traits::kCallbackType != kNotWeak) {
506  auto map = Traits::MapFromWeakCallbackInfo(data);
507  K key = Traits::KeyFromWeakCallbackInfo(data);
508  map->RemoveWeak(key);
509  Traits::OnWeakCallback(data);
510  data.SetSecondPassCallback(SecondWeakCallback);
511  }
512  }
513 
514  static void SecondWeakCallback(
515  const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
516  Traits::DisposeWeak(data);
517  }
518 };
519 
520 
528 template<typename K, typename V,
529  typename Traits = DefaultPersistentValueMapTraits<K, V> >
530 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
531  public:
533  : PersistentValueMap<K, V, Traits>(isolate) {}
534 };
535 
536 
544 template <typename K, typename V,
545  typename Traits = DefaultGlobalMapTraits<K, V> >
546 class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
547  public:
549  : GlobalValueMap<K, V, Traits>(isolate) {}
550 };
551 
552 
554  public:
555  typedef std::vector<PersistentContainerValue> Impl;
556 
557  static void Append(Impl* impl, PersistentContainerValue value) {
558  impl->push_back(value);
559  }
560  static bool IsEmpty(const Impl* impl) {
561  return impl->empty();
562  }
563  static size_t Size(const Impl* impl) {
564  return impl->size();
565  }
566  static PersistentContainerValue Get(const Impl* impl, size_t i) {
567  return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
568  }
569  static void ReserveCapacity(Impl* impl, size_t capacity) {
570  impl->reserve(capacity);
571  }
572  static void Clear(Impl* impl) {
573  impl->clear();
574  }
575 };
576 
577 
588 template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
590  public:
591  explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
592 
594  Clear();
595  }
596 
600  void Append(Local<V> value) {
601  Global<V> persistent(isolate_, value);
602  Traits::Append(&impl_, ClearAndLeak(&persistent));
603  }
604 
608  void Append(Global<V> persistent) {
609  Traits::Append(&impl_, ClearAndLeak(&persistent));
610  }
611 
615  bool IsEmpty() const {
616  return Traits::IsEmpty(&impl_);
617  }
618 
622  size_t Size() const {
623  return Traits::Size(&impl_);
624  }
625 
629  Local<V> Get(size_t index) const {
630  return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
631  }
632 
636  void Clear() {
637  size_t length = Traits::Size(&impl_);
638  for (size_t i = 0; i < length; i++) {
639  Global<V> p;
640  p.val_ = FromVal(Traits::Get(&impl_, i));
641  }
642  Traits::Clear(&impl_);
643  }
644 
649  void ReserveCapacity(size_t capacity) {
650  Traits::ReserveCapacity(&impl_, capacity);
651  }
652 
653  private:
654  static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
655  V* v = persistent->val_;
656  persistent->val_ = nullptr;
657  return reinterpret_cast<PersistentContainerValue>(v);
658  }
659 
660  static V* FromVal(PersistentContainerValue v) {
661  return reinterpret_cast<V*>(v);
662  }
663 
664  Isolate* isolate_;
665  typename Traits::Impl impl_;
666 };
667 
668 } // namespace v8
669 
670 #endif // V8_UTIL_H
static MapType * MapFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:97
Global< V > Set(const K &key, Global< V > value)
Definition: v8-util.h:390
Definition: v8.h:95
static void Clear(Impl *impl)
Definition: v8-util.h:572
PersistentValueVector(Isolate *isolate)
Definition: v8-util.h:591
static MapType * MapFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:126
static size_t Size(const Impl *impl)
Definition: v8-util.h:563
Global< V > SetUnique(const K &key, Global< V > *persistent)
Definition: v8-util.h:398
static void OnWeakCallback(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:135
V8_INLINE T * GetParameter() const
Definition: v8.h:417
Global< V > Set(const K &key, Local< V > value)
Definition: v8-util.h:382
StdGlobalValueMap(Isolate *isolate)
Definition: v8-util.h:548
static PersistentContainerValue Remove(Impl *impl, K key)
Definition: v8-util.h:66
static PersistentContainerValue Leak(Global< V > *persistent)
Definition: v8-util.h:307
static PersistentContainerValue ClearAndLeak(Global< V > *persistent)
Definition: v8-util.h:301
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Definition: v8-util.h:496
Global< V > SetUnique(const K &key, Global< V > *persistent)
Definition: v8-util.h:474
PersistentValueReference GetReference(const K &key)
Definition: v8-util.h:282
static size_t Size(Impl *impl)
Definition: v8-util.h:45
static bool IsEmpty(const Impl *impl)
Definition: v8-util.h:560
static const PersistentContainerCallbackType kCallbackType
Definition: v8-util.h:88
static void Append(Impl *impl, PersistentContainerValue value)
Definition: v8-util.h:557
void ReserveCapacity(size_t capacity)
Definition: v8-util.h:649
std::vector< PersistentContainerValue > Impl
Definition: v8-util.h:555
static void ReserveCapacity(Impl *impl, size_t capacity)
Definition: v8-util.h:569
static void DisposeWeak(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:139
static V * FromVal(PersistentContainerValue v)
Definition: v8-util.h:297
PersistentValueMapBase< K, V, Traits >::PersistentValueReference PersistentValueReference
Definition: v8-util.h:451
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition: v8-util.h:122
static void Dispose(Isolate *isolate, Global< V > value, K key)
Definition: v8-util.h:106
Global< V > Remove(const K &key)
Definition: v8-util.h:208
static Global< V > Release(PersistentContainerValue v)
Definition: v8-util.h:316
V8_INLINE void AnnotateStrongRetainer(const char *label)
Definition: v8.h:9856
bool Contains(const K &key)
Definition: v8-util.h:184
PersistentValueMap(Isolate *isolate)
Definition: v8-util.h:368
GlobalValueMap< K, V, DefaultGlobalMapTraits< K, V > > MapType
Definition: v8-util.h:119
PersistentContainerCallbackType
Definition: v8-util.h:24
PersistentValueMapBase(Isolate *isolate, const char *label)
Definition: v8-util.h:289
static bool Empty(Impl *impl)
Definition: v8-util.h:44
static PersistentContainerValue Get(const Impl *impl, size_t i)
Definition: v8-util.h:566
uintptr_t PersistentContainerValue
Definition: v8-util.h:22
Definition: libplatform.h:13
static const PersistentContainerCallbackType kCallbackType
Definition: v8-util.h:118
static K KeyFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:101
GlobalValueMap(Isolate *isolate, const char *label)
Definition: v8-util.h:446
static K Key(Iterator it)
Definition: v8-util.h:49
bool SetReturnValue(ReturnValue< T > returnValue)
Definition: v8-util.h:247
static Iterator Begin(Impl *impl)
Definition: v8-util.h:47
V8_INLINE Isolate * GetIsolate() const
Definition: v8.h:416
static Iterator End(Impl *impl)
Definition: v8-util.h:48
bool SetReturnValue(const K &key, ReturnValue< Value > returnValue)
Definition: v8-util.h:192
void AnnotateStrongRetainer(Global< V > *persistent)
Definition: v8-util.h:332
static void Dispose(Isolate *isolate, Global< V > value, K key)
Definition: v8-util.h:137
Local< V > Get(size_t index) const
Definition: v8-util.h:629
PersistentValueMapBase< K, V, Traits >::PersistentValueReference PersistentValueReference
Definition: v8-util.h:375
Global Pass()
Definition: v8.h:807
V8_INLINE bool IsWeak() const
Definition: v8.h:9796
PersistentValueReference(const PersistentValueReference &other)
Definition: v8-util.h:237
StdPersistentValueMap(Isolate *isolate)
Definition: v8-util.h:532
Local< V > Get(const K &key)
Definition: v8-util.h:177
V8_DEPRECATE_SOON("Used TracedGlobal and EmbedderHeapTracer::RegisterEmbedderReference", inline void RegisterExternallyReferencedObject(K &key))
bool IsEmpty() const
Definition: v8-util.h:615
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Definition: v8-util.h:420
Isolate * GetIsolate()
Definition: v8-util.h:162
void SetSecondPassCallback(Callback callback) const
Definition: v8.h:426
Global< V > Set(const K &key, Local< V > value)
Definition: v8-util.h:458
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition: v8-util.h:105
Impl::iterator Iterator
Definition: v8-util.h:42
V8_INLINE void Reset()
Definition: v8.h:9805
static PersistentContainerValue Value(Iterator it)
Definition: v8-util.h:50
size_t Size() const
Definition: v8-util.h:622
Traits::Impl * impl()
Definition: v8-util.h:295
static V8_INLINE Local< T > New(Isolate *isolate, Local< T > that)
Definition: v8.h:9697
void operator=(const PersistentValueReference &other)
Definition: v8-util.h:253
Local< V > NewLocal(Isolate *isolate) const
Definition: v8-util.h:240
void RemoveWeak(const K &key)
Definition: v8-util.h:326
static PersistentContainerValue Set(Impl *impl, K key, PersistentContainerValue value)
Definition: v8-util.h:51
static K KeyFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:130
PersistentValueMapBase(Isolate *isolate)
Definition: v8-util.h:287
std::map< K, PersistentContainerValue > Impl
Definition: v8-util.h:41
static void Swap(Impl &a, Impl &b)
Definition: v8-util.h:46
void Append(Local< V > value)
Definition: v8-util.h:600
GlobalValueMap(Isolate *isolate)
Definition: v8-util.h:444
Definition: v8.h:86
WeakCallbackType
Definition: v8.h:441
PersistentValueMap< K, V, DefaultPersistentValueMapTraits< K, V > > MapType
Definition: v8-util.h:90
void Append(Global< V > persistent)
Definition: v8-util.h:608
PersistentValueMap(Isolate *isolate, const char *label)
Definition: v8-util.h:370
Global< V > Set(const K &key, Global< V > value)
Definition: v8-util.h:466
static PersistentContainerValue Get(Impl *impl, K key)
Definition: v8-util.h:61
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition: v8-util.h:93
#define V(Name)
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition: v8-util.h:134