mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-27 01:29:19 -05:00
Invert the TryCatch/TryCatchScope relationship (#118)
This commit is contained in:
parent
6d30c77116
commit
ac8aec9c8f
1 changed files with 41 additions and 40 deletions
|
@ -51,62 +51,32 @@ extern "C" {
|
||||||
// once, the same TryCatch object can't be entered again.
|
// once, the same TryCatch object can't be entered again.
|
||||||
|
|
||||||
/// An external exception handler.
|
/// An external exception handler.
|
||||||
pub struct TryCatch<'tc>(TryCatchState<'tc>);
|
|
||||||
|
|
||||||
/// An activated TryCatch handler that is active as long as it is in scope.
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct TryCatchScope<'tc>(CxxTryCatch, PhantomData<&'tc ()>);
|
pub struct TryCatch<'tc>(CxxTryCatch, PhantomData<&'tc ()>);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct CxxTryCatch([usize; 6]);
|
struct CxxTryCatch([usize; 6]);
|
||||||
|
|
||||||
|
/// A scope object that will, when entered, active the embedded TryCatch block.
|
||||||
|
pub struct TryCatchScope<'tc>(TryCatchState<'tc>);
|
||||||
|
|
||||||
enum TryCatchState<'tc> {
|
enum TryCatchState<'tc> {
|
||||||
New { isolate: *mut Isolate },
|
New { isolate: *mut Isolate },
|
||||||
Uninit(MaybeUninit<TryCatchScope<'tc>>),
|
Uninit(MaybeUninit<TryCatch<'tc>>),
|
||||||
Constructed(TryCatchScope<'tc>),
|
Entered(TryCatch<'tc>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tc> TryCatch<'tc> {
|
impl<'tc> TryCatch<'tc> {
|
||||||
/// Creates a new try/catch block. Note that all TryCatch blocks should be
|
/// Creates a new try/catch block. Note that all TryCatch blocks should be
|
||||||
/// stack allocated because the memory location itself is compared against
|
/// stack allocated because the memory location itself is compared against
|
||||||
/// JavaScript try/catch blocks.
|
/// JavaScript try/catch blocks.
|
||||||
pub fn new(scope: &mut impl AsMut<Isolate>) -> Self {
|
#[allow(clippy::new_ret_no_self)]
|
||||||
Self(TryCatchState::New {
|
pub fn new(scope: &mut impl AsMut<Isolate>) -> TryCatchScope<'tc> {
|
||||||
|
TryCatchScope(TryCatchState::New {
|
||||||
isolate: scope.as_mut(),
|
isolate: scope.as_mut(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enters the TryCatch block. Exceptions are caught as long as the returned
|
|
||||||
/// TryCatchScope remains in scope.
|
|
||||||
pub fn enter(&'tc mut self) -> &'tc mut TryCatchScope {
|
|
||||||
use TryCatchState::*;
|
|
||||||
let state = &mut self.0;
|
|
||||||
|
|
||||||
let isolate = match take(state) {
|
|
||||||
New { isolate } => isolate,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let buf = match state {
|
|
||||||
Uninit(b) => b,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
TryCatchScope::construct(buf, isolate);
|
|
||||||
|
|
||||||
*state = match take(state) {
|
|
||||||
Uninit(b) => Constructed(unsafe { b.assume_init() }),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
match state {
|
|
||||||
Constructed(v) => v,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tc> TryCatchScope<'tc> {
|
|
||||||
/// Returns true if an exception has been caught by this try/catch block.
|
/// Returns true if an exception has been caught by this try/catch block.
|
||||||
pub fn has_caught(&self) -> bool {
|
pub fn has_caught(&self) -> bool {
|
||||||
unsafe { v8__TryCatch__HasCaught(&self.0) }
|
unsafe { v8__TryCatch__HasCaught(&self.0) }
|
||||||
|
@ -206,7 +176,7 @@ impl<'tc> TryCatchScope<'tc> {
|
||||||
unsafe { v8__TryCatch__SetCaptureMessage(&mut self.0, value) };
|
unsafe { v8__TryCatch__SetCaptureMessage(&mut self.0, value) };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct(buf: &mut MaybeUninit<TryCatchScope>, isolate: *mut Isolate) {
|
fn construct(buf: &mut MaybeUninit<TryCatch>, isolate: *mut Isolate) {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert_eq!(size_of_val(buf), size_of::<CxxTryCatch>());
|
assert_eq!(size_of_val(buf), size_of::<CxxTryCatch>());
|
||||||
let buf = &mut *(buf as *mut _ as *mut MaybeUninit<CxxTryCatch>);
|
let buf = &mut *(buf as *mut _ as *mut MaybeUninit<CxxTryCatch>);
|
||||||
|
@ -221,6 +191,37 @@ impl Drop for CxxTryCatch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tc> TryCatchScope<'tc> {
|
||||||
|
/// Enters the TryCatch block. Exceptions are caught as long as the returned
|
||||||
|
/// TryCatch object remains in scope.
|
||||||
|
pub fn enter(&'tc mut self) -> &'tc mut TryCatch {
|
||||||
|
use TryCatchState::*;
|
||||||
|
let state = &mut self.0;
|
||||||
|
|
||||||
|
let isolate = match take(state) {
|
||||||
|
New { isolate } => isolate,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let buf = match state {
|
||||||
|
Uninit(b) => b,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
TryCatch::construct(buf, isolate);
|
||||||
|
|
||||||
|
*state = match take(state) {
|
||||||
|
Uninit(b) => Entered(unsafe { b.assume_init() }),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
match state {
|
||||||
|
Entered(v) => v,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tc> Default for TryCatchState<'tc> {
|
impl<'tc> Default for TryCatchState<'tc> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Uninit(MaybeUninit::uninit())
|
Self::Uninit(MaybeUninit::uninit())
|
||||||
|
|
Loading…
Reference in a new issue