libv8-node 20.12.1.0-x86_64-darwin → 22.5.1.0-x86_64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/libv8/node/version.rb +3 -3
  3. data/vendor/v8/include/cppgc/internal/api-constants.h +24 -5
  4. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +16 -6
  5. data/vendor/v8/include/cppgc/internal/caged-heap.h +12 -5
  6. data/vendor/v8/include/cppgc/internal/gc-info.h +82 -91
  7. data/vendor/v8/include/cppgc/internal/member-storage.h +16 -8
  8. data/vendor/v8/include/cppgc/member.h +25 -0
  9. data/vendor/v8/include/cppgc/persistent.h +4 -0
  10. data/vendor/v8/include/cppgc/platform.h +6 -1
  11. data/vendor/v8/include/cppgc/sentinel-pointer.h +7 -0
  12. data/vendor/v8/include/cppgc/source-location.h +2 -78
  13. data/vendor/v8/include/cppgc/trace-trait.h +8 -0
  14. data/vendor/v8/include/cppgc/type-traits.h +25 -4
  15. data/vendor/v8/include/cppgc/visitor.h +82 -4
  16. data/vendor/v8/include/libplatform/libplatform.h +7 -1
  17. data/vendor/v8/include/v8-array-buffer.h +6 -0
  18. data/vendor/v8/include/v8-callbacks.h +57 -19
  19. data/vendor/v8/include/v8-container.h +54 -0
  20. data/vendor/v8/include/v8-context.h +58 -32
  21. data/vendor/v8/include/v8-embedder-heap.h +31 -3
  22. data/vendor/v8/include/v8-embedder-state-scope.h +2 -1
  23. data/vendor/v8/include/v8-exception.h +15 -9
  24. data/vendor/v8/include/v8-fast-api-calls.h +58 -31
  25. data/vendor/v8/include/v8-forward.h +1 -0
  26. data/vendor/v8/include/v8-function-callback.h +135 -30
  27. data/vendor/v8/include/v8-function.h +6 -0
  28. data/vendor/v8/include/v8-handle-base.h +137 -0
  29. data/vendor/v8/include/v8-inspector.h +35 -13
  30. data/vendor/v8/include/v8-internal.h +510 -71
  31. data/vendor/v8/include/v8-isolate.h +176 -100
  32. data/vendor/v8/include/v8-local-handle.h +383 -112
  33. data/vendor/v8/include/v8-memory-span.h +157 -2
  34. data/vendor/v8/include/v8-message.h +22 -3
  35. data/vendor/v8/include/v8-metrics.h +1 -0
  36. data/vendor/v8/include/v8-object.h +98 -77
  37. data/vendor/v8/include/v8-persistent-handle.h +68 -90
  38. data/vendor/v8/include/v8-platform.h +191 -23
  39. data/vendor/v8/include/v8-primitive.h +12 -8
  40. data/vendor/v8/include/v8-profiler.h +16 -2
  41. data/vendor/v8/include/v8-script.h +88 -14
  42. data/vendor/v8/include/v8-snapshot.h +96 -22
  43. data/vendor/v8/include/v8-source-location.h +92 -0
  44. data/vendor/v8/include/v8-statistics.h +31 -10
  45. data/vendor/v8/include/v8-template.h +410 -131
  46. data/vendor/v8/include/v8-traced-handle.h +108 -90
  47. data/vendor/v8/include/v8-typed-array.h +115 -7
  48. data/vendor/v8/include/v8-unwinder.h +1 -1
  49. data/vendor/v8/include/v8-util.h +23 -20
  50. data/vendor/v8/include/v8-value-serializer.h +14 -0
  51. data/vendor/v8/include/v8-value.h +105 -3
  52. data/vendor/v8/include/v8-version.h +4 -4
  53. data/vendor/v8/include/v8config.h +54 -20
  54. data/vendor/v8/x86_64-darwin/libv8/obj/libv8_monolith.a +0 -0
  55. metadata +5 -3
@@ -8,30 +8,47 @@
8
8
  #include <stddef.h>
9
9
 
10
10
  #include <type_traits>
11
+ #include <vector>
11
12
 
12
- #include "v8-internal.h" // NOLINT(build/include_directory)
13
+ #include "v8-handle-base.h" // NOLINT(build/include_directory)
14
+ #include "v8-internal.h" // NOLINT(build/include_directory)
13
15
 
14
16
  namespace v8 {
15
17
 
16
- class Boolean;
17
18
  template <class T>
18
- class BasicTracedReference;
19
- class Context;
20
- class EscapableHandleScope;
21
- template <class F>
22
- class Eternal;
23
- template <class F>
24
- class FunctionCallbackInfo;
25
- class Isolate;
19
+ class LocalBase;
20
+ template <class T>
21
+ class Local;
22
+ template <class T>
23
+ class LocalVector;
26
24
  template <class F>
27
25
  class MaybeLocal;
26
+
27
+ template <class T>
28
+ class Eternal;
29
+ template <class T>
30
+ class Global;
31
+
28
32
  template <class T>
29
33
  class NonCopyablePersistentTraits;
30
- class Object;
34
+ template <class T>
35
+ class PersistentBase;
31
36
  template <class T, class M = NonCopyablePersistentTraits<T>>
32
37
  class Persistent;
38
+
39
+ class TracedReferenceBase;
33
40
  template <class T>
34
- class PersistentBase;
41
+ class BasicTracedReference;
42
+ template <class F>
43
+ class TracedReference;
44
+
45
+ class Boolean;
46
+ class Context;
47
+ class EscapableHandleScope;
48
+ template <class F>
49
+ class FunctionCallbackInfo;
50
+ class Isolate;
51
+ class Object;
35
52
  template <class F1, class F2, class F3>
36
53
  class PersistentValueMapBase;
37
54
  template <class F1, class F2>
@@ -45,9 +62,7 @@ class ReturnValue;
45
62
  class String;
46
63
  template <class F>
47
64
  class Traced;
48
- template <class F>
49
- class TracedReference;
50
- class TracedReferenceBase;
65
+ class TypecheckWitness;
51
66
  class Utils;
52
67
 
53
68
  namespace debug {
@@ -57,6 +72,8 @@ class ConsoleCallArguments;
57
72
  namespace internal {
58
73
  template <typename T>
59
74
  class CustomArguments;
75
+ template <typename T>
76
+ class LocalUnchecked;
60
77
  class SamplingHeapProfiler;
61
78
  } // namespace internal
62
79
 
@@ -119,10 +136,13 @@ class V8_EXPORT V8_NODISCARD HandleScope {
119
136
  internal::Isolate* i_isolate_;
120
137
  internal::Address* prev_next_;
121
138
  internal::Address* prev_limit_;
139
+ #ifdef V8_ENABLE_CHECKS
140
+ int scope_level_ = 0;
141
+ #endif
122
142
 
123
- // Local::New uses CreateHandle with an Isolate* parameter.
124
- template <class F>
125
- friend class Local;
143
+ // LocalBase<T>::New uses CreateHandle with an Isolate* parameter.
144
+ template <typename T>
145
+ friend class LocalBase;
126
146
 
127
147
  // Object::GetInternalField and Context::GetEmbedderData use CreateHandle with
128
148
  // a HeapObject in their shortcuts.
@@ -130,32 +150,74 @@ class V8_EXPORT V8_NODISCARD HandleScope {
130
150
  friend class Context;
131
151
  };
132
152
 
133
- namespace internal {
134
-
135
153
  /**
136
- * Helper functions about handles.
154
+ * A base class for local handles.
155
+ * Its implementation depends on whether direct local support is enabled.
156
+ * When it is, a local handle contains a direct pointer to the referenced
157
+ * object, otherwise it contains an indirect pointer.
137
158
  */
138
- class HandleHelper final {
139
- public:
140
- /**
141
- * Checks whether two handles are equal.
142
- * They are equal iff they are both empty or they are both non-empty and the
143
- * objects to which they refer are physically equal.
144
- *
145
- * If both handles refer to JS objects, this is the same as strict equality.
146
- * For primitives, such as numbers or strings, a `false` return value does not
147
- * indicate that the values aren't equal in the JavaScript sense.
148
- * Use `Value::StrictEquals()` to check primitives for equality.
149
- */
150
- template <typename T1, typename T2>
151
- V8_INLINE static bool EqualHandles(const T1& lhs, const T2& rhs) {
152
- if (lhs.IsEmpty()) return rhs.IsEmpty();
153
- if (rhs.IsEmpty()) return false;
154
- return lhs.address() == rhs.address();
159
+ #ifdef V8_ENABLE_DIRECT_LOCAL
160
+
161
+ template <typename T>
162
+ class LocalBase : public api_internal::DirectHandleBase {
163
+ protected:
164
+ template <class F>
165
+ friend class Local;
166
+
167
+ V8_INLINE LocalBase() = default;
168
+
169
+ V8_INLINE explicit LocalBase(internal::Address ptr) : DirectHandleBase(ptr) {}
170
+
171
+ template <typename S>
172
+ V8_INLINE LocalBase(const LocalBase<S>& other) : DirectHandleBase(other) {}
173
+
174
+ V8_INLINE static LocalBase<T> New(Isolate* isolate, internal::Address value) {
175
+ return LocalBase<T>(value);
176
+ }
177
+
178
+ V8_INLINE static LocalBase<T> New(Isolate* isolate, T* that) {
179
+ return LocalBase<T>::New(isolate,
180
+ internal::ValueHelper::ValueAsAddress(that));
181
+ }
182
+
183
+ V8_INLINE static LocalBase<T> FromSlot(internal::Address* slot) {
184
+ return LocalBase<T>(*slot);
155
185
  }
156
186
  };
157
187
 
158
- } // namespace internal
188
+ #else // !V8_ENABLE_DIRECT_LOCAL
189
+
190
+ template <typename T>
191
+ class LocalBase : public api_internal::IndirectHandleBase {
192
+ protected:
193
+ template <class F>
194
+ friend class Local;
195
+
196
+ V8_INLINE LocalBase() = default;
197
+
198
+ V8_INLINE explicit LocalBase(internal::Address* location)
199
+ : IndirectHandleBase(location) {}
200
+
201
+ template <typename S>
202
+ V8_INLINE LocalBase(const LocalBase<S>& other) : IndirectHandleBase(other) {}
203
+
204
+ V8_INLINE static LocalBase<T> New(Isolate* isolate, internal::Address value) {
205
+ return LocalBase(HandleScope::CreateHandle(
206
+ reinterpret_cast<internal::Isolate*>(isolate), value));
207
+ }
208
+
209
+ V8_INLINE static LocalBase<T> New(Isolate* isolate, T* that) {
210
+ if (internal::ValueHelper::IsEmpty(that)) return LocalBase<T>();
211
+ return LocalBase<T>::New(isolate,
212
+ internal::ValueHelper::ValueAsAddress(that));
213
+ }
214
+
215
+ V8_INLINE static LocalBase<T> FromSlot(internal::Address* slot) {
216
+ return LocalBase<T>(slot);
217
+ }
218
+ };
219
+
220
+ #endif // V8_ENABLE_DIRECT_LOCAL
159
221
 
160
222
  /**
161
223
  * An object reference managed by the v8 garbage collector.
@@ -187,12 +249,18 @@ class HandleHelper final {
187
249
  * to these values as to their handles.
188
250
  */
189
251
  template <class T>
190
- class Local {
252
+ class V8_TRIVIAL_ABI Local : public LocalBase<T>,
253
+ #ifdef V8_ENABLE_LOCAL_OFF_STACK_CHECK
254
+ public api_internal::StackAllocated<true>
255
+ #else
256
+ public api_internal::StackAllocated<false>
257
+ #endif
258
+ {
191
259
  public:
192
- V8_INLINE Local() : val_(internal::ValueHelper::EmptyValue<T>()) {}
260
+ V8_INLINE Local() = default;
193
261
 
194
262
  template <class S>
195
- V8_INLINE Local(Local<S> that) : val_(reinterpret_cast<T*>(*that)) {
263
+ V8_INLINE Local(Local<S> that) : LocalBase<T>(that) {
196
264
  /**
197
265
  * This check fails when trying to convert between incompatible
198
266
  * handles. For example, converting from a Local<String> to a
@@ -201,21 +269,9 @@ class Local {
201
269
  static_assert(std::is_base_of<T, S>::value, "type check");
202
270
  }
203
271
 
204
- /**
205
- * Returns true if the handle is empty.
206
- */
207
- V8_INLINE bool IsEmpty() const {
208
- return val_ == internal::ValueHelper::EmptyValue<T>();
209
- }
272
+ V8_INLINE T* operator->() const { return this->template value<T>(); }
210
273
 
211
- /**
212
- * Sets the handle to be empty. IsEmpty() will then return true.
213
- */
214
- V8_INLINE void Clear() { val_ = internal::ValueHelper::EmptyValue<T>(); }
215
-
216
- V8_INLINE T* operator->() const { return val_; }
217
-
218
- V8_INLINE T* operator*() const { return val_; }
274
+ V8_INLINE T* operator*() const { return this->operator->(); }
219
275
 
220
276
  /**
221
277
  * Checks whether two handles are equal or different.
@@ -259,8 +315,9 @@ class Local {
259
315
  // If we're going to perform the type check then we have to check
260
316
  // that the handle isn't empty before doing the checked cast.
261
317
  if (that.IsEmpty()) return Local<T>();
318
+ T::Cast(that.template value<S>());
262
319
  #endif
263
- return Local<T>(T::Cast(*that));
320
+ return Local<T>(LocalBase<T>(that));
264
321
  }
265
322
 
266
323
  /**
@@ -279,17 +336,17 @@ class Local {
279
336
  * the original handle is destroyed/disposed.
280
337
  */
281
338
  V8_INLINE static Local<T> New(Isolate* isolate, Local<T> that) {
282
- return New(isolate, that.val_);
339
+ return New(isolate, that.template value<T, true>());
283
340
  }
284
341
 
285
342
  V8_INLINE static Local<T> New(Isolate* isolate,
286
343
  const PersistentBase<T>& that) {
287
- return New(isolate, internal::ValueHelper::SlotAsValue<T>(that.val_));
344
+ return New(isolate, that.template value<T, true>());
288
345
  }
289
346
 
290
347
  V8_INLINE static Local<T> New(Isolate* isolate,
291
348
  const BasicTracedReference<T>& that) {
292
- return New(isolate, internal::ValueHelper::SlotAsValue<T>(*that));
349
+ return New(isolate, that.template value<T, true>());
293
350
  }
294
351
 
295
352
  private:
@@ -298,7 +355,13 @@ class Local {
298
355
  template <class F>
299
356
  friend class Eternal;
300
357
  template <class F>
358
+ friend class Global;
359
+ template <class F>
360
+ friend class Local;
361
+ template <class F>
301
362
  friend class MaybeLocal;
363
+ template <class F, class M>
364
+ friend class Persistent;
302
365
  template <class F>
303
366
  friend class FunctionCallbackInfo;
304
367
  template <class F>
@@ -316,6 +379,7 @@ class Local {
316
379
  friend Local<Boolean> False(Isolate* isolate);
317
380
  friend class HandleScope;
318
381
  friend class EscapableHandleScope;
382
+ friend class InternalEscapableScope;
319
383
  template <class F1, class F2, class F3>
320
384
  friend class PersistentValueMapBase;
321
385
  template <class F1, class F2>
@@ -327,29 +391,209 @@ class Local {
327
391
  friend class internal::SamplingHeapProfiler;
328
392
  friend class internal::HandleHelper;
329
393
  friend class debug::ConsoleCallArguments;
394
+ friend class internal::LocalUnchecked<T>;
330
395
 
331
- explicit V8_INLINE Local(T* that) : val_(that) {}
396
+ explicit Local(no_checking_tag do_not_check)
397
+ : LocalBase<T>(), StackAllocated(do_not_check) {}
398
+ explicit Local(const Local<T>& other, no_checking_tag do_not_check)
399
+ : LocalBase<T>(other), StackAllocated(do_not_check) {}
332
400
 
333
- V8_INLINE internal::Address address() const {
334
- return internal::ValueHelper::ValueAsAddress(val_);
335
- }
401
+ V8_INLINE explicit Local<T>(const LocalBase<T>& other)
402
+ : LocalBase<T>(other) {}
336
403
 
337
404
  V8_INLINE static Local<T> FromSlot(internal::Address* slot) {
338
- return Local<T>(internal::ValueHelper::SlotAsValue<T>(slot));
405
+ return Local<T>(LocalBase<T>::FromSlot(slot));
406
+ }
407
+
408
+ #ifdef V8_ENABLE_DIRECT_LOCAL
409
+ friend class TypecheckWitness;
410
+
411
+ V8_INLINE static Local<T> FromAddress(internal::Address ptr) {
412
+ return Local<T>(LocalBase<T>(ptr));
413
+ }
414
+ #endif // V8_ENABLE_DIRECT_LOCAL
415
+
416
+ V8_INLINE static Local<T> New(Isolate* isolate, internal::Address value) {
417
+ return Local<T>(LocalBase<T>::New(isolate, value));
339
418
  }
340
419
 
341
420
  V8_INLINE static Local<T> New(Isolate* isolate, T* that) {
342
- #ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
343
- return Local<T>(that);
344
- #else
345
- if (that == nullptr) return Local<T>();
346
- internal::Address* p = reinterpret_cast<internal::Address*>(that);
347
- return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
348
- reinterpret_cast<internal::Isolate*>(isolate), *p)));
421
+ return Local<T>(LocalBase<T>::New(isolate, that));
422
+ }
423
+
424
+ // Unsafe cast, should be avoided.
425
+ template <class S>
426
+ V8_INLINE Local<S> UnsafeAs() const {
427
+ return Local<S>(LocalBase<S>(*this));
428
+ }
429
+ };
430
+
431
+ namespace internal {
432
+ // A local variant that is suitable for off-stack allocation.
433
+ // Used internally by LocalVector<T>. Not to be used directly!
434
+ template <typename T>
435
+ class V8_TRIVIAL_ABI LocalUnchecked : public Local<T> {
436
+ public:
437
+ LocalUnchecked() : Local<T>(Local<T>::do_not_check) {}
438
+
439
+ #if defined(V8_ENABLE_LOCAL_OFF_STACK_CHECK) && V8_HAS_ATTRIBUTE_TRIVIAL_ABI
440
+ // In this case, the check is also enforced in the copy constructor and we
441
+ // need to suppress it.
442
+ LocalUnchecked(const LocalUnchecked& other)
443
+ : Local<T>(other, Local<T>::do_not_check) {}
444
+ LocalUnchecked& operator=(const LocalUnchecked&) = default;
349
445
  #endif
446
+
447
+ // Implicit conversion from Local.
448
+ LocalUnchecked(const Local<T>& other) // NOLINT(runtime/explicit)
449
+ : Local<T>(other, Local<T>::do_not_check) {}
450
+ };
451
+
452
+ #ifdef V8_ENABLE_DIRECT_LOCAL
453
+ // Off-stack allocated direct locals must be registered as strong roots.
454
+ // For off-stack indirect locals, this is not necessary.
455
+
456
+ template <typename T>
457
+ class StrongRootAllocator<LocalUnchecked<T>> : public StrongRootAllocatorBase {
458
+ public:
459
+ using value_type = LocalUnchecked<T>;
460
+ static_assert(std::is_standard_layout_v<value_type>);
461
+ static_assert(sizeof(value_type) == sizeof(Address));
462
+
463
+ explicit StrongRootAllocator(Heap* heap) : StrongRootAllocatorBase(heap) {}
464
+ explicit StrongRootAllocator(v8::Isolate* isolate)
465
+ : StrongRootAllocatorBase(isolate) {}
466
+ template <typename U>
467
+ StrongRootAllocator(const StrongRootAllocator<U>& other) noexcept
468
+ : StrongRootAllocatorBase(other) {}
469
+
470
+ value_type* allocate(size_t n) {
471
+ return reinterpret_cast<value_type*>(allocate_impl(n));
472
+ }
473
+ void deallocate(value_type* p, size_t n) noexcept {
474
+ return deallocate_impl(reinterpret_cast<Address*>(p), n);
475
+ }
476
+ };
477
+ #endif // V8_ENABLE_DIRECT_LOCAL
478
+ } // namespace internal
479
+
480
+ template <typename T>
481
+ class LocalVector {
482
+ private:
483
+ using element_type = internal::LocalUnchecked<T>;
484
+
485
+ #ifdef V8_ENABLE_DIRECT_LOCAL
486
+ using allocator_type = internal::StrongRootAllocator<element_type>;
487
+
488
+ static allocator_type make_allocator(Isolate* isolate) noexcept {
489
+ return allocator_type(isolate);
490
+ }
491
+ #else
492
+ using allocator_type = std::allocator<element_type>;
493
+
494
+ static allocator_type make_allocator(Isolate* isolate) noexcept {
495
+ return allocator_type();
496
+ }
497
+ #endif // V8_ENABLE_DIRECT_LOCAL
498
+
499
+ using vector_type = std::vector<element_type, allocator_type>;
500
+
501
+ public:
502
+ using value_type = Local<T>;
503
+ using reference = value_type&;
504
+ using const_reference = const value_type&;
505
+ using size_type = size_t;
506
+ using difference_type = ptrdiff_t;
507
+ using iterator =
508
+ internal::WrappedIterator<typename vector_type::iterator, Local<T>>;
509
+ using const_iterator =
510
+ internal::WrappedIterator<typename vector_type::const_iterator,
511
+ const Local<T>>;
512
+
513
+ explicit LocalVector(Isolate* isolate) : backing_(make_allocator(isolate)) {}
514
+ LocalVector(Isolate* isolate, size_t n)
515
+ : backing_(n, make_allocator(isolate)) {}
516
+ explicit LocalVector(Isolate* isolate, std::initializer_list<Local<T>> init)
517
+ : backing_(make_allocator(isolate)) {
518
+ if (init.size() == 0) return;
519
+ backing_.reserve(init.size());
520
+ backing_.insert(backing_.end(), init.begin(), init.end());
521
+ }
522
+
523
+ iterator begin() noexcept { return iterator(backing_.begin()); }
524
+ const_iterator begin() const noexcept {
525
+ return const_iterator(backing_.begin());
526
+ }
527
+ iterator end() noexcept { return iterator(backing_.end()); }
528
+ const_iterator end() const noexcept { return const_iterator(backing_.end()); }
529
+
530
+ size_t size() const noexcept { return backing_.size(); }
531
+ bool empty() const noexcept { return backing_.empty(); }
532
+ void reserve(size_t n) { backing_.reserve(n); }
533
+ void shrink_to_fit() { backing_.shrink_to_fit(); }
534
+
535
+ Local<T>& operator[](size_t n) { return backing_[n]; }
536
+ const Local<T>& operator[](size_t n) const { return backing_[n]; }
537
+
538
+ Local<T>& at(size_t n) { return backing_.at(n); }
539
+ const Local<T>& at(size_t n) const { return backing_.at(n); }
540
+
541
+ Local<T>& front() { return backing_.front(); }
542
+ const Local<T>& front() const { return backing_.front(); }
543
+ Local<T>& back() { return backing_.back(); }
544
+ const Local<T>& back() const { return backing_.back(); }
545
+
546
+ Local<T>* data() noexcept { return backing_.data(); }
547
+ const Local<T>* data() const noexcept { return backing_.data(); }
548
+
549
+ iterator insert(const_iterator pos, const Local<T>& value) {
550
+ return iterator(backing_.insert(pos.base(), value));
551
+ }
552
+
553
+ template <typename InputIt>
554
+ iterator insert(const_iterator pos, InputIt first, InputIt last) {
555
+ return iterator(backing_.insert(pos.base(), first, last));
556
+ }
557
+
558
+ iterator insert(const_iterator pos, std::initializer_list<Local<T>> init) {
559
+ return iterator(backing_.insert(pos.base(), init.begin(), init.end()));
560
+ }
561
+
562
+ LocalVector<T>& operator=(std::initializer_list<Local<T>> init) {
563
+ backing_.clear();
564
+ backing_.insert(backing_.end(), init.begin(), init.end());
565
+ return *this;
566
+ }
567
+
568
+ void push_back(const Local<T>& x) { backing_.push_back(x); }
569
+ void pop_back() { backing_.pop_back(); }
570
+ void emplace_back(const Local<T>& x) { backing_.emplace_back(x); }
571
+
572
+ void clear() noexcept { backing_.clear(); }
573
+ void resize(size_t n) { backing_.resize(n); }
574
+ void swap(LocalVector<T>& other) { backing_.swap(other.backing_); }
575
+
576
+ friend bool operator==(const LocalVector<T>& x, const LocalVector<T>& y) {
577
+ return x.backing_ == y.backing_;
578
+ }
579
+ friend bool operator!=(const LocalVector<T>& x, const LocalVector<T>& y) {
580
+ return x.backing_ != y.backing_;
581
+ }
582
+ friend bool operator<(const LocalVector<T>& x, const LocalVector<T>& y) {
583
+ return x.backing_ < y.backing_;
584
+ }
585
+ friend bool operator>(const LocalVector<T>& x, const LocalVector<T>& y) {
586
+ return x.backing_ > y.backing_;
587
+ }
588
+ friend bool operator<=(const LocalVector<T>& x, const LocalVector<T>& y) {
589
+ return x.backing_ <= y.backing_;
590
+ }
591
+ friend bool operator>=(const LocalVector<T>& x, const LocalVector<T>& y) {
592
+ return x.backing_ >= y.backing_;
350
593
  }
351
594
 
352
- T* val_;
595
+ private:
596
+ vector_type backing_;
353
597
  };
354
598
 
355
599
  #if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
@@ -371,15 +615,11 @@ using Handle = Local<T>;
371
615
  template <class T>
372
616
  class MaybeLocal {
373
617
  public:
374
- V8_INLINE MaybeLocal() : val_(internal::ValueHelper::EmptyValue<T>()) {}
618
+ V8_INLINE MaybeLocal() : local_() {}
375
619
  template <class S>
376
- V8_INLINE MaybeLocal(Local<S> that) : val_(reinterpret_cast<T*>(*that)) {
377
- static_assert(std::is_base_of<T, S>::value, "type check");
378
- }
620
+ V8_INLINE MaybeLocal(Local<S> that) : local_(that) {}
379
621
 
380
- V8_INLINE bool IsEmpty() const {
381
- return val_ == internal::ValueHelper::EmptyValue<T>();
382
- }
622
+ V8_INLINE bool IsEmpty() const { return local_.IsEmpty(); }
383
623
 
384
624
  /**
385
625
  * Converts this MaybeLocal<> to a Local<>. If this MaybeLocal<> is empty,
@@ -387,7 +627,7 @@ class MaybeLocal {
387
627
  */
388
628
  template <class S>
389
629
  V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local<S>* out) const {
390
- out->val_ = IsEmpty() ? internal::ValueHelper::EmptyValue<T>() : this->val_;
630
+ *out = local_;
391
631
  return !IsEmpty();
392
632
  }
393
633
 
@@ -397,7 +637,7 @@ class MaybeLocal {
397
637
  */
398
638
  V8_INLINE Local<T> ToLocalChecked() {
399
639
  if (V8_UNLIKELY(IsEmpty())) api_internal::ToLocalEmpty();
400
- return Local<T>(val_);
640
+ return local_;
401
641
  }
402
642
 
403
643
  /**
@@ -406,34 +646,82 @@ class MaybeLocal {
406
646
  */
407
647
  template <class S>
408
648
  V8_INLINE Local<S> FromMaybe(Local<S> default_value) const {
409
- return IsEmpty() ? default_value : Local<S>(val_);
649
+ return IsEmpty() ? default_value : Local<S>(local_);
650
+ }
651
+
652
+ /**
653
+ * Cast a handle to a subclass, e.g. MaybeLocal<Value> to MaybeLocal<Object>.
654
+ * This is only valid if the handle actually refers to a value of the target
655
+ * type.
656
+ */
657
+ template <class S>
658
+ V8_INLINE static MaybeLocal<T> Cast(MaybeLocal<S> that) {
659
+ #ifdef V8_ENABLE_CHECKS
660
+ // If we're going to perform the type check then we have to check
661
+ // that the handle isn't empty before doing the checked cast.
662
+ if (that.IsEmpty()) return MaybeLocal<T>();
663
+ T::Cast(that.local_.template value<S>());
664
+ #endif
665
+ return MaybeLocal<T>(that.local_);
666
+ }
667
+
668
+ /**
669
+ * Calling this is equivalent to MaybeLocal<S>::Cast().
670
+ * In particular, this is only valid if the handle actually refers to a value
671
+ * of the target type.
672
+ */
673
+ template <class S>
674
+ V8_INLINE MaybeLocal<S> As() const {
675
+ return MaybeLocal<S>::Cast(*this);
410
676
  }
411
677
 
412
678
  private:
413
- T* val_;
679
+ Local<T> local_;
680
+
681
+ template <typename S>
682
+ friend class MaybeLocal;
414
683
  };
415
684
 
416
685
  /**
417
686
  * A HandleScope which first allocates a handle in the current scope
418
687
  * which will be later filled with the escape value.
419
688
  */
420
- class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope {
689
+ class V8_EXPORT V8_NODISCARD EscapableHandleScopeBase : public HandleScope {
421
690
  public:
422
- explicit EscapableHandleScope(Isolate* isolate);
423
- V8_INLINE ~EscapableHandleScope() = default;
691
+ explicit EscapableHandleScopeBase(Isolate* isolate);
692
+ V8_INLINE ~EscapableHandleScopeBase() = default;
693
+
694
+ EscapableHandleScopeBase(const EscapableHandleScopeBase&) = delete;
695
+ void operator=(const EscapableHandleScopeBase&) = delete;
696
+ void* operator new(size_t size) = delete;
697
+ void* operator new[](size_t size) = delete;
698
+ void operator delete(void*, size_t) = delete;
699
+ void operator delete[](void*, size_t) = delete;
424
700
 
701
+ protected:
425
702
  /**
426
703
  * Pushes the value into the previous scope and returns a handle to it.
427
704
  * Cannot be called twice.
428
705
  */
706
+ internal::Address* EscapeSlot(internal::Address* escape_value);
707
+
708
+ private:
709
+ internal::Address* escape_slot_;
710
+ };
711
+
712
+ class V8_EXPORT V8_NODISCARD EscapableHandleScope
713
+ : public EscapableHandleScopeBase {
714
+ public:
715
+ explicit EscapableHandleScope(Isolate* isolate)
716
+ : EscapableHandleScopeBase(isolate) {}
717
+ V8_INLINE ~EscapableHandleScope() = default;
429
718
  template <class T>
430
719
  V8_INLINE Local<T> Escape(Local<T> value) {
431
- #ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
720
+ #ifdef V8_ENABLE_DIRECT_LOCAL
432
721
  return value;
433
722
  #else
434
- internal::Address* slot =
435
- Escape(reinterpret_cast<internal::Address*>(*value));
436
- return Local<T>(reinterpret_cast<T*>(slot));
723
+ if (value.IsEmpty()) return value;
724
+ return Local<T>::FromSlot(EscapeSlot(value.slot()));
437
725
  #endif
438
726
  }
439
727
 
@@ -441,20 +729,6 @@ class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope {
441
729
  V8_INLINE MaybeLocal<T> EscapeMaybe(MaybeLocal<T> value) {
442
730
  return Escape(value.FromMaybe(Local<T>()));
443
731
  }
444
-
445
- EscapableHandleScope(const EscapableHandleScope&) = delete;
446
- void operator=(const EscapableHandleScope&) = delete;
447
-
448
- private:
449
- // Declaring operator new and delete as deleted is not spec compliant.
450
- // Therefore declare them private instead to disable dynamic alloc
451
- void* operator new(size_t size);
452
- void* operator new[](size_t size);
453
- void operator delete(void*, size_t);
454
- void operator delete[](void*, size_t);
455
-
456
- internal::Address* Escape(internal::Address* escape_value);
457
- internal::Address* escape_slot_;
458
732
  };
459
733
 
460
734
  /**
@@ -469,15 +743,12 @@ class V8_EXPORT V8_NODISCARD SealHandleScope {
469
743
 
470
744
  SealHandleScope(const SealHandleScope&) = delete;
471
745
  void operator=(const SealHandleScope&) = delete;
746
+ void* operator new(size_t size) = delete;
747
+ void* operator new[](size_t size) = delete;
748
+ void operator delete(void*, size_t) = delete;
749
+ void operator delete[](void*, size_t) = delete;
472
750
 
473
751
  private:
474
- // Declaring operator new and delete as deleted is not spec compliant.
475
- // Therefore declare them private instead to disable dynamic alloc
476
- void* operator new(size_t size);
477
- void* operator new[](size_t size);
478
- void operator delete(void*, size_t);
479
- void operator delete[](void*, size_t);
480
-
481
752
  internal::Isolate* const i_isolate_;
482
753
  internal::Address* prev_limit_;
483
754
  int prev_sealed_level_;