summaryrefslogtreecommitdiff
path: root/core/ops.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/ops.rs')
-rw-r--r--core/ops.rs35
1 files changed, 34 insertions, 1 deletions
diff --git a/core/ops.rs b/core/ops.rs
index a5c76e412..361fc3cb7 100644
--- a/core/ops.rs
+++ b/core/ops.rs
@@ -14,6 +14,7 @@ use futures::Future;
use pin_project::pin_project;
use serde::Serialize;
use std::cell::RefCell;
+use std::cell::UnsafeCell;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ptr::NonNull;
@@ -106,7 +107,10 @@ pub fn to_op_result<R: Serialize + 'static>(
}
}
-// TODO(@AaronO): optimize OpCtx(s) mem usage ?
+/// Per-op context.
+///
+// Note: We don't worry too much about the size of this struct because it's allocated once per realm, and is
+// stored in a contiguous array.
pub struct OpCtx {
pub id: OpId,
pub state: Rc<RefCell<OpState>>,
@@ -114,6 +118,8 @@ pub struct OpCtx {
pub fast_fn_c_info: Option<NonNull<v8::fast_api::CFunctionInfo>>,
pub runtime_state: Weak<RefCell<JsRuntimeState>>,
pub(crate) context_state: Rc<RefCell<ContextState>>,
+ /// If the last fast op failed, stores the error to be picked up by the slow op.
+ pub(crate) last_fast_error: UnsafeCell<Option<AnyError>>,
}
impl OpCtx {
@@ -145,8 +151,35 @@ impl OpCtx {
decl,
context_state,
fast_fn_c_info,
+ last_fast_error: UnsafeCell::new(None),
}
}
+
+ /// This takes the last error from an [`OpCtx`], assuming that no other code anywhere
+ /// can hold a `&mut` to the last_fast_error field.
+ ///
+ /// # Safety
+ ///
+ /// Must only be called from op implementations.
+ #[inline(always)]
+ pub unsafe fn unsafely_take_last_error_for_ops_only(
+ &self,
+ ) -> Option<AnyError> {
+ let opt_mut = &mut *self.last_fast_error.get();
+ opt_mut.take()
+ }
+
+ /// This set the last error for an [`OpCtx`], assuming that no other code anywhere
+ /// can hold a `&mut` to the last_fast_error field.
+ ///
+ /// # Safety
+ ///
+ /// Must only be called from op implementations.
+ #[inline(always)]
+ pub unsafe fn unsafely_set_last_error_for_ops_only(&self, error: AnyError) {
+ let opt_mut = &mut *self.last_fast_error.get();
+ *opt_mut = Some(error);
+ }
}
/// Maintains the resources and ops inside a JS runtime.