v8 11.3.244 (node 20.3.0)
V8 is Google's open source JavaScript engine
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_CONSERVATIVE_STACK_SCANNING
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(
244 isolate, internal::ValueHelper::SlotAsValue<V>(FromVal(value_)));
245 }
246 bool IsEmpty() const {
247 return value_ == kPersistentContainerNotFound;
248 }
249 template<typename T>
250 bool SetReturnValue(ReturnValue<T> returnValue) {
251 return SetReturnValueFromVal(&returnValue, value_);
252 }
253 void Reset() {
254 value_ = kPersistentContainerNotFound;
255 }
257 value_ = other.value_;
258 }
259
260 private:
262 friend class PersistentValueMap<K, V, Traits>;
263 friend class GlobalValueMap<K, V, Traits>;
264
266 : value_(value) { }
267
269 value_ = value;
270 }
271
273 };
274
286 return PersistentValueReference(Traits::Get(&impl_, key));
287 }
288
289 protected:
291 : isolate_(isolate), label_(nullptr) {}
293 : isolate_(isolate), label_(label) {}
294
296
297 Isolate* isolate() { return isolate_; }
298 typename Traits::Impl* impl() { return &impl_; }
299
301 return reinterpret_cast<V*>(v);
302 }
303
305 V* v = persistent->val_;
306 persistent->val_ = nullptr;
307 return reinterpret_cast<PersistentContainerValue>(v);
308 }
309
311 return reinterpret_cast<PersistentContainerValue>(persistent->val_);
312 }
313
320 Global<V> p;
321 p.val_ = FromVal(v);
322 if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
323 Traits::DisposeCallbackData(
324 p.template ClearWeak<typename Traits::WeakCallbackDataType>());
325 }
326 return p.Pass();
327 }
328
329 void RemoveWeak(const K& key) {
330 Global<V> p;
331 p.val_ = FromVal(Traits::Remove(&impl_, key));
332 p.Reset();
333 }
334
336 persistent->AnnotateStrongRetainer(label_);
337 }
338
339 private:
341 void operator=(PersistentValueMapBase&);
342
343 static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
345 bool hasValue = value != kPersistentContainerNotFound;
346 if (hasValue) {
347 returnValue->SetInternal(
348 *reinterpret_cast<internal::Address*>(FromVal(value)));
349 }
350 return hasValue;
351 }
352
353 Isolate* isolate_;
354 typename Traits::Impl impl_;
355 const char* label_;
356};
357
358template <typename K, typename V, typename Traits>
359class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
360 public:
362 : PersistentValueMapBase<K, V, Traits>(isolate) {}
363 PersistentValueMap(Isolate* isolate, const char* label)
364 : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
365
366 typedef
369
375 Global<V> Set(const K& key, Local<V> value) {
376 Global<V> persistent(this->isolate(), value);
377 return SetUnique(key, &persistent);
378 }
379
383 Global<V> Set(const K& key, Global<V> value) {
384 return SetUnique(key, &value);
385 }
386
391 Global<V> SetUnique(const K& key, Global<V>* persistent) {
392 if (Traits::kCallbackType == kNotWeak) {
393 this->AnnotateStrongRetainer(persistent);
394 } else {
395 WeakCallbackType callback_type =
396 Traits::kCallbackType == kWeakWithInternalFields
399 Local<V> value(Local<V>::New(this->isolate(), *persistent));
400 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
401 Traits::WeakCallbackParameter(this, key, value), WeakCallback,
402 callback_type);
403 }
404 PersistentContainerValue old_value =
405 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
406 return this->Release(old_value).Pass();
407 }
408
413 Global<V> Set(const K& key, Global<V> value,
414 PersistentValueReference* reference) {
415 *reference = this->Leak(&value);
416 return SetUnique(key, &value);
417 }
418
419 private:
420 static void WeakCallback(
422 if (Traits::kCallbackType != kNotWeak) {
423 PersistentValueMap<K, V, Traits>* persistentValueMap =
424 Traits::MapFromWeakCallbackInfo(data);
425 K key = Traits::KeyFromWeakCallbackInfo(data);
426 Traits::Dispose(data.GetIsolate(),
427 persistentValueMap->Remove(key).Pass(), key);
428 Traits::DisposeCallbackData(data.GetParameter());
429 }
430 }
431};
432
433
434template <typename K, typename V, typename Traits>
435class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
436 public:
438 : PersistentValueMapBase<K, V, Traits>(isolate) {}
439 GlobalValueMap(Isolate* isolate, const char* label)
440 : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
441
442 typedef
445
451 Global<V> Set(const K& key, Local<V> value) {
452 Global<V> persistent(this->isolate(), value);
453 return SetUnique(key, &persistent);
454 }
455
459 Global<V> Set(const K& key, Global<V> value) {
460 return SetUnique(key, &value);
461 }
462
467 Global<V> SetUnique(const K& key, Global<V>* persistent) {
468 if (Traits::kCallbackType == kNotWeak) {
469 this->AnnotateStrongRetainer(persistent);
470 } else {
471 WeakCallbackType callback_type =
472 Traits::kCallbackType == kWeakWithInternalFields
475 Local<V> value(Local<V>::New(this->isolate(), *persistent));
476 persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
477 Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
478 callback_type);
479 }
480 PersistentContainerValue old_value =
481 Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
482 return this->Release(old_value).Pass();
483 }
484
489 Global<V> Set(const K& key, Global<V> value,
490 PersistentValueReference* reference) {
491 *reference = this->Leak(&value);
492 return SetUnique(key, &value);
493 }
494
495 private:
496 static void OnWeakCallback(
498 if (Traits::kCallbackType != kNotWeak) {
499 auto map = Traits::MapFromWeakCallbackInfo(data);
500 K key = Traits::KeyFromWeakCallbackInfo(data);
501 map->RemoveWeak(key);
502 Traits::OnWeakCallback(data);
503 data.SetSecondPassCallback(SecondWeakCallback);
504 }
505 }
506
507 static void SecondWeakCallback(
508 const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
509 Traits::DisposeWeak(data);
510 }
511};
512
513
521template<typename K, typename V,
522 typename Traits = DefaultPersistentValueMapTraits<K, V> >
523class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
524 public:
526 : PersistentValueMap<K, V, Traits>(isolate) {}
527};
528
529
537template <typename K, typename V,
538 typename Traits = DefaultGlobalMapTraits<K, V> >
539class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
540 public:
542 : GlobalValueMap<K, V, Traits>(isolate) {}
543};
544
546 public:
547 typedef std::vector<PersistentContainerValue> Impl;
548
549 static void Append(Impl* impl, PersistentContainerValue value) {
550 impl->push_back(value);
551 }
552 static bool IsEmpty(const Impl* impl) {
553 return impl->empty();
554 }
555 static size_t Size(const Impl* impl) {
556 return impl->size();
557 }
558 static PersistentContainerValue Get(const Impl* impl, size_t i) {
559 return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
560 }
561 static void ReserveCapacity(Impl* impl, size_t capacity) {
562 impl->reserve(capacity);
563 }
564 static void Clear(Impl* impl) {
565 impl->clear();
566 }
567};
568
579template <typename V, typename Traits = DefaultPersistentValueVectorTraits>
580class V8_DEPRECATE_SOON("Use std::vector<Global<V>>.") PersistentValueVector {
581 public:
582 explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
583
584 ~PersistentValueVector() {
585 Clear();
586 }
587
591 void Append(Local<V> value) {
592 Global<V> persistent(isolate_, value);
593 Traits::Append(&impl_, ClearAndLeak(&persistent));
594 }
595
599 void Append(Global<V> persistent) {
600 Traits::Append(&impl_, ClearAndLeak(&persistent));
601 }
602
606 bool IsEmpty() const {
607 return Traits::IsEmpty(&impl_);
608 }
609
613 size_t Size() const {
614 return Traits::Size(&impl_);
615 }
616
620 Local<V> Get(size_t index) const {
621 return Local<V>::New(isolate_, internal::ValueHelper::SlotAsValue<V>(
622 FromVal(Traits::Get(&impl_, index))));
623 }
624
628 void Clear() {
629 size_t length = Traits::Size(&impl_);
630 for (size_t i = 0; i < length; i++) {
631 Global<V> p;
632 p.val_ = FromVal(Traits::Get(&impl_, i));
633 }
634 Traits::Clear(&impl_);
635 }
636
641 void ReserveCapacity(size_t capacity) {
642 Traits::ReserveCapacity(&impl_, capacity);
643 }
644
645 private:
646 static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
647 V* v = persistent->val_;
648 persistent->val_ = nullptr;
649 return reinterpret_cast<PersistentContainerValue>(v);
650 }
651
652 static V* FromVal(PersistentContainerValue v) {
653 return reinterpret_cast<V*>(v);
654 }
655
656 Isolate* isolate_;
657 typename Traits::Impl impl_;
658};
659
660} // namespace v8
661
662#endif // V8_UTIL_H
static const PersistentContainerCallbackType kCallbackType
Definition v8-util.h:124
static void Dispose(Isolate *isolate, Global< V > value, K key)
Definition v8-util.h:143
static void DisposeWeak(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition v8-util.h:145
static void OnWeakCallback(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition v8-util.h:141
GlobalValueMap< K, V, DefaultGlobalMapTraits< K, V > > MapType
Definition v8-util.h:125
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition v8-util.h:140
static MapType * MapFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition v8-util.h:132
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition v8-util.h:128
static K KeyFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition v8-util.h:136
static const PersistentContainerCallbackType kCallbackType
Definition v8-util.h:94
static void Dispose(Isolate *isolate, Global< V > value, K key)
Definition v8-util.h:112
PersistentValueMap< K, V, DefaultPersistentValueMapTraits< K, V > > MapType
Definition v8-util.h:96
static void DisposeCallbackData(WeakCallbackDataType *data)
Definition v8-util.h:111
static MapType * MapFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition v8-util.h:103
static WeakCallbackDataType * WeakCallbackParameter(MapType *map, const K &key, Local< V > value)
Definition v8-util.h:99
static K KeyFromWeakCallbackInfo(const WeakCallbackInfo< WeakCallbackDataType > &data)
Definition v8-util.h:107
static void ReserveCapacity(Impl *impl, size_t capacity)
Definition v8-util.h:561
static bool IsEmpty(const Impl *impl)
Definition v8-util.h:552
static PersistentContainerValue Get(const Impl *impl, size_t i)
Definition v8-util.h:558
static size_t Size(const Impl *impl)
Definition v8-util.h:555
static void Append(Impl *impl, PersistentContainerValue value)
Definition v8-util.h:549
static void Clear(Impl *impl)
Definition v8-util.h:564
std::vector< PersistentContainerValue > Impl
Definition v8-util.h:547
GlobalValueMap(Isolate *isolate)
Definition v8-util.h:437
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Definition v8-util.h:489
Global< V > Set(const K &key, Local< V > value)
Definition v8-util.h:451
GlobalValueMap(Isolate *isolate, const char *label)
Definition v8-util.h:439
Global< V > Set(const K &key, Global< V > value)
Definition v8-util.h:459
PersistentValueMapBase< K, V, Traits >::PersistentValueReference PersistentValueReference
Definition v8-util.h:444
Global< V > SetUnique(const K &key, Global< V > *persistent)
Definition v8-util.h:467
static V8_INLINE Local< T > New(Isolate *isolate, Local< T > that)
V8_INLINE bool IsWeak() const
V8_INLINE void AnnotateStrongRetainer(const char *label)
Local< V > NewLocal(Isolate *isolate) const
Definition v8-util.h:242
bool SetReturnValue(ReturnValue< T > returnValue)
Definition v8-util.h:250
void operator=(const PersistentValueReference &other)
Definition v8-util.h:256
PersistentValueReference(const PersistentValueReference &other)
Definition v8-util.h:239
static Global< V > Release(PersistentContainerValue v)
Definition v8-util.h:319
static PersistentContainerValue Leak(Global< V > *persistent)
Definition v8-util.h:310
Global< V > Remove(const K &key)
Definition v8-util.h:210
PersistentValueMapBase(Isolate *isolate, const char *label)
Definition v8-util.h:292
bool SetReturnValue(const K &key, ReturnValue< Value > returnValue)
Definition v8-util.h:202
void RemoveWeak(const K &key)
Definition v8-util.h:329
static V * FromVal(PersistentContainerValue v)
Definition v8-util.h:300
PersistentValueReference GetReference(const K &key)
Definition v8-util.h:285
bool Contains(const K &key)
Definition v8-util.h:194
static PersistentContainerValue ClearAndLeak(Global< V > *persistent)
Definition v8-util.h:304
PersistentValueMapBase(Isolate *isolate)
Definition v8-util.h:290
Traits::Impl * impl()
Definition v8-util.h:298
void AnnotateStrongRetainer(Global< V > *persistent)
Definition v8-util.h:335
Local< V > Get(const K &key)
Definition v8-util.h:183
Global< V > Set(const K &key, Global< V > value, PersistentValueReference *reference)
Definition v8-util.h:413
Global< V > Set(const K &key, Local< V > value)
Definition v8-util.h:375
PersistentValueMap(Isolate *isolate, const char *label)
Definition v8-util.h:363
PersistentValueMap(Isolate *isolate)
Definition v8-util.h:361
Global< V > Set(const K &key, Global< V > value)
Definition v8-util.h:383
PersistentValueMapBase< K, V, Traits >::PersistentValueReference PersistentValueReference
Definition v8-util.h:368
Global< V > SetUnique(const K &key, Global< V > *persistent)
Definition v8-util.h:391
StdGlobalValueMap(Isolate *isolate)
Definition v8-util.h:541
Impl::iterator Iterator
Definition v8-util.h:48
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 PersistentContainerValue Value(Iterator it)
Definition v8-util.h:56
static void Swap(Impl &a, Impl &b)
Definition v8-util.h:52
static K Key(Iterator it)
Definition v8-util.h:55
static PersistentContainerValue Remove(Impl *impl, K key)
Definition v8-util.h:72
static PersistentContainerValue Get(Impl *impl, K key)
Definition v8-util.h:67
static size_t Size(Impl *impl)
Definition v8-util.h:51
static bool Empty(Impl *impl)
Definition v8-util.h:50
std::map< K, PersistentContainerValue > Impl
Definition v8-util.h:47
static Iterator Begin(Impl *impl)
Definition v8-util.h:53
StdPersistentValueMap(Isolate *isolate)
Definition v8-util.h:525
V8_INLINE T * GetParameter() const
void SetSecondPassCallback(Callback callback) const
V8_INLINE Isolate * GetIsolate() const
uintptr_t Address
Definition v8-internal.h:29
PersistentContainerCallbackType
Definition v8-util.h:30
@ kWeakWithInternalFields
Definition v8-util.h:34
@ kNotWeak
Definition v8-util.h:31
@ kWeakWithParameter
Definition v8-util.h:33
uintptr_t PersistentContainerValue
Definition v8-util.h:28
#define V(Name)
#define V8_DEPRECATE_SOON(message)
Definition v8config.h:552