libv8 7.3.492.27.1-universal-darwin17

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,48 @@
1
+ // Copyright 2010 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_V8_TEST_H_
6
+ #define V8_V8_TEST_H_
7
+
8
+ #include "v8.h" // NOLINT(build/include)
9
+
10
+ /**
11
+ * Testing support for the V8 JavaScript engine.
12
+ */
13
+ namespace v8 {
14
+
15
+ class V8_EXPORT Testing {
16
+ public:
17
+ enum StressType {
18
+ kStressTypeOpt,
19
+ kStressTypeDeopt
20
+ };
21
+
22
+ /**
23
+ * Set the type of stressing to do. The default if not set is kStressTypeOpt.
24
+ */
25
+ static void SetStressRunType(StressType type);
26
+
27
+ /**
28
+ * Get the number of runs of a given test that is required to get the full
29
+ * stress coverage.
30
+ */
31
+ static int GetStressRuns();
32
+
33
+ /**
34
+ * Indicate the number of the run which is about to start. The value of run
35
+ * should be between 0 and one less than the result from GetStressRuns()
36
+ */
37
+ static void PrepareStressRun(int run);
38
+
39
+ /**
40
+ * Force deoptimization of all functions.
41
+ */
42
+ static void DeoptimizeAll(Isolate* isolate);
43
+ };
44
+
45
+
46
+ } // namespace v8
47
+
48
+ #endif // V8_V8_TEST_H_
@@ -0,0 +1,664 @@
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
+
13
+ /**
14
+ * Support for Persistent containers.
15
+ *
16
+ * C++11 embedders can use STL containers with Global values,
17
+ * but pre-C++11 does not support the required move semantic and hence
18
+ * may want these container classes.
19
+ */
20
+ namespace v8 {
21
+
22
+ typedef uintptr_t PersistentContainerValue;
23
+ static const uintptr_t kPersistentContainerNotFound = 0;
24
+ enum PersistentContainerCallbackType {
25
+ kNotWeak,
26
+ // These correspond to v8::WeakCallbackType
27
+ kWeakWithParameter,
28
+ kWeakWithInternalFields
29
+ };
30
+
31
+ /**
32
+ * A default trait implementation for PersistentValueMap which uses std::map
33
+ * as a backing map.
34
+ *
35
+ * Users will have to implement their own weak callbacks & dispose traits.
36
+ */
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,
52
+ PersistentContainerValue value) {
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
+
76
+ /**
77
+ * A default trait implementation for PersistentValueMap, which inherits
78
+ * a std:map backing map from StdMapTraits and holds non-weak persistent
79
+ * objects and has no special Dispose handling.
80
+ *
81
+ * You should not derive from this class, since MapType depends on the
82
+ * surrounding class, and hence a subclass cannot simply inherit the methods.
83
+ */
84
+ template<typename K, typename V>
85
+ class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
86
+ public:
87
+ // Weak callback & friends:
88
+ static const PersistentContainerCallbackType kCallbackType = kNotWeak;
89
+ typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
90
+ MapType;
91
+ typedef void WeakCallbackDataType;
92
+
93
+ static WeakCallbackDataType* WeakCallbackParameter(
94
+ MapType* map, const K& key, Local<V> value) {
95
+ return nullptr;
96
+ }
97
+ static MapType* MapFromWeakCallbackInfo(
98
+ const WeakCallbackInfo<WeakCallbackDataType>& data) {
99
+ return nullptr;
100
+ }
101
+ static K KeyFromWeakCallbackInfo(
102
+ const WeakCallbackInfo<WeakCallbackDataType>& data) {
103
+ return K();
104
+ }
105
+ static void DisposeCallbackData(WeakCallbackDataType* data) { }
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:
118
+ static const PersistentContainerCallbackType kCallbackType = kNotWeak;
119
+ typedef GlobalValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
120
+ typedef void WeakCallbackDataType;
121
+
122
+ static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
123
+ Local<V> value) {
124
+ return nullptr;
125
+ }
126
+ static MapType* MapFromWeakCallbackInfo(
127
+ const WeakCallbackInfo<WeakCallbackDataType>& data) {
128
+ return nullptr;
129
+ }
130
+ static K KeyFromWeakCallbackInfo(
131
+ const WeakCallbackInfo<WeakCallbackDataType>& data) {
132
+ return K();
133
+ }
134
+ static void DisposeCallbackData(WeakCallbackDataType* data) {}
135
+ static void OnWeakCallback(
136
+ const WeakCallbackInfo<WeakCallbackDataType>& data) {}
137
+ static void Dispose(Isolate* isolate, Global<V> value, K key) {}
138
+ // This is a second pass callback, so SetSecondPassCallback cannot be called.
139
+ static void DisposeWeak(const WeakCallbackInfo<WeakCallbackDataType>& data) {}
140
+
141
+ private:
142
+ template <typename T>
143
+ struct RemovePointer<T*> {
144
+ typedef T Type;
145
+ };
146
+ };
147
+
148
+
149
+ /**
150
+ * A map wrapper that allows using Global as a mapped value.
151
+ * C++11 embedders don't need this class, as they can use Global
152
+ * directly in std containers.
153
+ *
154
+ * The map relies on a backing map, whose type and accessors are described
155
+ * by the Traits class. The backing map will handle values of type
156
+ * PersistentContainerValue, with all conversion into and out of V8
157
+ * handles being transparently handled by this class.
158
+ */
159
+ template <typename K, typename V, typename Traits>
160
+ class PersistentValueMapBase {
161
+ public:
162
+ Isolate* GetIsolate() { return isolate_; }
163
+
164
+ /**
165
+ * Return size of the map.
166
+ */
167
+ size_t Size() { return Traits::Size(&impl_); }
168
+
169
+ /**
170
+ * Return whether the map holds weak persistents.
171
+ */
172
+ bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
173
+
174
+ /**
175
+ * Get value stored in map.
176
+ */
177
+ Local<V> Get(const K& key) {
178
+ return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
179
+ }
180
+
181
+ /**
182
+ * Check whether a value is contained in the map.
183
+ */
184
+ bool Contains(const K& key) {
185
+ return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
186
+ }
187
+
188
+ /**
189
+ * Get value stored in map and set it in returnValue.
190
+ * Return true if a value was found.
191
+ */
192
+ bool SetReturnValue(const K& key,
193
+ ReturnValue<Value> returnValue) {
194
+ return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
195
+ }
196
+
197
+ /**
198
+ * Call V8::RegisterExternallyReferencedObject with the map value for given
199
+ * key.
200
+ */
201
+ void RegisterExternallyReferencedObject(K& key) {
202
+ assert(Contains(key));
203
+ V8::RegisterExternallyReferencedObject(
204
+ reinterpret_cast<internal::Address*>(FromVal(Traits::Get(&impl_, key))),
205
+ reinterpret_cast<internal::Isolate*>(GetIsolate()));
206
+ }
207
+
208
+ /**
209
+ * Return value for key and remove it from the map.
210
+ */
211
+ Global<V> Remove(const K& key) {
212
+ return Release(Traits::Remove(&impl_, key)).Pass();
213
+ }
214
+
215
+ /**
216
+ * Traverses the map repeatedly,
217
+ * in case side effects of disposal cause insertions.
218
+ **/
219
+ void Clear() {
220
+ typedef typename Traits::Iterator It;
221
+ HandleScope handle_scope(isolate_);
222
+ // TODO(dcarney): figure out if this swap and loop is necessary.
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(),
228
+ Traits::Key(i));
229
+ }
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Helper class for GetReference/SetWithReference. Do not use outside
235
+ * that context.
236
+ */
237
+ class PersistentValueReference {
238
+ public:
239
+ PersistentValueReference() : value_(kPersistentContainerNotFound) { }
240
+ PersistentValueReference(const PersistentValueReference& other)
241
+ : value_(other.value_) { }
242
+
243
+ Local<V> NewLocal(Isolate* isolate) const {
244
+ return Local<V>::New(isolate, 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
+ }
256
+ void operator=(const PersistentValueReference& other) {
257
+ value_ = other.value_;
258
+ }
259
+
260
+ private:
261
+ friend class PersistentValueMapBase;
262
+ friend class PersistentValueMap<K, V, Traits>;
263
+ friend class GlobalValueMap<K, V, Traits>;
264
+
265
+ explicit PersistentValueReference(PersistentContainerValue value)
266
+ : value_(value) { }
267
+
268
+ void operator=(PersistentContainerValue value) {
269
+ value_ = value;
270
+ }
271
+
272
+ PersistentContainerValue value_;
273
+ };
274
+
275
+ /**
276
+ * Get a reference to a map value. This enables fast, repeated access
277
+ * to a value stored in the map while the map remains unchanged.
278
+ *
279
+ * Careful: This is potentially unsafe, so please use with care.
280
+ * The value will become invalid if the value for this key changes
281
+ * in the underlying map, as a result of Set or Remove for the same
282
+ * key; as a result of the weak callback for the same key; or as a
283
+ * result of calling Clear() or destruction of the map.
284
+ */
285
+ PersistentValueReference GetReference(const K& key) {
286
+ return PersistentValueReference(Traits::Get(&impl_, key));
287
+ }
288
+
289
+ protected:
290
+ explicit PersistentValueMapBase(Isolate* isolate)
291
+ : isolate_(isolate), label_(nullptr) {}
292
+ PersistentValueMapBase(Isolate* isolate, const char* label)
293
+ : isolate_(isolate), label_(label) {}
294
+
295
+ ~PersistentValueMapBase() { Clear(); }
296
+
297
+ Isolate* isolate() { return isolate_; }
298
+ typename Traits::Impl* impl() { return &impl_; }
299
+
300
+ static V* FromVal(PersistentContainerValue v) {
301
+ return reinterpret_cast<V*>(v);
302
+ }
303
+
304
+ static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
305
+ V* v = persistent->val_;
306
+ persistent->val_ = nullptr;
307
+ return reinterpret_cast<PersistentContainerValue>(v);
308
+ }
309
+
310
+ static PersistentContainerValue Leak(Global<V>* persistent) {
311
+ return reinterpret_cast<PersistentContainerValue>(persistent->val_);
312
+ }
313
+
314
+ /**
315
+ * Return a container value as Global and make sure the weak
316
+ * callback is properly disposed of. All remove functionality should go
317
+ * through this.
318
+ */
319
+ static Global<V> Release(PersistentContainerValue v) {
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
+
335
+ void AnnotateStrongRetainer(Global<V>* persistent) {
336
+ persistent->AnnotateStrongRetainer(label_);
337
+ }
338
+
339
+ private:
340
+ PersistentValueMapBase(PersistentValueMapBase&);
341
+ void operator=(PersistentValueMapBase&);
342
+
343
+ static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
344
+ PersistentContainerValue value) {
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
+
358
+
359
+ template <typename K, typename V, typename Traits>
360
+ class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
361
+ public:
362
+ explicit PersistentValueMap(Isolate* isolate)
363
+ : PersistentValueMapBase<K, V, Traits>(isolate) {}
364
+ PersistentValueMap(Isolate* isolate, const char* label)
365
+ : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
366
+
367
+ typedef
368
+ typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
369
+ PersistentValueReference;
370
+
371
+ /**
372
+ * Put value into map. Depending on Traits::kIsWeak, the value will be held
373
+ * by the map strongly or weakly.
374
+ * Returns old value as Global.
375
+ */
376
+ Global<V> Set(const K& key, Local<V> value) {
377
+ Global<V> persistent(this->isolate(), value);
378
+ return SetUnique(key, &persistent);
379
+ }
380
+
381
+ /**
382
+ * Put value into map, like Set(const K&, Local<V>).
383
+ */
384
+ Global<V> Set(const K& key, Global<V> value) {
385
+ return SetUnique(key, &value);
386
+ }
387
+
388
+ /**
389
+ * Put the value into the map, and set the 'weak' callback when demanded
390
+ * by the Traits class.
391
+ */
392
+ Global<V> SetUnique(const K& key, Global<V>* persistent) {
393
+ if (Traits::kCallbackType == kNotWeak) {
394
+ this->AnnotateStrongRetainer(persistent);
395
+ } else {
396
+ WeakCallbackType callback_type =
397
+ Traits::kCallbackType == kWeakWithInternalFields
398
+ ? WeakCallbackType::kInternalFields
399
+ : WeakCallbackType::kParameter;
400
+ Local<V> value(Local<V>::New(this->isolate(), *persistent));
401
+ persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
402
+ Traits::WeakCallbackParameter(this, key, value), WeakCallback,
403
+ callback_type);
404
+ }
405
+ PersistentContainerValue old_value =
406
+ Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
407
+ return this->Release(old_value).Pass();
408
+ }
409
+
410
+ /**
411
+ * Put a value into the map and update the reference.
412
+ * Restrictions of GetReference apply here as well.
413
+ */
414
+ Global<V> Set(const K& key, Global<V> value,
415
+ PersistentValueReference* reference) {
416
+ *reference = this->Leak(&value);
417
+ return SetUnique(key, &value);
418
+ }
419
+
420
+ private:
421
+ static void WeakCallback(
422
+ const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
423
+ if (Traits::kCallbackType != kNotWeak) {
424
+ PersistentValueMap<K, V, Traits>* persistentValueMap =
425
+ Traits::MapFromWeakCallbackInfo(data);
426
+ K key = Traits::KeyFromWeakCallbackInfo(data);
427
+ Traits::Dispose(data.GetIsolate(),
428
+ persistentValueMap->Remove(key).Pass(), key);
429
+ Traits::DisposeCallbackData(data.GetParameter());
430
+ }
431
+ }
432
+ };
433
+
434
+
435
+ template <typename K, typename V, typename Traits>
436
+ class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
437
+ public:
438
+ explicit GlobalValueMap(Isolate* isolate)
439
+ : PersistentValueMapBase<K, V, Traits>(isolate) {}
440
+ GlobalValueMap(Isolate* isolate, const char* label)
441
+ : PersistentValueMapBase<K, V, Traits>(isolate, label) {}
442
+
443
+ typedef
444
+ typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
445
+ PersistentValueReference;
446
+
447
+ /**
448
+ * Put value into map. Depending on Traits::kIsWeak, the value will be held
449
+ * by the map strongly or weakly.
450
+ * Returns old value as Global.
451
+ */
452
+ Global<V> Set(const K& key, Local<V> value) {
453
+ Global<V> persistent(this->isolate(), value);
454
+ return SetUnique(key, &persistent);
455
+ }
456
+
457
+ /**
458
+ * Put value into map, like Set(const K&, Local<V>).
459
+ */
460
+ Global<V> Set(const K& key, Global<V> value) {
461
+ return SetUnique(key, &value);
462
+ }
463
+
464
+ /**
465
+ * Put the value into the map, and set the 'weak' callback when demanded
466
+ * by the Traits class.
467
+ */
468
+ Global<V> SetUnique(const K& key, Global<V>* persistent) {
469
+ if (Traits::kCallbackType == kNotWeak) {
470
+ this->AnnotateStrongRetainer(persistent);
471
+ } else {
472
+ WeakCallbackType callback_type =
473
+ Traits::kCallbackType == kWeakWithInternalFields
474
+ ? WeakCallbackType::kInternalFields
475
+ : WeakCallbackType::kParameter;
476
+ Local<V> value(Local<V>::New(this->isolate(), *persistent));
477
+ persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
478
+ Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
479
+ callback_type);
480
+ }
481
+ PersistentContainerValue old_value =
482
+ Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
483
+ return this->Release(old_value).Pass();
484
+ }
485
+
486
+ /**
487
+ * Put a value into the map and update the reference.
488
+ * Restrictions of GetReference apply here as well.
489
+ */
490
+ Global<V> Set(const K& key, Global<V> value,
491
+ PersistentValueReference* reference) {
492
+ *reference = this->Leak(&value);
493
+ return SetUnique(key, &value);
494
+ }
495
+
496
+ private:
497
+ static void OnWeakCallback(
498
+ const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
499
+ if (Traits::kCallbackType != kNotWeak) {
500
+ auto map = Traits::MapFromWeakCallbackInfo(data);
501
+ K key = Traits::KeyFromWeakCallbackInfo(data);
502
+ map->RemoveWeak(key);
503
+ Traits::OnWeakCallback(data);
504
+ data.SetSecondPassCallback(SecondWeakCallback);
505
+ }
506
+ }
507
+
508
+ static void SecondWeakCallback(
509
+ const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
510
+ Traits::DisposeWeak(data);
511
+ }
512
+ };
513
+
514
+
515
+ /**
516
+ * A map that uses Global as value and std::map as the backing
517
+ * implementation. Persistents are held non-weak.
518
+ *
519
+ * C++11 embedders don't need this class, as they can use
520
+ * Global directly in std containers.
521
+ */
522
+ template<typename K, typename V,
523
+ typename Traits = DefaultPersistentValueMapTraits<K, V> >
524
+ class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
525
+ public:
526
+ explicit StdPersistentValueMap(Isolate* isolate)
527
+ : PersistentValueMap<K, V, Traits>(isolate) {}
528
+ };
529
+
530
+
531
+ /**
532
+ * A map that uses Global as value and std::map as the backing
533
+ * implementation. Globals are held non-weak.
534
+ *
535
+ * C++11 embedders don't need this class, as they can use
536
+ * Global directly in std containers.
537
+ */
538
+ template <typename K, typename V,
539
+ typename Traits = DefaultGlobalMapTraits<K, V> >
540
+ class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
541
+ public:
542
+ explicit StdGlobalValueMap(Isolate* isolate)
543
+ : GlobalValueMap<K, V, Traits>(isolate) {}
544
+ };
545
+
546
+
547
+ class DefaultPersistentValueVectorTraits {
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
+
571
+
572
+ /**
573
+ * A vector wrapper that safely stores Global values.
574
+ * C++11 embedders don't need this class, as they can use Global
575
+ * directly in std containers.
576
+ *
577
+ * This class relies on a backing vector implementation, whose type and methods
578
+ * are described by the Traits class. The backing map will handle values of type
579
+ * PersistentContainerValue, with all conversion into and out of V8
580
+ * handles being transparently handled by this class.
581
+ */
582
+ template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
583
+ class PersistentValueVector {
584
+ public:
585
+ explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
586
+
587
+ ~PersistentValueVector() {
588
+ Clear();
589
+ }
590
+
591
+ /**
592
+ * Append a value to the vector.
593
+ */
594
+ void Append(Local<V> value) {
595
+ Global<V> persistent(isolate_, value);
596
+ Traits::Append(&impl_, ClearAndLeak(&persistent));
597
+ }
598
+
599
+ /**
600
+ * Append a persistent's value to the vector.
601
+ */
602
+ void Append(Global<V> persistent) {
603
+ Traits::Append(&impl_, ClearAndLeak(&persistent));
604
+ }
605
+
606
+ /**
607
+ * Are there any values in the vector?
608
+ */
609
+ bool IsEmpty() const {
610
+ return Traits::IsEmpty(&impl_);
611
+ }
612
+
613
+ /**
614
+ * How many elements are in the vector?
615
+ */
616
+ size_t Size() const {
617
+ return Traits::Size(&impl_);
618
+ }
619
+
620
+ /**
621
+ * Retrieve the i-th value in the vector.
622
+ */
623
+ Local<V> Get(size_t index) const {
624
+ return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
625
+ }
626
+
627
+ /**
628
+ * Remove all elements from the vector.
629
+ */
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.val_ = FromVal(Traits::Get(&impl_, i));
635
+ }
636
+ Traits::Clear(&impl_);
637
+ }
638
+
639
+ /**
640
+ * Reserve capacity in the vector.
641
+ * (Efficiency gains depend on the backing implementation.)
642
+ */
643
+ void ReserveCapacity(size_t capacity) {
644
+ Traits::ReserveCapacity(&impl_, capacity);
645
+ }
646
+
647
+ private:
648
+ static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
649
+ V* v = persistent->val_;
650
+ persistent->val_ = nullptr;
651
+ return reinterpret_cast<PersistentContainerValue>(v);
652
+ }
653
+
654
+ static V* FromVal(PersistentContainerValue v) {
655
+ return reinterpret_cast<V*>(v);
656
+ }
657
+
658
+ Isolate* isolate_;
659
+ typename Traits::Impl impl_;
660
+ };
661
+
662
+ } // namespace v8
663
+
664
+ #endif // V8_UTIL_H