v8  7.0.276(node11.14.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  kWeak = kWeakWithParameter // For backwards compatibility. Deprecate.
30 };
31 
32 
39 template<typename K, typename V>
40 class StdMapTraits {
41  public:
42  // STL map & related:
43  typedef std::map<K, PersistentContainerValue> Impl;
44  typedef typename Impl::iterator Iterator;
45 
46  static bool Empty(Impl* impl) { return impl->empty(); }
47  static size_t Size(Impl* impl) { return impl->size(); }
48  static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
49  static Iterator Begin(Impl* impl) { return impl->begin(); }
50  static Iterator End(Impl* impl) { return impl->end(); }
51  static K Key(Iterator it) { return it->first; }
52  static PersistentContainerValue Value(Iterator it) { return it->second; }
53  static PersistentContainerValue Set(Impl* impl, K key,
55  std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
56  PersistentContainerValue old_value = kPersistentContainerNotFound;
57  if (!res.second) {
58  old_value = res.first->second;
59  res.first->second = value;
60  }
61  return old_value;
62  }
63  static PersistentContainerValue Get(Impl* impl, K key) {
64  Iterator it = impl->find(key);
65  if (it == impl->end()) return kPersistentContainerNotFound;
66  return it->second;
67  }
68  static PersistentContainerValue Remove(Impl* impl, K key) {
69  Iterator it = impl->find(key);
70  if (it == impl->end()) return kPersistentContainerNotFound;
71  PersistentContainerValue value = it->second;
72  impl->erase(it);
73  return value;
74  }
75 };
76 
77 
86 template<typename K, typename V>
88  public:
89  // Weak callback & friends:
93  typedef void WeakCallbackDataType;
94 
96  MapType* map, const K& key, Local<V> value) {
97  return NULL;
98  }
101  return NULL;
102  }
105  return K();
106  }
108  static void Dispose(Isolate* isolate, Global<V> value, K key) {}
109 };
110 
111 
112 template <typename K, typename V>
113 class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
114  private:
115  template <typename T>
116  struct RemovePointer;
117 
118  public:
119  // Weak callback & friends:
122  typedef void WeakCallbackDataType;
123 
125  Local<V> value) {
126  return nullptr;
127  }
130  return nullptr;
131  }
134  return K();
135  }
137  static void OnWeakCallback(
139  static void Dispose(Isolate* isolate, Global<V> value, K key) {}
140  // This is a second pass callback, so SetSecondPassCallback cannot be called.
142 
143  private:
144  template <typename T>
145  struct RemovePointer<T*> {
146  typedef T Type;
147  };
148 };
149 
150 
161 template <typename K, typename V, typename Traits>
163  public:
164  Isolate* GetIsolate() { return isolate_; }
165 
169  size_t Size() { return Traits::Size(&impl_); }
170 
174  bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
175 
179  Local<V> Get(const K& key) {
180  return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
181  }
182 
186  bool Contains(const K& key) {
187  return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
188  }
189 
194  bool SetReturnValue(const K& key,
195  ReturnValue<Value> returnValue) {
196  return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
197  }
198 
204  assert(Contains(key));
205  V8::RegisterExternallyReferencedObject(
206  reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))),
207  reinterpret_cast<internal::Isolate*>(GetIsolate()));
208  }
209 
213  Global<V> Remove(const K& key) {
214  return Release(Traits::Remove(&impl_, key)).Pass();
215  }
216 
221  void Clear() {
222  typedef typename Traits::Iterator It;
223  HandleScope handle_scope(isolate_);
224  // TODO(dcarney): figure out if this swap and loop is necessary.
225  while (!Traits::Empty(&impl_)) {
226  typename Traits::Impl impl;
227  Traits::Swap(impl_, impl);
228  for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
229  Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
230  Traits::Key(i));
231  }
232  }
233  }
234 
240  public:
241  PersistentValueReference() : value_(kPersistentContainerNotFound) { }
243  : value_(other.value_) { }
244 
245  Local<V> NewLocal(Isolate* isolate) const {
246  return Local<V>::New(isolate, FromVal(value_));
247  }
248  bool IsEmpty() const {
249  return value_ == kPersistentContainerNotFound;
250  }
251  template<typename T>
252  bool SetReturnValue(ReturnValue<T> returnValue) {
253  return SetReturnValueFromVal(&returnValue, value_);
254  }
255  void Reset() {
256  value_ = kPersistentContainerNotFound;
257  }
258  void operator=(const PersistentValueReference& other) {
259  value_ = other.value_;
260  }
261 
262  private:
264  friend class PersistentValueMap<K, V, Traits>;
265  friend class GlobalValueMap<K, V, Traits>;
266 
268  : value_(value) { }
269 
270  void operator=(PersistentContainerValue value) {
271  value_ = value;
272  }
273 
275  };
276 
288  return PersistentValueReference(Traits::Get(&impl_, key));
289  }
290 
291  protected:
292  explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {}
293 
295 
296  Isolate* isolate() { return isolate_; }
297  typename Traits::Impl* impl() { return &impl_; }
298 
300  return reinterpret_cast<V*>(v);
301  }
302 
304  V* v = persistent->val_;
305  persistent->val_ = 0;
306  return reinterpret_cast<PersistentContainerValue>(v);
307  }
308 
310  return reinterpret_cast<PersistentContainerValue>(persistent->val_);
311  }
312 
319  Global<V> p;
320  p.val_ = FromVal(v);
321  if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
322  Traits::DisposeCallbackData(
323  p.template ClearWeak<typename Traits::WeakCallbackDataType>());
324  }
325  return p.Pass();
326  }
327 
328  void RemoveWeak(const K& key) {
329  Global<V> p;
330  p.val_ = FromVal(Traits::Remove(&impl_, key));
331  p.Reset();
332  }
333 
334  private:
336  void operator=(PersistentValueMapBase&);
337 
338  static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
339  PersistentContainerValue value) {
340  bool hasValue = value != kPersistentContainerNotFound;
341  if (hasValue) {
342  returnValue->SetInternal(
343  *reinterpret_cast<internal::Object**>(FromVal(value)));
344  }
345  return hasValue;
346  }
347 
348  Isolate* isolate_;
349  typename Traits::Impl impl_;
350 };
351 
352 
353 template <typename K, typename V, typename Traits>
354 class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
355  public:
356  explicit PersistentValueMap(Isolate* isolate)
357  : PersistentValueMapBase<K, V, Traits>(isolate) {}
358 
359  typedef
362 
368  Global<V> Set(const K& key, Local<V> value) {
369  Global<V> persistent(this->isolate(), value);
370  return SetUnique(key, &persistent);
371  }
372 
376  Global<V> Set(const K& key, Global<V> value) {
377  return SetUnique(key, &value);
378  }
379 
384  Global<V> SetUnique(const K& key, Global<V>* persistent) {
385  if (Traits::kCallbackType != kNotWeak) {
386  WeakCallbackType callback_type =
387  Traits::kCallbackType == kWeakWithInternalFields
390  Local<V> value(Local<V>::New(this->isolate(), *persistent));
391  persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
392  Traits::WeakCallbackParameter(this, key, value), WeakCallback,
393  callback_type);
394  }
395  PersistentContainerValue old_value =
396  Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
397  return this->Release(old_value).Pass();
398  }
399 
404  Global<V> Set(const K& key, Global<V> value,
405  PersistentValueReference* reference) {
406  *reference = this->Leak(&value);
407  return SetUnique(key, &value);
408  }
409 
410  private:
411  static void WeakCallback(
413  if (Traits::kCallbackType != kNotWeak) {
414  PersistentValueMap<K, V, Traits>* persistentValueMap =
415  Traits::MapFromWeakCallbackInfo(data);
416  K key = Traits::KeyFromWeakCallbackInfo(data);
417  Traits::Dispose(data.GetIsolate(),
418  persistentValueMap->Remove(key).Pass(), key);
419  Traits::DisposeCallbackData(data.GetParameter());
420  }
421  }
422 };
423 
424 
425 template <typename K, typename V, typename Traits>
426 class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
427  public:
428  explicit GlobalValueMap(Isolate* isolate)
429  : PersistentValueMapBase<K, V, Traits>(isolate) {}
430 
431  typedef
434 
440  Global<V> Set(const K& key, Local<V> value) {
441  Global<V> persistent(this->isolate(), value);
442  return SetUnique(key, &persistent);
443  }
444 
448  Global<V> Set(const K& key, Global<V> value) {
449  return SetUnique(key, &value);
450  }
451 
456  Global<V> SetUnique(const K& key, Global<V>* persistent) {
457  if (Traits::kCallbackType != kNotWeak) {
458  WeakCallbackType callback_type =
459  Traits::kCallbackType == kWeakWithInternalFields
462  Local<V> value(Local<V>::New(this->isolate(), *persistent));
463  persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
464  Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
465  callback_type);
466  }
467  PersistentContainerValue old_value =
468  Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
469  return this->Release(old_value).Pass();
470  }
471 
476  Global<V> Set(const K& key, Global<V> value,
477  PersistentValueReference* reference) {
478  *reference = this->Leak(&value);
479  return SetUnique(key, &value);
480  }
481 
482  private:
483  static void OnWeakCallback(
485  if (Traits::kCallbackType != kNotWeak) {
486  auto map = Traits::MapFromWeakCallbackInfo(data);
487  K key = Traits::KeyFromWeakCallbackInfo(data);
488  map->RemoveWeak(key);
489  Traits::OnWeakCallback(data);
490  data.SetSecondPassCallback(SecondWeakCallback);
491  }
492  }
493 
494  static void SecondWeakCallback(
495  const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
496  Traits::DisposeWeak(data);
497  }
498 };
499 
500 
508 template<typename K, typename V,
509  typename Traits = DefaultPersistentValueMapTraits<K, V> >
510 class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
511  public:
512  explicit StdPersistentValueMap(Isolate* isolate)
513  : PersistentValueMap<K, V, Traits>(isolate) {}
514 };
515 
516 
524 template <typename K, typename V,
525  typename Traits = DefaultGlobalMapTraits<K, V> >
526 class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
527  public:
528  explicit StdGlobalValueMap(Isolate* isolate)
529  : GlobalValueMap<K, V, Traits>(isolate) {}
530 };
531 
532 
534  public:
535  typedef std::vector<PersistentContainerValue> Impl;
536 
537  static void Append(Impl* impl, PersistentContainerValue value) {
538  impl->push_back(value);
539  }
540  static bool IsEmpty(const Impl* impl) {
541  return impl->empty();
542  }
543  static size_t Size(const Impl* impl) {
544  return impl->size();
545  }
546  static PersistentContainerValue Get(const Impl* impl, size_t i) {
547  return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
548  }
549  static void ReserveCapacity(Impl* impl, size_t capacity) {
550  impl->reserve(capacity);
551  }
552  static void Clear(Impl* impl) {
553  impl->clear();
554  }
555 };
556 
557 
568 template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
570  public:
571  explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
572 
574  Clear();
575  }
576 
580  void Append(Local<V> value) {
581  Global<V> persistent(isolate_, value);
582  Traits::Append(&impl_, ClearAndLeak(&persistent));
583  }
584 
588  void Append(Global<V> persistent) {
589  Traits::Append(&impl_, ClearAndLeak(&persistent));
590  }
591 
595  bool IsEmpty() const {
596  return Traits::IsEmpty(&impl_);
597  }
598 
602  size_t Size() const {
603  return Traits::Size(&impl_);
604  }
605 
609  Local<V> Get(size_t index) const {
610  return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
611  }
612 
616  void Clear() {
617  size_t length = Traits::Size(&impl_);
618  for (size_t i = 0; i < length; i++) {
619  Global<V> p;
620  p.val_ = FromVal(Traits::Get(&impl_, i));
621  }
622  Traits::Clear(&impl_);
623  }
624 
629  void ReserveCapacity(size_t capacity) {
630  Traits::ReserveCapacity(&impl_, capacity);
631  }
632 
633  private:
634  static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
635  V* v = persistent->val_;
636  persistent->val_ = 0;
637  return reinterpret_cast<PersistentContainerValue>(v);
638  }
639 
640  static V* FromVal(PersistentContainerValue v) {
641  return reinterpret_cast<V*>(v);
642  }
643 
644  Isolate* isolate_;
645  typename Traits::Impl impl_;
646 };
647 
648 } // namespace v8
649 
650 #endif // V8_UTIL_H
static MapType * MapFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:99
Global< V > Set(const K &key, Global< V > value)
Definition: v8-util.h:376
Definition: v8.h:123
static void Clear(Impl *impl)
Definition: v8-util.h:552
PersistentValueVector(Isolate *isolate)
Definition: v8-util.h:571
static MapType * MapFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:128
static size_t Size(const Impl *impl)
Definition: v8-util.h:543
Global< V > SetUnique(const K &key, Global< V > *persistent)
Definition: v8-util.h:384
const char * data() const
Definition: v8.h:6303
static void OnWeakCallback(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:137
Global< V > Set(const K &key, Local< V > value)
Definition: v8-util.h:368
StdGlobalValueMap(Isolate *isolate)
Definition: v8-util.h:528
static PersistentContainerValue Remove(Impl *impl, K key)
Definition: v8-util.h:68
static PersistentContainerValue Leak(Global< V > *persistent)
Definition: v8-util.h:309
static PersistentContainerValue ClearAndLeak(Global< V > *persistent)
Definition: v8-util.h:303
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Definition: v8-util.h:476
Global< V > SetUnique(const K &key, Global< V > *persistent)
Definition: v8-util.h:456
PersistentValueReference GetReference(const K &key)
Definition: v8-util.h:287
static size_t Size(Impl *impl)
Definition: v8-util.h:47
static bool IsEmpty(const Impl *impl)
Definition: v8-util.h:540
static const PersistentContainerCallbackType kCallbackType
Definition: v8-util.h:90
static void Append(Impl *impl, PersistentContainerValue value)
Definition: v8-util.h:537
void ReserveCapacity(size_t capacity)
Definition: v8-util.h:629
std::vector< PersistentContainerValue > Impl
Definition: v8-util.h:535
static void ReserveCapacity(Impl *impl, size_t capacity)
Definition: v8-util.h:549
static void DisposeWeak(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:141
static V * FromVal(PersistentContainerValue v)
Definition: v8-util.h:299
PersistentValueMapBase< K, V, Traits >::PersistentValueReference PersistentValueReference
Definition: v8-util.h:433
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition: v8-util.h:124
static void Dispose(Isolate *isolate, Global< V > value, K key)
Definition: v8-util.h:108
Global< V > Remove(const K &key)
Definition: v8-util.h:213
static Global< V > Release(PersistentContainerValue v)
Definition: v8-util.h:318
bool Contains(const K &key)
Definition: v8-util.h:186
PersistentValueMap(Isolate *isolate)
Definition: v8-util.h:356
GlobalValueMap< K, V, DefaultGlobalMapTraits< K, V > > MapType
Definition: v8-util.h:121
PersistentContainerCallbackType
Definition: v8-util.h:24
static bool Empty(Impl *impl)
Definition: v8-util.h:46
static PersistentContainerValue Get(const Impl *impl, size_t i)
Definition: v8-util.h:546
uintptr_t PersistentContainerValue
Definition: v8-util.h:22
void RegisterExternallyReferencedObject(K &key)
Definition: v8-util.h:203
Definition: libplatform.h:13
static const PersistentContainerCallbackType kCallbackType
Definition: v8-util.h:120
static K KeyFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:103
static K Key(Iterator it)
Definition: v8-util.h:51
bool SetReturnValue(ReturnValue< T > returnValue)
Definition: v8-util.h:252
static Iterator Begin(Impl *impl)
Definition: v8-util.h:49
static Iterator End(Impl *impl)
Definition: v8-util.h:50
bool SetReturnValue(const K &key, ReturnValue< Value > returnValue)
Definition: v8-util.h:194
static void Dispose(Isolate *isolate, Global< V > value, K key)
Definition: v8-util.h:139
Local< V > Get(size_t index) const
Definition: v8-util.h:609
PersistentValueMapBase< K, V, Traits >::PersistentValueReference PersistentValueReference
Definition: v8-util.h:361
Global Pass()
Definition: v8.h:927
V8_INLINE bool IsWeak() const
Definition: v8.h:9640
PersistentValueReference(const PersistentValueReference &other)
Definition: v8-util.h:242
StdPersistentValueMap(Isolate *isolate)
Definition: v8-util.h:512
Local< V > Get(const K &key)
Definition: v8-util.h:179
bool IsEmpty() const
Definition: v8-util.h:595
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Definition: v8-util.h:404
Isolate * GetIsolate()
Definition: v8-util.h:164
Global< V > Set(const K &key, Local< V > value)
Definition: v8-util.h:440
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition: v8-util.h:107
Impl::iterator Iterator
Definition: v8-util.h:44
V8_INLINE void Reset()
Definition: v8.h:9649
static PersistentContainerValue Value(Iterator it)
Definition: v8-util.h:52
size_t Size() const
Definition: v8-util.h:602
Traits::Impl * impl()
Definition: v8-util.h:297
static V8_INLINE Local< T > New(Isolate *isolate, Local< T > that)
Definition: v8.h:9545
void operator=(const PersistentValueReference &other)
Definition: v8-util.h:258
Local< V > NewLocal(Isolate *isolate) const
Definition: v8-util.h:245
void RemoveWeak(const K &key)
Definition: v8-util.h:328
static PersistentContainerValue Set(Impl *impl, K key, PersistentContainerValue value)
Definition: v8-util.h:53
static K KeyFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition: v8-util.h:132
PersistentValueMapBase(Isolate *isolate)
Definition: v8-util.h:292
std::map< K, PersistentContainerValue > Impl
Definition: v8-util.h:43
static void Swap(Impl &a, Impl &b)
Definition: v8-util.h:48
void Append(Local< V > value)
Definition: v8-util.h:580
GlobalValueMap(Isolate *isolate)
Definition: v8-util.h:428
Definition: v8.h:114
WeakCallbackType
Definition: v8.h:559
PersistentValueMap< K, V, DefaultPersistentValueMapTraits< K, V > > MapType
Definition: v8-util.h:92
void Append(Global< V > persistent)
Definition: v8-util.h:588
Global< V > Set(const K &key, Global< V > value)
Definition: v8-util.h:448
static PersistentContainerValue Get(Impl *impl, K key)
Definition: v8-util.h:63
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition: v8-util.h:95
#define V(Name)
size_t length() const
Definition: v8.h:6304
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition: v8-util.h:136