summaryrefslogtreecommitdiff
path: root/core/realm.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/realm.rs')
-rw-r--r--core/realm.rs73
1 files changed, 61 insertions, 12 deletions
diff --git a/core/realm.rs b/core/realm.rs
index 1595d9160..8e2d932b5 100644
--- a/core/realm.rs
+++ b/core/realm.rs
@@ -8,21 +8,43 @@ use anyhow::Error;
use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::HashSet;
+use std::hash::BuildHasherDefault;
+use std::hash::Hasher;
+use std::marker::PhantomData;
use std::option::Option;
use std::rc::Rc;
use v8::HandleScope;
use v8::Local;
+// Hasher used for `unrefed_ops`. Since these are rolling i32, there's no
+// need to actually hash them.
+#[derive(Default)]
+pub(crate) struct IdentityHasher(u64, PhantomData<i32>);
+
+impl Hasher for IdentityHasher {
+ fn write_i32(&mut self, i: i32) {
+ self.0 = i as u64;
+ }
+
+ fn finish(&self) -> u64 {
+ self.0
+ }
+
+ fn write(&mut self, _bytes: &[u8]) {
+ unreachable!()
+ }
+}
+
#[derive(Default)]
pub(crate) struct ContextState {
- pub(crate) js_event_loop_tick_cb: Option<v8::Global<v8::Function>>,
- pub(crate) js_build_custom_error_cb: Option<v8::Global<v8::Function>>,
- pub(crate) js_promise_reject_cb: Option<v8::Global<v8::Function>>,
- pub(crate) js_format_exception_cb: Option<v8::Global<v8::Function>>,
- pub(crate) js_wasm_streaming_cb: Option<v8::Global<v8::Function>>,
+ pub(crate) js_event_loop_tick_cb: Option<Rc<v8::Global<v8::Function>>>,
+ pub(crate) js_build_custom_error_cb: Option<Rc<v8::Global<v8::Function>>>,
+ pub(crate) js_promise_reject_cb: Option<Rc<v8::Global<v8::Function>>>,
+ pub(crate) js_format_exception_cb: Option<Rc<v8::Global<v8::Function>>>,
+ pub(crate) js_wasm_streaming_cb: Option<Rc<v8::Global<v8::Function>>>,
pub(crate) pending_promise_rejections:
HashMap<v8::Global<v8::Promise>, v8::Global<v8::Value>>,
- pub(crate) unrefed_ops: HashSet<i32>,
+ pub(crate) unrefed_ops: HashSet<i32, BuildHasherDefault<IdentityHasher>>,
// We don't explicitly re-read this prop but need the slice to live alongside
// the context
pub(crate) op_ctxs: Box<[OpCtx]>,
@@ -73,16 +95,18 @@ pub(crate) struct ContextState {
/// keep the underlying V8 context alive even if it would have otherwise been
/// garbage collected.
#[derive(Clone)]
-pub struct JsRealm(v8::Global<v8::Context>);
+pub struct JsRealm(Rc<v8::Global<v8::Context>>);
impl JsRealm {
pub fn new(context: v8::Global<v8::Context>) -> Self {
- JsRealm(context)
+ JsRealm(Rc::new(context))
}
+ #[inline(always)]
pub fn context(&self) -> &v8::Global<v8::Context> {
&self.0
}
+ #[inline(always)]
pub(crate) fn state(
&self,
isolate: &mut v8::Isolate,
@@ -95,6 +119,7 @@ impl JsRealm {
.clone()
}
+ #[inline(always)]
pub(crate) fn state_from_scope(
scope: &mut v8::HandleScope,
) -> Rc<RefCell<ContextState>> {
@@ -106,11 +131,12 @@ impl JsRealm {
}
/// For info on the [`v8::Isolate`] parameter, check [`JsRealm#panics`].
+ #[inline(always)]
pub fn handle_scope<'s>(
&self,
isolate: &'s mut v8::Isolate,
) -> v8::HandleScope<'s> {
- v8::HandleScope::with_context(isolate, &self.0)
+ v8::HandleScope::with_context(isolate, &*self.0)
}
/// For info on the [`v8::Isolate`] parameter, check [`JsRealm#panics`].
@@ -212,12 +238,36 @@ impl JsRealm {
}
// TODO(andreubotella): `mod_evaluate`, `load_main_module`, `load_side_module`
+}
- pub(crate) fn check_promise_rejections(
+pub struct JsRealmLocal<'s>(v8::Local<'s, v8::Context>);
+impl<'s> JsRealmLocal<'s> {
+ pub fn new(context: v8::Local<'s, v8::Context>) -> Self {
+ JsRealmLocal(context)
+ }
+
+ #[inline(always)]
+ pub fn context(&self) -> v8::Local<v8::Context> {
+ self.0
+ }
+
+ #[inline(always)]
+ pub(crate) fn state(
&self,
isolate: &mut v8::Isolate,
+ ) -> Rc<RefCell<ContextState>> {
+ self
+ .context()
+ .get_slot::<Rc<RefCell<ContextState>>>(isolate)
+ .unwrap()
+ .clone()
+ }
+
+ pub(crate) fn check_promise_rejections(
+ &self,
+ scope: &mut v8::HandleScope,
) -> Result<(), Error> {
- let context_state_rc = self.state(isolate);
+ let context_state_rc = self.state(scope);
let mut context_state = context_state_rc.borrow_mut();
if context_state.pending_promise_rejections.is_empty() {
@@ -238,7 +288,6 @@ impl JsRealm {
.unwrap();
drop(context_state);
- let scope = &mut self.handle_scope(isolate);
let exception = v8::Local::new(scope, handle);
exception_to_err_result(scope, exception, true)
}