1use std::alloc::alloc;
81use std::alloc::Layout;
82use std::any::type_name;
83use std::cell::Cell;
84use std::convert::TryInto;
85
86use std::marker::PhantomData;
87use std::mem::MaybeUninit;
88use std::num::NonZeroUsize;
89use std::ops::Deref;
90use std::ops::DerefMut;
91use std::ptr;
92use std::ptr::NonNull;
93
94use crate::function::FunctionCallbackInfo;
95use crate::function::PropertyCallbackInfo;
96use crate::Context;
97use crate::Data;
98use crate::DataError;
99use crate::Handle;
100use crate::Isolate;
101use crate::Local;
102use crate::Message;
103use crate::Object;
104use crate::OwnedIsolate;
105use crate::Primitive;
106use crate::PromiseRejectMessage;
107use crate::Value;
108
109#[derive(Debug)]
113pub struct ContextScope<'s, P> {
114 data: NonNull<data::ScopeData>,
115 _phantom: PhantomData<&'s mut P>,
116}
117
118impl<'s, P: param::NewContextScope<'s>> ContextScope<'s, P> {
119 #[allow(clippy::new_ret_no_self)]
120 pub fn new(param: &'s mut P, context: Local<Context>) -> P::NewScope {
121 let scope_data = param.get_scope_data_mut();
122 if scope_data.get_isolate_ptr()
123 != unsafe { raw::v8__Context__GetIsolate(&*context) }
124 {
125 panic!(
126 "{} and Context do not belong to the same Isolate",
127 type_name::<P>()
128 )
129 }
130 let new_scope_data = scope_data.new_context_scope_data(context);
131 new_scope_data.as_scope()
132 }
133}
134
135#[derive(Debug)]
148pub struct HandleScope<'s, C = Context> {
149 data: NonNull<data::ScopeData>,
150 _phantom: PhantomData<&'s mut C>,
151}
152
153impl<'s> HandleScope<'s> {
154 #[allow(clippy::new_ret_no_self)]
155 pub fn new<P: param::NewHandleScope<'s>>(param: &'s mut P) -> P::NewScope {
156 param
157 .get_scope_data_mut()
158 .new_handle_scope_data()
159 .as_scope()
160 }
161
162 pub fn with_context<
167 P: param::NewHandleScopeWithContext<'s>,
168 H: Handle<Data = Context>,
169 >(
170 param: &'s mut P,
171 context: H,
172 ) -> Self {
173 let context_ref = context.open(param.get_isolate_mut());
174 param
175 .get_scope_data_mut()
176 .new_handle_scope_data_with_context(context_ref)
177 .as_scope()
178 }
179
180 pub fn get_current_context(&self) -> Local<'s, Context> {
183 let context_ptr = data::ScopeData::get(self).get_current_context();
184 unsafe { Local::from_raw(context_ptr) }.unwrap()
185 }
186
187 pub fn get_entered_or_microtask_context(&self) -> Local<'s, Context> {
192 let data = data::ScopeData::get(self);
193 let isolate_ptr = data.get_isolate_ptr();
194 let context_ptr =
195 unsafe { raw::v8__Isolate__GetEnteredOrMicrotaskContext(isolate_ptr) };
196 unsafe { Local::from_raw(context_ptr) }.unwrap()
197 }
198}
199
200impl<'s> HandleScope<'s, ()> {
201 pub fn throw_exception(
209 &mut self,
210 exception: Local<Value>,
211 ) -> Local<'s, Value> {
212 unsafe {
213 self.cast_local(|sd| {
214 raw::v8__Isolate__ThrowException(sd.get_isolate_ptr(), &*exception)
215 })
216 }
217 .unwrap()
218 }
219
220 pub(crate) unsafe fn cast_local<T>(
221 &mut self,
222 f: impl FnOnce(&mut data::ScopeData) -> *const T,
223 ) -> Option<Local<'s, T>> {
224 Local::from_raw(f(data::ScopeData::get_mut(self)))
225 }
226
227 pub(crate) fn get_isolate_ptr(&self) -> *mut Isolate {
228 data::ScopeData::get(self).get_isolate_ptr()
229 }
230}
231
232impl<'s> HandleScope<'s> {
233 pub fn get_isolate_data_from_snapshot_once<T>(
241 &mut self,
242 index: usize,
243 ) -> Result<Local<'s, T>, DataError>
244 where
245 T: 'static,
246 for<'l> Local<'l, Data>: TryInto<Local<'l, T>, Error = DataError>,
247 {
248 unsafe {
249 self
250 .cast_local(|sd| {
251 raw::v8__Isolate__GetDataFromSnapshotOnce(sd.get_isolate_ptr(), index)
252 })
253 .ok_or_else(DataError::no_data::<T>)
254 .and_then(|data| data.try_into())
255 }
256 }
257
258 pub fn get_context_data_from_snapshot_once<T>(
266 &mut self,
267 index: usize,
268 ) -> Result<Local<'s, T>, DataError>
269 where
270 T: 'static,
271 for<'l> Local<'l, Data>: TryInto<Local<'l, T>, Error = DataError>,
272 {
273 unsafe {
274 self
275 .cast_local(|sd| {
276 raw::v8__Context__GetDataFromSnapshotOnce(
277 sd.get_current_context(),
278 index,
279 )
280 })
281 .ok_or_else(DataError::no_data::<T>)
282 .and_then(|data| data.try_into())
283 }
284 }
285}
286
287#[derive(Debug)]
295pub struct EscapableHandleScope<'s, 'e: 's, C = Context> {
296 data: NonNull<data::ScopeData>,
297 _phantom:
298 PhantomData<(&'s mut raw::HandleScope, &'e mut raw::EscapeSlot, &'s C)>,
299}
300
301impl<'s, 'e: 's> EscapableHandleScope<'s, 'e> {
302 #[allow(clippy::new_ret_no_self)]
303 pub fn new<P: param::NewEscapableHandleScope<'s, 'e>>(
304 param: &'s mut P,
305 ) -> P::NewScope {
306 param
307 .get_scope_data_mut()
308 .new_escapable_handle_scope_data()
309 .as_scope()
310 }
311}
312
313impl<'s, 'e: 's, C> EscapableHandleScope<'s, 'e, C> {
314 pub fn escape<T>(&mut self, value: Local<T>) -> Local<'e, T>
317 where
318 for<'l> Local<'l, T>: Into<Local<'l, Data>>,
319 {
320 let escape_slot = data::ScopeData::get_mut(self)
321 .get_escape_slot_mut()
322 .expect("internal error: EscapableHandleScope has no escape slot")
323 .take()
324 .expect("EscapableHandleScope::escape() called twice");
325 escape_slot.escape(value)
326 }
327}
328
329#[derive(Debug)]
331pub struct TryCatch<'s, P> {
332 data: NonNull<data::ScopeData>,
333 _phantom: PhantomData<&'s mut P>,
334}
335
336impl<'s, P: param::NewTryCatch<'s>> TryCatch<'s, P> {
337 #[allow(clippy::new_ret_no_self)]
338 pub fn new(param: &'s mut P) -> P::NewScope {
339 param.get_scope_data_mut().new_try_catch_data().as_scope()
340 }
341}
342
343impl<'s, P> TryCatch<'s, P> {
344 pub fn has_caught(&self) -> bool {
346 unsafe { raw::v8__TryCatch__HasCaught(self.get_raw()) }
347 }
348
349 pub fn can_continue(&self) -> bool {
356 unsafe { raw::v8__TryCatch__CanContinue(self.get_raw()) }
357 }
358
359 pub fn has_terminated(&self) -> bool {
370 unsafe { raw::v8__TryCatch__HasTerminated(self.get_raw()) }
371 }
372
373 pub fn is_verbose(&self) -> bool {
375 unsafe { raw::v8__TryCatch__IsVerbose(self.get_raw()) }
376 }
377
378 pub fn set_verbose(&mut self, value: bool) {
385 unsafe { raw::v8__TryCatch__SetVerbose(self.get_raw_mut(), value) };
386 }
387
388 pub fn set_capture_message(&mut self, value: bool) {
392 unsafe { raw::v8__TryCatch__SetCaptureMessage(self.get_raw_mut(), value) };
393 }
394
395 pub fn reset(&mut self) {
405 unsafe { raw::v8__TryCatch__Reset(self.get_raw_mut()) };
406 }
407
408 fn get_raw(&self) -> &raw::TryCatch {
409 data::ScopeData::get(self).get_try_catch()
410 }
411
412 fn get_raw_mut(&mut self) -> &mut raw::TryCatch {
413 data::ScopeData::get_mut(self).get_try_catch_mut()
414 }
415}
416
417impl<'s, 'p: 's, P> TryCatch<'s, P>
418where
419 Self: AsMut<HandleScope<'p, ()>>,
420{
421 pub fn exception(&mut self) -> Option<Local<'p, Value>> {
430 unsafe {
431 self
432 .as_mut()
433 .cast_local(|sd| raw::v8__TryCatch__Exception(sd.get_try_catch()))
434 }
435 }
436
437 pub fn message(&mut self) -> Option<Local<'p, Message>> {
443 unsafe {
444 self
445 .as_mut()
446 .cast_local(|sd| raw::v8__TryCatch__Message(sd.get_try_catch()))
447 }
448 }
449
450 pub fn rethrow(&mut self) -> Option<Local<'_, Value>> {
459 unsafe {
460 self
461 .as_mut()
462 .cast_local(|sd| raw::v8__TryCatch__ReThrow(sd.get_try_catch_mut()))
463 }
464 }
465}
466
467impl<'s, 'p: 's, P> TryCatch<'s, P>
468where
469 Self: AsMut<HandleScope<'p>>,
470{
471 pub fn stack_trace(&mut self) -> Option<Local<'p, Value>> {
474 unsafe {
475 self.as_mut().cast_local(|sd| {
476 raw::v8__TryCatch__StackTrace(
477 sd.get_try_catch(),
478 sd.get_current_context(),
479 )
480 })
481 }
482 }
483}
484
485#[derive(Debug)]
510pub struct CallbackScope<'s, C = Context> {
511 data: NonNull<data::ScopeData>,
512 _phantom: PhantomData<&'s mut HandleScope<'s, C>>,
513}
514
515impl<'s> CallbackScope<'s> {
516 #[allow(clippy::new_ret_no_self)]
517 pub unsafe fn new<P: param::NewCallbackScope<'s>>(param: P) -> P::NewScope {
518 let (isolate, context) = param.get_isolate_mut_and_maybe_current_context();
519 data::ScopeData::get_current_mut(isolate)
520 .new_callback_scope_data(context)
521 .as_scope()
522 }
523}
524
525macro_rules! impl_as {
526 (<$($params:tt),+> $src_type:ty as Isolate) => {
528 impl<$($params),*> AsRef<Isolate> for $src_type {
529 fn as_ref(&self) -> &Isolate {
530 data::ScopeData::get(self).get_isolate()
531 }
532 }
533
534 impl<$($params),*> AsMut<Isolate> for $src_type {
535 fn as_mut(&mut self) -> &mut Isolate {
536 data::ScopeData::get_mut(self).get_isolate_mut()
537 }
538 }
539 };
540
541 (<$($params:tt),+> $src_type:ty as $tgt_type:ty) => {
544 impl<$($params),*> AsRef<$tgt_type> for $src_type {
545 fn as_ref(&self) -> &$tgt_type {
546 self.cast_ref()
547 }
548 }
549
550 impl<$($params),*> AsMut< $tgt_type> for $src_type {
551 fn as_mut(&mut self) -> &mut $tgt_type {
552 self.cast_mut()
553 }
554 }
555 };
556}
557
558impl_as!(<'s, 'p, P> ContextScope<'s, P> as Isolate);
559impl_as!(<'s, C> HandleScope<'s, C> as Isolate);
560impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as Isolate);
561impl_as!(<'s, P> TryCatch<'s, P> as Isolate);
562impl_as!(<'s, C> CallbackScope<'s, C> as Isolate);
563
564impl_as!(<'s, 'p> ContextScope<'s, HandleScope<'p>> as HandleScope<'p, ()>);
565impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p, ()>);
566impl_as!(<'s, C> HandleScope<'s, C> as HandleScope<'s, ()>);
567impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as HandleScope<'s, ()>);
568impl_as!(<'s, 'p, C> TryCatch<'s, HandleScope<'p, C>> as HandleScope<'p, ()>);
569impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as HandleScope<'p, ()>);
570impl_as!(<'s, C> CallbackScope<'s, C> as HandleScope<'s, ()>);
571
572impl_as!(<'s, 'p> ContextScope<'s, HandleScope<'p>> as HandleScope<'p>);
573impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>);
574impl_as!(<'s> HandleScope<'s> as HandleScope<'s>);
575impl_as!(<'s, 'e> EscapableHandleScope<'s, 'e> as HandleScope<'s>);
576impl_as!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as HandleScope<'p>);
577impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>);
578impl_as!(<'s> CallbackScope<'s> as HandleScope<'s>);
579
580impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e, ()>);
581impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as EscapableHandleScope<'s, 'e, ()>);
582impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as EscapableHandleScope<'p, 'e, ()>);
583
584impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
585impl_as!(<'s, 'e> EscapableHandleScope<'s, 'e> as EscapableHandleScope<'s, 'e>);
586impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
587
588impl_as!(<'s, 'p, C> TryCatch<'s, HandleScope<'p, C>> as TryCatch<'s, HandleScope<'p, ()>>);
589impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as TryCatch<'s, HandleScope<'p, ()>>);
590impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as TryCatch<'s, EscapableHandleScope<'p, 'e, ()>>);
591
592impl_as!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as TryCatch<'s, HandleScope<'p>>);
593impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as TryCatch<'s, HandleScope<'p>>);
594impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as TryCatch<'s, EscapableHandleScope<'p, 'e>>);
595
596macro_rules! impl_deref {
597 (<$($params:tt),+> $src_type:ty as $tgt_type:ty) => {
598 impl<$($params),*> Deref for $src_type {
599 type Target = $tgt_type;
600 fn deref(&self) -> &Self::Target {
601 self.as_ref()
602 }
603 }
604
605 impl<$($params),*> DerefMut for $src_type {
606 fn deref_mut(&mut self) -> &mut Self::Target {
607 self.as_mut()
608 }
609 }
610 };
611}
612
613impl_deref!(<'s, 'p> ContextScope<'s, HandleScope<'p>> as HandleScope<'p>);
614impl_deref!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
615
616impl_deref!(<'s> HandleScope<'s, ()> as Isolate);
617impl_deref!(<'s> HandleScope<'s> as HandleScope<'s, ()>);
618
619impl_deref!(<'s, 'e> EscapableHandleScope<'s, 'e, ()> as HandleScope<'s, ()>);
620impl_deref!(<'s, 'e> EscapableHandleScope<'s, 'e> as HandleScope<'s>);
621
622impl_deref!(<'s, 'p> TryCatch<'s, HandleScope<'p, ()>> as HandleScope<'p, ()>);
623impl_deref!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as HandleScope<'p>);
624impl_deref!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e, ()>> as EscapableHandleScope<'p, 'e, ()>);
625impl_deref!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
626
627impl_deref!(<'s> CallbackScope<'s, ()> as HandleScope<'s, ()>);
628impl_deref!(<'s> CallbackScope<'s> as HandleScope<'s>);
629
630macro_rules! impl_scope_drop {
631 (<$($params:tt),+> $type:ty) => {
632 unsafe impl<$($params),*> Scope for $type {}
633
634 impl<$($params),*> Drop for $type {
635 fn drop(&mut self) {
636 data::ScopeData::get_mut(self).notify_scope_dropped();
637 }
638 }
639 };
640}
641
642impl_scope_drop!(<'s, 'p, P> ContextScope<'s, P>);
643impl_scope_drop!(<'s, C> HandleScope<'s, C> );
644impl_scope_drop!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> );
645impl_scope_drop!(<'s, P> TryCatch<'s, P> );
646impl_scope_drop!(<'s, C> CallbackScope<'s, C> );
647
648pub unsafe trait Scope: Sized {}
649
650trait ScopeCast: Sized {
651 fn cast_ref<S: Scope>(&self) -> &S;
652 fn cast_mut<S: Scope>(&mut self) -> &mut S;
653}
654
655impl<T: Scope> ScopeCast for T {
656 fn cast_ref<S: Scope>(&self) -> &S {
657 assert_eq!(Layout::new::<Self>(), Layout::new::<S>());
658 unsafe { &*(self as *const _ as *const S) }
659 }
660
661 fn cast_mut<S: Scope>(&mut self) -> &mut S {
662 assert_eq!(Layout::new::<Self>(), Layout::new::<S>());
663 unsafe { &mut *(self as *mut _ as *mut S) }
664 }
665}
666
667mod param {
681 use super::*;
682
683 pub trait NewContextScope<'s>: getter::GetScopeData {
684 type NewScope: Scope;
685 }
686
687 impl<'s, 'p: 's, P: Scope> NewContextScope<'s> for ContextScope<'p, P> {
688 type NewScope = ContextScope<'s, P>;
689 }
690
691 impl<'s, 'p: 's, C> NewContextScope<'s> for HandleScope<'p, C> {
692 type NewScope = ContextScope<'s, HandleScope<'p>>;
693 }
694
695 impl<'s, 'p: 's, 'e: 'p, C> NewContextScope<'s>
696 for EscapableHandleScope<'p, 'e, C>
697 {
698 type NewScope = ContextScope<'s, EscapableHandleScope<'p, 'e>>;
699 }
700
701 impl<'s, 'p: 's, P: NewContextScope<'s>> NewContextScope<'s>
702 for TryCatch<'p, P>
703 {
704 type NewScope = <P as NewContextScope<'s>>::NewScope;
705 }
706
707 impl<'s, 'p: 's, C> NewContextScope<'s> for CallbackScope<'p, C> {
708 type NewScope = ContextScope<'s, HandleScope<'p>>;
709 }
710
711 pub trait NewHandleScope<'s>: getter::GetScopeData {
712 type NewScope: Scope;
713 }
714
715 impl<'s> NewHandleScope<'s> for Isolate {
716 type NewScope = HandleScope<'s, ()>;
717 }
718
719 impl<'s> NewHandleScope<'s> for OwnedIsolate {
720 type NewScope = HandleScope<'s, ()>;
721 }
722
723 impl<'s, 'p: 's, P: NewHandleScope<'s>> NewHandleScope<'s>
724 for ContextScope<'p, P>
725 {
726 type NewScope = <P as NewHandleScope<'s>>::NewScope;
727 }
728
729 impl<'s, 'p: 's, C> NewHandleScope<'s> for HandleScope<'p, C> {
730 type NewScope = HandleScope<'s, C>;
731 }
732
733 impl<'s, 'p: 's, 'e: 'p, C> NewHandleScope<'s>
734 for EscapableHandleScope<'p, 'e, C>
735 {
736 type NewScope = EscapableHandleScope<'s, 'e, C>;
737 }
738
739 impl<'s, 'p: 's, P: NewHandleScope<'s>> NewHandleScope<'s> for TryCatch<'p, P> {
740 type NewScope = <P as NewHandleScope<'s>>::NewScope;
741 }
742
743 impl<'s, 'p: 's, C> NewHandleScope<'s> for CallbackScope<'p, C> {
744 type NewScope = HandleScope<'s, C>;
745 }
746
747 pub trait NewHandleScopeWithContext<'s>: getter::GetScopeData {
748 fn get_isolate_mut(&mut self) -> &mut Isolate;
749 }
750
751 impl<'s> NewHandleScopeWithContext<'s> for Isolate {
752 fn get_isolate_mut(&mut self) -> &mut Isolate {
753 self
754 }
755 }
756
757 impl<'s> NewHandleScopeWithContext<'s> for OwnedIsolate {
758 fn get_isolate_mut(&mut self) -> &mut Isolate {
759 &mut *self
760 }
761 }
762
763 pub trait NewEscapableHandleScope<'s, 'e: 's>: getter::GetScopeData {
764 type NewScope: Scope;
765 }
766
767 impl<'s, 'p: 's, 'e: 'p, P: NewEscapableHandleScope<'s, 'e>>
768 NewEscapableHandleScope<'s, 'e> for ContextScope<'p, P>
769 {
770 type NewScope = <P as NewEscapableHandleScope<'s, 'e>>::NewScope;
771 }
772
773 impl<'s, 'p: 's, C> NewEscapableHandleScope<'s, 'p> for HandleScope<'p, C> {
774 type NewScope = EscapableHandleScope<'s, 'p, C>;
775 }
776
777 impl<'s, 'p: 's, 'e: 'p, C> NewEscapableHandleScope<'s, 'p>
778 for EscapableHandleScope<'p, 'e, C>
779 {
780 type NewScope = EscapableHandleScope<'s, 'p, C>;
781 }
782
783 impl<'s, 'p: 's, 'e: 'p, P: NewEscapableHandleScope<'s, 'e>>
784 NewEscapableHandleScope<'s, 'e> for TryCatch<'p, P>
785 {
786 type NewScope = <P as NewEscapableHandleScope<'s, 'e>>::NewScope;
787 }
788
789 impl<'s, 'p: 's, C> NewEscapableHandleScope<'s, 'p> for CallbackScope<'p, C> {
790 type NewScope = EscapableHandleScope<'s, 'p, C>;
791 }
792
793 pub trait NewTryCatch<'s>: getter::GetScopeData {
794 type NewScope: Scope;
795 }
796
797 impl<'s, 'p: 's, P: NewTryCatch<'s>> NewTryCatch<'s> for ContextScope<'p, P> {
798 type NewScope = <P as NewTryCatch<'s>>::NewScope;
799 }
800
801 impl<'s, 'p: 's, C> NewTryCatch<'s> for HandleScope<'p, C> {
802 type NewScope = TryCatch<'s, HandleScope<'p, C>>;
803 }
804
805 impl<'s, 'p: 's, 'e: 'p, C> NewTryCatch<'s>
806 for EscapableHandleScope<'p, 'e, C>
807 {
808 type NewScope = TryCatch<'s, EscapableHandleScope<'p, 'e, C>>;
809 }
810
811 impl<'s, 'p: 's, P> NewTryCatch<'s> for TryCatch<'p, P> {
812 type NewScope = TryCatch<'s, P>;
813 }
814
815 impl<'s, 'p: 's, C> NewTryCatch<'s> for CallbackScope<'p, C> {
816 type NewScope = TryCatch<'s, HandleScope<'p, C>>;
817 }
818
819 pub trait NewCallbackScope<'s>: Sized + getter::GetIsolate<'s> {
820 type NewScope: Scope;
821
822 unsafe fn get_isolate_mut_and_maybe_current_context(
823 self,
824 ) -> (&'s mut Isolate, Option<Local<'s, Context>>) {
825 (self.get_isolate_mut(), None)
826 }
827 }
828
829 impl<'s> NewCallbackScope<'s> for &'s mut Isolate {
830 type NewScope = CallbackScope<'s, ()>;
831 }
832
833 impl<'s> NewCallbackScope<'s> for &'s mut OwnedIsolate {
834 type NewScope = CallbackScope<'s, ()>;
835 }
836
837 impl<'s> NewCallbackScope<'s> for &'s FunctionCallbackInfo {
838 type NewScope = CallbackScope<'s>;
839 }
840
841 impl<'s> NewCallbackScope<'s> for &'s PropertyCallbackInfo {
842 type NewScope = CallbackScope<'s>;
843 }
844
845 impl<'s> NewCallbackScope<'s> for Local<'s, Context> {
846 type NewScope = CallbackScope<'s>;
847
848 unsafe fn get_isolate_mut_and_maybe_current_context(
849 self,
850 ) -> (&'s mut Isolate, Option<Local<'s, Context>>) {
851 (getter::GetIsolate::get_isolate_mut(self), Some(self))
852 }
853 }
854
855 impl<'s> NewCallbackScope<'s> for Local<'s, Message> {
856 type NewScope = CallbackScope<'s>;
857 }
858
859 impl<'s, T: Into<Local<'s, Object>>> NewCallbackScope<'s> for T {
860 type NewScope = CallbackScope<'s>;
861 }
862
863 impl<'s> NewCallbackScope<'s> for &'s PromiseRejectMessage<'s> {
864 type NewScope = CallbackScope<'s>;
865 }
866}
867
868mod getter {
872 pub use super::*;
873
874 pub trait GetIsolate<'s> {
875 unsafe fn get_isolate_mut(self) -> &'s mut Isolate;
876 }
877
878 impl<'s> GetIsolate<'s> for &'s mut Isolate {
879 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
880 self
881 }
882 }
883
884 impl<'s> GetIsolate<'s> for &'s mut OwnedIsolate {
885 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
886 &mut *self
887 }
888 }
889
890 impl<'s> GetIsolate<'s> for &'s FunctionCallbackInfo {
891 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
892 &mut *raw::v8__FunctionCallbackInfo__GetIsolate(self)
893 }
894 }
895
896 impl<'s> GetIsolate<'s> for &'s PropertyCallbackInfo {
897 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
898 &mut *raw::v8__PropertyCallbackInfo__GetIsolate(self)
899 }
900 }
901
902 impl<'s> GetIsolate<'s> for Local<'s, Context> {
903 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
904 &mut *raw::v8__Context__GetIsolate(&*self)
905 }
906 }
907
908 impl<'s> GetIsolate<'s> for Local<'s, Message> {
909 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
910 &mut *raw::v8__Message__GetIsolate(&*self)
911 }
912 }
913
914 impl<'s, T: Into<Local<'s, Object>>> GetIsolate<'s> for T {
915 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
916 let object: Local<Object> = self.into();
917 &mut *raw::v8__Object__GetIsolate(&*object)
918 }
919 }
920
921 impl<'s> GetIsolate<'s> for &'s PromiseRejectMessage<'s> {
922 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
923 let object: Local<Object> = self.get_promise().into();
924 &mut *raw::v8__Object__GetIsolate(&*object)
925 }
926 }
927
928 pub trait GetScopeData {
929 fn get_scope_data_mut(&mut self) -> &mut data::ScopeData;
930 }
931
932 impl<T: Scope> GetScopeData for T {
933 fn get_scope_data_mut(&mut self) -> &mut data::ScopeData {
934 data::ScopeData::get_mut(self)
935 }
936 }
937
938 impl GetScopeData for Isolate {
939 fn get_scope_data_mut(&mut self) -> &mut data::ScopeData {
940 data::ScopeData::get_root_mut(self)
941 }
942 }
943
944 impl GetScopeData for OwnedIsolate {
945 fn get_scope_data_mut(&mut self) -> &mut data::ScopeData {
946 data::ScopeData::get_root_mut(self)
947 }
948 }
949}
950
951pub(crate) mod data {
955 use super::*;
956
957 #[derive(Debug)]
958 pub struct ScopeData {
959 isolate: NonNull<Isolate>,
966 previous: Option<NonNull<ScopeData>>,
967 next: Option<Box<ScopeData>>,
968 status: Cell<ScopeStatus>,
970 context: Cell<Option<NonNull<Context>>>,
973 escape_slot: Option<NonNull<Option<raw::EscapeSlot>>>,
974 try_catch: Option<NonNull<raw::TryCatch>>,
975 scope_type_specific_data: ScopeTypeSpecificData,
976 }
977
978 impl ScopeData {
979 pub(crate) fn get_current_mut(isolate: &mut Isolate) -> &mut Self {
983 let self_mut = isolate
984 .get_current_scope_data()
985 .map(NonNull::as_ptr)
986 .map(|p| unsafe { &mut *p })
987 .unwrap();
988 match self_mut.status.get() {
989 ScopeStatus::Current { .. } => self_mut,
990 _ => unreachable!(),
991 }
992 }
993
994 pub(crate) fn new_root(isolate: &mut Isolate) {
998 let root = Box::leak(Self::boxed(isolate.into()));
999 root.status = ScopeStatus::Current { zombie: false }.into();
1000 debug_assert!(isolate.get_current_scope_data().is_none());
1001 isolate.set_current_scope_data(Some(root.into()));
1002 }
1003
1004 pub(crate) fn get_root_mut(isolate: &mut Isolate) -> &mut Self {
1013 let mut current_scope_data = Self::get_current_mut(isolate);
1014 loop {
1015 current_scope_data = match current_scope_data {
1016 root if root.previous.is_none() => break root,
1017 data => data.try_exit_scope(),
1018 };
1019 }
1020 }
1021
1022 pub(crate) fn drop_root(isolate: &mut Isolate) {
1025 let root = Self::get_root_mut(isolate);
1026 unsafe { Box::from_raw(root) };
1027 isolate.set_current_scope_data(None);
1028 }
1029
1030 pub(super) fn new_context_scope_data<'s>(
1031 &'s mut self,
1032 context: Local<'s, Context>,
1033 ) -> &'s mut Self {
1034 self.new_scope_data_with(move |data| {
1035 data.scope_type_specific_data.init_with(|| {
1036 ScopeTypeSpecificData::ContextScope {
1037 raw_context_scope: raw::ContextScope::new(context),
1038 }
1039 });
1040 data.context.set(Some(context.as_non_null()));
1041 })
1042 }
1043
1044 #[inline(always)]
1049 fn new_handle_scope_data_with<F>(&mut self, init_context_fn: F) -> &mut Self
1050 where
1051 F: FnOnce(
1052 NonNull<Isolate>,
1053 &mut Cell<Option<NonNull<Context>>>,
1054 &mut Option<raw::ContextScope>,
1055 ),
1056 {
1057 self.new_scope_data_with(|data| {
1058 let isolate = data.isolate;
1059 data.scope_type_specific_data.init_with(|| {
1060 ScopeTypeSpecificData::HandleScope {
1061 raw_handle_scope: unsafe { raw::HandleScope::uninit() },
1062 raw_context_scope: None,
1063 }
1064 });
1065 match &mut data.scope_type_specific_data {
1066 ScopeTypeSpecificData::HandleScope {
1067 raw_handle_scope,
1068 raw_context_scope,
1069 } => {
1070 unsafe { raw_handle_scope.init(isolate) };
1071 init_context_fn(isolate, &mut data.context, raw_context_scope);
1072 }
1073 _ => unreachable!(),
1074 };
1075 })
1076 }
1077
1078 pub(super) fn new_handle_scope_data(&mut self) -> &mut Self {
1079 self.new_handle_scope_data_with(|_, _, raw_context_scope| {
1080 debug_assert!(raw_context_scope.is_none())
1081 })
1082 }
1083
1084 pub(super) fn new_handle_scope_data_with_context(
1085 &mut self,
1086 context_ref: &Context,
1087 ) -> &mut Self {
1088 self.new_handle_scope_data_with(
1089 move |isolate, context_data, raw_context_scope| unsafe {
1090 let context_nn = NonNull::from(context_ref);
1091 let local_context_ptr =
1094 raw::v8__Local__New(isolate.as_ptr(), context_nn.cast().as_ptr())
1095 as *const Context;
1096 let local_context_nn =
1097 NonNull::new_unchecked(local_context_ptr as *mut _);
1098 let local_context = Local::from_non_null(local_context_nn);
1099 debug_assert!(raw_context_scope.is_none());
1101 ptr::write(
1102 raw_context_scope,
1103 Some(raw::ContextScope::new(local_context)),
1104 );
1105 context_data.set(Some(local_context_nn));
1108 },
1109 )
1110 }
1111
1112 pub(super) fn new_escapable_handle_scope_data(&mut self) -> &mut Self {
1113 self.new_scope_data_with(|data| {
1114 let isolate = data.isolate;
1119 data.scope_type_specific_data.init_with(|| {
1120 ScopeTypeSpecificData::EscapableHandleScope {
1121 raw_handle_scope: unsafe { raw::HandleScope::uninit() },
1122 raw_escape_slot: Some(raw::EscapeSlot::new(isolate)),
1123 }
1124 });
1125 match &mut data.scope_type_specific_data {
1126 ScopeTypeSpecificData::EscapableHandleScope {
1127 raw_handle_scope,
1128 raw_escape_slot,
1129 } => {
1130 unsafe { raw_handle_scope.init(isolate) };
1131 data.escape_slot.replace(raw_escape_slot.into());
1132 }
1133 _ => unreachable!(),
1134 }
1135 })
1136 }
1137
1138 pub(super) fn new_try_catch_data(&mut self) -> &mut Self {
1139 self.new_scope_data_with(|data| {
1140 let isolate = data.isolate;
1141 data.scope_type_specific_data.init_with(|| {
1142 ScopeTypeSpecificData::TryCatch {
1143 raw_try_catch: unsafe { raw::TryCatch::uninit() },
1144 }
1145 });
1146 match &mut data.scope_type_specific_data {
1147 ScopeTypeSpecificData::TryCatch { raw_try_catch } => {
1148 unsafe { raw_try_catch.init(isolate) };
1149 data.try_catch.replace(raw_try_catch.into());
1150 }
1151 _ => unreachable!(),
1152 }
1153 })
1154 }
1155
1156 pub(super) fn new_callback_scope_data<'s>(
1157 &'s mut self,
1158 maybe_current_context: Option<Local<'s, Context>>,
1159 ) -> &'s mut Self {
1160 self.new_scope_data_with(|data| {
1161 debug_assert!(data.scope_type_specific_data.is_none());
1162 data
1163 .context
1164 .set(maybe_current_context.map(|cx| cx.as_non_null()));
1165 })
1166 }
1167
1168 fn new_scope_data_with(
1169 &mut self,
1170 init_fn: impl FnOnce(&mut Self),
1171 ) -> &mut Self {
1172 self.status.set(match self.status.get() {
1174 ScopeStatus::Current { zombie } => ScopeStatus::Shadowed { zombie },
1175 _ => unreachable!(),
1176 });
1177 let context = self.context.get().into();
1179 let escape_slot = self.escape_slot;
1180 let new_scope_data = self.allocate_or_reuse_scope_data();
1182 new_scope_data.status = Cell::new(ScopeStatus::Current {
1187 zombie: cfg!(debug_assertions),
1188 });
1189 new_scope_data.context = context;
1191 new_scope_data.escape_slot = escape_slot;
1192 (init_fn)(new_scope_data);
1193 let new_scope_nn = unsafe { NonNull::new_unchecked(new_scope_data) };
1195 new_scope_data
1196 .get_isolate_mut()
1197 .set_current_scope_data(Some(new_scope_nn));
1198 new_scope_data
1199 }
1200
1201 fn allocate_or_reuse_scope_data(&mut self) -> &mut Self {
1204 let self_nn = NonNull::new(self);
1205 match &mut self.next {
1206 Some(next_box) => {
1207 debug_assert_eq!(next_box.isolate, self.isolate);
1209 debug_assert_eq!(next_box.previous, self_nn);
1210 debug_assert_eq!(next_box.status.get(), ScopeStatus::Free);
1211 debug_assert!(next_box.scope_type_specific_data.is_none());
1212 next_box.as_mut()
1213 }
1214 next_field @ None => {
1215 let mut next_box = Self::boxed(self.isolate);
1217 next_box.previous = self_nn;
1218 next_field.replace(next_box);
1219 next_field.as_mut().unwrap()
1220 }
1221 }
1222 }
1223
1224 pub(super) fn as_scope<S: Scope>(&mut self) -> S {
1225 assert_eq!(Layout::new::<&mut Self>(), Layout::new::<S>());
1226 if cfg!(debug_assertions) {
1230 assert_eq!(self.status.get(), ScopeStatus::Current { zombie: true });
1231 self.status.set(ScopeStatus::Current { zombie: false });
1232 }
1233 let self_nn = NonNull::from(self);
1234 unsafe { ptr::read(&self_nn as *const _ as *const S) }
1235 }
1236
1237 pub(super) fn get<S: Scope>(scope: &S) -> &Self {
1238 let self_mut = unsafe {
1239 (*(scope as *const S as *mut S as *mut NonNull<Self>)).as_mut()
1240 };
1241 self_mut.try_activate_scope();
1242 self_mut
1243 }
1244
1245 pub(super) fn get_mut<S: Scope>(scope: &mut S) -> &mut Self {
1246 let self_mut =
1247 unsafe { (*(scope as *mut S as *mut NonNull<Self>)).as_mut() };
1248 self_mut.try_activate_scope();
1249 self_mut
1250 }
1251
1252 #[inline(always)]
1253 fn try_activate_scope(mut self: &mut Self) -> &mut Self {
1254 self = match self.status.get() {
1255 ScopeStatus::Current { zombie: false } => self,
1256 ScopeStatus::Shadowed { zombie: false } => {
1257 self.next.as_mut().unwrap().try_exit_scope()
1258 }
1259 _ => unreachable!(),
1260 };
1261 debug_assert_eq!(
1262 self.get_isolate().get_current_scope_data(),
1263 NonNull::new(self as *mut _)
1264 );
1265 self
1266 }
1267
1268 fn try_exit_scope(mut self: &mut Self) -> &mut Self {
1269 loop {
1270 self = match self.status.get() {
1271 ScopeStatus::Shadowed { .. } => {
1272 self.next.as_mut().unwrap().try_exit_scope()
1273 }
1274 ScopeStatus::Current { zombie: true } => break self.exit_scope(),
1275 ScopeStatus::Current { zombie: false } => {
1276 panic!("active scope can't be dropped")
1277 }
1278 _ => unreachable!(),
1279 }
1280 }
1281 }
1282
1283 fn exit_scope(&mut self) -> &mut Self {
1284 self.scope_type_specific_data = Default::default();
1287 self.status.set(ScopeStatus::Free);
1290
1291 let previous_nn = self.previous.unwrap();
1293 self
1294 .get_isolate_mut()
1295 .set_current_scope_data(Some(previous_nn));
1296 let previous_mut = unsafe { &mut *previous_nn.as_ptr() };
1299 previous_mut.status.set(match previous_mut.status.get() {
1300 ScopeStatus::Shadowed { zombie } => ScopeStatus::Current { zombie },
1301 _ => unreachable!(),
1302 });
1303
1304 previous_mut
1305 }
1306
1307 pub(super) fn notify_scope_dropped(&mut self) {
1327 match &self.scope_type_specific_data {
1328 ScopeTypeSpecificData::HandleScope { .. }
1329 | ScopeTypeSpecificData::EscapableHandleScope { .. } => {
1330 self.status.set(match self.status.get() {
1332 ScopeStatus::Current { zombie: false } => {
1333 ScopeStatus::Current { zombie: true }
1334 }
1335 _ => unreachable!(),
1336 })
1337 }
1338 _ => {
1339 self.exit_scope();
1341 }
1342 }
1343 }
1344
1345 pub(crate) fn get_isolate(&self) -> &Isolate {
1346 unsafe { self.isolate.as_ref() }
1347 }
1348
1349 pub(crate) fn get_isolate_mut(&mut self) -> &mut Isolate {
1350 unsafe { self.isolate.as_mut() }
1351 }
1352
1353 pub(crate) fn get_isolate_ptr(&self) -> *mut Isolate {
1354 self.isolate.as_ptr()
1355 }
1356
1357 pub(crate) fn get_current_context(&self) -> *const Context {
1358 let get_current_context_from_isolate = || unsafe {
1363 raw::v8__Isolate__GetCurrentContext(self.get_isolate_ptr())
1364 };
1365 match self.context.get().map(|nn| nn.as_ptr() as *const _) {
1366 Some(context) => {
1367 debug_assert!(unsafe {
1368 raw::v8__Context__EQ(context, get_current_context_from_isolate())
1369 });
1370 context
1371 }
1372 None => {
1373 let context = get_current_context_from_isolate();
1374 self.context.set(NonNull::new(context as *mut _));
1375 context
1376 }
1377 }
1378 }
1379
1380 pub(super) fn get_escape_slot_mut(
1381 &mut self,
1382 ) -> Option<&mut Option<raw::EscapeSlot>> {
1383 self
1384 .escape_slot
1385 .as_mut()
1386 .map(|escape_slot_nn| unsafe { escape_slot_nn.as_mut() })
1387 }
1388
1389 pub(super) fn get_try_catch(&self) -> &raw::TryCatch {
1390 self
1391 .try_catch
1392 .as_ref()
1393 .map(|try_catch_nn| unsafe { try_catch_nn.as_ref() })
1394 .unwrap()
1395 }
1396
1397 pub(super) fn get_try_catch_mut(&mut self) -> &mut raw::TryCatch {
1398 self
1399 .try_catch
1400 .as_mut()
1401 .map(|try_catch_nn| unsafe { try_catch_nn.as_mut() })
1402 .unwrap()
1403 }
1404
1405 fn boxed(isolate: NonNull<Isolate>) -> Box<Self> {
1411 unsafe {
1412 #[allow(clippy::cast_ptr_alignment)]
1413 let self_ptr = alloc(Layout::new::<Self>()) as *mut Self;
1414 ptr::write(
1415 self_ptr,
1416 Self {
1417 isolate,
1418 previous: Default::default(),
1419 next: Default::default(),
1420 status: Default::default(),
1421 context: Default::default(),
1422 escape_slot: Default::default(),
1423 try_catch: Default::default(),
1424 scope_type_specific_data: Default::default(),
1425 },
1426 );
1427 Box::from_raw(self_ptr)
1428 }
1429 }
1430 }
1431
1432 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
1433 enum ScopeStatus {
1434 Free,
1435 Current { zombie: bool },
1436 Shadowed { zombie: bool },
1437 }
1438
1439 impl Default for ScopeStatus {
1440 fn default() -> Self {
1441 Self::Free
1442 }
1443 }
1444
1445 #[derive(Debug)]
1446 enum ScopeTypeSpecificData {
1447 None,
1448 ContextScope {
1449 raw_context_scope: raw::ContextScope,
1450 },
1451 HandleScope {
1452 raw_handle_scope: raw::HandleScope,
1453 raw_context_scope: Option<raw::ContextScope>,
1454 },
1455 EscapableHandleScope {
1456 raw_handle_scope: raw::HandleScope,
1457 raw_escape_slot: Option<raw::EscapeSlot>,
1458 },
1459 TryCatch {
1460 raw_try_catch: raw::TryCatch,
1461 },
1462 }
1463
1464 impl Default for ScopeTypeSpecificData {
1465 fn default() -> Self {
1466 Self::None
1467 }
1468 }
1469
1470 impl Drop for ScopeTypeSpecificData {
1471 fn drop(&mut self) {
1472 if let Self::HandleScope {
1478 raw_context_scope, ..
1479 } = self
1480 {
1481 *raw_context_scope = None
1482 }
1483 }
1484 }
1485
1486 impl ScopeTypeSpecificData {
1487 pub fn is_none(&self) -> bool {
1488 matches!(self, Self::None)
1489 }
1490
1491 pub fn init_with(&mut self, init_fn: impl FnOnce() -> Self) {
1498 assert!(self.is_none());
1499 unsafe { ptr::write(self, (init_fn)()) }
1500 }
1501 }
1502}
1503
1504mod raw {
1507 use super::*;
1508
1509 #[derive(Clone, Copy, Debug)]
1510 #[repr(transparent)]
1511 pub(super) struct Address(NonZeroUsize);
1512
1513 #[derive(Debug)]
1514 pub(super) struct ContextScope {
1515 entered_context: NonNull<Context>,
1516 }
1517
1518 impl ContextScope {
1519 pub fn new(context: Local<Context>) -> Self {
1520 unsafe { v8__Context__Enter(&*context) };
1521 Self {
1522 entered_context: context.as_non_null(),
1523 }
1524 }
1525 }
1526
1527 impl Drop for ContextScope {
1528 fn drop(&mut self) {
1529 unsafe { v8__Context__Exit(self.entered_context.as_ptr()) };
1530 }
1531 }
1532
1533 #[repr(C)]
1534 #[derive(Debug)]
1535 pub(super) struct HandleScope([usize; 3]);
1536
1537 impl HandleScope {
1538 pub unsafe fn uninit() -> Self {
1541 #[allow(clippy::uninit_assumed_init)]
1544 Self(MaybeUninit::uninit().assume_init())
1545 }
1546
1547 pub unsafe fn init(&mut self, isolate: NonNull<Isolate>) {
1551 let buf = NonNull::from(self).cast();
1552 v8__HandleScope__CONSTRUCT(buf.as_ptr(), isolate.as_ptr());
1553 }
1554 }
1555
1556 impl Drop for HandleScope {
1557 fn drop(&mut self) {
1558 unsafe { v8__HandleScope__DESTRUCT(self) };
1559 }
1560 }
1561
1562 #[repr(transparent)]
1563 #[derive(Debug)]
1564 pub(super) struct EscapeSlot(NonNull<raw::Address>);
1565
1566 impl EscapeSlot {
1567 pub fn new(isolate: NonNull<Isolate>) -> Self {
1568 unsafe {
1569 let undefined = raw::v8__Undefined(isolate.as_ptr()) as *const _;
1570 let local = raw::v8__Local__New(isolate.as_ptr(), undefined);
1571 let slot_address_ptr = local as *const Address as *mut _;
1572 let slot_address_nn = NonNull::new_unchecked(slot_address_ptr);
1573 Self(slot_address_nn)
1574 }
1575 }
1576
1577 pub fn escape<'e, T>(self, value: Local<'_, T>) -> Local<'e, T>
1578 where
1579 for<'l> Local<'l, T>: Into<Local<'l, Data>>,
1580 {
1581 assert_eq!(Layout::new::<Self>(), Layout::new::<Local<T>>());
1582 unsafe {
1583 let undefined = Local::<Value>::from_non_null(self.0.cast());
1584 debug_assert!(undefined.is_undefined());
1585 let value_address = *(&*value as *const T as *const Address);
1586 ptr::write(self.0.as_ptr(), value_address);
1587 Local::from_non_null(self.0.cast())
1588 }
1589 }
1590 }
1591
1592 #[repr(C)]
1593 #[derive(Debug)]
1594 pub(super) struct TryCatch([usize; 6]);
1595
1596 impl TryCatch {
1597 pub unsafe fn uninit() -> Self {
1600 #[allow(clippy::uninit_assumed_init)]
1603 Self(MaybeUninit::uninit().assume_init())
1604 }
1605
1606 pub unsafe fn init(&mut self, isolate: NonNull<Isolate>) {
1610 let buf = NonNull::from(self).cast();
1611 v8__TryCatch__CONSTRUCT(buf.as_ptr(), isolate.as_ptr());
1612 }
1613 }
1614
1615 impl Drop for TryCatch {
1616 fn drop(&mut self) {
1617 unsafe { v8__TryCatch__DESTRUCT(self) };
1618 }
1619 }
1620
1621 extern "C" {
1622 pub(super) fn v8__Isolate__GetCurrentContext(
1623 isolate: *mut Isolate,
1624 ) -> *const Context;
1625 pub(super) fn v8__Isolate__GetEnteredOrMicrotaskContext(
1626 isolate: *mut Isolate,
1627 ) -> *const Context;
1628 pub(super) fn v8__Isolate__ThrowException(
1629 isolate: *mut Isolate,
1630 exception: *const Value,
1631 ) -> *const Value;
1632 pub(super) fn v8__Isolate__GetDataFromSnapshotOnce(
1633 this: *mut Isolate,
1634 index: usize,
1635 ) -> *const Data;
1636
1637 pub(super) fn v8__Context__EQ(
1638 this: *const Context,
1639 other: *const Context,
1640 ) -> bool;
1641 pub(super) fn v8__Context__Enter(this: *const Context);
1642 pub(super) fn v8__Context__Exit(this: *const Context);
1643 pub(super) fn v8__Context__GetIsolate(this: *const Context)
1644 -> *mut Isolate;
1645 pub(super) fn v8__Context__GetDataFromSnapshotOnce(
1646 this: *const Context,
1647 index: usize,
1648 ) -> *const Data;
1649
1650 pub(super) fn v8__HandleScope__CONSTRUCT(
1651 buf: *mut MaybeUninit<HandleScope>,
1652 isolate: *mut Isolate,
1653 );
1654 pub(super) fn v8__HandleScope__DESTRUCT(this: *mut HandleScope);
1655
1656 pub(super) fn v8__Local__New(
1657 isolate: *mut Isolate,
1658 other: *const Data,
1659 ) -> *const Data;
1660 pub(super) fn v8__Undefined(isolate: *mut Isolate) -> *const Primitive;
1661
1662 pub(super) fn v8__TryCatch__CONSTRUCT(
1663 buf: *mut MaybeUninit<TryCatch>,
1664 isolate: *mut Isolate,
1665 );
1666 pub(super) fn v8__TryCatch__DESTRUCT(this: *mut TryCatch);
1667 pub(super) fn v8__TryCatch__HasCaught(this: *const TryCatch) -> bool;
1668 pub(super) fn v8__TryCatch__CanContinue(this: *const TryCatch) -> bool;
1669 pub(super) fn v8__TryCatch__HasTerminated(this: *const TryCatch) -> bool;
1670 pub(super) fn v8__TryCatch__IsVerbose(this: *const TryCatch) -> bool;
1671 pub(super) fn v8__TryCatch__SetVerbose(this: *mut TryCatch, value: bool);
1672 pub(super) fn v8__TryCatch__SetCaptureMessage(
1673 this: *mut TryCatch,
1674 value: bool,
1675 );
1676 pub(super) fn v8__TryCatch__Reset(this: *mut TryCatch);
1677 pub(super) fn v8__TryCatch__Exception(
1678 this: *const TryCatch,
1679 ) -> *const Value;
1680 pub(super) fn v8__TryCatch__StackTrace(
1681 this: *const TryCatch,
1682 context: *const Context,
1683 ) -> *const Value;
1684 pub(super) fn v8__TryCatch__Message(
1685 this: *const TryCatch,
1686 ) -> *const Message;
1687 pub(super) fn v8__TryCatch__ReThrow(this: *mut TryCatch) -> *const Value;
1688
1689 pub(super) fn v8__Message__GetIsolate(this: *const Message)
1690 -> *mut Isolate;
1691 pub(super) fn v8__Object__GetIsolate(this: *const Object) -> *mut Isolate;
1692 pub(super) fn v8__FunctionCallbackInfo__GetIsolate(
1693 this: *const FunctionCallbackInfo,
1694 ) -> *mut Isolate;
1695 pub(super) fn v8__PropertyCallbackInfo__GetIsolate(
1696 this: *const PropertyCallbackInfo,
1697 ) -> *mut Isolate;
1698 }
1699}
1700
1701#[cfg(test)]
1702mod tests {
1703 use super::*;
1704 use crate::new_default_platform;
1705 use crate::Global;
1706 use crate::V8;
1707 use std::any::type_name;
1708 use std::sync::Once;
1709
1710 trait SameType {}
1711 impl<A> SameType for (A, A) {}
1712
1713 struct AssertTypeOf<'a, T>(pub &'a T);
1718 impl<'a, T> AssertTypeOf<'a, T> {
1719 pub fn is<A>(self)
1720 where
1721 (A, T): SameType,
1722 {
1723 assert_eq!(type_name::<A>(), type_name::<T>());
1724 }
1725 }
1726
1727 fn initialize_v8() {
1728 static INIT: Once = Once::new();
1729 INIT.call_once(|| {
1730 V8::initialize_platform(new_default_platform(0, false).make_shared());
1731 V8::initialize();
1732 });
1733 }
1734
1735 #[test]
1736 fn deref_types() {
1737 initialize_v8();
1738 let isolate = &mut Isolate::new(Default::default());
1739 AssertTypeOf(isolate).is::<OwnedIsolate>();
1740 let l1_hs = &mut HandleScope::new(isolate);
1741 AssertTypeOf(l1_hs).is::<HandleScope<()>>();
1742 let context = Context::new(l1_hs);
1743 {
1744 let l2_cxs = &mut ContextScope::new(l1_hs, context);
1745 AssertTypeOf(l2_cxs).is::<ContextScope<HandleScope>>();
1746 {
1747 let d = l2_cxs.deref_mut();
1748 AssertTypeOf(d).is::<HandleScope>();
1749 let d = d.deref_mut();
1750 AssertTypeOf(d).is::<HandleScope<()>>();
1751 let d = d.deref_mut();
1752 AssertTypeOf(d).is::<Isolate>();
1753 }
1754 {
1755 let l3_tc = &mut TryCatch::new(l2_cxs);
1756 AssertTypeOf(l3_tc).is::<TryCatch<HandleScope>>();
1757 let d = l3_tc.deref_mut();
1758 AssertTypeOf(d).is::<HandleScope>();
1759 let d = d.deref_mut();
1760 AssertTypeOf(d).is::<HandleScope<()>>();
1761 let d = d.deref_mut();
1762 AssertTypeOf(d).is::<Isolate>();
1763 }
1764 {
1765 let l3_ehs = &mut EscapableHandleScope::new(l2_cxs);
1766 AssertTypeOf(l3_ehs).is::<EscapableHandleScope>();
1767 {
1768 let l4_cxs = &mut ContextScope::new(l3_ehs, context);
1769 AssertTypeOf(l4_cxs).is::<ContextScope<EscapableHandleScope>>();
1770 let d = l4_cxs.deref_mut();
1771 AssertTypeOf(d).is::<EscapableHandleScope>();
1772 let d = d.deref_mut();
1773 AssertTypeOf(d).is::<HandleScope>();
1774 let d = d.deref_mut();
1775 AssertTypeOf(d).is::<HandleScope<()>>();
1776 let d = d.deref_mut();
1777 AssertTypeOf(d).is::<Isolate>();
1778 }
1779 {
1780 let l4_tc = &mut TryCatch::new(l3_ehs);
1781 AssertTypeOf(l4_tc).is::<TryCatch<EscapableHandleScope>>();
1782 let d = l4_tc.deref_mut();
1783 AssertTypeOf(d).is::<EscapableHandleScope>();
1784 let d = d.deref_mut();
1785 AssertTypeOf(d).is::<HandleScope>();
1786 let d = d.deref_mut();
1787 AssertTypeOf(d).is::<HandleScope<()>>();
1788 let d = d.deref_mut();
1789 AssertTypeOf(d).is::<Isolate>();
1790 }
1791 }
1792 }
1793 {
1794 let l2_tc = &mut TryCatch::new(l1_hs);
1795 AssertTypeOf(l2_tc).is::<TryCatch<HandleScope<()>>>();
1796 let d = l2_tc.deref_mut();
1797 AssertTypeOf(d).is::<HandleScope<()>>();
1798 let d = d.deref_mut();
1799 AssertTypeOf(d).is::<Isolate>();
1800 }
1801 {
1802 let l2_ehs = &mut EscapableHandleScope::new(l1_hs);
1803 AssertTypeOf(l2_ehs).is::<EscapableHandleScope<()>>();
1804 let l3_tc = &mut TryCatch::new(l2_ehs);
1805 AssertTypeOf(l3_tc).is::<TryCatch<EscapableHandleScope<()>>>();
1806 let d = l3_tc.deref_mut();
1807 AssertTypeOf(d).is::<EscapableHandleScope<()>>();
1808 let d = d.deref_mut();
1809 AssertTypeOf(d).is::<HandleScope<()>>();
1810 let d = d.deref_mut();
1811 AssertTypeOf(d).is::<Isolate>();
1812 }
1813 {
1814 let _ = ContextScope::new(l1_hs, context);
1819 let l2_cbs = &mut unsafe { CallbackScope::new(context) };
1820 AssertTypeOf(l2_cbs).is::<CallbackScope>();
1821 let d = l2_cbs.deref_mut();
1822 AssertTypeOf(d).is::<HandleScope>();
1823 let d = d.deref_mut();
1824 AssertTypeOf(d).is::<HandleScope<()>>();
1825 let d = d.deref_mut();
1826 AssertTypeOf(d).is::<Isolate>();
1827 }
1828 {
1829 let isolate: &mut Isolate = l1_hs.as_mut();
1830 let l2_cbs = &mut unsafe { CallbackScope::new(isolate) };
1831 AssertTypeOf(l2_cbs).is::<CallbackScope<()>>();
1832 let d = l2_cbs.deref_mut();
1833 AssertTypeOf(d).is::<HandleScope<()>>();
1834 let d = d.deref_mut();
1835 AssertTypeOf(d).is::<Isolate>();
1836 }
1837 }
1838
1839 #[test]
1840 fn new_scope_types() {
1841 initialize_v8();
1842 let isolate = &mut Isolate::new(Default::default());
1843 AssertTypeOf(isolate).is::<OwnedIsolate>();
1844 let global_context: Global<Context>;
1845 {
1846 let l1_hs = &mut HandleScope::new(isolate);
1847 AssertTypeOf(l1_hs).is::<HandleScope<()>>();
1848 let context = Context::new(l1_hs);
1849 global_context = Global::new(l1_hs, context);
1850 AssertTypeOf(&HandleScope::new(l1_hs)).is::<HandleScope<()>>();
1851 {
1852 let l2_cxs = &mut ContextScope::new(l1_hs, context);
1853 AssertTypeOf(l2_cxs).is::<ContextScope<HandleScope>>();
1854 AssertTypeOf(&ContextScope::new(l2_cxs, context))
1855 .is::<ContextScope<HandleScope>>();
1856 AssertTypeOf(&HandleScope::new(l2_cxs)).is::<HandleScope>();
1857 AssertTypeOf(&EscapableHandleScope::new(l2_cxs))
1858 .is::<EscapableHandleScope>();
1859 AssertTypeOf(&TryCatch::new(l2_cxs)).is::<TryCatch<HandleScope>>();
1860 }
1861 {
1862 let l2_ehs = &mut EscapableHandleScope::new(l1_hs);
1863 AssertTypeOf(l2_ehs).is::<EscapableHandleScope<()>>();
1864 AssertTypeOf(&HandleScope::new(l2_ehs))
1865 .is::<EscapableHandleScope<()>>();
1866 AssertTypeOf(&EscapableHandleScope::new(l2_ehs))
1867 .is::<EscapableHandleScope<()>>();
1868 {
1869 let l3_cxs = &mut ContextScope::new(l2_ehs, context);
1870 AssertTypeOf(l3_cxs).is::<ContextScope<EscapableHandleScope>>();
1871 AssertTypeOf(&ContextScope::new(l3_cxs, context))
1872 .is::<ContextScope<EscapableHandleScope>>();
1873 AssertTypeOf(&HandleScope::new(l3_cxs)).is::<EscapableHandleScope>();
1874 AssertTypeOf(&EscapableHandleScope::new(l3_cxs))
1875 .is::<EscapableHandleScope>();
1876 {
1877 let l4_tc = &mut TryCatch::new(l3_cxs);
1878 AssertTypeOf(l4_tc).is::<TryCatch<EscapableHandleScope>>();
1879 AssertTypeOf(&ContextScope::new(l4_tc, context))
1880 .is::<ContextScope<EscapableHandleScope>>();
1881 AssertTypeOf(&HandleScope::new(l4_tc)).is::<EscapableHandleScope>();
1882 AssertTypeOf(&EscapableHandleScope::new(l4_tc))
1883 .is::<EscapableHandleScope>();
1884 AssertTypeOf(&TryCatch::new(l4_tc))
1885 .is::<TryCatch<EscapableHandleScope>>();
1886 }
1887 }
1888 {
1889 let l3_tc = &mut TryCatch::new(l2_ehs);
1890 AssertTypeOf(l3_tc).is::<TryCatch<EscapableHandleScope<()>>>();
1891 AssertTypeOf(&ContextScope::new(l3_tc, context))
1892 .is::<ContextScope<EscapableHandleScope>>();
1893 AssertTypeOf(&HandleScope::new(l3_tc))
1894 .is::<EscapableHandleScope<()>>();
1895 AssertTypeOf(&EscapableHandleScope::new(l3_tc))
1896 .is::<EscapableHandleScope<()>>();
1897 AssertTypeOf(&TryCatch::new(l3_tc))
1898 .is::<TryCatch<EscapableHandleScope<()>>>();
1899 }
1900 }
1901 {
1902 let l2_tc = &mut TryCatch::new(l1_hs);
1903 AssertTypeOf(l2_tc).is::<TryCatch<HandleScope<()>>>();
1904 AssertTypeOf(&ContextScope::new(l2_tc, context))
1905 .is::<ContextScope<HandleScope>>();
1906 AssertTypeOf(&HandleScope::new(l2_tc)).is::<HandleScope<()>>();
1907 AssertTypeOf(&EscapableHandleScope::new(l2_tc))
1908 .is::<EscapableHandleScope<()>>();
1909 AssertTypeOf(&TryCatch::new(l2_tc)).is::<TryCatch<HandleScope<()>>>();
1910 }
1911 {
1912 let l2_cbs = &mut unsafe { CallbackScope::new(context) };
1913 AssertTypeOf(l2_cbs).is::<CallbackScope>();
1914 AssertTypeOf(&ContextScope::new(l2_cbs, context))
1915 .is::<ContextScope<HandleScope>>();
1916 {
1917 let l3_hs = &mut HandleScope::new(l2_cbs);
1918 AssertTypeOf(l3_hs).is::<HandleScope>();
1919 AssertTypeOf(&ContextScope::new(l3_hs, context))
1920 .is::<ContextScope<HandleScope>>();
1921 AssertTypeOf(&HandleScope::new(l3_hs)).is::<HandleScope>();
1922 AssertTypeOf(&EscapableHandleScope::new(l3_hs))
1923 .is::<EscapableHandleScope>();
1924 AssertTypeOf(&TryCatch::new(l3_hs)).is::<TryCatch<HandleScope>>();
1925 }
1926 {
1927 let l3_ehs = &mut EscapableHandleScope::new(l2_cbs);
1928 AssertTypeOf(l3_ehs).is::<EscapableHandleScope>();
1929 AssertTypeOf(&ContextScope::new(l3_ehs, context))
1930 .is::<ContextScope<EscapableHandleScope>>();
1931 AssertTypeOf(&HandleScope::new(l3_ehs)).is::<EscapableHandleScope>();
1932 AssertTypeOf(&EscapableHandleScope::new(l3_ehs))
1933 .is::<EscapableHandleScope>();
1934 AssertTypeOf(&TryCatch::new(l3_ehs))
1935 .is::<TryCatch<EscapableHandleScope>>();
1936 }
1937 {
1938 let l3_tc = &mut TryCatch::new(l2_cbs);
1939 AssertTypeOf(l3_tc).is::<TryCatch<HandleScope>>();
1940 AssertTypeOf(&ContextScope::new(l3_tc, context))
1941 .is::<ContextScope<HandleScope>>();
1942 AssertTypeOf(&HandleScope::new(l3_tc)).is::<HandleScope>();
1943 AssertTypeOf(&EscapableHandleScope::new(l3_tc))
1944 .is::<EscapableHandleScope>();
1945 AssertTypeOf(&TryCatch::new(l3_tc)).is::<TryCatch<HandleScope>>();
1946 }
1947 }
1948 }
1949 {
1950 let l1_cbs = &mut unsafe { CallbackScope::new(&mut *isolate) };
1951 AssertTypeOf(l1_cbs).is::<CallbackScope<()>>();
1952 let context = Context::new(l1_cbs);
1953 AssertTypeOf(&ContextScope::new(l1_cbs, context))
1954 .is::<ContextScope<HandleScope>>();
1955 AssertTypeOf(&HandleScope::new(l1_cbs)).is::<HandleScope<()>>();
1956 AssertTypeOf(&EscapableHandleScope::new(l1_cbs))
1957 .is::<EscapableHandleScope<()>>();
1958 AssertTypeOf(&TryCatch::new(l1_cbs)).is::<TryCatch<HandleScope<()>>>();
1959 }
1960 {
1961 AssertTypeOf(&HandleScope::with_context(isolate, &global_context))
1962 .is::<HandleScope>();
1963 AssertTypeOf(&HandleScope::with_context(isolate, global_context))
1964 .is::<HandleScope>();
1965 }
1966 }
1967}