1use std::alloc::Layout;
92use std::alloc::alloc;
93use std::any::type_name;
94use std::cell::Cell;
95use std::convert::TryInto;
96
97use std::marker::PhantomData;
98use std::mem::MaybeUninit;
99use std::num::NonZeroUsize;
100use std::ops::Deref;
101use std::ops::DerefMut;
102use std::ptr;
103use std::ptr::NonNull;
104
105use crate::Context;
106use crate::Data;
107use crate::DataError;
108use crate::Function;
109use crate::Handle;
110use crate::Isolate;
111use crate::Local;
112use crate::Message;
113use crate::Object;
114use crate::OwnedIsolate;
115use crate::Primitive;
116use crate::PromiseRejectMessage;
117use crate::SealedLocal;
118use crate::Value;
119use crate::fast_api::FastApiCallbackOptions;
120use crate::function::FunctionCallbackInfo;
121use crate::function::PropertyCallbackInfo;
122
123#[derive(Debug)]
127pub struct ContextScope<'s, P> {
128 _data: NonNull<data::ScopeData>,
129 _phantom: PhantomData<&'s mut P>,
130}
131
132impl<'s, P: param::NewContextScope<'s>> ContextScope<'s, P> {
133 #[allow(clippy::new_ret_no_self)]
134 pub fn new(param: &'s mut P, context: Local<Context>) -> P::NewScope {
135 let scope_data = param.get_scope_data_mut();
136 if scope_data.get_isolate_ptr()
137 != unsafe { raw::v8__Context__GetIsolate(&*context) }
138 {
139 panic!(
140 "{} and Context do not belong to the same Isolate",
141 type_name::<P>()
142 )
143 }
144 let new_scope_data = scope_data.new_context_scope_data(context);
145 new_scope_data.as_scope()
146 }
147}
148
149#[derive(Debug)]
162pub struct HandleScope<'s, C = Context> {
163 _data: NonNull<data::ScopeData>,
164 _phantom: PhantomData<&'s mut C>,
165}
166
167impl<'s> HandleScope<'s> {
168 #[allow(clippy::new_ret_no_self)]
169 pub fn new<P: param::NewHandleScope<'s>>(param: &'s mut P) -> P::NewScope {
170 param
171 .get_scope_data_mut()
172 .new_handle_scope_data()
173 .as_scope()
174 }
175
176 pub fn with_context<
181 P: param::NewHandleScopeWithContext<'s>,
182 H: Handle<Data = Context>,
183 >(
184 param: &'s mut P,
185 context: H,
186 ) -> Self {
187 let context_ref = context.open(param.get_isolate_mut());
188 param
189 .get_scope_data_mut()
190 .new_handle_scope_data_with_context(context_ref)
191 .as_scope()
192 }
193
194 #[inline(always)]
197 pub fn get_current_context(&self) -> Local<'s, Context> {
198 let context_ptr = data::ScopeData::get(self).get_current_context();
199 unsafe { Local::from_raw(context_ptr) }.unwrap()
200 }
201
202 pub fn get_entered_or_microtask_context(&self) -> Local<'s, Context> {
207 let data = data::ScopeData::get(self);
208 let isolate_ptr = data.get_isolate_ptr();
209 let context_ptr =
210 unsafe { raw::v8__Isolate__GetEnteredOrMicrotaskContext(isolate_ptr) };
211 unsafe { Local::from_raw(context_ptr) }.unwrap()
212 }
213
214 #[inline(always)]
217 pub fn get_current_host_defined_options(&self) -> Option<Local<'s, Data>> {
218 let data = data::ScopeData::get(self);
219 let isolate_ptr = data.get_isolate_ptr();
220 unsafe {
221 Local::from_raw(raw::v8__Isolate__GetCurrentHostDefinedOptions(
222 isolate_ptr,
223 ))
224 }
225 }
226}
227
228impl<'s> HandleScope<'s, ()> {
229 #[inline(always)]
237 pub fn throw_exception(
238 &mut self,
239 exception: Local<Value>,
240 ) -> Local<'s, Value> {
241 unsafe {
242 self.cast_local(|sd| {
243 raw::v8__Isolate__ThrowException(sd.get_isolate_ptr(), &*exception)
244 })
245 }
246 .unwrap()
247 }
248
249 #[inline(always)]
250 pub(crate) unsafe fn cast_local<T>(
251 &mut self,
252 f: impl FnOnce(&mut data::ScopeData) -> *const T,
253 ) -> Option<Local<'s, T>> {
254 unsafe { Local::from_raw(f(data::ScopeData::get_mut(self))) }
255 }
256
257 #[inline(always)]
258 pub(crate) fn get_isolate_ptr(&self) -> *mut Isolate {
259 data::ScopeData::get(self).get_isolate_ptr()
260 }
261
262 #[inline(always)]
268 pub unsafe fn unseal<T>(&self, v: SealedLocal<T>) -> Local<'s, T> {
269 unsafe { Local::from_non_null(v.0) }
270 }
271}
272
273mod get_data_sealed {
278 use crate::DataError;
279 use std::convert::Infallible;
280
281 pub trait ToDataError {
282 fn to_data_error(self) -> DataError;
283 }
284 impl ToDataError for DataError {
285 fn to_data_error(self) -> DataError {
286 self
287 }
288 }
289 impl ToDataError for Infallible {
290 fn to_data_error(self) -> DataError {
291 unreachable!()
292 }
293 }
294}
295
296impl<'s> HandleScope<'s> {
297 pub fn get_isolate_data_from_snapshot_once<T>(
305 &mut self,
306 index: usize,
307 ) -> Result<Local<'s, T>, DataError>
308 where
309 T: 'static,
310 for<'l> <Local<'l, Data> as TryInto<Local<'l, T>>>::Error:
311 get_data_sealed::ToDataError,
312 for<'l> Local<'l, Data>: TryInto<Local<'l, T>>,
313 {
314 unsafe {
315 let Some(res) = self.cast_local(|sd| {
316 raw::v8__Isolate__GetDataFromSnapshotOnce(sd.get_isolate_ptr(), index)
317 }) else {
318 return Err(DataError::no_data::<T>());
319 };
320 use get_data_sealed::ToDataError;
321 match res.try_into() {
322 Ok(x) => Ok(x),
323 Err(e) => Err(e.to_data_error()),
324 }
325 }
326 }
327
328 pub fn get_context_data_from_snapshot_once<T>(
336 &mut self,
337 index: usize,
338 ) -> Result<Local<'s, T>, DataError>
339 where
340 T: 'static,
341 for<'l> <Local<'l, Data> as TryInto<Local<'l, T>>>::Error:
342 get_data_sealed::ToDataError,
343 for<'l> Local<'l, Data>: TryInto<Local<'l, T>>,
344 {
345 unsafe {
346 let Some(res) = self.cast_local(|sd| {
347 raw::v8__Context__GetDataFromSnapshotOnce(
348 sd.get_current_context(),
349 index,
350 )
351 }) else {
352 return Err(DataError::no_data::<T>());
353 };
354 use get_data_sealed::ToDataError;
355 match res.try_into() {
356 Ok(x) => Ok(x),
357 Err(e) => Err(e.to_data_error()),
358 }
359 }
360 }
361
362 #[inline(always)]
363 pub fn set_promise_hooks(
364 &mut self,
365 init_hook: Option<Local<Function>>,
366 before_hook: Option<Local<Function>>,
367 after_hook: Option<Local<Function>>,
368 resolve_hook: Option<Local<Function>>,
369 ) {
370 unsafe {
371 let sd = data::ScopeData::get_mut(self);
372 raw::v8__Context__SetPromiseHooks(
373 sd.get_current_context(),
374 init_hook.map_or_else(std::ptr::null, |v| &*v),
375 before_hook.map_or_else(std::ptr::null, |v| &*v),
376 after_hook.map_or_else(std::ptr::null, |v| &*v),
377 resolve_hook.map_or_else(std::ptr::null, |v| &*v),
378 );
379 }
380 }
381
382 #[inline(always)]
383 pub fn set_continuation_preserved_embedder_data(
384 &mut self,
385 data: Local<Value>,
386 ) {
387 unsafe {
388 let sd = data::ScopeData::get_mut(self);
389 raw::v8__Context__SetContinuationPreservedEmbedderData(
390 sd.get_isolate_ptr(),
391 &*data,
392 );
393 }
394 }
395
396 #[inline(always)]
397 pub fn get_continuation_preserved_embedder_data(
398 &mut self,
399 ) -> Local<'s, Value> {
400 unsafe {
401 self
402 .cast_local(|sd| {
403 raw::v8__Context__GetContinuationPreservedEmbedderData(
404 sd.get_isolate_ptr(),
405 )
406 })
407 .unwrap()
408 }
409 }
410}
411
412#[derive(Debug)]
420pub struct EscapableHandleScope<'s, 'e: 's, C = Context> {
421 _data: NonNull<data::ScopeData>,
422 _phantom:
423 PhantomData<(&'s mut raw::HandleScope, &'e mut raw::EscapeSlot, &'s C)>,
424}
425
426impl<'s, 'e: 's> EscapableHandleScope<'s, 'e> {
427 #[allow(clippy::new_ret_no_self)]
428 pub fn new<P: param::NewEscapableHandleScope<'s, 'e>>(
429 param: &'s mut P,
430 ) -> P::NewScope {
431 param
432 .get_scope_data_mut()
433 .new_escapable_handle_scope_data()
434 .as_scope()
435 }
436}
437
438impl<'s, 'e: 's, C> EscapableHandleScope<'s, 'e, C> {
439 pub fn escape<T>(&mut self, value: Local<T>) -> Local<'e, T>
442 where
443 for<'l> Local<'l, T>: Into<Local<'l, Data>>,
444 {
445 let escape_slot = data::ScopeData::get_mut(self)
446 .get_escape_slot_mut()
447 .expect("internal error: EscapableHandleScope has no escape slot")
448 .take()
449 .expect("EscapableHandleScope::escape() called twice");
450 escape_slot.escape(value)
451 }
452}
453
454#[derive(Debug)]
456pub struct TryCatch<'s, P> {
457 _data: NonNull<data::ScopeData>,
458 _phantom: PhantomData<&'s mut P>,
459}
460
461impl<'s, P: param::NewTryCatch<'s>> TryCatch<'s, P> {
462 #[allow(clippy::new_ret_no_self)]
463 pub fn new(param: &'s mut P) -> P::NewScope {
464 param.get_scope_data_mut().new_try_catch_data().as_scope()
465 }
466}
467
468impl<P> TryCatch<'_, P> {
469 #[inline(always)]
471 pub fn has_caught(&self) -> bool {
472 unsafe { raw::v8__TryCatch__HasCaught(self.get_raw()) }
473 }
474
475 #[inline(always)]
482 pub fn can_continue(&self) -> bool {
483 unsafe { raw::v8__TryCatch__CanContinue(self.get_raw()) }
484 }
485
486 #[inline(always)]
497 pub fn has_terminated(&self) -> bool {
498 unsafe { raw::v8__TryCatch__HasTerminated(self.get_raw()) }
499 }
500
501 #[inline(always)]
503 pub fn is_verbose(&self) -> bool {
504 unsafe { raw::v8__TryCatch__IsVerbose(self.get_raw()) }
505 }
506
507 #[inline(always)]
514 pub fn set_verbose(&mut self, value: bool) {
515 unsafe { raw::v8__TryCatch__SetVerbose(self.get_raw_mut(), value) };
516 }
517
518 #[inline(always)]
522 pub fn set_capture_message(&mut self, value: bool) {
523 unsafe { raw::v8__TryCatch__SetCaptureMessage(self.get_raw_mut(), value) };
524 }
525
526 #[inline(always)]
536 pub fn reset(&mut self) {
537 unsafe { raw::v8__TryCatch__Reset(self.get_raw_mut()) };
538 }
539
540 #[inline(always)]
541 fn get_raw(&self) -> &raw::TryCatch {
542 data::ScopeData::get(self).get_try_catch()
543 }
544
545 #[inline(always)]
546 fn get_raw_mut(&mut self) -> &mut raw::TryCatch {
547 data::ScopeData::get_mut(self).get_try_catch_mut()
548 }
549}
550
551impl<'s, 'p: 's, P> TryCatch<'s, P>
552where
553 Self: AsMut<HandleScope<'p, ()>>,
554{
555 pub fn exception(&mut self) -> Option<Local<'p, Value>> {
564 unsafe {
565 self
566 .as_mut()
567 .cast_local(|sd| raw::v8__TryCatch__Exception(sd.get_try_catch()))
568 }
569 }
570
571 pub fn message(&mut self) -> Option<Local<'p, Message>> {
577 unsafe {
578 self
579 .as_mut()
580 .cast_local(|sd| raw::v8__TryCatch__Message(sd.get_try_catch()))
581 }
582 }
583
584 pub fn rethrow(&mut self) -> Option<Local<'_, Value>> {
593 unsafe {
594 self
595 .as_mut()
596 .cast_local(|sd| raw::v8__TryCatch__ReThrow(sd.get_try_catch_mut()))
597 }
598 }
599}
600
601impl<'s, 'p: 's, P> TryCatch<'s, P>
602where
603 Self: AsMut<HandleScope<'p>>,
604{
605 pub fn stack_trace(&mut self) -> Option<Local<'p, Value>> {
608 unsafe {
609 self.as_mut().cast_local(|sd| {
610 raw::v8__TryCatch__StackTrace(
611 sd.get_try_catch(),
612 sd.get_current_context(),
613 )
614 })
615 }
616 }
617}
618
619#[derive(Debug)]
645pub struct CallbackScope<'s, C = Context> {
646 _data: NonNull<data::ScopeData>,
647 _phantom: PhantomData<&'s mut HandleScope<'s, C>>,
648}
649
650impl<'s> CallbackScope<'s> {
651 #[allow(clippy::new_ret_no_self)]
652 pub unsafe fn new<P: param::NewCallbackScope<'s>>(param: P) -> P::NewScope {
653 let context = param.get_context();
654 let scope_data =
655 data::ScopeData::get_current_mut(unsafe { param.get_isolate_mut() });
656 let scope_data = if P::NEEDS_SCOPE {
659 if let Some(context) = context {
660 scope_data.new_handle_scope_data_with_context(&context)
661 } else {
662 scope_data.new_handle_scope_data()
663 }
664 } else {
665 scope_data.new_callback_scope_data(context)
666 };
667 scope_data.disable_zombie();
670 scope_data.as_scope()
671 }
672}
673
674#[derive(Debug, Clone, Copy, PartialEq, Eq)]
675#[repr(C)]
676pub enum OnFailure {
677 CrashOnFailure,
678 ThrowOnFailure,
679 DumpOnFailure,
680}
681
682#[derive(Debug)]
683pub struct DisallowJavascriptExecutionScope<'s, P> {
684 _data: NonNull<data::ScopeData>,
685 _phantom: PhantomData<&'s mut P>,
686}
687
688impl<'s, P: param::NewDisallowJavascriptExecutionScope<'s>>
689 DisallowJavascriptExecutionScope<'s, P>
690{
691 #[allow(clippy::new_ret_no_self)]
692 pub fn new(param: &'s mut P, on_failure: OnFailure) -> P::NewScope {
693 param
694 .get_scope_data_mut()
695 .new_disallow_javascript_execution_scope_data(on_failure)
696 .as_scope()
697 }
698}
699
700#[derive(Debug)]
701pub struct AllowJavascriptExecutionScope<'s, P> {
702 _data: NonNull<data::ScopeData>,
703 _phantom: PhantomData<&'s mut P>,
704}
705
706impl<'s, P: param::NewAllowJavascriptExecutionScope<'s>>
707 AllowJavascriptExecutionScope<'s, P>
708{
709 #[allow(clippy::new_ret_no_self)]
710 pub fn new(param: &'s mut P) -> P::NewScope {
711 param
712 .get_scope_data_mut()
713 .new_allow_javascript_execution_scope_data()
714 .as_scope()
715 }
716}
717
718macro_rules! impl_as {
719 (<$($params:tt),+> $src_type:ty as Isolate) => {
721 impl<$($params),*> AsRef<Isolate> for $src_type {
722 fn as_ref(&self) -> &Isolate {
723 data::ScopeData::get(self).get_isolate()
724 }
725 }
726
727 impl<$($params),*> AsMut<Isolate> for $src_type {
728 fn as_mut(&mut self) -> &mut Isolate {
729 data::ScopeData::get_mut(self).get_isolate_mut()
730 }
731 }
732 };
733
734 (<$($params:tt),+> $src_type:ty as $tgt_type:ty) => {
737 impl<$($params),*> AsRef<$tgt_type> for $src_type {
738 fn as_ref(&self) -> &$tgt_type {
739 self.cast_ref()
740 }
741 }
742
743 impl<$($params),*> AsMut< $tgt_type> for $src_type {
744 fn as_mut(&mut self) -> &mut $tgt_type {
745 self.cast_mut()
746 }
747 }
748 };
749}
750
751impl_as!(<'s, 'p, P> ContextScope<'s, P> as Isolate);
752impl_as!(<'s, C> HandleScope<'s, C> as Isolate);
753impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as Isolate);
754impl_as!(<'s, P> TryCatch<'s, P> as Isolate);
755impl_as!(<'s, P> DisallowJavascriptExecutionScope<'s, P> as Isolate);
756impl_as!(<'s, P> AllowJavascriptExecutionScope<'s, P> as Isolate);
757impl_as!(<'s, C> CallbackScope<'s, C> as Isolate);
758
759impl_as!(<'s, 'p> ContextScope<'s, HandleScope<'p>> as HandleScope<'p, ()>);
760impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p, ()>);
761impl_as!(<'s, C> HandleScope<'s, C> as HandleScope<'s, ()>);
762impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as HandleScope<'s, ()>);
763impl_as!(<'s, 'p, C> TryCatch<'s, HandleScope<'p, C>> as HandleScope<'p, ()>);
764impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as HandleScope<'p, ()>);
765impl_as!(<'s, 'p, C> DisallowJavascriptExecutionScope<'s, HandleScope<'p, C>> as HandleScope<'p, ()>);
766impl_as!(<'s, 'p, 'e, C> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as HandleScope<'p, ()>);
767impl_as!(<'s, 'p, C> AllowJavascriptExecutionScope<'s, HandleScope<'p, C>> as HandleScope<'p, ()>);
768impl_as!(<'s, 'p, 'e, C> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as HandleScope<'p, ()>);
769impl_as!(<'s, C> CallbackScope<'s, C> as HandleScope<'s, ()>);
770
771impl_as!(<'s, 'p> ContextScope<'s, HandleScope<'p>> as HandleScope<'p>);
772impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>);
773impl_as!(<'s> HandleScope<'s> as HandleScope<'s>);
774impl_as!(<'s, 'e> EscapableHandleScope<'s, 'e> as HandleScope<'s>);
775impl_as!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as HandleScope<'p>);
776impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>);
777impl_as!(<'s, 'p> DisallowJavascriptExecutionScope<'s, HandleScope<'p>> as HandleScope<'p>);
778impl_as!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>);
779impl_as!(<'s, 'p> AllowJavascriptExecutionScope<'s, HandleScope<'p>> as HandleScope<'p>);
780impl_as!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>);
781impl_as!(<'s> CallbackScope<'s> as HandleScope<'s>);
782
783impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e, ()>);
784impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as EscapableHandleScope<'s, 'e, ()>);
785impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as EscapableHandleScope<'p, 'e, ()>);
786impl_as!(<'s, 'p, 'e, C> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as EscapableHandleScope<'p, 'e, ()>);
787impl_as!(<'s, 'p, 'e, C> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as EscapableHandleScope<'p, 'e, ()>);
788
789impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
790impl_as!(<'s, 'e> EscapableHandleScope<'s, 'e> as EscapableHandleScope<'s, 'e>);
791impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
792impl_as!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
793impl_as!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
794
795impl_as!(<'s, 'p, C> TryCatch<'s, HandleScope<'p, C>> as TryCatch<'s, HandleScope<'p, ()>>);
796impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as TryCatch<'s, HandleScope<'p, ()>>);
797impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as TryCatch<'s, EscapableHandleScope<'p, 'e, ()>>);
798
799impl_as!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as TryCatch<'s, HandleScope<'p>>);
800impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as TryCatch<'s, HandleScope<'p>>);
801impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as TryCatch<'s, EscapableHandleScope<'p, 'e>>);
802
803impl_as!(<'s, 'p, C> DisallowJavascriptExecutionScope<'s, HandleScope<'p, C>> as DisallowJavascriptExecutionScope<'s, HandleScope<'p, ()>>);
804impl_as!(<'s, 'p, 'e, C> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as DisallowJavascriptExecutionScope<'s, HandleScope<'p, ()>>);
805impl_as!(<'s, 'p, 'e, C> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, ()>>);
806
807impl_as!(<'s, 'p> DisallowJavascriptExecutionScope<'s, HandleScope<'p>> as DisallowJavascriptExecutionScope<'s, HandleScope<'p>>);
808impl_as!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as DisallowJavascriptExecutionScope<'s, HandleScope<'p>>);
809impl_as!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>>);
810
811impl_as!(<'s, 'p, C> AllowJavascriptExecutionScope<'s, HandleScope<'p, C>> as AllowJavascriptExecutionScope<'s, HandleScope<'p, ()>>);
812impl_as!(<'s, 'p, 'e, C> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as AllowJavascriptExecutionScope<'s, HandleScope<'p, ()>>);
813impl_as!(<'s, 'p, 'e, C> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, ()>>);
814
815impl_as!(<'s, 'p> AllowJavascriptExecutionScope<'s, HandleScope<'p>> as AllowJavascriptExecutionScope<'s, HandleScope<'p>>);
816impl_as!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as AllowJavascriptExecutionScope<'s, HandleScope<'p>>);
817impl_as!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>>);
818
819impl_as!(<'s, 'p, P> DisallowJavascriptExecutionScope<'s, TryCatch<'p, P>> as TryCatch<'p, P>);
820impl_as!(<'s, 'p, P> AllowJavascriptExecutionScope<'s, TryCatch<'p, P>> as TryCatch<'p, P>);
821
822macro_rules! impl_deref {
823 (<$($params:tt),+> $src_type:ty as $tgt_type:ty) => {
824 impl<$($params),*> Deref for $src_type {
825 type Target = $tgt_type;
826 fn deref(&self) -> &Self::Target {
827 self.as_ref()
828 }
829 }
830
831 impl<$($params),*> DerefMut for $src_type {
832 fn deref_mut(&mut self) -> &mut Self::Target {
833 self.as_mut()
834 }
835 }
836 };
837}
838
839impl_deref!(<'s, 'p> ContextScope<'s, HandleScope<'p>> as HandleScope<'p>);
840impl_deref!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
841
842impl_deref!(<'s> HandleScope<'s, ()> as Isolate);
843impl_deref!(<'s> HandleScope<'s> as HandleScope<'s, ()>);
844
845impl_deref!(<'s, 'e> EscapableHandleScope<'s, 'e, ()> as HandleScope<'s, ()>);
846impl_deref!(<'s, 'e> EscapableHandleScope<'s, 'e> as HandleScope<'s>);
847
848impl_deref!(<'s, 'p> TryCatch<'s, HandleScope<'p, ()>> as HandleScope<'p, ()>);
849impl_deref!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as HandleScope<'p>);
850impl_deref!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e, ()>> as EscapableHandleScope<'p, 'e, ()>);
851impl_deref!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
852
853impl_deref!(<'s, 'p> DisallowJavascriptExecutionScope<'s, HandleScope<'p, ()>> as HandleScope<'p, ()>);
854impl_deref!(<'s, 'p> DisallowJavascriptExecutionScope<'s, HandleScope<'p>> as HandleScope<'p>);
855impl_deref!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, ()>> as EscapableHandleScope<'p, 'e, ()>);
856impl_deref!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
857impl_deref!(<'s, 'p, P> DisallowJavascriptExecutionScope<'s, TryCatch<'p, P>> as TryCatch<'p, P>);
858
859impl_deref!(<'s, 'p> AllowJavascriptExecutionScope<'s, HandleScope<'p, ()>> as HandleScope<'p, ()>);
860impl_deref!(<'s, 'p> AllowJavascriptExecutionScope<'s, HandleScope<'p>> as HandleScope<'p>);
861impl_deref!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, ()>> as EscapableHandleScope<'p, 'e, ()>);
862impl_deref!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>);
863impl_deref!(<'s, 'p, P> AllowJavascriptExecutionScope<'s, TryCatch<'p, P>> as TryCatch<'p, P>);
864
865impl_deref!(<'s> CallbackScope<'s, ()> as HandleScope<'s, ()>);
866impl_deref!(<'s> CallbackScope<'s> as HandleScope<'s>);
867
868macro_rules! impl_scope_drop {
869 (<$($params:tt),+> $type:ty) => {
870 unsafe impl<$($params),*> Scope for $type {}
871
872 impl<$($params),*> Drop for $type {
873 #[inline(always)]
874 fn drop(&mut self) {
875 data::ScopeData::get_mut(self).notify_scope_dropped();
876 }
877 }
878 };
879}
880
881impl_scope_drop!(<'s, 'p, P> ContextScope<'s, P>);
882impl_scope_drop!(<'s, C> HandleScope<'s, C> );
883impl_scope_drop!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> );
884impl_scope_drop!(<'s, P> TryCatch<'s, P> );
885impl_scope_drop!(<'s, P> DisallowJavascriptExecutionScope<'s, P>);
886impl_scope_drop!(<'s, P> AllowJavascriptExecutionScope<'s, P>);
887impl_scope_drop!(<'s, C> CallbackScope<'s, C> );
888
889pub unsafe trait Scope: Sized {}
890
891trait ScopeCast: Sized {
892 fn cast_ref<S: Scope>(&self) -> &S;
893 fn cast_mut<S: Scope>(&mut self) -> &mut S;
894}
895
896impl<T: Scope> ScopeCast for T {
897 fn cast_ref<S: Scope>(&self) -> &S {
898 assert_eq!(Layout::new::<Self>(), Layout::new::<S>());
899 unsafe { &*(self as *const _ as *const S) }
900 }
901
902 fn cast_mut<S: Scope>(&mut self) -> &mut S {
903 assert_eq!(Layout::new::<Self>(), Layout::new::<S>());
904 unsafe { &mut *(self as *mut _ as *mut S) }
905 }
906}
907
908mod param {
922 use super::*;
923
924 pub trait NewContextScope<'s>: getter::GetScopeData {
925 type NewScope: Scope;
926 }
927
928 impl<'s, 'p: 's, P: Scope> NewContextScope<'s> for ContextScope<'p, P> {
929 type NewScope = ContextScope<'s, P>;
930 }
931
932 impl<'s, 'p: 's, C> NewContextScope<'s> for HandleScope<'p, C> {
933 type NewScope = ContextScope<'s, HandleScope<'p>>;
934 }
935
936 impl<'s, 'p: 's, 'e: 'p, C> NewContextScope<'s>
937 for EscapableHandleScope<'p, 'e, C>
938 {
939 type NewScope = ContextScope<'s, EscapableHandleScope<'p, 'e>>;
940 }
941
942 impl<'s, 'p: 's, P: NewContextScope<'s>> NewContextScope<'s>
943 for TryCatch<'p, P>
944 {
945 type NewScope = <P as NewContextScope<'s>>::NewScope;
946 }
947
948 impl<'s, 'p: 's, P: NewContextScope<'s>> NewContextScope<'s>
949 for DisallowJavascriptExecutionScope<'p, P>
950 {
951 type NewScope = <P as NewContextScope<'s>>::NewScope;
952 }
953
954 impl<'s, 'p: 's, P: NewContextScope<'s>> NewContextScope<'s>
955 for AllowJavascriptExecutionScope<'p, P>
956 {
957 type NewScope = <P as NewContextScope<'s>>::NewScope;
958 }
959
960 impl<'s, 'p: 's, C> NewContextScope<'s> for CallbackScope<'p, C> {
961 type NewScope = ContextScope<'s, HandleScope<'p>>;
962 }
963
964 pub trait NewHandleScope<'s>: getter::GetScopeData {
965 type NewScope: Scope;
966 }
967
968 impl<'s> NewHandleScope<'s> for Isolate {
969 type NewScope = HandleScope<'s, ()>;
970 }
971
972 impl<'s> NewHandleScope<'s> for OwnedIsolate {
973 type NewScope = HandleScope<'s, ()>;
974 }
975
976 impl<'s, 'p: 's, P: NewHandleScope<'s>> NewHandleScope<'s>
977 for ContextScope<'p, P>
978 {
979 type NewScope = <P as NewHandleScope<'s>>::NewScope;
980 }
981
982 impl<'s, 'p: 's, C> NewHandleScope<'s> for HandleScope<'p, C> {
983 type NewScope = HandleScope<'s, C>;
984 }
985
986 impl<'s, 'p: 's, 'e: 'p, C> NewHandleScope<'s>
987 for EscapableHandleScope<'p, 'e, C>
988 {
989 type NewScope = EscapableHandleScope<'s, 'e, C>;
990 }
991
992 impl<'s, 'p: 's, P: NewHandleScope<'s>> NewHandleScope<'s> for TryCatch<'p, P> {
993 type NewScope = <P as NewHandleScope<'s>>::NewScope;
994 }
995
996 impl<'s, 'p: 's, P: NewHandleScope<'s>> NewHandleScope<'s>
997 for DisallowJavascriptExecutionScope<'p, P>
998 {
999 type NewScope = <P as NewHandleScope<'s>>::NewScope;
1000 }
1001
1002 impl<'s, 'p: 's, P: NewHandleScope<'s>> NewHandleScope<'s>
1003 for AllowJavascriptExecutionScope<'p, P>
1004 {
1005 type NewScope = <P as NewHandleScope<'s>>::NewScope;
1006 }
1007
1008 impl<'s, 'p: 's, C> NewHandleScope<'s> for CallbackScope<'p, C> {
1009 type NewScope = HandleScope<'s, C>;
1010 }
1011
1012 pub trait NewHandleScopeWithContext<'s>: getter::GetScopeData {
1013 fn get_isolate_mut(&mut self) -> &mut Isolate;
1014 }
1015
1016 impl NewHandleScopeWithContext<'_> for Isolate {
1017 fn get_isolate_mut(&mut self) -> &mut Isolate {
1018 self
1019 }
1020 }
1021
1022 impl NewHandleScopeWithContext<'_> for OwnedIsolate {
1023 fn get_isolate_mut(&mut self) -> &mut Isolate {
1024 &mut *self
1025 }
1026 }
1027
1028 pub trait NewEscapableHandleScope<'s, 'e: 's>: getter::GetScopeData {
1029 type NewScope: Scope;
1030 }
1031
1032 impl<'s, 'p: 's, 'e: 'p, P: NewEscapableHandleScope<'s, 'e>>
1033 NewEscapableHandleScope<'s, 'e> for ContextScope<'p, P>
1034 {
1035 type NewScope = <P as NewEscapableHandleScope<'s, 'e>>::NewScope;
1036 }
1037
1038 impl<'s, 'p: 's, C> NewEscapableHandleScope<'s, 'p> for HandleScope<'p, C> {
1039 type NewScope = EscapableHandleScope<'s, 'p, C>;
1040 }
1041
1042 impl<'s, 'p: 's, 'e: 'p, C> NewEscapableHandleScope<'s, 'p>
1043 for EscapableHandleScope<'p, 'e, C>
1044 {
1045 type NewScope = EscapableHandleScope<'s, 'p, C>;
1046 }
1047
1048 impl<'s, 'p: 's, 'e: 'p, P: NewEscapableHandleScope<'s, 'e>>
1049 NewEscapableHandleScope<'s, 'e> for TryCatch<'p, P>
1050 {
1051 type NewScope = <P as NewEscapableHandleScope<'s, 'e>>::NewScope;
1052 }
1053
1054 impl<'s, 'p: 's, 'e: 'p, P: NewEscapableHandleScope<'s, 'e>>
1055 NewEscapableHandleScope<'s, 'e>
1056 for DisallowJavascriptExecutionScope<'p, P>
1057 {
1058 type NewScope = <P as NewEscapableHandleScope<'s, 'e>>::NewScope;
1059 }
1060
1061 impl<'s, 'p: 's, 'e: 'p, P: NewEscapableHandleScope<'s, 'e>>
1062 NewEscapableHandleScope<'s, 'e> for AllowJavascriptExecutionScope<'p, P>
1063 {
1064 type NewScope = <P as NewEscapableHandleScope<'s, 'e>>::NewScope;
1065 }
1066
1067 impl<'s, 'p: 's, C> NewEscapableHandleScope<'s, 'p> for CallbackScope<'p, C> {
1068 type NewScope = EscapableHandleScope<'s, 'p, C>;
1069 }
1070
1071 pub trait NewTryCatch<'s>: getter::GetScopeData {
1072 type NewScope: Scope;
1073 }
1074
1075 impl<'s, 'p: 's, P: NewTryCatch<'s>> NewTryCatch<'s> for ContextScope<'p, P> {
1076 type NewScope = <P as NewTryCatch<'s>>::NewScope;
1077 }
1078
1079 impl<'s, 'p: 's, C> NewTryCatch<'s> for HandleScope<'p, C> {
1080 type NewScope = TryCatch<'s, HandleScope<'p, C>>;
1081 }
1082
1083 impl<'s, 'p: 's, 'e: 'p, C> NewTryCatch<'s>
1084 for EscapableHandleScope<'p, 'e, C>
1085 {
1086 type NewScope = TryCatch<'s, EscapableHandleScope<'p, 'e, C>>;
1087 }
1088
1089 impl<'s, 'p: 's, P> NewTryCatch<'s> for TryCatch<'p, P> {
1090 type NewScope = TryCatch<'s, P>;
1091 }
1092
1093 impl<'s, 'p: 's, P> NewTryCatch<'s>
1094 for DisallowJavascriptExecutionScope<'p, P>
1095 {
1096 type NewScope = TryCatch<'s, P>;
1097 }
1098
1099 impl<'s, 'p: 's, P> NewTryCatch<'s> for AllowJavascriptExecutionScope<'p, P> {
1100 type NewScope = TryCatch<'s, P>;
1101 }
1102
1103 impl<'s, 'p: 's, C> NewTryCatch<'s> for CallbackScope<'p, C> {
1104 type NewScope = TryCatch<'s, HandleScope<'p, C>>;
1105 }
1106
1107 pub trait NewDisallowJavascriptExecutionScope<'s>:
1108 getter::GetScopeData
1109 {
1110 type NewScope: Scope;
1111 }
1112
1113 impl<'s, 'p: 's, P: NewDisallowJavascriptExecutionScope<'s>>
1114 NewDisallowJavascriptExecutionScope<'s> for ContextScope<'p, P>
1115 {
1116 type NewScope = <P as NewDisallowJavascriptExecutionScope<'s>>::NewScope;
1117 }
1118
1119 impl<'s, 'p: 's, C> NewDisallowJavascriptExecutionScope<'s>
1120 for HandleScope<'p, C>
1121 {
1122 type NewScope = DisallowJavascriptExecutionScope<'s, HandleScope<'p, C>>;
1123 }
1124
1125 impl<'s, 'p: 's, 'e: 'p, C> NewDisallowJavascriptExecutionScope<'s>
1126 for EscapableHandleScope<'p, 'e, C>
1127 {
1128 type NewScope =
1129 DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>>;
1130 }
1131
1132 impl<'s, 'p: 's, P> NewDisallowJavascriptExecutionScope<'s>
1133 for TryCatch<'p, P>
1134 {
1135 type NewScope = DisallowJavascriptExecutionScope<'s, TryCatch<'p, P>>;
1136 }
1137
1138 impl<'s, 'p: 's, P> NewDisallowJavascriptExecutionScope<'s>
1139 for DisallowJavascriptExecutionScope<'p, P>
1140 {
1141 type NewScope = DisallowJavascriptExecutionScope<'s, P>;
1142 }
1143
1144 impl<'s, 'p: 's, P> NewDisallowJavascriptExecutionScope<'s>
1145 for AllowJavascriptExecutionScope<'p, P>
1146 {
1147 type NewScope = DisallowJavascriptExecutionScope<'s, P>;
1148 }
1149
1150 pub trait NewAllowJavascriptExecutionScope<'s>: getter::GetScopeData {
1151 type NewScope: Scope;
1152 }
1153
1154 impl<'s, 'p: 's, P: NewAllowJavascriptExecutionScope<'s>>
1155 NewAllowJavascriptExecutionScope<'s> for ContextScope<'p, P>
1156 {
1157 type NewScope = <P as NewAllowJavascriptExecutionScope<'s>>::NewScope;
1158 }
1159
1160 impl<'s, 'p: 's, C> NewAllowJavascriptExecutionScope<'s>
1161 for HandleScope<'p, C>
1162 {
1163 type NewScope = HandleScope<'p, C>;
1164 }
1165
1166 impl<'s, 'p: 's, 'e: 'p, C> NewAllowJavascriptExecutionScope<'s>
1167 for EscapableHandleScope<'p, 'e, C>
1168 {
1169 type NewScope = EscapableHandleScope<'p, 'e, C>;
1170 }
1171
1172 impl<'s, 'p: 's, P> NewAllowJavascriptExecutionScope<'s> for TryCatch<'p, P> {
1173 type NewScope = TryCatch<'s, P>;
1174 }
1175
1176 impl<'s, 'p: 's, P: Scope> NewAllowJavascriptExecutionScope<'s>
1177 for DisallowJavascriptExecutionScope<'p, P>
1178 {
1179 type NewScope = P;
1180 }
1181
1182 impl<'s, 'p: 's, P> NewAllowJavascriptExecutionScope<'s>
1183 for AllowJavascriptExecutionScope<'p, P>
1184 {
1185 type NewScope = AllowJavascriptExecutionScope<'s, P>;
1186 }
1187
1188 pub trait NewCallbackScope<'s>: Sized + getter::GetIsolate<'s> {
1189 type NewScope: Scope;
1190 const NEEDS_SCOPE: bool = false;
1191
1192 fn get_context(&self) -> Option<Local<'s, Context>> {
1193 None
1194 }
1195 }
1196
1197 impl<'s> NewCallbackScope<'s> for &'s mut Isolate {
1198 type NewScope = CallbackScope<'s, ()>;
1199 }
1200
1201 impl<'s> NewCallbackScope<'s> for &'s mut OwnedIsolate {
1202 type NewScope = CallbackScope<'s, ()>;
1203 }
1204
1205 impl<'s> NewCallbackScope<'s> for &'s FunctionCallbackInfo {
1206 type NewScope = CallbackScope<'s>;
1207 }
1208
1209 impl<'s, T> NewCallbackScope<'s> for &'s PropertyCallbackInfo<T> {
1210 type NewScope = CallbackScope<'s>;
1211 }
1212
1213 impl<'s> NewCallbackScope<'s> for &'s FastApiCallbackOptions<'s> {
1214 type NewScope = CallbackScope<'s>;
1215 const NEEDS_SCOPE: bool = true;
1216 }
1217
1218 impl<'s> NewCallbackScope<'s> for Local<'s, Context> {
1219 type NewScope = CallbackScope<'s>;
1220
1221 fn get_context(&self) -> Option<Local<'s, Context>> {
1222 Some(*self)
1223 }
1224 }
1225
1226 impl<'s> NewCallbackScope<'s> for Local<'s, Message> {
1227 type NewScope = CallbackScope<'s>;
1228 }
1229
1230 impl<'s, T: Into<Local<'s, Object>>> NewCallbackScope<'s> for T {
1231 type NewScope = CallbackScope<'s>;
1232 }
1233
1234 impl<'s> NewCallbackScope<'s> for &'s PromiseRejectMessage<'s> {
1235 type NewScope = CallbackScope<'s>;
1236 }
1237}
1238
1239mod getter {
1243 pub use super::*;
1244
1245 pub trait GetIsolate<'s> {
1246 unsafe fn get_isolate_mut(self) -> &'s mut Isolate;
1247 }
1248
1249 impl<'s> GetIsolate<'s> for &'s mut Isolate {
1250 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1251 self
1252 }
1253 }
1254
1255 impl<'s> GetIsolate<'s> for &'s mut OwnedIsolate {
1256 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1257 &mut *self
1258 }
1259 }
1260
1261 impl<'s> GetIsolate<'s> for &'s FunctionCallbackInfo {
1262 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1263 unsafe { &mut *self.get_isolate_ptr() }
1264 }
1265 }
1266
1267 impl<'s, T> GetIsolate<'s> for &'s PropertyCallbackInfo<T> {
1268 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1269 unsafe { &mut *self.get_isolate_ptr() }
1270 }
1271 }
1272
1273 impl<'s> GetIsolate<'s> for &'s FastApiCallbackOptions<'s> {
1274 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1275 unsafe { &mut *self.isolate }
1276 }
1277 }
1278
1279 impl<'s> GetIsolate<'s> for Local<'s, Context> {
1280 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1281 unsafe { &mut *raw::v8__Context__GetIsolate(&*self) }
1282 }
1283 }
1284
1285 impl<'s> GetIsolate<'s> for Local<'s, Message> {
1286 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1287 unsafe { &mut *raw::v8__Message__GetIsolate(&*self) }
1288 }
1289 }
1290
1291 impl<'s, T: Into<Local<'s, Object>>> GetIsolate<'s> for T {
1292 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1293 let object: Local<Object> = self.into();
1294 unsafe { &mut *raw::v8__Object__GetIsolate(&*object) }
1295 }
1296 }
1297
1298 impl<'s> GetIsolate<'s> for &'s PromiseRejectMessage<'s> {
1299 unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
1300 let object: Local<Object> = self.get_promise().into();
1301 unsafe { &mut *raw::v8__Object__GetIsolate(&*object) }
1302 }
1303 }
1304
1305 pub trait GetScopeData {
1306 fn get_scope_data_mut(&mut self) -> &mut data::ScopeData;
1307 }
1308
1309 impl<T: Scope> GetScopeData for T {
1310 fn get_scope_data_mut(&mut self) -> &mut data::ScopeData {
1311 data::ScopeData::get_mut(self)
1312 }
1313 }
1314
1315 impl GetScopeData for Isolate {
1316 fn get_scope_data_mut(&mut self) -> &mut data::ScopeData {
1317 data::ScopeData::get_root_mut(self)
1318 }
1319 }
1320
1321 impl GetScopeData for OwnedIsolate {
1322 fn get_scope_data_mut(&mut self) -> &mut data::ScopeData {
1323 data::ScopeData::get_root_mut(self)
1324 }
1325 }
1326}
1327
1328pub(crate) mod data {
1332 use super::*;
1333
1334 #[derive(Debug)]
1335 pub struct ScopeData {
1336 isolate: NonNull<Isolate>,
1343 previous: Option<NonNull<ScopeData>>,
1344 next: Option<Box<ScopeData>>,
1345 status: Cell<ScopeStatus>,
1347 context: Cell<Option<NonNull<Context>>>,
1350 escape_slot: Option<NonNull<Option<raw::EscapeSlot>>>,
1351 try_catch: Option<NonNull<raw::TryCatch>>,
1352 scope_type_specific_data: ScopeTypeSpecificData,
1353 }
1354
1355 impl ScopeData {
1356 #[inline(always)]
1360 pub(crate) fn get_current_mut(isolate: &mut Isolate) -> &mut Self {
1361 let self_mut = isolate
1362 .get_current_scope_data()
1363 .map(NonNull::as_ptr)
1364 .map(|p| unsafe { &mut *p })
1365 .unwrap();
1366 match self_mut.status.get() {
1367 ScopeStatus::Current { .. } => self_mut,
1368 _ => unreachable!(),
1369 }
1370 }
1371
1372 pub(crate) fn new_root(isolate: &mut Isolate) {
1376 let root = Box::leak(Self::boxed(isolate.into()));
1377 root.status = ScopeStatus::Current { zombie: false }.into();
1378 debug_assert!(isolate.get_current_scope_data().is_none());
1379 isolate.set_current_scope_data(Some(root.into()));
1380 }
1381
1382 #[inline(always)]
1391 pub(crate) fn get_root_mut(isolate: &mut Isolate) -> &mut Self {
1392 let mut current_scope_data = Self::get_current_mut(isolate);
1393 loop {
1394 current_scope_data = match current_scope_data {
1395 root if root.previous.is_none() => break root,
1396 data => data.try_exit_scope(),
1397 };
1398 }
1399 }
1400
1401 pub(crate) fn drop_root(isolate: &mut Isolate) {
1404 let root = Self::get_root_mut(isolate);
1405 unsafe {
1406 let _ = Box::from_raw(root);
1407 };
1408 isolate.set_current_scope_data(None);
1409 }
1410
1411 #[inline(always)]
1412 pub(super) fn new_context_scope_data<'s>(
1413 &'s mut self,
1414 context: Local<'s, Context>,
1415 ) -> &'s mut Self {
1416 self.new_scope_data_with(move |data| {
1417 data.scope_type_specific_data.init_with(|| {
1418 ScopeTypeSpecificData::ContextScope {
1419 _raw_context_scope: raw::ContextScope::new(context),
1420 }
1421 });
1422 data.context.set(Some(context.as_non_null()));
1423 })
1424 }
1425
1426 #[inline(always)]
1431 fn new_handle_scope_data_with<F>(&mut self, init_context_fn: F) -> &mut Self
1432 where
1433 F: FnOnce(
1434 NonNull<Isolate>,
1435 &mut Cell<Option<NonNull<Context>>>,
1436 &mut Option<raw::ContextScope>,
1437 ),
1438 {
1439 self.new_scope_data_with(|data| {
1440 let isolate = data.isolate;
1441 data.scope_type_specific_data.init_with(|| {
1442 ScopeTypeSpecificData::HandleScope {
1443 allow_zombie: true,
1444 raw_handle_scope: unsafe { raw::HandleScope::uninit() },
1445 raw_context_scope: None,
1446 }
1447 });
1448 match &mut data.scope_type_specific_data {
1449 ScopeTypeSpecificData::HandleScope {
1450 raw_handle_scope,
1451 raw_context_scope,
1452 ..
1453 } => {
1454 unsafe { raw_handle_scope.init(isolate) };
1455 init_context_fn(isolate, &mut data.context, raw_context_scope);
1456 }
1457 _ => unreachable!(),
1458 };
1459 })
1460 }
1461
1462 #[inline(always)]
1463 pub(super) fn disable_zombie(&mut self) {
1464 if let ScopeTypeSpecificData::HandleScope { allow_zombie, .. } =
1465 &mut self.scope_type_specific_data
1466 {
1467 *allow_zombie = false;
1468 }
1469 }
1470
1471 #[inline(always)]
1472 pub(super) fn new_handle_scope_data(&mut self) -> &mut Self {
1473 self.new_handle_scope_data_with(|_, _, raw_context_scope| {
1474 debug_assert!(raw_context_scope.is_none());
1475 })
1476 }
1477
1478 #[inline(always)]
1479 pub(super) fn new_handle_scope_data_with_context(
1480 &mut self,
1481 context_ref: &Context,
1482 ) -> &mut Self {
1483 self.new_handle_scope_data_with(
1484 move |isolate, context_data, raw_context_scope| unsafe {
1485 let context_nn = NonNull::from(context_ref);
1486 let local_context_ptr =
1489 raw::v8__Local__New(isolate.as_ptr(), context_nn.cast().as_ptr())
1490 as *const Context;
1491 let local_context_nn =
1492 NonNull::new_unchecked(local_context_ptr as *mut _);
1493 let local_context = Local::from_non_null(local_context_nn);
1494 debug_assert!(raw_context_scope.is_none());
1496 ptr::write(
1497 raw_context_scope,
1498 Some(raw::ContextScope::new(local_context)),
1499 );
1500 context_data.set(Some(local_context_nn));
1503 },
1504 )
1505 }
1506
1507 #[inline(always)]
1508 pub(super) fn new_escapable_handle_scope_data(&mut self) -> &mut Self {
1509 self.new_scope_data_with(|data| {
1510 let isolate = data.isolate;
1515 data.scope_type_specific_data.init_with(|| {
1516 ScopeTypeSpecificData::EscapableHandleScope {
1517 raw_handle_scope: unsafe { raw::HandleScope::uninit() },
1518 raw_escape_slot: Some(raw::EscapeSlot::new(isolate)),
1519 }
1520 });
1521 match &mut data.scope_type_specific_data {
1522 ScopeTypeSpecificData::EscapableHandleScope {
1523 raw_handle_scope,
1524 raw_escape_slot,
1525 } => {
1526 unsafe { raw_handle_scope.init(isolate) };
1527 data.escape_slot.replace(raw_escape_slot.into());
1528 }
1529 _ => unreachable!(),
1530 }
1531 })
1532 }
1533
1534 #[inline(always)]
1535 pub(super) fn new_try_catch_data(&mut self) -> &mut Self {
1536 self.new_scope_data_with(|data| {
1537 let isolate = data.isolate;
1538 data.scope_type_specific_data.init_with(|| {
1539 ScopeTypeSpecificData::TryCatch {
1540 raw_try_catch: unsafe { raw::TryCatch::uninit() },
1541 }
1542 });
1543 match &mut data.scope_type_specific_data {
1544 ScopeTypeSpecificData::TryCatch { raw_try_catch } => {
1545 unsafe { raw_try_catch.init(isolate) };
1546 data.try_catch.replace(raw_try_catch.into());
1547 }
1548 _ => unreachable!(),
1549 }
1550 })
1551 }
1552
1553 #[inline(always)]
1554 pub(super) fn new_disallow_javascript_execution_scope_data(
1555 &mut self,
1556 on_failure: OnFailure,
1557 ) -> &mut Self {
1558 self.new_scope_data_with(|data| {
1559 let isolate = data.isolate;
1560 data.scope_type_specific_data.init_with(|| {
1561 ScopeTypeSpecificData::DisallowJavascriptExecutionScope {
1562 raw_scope: unsafe {
1563 raw::DisallowJavascriptExecutionScope::uninit()
1564 },
1565 }
1566 });
1567 match &mut data.scope_type_specific_data {
1568 ScopeTypeSpecificData::DisallowJavascriptExecutionScope {
1569 raw_scope,
1570 } => unsafe { raw_scope.init(isolate, on_failure) },
1571 _ => unreachable!(),
1572 }
1573 })
1574 }
1575
1576 #[inline(always)]
1577 pub(super) fn new_allow_javascript_execution_scope_data(
1578 &mut self,
1579 ) -> &mut Self {
1580 self.new_scope_data_with(|data| {
1581 let isolate = data.isolate;
1582 data.scope_type_specific_data.init_with(|| {
1583 ScopeTypeSpecificData::AllowJavascriptExecutionScope {
1584 raw_scope: unsafe { raw::AllowJavascriptExecutionScope::uninit() },
1585 }
1586 });
1587 match &mut data.scope_type_specific_data {
1588 ScopeTypeSpecificData::AllowJavascriptExecutionScope {
1589 raw_scope,
1590 } => unsafe { raw_scope.init(isolate) },
1591 _ => unreachable!(),
1592 }
1593 })
1594 }
1595
1596 #[inline(always)]
1597 pub(super) fn new_callback_scope_data<'s>(
1598 &'s mut self,
1599 maybe_current_context: Option<Local<'s, Context>>,
1600 ) -> &'s mut Self {
1601 self.new_scope_data_with(|data| {
1602 debug_assert!(data.scope_type_specific_data.is_none());
1603 data
1604 .context
1605 .set(maybe_current_context.map(|cx| cx.as_non_null()));
1606 })
1607 }
1608
1609 #[inline(always)]
1610 fn new_scope_data_with(
1611 &mut self,
1612 init_fn: impl FnOnce(&mut Self),
1613 ) -> &mut Self {
1614 self.status.set(match self.status.get() {
1616 ScopeStatus::Current { zombie } => ScopeStatus::Shadowed { zombie },
1617 _ => unreachable!(),
1618 });
1619 let context = self.context.get().into();
1621 let escape_slot = self.escape_slot;
1622 let new_scope_data = self.allocate_or_reuse_scope_data();
1624 new_scope_data.status = Cell::new(ScopeStatus::Current {
1629 zombie: cfg!(debug_assertions),
1630 });
1631 new_scope_data.context = context;
1633 new_scope_data.escape_slot = escape_slot;
1634 (init_fn)(new_scope_data);
1635 let new_scope_nn = unsafe { NonNull::new_unchecked(new_scope_data) };
1637 new_scope_data
1638 .get_isolate_mut()
1639 .set_current_scope_data(Some(new_scope_nn));
1640 new_scope_data
1641 }
1642
1643 #[inline(always)]
1646 fn allocate_or_reuse_scope_data(&mut self) -> &mut Self {
1647 let self_nn = NonNull::new(self);
1648 match &mut self.next {
1649 Some(next_box) => {
1650 debug_assert_eq!(next_box.isolate, self.isolate);
1652 debug_assert_eq!(next_box.previous, self_nn);
1653 debug_assert_eq!(next_box.status.get(), ScopeStatus::Free);
1654 debug_assert!(next_box.scope_type_specific_data.is_none());
1655 next_box.as_mut()
1656 }
1657 next_field @ None => {
1658 let mut next_box = Self::boxed(self.isolate);
1660 next_box.previous = self_nn;
1661 next_field.replace(next_box);
1662 next_field.as_mut().unwrap()
1663 }
1664 }
1665 }
1666
1667 #[inline(always)]
1668 pub(super) fn as_scope<S: Scope>(&mut self) -> S {
1669 assert_eq!(Layout::new::<&mut Self>(), Layout::new::<S>());
1670 if cfg!(debug_assertions) {
1674 assert_eq!(self.status.get(), ScopeStatus::Current { zombie: true });
1675 self.status.set(ScopeStatus::Current { zombie: false });
1676 }
1677 let self_nn = NonNull::from(self);
1678 unsafe { ptr::read(&self_nn as *const _ as *const S) }
1679 }
1680
1681 #[inline(always)]
1682 pub(super) fn get<S: Scope>(scope: &S) -> &Self {
1683 let self_mut = unsafe {
1684 (*(scope as *const S as *mut S as *mut NonNull<Self>)).as_mut()
1685 };
1686 self_mut.try_activate_scope();
1687 self_mut
1688 }
1689
1690 #[inline(always)]
1691 pub(super) fn get_mut<S: Scope>(scope: &mut S) -> &mut Self {
1692 let self_mut =
1693 unsafe { (*(scope as *mut S as *mut NonNull<Self>)).as_mut() };
1694 self_mut.try_activate_scope();
1695 self_mut
1696 }
1697
1698 #[inline(always)]
1699 fn try_activate_scope(mut self: &mut Self) -> &mut Self {
1700 self = match self.status.get() {
1701 ScopeStatus::Current { zombie: false } => self,
1702 ScopeStatus::Shadowed { zombie: false } => {
1703 self.next.as_mut().unwrap().try_exit_scope()
1704 }
1705 _ => unreachable!(),
1706 };
1707 debug_assert_eq!(
1708 self.get_isolate().get_current_scope_data(),
1709 NonNull::new(self as *mut _)
1710 );
1711 self
1712 }
1713
1714 #[inline(always)]
1715 fn try_exit_scope(mut self: &mut Self) -> &mut Self {
1716 loop {
1717 self = match self.status.get() {
1718 ScopeStatus::Shadowed { .. } => {
1719 self.next.as_mut().unwrap().try_exit_scope()
1720 }
1721 ScopeStatus::Current { zombie: true } => break self.exit_scope(),
1722 ScopeStatus::Current { zombie: false } => {
1723 panic!("active scope can't be dropped")
1724 }
1725 _ => unreachable!(),
1726 }
1727 }
1728 }
1729
1730 #[inline(always)]
1731 fn exit_scope(&mut self) -> &mut Self {
1732 if !matches!(self.scope_type_specific_data, ScopeTypeSpecificData::None) {
1735 self.scope_type_specific_data = Default::default();
1736 }
1737
1738 self.status.set(ScopeStatus::Free);
1741
1742 let previous_nn = self.previous.unwrap();
1744 self
1745 .get_isolate_mut()
1746 .set_current_scope_data(Some(previous_nn));
1747
1748 let previous_mut = unsafe { &mut *previous_nn.as_ptr() };
1751 previous_mut.status.set(match previous_mut.status.get() {
1752 ScopeStatus::Shadowed { zombie } => ScopeStatus::Current { zombie },
1753 _ => unreachable!(),
1754 });
1755
1756 previous_mut
1757 }
1758
1759 #[inline(always)]
1779 pub(super) fn notify_scope_dropped(&mut self) {
1780 match &self.scope_type_specific_data {
1781 ScopeTypeSpecificData::HandleScope {
1782 allow_zombie: true, ..
1783 }
1784 | ScopeTypeSpecificData::EscapableHandleScope { .. } => {
1785 self.status.set(match self.status.get() {
1787 ScopeStatus::Current { zombie: false } => {
1788 ScopeStatus::Current { zombie: true }
1789 }
1790 _ => unreachable!(),
1791 });
1792 }
1793 _ => {
1794 self.exit_scope();
1796 }
1797 }
1798 }
1799
1800 #[inline(always)]
1801 pub(crate) fn get_isolate(&self) -> &Isolate {
1802 unsafe { self.isolate.as_ref() }
1803 }
1804
1805 #[inline(always)]
1806 pub(crate) fn get_isolate_mut(&mut self) -> &mut Isolate {
1807 unsafe { self.isolate.as_mut() }
1808 }
1809
1810 #[inline(always)]
1811 pub(crate) fn get_isolate_ptr(&self) -> *mut Isolate {
1812 self.isolate.as_ptr()
1813 }
1814
1815 #[inline(always)]
1816 pub(crate) fn get_current_context(&self) -> *const Context {
1817 let get_current_context_from_isolate = || unsafe {
1822 raw::v8__Isolate__GetCurrentContext(self.get_isolate_ptr())
1823 };
1824 match self.context.get().map(|nn| nn.as_ptr() as *const _) {
1825 Some(context) => {
1826 debug_assert!(unsafe {
1827 raw::v8__Context__EQ(context, get_current_context_from_isolate())
1828 });
1829 context
1830 }
1831 None => {
1832 let context = get_current_context_from_isolate();
1833 self.context.set(NonNull::new(context as *mut _));
1834 context
1835 }
1836 }
1837 }
1838
1839 #[inline(always)]
1840 pub(super) fn get_escape_slot_mut(
1841 &mut self,
1842 ) -> Option<&mut Option<raw::EscapeSlot>> {
1843 self
1844 .escape_slot
1845 .as_mut()
1846 .map(|escape_slot_nn| unsafe { escape_slot_nn.as_mut() })
1847 }
1848
1849 #[inline(always)]
1850 pub(super) fn get_try_catch(&self) -> &raw::TryCatch {
1851 self
1852 .try_catch
1853 .as_ref()
1854 .map(|try_catch_nn| unsafe { try_catch_nn.as_ref() })
1855 .unwrap()
1856 }
1857
1858 #[inline(always)]
1859 pub(super) fn get_try_catch_mut(&mut self) -> &mut raw::TryCatch {
1860 self
1861 .try_catch
1862 .as_mut()
1863 .map(|try_catch_nn| unsafe { try_catch_nn.as_mut() })
1864 .unwrap()
1865 }
1866
1867 #[cold]
1873 fn boxed(isolate: NonNull<Isolate>) -> Box<Self> {
1874 unsafe {
1875 #[allow(clippy::cast_ptr_alignment)]
1876 let self_ptr = alloc(Layout::new::<Self>()) as *mut Self;
1877 ptr::write(
1878 self_ptr,
1879 Self {
1880 isolate,
1881 previous: Default::default(),
1882 next: Default::default(),
1883 status: Default::default(),
1884 context: Default::default(),
1885 escape_slot: Default::default(),
1886 try_catch: Default::default(),
1887 scope_type_specific_data: Default::default(),
1888 },
1889 );
1890 Box::from_raw(self_ptr)
1891 }
1892 }
1893 }
1894
1895 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
1896 enum ScopeStatus {
1897 Free,
1898 Current { zombie: bool },
1899 Shadowed { zombie: bool },
1900 }
1901
1902 impl Default for ScopeStatus {
1903 fn default() -> Self {
1904 Self::Free
1905 }
1906 }
1907
1908 #[derive(Debug)]
1909 enum ScopeTypeSpecificData {
1910 None,
1911 ContextScope {
1912 _raw_context_scope: raw::ContextScope,
1913 },
1914 HandleScope {
1915 allow_zombie: bool,
1916 raw_handle_scope: raw::HandleScope,
1917 raw_context_scope: Option<raw::ContextScope>,
1918 },
1919 EscapableHandleScope {
1920 raw_handle_scope: raw::HandleScope,
1921 raw_escape_slot: Option<raw::EscapeSlot>,
1922 },
1923 TryCatch {
1924 raw_try_catch: raw::TryCatch,
1925 },
1926 DisallowJavascriptExecutionScope {
1927 raw_scope: raw::DisallowJavascriptExecutionScope,
1928 },
1929 AllowJavascriptExecutionScope {
1930 raw_scope: raw::AllowJavascriptExecutionScope,
1931 },
1932 }
1933
1934 impl Default for ScopeTypeSpecificData {
1935 fn default() -> Self {
1936 Self::None
1937 }
1938 }
1939
1940 impl Drop for ScopeTypeSpecificData {
1941 #[inline(always)]
1942 fn drop(&mut self) {
1943 if let Self::HandleScope {
1949 raw_context_scope, ..
1950 } = self
1951 {
1952 *raw_context_scope = None;
1953 }
1954 }
1955 }
1956
1957 impl ScopeTypeSpecificData {
1958 pub fn is_none(&self) -> bool {
1959 matches!(self, Self::None)
1960 }
1961
1962 pub fn init_with(&mut self, init_fn: impl FnOnce() -> Self) {
1969 assert!(self.is_none());
1970 unsafe { ptr::write(self, (init_fn)()) }
1971 }
1972 }
1973}
1974
1975mod raw {
1978 use super::*;
1979
1980 #[derive(Clone, Copy, Debug)]
1981 #[repr(transparent)]
1982 pub(super) struct Address(NonZeroUsize);
1983
1984 #[derive(Debug)]
1985 pub(super) struct ContextScope {
1986 entered_context: NonNull<Context>,
1987 }
1988
1989 impl ContextScope {
1990 pub fn new(context: Local<Context>) -> Self {
1991 unsafe { v8__Context__Enter(&*context) };
1992 Self {
1993 entered_context: context.as_non_null(),
1994 }
1995 }
1996 }
1997
1998 impl Drop for ContextScope {
1999 #[inline(always)]
2000 fn drop(&mut self) {
2001 unsafe { v8__Context__Exit(self.entered_context.as_ptr()) };
2002 }
2003 }
2004
2005 #[repr(C)]
2006 #[derive(Debug)]
2007 pub(super) struct HandleScope([MaybeUninit<usize>; 3]);
2008
2009 impl HandleScope {
2010 pub unsafe fn uninit() -> Self {
2015 Self(unsafe { MaybeUninit::uninit().assume_init() })
2016 }
2017
2018 pub unsafe fn init(&mut self, isolate: NonNull<Isolate>) {
2022 let buf = NonNull::from(self).cast();
2023 unsafe {
2024 v8__HandleScope__CONSTRUCT(buf.as_ptr(), isolate.as_ptr());
2025 }
2026 }
2027 }
2028
2029 impl Drop for HandleScope {
2030 #[inline(always)]
2031 fn drop(&mut self) {
2032 unsafe { v8__HandleScope__DESTRUCT(self) };
2033 }
2034 }
2035
2036 #[repr(transparent)]
2037 #[derive(Debug)]
2038 pub(super) struct EscapeSlot(NonNull<raw::Address>);
2039
2040 impl EscapeSlot {
2041 pub fn new(isolate: NonNull<Isolate>) -> Self {
2042 unsafe {
2043 let undefined = raw::v8__Undefined(isolate.as_ptr()) as *const _;
2044 let local = raw::v8__Local__New(isolate.as_ptr(), undefined);
2045 let slot_address_ptr = local as *const Address as *mut _;
2046 let slot_address_nn = NonNull::new_unchecked(slot_address_ptr);
2047 Self(slot_address_nn)
2048 }
2049 }
2050
2051 pub fn escape<'e, T>(self, value: Local<'_, T>) -> Local<'e, T>
2052 where
2053 for<'l> Local<'l, T>: Into<Local<'l, Data>>,
2054 {
2055 assert_eq!(Layout::new::<Self>(), Layout::new::<Local<T>>());
2056 unsafe {
2057 let undefined = Local::<Value>::from_non_null(self.0.cast());
2058 debug_assert!(undefined.is_undefined());
2059 let value_address = *(&*value as *const T as *const Address);
2060 ptr::write(self.0.as_ptr(), value_address);
2061 Local::from_non_null(self.0.cast())
2062 }
2063 }
2064 }
2065
2066 #[repr(C)]
2067 #[derive(Debug)]
2068 pub(super) struct TryCatch([MaybeUninit<usize>; 6]);
2069
2070 impl TryCatch {
2071 pub unsafe fn uninit() -> Self {
2076 Self(unsafe { MaybeUninit::uninit().assume_init() })
2077 }
2078
2079 pub unsafe fn init(&mut self, isolate: NonNull<Isolate>) {
2083 let buf = NonNull::from(self).cast();
2084 unsafe {
2085 v8__TryCatch__CONSTRUCT(buf.as_ptr(), isolate.as_ptr());
2086 }
2087 }
2088 }
2089
2090 impl Drop for TryCatch {
2091 #[inline(always)]
2092 fn drop(&mut self) {
2093 unsafe { v8__TryCatch__DESTRUCT(self) };
2094 }
2095 }
2096
2097 #[repr(C)]
2098 #[derive(Debug)]
2099 pub(super) struct DisallowJavascriptExecutionScope([MaybeUninit<usize>; 2]);
2100
2101 impl DisallowJavascriptExecutionScope {
2102 pub unsafe fn uninit() -> Self {
2107 Self(unsafe { MaybeUninit::uninit().assume_init() })
2108 }
2109
2110 pub unsafe fn init(
2115 &mut self,
2116 isolate: NonNull<Isolate>,
2117 on_failure: OnFailure,
2118 ) {
2119 let buf = NonNull::from(self).cast();
2120 unsafe {
2121 v8__DisallowJavascriptExecutionScope__CONSTRUCT(
2122 buf.as_ptr(),
2123 isolate.as_ptr(),
2124 on_failure,
2125 );
2126 }
2127 }
2128 }
2129
2130 impl Drop for DisallowJavascriptExecutionScope {
2131 #[inline(always)]
2132 fn drop(&mut self) {
2133 unsafe { v8__DisallowJavascriptExecutionScope__DESTRUCT(self) };
2134 }
2135 }
2136
2137 #[repr(C)]
2138 #[derive(Debug)]
2139 pub(super) struct AllowJavascriptExecutionScope([MaybeUninit<usize>; 2]);
2140
2141 impl AllowJavascriptExecutionScope {
2142 pub unsafe fn uninit() -> Self {
2147 Self(unsafe { MaybeUninit::uninit().assume_init() })
2148 }
2149
2150 pub unsafe fn init(&mut self, isolate: NonNull<Isolate>) {
2155 unsafe {
2156 let buf = NonNull::from(self).cast();
2157 v8__AllowJavascriptExecutionScope__CONSTRUCT(
2158 buf.as_ptr(),
2159 isolate.as_ptr(),
2160 );
2161 }
2162 }
2163 }
2164
2165 impl Drop for AllowJavascriptExecutionScope {
2166 #[inline(always)]
2167 fn drop(&mut self) {
2168 unsafe { v8__AllowJavascriptExecutionScope__DESTRUCT(self) };
2169 }
2170 }
2171
2172 unsafe extern "C" {
2173 pub(super) fn v8__Isolate__GetCurrentContext(
2174 isolate: *mut Isolate,
2175 ) -> *const Context;
2176 pub(super) fn v8__Isolate__GetEnteredOrMicrotaskContext(
2177 isolate: *mut Isolate,
2178 ) -> *const Context;
2179 pub(super) fn v8__Isolate__ThrowException(
2180 isolate: *mut Isolate,
2181 exception: *const Value,
2182 ) -> *const Value;
2183 pub(super) fn v8__Isolate__GetDataFromSnapshotOnce(
2184 this: *mut Isolate,
2185 index: usize,
2186 ) -> *const Data;
2187 pub(super) fn v8__Isolate__GetCurrentHostDefinedOptions(
2188 this: *mut Isolate,
2189 ) -> *const Data;
2190
2191 pub(super) fn v8__Context__EQ(
2192 this: *const Context,
2193 other: *const Context,
2194 ) -> bool;
2195 pub(super) fn v8__Context__Enter(this: *const Context);
2196 pub(super) fn v8__Context__Exit(this: *const Context);
2197 pub(super) fn v8__Context__GetIsolate(this: *const Context)
2198 -> *mut Isolate;
2199 pub(super) fn v8__Context__GetDataFromSnapshotOnce(
2200 this: *const Context,
2201 index: usize,
2202 ) -> *const Data;
2203 pub(super) fn v8__Context__SetPromiseHooks(
2204 this: *const Context,
2205 init_hook: *const Function,
2206 before_hook: *const Function,
2207 after_hook: *const Function,
2208 resolve_hook: *const Function,
2209 );
2210 pub(super) fn v8__Context__SetContinuationPreservedEmbedderData(
2211 this: *mut Isolate,
2212 value: *const Value,
2213 );
2214 pub(super) fn v8__Context__GetContinuationPreservedEmbedderData(
2215 this: *mut Isolate,
2216 ) -> *const Value;
2217
2218 pub(super) fn v8__HandleScope__CONSTRUCT(
2219 buf: *mut MaybeUninit<HandleScope>,
2220 isolate: *mut Isolate,
2221 );
2222 pub(super) fn v8__HandleScope__DESTRUCT(this: *mut HandleScope);
2223
2224 pub(super) fn v8__Local__New(
2225 isolate: *mut Isolate,
2226 other: *const Data,
2227 ) -> *const Data;
2228 pub(super) fn v8__Undefined(isolate: *mut Isolate) -> *const Primitive;
2229
2230 pub(super) fn v8__TryCatch__CONSTRUCT(
2231 buf: *mut MaybeUninit<TryCatch>,
2232 isolate: *mut Isolate,
2233 );
2234 pub(super) fn v8__TryCatch__DESTRUCT(this: *mut TryCatch);
2235 pub(super) fn v8__TryCatch__HasCaught(this: *const TryCatch) -> bool;
2236 pub(super) fn v8__TryCatch__CanContinue(this: *const TryCatch) -> bool;
2237 pub(super) fn v8__TryCatch__HasTerminated(this: *const TryCatch) -> bool;
2238 pub(super) fn v8__TryCatch__IsVerbose(this: *const TryCatch) -> bool;
2239 pub(super) fn v8__TryCatch__SetVerbose(this: *mut TryCatch, value: bool);
2240 pub(super) fn v8__TryCatch__SetCaptureMessage(
2241 this: *mut TryCatch,
2242 value: bool,
2243 );
2244 pub(super) fn v8__TryCatch__Reset(this: *mut TryCatch);
2245 pub(super) fn v8__TryCatch__Exception(
2246 this: *const TryCatch,
2247 ) -> *const Value;
2248 pub(super) fn v8__TryCatch__StackTrace(
2249 this: *const TryCatch,
2250 context: *const Context,
2251 ) -> *const Value;
2252 pub(super) fn v8__TryCatch__Message(
2253 this: *const TryCatch,
2254 ) -> *const Message;
2255 pub(super) fn v8__TryCatch__ReThrow(this: *mut TryCatch) -> *const Value;
2256
2257 pub(super) fn v8__DisallowJavascriptExecutionScope__CONSTRUCT(
2258 buf: *mut MaybeUninit<DisallowJavascriptExecutionScope>,
2259 isolate: *mut Isolate,
2260 on_failure: OnFailure,
2261 );
2262 pub(super) fn v8__DisallowJavascriptExecutionScope__DESTRUCT(
2263 this: *mut DisallowJavascriptExecutionScope,
2264 );
2265
2266 pub(super) fn v8__AllowJavascriptExecutionScope__CONSTRUCT(
2267 buf: *mut MaybeUninit<AllowJavascriptExecutionScope>,
2268 isolate: *mut Isolate,
2269 );
2270 pub(super) fn v8__AllowJavascriptExecutionScope__DESTRUCT(
2271 this: *mut AllowJavascriptExecutionScope,
2272 );
2273
2274 pub(super) fn v8__Message__GetIsolate(this: *const Message)
2275 -> *mut Isolate;
2276 pub(super) fn v8__Object__GetIsolate(this: *const Object) -> *mut Isolate;
2277 }
2278}
2279
2280#[cfg(test)]
2281mod tests {
2282 use super::*;
2283 use crate::ContextOptions;
2284 use crate::Global;
2285 use std::any::type_name;
2286
2287 trait SameType {}
2288 impl<A> SameType for (A, A) {}
2289
2290 struct AssertTypeOf<'a, T>(#[allow(dead_code)] &'a T);
2295 impl<T> AssertTypeOf<'_, T> {
2296 pub fn is<A>(self)
2297 where
2298 (A, T): SameType,
2299 {
2300 assert_eq!(type_name::<A>(), type_name::<T>());
2301 }
2302 }
2303
2304 #[test]
2305 fn deref_types() {
2306 crate::initialize_v8();
2307 let isolate = &mut Isolate::new(Default::default());
2308 AssertTypeOf(isolate).is::<OwnedIsolate>();
2309 let l1_hs = &mut HandleScope::new(isolate);
2310 AssertTypeOf(l1_hs).is::<HandleScope<()>>();
2311 let context = Context::new(l1_hs, ContextOptions::default());
2312 {
2313 let l2_cxs = &mut ContextScope::new(l1_hs, context);
2314 AssertTypeOf(l2_cxs).is::<ContextScope<HandleScope>>();
2315 {
2316 let d = l2_cxs.deref_mut();
2317 AssertTypeOf(d).is::<HandleScope>();
2318 let d = d.deref_mut();
2319 AssertTypeOf(d).is::<HandleScope<()>>();
2320 let d = d.deref_mut();
2321 AssertTypeOf(d).is::<Isolate>();
2322 }
2323 {
2324 let l3_tc = &mut TryCatch::new(l2_cxs);
2325 AssertTypeOf(l3_tc).is::<TryCatch<HandleScope>>();
2326 let d = l3_tc.deref_mut();
2327 AssertTypeOf(d).is::<HandleScope>();
2328 let d = d.deref_mut();
2329 AssertTypeOf(d).is::<HandleScope<()>>();
2330 let d = d.deref_mut();
2331 AssertTypeOf(d).is::<Isolate>();
2332 }
2333 {
2334 let l3_djses = &mut DisallowJavascriptExecutionScope::new(
2335 l2_cxs,
2336 OnFailure::CrashOnFailure,
2337 );
2338 AssertTypeOf(l3_djses)
2339 .is::<DisallowJavascriptExecutionScope<HandleScope>>();
2340 let d = l3_djses.deref_mut();
2341 AssertTypeOf(d).is::<HandleScope>();
2342 let d = d.deref_mut();
2343 AssertTypeOf(d).is::<HandleScope<()>>();
2344 let d = d.deref_mut();
2345 AssertTypeOf(d).is::<Isolate>();
2346 {
2347 let l4_ajses = &mut AllowJavascriptExecutionScope::new(l3_djses);
2348 AssertTypeOf(l4_ajses).is::<HandleScope>();
2349 let d = l4_ajses.deref_mut();
2350 AssertTypeOf(d).is::<HandleScope<()>>();
2351 let d = d.deref_mut();
2352 AssertTypeOf(d).is::<Isolate>();
2353 }
2354 }
2355 {
2356 let l3_ehs = &mut EscapableHandleScope::new(l2_cxs);
2357 AssertTypeOf(l3_ehs).is::<EscapableHandleScope>();
2358 {
2359 let l4_cxs = &mut ContextScope::new(l3_ehs, context);
2360 AssertTypeOf(l4_cxs).is::<ContextScope<EscapableHandleScope>>();
2361 let d = l4_cxs.deref_mut();
2362 AssertTypeOf(d).is::<EscapableHandleScope>();
2363 let d = d.deref_mut();
2364 AssertTypeOf(d).is::<HandleScope>();
2365 let d = d.deref_mut();
2366 AssertTypeOf(d).is::<HandleScope<()>>();
2367 let d = d.deref_mut();
2368 AssertTypeOf(d).is::<Isolate>();
2369 }
2370 {
2371 let l4_tc = &mut TryCatch::new(l3_ehs);
2372 AssertTypeOf(l4_tc).is::<TryCatch<EscapableHandleScope>>();
2373 let d = l4_tc.deref_mut();
2374 AssertTypeOf(d).is::<EscapableHandleScope>();
2375 let d = d.deref_mut();
2376 AssertTypeOf(d).is::<HandleScope>();
2377 let d = d.deref_mut();
2378 AssertTypeOf(d).is::<HandleScope<()>>();
2379 let d = d.deref_mut();
2380 AssertTypeOf(d).is::<Isolate>();
2381 }
2382 {
2383 let l4_djses = &mut DisallowJavascriptExecutionScope::new(
2384 l3_ehs,
2385 OnFailure::CrashOnFailure,
2386 );
2387 AssertTypeOf(l4_djses)
2388 .is::<DisallowJavascriptExecutionScope<EscapableHandleScope>>();
2389 let d = l4_djses.deref_mut();
2390 AssertTypeOf(d).is::<EscapableHandleScope>();
2391 let d = d.deref_mut();
2392 AssertTypeOf(d).is::<HandleScope>();
2393 let d = d.deref_mut();
2394 AssertTypeOf(d).is::<HandleScope<()>>();
2395 let d = d.deref_mut();
2396 AssertTypeOf(d).is::<Isolate>();
2397 {
2398 let l5_ajses = &mut AllowJavascriptExecutionScope::new(l4_djses);
2399 AssertTypeOf(l5_ajses).is::<EscapableHandleScope>();
2400 let d = l5_ajses.deref_mut();
2401 AssertTypeOf(d).is::<HandleScope>();
2402 let d = d.deref_mut();
2403 AssertTypeOf(d).is::<HandleScope<()>>();
2404 let d = d.deref_mut();
2405 AssertTypeOf(d).is::<Isolate>();
2406 }
2407 }
2408 }
2409 }
2410 {
2411 let l2_tc = &mut TryCatch::new(l1_hs);
2412 AssertTypeOf(l2_tc).is::<TryCatch<HandleScope<()>>>();
2413 let d = l2_tc.deref_mut();
2414 AssertTypeOf(d).is::<HandleScope<()>>();
2415 let d = d.deref_mut();
2416 AssertTypeOf(d).is::<Isolate>();
2417 {
2418 let l3_djses = &mut DisallowJavascriptExecutionScope::new(
2419 l2_tc,
2420 OnFailure::CrashOnFailure,
2421 );
2422 AssertTypeOf(l3_djses)
2423 .is::<DisallowJavascriptExecutionScope<TryCatch<HandleScope<()>>>>();
2424 let d = l3_djses.deref_mut();
2425 AssertTypeOf(d).is::<TryCatch<HandleScope<()>>>();
2426 let d = d.deref_mut();
2427 AssertTypeOf(d).is::<HandleScope<()>>();
2428 let d = d.deref_mut();
2429 AssertTypeOf(d).is::<Isolate>();
2430 {
2431 let l4_ajses = &mut AllowJavascriptExecutionScope::new(l3_djses);
2432 AssertTypeOf(l4_ajses).is::<TryCatch<HandleScope<()>>>();
2433 let d = l4_ajses.deref_mut();
2434 AssertTypeOf(d).is::<HandleScope<()>>();
2435 let d = d.deref_mut();
2436 AssertTypeOf(d).is::<Isolate>();
2437 }
2438 }
2439 }
2440 {
2441 let l2_ehs = &mut EscapableHandleScope::new(l1_hs);
2442 AssertTypeOf(l2_ehs).is::<EscapableHandleScope<()>>();
2443 let l3_tc = &mut TryCatch::new(l2_ehs);
2444 AssertTypeOf(l3_tc).is::<TryCatch<EscapableHandleScope<()>>>();
2445 let d = l3_tc.deref_mut();
2446 AssertTypeOf(d).is::<EscapableHandleScope<()>>();
2447 let d = d.deref_mut();
2448 AssertTypeOf(d).is::<HandleScope<()>>();
2449 let d = d.deref_mut();
2450 AssertTypeOf(d).is::<Isolate>();
2451 }
2452 {
2453 let _ = ContextScope::new(l1_hs, context);
2458 let l2_cbs = &mut unsafe { CallbackScope::new(context) };
2459 AssertTypeOf(l2_cbs).is::<CallbackScope>();
2460 let d = l2_cbs.deref_mut();
2461 AssertTypeOf(d).is::<HandleScope>();
2462 let d = d.deref_mut();
2463 AssertTypeOf(d).is::<HandleScope<()>>();
2464 let d = d.deref_mut();
2465 AssertTypeOf(d).is::<Isolate>();
2466 }
2467 {
2468 let isolate: &mut Isolate = l1_hs.as_mut();
2469 let l2_cbs = &mut unsafe { CallbackScope::new(isolate) };
2470 AssertTypeOf(l2_cbs).is::<CallbackScope<()>>();
2471 let d = l2_cbs.deref_mut();
2472 AssertTypeOf(d).is::<HandleScope<()>>();
2473 let d = d.deref_mut();
2474 AssertTypeOf(d).is::<Isolate>();
2475 }
2476 }
2477
2478 #[test]
2479 fn new_scope_types() {
2480 crate::initialize_v8();
2481 let isolate = &mut Isolate::new(Default::default());
2482 AssertTypeOf(isolate).is::<OwnedIsolate>();
2483 let global_context: Global<Context>;
2484 {
2485 let l1_hs = &mut HandleScope::new(isolate);
2486 AssertTypeOf(l1_hs).is::<HandleScope<()>>();
2487 let context = Context::new(l1_hs, Default::default());
2488 global_context = Global::new(l1_hs, context);
2489 AssertTypeOf(&HandleScope::new(l1_hs)).is::<HandleScope<()>>();
2490 {
2491 let l2_cxs = &mut ContextScope::new(l1_hs, context);
2492 AssertTypeOf(l2_cxs).is::<ContextScope<HandleScope>>();
2493 AssertTypeOf(&ContextScope::new(l2_cxs, context))
2494 .is::<ContextScope<HandleScope>>();
2495 AssertTypeOf(&HandleScope::new(l2_cxs)).is::<HandleScope>();
2496 AssertTypeOf(&EscapableHandleScope::new(l2_cxs))
2497 .is::<EscapableHandleScope>();
2498 AssertTypeOf(&TryCatch::new(l2_cxs)).is::<TryCatch<HandleScope>>();
2499 }
2500 {
2501 let l2_ehs = &mut EscapableHandleScope::new(l1_hs);
2502 AssertTypeOf(l2_ehs).is::<EscapableHandleScope<()>>();
2503 AssertTypeOf(&HandleScope::new(l2_ehs))
2504 .is::<EscapableHandleScope<()>>();
2505 AssertTypeOf(&EscapableHandleScope::new(l2_ehs))
2506 .is::<EscapableHandleScope<()>>();
2507 {
2508 let l3_cxs = &mut ContextScope::new(l2_ehs, context);
2509 AssertTypeOf(l3_cxs).is::<ContextScope<EscapableHandleScope>>();
2510 AssertTypeOf(&ContextScope::new(l3_cxs, context))
2511 .is::<ContextScope<EscapableHandleScope>>();
2512 AssertTypeOf(&HandleScope::new(l3_cxs)).is::<EscapableHandleScope>();
2513 AssertTypeOf(&EscapableHandleScope::new(l3_cxs))
2514 .is::<EscapableHandleScope>();
2515 {
2516 let l4_tc = &mut TryCatch::new(l3_cxs);
2517 AssertTypeOf(l4_tc).is::<TryCatch<EscapableHandleScope>>();
2518 AssertTypeOf(&ContextScope::new(l4_tc, context))
2519 .is::<ContextScope<EscapableHandleScope>>();
2520 AssertTypeOf(&HandleScope::new(l4_tc)).is::<EscapableHandleScope>();
2521 AssertTypeOf(&EscapableHandleScope::new(l4_tc))
2522 .is::<EscapableHandleScope>();
2523 AssertTypeOf(&TryCatch::new(l4_tc))
2524 .is::<TryCatch<EscapableHandleScope>>();
2525 }
2526 }
2527 {
2528 let l3_tc = &mut TryCatch::new(l2_ehs);
2529 AssertTypeOf(l3_tc).is::<TryCatch<EscapableHandleScope<()>>>();
2530 AssertTypeOf(&ContextScope::new(l3_tc, context))
2531 .is::<ContextScope<EscapableHandleScope>>();
2532 AssertTypeOf(&HandleScope::new(l3_tc))
2533 .is::<EscapableHandleScope<()>>();
2534 AssertTypeOf(&EscapableHandleScope::new(l3_tc))
2535 .is::<EscapableHandleScope<()>>();
2536 AssertTypeOf(&TryCatch::new(l3_tc))
2537 .is::<TryCatch<EscapableHandleScope<()>>>();
2538 }
2539 }
2540 {
2541 let l2_tc = &mut TryCatch::new(l1_hs);
2542 AssertTypeOf(l2_tc).is::<TryCatch<HandleScope<()>>>();
2543 AssertTypeOf(&ContextScope::new(l2_tc, context))
2544 .is::<ContextScope<HandleScope>>();
2545 AssertTypeOf(&HandleScope::new(l2_tc)).is::<HandleScope<()>>();
2546 AssertTypeOf(&EscapableHandleScope::new(l2_tc))
2547 .is::<EscapableHandleScope<()>>();
2548 AssertTypeOf(&TryCatch::new(l2_tc)).is::<TryCatch<HandleScope<()>>>();
2549 }
2550 {
2551 let l2_cbs = &mut unsafe { CallbackScope::new(context) };
2552 AssertTypeOf(l2_cbs).is::<CallbackScope>();
2553 AssertTypeOf(&ContextScope::new(l2_cbs, context))
2554 .is::<ContextScope<HandleScope>>();
2555 {
2556 let l3_hs = &mut HandleScope::new(l2_cbs);
2557 AssertTypeOf(l3_hs).is::<HandleScope>();
2558 AssertTypeOf(&ContextScope::new(l3_hs, context))
2559 .is::<ContextScope<HandleScope>>();
2560 AssertTypeOf(&HandleScope::new(l3_hs)).is::<HandleScope>();
2561 AssertTypeOf(&EscapableHandleScope::new(l3_hs))
2562 .is::<EscapableHandleScope>();
2563 AssertTypeOf(&TryCatch::new(l3_hs)).is::<TryCatch<HandleScope>>();
2564 }
2565 {
2566 let l3_ehs = &mut EscapableHandleScope::new(l2_cbs);
2567 AssertTypeOf(l3_ehs).is::<EscapableHandleScope>();
2568 AssertTypeOf(&ContextScope::new(l3_ehs, context))
2569 .is::<ContextScope<EscapableHandleScope>>();
2570 AssertTypeOf(&HandleScope::new(l3_ehs)).is::<EscapableHandleScope>();
2571 AssertTypeOf(&EscapableHandleScope::new(l3_ehs))
2572 .is::<EscapableHandleScope>();
2573 AssertTypeOf(&TryCatch::new(l3_ehs))
2574 .is::<TryCatch<EscapableHandleScope>>();
2575 }
2576 {
2577 let l3_tc = &mut TryCatch::new(l2_cbs);
2578 AssertTypeOf(l3_tc).is::<TryCatch<HandleScope>>();
2579 AssertTypeOf(&ContextScope::new(l3_tc, context))
2580 .is::<ContextScope<HandleScope>>();
2581 AssertTypeOf(&HandleScope::new(l3_tc)).is::<HandleScope>();
2582 AssertTypeOf(&EscapableHandleScope::new(l3_tc))
2583 .is::<EscapableHandleScope>();
2584 AssertTypeOf(&TryCatch::new(l3_tc)).is::<TryCatch<HandleScope>>();
2585 }
2586 }
2587 }
2588 {
2589 let l1_cbs = &mut unsafe { CallbackScope::new(&mut *isolate) };
2590 AssertTypeOf(l1_cbs).is::<CallbackScope<()>>();
2591 let context = Context::new(l1_cbs, Default::default());
2592 AssertTypeOf(&ContextScope::new(l1_cbs, context))
2593 .is::<ContextScope<HandleScope>>();
2594 AssertTypeOf(&HandleScope::new(l1_cbs)).is::<HandleScope<()>>();
2595 AssertTypeOf(&EscapableHandleScope::new(l1_cbs))
2596 .is::<EscapableHandleScope<()>>();
2597 AssertTypeOf(&TryCatch::new(l1_cbs)).is::<TryCatch<HandleScope<()>>>();
2598 }
2599 {
2600 AssertTypeOf(&HandleScope::with_context(isolate, &global_context))
2601 .is::<HandleScope>();
2602 AssertTypeOf(&HandleScope::with_context(isolate, global_context))
2603 .is::<HandleScope>();
2604 }
2605 }
2606}