diff options
author | Andreu Botella <andreu@andreubotella.com> | 2022-09-01 23:01:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-01 23:01:05 +0200 |
commit | 307d84cfa5c1489ddfc8477f6561676356399e8c (patch) | |
tree | 5a65bdf5a3be832ee26852461b087552a552d22d /core/ops_builtin_v8.rs | |
parent | 58e76098e6325ad16d552924d58c33bad6573c07 (diff) |
refactor(core): Move optional callbacks from `JsRuntimeState` to `ContextState` (#15599)
The `JsRuntimeState` struct stores a number of JS callbacks that are
used either in the event loop or when interacting with V8. Some of
these callback fields are vectors of callbacks, and therefore could
plausibly store at least one callback per realm. However, some of
those fields are `Option<v8::Global<v8::Function>>`, which would make
the callbacks set by a realm override the one that might have been set
by a different realm.
As it turns out, all of the current such optional callbacks
(`js_promise_reject_cb`, `js_format_exception_cb` and
`js_wasm_streaming_cb`) are only used from inside a realm, and
therefore this change makes it so such callbacks can only be set from
inside a realm, and will only affect that realm.
Diffstat (limited to 'core/ops_builtin_v8.rs')
-rw-r--r-- | core/ops_builtin_v8.rs | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/core/ops_builtin_v8.rs b/core/ops_builtin_v8.rs index fe6a38bb4..f8b59a760 100644 --- a/core/ops_builtin_v8.rs +++ b/core/ops_builtin_v8.rs @@ -103,8 +103,8 @@ fn op_set_promise_reject_callback<'a>( cb: serde_v8::Value, ) -> Result<Option<serde_v8::Value<'a>>, Error> { let cb = to_v8_fn(scope, cb)?; - let state_rc = JsRuntime::state(scope); - let old = state_rc.borrow_mut().js_promise_reject_cb.replace(cb); + let realm_state_rc = JsRealm::state_from_scope(scope); + let old = realm_state_rc.borrow_mut().js_promise_reject_cb.replace(cb); let old = old.map(|v| v8::Local::new(scope, v)); Ok(old.map(|v| from_v8(scope, v.into()).unwrap())) } @@ -641,22 +641,28 @@ fn op_set_wasm_streaming_callback( cb: serde_v8::Value, ) -> Result<(), Error> { let cb = to_v8_fn(scope, cb)?; - let state_rc = JsRuntime::state(scope); - let mut state = state_rc.borrow_mut(); + let realm_state_rc = JsRealm::state_from_scope(scope); + let mut realm_state = realm_state_rc.borrow_mut(); // The callback to pass to the v8 API has to be a unit type, so it can't // borrow or move any local variables. Therefore, we're storing the JS // callback in a JsRuntimeState slot. - if state.js_wasm_streaming_cb.is_some() { + if realm_state.js_wasm_streaming_cb.is_some() { return Err(type_error("op_set_wasm_streaming_callback already called")); } - state.js_wasm_streaming_cb = Some(cb); + realm_state.js_wasm_streaming_cb = Some(cb); scope.set_wasm_streaming_callback(|scope, arg, wasm_streaming| { let (cb_handle, streaming_rid) = { + let realm_state_rc = JsRealm::state_from_scope(scope); + let cb_handle = realm_state_rc + .borrow() + .js_wasm_streaming_cb + .as_ref() + .unwrap() + .clone(); let state_rc = JsRuntime::state(scope); - let state = state_rc.borrow(); - let cb_handle = state.js_wasm_streaming_cb.as_ref().unwrap().clone(); - let streaming_rid = state + let streaming_rid = state_rc + .borrow() .op_state .borrow_mut() .resource_table @@ -775,8 +781,11 @@ fn op_set_format_exception_callback<'a>( cb: serde_v8::Value<'a>, ) -> Result<Option<serde_v8::Value<'a>>, Error> { let cb = to_v8_fn(scope, cb)?; - let state_rc = JsRuntime::state(scope); - let old = state_rc.borrow_mut().js_format_exception_cb.replace(cb); + let realm_state_rc = JsRealm::state_from_scope(scope); + let old = realm_state_rc + .borrow_mut() + .js_format_exception_cb + .replace(cb); let old = old.map(|v| v8::Local::new(scope, v)); Ok(old.map(|v| from_v8(scope, v.into()).unwrap())) } |