Skip to content

Commit 226c92e

Browse files
authored
Re implement ExceptionGuard by myself. (#113)
1 parent da78bc1 commit 226c92e

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

phper/src/errors.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ use crate::{classes::ClassEntry, objects::ZObject, sys::*, types::TypeInfo, valu
1414
use derive_more::Constructor;
1515
use phper_alloc::ToRefOwned;
1616
use std::{
17+
cell::RefCell,
1718
convert::Infallible,
1819
error,
1920
ffi::FromBytesWithNulError,
2021
fmt::{self, Debug, Display},
2122
io,
2223
marker::PhantomData,
23-
mem::ManuallyDrop,
24+
mem::{replace, ManuallyDrop},
2425
ops::{Deref, DerefMut},
26+
ptr::null_mut,
2527
result,
2628
str::Utf8Error,
27-
sync::atomic::{self, AtomicIsize},
2829
};
2930

3031
/// Predefined interface `Throwable`.
@@ -466,8 +467,6 @@ impl Throwable for NotImplementThrowableError {
466467
}
467468
}
468469

469-
static EXCEPTION_GUARD_COUNT: AtomicIsize = AtomicIsize::new(0);
470-
471470
/// Guarder for preventing the thrown exception from being overwritten.
472471
///
473472
/// Normally, you don't need to use `ExceptionGuard`, unless before you call the
@@ -476,24 +475,26 @@ static EXCEPTION_GUARD_COUNT: AtomicIsize = AtomicIsize::new(0);
476475
/// Can be used nested.
477476
pub struct ExceptionGuard(PhantomData<*mut ()>);
478477

478+
thread_local! {
479+
static EXCEPTION_STACK: RefCell<Vec<*mut zend_object>> = Default::default();
480+
}
481+
479482
impl Default for ExceptionGuard {
480483
fn default() -> Self {
481-
if EXCEPTION_GUARD_COUNT.fetch_add(1, atomic::Ordering::Acquire) == 0 {
482-
unsafe {
483-
zend_exception_save();
484-
}
485-
}
484+
EXCEPTION_STACK.with(|stack| unsafe {
485+
stack
486+
.borrow_mut()
487+
.push(replace(&mut eg!(exception), null_mut()));
488+
});
486489
Self(PhantomData)
487490
}
488491
}
489492

490493
impl Drop for ExceptionGuard {
491494
fn drop(&mut self) {
492-
if EXCEPTION_GUARD_COUNT.fetch_sub(1, atomic::Ordering::Acquire) == 1 {
493-
unsafe {
494-
zend_exception_restore();
495-
}
496-
}
495+
EXCEPTION_STACK.with(|stack| unsafe {
496+
eg!(exception) = stack.borrow_mut().pop().expect("exception stack is empty");
497+
});
497498
}
498499
}
499500

0 commit comments

Comments
 (0)