summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2022-10-15 16:01:01 +0200
committerGitHub <noreply@github.com>2022-10-15 16:01:01 +0200
commite32719c2915aee9055327609ef03cf9bfc2b1785 (patch)
tree8894c93aa320ba3aa0a57637cf584f6f95dd807e
parent4ea4d3ad603ca06591e33592724cd935afb0185b (diff)
refactor(core): use isolate get_data/set_data instead of slots (#16286)
-rw-r--r--core/modules.rs6
-rw-r--r--core/runtime.rs77
2 files changed, 63 insertions, 20 deletions
diff --git a/core/modules.rs b/core/modules.rs
index 65b3852d9..8d0ae9733 100644
--- a/core/modules.rs
+++ b/core/modules.rs
@@ -5,6 +5,7 @@ use crate::error::generic_error;
use crate::module_specifier::ModuleSpecifier;
use crate::resolve_import;
use crate::resolve_url;
+use crate::JsRuntime;
use crate::OpState;
use anyhow::Error;
use futures::future::FutureExt;
@@ -125,10 +126,7 @@ fn json_module_evaluation_steps<'a>(
// SAFETY: `CallbackScope` can be safely constructed from `Local<Context>`
let scope = &mut unsafe { v8::CallbackScope::new(context) };
let tc_scope = &mut v8::TryCatch::new(scope);
- let module_map = tc_scope
- .get_slot::<Rc<RefCell<ModuleMap>>>()
- .unwrap()
- .clone();
+ let module_map = JsRuntime::module_map(tc_scope);
let handle = v8::Global::<v8::Module>::new(tc_scope, module);
let value_handle = module_map
diff --git a/core/runtime.rs b/core/runtime.rs
index 2b824588c..9867ae821 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -45,6 +45,7 @@ use std::sync::Mutex;
use std::sync::Once;
use std::task::Context;
use std::task::Poll;
+use v8::OwnedIsolate;
type PendingOpFuture =
OpCall<(v8::Global<v8::Context>, PromiseId, OpId, OpResult)>;
@@ -280,7 +281,18 @@ pub struct RuntimeOptions {
pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>,
}
+impl Drop for JsRuntime {
+ fn drop(&mut self) {
+ if let Some(v8_isolate) = self.v8_isolate.as_mut() {
+ Self::drop_state_and_module_map(v8_isolate);
+ }
+ }
+}
+
impl JsRuntime {
+ const STATE_DATA_OFFSET: u32 = 0;
+ const MODULE_MAP_DATA_OFFSET: u32 = 1;
+
/// Only constructor, configuration is done through `options`.
pub fn new(mut options: RuntimeOptions) -> Self {
let v8_platform = options.v8_platform.take();
@@ -397,7 +409,7 @@ impl JsRuntime {
.unwrap_or_else(|| Rc::new(NoopModuleLoader));
let known_realms = vec![v8::Weak::new(&mut isolate, &global_context)];
- isolate.set_slot(Rc::new(RefCell::new(JsRuntimeState {
+ let state_rc = Rc::new(RefCell::new(JsRuntimeState {
global_realm: Some(JsRealm(global_context.clone())),
known_realms,
pending_promise_exceptions: HashMap::new(),
@@ -418,14 +430,21 @@ impl JsRuntime {
dispatched_exceptions: Default::default(),
inspector: Some(inspector),
waker: AtomicWaker::new(),
- })));
+ }));
+ isolate.set_data(
+ Self::STATE_DATA_OFFSET,
+ Rc::into_raw(state_rc) as *mut c_void,
+ );
global_context
.open(&mut isolate)
.set_slot(&mut isolate, Rc::<RefCell<ContextState>>::default());
- let module_map = ModuleMap::new(loader, op_state);
- isolate.set_slot(Rc::new(RefCell::new(module_map)));
+ let module_map_rc = Rc::new(RefCell::new(ModuleMap::new(loader, op_state)));
+ isolate.set_data(
+ Self::MODULE_MAP_DATA_OFFSET,
+ Rc::into_raw(module_map_rc) as *mut c_void,
+ );
let mut js_runtime = Self {
v8_isolate: Some(isolate),
@@ -451,6 +470,22 @@ impl JsRuntime {
js_runtime
}
+ fn drop_state_and_module_map(v8_isolate: &mut OwnedIsolate) {
+ let state_ptr = v8_isolate.get_data(Self::STATE_DATA_OFFSET);
+ let state_rc =
+ // SAFETY: We are sure that it's a valid pointer for whole lifetime of
+ // the runtime.
+ unsafe { Rc::from_raw(state_ptr as *const RefCell<JsRuntimeState>) };
+ drop(state_rc);
+
+ let module_map_ptr = v8_isolate.get_data(Self::MODULE_MAP_DATA_OFFSET);
+ let module_map_rc =
+ // SAFETY: We are sure that it's a valid pointer for whole lifetime of
+ // the runtime.
+ unsafe { Rc::from_raw(module_map_ptr as *const RefCell<ModuleMap>) };
+ drop(module_map_rc);
+ }
+
pub fn global_context(&mut self) -> v8::Global<v8::Context> {
self.global_realm().0
}
@@ -523,13 +558,25 @@ impl JsRuntime {
}
pub(crate) fn state(isolate: &v8::Isolate) -> Rc<RefCell<JsRuntimeState>> {
- let s = isolate.get_slot::<Rc<RefCell<JsRuntimeState>>>().unwrap();
- s.clone()
+ let state_ptr = isolate.get_data(Self::STATE_DATA_OFFSET);
+ let state_rc =
+ // SAFETY: We are sure that it's a valid pointer for whole lifetime of
+ // the runtime.
+ unsafe { Rc::from_raw(state_ptr as *const RefCell<JsRuntimeState>) };
+ let state = state_rc.clone();
+ Rc::into_raw(state_rc);
+ state
}
pub(crate) fn module_map(isolate: &v8::Isolate) -> Rc<RefCell<ModuleMap>> {
- let module_map = isolate.get_slot::<Rc<RefCell<ModuleMap>>>().unwrap();
- module_map.clone()
+ let module_map_ptr = isolate.get_data(Self::MODULE_MAP_DATA_OFFSET);
+ let module_map_rc =
+ // SAFETY: We are sure that it's a valid pointer for whole lifetime of
+ // the runtime.
+ unsafe { Rc::from_raw(module_map_ptr as *const RefCell<ModuleMap>) };
+ let module_map = module_map_rc.clone();
+ Rc::into_raw(module_map_rc);
+ module_map
}
/// Initializes JS of provided Extensions in the given realm
@@ -733,13 +780,11 @@ impl JsRuntime {
state.borrow_mut().inspector.take();
- // Overwrite existing ModuleMap to drop v8::Global handles
- self
- .v8_isolate()
- .set_slot(Rc::new(RefCell::new(ModuleMap::new(
- Rc::new(NoopModuleLoader),
- state.borrow().op_state.clone(),
- ))));
+ // Drop existing ModuleMap to drop v8::Global handles
+ {
+ let v8_isolate = self.v8_isolate();
+ Self::drop_state_and_module_map(v8_isolate);
+ }
// Drop other v8::Global handles before snapshotting
{
@@ -763,7 +808,7 @@ impl JsRuntime {
state.js_nexttick_cbs.clear();
}
- let snapshot_creator = self.v8_isolate.unwrap();
+ let snapshot_creator = self.v8_isolate.take().unwrap();
snapshot_creator
.create_blob(v8::FunctionCodeHandling::Keep)
.unwrap()