1use crate::Array;
3use crate::CallbackScope;
4use crate::Context;
5use crate::Data;
6use crate::FixedArray;
7use crate::Function;
8use crate::FunctionCodeHandling;
9use crate::Local;
10use crate::Message;
11use crate::Module;
12use crate::Object;
13use crate::PinScope;
14use crate::Platform;
15use crate::Promise;
16use crate::PromiseResolver;
17use crate::StartupData;
18use crate::String;
19use crate::V8::get_current_platform;
20use crate::Value;
21use crate::binding::v8__HeapCodeStatistics;
22use crate::binding::v8__HeapSpaceStatistics;
23use crate::binding::v8__HeapStatistics;
24use crate::binding::v8__Isolate__UseCounterFeature;
25pub use crate::binding::v8__ModuleImportPhase as ModuleImportPhase;
26use crate::cppgc::Heap;
27use crate::external_references::ExternalReference;
28use crate::function::FunctionCallbackInfo;
29use crate::gc::GCCallbackFlags;
30use crate::gc::GCType;
31use crate::handle::FinalizerCallback;
32use crate::handle::FinalizerMap;
33use crate::isolate_create_params::CreateParams;
34use crate::isolate_create_params::raw;
35use crate::promise::PromiseRejectMessage;
36use crate::snapshot::SnapshotCreator;
37use crate::support::MapFnFrom;
38use crate::support::MapFnTo;
39use crate::support::Opaque;
40use crate::support::ToCFn;
41use crate::support::UnitType;
42use crate::support::char;
43use crate::support::int;
44use crate::support::size_t;
45use crate::wasm::WasmStreaming;
46use crate::wasm::trampoline;
47use std::cell::UnsafeCell;
48use std::ffi::CStr;
49
50use std::any::Any;
51use std::any::TypeId;
52use std::borrow::Cow;
53use std::collections::HashMap;
54use std::ffi::c_void;
55use std::fmt::{self, Debug, Formatter};
56use std::hash::BuildHasher;
57use std::hash::Hasher;
58use std::mem::MaybeUninit;
59use std::mem::align_of;
60use std::mem::forget;
61use std::mem::needs_drop;
62use std::mem::size_of;
63use std::ops::Deref;
64use std::ops::DerefMut;
65use std::pin::pin;
66use std::ptr;
67use std::ptr::NonNull;
68use std::ptr::addr_of_mut;
69use std::ptr::drop_in_place;
70use std::ptr::null_mut;
71use std::sync::Arc;
72use std::sync::Mutex;
73use std::sync::atomic::AtomicPtr;
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81#[repr(C)]
82pub enum MicrotasksPolicy {
83 Explicit = 0,
84 Auto = 2,
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
95#[repr(C)]
96pub enum MemoryPressureLevel {
97 None = 0,
98 Moderate = 1,
99 Critical = 2,
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
114#[repr(C)]
115pub enum TimeZoneDetection {
116 Skip = 0,
117 Redetect = 1,
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq)]
135#[repr(C)]
136pub enum PromiseHookType {
137 Init,
138 Resolve,
139 Before,
140 After,
141}
142
143#[derive(Debug, Clone, Copy, PartialEq, Eq)]
146#[repr(C)]
147pub enum GarbageCollectionType {
148 Full,
149 Minor,
150}
151
152pub type MessageCallback = unsafe extern "C" fn(Local<Message>, Local<Value>);
153
154bitflags! {
155 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
156 #[repr(transparent)]
157 pub struct MessageErrorLevel: int {
158 const LOG = 1 << 0;
159 const DEBUG = 1 << 1;
160 const INFO = 1 << 2;
161 const ERROR = 1 << 3;
162 const WARNING = 1 << 4;
163 const ALL = (1 << 5) - 1;
164 }
165}
166
167pub type PromiseHook =
168 unsafe extern "C" fn(PromiseHookType, Local<Promise>, Local<Value>);
169
170pub type PromiseRejectCallback = unsafe extern "C" fn(PromiseRejectMessage);
171
172#[derive(Debug, Clone, Copy, PartialEq, Eq)]
173#[repr(C)]
174pub enum WasmAsyncSuccess {
175 Success,
176 Fail,
177}
178pub type WasmAsyncResolvePromiseCallback = unsafe extern "C" fn(
179 UnsafeRawIsolatePtr,
180 Local<Context>,
181 Local<PromiseResolver>,
182 Local<Value>,
183 WasmAsyncSuccess,
184);
185
186pub type AllowWasmCodeGenerationCallback =
187 unsafe extern "C" fn(Local<Context>, Local<String>) -> bool;
188
189pub type HostInitializeImportMetaObjectCallback =
198 unsafe extern "C" fn(Local<Context>, Local<Module>, Local<Object>);
199
200pub trait HostImportModuleDynamicallyCallback:
240 UnitType
241 + for<'s, 'i> FnOnce(
242 &mut PinScope<'s, 'i>,
243 Local<'s, Data>,
244 Local<'s, Value>,
245 Local<'s, String>,
246 Local<'s, FixedArray>,
247 ) -> Option<Local<'s, Promise>>
248{
249 fn to_c_fn(self) -> RawHostImportModuleDynamicallyCallback;
250}
251
252#[cfg(target_family = "unix")]
253pub(crate) type RawHostImportModuleDynamicallyCallback =
254 for<'s> unsafe extern "C" fn(
255 Local<'s, Context>,
256 Local<'s, Data>,
257 Local<'s, Value>,
258 Local<'s, String>,
259 Local<'s, FixedArray>,
260 ) -> *mut Promise;
261
262#[cfg(all(
263 target_family = "windows",
264 any(target_arch = "x86_64", target_arch = "aarch64")
265))]
266pub type RawHostImportModuleDynamicallyCallback =
267 for<'s> unsafe extern "C" fn(
268 *mut *mut Promise,
269 Local<'s, Context>,
270 Local<'s, Data>,
271 Local<'s, Value>,
272 Local<'s, String>,
273 Local<'s, FixedArray>,
274 ) -> *mut *mut Promise;
275
276impl<F> HostImportModuleDynamicallyCallback for F
277where
278 F: UnitType
279 + for<'s, 'i> FnOnce(
280 &mut PinScope<'s, 'i>,
281 Local<'s, Data>,
282 Local<'s, Value>,
283 Local<'s, String>,
284 Local<'s, FixedArray>,
285 ) -> Option<Local<'s, Promise>>,
286{
287 #[inline(always)]
288 fn to_c_fn(self) -> RawHostImportModuleDynamicallyCallback {
289 #[allow(unused_variables)]
290 #[inline(always)]
291 fn scope_adapter<'s, 'i: 's, F: HostImportModuleDynamicallyCallback>(
292 context: Local<'s, Context>,
293 host_defined_options: Local<'s, Data>,
294 resource_name: Local<'s, Value>,
295 specifier: Local<'s, String>,
296 import_attributes: Local<'s, FixedArray>,
297 ) -> Option<Local<'s, Promise>> {
298 let scope = pin!(unsafe { CallbackScope::new(context) });
299 let mut scope = scope.init();
300 (F::get())(
301 &mut scope,
302 host_defined_options,
303 resource_name,
304 specifier,
305 import_attributes,
306 )
307 }
308
309 #[cfg(target_family = "unix")]
310 #[inline(always)]
311 unsafe extern "C" fn abi_adapter<
312 's,
313 F: HostImportModuleDynamicallyCallback,
314 >(
315 context: Local<'s, Context>,
316 host_defined_options: Local<'s, Data>,
317 resource_name: Local<'s, Value>,
318 specifier: Local<'s, String>,
319 import_attributes: Local<'s, FixedArray>,
320 ) -> *mut Promise {
321 scope_adapter::<F>(
322 context,
323 host_defined_options,
324 resource_name,
325 specifier,
326 import_attributes,
327 )
328 .map_or_else(null_mut, |return_value| return_value.as_non_null().as_ptr())
329 }
330
331 #[cfg(all(
332 target_family = "windows",
333 any(target_arch = "x86_64", target_arch = "aarch64")
334 ))]
335 #[inline(always)]
336 unsafe extern "C" fn abi_adapter<
337 's,
338 F: HostImportModuleDynamicallyCallback,
339 >(
340 return_value: *mut *mut Promise,
341 context: Local<'s, Context>,
342 host_defined_options: Local<'s, Data>,
343 resource_name: Local<'s, Value>,
344 specifier: Local<'s, String>,
345 import_attributes: Local<'s, FixedArray>,
346 ) -> *mut *mut Promise {
347 unsafe {
348 std::ptr::write(
349 return_value,
350 scope_adapter::<F>(
351 context,
352 host_defined_options,
353 resource_name,
354 specifier,
355 import_attributes,
356 )
357 .map(|return_value| return_value.as_non_null().as_ptr())
358 .unwrap_or_else(null_mut),
359 );
360 return_value
361 }
362 }
363
364 abi_adapter::<F>
365 }
366}
367
368pub trait HostImportModuleWithPhaseDynamicallyCallback:
403 UnitType
404 + for<'s, 'i> FnOnce(
405 &mut PinScope<'s, 'i>,
406 Local<'s, Data>,
407 Local<'s, Value>,
408 Local<'s, String>,
409 ModuleImportPhase,
410 Local<'s, FixedArray>,
411 ) -> Option<Local<'s, Promise>>
412{
413 fn to_c_fn(self) -> RawHostImportModuleWithPhaseDynamicallyCallback;
414}
415
416#[cfg(target_family = "unix")]
417pub(crate) type RawHostImportModuleWithPhaseDynamicallyCallback =
418 for<'s> unsafe extern "C" fn(
419 Local<'s, Context>,
420 Local<'s, Data>,
421 Local<'s, Value>,
422 Local<'s, String>,
423 ModuleImportPhase,
424 Local<'s, FixedArray>,
425 ) -> *mut Promise;
426
427#[cfg(all(
428 target_family = "windows",
429 any(target_arch = "x86_64", target_arch = "aarch64")
430))]
431pub type RawHostImportModuleWithPhaseDynamicallyCallback =
432 for<'s> unsafe extern "C" fn(
433 *mut *mut Promise,
434 Local<'s, Context>,
435 Local<'s, Data>,
436 Local<'s, Value>,
437 Local<'s, String>,
438 ModuleImportPhase,
439 Local<'s, FixedArray>,
440 ) -> *mut *mut Promise;
441
442impl<F> HostImportModuleWithPhaseDynamicallyCallback for F
443where
444 F: UnitType
445 + for<'s, 'i> FnOnce(
446 &mut PinScope<'s, 'i>,
447 Local<'s, Data>,
448 Local<'s, Value>,
449 Local<'s, String>,
450 ModuleImportPhase,
451 Local<'s, FixedArray>,
452 ) -> Option<Local<'s, Promise>>,
453{
454 #[inline(always)]
455 fn to_c_fn(self) -> RawHostImportModuleWithPhaseDynamicallyCallback {
456 #[allow(unused_variables)]
457 #[inline(always)]
458 fn scope_adapter<'s, F: HostImportModuleWithPhaseDynamicallyCallback>(
459 context: Local<'s, Context>,
460 host_defined_options: Local<'s, Data>,
461 resource_name: Local<'s, Value>,
462 specifier: Local<'s, String>,
463 import_phase: ModuleImportPhase,
464 import_attributes: Local<'s, FixedArray>,
465 ) -> Option<Local<'s, Promise>> {
466 let scope = pin!(unsafe { CallbackScope::new(context) });
467 let mut scope = scope.init();
468 (F::get())(
469 &mut scope,
470 host_defined_options,
471 resource_name,
472 specifier,
473 import_phase,
474 import_attributes,
475 )
476 }
477
478 #[cfg(target_family = "unix")]
479 #[inline(always)]
480 unsafe extern "C" fn abi_adapter<
481 's,
482 F: HostImportModuleWithPhaseDynamicallyCallback,
483 >(
484 context: Local<'s, Context>,
485 host_defined_options: Local<'s, Data>,
486 resource_name: Local<'s, Value>,
487 specifier: Local<'s, String>,
488 import_phase: ModuleImportPhase,
489 import_attributes: Local<'s, FixedArray>,
490 ) -> *mut Promise {
491 scope_adapter::<F>(
492 context,
493 host_defined_options,
494 resource_name,
495 specifier,
496 import_phase,
497 import_attributes,
498 )
499 .map_or_else(null_mut, |return_value| return_value.as_non_null().as_ptr())
500 }
501
502 #[cfg(all(
503 target_family = "windows",
504 any(target_arch = "x86_64", target_arch = "aarch64")
505 ))]
506 #[inline(always)]
507 unsafe extern "C" fn abi_adapter<
508 's,
509 F: HostImportModuleWithPhaseDynamicallyCallback,
510 >(
511 return_value: *mut *mut Promise,
512 context: Local<'s, Context>,
513 host_defined_options: Local<'s, Data>,
514 resource_name: Local<'s, Value>,
515 specifier: Local<'s, String>,
516 import_phase: ModuleImportPhase,
517 import_attributes: Local<'s, FixedArray>,
518 ) -> *mut *mut Promise {
519 unsafe {
520 std::ptr::write(
521 return_value,
522 scope_adapter::<F>(
523 context,
524 host_defined_options,
525 resource_name,
526 specifier,
527 import_phase,
528 import_attributes,
529 )
530 .map(|return_value| return_value.as_non_null().as_ptr())
531 .unwrap_or_else(null_mut),
532 );
533 return_value
534 }
535 }
536
537 abi_adapter::<F>
538 }
539}
540
541pub type HostCreateShadowRealmContextCallback =
552 for<'s, 'i> fn(scope: &mut PinScope<'s, 'i>) -> Option<Local<'s, Context>>;
553
554pub type GcCallbackWithData = unsafe extern "C" fn(
555 isolate: UnsafeRawIsolatePtr,
556 r#type: GCType,
557 flags: GCCallbackFlags,
558 data: *mut c_void,
559);
560
561pub type InterruptCallback =
562 unsafe extern "C" fn(isolate: UnsafeRawIsolatePtr, data: *mut c_void);
563
564pub type NearHeapLimitCallback = unsafe extern "C" fn(
565 data: *mut c_void,
566 current_heap_limit: usize,
567 initial_heap_limit: usize,
568) -> usize;
569
570#[repr(C)]
571pub struct OomDetails {
572 pub is_heap_oom: bool,
573 pub detail: *const char,
574}
575
576pub type OomErrorCallback =
577 unsafe extern "C" fn(location: *const char, details: &OomDetails);
578
579#[cfg(target_os = "windows")]
581pub type PrepareStackTraceCallback<'s> =
582 unsafe extern "C" fn(
583 *mut *const Value,
584 Local<'s, Context>,
585 Local<'s, Value>,
586 Local<'s, Array>,
587 ) -> *mut *const Value;
588
589#[cfg(not(target_os = "windows"))]
590pub type PrepareStackTraceCallback<'s> =
591 unsafe extern "C" fn(
592 Local<'s, Context>,
593 Local<'s, Value>,
594 Local<'s, Array>,
595 ) -> PrepareStackTraceCallbackRet;
596
597#[cfg(not(target_os = "windows"))]
600#[repr(C)]
601pub struct PrepareStackTraceCallbackRet(*const Value);
602
603pub type UseCounterFeature = v8__Isolate__UseCounterFeature;
604pub type UseCounterCallback =
605 unsafe extern "C" fn(&mut Isolate, UseCounterFeature);
606
607unsafe extern "C" {
608 fn v8__Isolate__New(params: *const raw::CreateParams) -> *mut RealIsolate;
609 fn v8__Isolate__Dispose(this: *mut RealIsolate);
610 fn v8__Isolate__GetNumberOfDataSlots(this: *const RealIsolate) -> u32;
611 fn v8__Isolate__GetData(
612 isolate: *const RealIsolate,
613 slot: u32,
614 ) -> *mut c_void;
615 fn v8__Isolate__SetData(
616 isolate: *const RealIsolate,
617 slot: u32,
618 data: *mut c_void,
619 );
620 fn v8__Isolate__Enter(this: *mut RealIsolate);
621 fn v8__Isolate__Exit(this: *mut RealIsolate);
622 fn v8__Isolate__GetCurrent() -> *mut RealIsolate;
623 fn v8__Isolate__MemoryPressureNotification(this: *mut RealIsolate, level: u8);
624 fn v8__Isolate__ClearKeptObjects(isolate: *mut RealIsolate);
625 fn v8__Isolate__LowMemoryNotification(isolate: *mut RealIsolate);
626 fn v8__Isolate__SetIdle(isolate: *mut RealIsolate, is_idle: bool);
627 fn v8__CpuProfiler__CollectSample(
628 isolate: *mut RealIsolate,
629 trace_id: *const u64,
630 );
631 fn v8__CpuProfiler__UseDetailedSourcePositionsForProfiling(
632 isolate: *mut RealIsolate,
633 );
634 fn v8__Isolate__GetHeapStatistics(
635 this: *mut RealIsolate,
636 s: *mut v8__HeapStatistics,
637 );
638 fn v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(
639 this: *mut RealIsolate,
640 capture: bool,
641 frame_limit: i32,
642 );
643 fn v8__Isolate__AddMessageListener(
644 isolate: *mut RealIsolate,
645 callback: MessageCallback,
646 ) -> bool;
647 fn v8__Isolate__AddMessageListenerWithErrorLevel(
648 isolate: *mut RealIsolate,
649 callback: MessageCallback,
650 message_levels: MessageErrorLevel,
651 ) -> bool;
652 fn v8__Isolate__AddGCPrologueCallback(
653 isolate: *mut RealIsolate,
654 callback: GcCallbackWithData,
655 data: *mut c_void,
656 gc_type_filter: GCType,
657 );
658 fn v8__Isolate__RemoveGCPrologueCallback(
659 isolate: *mut RealIsolate,
660 callback: GcCallbackWithData,
661 data: *mut c_void,
662 );
663 fn v8__Isolate__AddGCEpilogueCallback(
664 isolate: *mut RealIsolate,
665 callback: GcCallbackWithData,
666 data: *mut c_void,
667 gc_type_filter: GCType,
668 );
669 fn v8__Isolate__RemoveGCEpilogueCallback(
670 isolate: *mut RealIsolate,
671 callback: GcCallbackWithData,
672 data: *mut c_void,
673 );
674 fn v8__Isolate__NumberOfHeapSpaces(isolate: *mut RealIsolate) -> size_t;
675 fn v8__Isolate__GetHeapSpaceStatistics(
676 isolate: *mut RealIsolate,
677 space_statistics: *mut v8__HeapSpaceStatistics,
678 index: size_t,
679 ) -> bool;
680 fn v8__Isolate__GetHeapCodeAndMetadataStatistics(
681 isolate: *mut RealIsolate,
682 code_statistics: *mut v8__HeapCodeStatistics,
683 ) -> bool;
684 fn v8__Isolate__AddNearHeapLimitCallback(
685 isolate: *mut RealIsolate,
686 callback: NearHeapLimitCallback,
687 data: *mut c_void,
688 );
689 fn v8__Isolate__RemoveNearHeapLimitCallback(
690 isolate: *mut RealIsolate,
691 callback: NearHeapLimitCallback,
692 heap_limit: usize,
693 );
694 fn v8__Isolate__SetOOMErrorHandler(
695 isolate: *mut RealIsolate,
696 callback: OomErrorCallback,
697 );
698 fn v8__Isolate__AdjustAmountOfExternalAllocatedMemory(
699 isolate: *mut RealIsolate,
700 change_in_bytes: i64,
701 ) -> i64;
702 fn v8__Isolate__GetCppHeap(isolate: *mut RealIsolate) -> *mut Heap;
703 fn v8__Isolate__SetPrepareStackTraceCallback(
704 isolate: *mut RealIsolate,
705 callback: PrepareStackTraceCallback,
706 );
707 fn v8__Isolate__SetPromiseHook(isolate: *mut RealIsolate, hook: PromiseHook);
708 fn v8__Isolate__SetPromiseRejectCallback(
709 isolate: *mut RealIsolate,
710 callback: PromiseRejectCallback,
711 );
712 fn v8__Isolate__SetWasmAsyncResolvePromiseCallback(
713 isolate: *mut RealIsolate,
714 callback: WasmAsyncResolvePromiseCallback,
715 );
716 fn v8__Isolate__SetAllowWasmCodeGenerationCallback(
717 isolate: *mut RealIsolate,
718 callback: AllowWasmCodeGenerationCallback,
719 );
720 fn v8__Isolate__SetHostInitializeImportMetaObjectCallback(
721 isolate: *mut RealIsolate,
722 callback: HostInitializeImportMetaObjectCallback,
723 );
724 fn v8__Isolate__SetHostImportModuleDynamicallyCallback(
725 isolate: *mut RealIsolate,
726 callback: RawHostImportModuleDynamicallyCallback,
727 );
728 fn v8__Isolate__SetHostImportModuleWithPhaseDynamicallyCallback(
729 isolate: *mut RealIsolate,
730 callback: RawHostImportModuleWithPhaseDynamicallyCallback,
731 );
732 #[cfg(not(target_os = "windows"))]
733 fn v8__Isolate__SetHostCreateShadowRealmContextCallback(
734 isolate: *mut RealIsolate,
735 callback: unsafe extern "C" fn(
736 initiator_context: Local<Context>,
737 ) -> *mut Context,
738 );
739 #[cfg(target_os = "windows")]
740 fn v8__Isolate__SetHostCreateShadowRealmContextCallback(
741 isolate: *mut RealIsolate,
742 callback: unsafe extern "C" fn(
743 rv: *mut *mut Context,
744 initiator_context: Local<Context>,
745 ) -> *mut *mut Context,
746 );
747 fn v8__Isolate__SetUseCounterCallback(
748 isolate: *mut RealIsolate,
749 callback: UseCounterCallback,
750 );
751 fn v8__Isolate__RequestInterrupt(
752 isolate: *const RealIsolate,
753 callback: InterruptCallback,
754 data: *mut c_void,
755 );
756 fn v8__Isolate__TerminateExecution(isolate: *const RealIsolate);
757 fn v8__Isolate__IsExecutionTerminating(isolate: *const RealIsolate) -> bool;
758 fn v8__Isolate__CancelTerminateExecution(isolate: *const RealIsolate);
759 fn v8__Isolate__GetMicrotasksPolicy(
760 isolate: *const RealIsolate,
761 ) -> MicrotasksPolicy;
762 fn v8__Isolate__SetMicrotasksPolicy(
763 isolate: *mut RealIsolate,
764 policy: MicrotasksPolicy,
765 );
766 fn v8__Isolate__PerformMicrotaskCheckpoint(isolate: *mut RealIsolate);
767 fn v8__Isolate__EnqueueMicrotask(
768 isolate: *mut RealIsolate,
769 function: *const Function,
770 );
771 fn v8__Isolate__SetAllowAtomicsWait(isolate: *mut RealIsolate, allow: bool);
772 fn v8__Isolate__SetWasmStreamingCallback(
773 isolate: *mut RealIsolate,
774 callback: unsafe extern "C" fn(*const FunctionCallbackInfo),
775 );
776 fn v8__Isolate__DateTimeConfigurationChangeNotification(
777 isolate: *mut RealIsolate,
778 time_zone_detection: TimeZoneDetection,
779 );
780 fn v8__Isolate__HasPendingBackgroundTasks(
781 isolate: *const RealIsolate,
782 ) -> bool;
783 fn v8__Isolate__RequestGarbageCollectionForTesting(
784 isolate: *mut RealIsolate,
785 r#type: usize,
786 );
787
788 fn v8__HeapProfiler__TakeHeapSnapshot(
789 isolate: *mut RealIsolate,
790 callback: unsafe extern "C" fn(*mut c_void, *const u8, usize) -> bool,
791 arg: *mut c_void,
792 );
793}
794
795#[repr(transparent)]
806#[derive(Debug)]
807pub struct Isolate(NonNull<RealIsolate>);
808
809#[repr(transparent)]
810#[derive(Debug, Clone, Copy)]
811pub struct UnsafeRawIsolatePtr(*mut RealIsolate);
812
813impl UnsafeRawIsolatePtr {
814 #[inline]
815 pub(crate) fn from_real_ptr(ptr: *mut RealIsolate) -> Self {
816 Self(ptr)
817 }
818
819 pub fn null() -> Self {
820 Self(std::ptr::null_mut())
821 }
822
823 pub fn is_null(&self) -> bool {
824 self.0.is_null()
825 }
826
827 #[inline]
828 pub(crate) fn as_real_ptr(&self) -> *mut RealIsolate {
829 self.0
830 }
831}
832
833#[repr(C)]
834pub struct RealIsolate(Opaque);
835
836impl Isolate {
837 pub(crate) fn as_real_ptr(&self) -> *mut RealIsolate {
838 self.0.as_ptr()
839 }
840
841 pub unsafe fn as_raw_isolate_ptr(&self) -> UnsafeRawIsolatePtr {
842 UnsafeRawIsolatePtr(self.0.as_ptr())
843 }
844
845 #[inline]
846 pub unsafe fn from_raw_isolate_ptr(ptr: UnsafeRawIsolatePtr) -> Self {
847 Self(NonNull::new(ptr.0).unwrap())
848 }
849
850 #[inline]
851 pub unsafe fn from_raw_isolate_ptr_unchecked(
852 ptr: UnsafeRawIsolatePtr,
853 ) -> Self {
854 Self(unsafe { NonNull::new_unchecked(ptr.0) })
855 }
856
857 pub unsafe fn from_raw_ptr_unchecked(ptr: *mut RealIsolate) -> Self {
858 Self(unsafe { NonNull::new_unchecked(ptr) })
859 }
860
861 pub unsafe fn from_raw_ptr(ptr: *mut RealIsolate) -> Self {
862 Self(NonNull::new(ptr).unwrap())
863 }
864
865 #[inline]
866 pub unsafe fn ref_from_raw_isolate_ptr(ptr: &UnsafeRawIsolatePtr) -> &Self {
867 if ptr.is_null() {
868 panic!("UnsafeRawIsolatePtr is null");
869 }
870 unsafe { &*(ptr as *const UnsafeRawIsolatePtr as *const Isolate) }
871 }
872
873 #[inline]
874 pub unsafe fn ref_from_raw_isolate_ptr_unchecked(
875 ptr: &UnsafeRawIsolatePtr,
876 ) -> &Self {
877 unsafe { &*(ptr as *const UnsafeRawIsolatePtr as *const Isolate) }
878 }
879
880 #[inline]
881 pub unsafe fn ref_from_raw_isolate_ptr_mut(
882 ptr: &mut UnsafeRawIsolatePtr,
883 ) -> &mut Self {
884 if ptr.is_null() {
885 panic!("UnsafeRawIsolatePtr is null");
886 }
887 unsafe { &mut *(ptr as *mut UnsafeRawIsolatePtr as *mut Isolate) }
888 }
889
890 #[inline]
891 pub unsafe fn ref_from_raw_isolate_ptr_mut_unchecked(
892 ptr: &mut UnsafeRawIsolatePtr,
893 ) -> &mut Self {
894 unsafe { &mut *(ptr as *mut UnsafeRawIsolatePtr as *mut Isolate) }
895 }
896
897 #[inline]
898 pub(crate) unsafe fn from_non_null(ptr: NonNull<RealIsolate>) -> Self {
899 Self(ptr)
900 }
901
902 #[inline]
903 pub(crate) unsafe fn from_raw_ref(ptr: &NonNull<RealIsolate>) -> &Self {
904 unsafe { &*(ptr as *const NonNull<RealIsolate> as *const Isolate) }
906 }
907
908 #[inline]
909 pub(crate) unsafe fn from_raw_ref_mut(
910 ptr: &mut NonNull<RealIsolate>,
911 ) -> &mut Self {
912 unsafe { &mut *(ptr as *mut NonNull<RealIsolate> as *mut Isolate) }
914 }
915
916 const ANNEX_SLOT: u32 = 0;
918 const INTERNAL_DATA_SLOT_COUNT: u32 = 1;
919
920 #[inline(always)]
921 fn assert_embedder_data_slot_count_and_offset_correct(&self) {
922 assert!(
923 unsafe { v8__Isolate__GetNumberOfDataSlots(self.as_real_ptr()) }
924 >= Self::INTERNAL_DATA_SLOT_COUNT
925 )
926 }
927
928 fn new_impl(params: CreateParams) -> *mut RealIsolate {
929 crate::V8::assert_initialized();
930 let (raw_create_params, create_param_allocations) = params.finalize();
931 let cxx_isolate = unsafe { v8__Isolate__New(&raw_create_params) };
932 let mut isolate = unsafe { Isolate::from_raw_ptr(cxx_isolate) };
933 isolate.initialize(create_param_allocations);
934 cxx_isolate
935 }
936
937 pub(crate) fn initialize(&mut self, create_param_allocations: Box<dyn Any>) {
938 self.assert_embedder_data_slot_count_and_offset_correct();
939 self.create_annex(create_param_allocations);
940 }
941
942 #[allow(clippy::new_ret_no_self)]
950 pub fn new(params: CreateParams) -> OwnedIsolate {
951 OwnedIsolate::new(Self::new_impl(params))
952 }
953
954 #[allow(clippy::new_ret_no_self)]
955 pub fn snapshot_creator(
956 external_references: Option<Cow<'static, [ExternalReference]>>,
957 params: Option<CreateParams>,
958 ) -> OwnedIsolate {
959 SnapshotCreator::new(external_references, params)
960 }
961
962 #[allow(clippy::new_ret_no_self)]
963 pub fn snapshot_creator_from_existing_snapshot(
964 existing_snapshot_blob: StartupData,
965 external_references: Option<Cow<'static, [ExternalReference]>>,
966 params: Option<CreateParams>,
967 ) -> OwnedIsolate {
968 SnapshotCreator::from_existing_snapshot(
969 existing_snapshot_blob,
970 external_references,
971 params,
972 )
973 }
974
975 #[inline(always)]
977 pub fn create_params() -> CreateParams {
978 CreateParams::default()
979 }
980
981 #[inline(always)]
982 pub fn thread_safe_handle(&self) -> IsolateHandle {
983 self.get_annex().isolate_handle.clone()
984 }
985
986 #[inline(always)]
987 pub(crate) fn global_liveness(&self) -> NonNull<IsolateLiveness> {
988 self.get_annex().global_liveness
989 }
990
991 #[inline(always)]
993 pub fn terminate_execution(&self) -> bool {
994 unsafe { v8__Isolate__TerminateExecution(self.as_real_ptr()) };
995 true
996 }
997
998 #[inline(always)]
1000 pub fn cancel_terminate_execution(&self) -> bool {
1001 unsafe { v8__Isolate__CancelTerminateExecution(self.as_real_ptr()) };
1002 true
1003 }
1004
1005 #[inline(always)]
1007 pub fn is_execution_terminating(&self) -> bool {
1008 unsafe { v8__Isolate__IsExecutionTerminating(self.as_real_ptr()) }
1009 }
1010
1011 pub(crate) fn create_annex(
1012 &mut self,
1013 create_param_allocations: Box<dyn Any>,
1014 ) {
1015 let annex_box = Box::new(IsolateAnnex::new(self, create_param_allocations));
1016 let annex_ptr = Box::into_raw(annex_box);
1017 assert!(self.get_data_internal(Self::ANNEX_SLOT).is_null());
1018 self.set_data_internal(Self::ANNEX_SLOT, annex_ptr as *mut _);
1019 }
1020
1021 unsafe fn prepare_annex_for_dispose(
1038 &mut self,
1039 ) -> (*mut IsolateAnnex, Box<dyn Any>) {
1040 let annex_ptr =
1041 self.get_data_internal(Self::ANNEX_SLOT) as *mut IsolateAnnex;
1042 assert!(!annex_ptr.is_null());
1043
1044 unsafe {
1057 (*annex_ptr).global_liveness().dispose();
1060 (*annex_ptr).isolate_handle.dispose();
1061 }
1062
1063 let create_param_allocations =
1067 unsafe { (*annex_ptr).create_param_allocations.take().unwrap() };
1068
1069 let slots = unsafe { std::mem::take(&mut (*annex_ptr).slots) };
1073 drop(slots);
1074
1075 (annex_ptr, create_param_allocations)
1076 }
1077
1078 unsafe fn run_remaining_guaranteed_finalizers(annex_ptr: *mut IsolateAnnex) {
1091 let mut map = unsafe { std::mem::take(&mut (*annex_ptr).finalizer_map) };
1096 for finalizer in map.drain() {
1097 if let FinalizerCallback::Guaranteed(callback) = finalizer {
1098 callback();
1099 }
1100 }
1101 }
1102
1103 unsafe fn finish_annex_dispose(annex_ptr: *mut IsolateAnnex) {
1116 unsafe { Self::run_remaining_guaranteed_finalizers(annex_ptr) };
1117 unsafe { drop(Box::from_raw(annex_ptr)) };
1118 }
1119
1120 unsafe fn dispose_annex(&mut self) -> Box<dyn Any> {
1127 let (annex_ptr, create_param_allocations) =
1128 unsafe { self.prepare_annex_for_dispose() };
1129 unsafe { Self::run_remaining_guaranteed_finalizers(annex_ptr) };
1130 let taken_annex =
1131 self.take_data_internal(Self::ANNEX_SLOT) as *mut IsolateAnnex;
1132 debug_assert_eq!(taken_annex, annex_ptr);
1133 unsafe { drop(Box::from_raw(annex_ptr)) };
1134 create_param_allocations
1135 }
1136
1137 #[inline(always)]
1138 fn get_annex(&self) -> &IsolateAnnex {
1139 let annex_ptr =
1140 self.get_data_internal(Self::ANNEX_SLOT) as *const IsolateAnnex;
1141 assert!(!annex_ptr.is_null());
1142 unsafe { &*annex_ptr }
1143 }
1144
1145 #[inline(always)]
1146 fn get_annex_mut(&mut self) -> &mut IsolateAnnex {
1147 let annex_ptr =
1148 self.get_data_internal(Self::ANNEX_SLOT) as *mut IsolateAnnex;
1149 assert!(!annex_ptr.is_null());
1150 unsafe { &mut *annex_ptr }
1151 }
1152
1153 #[inline(always)]
1157 pub(crate) fn get_annex_ptr(&self) -> NonNull<IsolateAnnex> {
1158 let annex_ptr =
1159 self.get_data_internal(Self::ANNEX_SLOT) as *mut IsolateAnnex;
1160 debug_assert!(!annex_ptr.is_null());
1161 unsafe { NonNull::new_unchecked(annex_ptr) }
1162 }
1163
1164 pub(crate) fn set_snapshot_creator(
1165 &mut self,
1166 snapshot_creator: SnapshotCreator,
1167 ) {
1168 let prev = self
1169 .get_annex_mut()
1170 .maybe_snapshot_creator
1171 .replace(snapshot_creator);
1172 assert!(prev.is_none());
1173 }
1174
1175 pub(crate) fn get_finalizer_map(&self) -> &FinalizerMap {
1176 &self.get_annex().finalizer_map
1177 }
1178
1179 pub(crate) fn get_finalizer_map_mut(&mut self) -> &mut FinalizerMap {
1180 &mut self.get_annex_mut().finalizer_map
1181 }
1182
1183 pub fn get_data(&self, slot: u32) -> *mut c_void {
1186 self.get_data_internal(Self::INTERNAL_DATA_SLOT_COUNT + slot)
1187 }
1188
1189 #[inline(always)]
1192 pub fn set_data(&mut self, slot: u32, data: *mut c_void) {
1193 self.set_data_internal(Self::INTERNAL_DATA_SLOT_COUNT + slot, data);
1194 }
1195
1196 pub fn get_number_of_data_slots(&self) -> u32 {
1199 let n = unsafe { v8__Isolate__GetNumberOfDataSlots(self.as_real_ptr()) };
1200 n - Self::INTERNAL_DATA_SLOT_COUNT
1201 }
1202
1203 #[inline(always)]
1204 pub(crate) fn get_data_internal(&self, slot: u32) -> *mut c_void {
1205 unsafe { v8__Isolate__GetData(self.as_real_ptr(), slot) }
1206 }
1207
1208 #[inline(always)]
1209 pub(crate) fn set_data_internal(&mut self, slot: u32, data: *mut c_void) {
1210 unsafe { v8__Isolate__SetData(self.as_real_ptr(), slot, data) }
1211 }
1212
1213 #[inline(always)]
1215 fn take_data_internal(&mut self, slot: u32) -> *mut c_void {
1216 let ptr = self.get_data_internal(slot);
1217 self.set_data_internal(slot, null_mut());
1218 ptr
1219 }
1220
1221 #[inline(always)]
1250 pub fn get_slot<T: 'static>(&self) -> Option<&T> {
1251 self.get_annex().get_slot::<T>()
1252 }
1253
1254 #[inline(always)]
1256 pub fn get_slot_mut<T: 'static>(&mut self) -> Option<&mut T> {
1257 self.get_annex_mut().get_slot_mut::<T>()
1258 }
1259
1260 #[inline(always)]
1272 pub fn set_slot<T: 'static>(&mut self, value: T) -> bool {
1273 self.get_annex_mut().set_slot(value)
1274 }
1275
1276 #[inline(always)]
1278 pub fn remove_slot<T: 'static>(&mut self) -> Option<T> {
1279 self.get_annex_mut().remove_slot::<T>()
1280 }
1281
1282 #[inline(always)]
1289 pub unsafe fn enter(&self) {
1290 unsafe {
1291 v8__Isolate__Enter(self.as_real_ptr());
1292 }
1293 }
1294
1295 #[inline(always)]
1304 pub unsafe fn exit(&self) {
1305 unsafe {
1306 v8__Isolate__Exit(self.as_real_ptr());
1307 }
1308 }
1309
1310 #[inline(always)]
1315 pub fn memory_pressure_notification(&mut self, level: MemoryPressureLevel) {
1316 unsafe {
1317 v8__Isolate__MemoryPressureNotification(self.as_real_ptr(), level as u8)
1318 }
1319 }
1320
1321 #[inline(always)]
1333 pub fn clear_kept_objects(&mut self) {
1334 unsafe { v8__Isolate__ClearKeptObjects(self.as_real_ptr()) }
1335 }
1336
1337 #[inline(always)]
1340 pub fn low_memory_notification(&mut self) {
1341 unsafe { v8__Isolate__LowMemoryNotification(self.as_real_ptr()) }
1342 }
1343
1344 #[inline(always)]
1356 pub fn set_idle(&mut self, is_idle: bool) {
1357 unsafe { v8__Isolate__SetIdle(self.as_real_ptr(), is_idle) }
1358 }
1359
1360 #[inline(always)]
1367 pub fn collect_cpu_profiler_sample(&mut self, trace_id: Option<u64>) {
1368 let trace_id_ptr = match &trace_id {
1369 Some(id) => id as *const u64,
1370 None => std::ptr::null(),
1371 };
1372 unsafe { v8__CpuProfiler__CollectSample(self.as_real_ptr(), trace_id_ptr) }
1373 }
1374
1375 #[inline(always)]
1379 pub fn use_detailed_source_positions_for_profiling(&mut self) {
1380 unsafe {
1381 v8__CpuProfiler__UseDetailedSourcePositionsForProfiling(
1382 self.as_real_ptr(),
1383 )
1384 }
1385 }
1386
1387 #[inline(always)]
1389 pub fn get_heap_statistics(&mut self) -> HeapStatistics {
1390 let inner = unsafe {
1391 let mut s = MaybeUninit::zeroed();
1392 v8__Isolate__GetHeapStatistics(self.as_real_ptr(), s.as_mut_ptr());
1393 s.assume_init()
1394 };
1395 HeapStatistics(inner)
1396 }
1397
1398 #[inline(always)]
1400 pub fn number_of_heap_spaces(&mut self) -> usize {
1401 unsafe { v8__Isolate__NumberOfHeapSpaces(self.as_real_ptr()) }
1402 }
1403
1404 #[inline(always)]
1412 pub fn get_heap_space_statistics(
1413 &mut self,
1414 index: usize,
1415 ) -> Option<HeapSpaceStatistics> {
1416 let inner = unsafe {
1417 let mut s = MaybeUninit::zeroed();
1418 if !v8__Isolate__GetHeapSpaceStatistics(
1419 self.as_real_ptr(),
1420 s.as_mut_ptr(),
1421 index,
1422 ) {
1423 return None;
1424 }
1425 s.assume_init()
1426 };
1427 Some(HeapSpaceStatistics(inner))
1428 }
1429
1430 #[inline(always)]
1434 pub fn get_heap_code_and_metadata_statistics(
1435 &mut self,
1436 ) -> Option<HeapCodeStatistics> {
1437 let inner = unsafe {
1438 let mut s = MaybeUninit::zeroed();
1439 if !v8__Isolate__GetHeapCodeAndMetadataStatistics(
1440 self.as_real_ptr(),
1441 s.as_mut_ptr(),
1442 ) {
1443 return None;
1444 }
1445 s.assume_init()
1446 };
1447 Some(HeapCodeStatistics(inner))
1448 }
1449
1450 #[inline(always)]
1453 pub fn set_capture_stack_trace_for_uncaught_exceptions(
1454 &mut self,
1455 capture: bool,
1456 frame_limit: i32,
1457 ) {
1458 unsafe {
1459 v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(
1460 self.as_real_ptr(),
1461 capture,
1462 frame_limit,
1463 );
1464 }
1465 }
1466
1467 #[inline(always)]
1474 pub fn add_message_listener(&mut self, callback: MessageCallback) -> bool {
1475 unsafe { v8__Isolate__AddMessageListener(self.as_real_ptr(), callback) }
1476 }
1477
1478 #[inline(always)]
1480 pub fn add_message_listener_with_error_level(
1481 &mut self,
1482 callback: MessageCallback,
1483 message_levels: MessageErrorLevel,
1484 ) -> bool {
1485 unsafe {
1486 v8__Isolate__AddMessageListenerWithErrorLevel(
1487 self.as_real_ptr(),
1488 callback,
1489 message_levels,
1490 )
1491 }
1492 }
1493
1494 #[inline(always)]
1503 pub fn set_prepare_stack_trace_callback<'s>(
1504 &mut self,
1505 callback: impl MapFnTo<PrepareStackTraceCallback<'s>>,
1506 ) {
1507 unsafe {
1511 v8__Isolate__SetPrepareStackTraceCallback(
1512 self.as_real_ptr(),
1513 callback.map_fn_to(),
1514 );
1515 };
1516 }
1517
1518 #[inline(always)]
1521 pub fn set_promise_hook(&mut self, hook: PromiseHook) {
1522 unsafe { v8__Isolate__SetPromiseHook(self.as_real_ptr(), hook) }
1523 }
1524
1525 #[inline(always)]
1528 pub fn set_promise_reject_callback(
1529 &mut self,
1530 callback: PromiseRejectCallback,
1531 ) {
1532 unsafe {
1533 v8__Isolate__SetPromiseRejectCallback(self.as_real_ptr(), callback)
1534 }
1535 }
1536
1537 #[inline(always)]
1538 pub fn set_wasm_async_resolve_promise_callback(
1539 &mut self,
1540 callback: WasmAsyncResolvePromiseCallback,
1541 ) {
1542 unsafe {
1543 v8__Isolate__SetWasmAsyncResolvePromiseCallback(
1544 self.as_real_ptr(),
1545 callback,
1546 )
1547 }
1548 }
1549
1550 #[inline(always)]
1551 pub fn set_allow_wasm_code_generation_callback(
1552 &mut self,
1553 callback: AllowWasmCodeGenerationCallback,
1554 ) {
1555 unsafe {
1556 v8__Isolate__SetAllowWasmCodeGenerationCallback(
1557 self.as_real_ptr(),
1558 callback,
1559 );
1560 }
1561 }
1562
1563 #[inline(always)]
1564 pub fn set_host_initialize_import_meta_object_callback(
1567 &mut self,
1568 callback: HostInitializeImportMetaObjectCallback,
1569 ) {
1570 unsafe {
1571 v8__Isolate__SetHostInitializeImportMetaObjectCallback(
1572 self.as_real_ptr(),
1573 callback,
1574 );
1575 }
1576 }
1577
1578 #[inline(always)]
1581 pub fn set_host_import_module_dynamically_callback(
1582 &mut self,
1583 callback: impl HostImportModuleDynamicallyCallback,
1584 ) {
1585 unsafe {
1586 v8__Isolate__SetHostImportModuleDynamicallyCallback(
1587 self.as_real_ptr(),
1588 callback.to_c_fn(),
1589 );
1590 }
1591 }
1592
1593 #[inline(always)]
1601 pub fn set_host_import_module_with_phase_dynamically_callback(
1602 &mut self,
1603 callback: impl HostImportModuleWithPhaseDynamicallyCallback,
1604 ) {
1605 unsafe {
1606 v8__Isolate__SetHostImportModuleWithPhaseDynamicallyCallback(
1607 self.as_real_ptr(),
1608 callback.to_c_fn(),
1609 );
1610 }
1611 }
1612
1613 pub fn set_host_create_shadow_realm_context_callback(
1616 &mut self,
1617 callback: HostCreateShadowRealmContextCallback,
1618 ) {
1619 #[inline]
1620 unsafe extern "C" fn rust_shadow_realm_callback(
1621 initiator_context: Local<Context>,
1622 ) -> *mut Context {
1623 let scope = pin!(unsafe { CallbackScope::new(initiator_context) });
1624 let mut scope = scope.init();
1625 let isolate = scope.as_ref();
1626 let callback = isolate
1627 .get_slot::<HostCreateShadowRealmContextCallback>()
1628 .unwrap();
1629 let context = callback(&mut scope);
1630 context.map_or_else(null_mut, |l| l.as_non_null().as_ptr())
1631 }
1632
1633 #[cfg(target_os = "windows")]
1635 unsafe extern "C" fn rust_shadow_realm_callback_windows(
1636 rv: *mut *mut Context,
1637 initiator_context: Local<Context>,
1638 ) -> *mut *mut Context {
1639 unsafe {
1640 let ret = rust_shadow_realm_callback(initiator_context);
1641 rv.write(ret);
1642 }
1643 rv
1644 }
1645
1646 let slot_didnt_exist_before = self.set_slot(callback);
1647 if slot_didnt_exist_before {
1648 unsafe {
1649 #[cfg(target_os = "windows")]
1650 v8__Isolate__SetHostCreateShadowRealmContextCallback(
1651 self.as_real_ptr(),
1652 rust_shadow_realm_callback_windows,
1653 );
1654 #[cfg(not(target_os = "windows"))]
1655 v8__Isolate__SetHostCreateShadowRealmContextCallback(
1656 self.as_real_ptr(),
1657 rust_shadow_realm_callback,
1658 );
1659 }
1660 }
1661 }
1662
1663 #[inline(always)]
1665 pub fn set_use_counter_callback(&mut self, callback: UseCounterCallback) {
1666 unsafe {
1667 v8__Isolate__SetUseCounterCallback(self.as_real_ptr(), callback);
1668 }
1669 }
1670
1671 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[inline(always)]
1680 pub fn add_gc_prologue_callback(
1681 &mut self,
1682 callback: GcCallbackWithData,
1683 data: *mut c_void,
1684 gc_type_filter: GCType,
1685 ) {
1686 unsafe {
1687 v8__Isolate__AddGCPrologueCallback(
1688 self.as_real_ptr(),
1689 callback,
1690 data,
1691 gc_type_filter,
1692 );
1693 }
1694 }
1695
1696 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[inline(always)]
1700 pub fn remove_gc_prologue_callback(
1701 &mut self,
1702 callback: GcCallbackWithData,
1703 data: *mut c_void,
1704 ) {
1705 unsafe {
1706 v8__Isolate__RemoveGCPrologueCallback(self.as_real_ptr(), callback, data)
1707 }
1708 }
1709
1710 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[inline(always)]
1714 pub fn add_gc_epilogue_callback(
1715 &mut self,
1716 callback: GcCallbackWithData,
1717 data: *mut c_void,
1718 gc_type_filter: GCType,
1719 ) {
1720 unsafe {
1721 v8__Isolate__AddGCEpilogueCallback(
1722 self.as_real_ptr(),
1723 callback,
1724 data,
1725 gc_type_filter,
1726 );
1727 }
1728 }
1729
1730 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[inline(always)]
1734 pub fn remove_gc_epilogue_callback(
1735 &mut self,
1736 callback: GcCallbackWithData,
1737 data: *mut c_void,
1738 ) {
1739 unsafe {
1740 v8__Isolate__RemoveGCEpilogueCallback(self.as_real_ptr(), callback, data)
1741 }
1742 }
1743
1744 #[allow(clippy::not_unsafe_ptr_arg_deref)] #[inline(always)]
1749 pub fn add_near_heap_limit_callback(
1750 &mut self,
1751 callback: NearHeapLimitCallback,
1752 data: *mut c_void,
1753 ) {
1754 unsafe {
1755 v8__Isolate__AddNearHeapLimitCallback(self.as_real_ptr(), callback, data)
1756 };
1757 }
1758
1759 #[inline(always)]
1764 pub fn remove_near_heap_limit_callback(
1765 &mut self,
1766 callback: NearHeapLimitCallback,
1767 heap_limit: usize,
1768 ) {
1769 unsafe {
1770 v8__Isolate__RemoveNearHeapLimitCallback(
1771 self.as_real_ptr(),
1772 callback,
1773 heap_limit,
1774 );
1775 };
1776 }
1777
1778 #[inline(always)]
1786 pub fn adjust_amount_of_external_allocated_memory(
1787 &mut self,
1788 change_in_bytes: i64,
1789 ) -> i64 {
1790 unsafe {
1791 v8__Isolate__AdjustAmountOfExternalAllocatedMemory(
1792 self.as_real_ptr(),
1793 change_in_bytes,
1794 )
1795 }
1796 }
1797
1798 #[inline(always)]
1799 pub fn get_cpp_heap(&mut self) -> Option<&Heap> {
1800 unsafe { v8__Isolate__GetCppHeap(self.as_real_ptr()).as_ref() }
1801 }
1802
1803 #[inline(always)]
1804 pub fn set_oom_error_handler(&mut self, callback: OomErrorCallback) {
1805 unsafe { v8__Isolate__SetOOMErrorHandler(self.as_real_ptr(), callback) };
1806 }
1807
1808 #[inline(always)]
1810 pub fn get_microtasks_policy(&self) -> MicrotasksPolicy {
1811 unsafe { v8__Isolate__GetMicrotasksPolicy(self.as_real_ptr()) }
1812 }
1813
1814 #[inline(always)]
1816 pub fn set_microtasks_policy(&mut self, policy: MicrotasksPolicy) {
1817 unsafe { v8__Isolate__SetMicrotasksPolicy(self.as_real_ptr(), policy) }
1818 }
1819
1820 #[inline(always)]
1825 pub fn perform_microtask_checkpoint(&mut self) {
1826 unsafe { v8__Isolate__PerformMicrotaskCheckpoint(self.as_real_ptr()) }
1827 }
1828
1829 #[inline(always)]
1831 pub fn enqueue_microtask(&mut self, microtask: Local<Function>) {
1832 unsafe { v8__Isolate__EnqueueMicrotask(self.as_real_ptr(), &*microtask) }
1833 }
1834
1835 #[inline(always)]
1839 pub fn set_allow_atomics_wait(&mut self, allow: bool) {
1840 unsafe { v8__Isolate__SetAllowAtomicsWait(self.as_real_ptr(), allow) }
1841 }
1842
1843 #[inline(always)]
1851 pub fn set_wasm_streaming_callback<F>(&mut self, _: F)
1852 where
1853 F: UnitType
1854 + for<'a, 'b, 'c> Fn(
1855 &'c mut PinScope<'a, 'b>,
1856 Local<'a, Value>,
1857 WasmStreaming<false>,
1858 ),
1859 {
1860 unsafe {
1861 v8__Isolate__SetWasmStreamingCallback(
1862 self.as_real_ptr(),
1863 trampoline::<F>(),
1864 )
1865 }
1866 }
1867
1868 #[inline(always)]
1877 pub fn date_time_configuration_change_notification(
1878 &mut self,
1879 time_zone_detection: TimeZoneDetection,
1880 ) {
1881 unsafe {
1882 v8__Isolate__DateTimeConfigurationChangeNotification(
1883 self.as_real_ptr(),
1884 time_zone_detection,
1885 );
1886 }
1887 }
1888
1889 #[inline(always)]
1893 pub fn has_pending_background_tasks(&self) -> bool {
1894 unsafe { v8__Isolate__HasPendingBackgroundTasks(self.as_real_ptr()) }
1895 }
1896
1897 #[inline(always)]
1907 pub fn request_garbage_collection_for_testing(
1908 &mut self,
1909 r#type: GarbageCollectionType,
1910 ) {
1911 unsafe {
1912 v8__Isolate__RequestGarbageCollectionForTesting(
1913 self.as_real_ptr(),
1914 match r#type {
1915 GarbageCollectionType::Full => 0,
1916 GarbageCollectionType::Minor => 1,
1917 },
1918 );
1919 }
1920 }
1921
1922 unsafe fn dispose(&mut self) {
1925 unsafe {
1928 v8__Isolate__Dispose(self.as_real_ptr());
1929 }
1930 }
1931
1932 pub fn take_heap_snapshot<F>(&mut self, mut callback: F)
1939 where
1940 F: FnMut(&[u8]) -> bool,
1941 {
1942 unsafe extern "C" fn trampoline<F>(
1943 arg: *mut c_void,
1944 data: *const u8,
1945 size: usize,
1946 ) -> bool
1947 where
1948 F: FnMut(&[u8]) -> bool,
1949 {
1950 unsafe {
1951 let mut callback = NonNull::<F>::new_unchecked(arg as _);
1952 if size > 0 {
1953 (callback.as_mut())(std::slice::from_raw_parts(data, size))
1954 } else {
1955 (callback.as_mut())(&[])
1956 }
1957 }
1958 }
1959
1960 let arg = addr_of_mut!(callback);
1961 unsafe {
1962 v8__HeapProfiler__TakeHeapSnapshot(
1963 self.as_real_ptr(),
1964 trampoline::<F>,
1965 arg as _,
1966 );
1967 }
1968 }
1969
1970 #[inline(always)]
1978 pub fn set_default_context(&mut self, context: Local<Context>) {
1979 let snapshot_creator = self
1980 .get_annex_mut()
1981 .maybe_snapshot_creator
1982 .as_mut()
1983 .unwrap();
1984 snapshot_creator.set_default_context(context);
1985 }
1986
1987 #[inline(always)]
1996 pub fn add_context(&mut self, context: Local<Context>) -> usize {
1997 let snapshot_creator = self
1998 .get_annex_mut()
1999 .maybe_snapshot_creator
2000 .as_mut()
2001 .unwrap();
2002 snapshot_creator.add_context(context)
2003 }
2004
2005 #[inline(always)]
2014 pub fn add_isolate_data<T>(&mut self, data: Local<T>) -> usize
2015 where
2016 for<'l> Local<'l, T>: Into<Local<'l, Data>>,
2017 {
2018 let snapshot_creator = self
2019 .get_annex_mut()
2020 .maybe_snapshot_creator
2021 .as_mut()
2022 .unwrap();
2023 snapshot_creator.add_isolate_data(data)
2024 }
2025
2026 #[inline(always)]
2035 pub fn add_context_data<T>(
2036 &mut self,
2037 context: Local<Context>,
2038 data: Local<T>,
2039 ) -> usize
2040 where
2041 for<'l> Local<'l, T>: Into<Local<'l, Data>>,
2042 {
2043 let snapshot_creator = self
2044 .get_annex_mut()
2045 .maybe_snapshot_creator
2046 .as_mut()
2047 .unwrap();
2048 snapshot_creator.add_context_data(context, data)
2049 }
2050}
2051
2052pub(crate) struct IsolateAnnex {
2053 create_param_allocations: Option<Box<dyn Any>>,
2059 slots: HashMap<TypeId, RawSlot, BuildTypeIdHasher>,
2060 finalizer_map: FinalizerMap,
2061 maybe_snapshot_creator: Option<SnapshotCreator>,
2062 isolate_handle: IsolateHandle,
2063 global_liveness: NonNull<IsolateLiveness>,
2064}
2065
2066impl IsolateAnnex {
2067 fn new(isolate: &Isolate, create_param_allocations: Box<dyn Any>) -> Self {
2068 let global_liveness = Box::leak(Box::new(IsolateLiveness::new(isolate)));
2072 Self {
2073 create_param_allocations: Some(create_param_allocations),
2074 slots: HashMap::default(),
2075 finalizer_map: FinalizerMap::default(),
2076 maybe_snapshot_creator: None,
2077 isolate_handle: IsolateHandle::new(isolate),
2078 global_liveness: NonNull::from(global_liveness),
2079 }
2080 }
2081
2082 #[inline(always)]
2083 fn global_liveness(&self) -> &IsolateLiveness {
2084 unsafe { self.global_liveness.as_ref() }
2085 }
2086
2087 #[inline(always)]
2088 pub(crate) fn get_slot<T: 'static>(&self) -> Option<&T> {
2089 self
2090 .slots
2091 .get(&TypeId::of::<T>())
2092 .map(|slot| unsafe { slot.borrow::<T>() })
2093 }
2094
2095 #[inline(always)]
2096 pub(crate) fn get_slot_mut<T: 'static>(&mut self) -> Option<&mut T> {
2097 self
2098 .slots
2099 .get_mut(&TypeId::of::<T>())
2100 .map(|slot| unsafe { slot.borrow_mut::<T>() })
2101 }
2102
2103 #[inline(always)]
2104 pub(crate) fn set_slot<T: 'static>(&mut self, value: T) -> bool {
2105 self
2106 .slots
2107 .insert(TypeId::of::<T>(), RawSlot::new(value))
2108 .is_none()
2109 }
2110
2111 #[inline(always)]
2112 pub(crate) fn remove_slot<T: 'static>(&mut self) -> Option<T> {
2113 self
2114 .slots
2115 .remove(&TypeId::of::<T>())
2116 .map(|slot| unsafe { slot.into_inner::<T>() })
2117 }
2118}
2119
2120pub(crate) struct IsolateLiveness {
2121 isolate: AtomicPtr<RealIsolate>,
2122}
2123
2124impl IsolateLiveness {
2125 #[inline(always)]
2126 fn new(isolate: &Isolate) -> Self {
2127 Self {
2128 isolate: AtomicPtr::new(isolate.as_real_ptr()),
2129 }
2130 }
2131
2132 #[inline(always)]
2133 fn dispose(&self) {
2134 self
2135 .isolate
2136 .store(null_mut(), std::sync::atomic::Ordering::Relaxed);
2137 }
2138
2139 #[inline(always)]
2140 pub(crate) fn get_isolate_ptr(&self) -> *mut RealIsolate {
2141 self.isolate.load(std::sync::atomic::Ordering::Relaxed)
2142 }
2143}
2144
2145impl Debug for IsolateAnnex {
2146 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2147 f.debug_struct("IsolateAnnex")
2148 .field("isolate_handle", &self.isolate_handle)
2149 .finish()
2150 }
2151}
2152
2153pub(crate) struct IsolateHandleInner {
2154 isolate: UnsafeCell<*mut RealIsolate>,
2162 isolate_mutex: Mutex<()>,
2163}
2164
2165unsafe impl Send for IsolateHandleInner {}
2166unsafe impl Sync for IsolateHandleInner {}
2167
2168#[derive(Clone)]
2175pub struct IsolateHandle(Arc<IsolateHandleInner>);
2176
2177impl fmt::Debug for IsolateHandle {
2178 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2179 if let Ok(_lock) = self.0.isolate_mutex.try_lock() {
2180 let ptr = unsafe { *self.0.isolate.get() };
2182 f.debug_struct("IsolateHandle")
2183 .field("isolate_ptr", &ptr)
2184 .finish()
2185 } else {
2186 f.debug_struct("IsolateHandle").finish_non_exhaustive()
2187 }
2188 }
2189}
2190
2191impl IsolateHandle {
2192 #[inline(always)]
2193 fn new(isolate: &Isolate) -> Self {
2194 let inner = Arc::new(IsolateHandleInner {
2195 isolate: UnsafeCell::new(isolate.as_real_ptr()),
2196 isolate_mutex: Mutex::new(()),
2197 });
2198 Self(inner)
2199 }
2200
2201 fn dispose(&self) {
2203 let _lock = self.0.isolate_mutex.lock().unwrap();
2204 unsafe { *self.0.isolate.get() = null_mut() }
2206 }
2207
2208 pub(crate) fn with_isolate_ptr<R>(
2215 &self,
2216 f: impl FnOnce(NonNull<RealIsolate>) -> R,
2217 ) -> Option<R> {
2218 let _lock = self.0.isolate_mutex.lock().unwrap();
2219 let ptr = unsafe { *self.0.isolate.get() };
2221 NonNull::new(ptr).map(f)
2222 }
2223
2224 pub(crate) unsafe fn get_isolate_ptr(&self) -> *mut RealIsolate {
2231 unsafe { *self.0.isolate.get() }
2235 }
2236
2237 #[inline(always)]
2245 pub fn terminate_execution(&self) -> bool {
2246 self
2247 .with_isolate_ptr(|isolate| unsafe {
2248 v8__Isolate__TerminateExecution(isolate.as_ptr())
2249 })
2250 .is_some()
2251 }
2252
2253 #[inline(always)]
2268 pub fn cancel_terminate_execution(&self) -> bool {
2269 self
2270 .with_isolate_ptr(|isolate| unsafe {
2271 v8__Isolate__CancelTerminateExecution(isolate.as_ptr())
2272 })
2273 .is_some()
2274 }
2275
2276 #[inline(always)]
2285 pub fn is_execution_terminating(&self) -> bool {
2286 self
2287 .with_isolate_ptr(|isolate| unsafe {
2288 v8__Isolate__IsExecutionTerminating(isolate.as_ptr())
2289 })
2290 .unwrap_or(false)
2291 }
2292
2293 #[allow(clippy::not_unsafe_ptr_arg_deref)]
2304 #[inline(always)]
2305 pub fn request_interrupt(
2306 &self,
2307 callback: InterruptCallback,
2308 data: *mut c_void,
2309 ) -> bool {
2310 self
2311 .with_isolate_ptr(|isolate| unsafe {
2312 v8__Isolate__RequestInterrupt(isolate.as_ptr(), callback, data)
2313 })
2314 .is_some()
2315 }
2316}
2317
2318#[derive(Debug)]
2320pub struct OwnedIsolate {
2321 cxx_isolate: NonNull<RealIsolate>,
2322}
2323
2324impl OwnedIsolate {
2325 pub(crate) fn new(cxx_isolate: *mut RealIsolate) -> Self {
2326 let isolate = Self::new_already_entered(cxx_isolate);
2327 unsafe {
2328 isolate.enter();
2329 }
2330 isolate
2331 }
2332
2333 pub(crate) fn new_already_entered(cxx_isolate: *mut RealIsolate) -> Self {
2334 let cxx_isolate = NonNull::new(cxx_isolate).unwrap();
2335 let owned_isolate: OwnedIsolate = Self { cxx_isolate };
2336 owned_isolate
2338 }
2339}
2340
2341impl Drop for OwnedIsolate {
2342 fn drop(&mut self) {
2343 unsafe {
2344 let snapshot_creator = self.get_annex_mut().maybe_snapshot_creator.take();
2345 assert!(
2346 snapshot_creator.is_none(),
2347 "If isolate was created using v8::Isolate::snapshot_creator, you should use v8::OwnedIsolate::create_blob before dropping an isolate."
2348 );
2349 assert!(
2351 std::ptr::eq(self.cxx_isolate.as_mut(), v8__Isolate__GetCurrent()),
2352 "v8::OwnedIsolate instances must be dropped in the reverse order of creation. They are entered upon creation and exited upon being dropped."
2353 );
2354 self.exit();
2356 let (annex_ptr, _create_param_allocations) =
2357 self.prepare_annex_for_dispose();
2358 Isolate::run_remaining_guaranteed_finalizers(annex_ptr);
2362 Platform::notify_isolate_shutdown(&get_current_platform(), self);
2363 self.dispose();
2368 Isolate::finish_annex_dispose(annex_ptr);
2373 }
2374 }
2375}
2376
2377impl OwnedIsolate {
2378 #[inline(always)]
2385 pub fn create_blob(
2386 mut self,
2387 function_code_handling: FunctionCodeHandling,
2388 ) -> Option<StartupData> {
2389 let mut snapshot_creator =
2390 self.get_annex_mut().maybe_snapshot_creator.take().unwrap();
2391
2392 let _create_param_allocations = unsafe {
2395 self.dispose_annex()
2397 };
2398
2399 std::mem::forget(self);
2402 snapshot_creator.create_blob(function_code_handling)
2403 }
2404}
2405
2406impl Deref for OwnedIsolate {
2407 type Target = Isolate;
2408 fn deref(&self) -> &Self::Target {
2409 unsafe {
2410 std::mem::transmute::<&NonNull<RealIsolate>, &Isolate>(&self.cxx_isolate)
2411 }
2412 }
2413}
2414
2415impl DerefMut for OwnedIsolate {
2416 fn deref_mut(&mut self) -> &mut Self::Target {
2417 unsafe {
2418 std::mem::transmute::<&mut NonNull<RealIsolate>, &mut Isolate>(
2419 &mut self.cxx_isolate,
2420 )
2421 }
2422 }
2423}
2424
2425impl AsMut<Isolate> for OwnedIsolate {
2426 fn as_mut(&mut self) -> &mut Isolate {
2427 self
2428 }
2429}
2430
2431impl AsMut<Isolate> for Isolate {
2432 fn as_mut(&mut self) -> &mut Isolate {
2433 self
2434 }
2435}
2436
2437pub struct HeapStatistics(v8__HeapStatistics);
2442
2443impl HeapStatistics {
2444 #[inline(always)]
2445 pub fn total_heap_size(&self) -> usize {
2446 self.0.total_heap_size_
2447 }
2448
2449 #[inline(always)]
2450 pub fn total_heap_size_executable(&self) -> usize {
2451 self.0.total_heap_size_executable_
2452 }
2453
2454 #[inline(always)]
2455 pub fn total_physical_size(&self) -> usize {
2456 self.0.total_physical_size_
2457 }
2458
2459 #[inline(always)]
2460 pub fn total_available_size(&self) -> usize {
2461 self.0.total_available_size_
2462 }
2463
2464 #[inline(always)]
2465 pub fn total_global_handles_size(&self) -> usize {
2466 self.0.total_global_handles_size_
2467 }
2468
2469 #[inline(always)]
2470 pub fn used_global_handles_size(&self) -> usize {
2471 self.0.used_global_handles_size_
2472 }
2473
2474 #[inline(always)]
2475 pub fn used_heap_size(&self) -> usize {
2476 self.0.used_heap_size_
2477 }
2478
2479 #[inline(always)]
2480 pub fn heap_size_limit(&self) -> usize {
2481 self.0.heap_size_limit_
2482 }
2483
2484 #[inline(always)]
2485 pub fn malloced_memory(&self) -> usize {
2486 self.0.malloced_memory_
2487 }
2488
2489 #[inline(always)]
2490 pub fn external_memory(&self) -> usize {
2491 self.0.external_memory_
2492 }
2493
2494 #[inline(always)]
2495 pub fn peak_malloced_memory(&self) -> usize {
2496 self.0.peak_malloced_memory_
2497 }
2498
2499 #[inline(always)]
2500 pub fn number_of_native_contexts(&self) -> usize {
2501 self.0.number_of_native_contexts_
2502 }
2503
2504 #[inline(always)]
2505 pub fn number_of_detached_contexts(&self) -> usize {
2506 self.0.number_of_detached_contexts_
2507 }
2508
2509 #[inline(always)]
2513 pub fn total_allocated_bytes(&self) -> u64 {
2514 self.0.total_allocated_bytes_
2515 }
2516
2517 #[inline(always)]
2520 pub fn does_zap_garbage(&self) -> bool {
2521 self.0.does_zap_garbage_
2522 }
2523}
2524
2525pub struct HeapSpaceStatistics(v8__HeapSpaceStatistics);
2526
2527impl HeapSpaceStatistics {
2528 pub fn space_name(&self) -> &'static CStr {
2529 unsafe { CStr::from_ptr(self.0.space_name_) }
2530 }
2531
2532 pub fn space_size(&self) -> usize {
2533 self.0.space_size_
2534 }
2535
2536 pub fn space_used_size(&self) -> usize {
2537 self.0.space_used_size_
2538 }
2539
2540 pub fn space_available_size(&self) -> usize {
2541 self.0.space_available_size_
2542 }
2543
2544 pub fn physical_space_size(&self) -> usize {
2545 self.0.physical_space_size_
2546 }
2547}
2548
2549pub struct HeapCodeStatistics(v8__HeapCodeStatistics);
2550
2551impl HeapCodeStatistics {
2552 pub fn code_and_metadata_size(&self) -> usize {
2553 self.0.code_and_metadata_size_
2554 }
2555
2556 pub fn bytecode_and_metadata_size(&self) -> usize {
2557 self.0.bytecode_and_metadata_size_
2558 }
2559
2560 pub fn external_script_source_size(&self) -> usize {
2561 self.0.external_script_source_size_
2562 }
2563
2564 pub fn cpu_profiler_metadata_size(&self) -> usize {
2565 self.0.cpu_profiler_metadata_size_
2566 }
2567}
2568
2569impl<'s, F> MapFnFrom<F> for PrepareStackTraceCallback<'s>
2570where
2571 F: UnitType
2572 + for<'a> Fn(
2573 &mut PinScope<'s, 'a>,
2574 Local<'s, Value>,
2575 Local<'s, Array>,
2576 ) -> Local<'s, Value>,
2577{
2578 #[cfg(target_os = "windows")]
2580 fn mapping() -> Self {
2581 let f = |ret_ptr, context, error, sites| {
2582 let scope = pin!(unsafe { CallbackScope::new(context) });
2583 let mut scope: crate::PinnedRef<CallbackScope> = scope.init();
2584 let r = (F::get())(&mut scope, error, sites);
2585 unsafe { std::ptr::write(ret_ptr, &*r as *const _) };
2586 ret_ptr
2587 };
2588 f.to_c_fn()
2589 }
2590
2591 #[cfg(not(target_os = "windows"))]
2593 fn mapping() -> Self {
2594 let f = |context, error, sites| {
2595 let scope = pin!(unsafe { CallbackScope::new(context) });
2596 let mut scope: crate::PinnedRef<CallbackScope> = scope.init();
2597
2598 let r = (F::get())(&mut scope, error, sites);
2599 PrepareStackTraceCallbackRet(&*r as *const _)
2600 };
2601 f.to_c_fn()
2602 }
2603}
2604
2605#[derive(Clone, Default)]
2609pub(crate) struct TypeIdHasher {
2610 state: Option<u64>,
2611}
2612
2613impl Hasher for TypeIdHasher {
2614 fn write(&mut self, _bytes: &[u8]) {
2615 panic!("TypeIdHasher::write() called unexpectedly");
2616 }
2617
2618 #[inline]
2619 fn write_u64(&mut self, value: u64) {
2620 let prev_state = self.state.replace(value);
2623 debug_assert_eq!(prev_state, None);
2624 }
2625
2626 #[inline]
2627 fn finish(&self) -> u64 {
2628 self.state.unwrap()
2629 }
2630}
2631
2632#[derive(Copy, Clone, Default)]
2636pub(crate) struct BuildTypeIdHasher;
2637
2638impl BuildHasher for BuildTypeIdHasher {
2639 type Hasher = TypeIdHasher;
2640
2641 #[inline]
2642 fn build_hasher(&self) -> Self::Hasher {
2643 Default::default()
2644 }
2645}
2646
2647const _: () = {
2648 assert!(
2649 size_of::<TypeId>() == size_of::<u64>()
2650 || size_of::<TypeId>() == size_of::<u128>()
2651 );
2652 assert!(
2653 align_of::<TypeId>() == align_of::<u64>()
2654 || align_of::<TypeId>() == align_of::<u128>()
2655 );
2656};
2657
2658pub(crate) struct RawSlot {
2659 data: RawSlotData,
2660 dtor: Option<RawSlotDtor>,
2661}
2662
2663type RawSlotData = MaybeUninit<usize>;
2664type RawSlotDtor = unsafe fn(&mut RawSlotData) -> ();
2665
2666impl RawSlot {
2667 #[inline]
2668 pub fn new<T: 'static>(value: T) -> Self {
2669 if Self::needs_box::<T>() {
2670 Self::new_internal(Box::new(value))
2671 } else {
2672 Self::new_internal(value)
2673 }
2674 }
2675
2676 #[inline]
2680 pub unsafe fn borrow<T: 'static>(&self) -> &T {
2681 unsafe {
2682 if Self::needs_box::<T>() {
2683 &*(self.data.as_ptr() as *const Box<T>)
2684 } else {
2685 &*(self.data.as_ptr() as *const T)
2686 }
2687 }
2688 }
2689
2690 #[inline]
2692 pub unsafe fn borrow_mut<T: 'static>(&mut self) -> &mut T {
2693 unsafe {
2694 if Self::needs_box::<T>() {
2695 &mut *(self.data.as_mut_ptr() as *mut Box<T>)
2696 } else {
2697 &mut *(self.data.as_mut_ptr() as *mut T)
2698 }
2699 }
2700 }
2701
2702 #[inline]
2704 pub unsafe fn into_inner<T: 'static>(self) -> T {
2705 unsafe {
2706 let value = if Self::needs_box::<T>() {
2707 *std::ptr::read(self.data.as_ptr() as *mut Box<T>)
2708 } else {
2709 std::ptr::read(self.data.as_ptr() as *mut T)
2710 };
2711 forget(self);
2712 value
2713 }
2714 }
2715
2716 const fn needs_box<T: 'static>() -> bool {
2717 size_of::<T>() > size_of::<RawSlotData>()
2718 || align_of::<T>() > align_of::<RawSlotData>()
2719 }
2720
2721 #[inline]
2722 fn new_internal<B: 'static>(value: B) -> Self {
2723 assert!(!Self::needs_box::<B>());
2724 let mut self_ = Self {
2725 data: RawSlotData::zeroed(),
2726 dtor: None,
2727 };
2728 unsafe {
2729 ptr::write(self_.data.as_mut_ptr() as *mut B, value);
2730 }
2731 if needs_drop::<B>() {
2732 self_.dtor.replace(Self::drop_internal::<B>);
2733 };
2734 self_
2735 }
2736
2737 unsafe fn drop_internal<B: 'static>(data: &mut RawSlotData) {
2739 assert!(!Self::needs_box::<B>());
2740 unsafe {
2741 drop_in_place(data.as_mut_ptr() as *mut B);
2742 }
2743 }
2744}
2745
2746impl Drop for RawSlot {
2747 fn drop(&mut self) {
2748 if let Some(dtor) = self.dtor {
2749 unsafe { dtor(&mut self.data) };
2750 }
2751 }
2752}
2753
2754impl AsRef<Isolate> for OwnedIsolate {
2755 fn as_ref(&self) -> &Isolate {
2756 unsafe { Isolate::from_raw_ref(&self.cxx_isolate) }
2757 }
2758}
2759impl AsRef<Isolate> for Isolate {
2760 fn as_ref(&self) -> &Isolate {
2761 self
2762 }
2763}