libv8-node 21.7.2.0-aarch64-linux-musl → 24.12.0.0-aarch64-linux-musl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libv8-node/location.rb +3 -5
  3. data/ext/libv8-node/paths.rb +2 -0
  4. data/lib/libv8/node/version.rb +7 -4
  5. data/lib/libv8/node.rb +2 -0
  6. data/lib/libv8-node.rb +2 -0
  7. data/vendor/v8/aarch64-linux-musl/libv8/obj/libv8_monolith.a +0 -0
  8. data/vendor/v8/include/cppgc/allocation.h +11 -13
  9. data/vendor/v8/include/cppgc/default-platform.h +3 -2
  10. data/vendor/v8/include/cppgc/garbage-collected.h +8 -0
  11. data/vendor/v8/include/cppgc/heap-consistency.h +1 -1
  12. data/vendor/v8/include/cppgc/heap-statistics.h +2 -0
  13. data/vendor/v8/include/cppgc/internal/api-constants.h +2 -14
  14. data/vendor/v8/include/cppgc/internal/base-page-handle.h +2 -4
  15. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +0 -4
  16. data/vendor/v8/include/cppgc/internal/caged-heap.h +0 -4
  17. data/vendor/v8/include/cppgc/internal/compiler-specific.h +9 -1
  18. data/vendor/v8/include/cppgc/internal/conditional-stack-allocated.h +41 -0
  19. data/vendor/v8/include/cppgc/internal/gc-info.h +12 -10
  20. data/vendor/v8/include/cppgc/internal/logging.h +3 -3
  21. data/vendor/v8/include/cppgc/internal/member-storage.h +69 -20
  22. data/vendor/v8/include/cppgc/internal/name-trait.h +5 -1
  23. data/vendor/v8/include/cppgc/internal/persistent-node.h +8 -3
  24. data/vendor/v8/include/cppgc/internal/pointer-policies.h +48 -11
  25. data/vendor/v8/include/cppgc/macros.h +21 -0
  26. data/vendor/v8/include/cppgc/member.h +70 -36
  27. data/vendor/v8/include/cppgc/name-provider.h +10 -0
  28. data/vendor/v8/include/cppgc/platform.h +11 -0
  29. data/vendor/v8/include/cppgc/type-traits.h +26 -4
  30. data/vendor/v8/include/cppgc/visitor.h +25 -1
  31. data/vendor/v8/include/libplatform/libplatform-export.h +2 -2
  32. data/vendor/v8/include/libplatform/v8-tracing.h +0 -1
  33. data/vendor/v8/include/v8-array-buffer.h +149 -46
  34. data/vendor/v8/include/v8-callbacks.h +100 -43
  35. data/vendor/v8/include/v8-container.h +54 -0
  36. data/vendor/v8/include/v8-context.h +92 -30
  37. data/vendor/v8/include/v8-cppgc.h +5 -56
  38. data/vendor/v8/include/v8-data.h +5 -0
  39. data/vendor/v8/include/v8-date.h +9 -0
  40. data/vendor/v8/include/v8-debug.h +11 -0
  41. data/vendor/v8/include/v8-embedder-heap.h +8 -20
  42. data/vendor/v8/include/v8-embedder-state-scope.h +2 -1
  43. data/vendor/v8/include/v8-exception.h +87 -9
  44. data/vendor/v8/include/v8-external-memory-accounter.h +60 -0
  45. data/vendor/v8/include/v8-fast-api-calls.h +67 -223
  46. data/vendor/v8/include/v8-forward.h +1 -0
  47. data/vendor/v8/include/v8-function-callback.h +296 -75
  48. data/vendor/v8/include/v8-function.h +11 -3
  49. data/vendor/v8/include/v8-handle-base.h +52 -82
  50. data/vendor/v8/include/v8-initialization.h +26 -1
  51. data/vendor/v8/include/v8-inspector.h +26 -27
  52. data/vendor/v8/include/v8-internal.h +960 -230
  53. data/vendor/v8/include/v8-isolate.h +347 -226
  54. data/vendor/v8/include/v8-local-handle.h +307 -55
  55. data/vendor/v8/include/v8-maybe.h +2 -1
  56. data/vendor/v8/include/v8-memory-span.h +284 -4
  57. data/vendor/v8/include/v8-message.h +11 -5
  58. data/vendor/v8/include/v8-metrics.h +15 -0
  59. data/vendor/v8/include/v8-microtask-queue.h +0 -5
  60. data/vendor/v8/include/v8-object.h +314 -41
  61. data/vendor/v8/include/v8-persistent-handle.h +29 -39
  62. data/vendor/v8/include/v8-platform.h +135 -77
  63. data/vendor/v8/include/v8-primitive.h +223 -5
  64. data/vendor/v8/include/v8-profiler.h +51 -2
  65. data/vendor/v8/include/v8-promise.h +2 -2
  66. data/vendor/v8/include/v8-proxy.h +0 -1
  67. data/vendor/v8/include/v8-regexp.h +0 -1
  68. data/vendor/v8/include/v8-sandbox.h +173 -0
  69. data/vendor/v8/include/v8-script.h +125 -27
  70. data/vendor/v8/include/v8-snapshot.h +130 -23
  71. data/vendor/v8/include/v8-source-location.h +6 -1
  72. data/vendor/v8/include/v8-statistics.h +10 -24
  73. data/vendor/v8/include/v8-template.h +320 -193
  74. data/vendor/v8/include/v8-trace-categories.h +23 -0
  75. data/vendor/v8/include/v8-traced-handle.h +99 -76
  76. data/vendor/v8/include/v8-typed-array.h +111 -7
  77. data/vendor/v8/include/v8-unwinder-state.h +2 -3
  78. data/vendor/v8/include/v8-unwinder.h +2 -1
  79. data/vendor/v8/include/v8-util.h +10 -125
  80. data/vendor/v8/include/v8-value-serializer-version.h +3 -3
  81. data/vendor/v8/include/v8-value.h +113 -6
  82. data/vendor/v8/include/v8-version.h +3 -3
  83. data/vendor/v8/include/v8-wasm.h +27 -0
  84. data/vendor/v8/include/v8-weak-callback-info.h +20 -12
  85. data/vendor/v8/include/v8.h +3 -3
  86. data/vendor/v8/include/v8config.h +116 -53
  87. metadata +55 -12
  88. data/vendor/v8/include/cppgc/ephemeron-pair.h +0 -30
@@ -8,8 +8,10 @@
8
8
  #include <stddef.h>
9
9
 
10
10
  #include <type_traits>
11
+ #include <vector>
11
12
 
12
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
 
@@ -17,6 +19,8 @@ template <class T>
17
19
  class LocalBase;
18
20
  template <class T>
19
21
  class Local;
22
+ template <class T>
23
+ class LocalVector;
20
24
  template <class F>
21
25
  class MaybeLocal;
22
26
 
@@ -47,8 +51,6 @@ class Isolate;
47
51
  class Object;
48
52
  template <class F1, class F2, class F3>
49
53
  class PersistentValueMapBase;
50
- template <class F1, class F2>
51
- class PersistentValueVector;
52
54
  class Primitive;
53
55
  class Private;
54
56
  template <class F>
@@ -58,6 +60,7 @@ class ReturnValue;
58
60
  class String;
59
61
  template <class F>
60
62
  class Traced;
63
+ class TypecheckWitness;
61
64
  class Utils;
62
65
 
63
66
  namespace debug {
@@ -67,6 +70,8 @@ class ConsoleCallArguments;
67
70
  namespace internal {
68
71
  template <typename T>
69
72
  class CustomArguments;
73
+ template <typename T>
74
+ class LocalUnchecked;
70
75
  class SamplingHeapProfiler;
71
76
  } // namespace internal
72
77
 
@@ -129,6 +134,9 @@ class V8_EXPORT V8_NODISCARD HandleScope {
129
134
  internal::Isolate* i_isolate_;
130
135
  internal::Address* prev_next_;
131
136
  internal::Address* prev_limit_;
137
+ #ifdef V8_ENABLE_CHECKS
138
+ int scope_level_ = 0;
139
+ #endif
132
140
 
133
141
  // LocalBase<T>::New uses CreateHandle with an Isolate* parameter.
134
142
  template <typename T>
@@ -142,14 +150,14 @@ class V8_EXPORT V8_NODISCARD HandleScope {
142
150
 
143
151
  /**
144
152
  * A base class for local handles.
145
- * Its implementation depends on whether direct local support is enabled.
153
+ * Its implementation depends on whether direct handle support is enabled.
146
154
  * When it is, a local handle contains a direct pointer to the referenced
147
155
  * object, otherwise it contains an indirect pointer.
148
156
  */
149
- #ifdef V8_ENABLE_DIRECT_LOCAL
157
+ #ifdef V8_ENABLE_DIRECT_HANDLE
150
158
 
151
159
  template <typename T>
152
- class LocalBase : public DirectHandleBase {
160
+ class LocalBase : public api_internal::DirectHandleBase {
153
161
  protected:
154
162
  template <class F>
155
163
  friend class Local;
@@ -171,14 +179,20 @@ class LocalBase : public DirectHandleBase {
171
179
  }
172
180
 
173
181
  V8_INLINE static LocalBase<T> FromSlot(internal::Address* slot) {
182
+ if (slot == nullptr) return LocalBase<T>();
174
183
  return LocalBase<T>(*slot);
175
184
  }
185
+
186
+ V8_INLINE static LocalBase<T> FromRepr(
187
+ internal::ValueHelper::InternalRepresentationType repr) {
188
+ return LocalBase<T>(repr);
189
+ }
176
190
  };
177
191
 
178
- #else // !V8_ENABLE_DIRECT_LOCAL
192
+ #else // !V8_ENABLE_DIRECT_HANDLE
179
193
 
180
194
  template <typename T>
181
- class LocalBase : public IndirectHandleBase {
195
+ class LocalBase : public api_internal::IndirectHandleBase {
182
196
  protected:
183
197
  template <class F>
184
198
  friend class Local;
@@ -205,9 +219,14 @@ class LocalBase : public IndirectHandleBase {
205
219
  V8_INLINE static LocalBase<T> FromSlot(internal::Address* slot) {
206
220
  return LocalBase<T>(slot);
207
221
  }
222
+
223
+ V8_INLINE static LocalBase<T> FromRepr(
224
+ internal::ValueHelper::InternalRepresentationType repr) {
225
+ return LocalBase<T>(repr);
226
+ }
208
227
  };
209
228
 
210
- #endif // V8_ENABLE_DIRECT_LOCAL
229
+ #endif // V8_ENABLE_DIRECT_HANDLE
211
230
 
212
231
  /**
213
232
  * An object reference managed by the v8 garbage collector.
@@ -239,19 +258,27 @@ class LocalBase : public IndirectHandleBase {
239
258
  * to these values as to their handles.
240
259
  */
241
260
  template <class T>
242
- class Local : public LocalBase<T> {
261
+ class V8_TRIVIAL_ABI Local : public LocalBase<T>,
262
+ #ifdef V8_ENABLE_LOCAL_OFF_STACK_CHECK
263
+ public api_internal::StackAllocated<true>
264
+ #else
265
+ public api_internal::StackAllocated<false>
266
+ #endif
267
+ {
243
268
  public:
269
+ /**
270
+ * Default constructor: Returns an empty handle.
271
+ */
244
272
  V8_INLINE Local() = default;
245
273
 
274
+ /**
275
+ * Constructor for handling automatic up casting.
276
+ * Ex. Local<Object> can be passed when Local<Value> is expected but not
277
+ * the other way round.
278
+ */
246
279
  template <class S>
247
- V8_INLINE Local(Local<S> that) : LocalBase<T>(that) {
248
- /**
249
- * This check fails when trying to convert between incompatible
250
- * handles. For example, converting from a Local<String> to a
251
- * Local<Number>.
252
- */
253
- static_assert(std::is_base_of<T, S>::value, "type check");
254
- }
280
+ requires std::is_base_of_v<T, S>
281
+ V8_INLINE Local(Local<S> that) : LocalBase<T>(that) {}
255
282
 
256
283
  V8_INLINE T* operator->() const { return this->template value<T>(); }
257
284
 
@@ -291,7 +318,7 @@ class Local : public LocalBase<T> {
291
318
  /**
292
319
  * Cast a handle to a subclass, e.g. Local<Value> to Local<Object>.
293
320
  * This is only valid if the handle actually refers to a value of the
294
- * target type.
321
+ * target type or if the handle is empty.
295
322
  */
296
323
  template <class S>
297
324
  V8_INLINE static Local<T> Cast(Local<S> that) {
@@ -307,7 +334,7 @@ class Local : public LocalBase<T> {
307
334
  /**
308
335
  * Calling this is equivalent to Local<S>::Cast().
309
336
  * In particular, this is only valid if the handle actually refers to a value
310
- * of the target type.
337
+ * of the target type or if the handle is empty.
311
338
  */
312
339
  template <class S>
313
340
  V8_INLINE Local<S> As() const {
@@ -320,17 +347,17 @@ class Local : public LocalBase<T> {
320
347
  * the original handle is destroyed/disposed.
321
348
  */
322
349
  V8_INLINE static Local<T> New(Isolate* isolate, Local<T> that) {
323
- return New(isolate, that.template value<T>());
350
+ return New(isolate, that.template value<T, true>());
324
351
  }
325
352
 
326
353
  V8_INLINE static Local<T> New(Isolate* isolate,
327
354
  const PersistentBase<T>& that) {
328
- return New(isolate, that.template value<T>());
355
+ return New(isolate, that.template value<T, true>());
329
356
  }
330
357
 
331
358
  V8_INLINE static Local<T> New(Isolate* isolate,
332
359
  const BasicTracedReference<T>& that) {
333
- return New(isolate, that.template value<T>());
360
+ return New(isolate, that.template value<T, true>());
334
361
  }
335
362
 
336
363
  private:
@@ -363,10 +390,9 @@ class Local : public LocalBase<T> {
363
390
  friend Local<Boolean> False(Isolate* isolate);
364
391
  friend class HandleScope;
365
392
  friend class EscapableHandleScope;
393
+ friend class InternalEscapableScope;
366
394
  template <class F1, class F2, class F3>
367
395
  friend class PersistentValueMapBase;
368
- template <class F1, class F2>
369
- friend class PersistentValueVector;
370
396
  template <class F>
371
397
  friend class ReturnValue;
372
398
  template <class F>
@@ -374,19 +400,31 @@ class Local : public LocalBase<T> {
374
400
  friend class internal::SamplingHeapProfiler;
375
401
  friend class internal::HandleHelper;
376
402
  friend class debug::ConsoleCallArguments;
403
+ friend class internal::LocalUnchecked<T>;
404
+
405
+ explicit Local(no_checking_tag do_not_check)
406
+ : LocalBase<T>(), StackAllocated(do_not_check) {}
407
+ explicit Local(const Local<T>& other, no_checking_tag do_not_check)
408
+ : LocalBase<T>(other), StackAllocated(do_not_check) {}
377
409
 
378
- V8_INLINE explicit Local<T>(const LocalBase<T>& other)
379
- : LocalBase<T>(other) {}
410
+ V8_INLINE explicit Local(const LocalBase<T>& other) : LocalBase<T>(other) {}
411
+
412
+ V8_INLINE static Local<T> FromRepr(
413
+ internal::ValueHelper::InternalRepresentationType repr) {
414
+ return Local<T>(LocalBase<T>::FromRepr(repr));
415
+ }
380
416
 
381
417
  V8_INLINE static Local<T> FromSlot(internal::Address* slot) {
382
418
  return Local<T>(LocalBase<T>::FromSlot(slot));
383
419
  }
384
420
 
385
- #ifdef V8_ENABLE_DIRECT_LOCAL
421
+ #ifdef V8_ENABLE_DIRECT_HANDLE
422
+ friend class TypecheckWitness;
423
+
386
424
  V8_INLINE static Local<T> FromAddress(internal::Address ptr) {
387
425
  return Local<T>(LocalBase<T>(ptr));
388
426
  }
389
- #endif // V8_ENABLE_DIRECT_LOCAL
427
+ #endif // V8_ENABLE_DIRECT_HANDLE
390
428
 
391
429
  V8_INLINE static Local<T> New(Isolate* isolate, internal::Address value) {
392
430
  return Local<T>(LocalBase<T>::New(isolate, value));
@@ -403,6 +441,180 @@ class Local : public LocalBase<T> {
403
441
  }
404
442
  };
405
443
 
444
+ namespace internal {
445
+ // A local variant that is suitable for off-stack allocation.
446
+ // Used internally by LocalVector<T>. Not to be used directly!
447
+ template <typename T>
448
+ class V8_TRIVIAL_ABI LocalUnchecked : public Local<T> {
449
+ public:
450
+ LocalUnchecked() : Local<T>(Local<T>::do_not_check) {}
451
+
452
+ #if defined(V8_ENABLE_LOCAL_OFF_STACK_CHECK) && V8_HAS_ATTRIBUTE_TRIVIAL_ABI
453
+ // In this case, the check is also enforced in the copy constructor and we
454
+ // need to suppress it.
455
+ LocalUnchecked(
456
+ const LocalUnchecked& other) noexcept // NOLINT(runtime/explicit)
457
+ : Local<T>(other, Local<T>::do_not_check) {}
458
+ LocalUnchecked& operator=(const LocalUnchecked&) noexcept = default;
459
+ #endif
460
+
461
+ // Implicit conversion from Local.
462
+ LocalUnchecked(const Local<T>& other) noexcept // NOLINT(runtime/explicit)
463
+ : Local<T>(other, Local<T>::do_not_check) {}
464
+ };
465
+
466
+ #ifdef V8_ENABLE_DIRECT_HANDLE
467
+ // Off-stack allocated direct locals must be registered as strong roots.
468
+ // For off-stack indirect locals, this is not necessary.
469
+
470
+ template <typename T>
471
+ class StrongRootAllocator<LocalUnchecked<T>> : public StrongRootAllocatorBase {
472
+ public:
473
+ using value_type = LocalUnchecked<T>;
474
+ static_assert(std::is_standard_layout_v<value_type>);
475
+ static_assert(sizeof(value_type) == sizeof(Address));
476
+
477
+ template <typename HeapOrIsolateT>
478
+ explicit StrongRootAllocator(HeapOrIsolateT* heap_or_isolate)
479
+ : StrongRootAllocatorBase(heap_or_isolate) {}
480
+ template <typename U>
481
+ StrongRootAllocator(const StrongRootAllocator<U>& other) noexcept
482
+ : StrongRootAllocatorBase(other) {}
483
+
484
+ value_type* allocate(size_t n) {
485
+ return reinterpret_cast<value_type*>(allocate_impl(n));
486
+ }
487
+ void deallocate(value_type* p, size_t n) noexcept {
488
+ return deallocate_impl(reinterpret_cast<Address*>(p), n);
489
+ }
490
+ };
491
+ #endif // V8_ENABLE_DIRECT_HANDLE
492
+ } // namespace internal
493
+
494
+ template <typename T>
495
+ class LocalVector {
496
+ private:
497
+ using element_type = internal::LocalUnchecked<T>;
498
+
499
+ #ifdef V8_ENABLE_DIRECT_HANDLE
500
+ using allocator_type = internal::StrongRootAllocator<element_type>;
501
+
502
+ static allocator_type make_allocator(Isolate* isolate) noexcept {
503
+ return allocator_type(isolate);
504
+ }
505
+ #else
506
+ using allocator_type = std::allocator<element_type>;
507
+
508
+ static allocator_type make_allocator(Isolate* isolate) noexcept {
509
+ return allocator_type();
510
+ }
511
+ #endif // V8_ENABLE_DIRECT_HANDLE
512
+
513
+ using vector_type = std::vector<element_type, allocator_type>;
514
+
515
+ public:
516
+ using value_type = Local<T>;
517
+ using reference = value_type&;
518
+ using const_reference = const value_type&;
519
+ using size_type = size_t;
520
+ using difference_type = ptrdiff_t;
521
+ using iterator =
522
+ internal::WrappedIterator<typename vector_type::iterator, Local<T>>;
523
+ using const_iterator =
524
+ internal::WrappedIterator<typename vector_type::const_iterator,
525
+ const Local<T>>;
526
+
527
+ explicit LocalVector(Isolate* isolate) : backing_(make_allocator(isolate)) {}
528
+ LocalVector(Isolate* isolate, size_t n)
529
+ : backing_(n, make_allocator(isolate)) {}
530
+ explicit LocalVector(Isolate* isolate, std::initializer_list<Local<T>> init)
531
+ : backing_(make_allocator(isolate)) {
532
+ if (init.size() == 0) return;
533
+ backing_.reserve(init.size());
534
+ backing_.insert(backing_.end(), init.begin(), init.end());
535
+ }
536
+
537
+ iterator begin() noexcept { return iterator(backing_.begin()); }
538
+ const_iterator begin() const noexcept {
539
+ return const_iterator(backing_.begin());
540
+ }
541
+ iterator end() noexcept { return iterator(backing_.end()); }
542
+ const_iterator end() const noexcept { return const_iterator(backing_.end()); }
543
+
544
+ size_t size() const noexcept { return backing_.size(); }
545
+ bool empty() const noexcept { return backing_.empty(); }
546
+ void reserve(size_t n) { backing_.reserve(n); }
547
+ void shrink_to_fit() { backing_.shrink_to_fit(); }
548
+
549
+ Local<T>& operator[](size_t n) { return backing_[n]; }
550
+ const Local<T>& operator[](size_t n) const { return backing_[n]; }
551
+
552
+ Local<T>& at(size_t n) { return backing_.at(n); }
553
+ const Local<T>& at(size_t n) const { return backing_.at(n); }
554
+
555
+ Local<T>& front() { return backing_.front(); }
556
+ const Local<T>& front() const { return backing_.front(); }
557
+ Local<T>& back() { return backing_.back(); }
558
+ const Local<T>& back() const { return backing_.back(); }
559
+
560
+ Local<T>* data() noexcept { return backing_.data(); }
561
+ const Local<T>* data() const noexcept { return backing_.data(); }
562
+
563
+ iterator insert(const_iterator pos, const Local<T>& value) {
564
+ return iterator(backing_.insert(pos.base(), value));
565
+ }
566
+
567
+ template <typename InputIt>
568
+ iterator insert(const_iterator pos, InputIt first, InputIt last) {
569
+ return iterator(backing_.insert(pos.base(), first, last));
570
+ }
571
+
572
+ iterator insert(const_iterator pos, std::initializer_list<Local<T>> init) {
573
+ return iterator(backing_.insert(pos.base(), init.begin(), init.end()));
574
+ }
575
+
576
+ LocalVector<T>& operator=(std::initializer_list<Local<T>> init) {
577
+ backing_.clear();
578
+ backing_.reserve(init.size());
579
+ backing_.insert(backing_.end(), init.begin(), init.end());
580
+ return *this;
581
+ }
582
+
583
+ void push_back(const Local<T>& x) { backing_.push_back(x); }
584
+ void pop_back() { backing_.pop_back(); }
585
+
586
+ template <typename... Args>
587
+ void emplace_back(Args&&... args) {
588
+ backing_.push_back(value_type{std::forward<Args>(args)...});
589
+ }
590
+
591
+ void clear() noexcept { backing_.clear(); }
592
+ void resize(size_t n) { backing_.resize(n); }
593
+ void swap(LocalVector<T>& other) { backing_.swap(other.backing_); }
594
+
595
+ friend bool operator==(const LocalVector<T>& x, const LocalVector<T>& y) {
596
+ return x.backing_ == y.backing_;
597
+ }
598
+ friend bool operator!=(const LocalVector<T>& x, const LocalVector<T>& y) {
599
+ return x.backing_ != y.backing_;
600
+ }
601
+ friend bool operator<(const LocalVector<T>& x, const LocalVector<T>& y) {
602
+ return x.backing_ < y.backing_;
603
+ }
604
+ friend bool operator>(const LocalVector<T>& x, const LocalVector<T>& y) {
605
+ return x.backing_ > y.backing_;
606
+ }
607
+ friend bool operator<=(const LocalVector<T>& x, const LocalVector<T>& y) {
608
+ return x.backing_ <= y.backing_;
609
+ }
610
+ friend bool operator>=(const LocalVector<T>& x, const LocalVector<T>& y) {
611
+ return x.backing_ >= y.backing_;
612
+ }
613
+
614
+ private:
615
+ vector_type backing_;
616
+ };
617
+
406
618
  #if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
407
619
  // Handle is an alias for Local for historical reasons.
408
620
  template <class T>
@@ -422,9 +634,22 @@ using Handle = Local<T>;
422
634
  template <class T>
423
635
  class MaybeLocal {
424
636
  public:
425
- V8_INLINE MaybeLocal() : local_() {}
637
+ /**
638
+ * Default constructor: Returns an empty handle.
639
+ */
640
+ V8_INLINE MaybeLocal() = default;
641
+ /**
642
+ * Implicitly construct MaybeLocal from Local.
643
+ */
426
644
  template <class S>
645
+ requires std::is_base_of_v<T, S>
427
646
  V8_INLINE MaybeLocal(Local<S> that) : local_(that) {}
647
+ /**
648
+ * Implicitly up-cast MaybeLocal<S> to MaybeLocal<T> if T is a base of S.
649
+ */
650
+ template <class S>
651
+ requires std::is_base_of_v<T, S>
652
+ V8_INLINE MaybeLocal(MaybeLocal<S> that) : local_(that.local_) {}
428
653
 
429
654
  V8_INLINE bool IsEmpty() const { return local_.IsEmpty(); }
430
655
 
@@ -456,29 +681,73 @@ class MaybeLocal {
456
681
  return IsEmpty() ? default_value : Local<S>(local_);
457
682
  }
458
683
 
684
+ /**
685
+ * Cast a handle to a subclass, e.g. MaybeLocal<Value> to MaybeLocal<Object>.
686
+ * This is only valid if the handle actually refers to a value of the target
687
+ * type or if the handle is empty.
688
+ */
689
+ template <class S>
690
+ V8_INLINE static MaybeLocal<T> Cast(MaybeLocal<S> that) {
691
+ return MaybeLocal<T>{Local<T>::Cast(that.local_)};
692
+ }
693
+
694
+ /**
695
+ * Calling this is equivalent to MaybeLocal<S>::Cast().
696
+ * In particular, this is only valid if the handle actually refers to a value
697
+ * of the target type or if the handle is empty.
698
+ */
699
+ template <class S>
700
+ V8_INLINE MaybeLocal<S> As() const {
701
+ return MaybeLocal<S>::Cast(*this);
702
+ }
703
+
459
704
  private:
460
705
  Local<T> local_;
706
+
707
+ template <typename S>
708
+ friend class MaybeLocal;
461
709
  };
462
710
 
463
711
  /**
464
712
  * A HandleScope which first allocates a handle in the current scope
465
713
  * which will be later filled with the escape value.
466
714
  */
467
- class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope {
715
+ class V8_EXPORT V8_NODISCARD EscapableHandleScopeBase : public HandleScope {
468
716
  public:
469
- explicit EscapableHandleScope(Isolate* isolate);
470
- V8_INLINE ~EscapableHandleScope() = default;
717
+ explicit EscapableHandleScopeBase(Isolate* isolate);
718
+ V8_INLINE ~EscapableHandleScopeBase() = default;
471
719
 
720
+ EscapableHandleScopeBase(const EscapableHandleScopeBase&) = delete;
721
+ void operator=(const EscapableHandleScopeBase&) = delete;
722
+ void* operator new(size_t size) = delete;
723
+ void* operator new[](size_t size) = delete;
724
+ void operator delete(void*, size_t) = delete;
725
+ void operator delete[](void*, size_t) = delete;
726
+
727
+ protected:
472
728
  /**
473
729
  * Pushes the value into the previous scope and returns a handle to it.
474
730
  * Cannot be called twice.
475
731
  */
732
+ internal::Address* EscapeSlot(internal::Address* escape_value);
733
+
734
+ private:
735
+ internal::Address* escape_slot_;
736
+ };
737
+
738
+ class V8_EXPORT V8_NODISCARD EscapableHandleScope
739
+ : public EscapableHandleScopeBase {
740
+ public:
741
+ explicit EscapableHandleScope(Isolate* isolate)
742
+ : EscapableHandleScopeBase(isolate) {}
743
+ V8_INLINE ~EscapableHandleScope() = default;
476
744
  template <class T>
477
745
  V8_INLINE Local<T> Escape(Local<T> value) {
478
- #ifdef V8_ENABLE_DIRECT_LOCAL
746
+ #ifdef V8_ENABLE_DIRECT_HANDLE
479
747
  return value;
480
748
  #else
481
- return Local<T>::FromSlot(Escape(value.slot()));
749
+ if (value.IsEmpty()) return value;
750
+ return Local<T>::FromSlot(EscapeSlot(value.slot()));
482
751
  #endif
483
752
  }
484
753
 
@@ -486,20 +755,6 @@ class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope {
486
755
  V8_INLINE MaybeLocal<T> EscapeMaybe(MaybeLocal<T> value) {
487
756
  return Escape(value.FromMaybe(Local<T>()));
488
757
  }
489
-
490
- EscapableHandleScope(const EscapableHandleScope&) = delete;
491
- void operator=(const EscapableHandleScope&) = delete;
492
-
493
- private:
494
- // Declaring operator new and delete as deleted is not spec compliant.
495
- // Therefore declare them private instead to disable dynamic alloc
496
- void* operator new(size_t size);
497
- void* operator new[](size_t size);
498
- void operator delete(void*, size_t);
499
- void operator delete[](void*, size_t);
500
-
501
- internal::Address* Escape(internal::Address* escape_value);
502
- internal::Address* escape_slot_;
503
758
  };
504
759
 
505
760
  /**
@@ -514,15 +769,12 @@ class V8_EXPORT V8_NODISCARD SealHandleScope {
514
769
 
515
770
  SealHandleScope(const SealHandleScope&) = delete;
516
771
  void operator=(const SealHandleScope&) = delete;
772
+ void* operator new(size_t size) = delete;
773
+ void* operator new[](size_t size) = delete;
774
+ void operator delete(void*, size_t) = delete;
775
+ void operator delete[](void*, size_t) = delete;
517
776
 
518
777
  private:
519
- // Declaring operator new and delete as deleted is not spec compliant.
520
- // Therefore declare them private instead to disable dynamic alloc
521
- void* operator new(size_t size);
522
- void* operator new[](size_t size);
523
- void operator delete(void*, size_t);
524
- void operator delete[](void*, size_t);
525
-
526
778
  internal::Isolate* const i_isolate_;
527
779
  internal::Address* prev_limit_;
528
780
  int prev_sealed_level_;
@@ -8,6 +8,7 @@
8
8
  #include <type_traits>
9
9
  #include <utility>
10
10
 
11
+ #include "cppgc/internal/conditional-stack-allocated.h" // NOLINT(build/include_directory)
11
12
  #include "v8-internal.h" // NOLINT(build/include_directory)
12
13
  #include "v8config.h" // NOLINT(build/include_directory)
13
14
 
@@ -29,7 +30,7 @@ V8_EXPORT void FromJustIsNothing();
29
30
  * "Nothing" value is returned.
30
31
  */
31
32
  template <class T>
32
- class Maybe {
33
+ class Maybe : public cppgc::internal::ConditionalStackAllocatedBase<T> {
33
34
  public:
34
35
  V8_INLINE bool IsNothing() const { return !has_value_; }
35
36
  V8_INLINE bool IsJust() const { return has_value_; }