summaryrefslogtreecommitdiff
path: root/core/bindings.rs
diff options
context:
space:
mode:
authorAndreu Botella <andreu@andreubotella.com>2022-09-01 23:01:05 +0200
committerGitHub <noreply@github.com>2022-09-01 23:01:05 +0200
commit307d84cfa5c1489ddfc8477f6561676356399e8c (patch)
tree5a65bdf5a3be832ee26852461b087552a552d22d /core/bindings.rs
parent58e76098e6325ad16d552924d58c33bad6573c07 (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/bindings.rs')
-rw-r--r--core/bindings.rs14
1 files changed, 9 insertions, 5 deletions
diff --git a/core/bindings.rs b/core/bindings.rs
index f75f6c7f3..eea16b13a 100644
--- a/core/bindings.rs
+++ b/core/bindings.rs
@@ -7,6 +7,7 @@ use crate::modules::validate_import_assertions;
use crate::modules::ImportAssertionsKind;
use crate::modules::ModuleMap;
use crate::ops::OpCtx;
+use crate::JsRealm;
use crate::JsRuntime;
use log::debug;
use std::option::Option;
@@ -408,15 +409,15 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
// SAFETY: `CallbackScope` can be safely constructed from `&PromiseRejectMessage`
let scope = &mut unsafe { v8::CallbackScope::new(&message) };
- let state_rc = JsRuntime::state(scope);
- let mut state = state_rc.borrow_mut();
+ let realm_state_rc = JsRealm::state_from_scope(scope);
- if let Some(js_promise_reject_cb) = state.js_promise_reject_cb.clone() {
+ if let Some(js_promise_reject_cb) =
+ realm_state_rc.borrow().js_promise_reject_cb.clone()
+ {
let tc_scope = &mut v8::TryCatch::new(scope);
let undefined: v8::Local<v8::Value> = v8::undefined(tc_scope).into();
let type_ = v8::Integer::new(tc_scope, message.get_event() as i32);
let promise = message.get_promise();
- drop(state); // Drop borrow, callbacks can call back into runtime.
let reason = match message.get_event() {
PromiseRejectWithNoHandler
@@ -439,6 +440,7 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
};
if has_unhandled_rejection_handler {
+ let state_rc = JsRuntime::state(tc_scope);
let mut state = state_rc.borrow_mut();
if let Some(pending_mod_evaluate) = state.pending_mod_evaluate.as_mut() {
if !pending_mod_evaluate.has_evaluated {
@@ -449,6 +451,8 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
}
}
} else {
+ let state_rc = JsRuntime::state(scope);
+ let mut state = state_rc.borrow_mut();
let promise = message.get_promise();
let promise_global = v8::Global::new(scope, promise);
match message.get_event() {
@@ -467,7 +471,7 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
// Should not warn. See #1272
}
}
- }
+ };
}
/// This binding should be used if there's a custom console implementation