mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Enter realms more consistently during the script event loop.
This commit is contained in:
parent
9ea1399c30
commit
864e072d5c
6 changed files with 52 additions and 5 deletions
|
@ -9,6 +9,7 @@ use crate::dom::dedicatedworkerglobalscope::{AutoWorkerReset, DedicatedWorkerScr
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::worker::TrustedWorkerAddress;
|
||||
use crate::dom::workerglobalscope::WorkerGlobalScope;
|
||||
use crate::realms::enter_realm;
|
||||
use crate::script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||
use crate::task_queue::{QueuedTaskConversion, TaskQueue};
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
|
@ -140,6 +141,7 @@ pub fn run_worker_event_loop<T, WorkerMsg, Event>(
|
|||
}
|
||||
// Step 3
|
||||
for event in sequential {
|
||||
let _realm = enter_realm(&*worker_scope);
|
||||
if !worker_scope.handle_event(event) {
|
||||
// Shutdown
|
||||
return;
|
||||
|
|
|
@ -46,6 +46,7 @@ use crate::fetch::create_a_potential_cors_request;
|
|||
use crate::image_listener::{generate_cache_listener_for_element, ImageCacheListener};
|
||||
use crate::microtask::{Microtask, MicrotaskRunnable};
|
||||
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
||||
use crate::realms::enter_realm;
|
||||
use crate::script_thread::ScriptThread;
|
||||
use crate::task_source::TaskSource;
|
||||
use app_units::{Au, AU_PER_PX};
|
||||
|
@ -56,6 +57,7 @@ use html5ever::{LocalName, Prefix, QualName};
|
|||
use ipc_channel::ipc;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::jsapi::JSAutoRealm;
|
||||
use mime::{self, Mime};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::image::base::{Image, ImageMetadata};
|
||||
|
@ -1353,6 +1355,13 @@ impl MicrotaskRunnable for ImageElementMicrotask {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_realm(&self) -> JSAutoRealm {
|
||||
match self {
|
||||
&ImageElementMicrotask::StableStateUpdateImageDataTask { ref elem, .. } |
|
||||
&ImageElementMicrotask::EnvironmentChangesTask { ref elem, .. } => enter_realm(&**elem),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LayoutHTMLImageElementHelpers {
|
||||
|
|
|
@ -62,7 +62,7 @@ use crate::dom::virtualmethods::VirtualMethods;
|
|||
use crate::fetch::{create_a_potential_cors_request, FetchCanceller};
|
||||
use crate::microtask::{Microtask, MicrotaskRunnable};
|
||||
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
||||
use crate::realms::InRealm;
|
||||
use crate::realms::{enter_realm, InRealm};
|
||||
use crate::script_thread::ScriptThread;
|
||||
use crate::task_source::TaskSource;
|
||||
use dom_struct::dom_struct;
|
||||
|
@ -74,6 +74,7 @@ use html5ever::{LocalName, Prefix};
|
|||
use http::header::{self, HeaderMap, HeaderValue};
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::jsapi::JSAutoRealm;
|
||||
use media::{glplayer_channel, GLPlayerMsg, GLPlayerMsgForward, WindowGLContext};
|
||||
use net_traits::image::base::Image;
|
||||
use net_traits::request::Destination;
|
||||
|
@ -2506,6 +2507,14 @@ impl MicrotaskRunnable for MediaElementMicrotask {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_realm(&self) -> JSAutoRealm {
|
||||
match self {
|
||||
&MediaElementMicrotask::ResourceSelectionTask { ref elem, .. } |
|
||||
&MediaElementMicrotask::PauseIfNotInDocumentTask { ref elem } |
|
||||
&MediaElementMicrotask::SeekedTask { ref elem, .. } => enter_realm(&**elem),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Resource {
|
||||
|
|
|
@ -34,6 +34,7 @@ use crate::dom::processinginstruction::ProcessingInstruction;
|
|||
use crate::dom::text::Text;
|
||||
use crate::dom::virtualmethods::vtable_for;
|
||||
use crate::network_listener::PreInvoke;
|
||||
use crate::realms::enter_realm;
|
||||
use crate::script_thread::ScriptThread;
|
||||
use content_security_policy::{self as csp, CspList};
|
||||
use dom_struct::dom_struct;
|
||||
|
@ -828,6 +829,8 @@ impl FetchResponseListener for ParserContext {
|
|||
return;
|
||||
}
|
||||
|
||||
let _realm = enter_realm(&*parser.document);
|
||||
|
||||
parser.document.set_csp_list(csp_list);
|
||||
self.parser = Some(Trusted::new(&*parser));
|
||||
self.submit_resource_timing();
|
||||
|
|
|
@ -15,9 +15,10 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use crate::dom::htmlimageelement::ImageElementMicrotask;
|
||||
use crate::dom::htmlmediaelement::MediaElementMicrotask;
|
||||
use crate::dom::mutationobserver::MutationObserver;
|
||||
use crate::realms::enter_realm;
|
||||
use crate::script_runtime::{notify_about_rejected_promises, JSContext};
|
||||
use crate::script_thread::ScriptThread;
|
||||
use js::jsapi::{JobQueueIsEmpty, JobQueueMayNotBeEmpty};
|
||||
use js::jsapi::{JSAutoRealm, JobQueueIsEmpty, JobQueueMayNotBeEmpty};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use std::cell::Cell;
|
||||
use std::mem;
|
||||
|
@ -44,6 +45,7 @@ pub enum Microtask {
|
|||
|
||||
pub trait MicrotaskRunnable {
|
||||
fn handler(&self) {}
|
||||
fn enter_realm(&self) -> JSAutoRealm;
|
||||
}
|
||||
|
||||
/// A promise callback scheduled to run during the next microtask checkpoint (#4283).
|
||||
|
@ -108,19 +110,23 @@ impl MicrotaskQueue {
|
|||
if let Some(target) = target_provider(job.pipeline) {
|
||||
let was_interacting = ScriptThread::is_user_interacting();
|
||||
ScriptThread::set_user_interacting(job.is_user_interacting);
|
||||
let _realm = enter_realm(&*target);
|
||||
let _ = job.callback.Call_(&*target, ExceptionHandling::Report);
|
||||
ScriptThread::set_user_interacting(was_interacting);
|
||||
}
|
||||
},
|
||||
Microtask::User(ref job) => {
|
||||
if let Some(target) = target_provider(job.pipeline) {
|
||||
let _realm = enter_realm(&*target);
|
||||
let _ = job.callback.Call_(&*target, ExceptionHandling::Report);
|
||||
}
|
||||
},
|
||||
Microtask::MediaElement(ref task) => {
|
||||
let _realm = task.enter_realm();
|
||||
task.handler();
|
||||
},
|
||||
Microtask::ImageElement(ref task) => {
|
||||
let _realm = task.enter_realm();
|
||||
task.handler();
|
||||
},
|
||||
Microtask::CustomElementReaction => {
|
||||
|
|
|
@ -1592,6 +1592,11 @@ impl ScriptThread {
|
|||
let category = self.categorize_msg(&msg);
|
||||
let pipeline_id = self.message_to_pipeline(&msg);
|
||||
|
||||
let _realm = pipeline_id.and_then(|id| {
|
||||
let global = self.documents.borrow().find_global(id);
|
||||
global.map(|global| enter_realm(&*global))
|
||||
});
|
||||
|
||||
if self.closing.load(Ordering::SeqCst) {
|
||||
// If we've received the closed signal from the BHM, only handle exit messages.
|
||||
match msg {
|
||||
|
@ -1656,6 +1661,8 @@ impl ScriptThread {
|
|||
}
|
||||
let window = document.window();
|
||||
|
||||
let _realm = enter_realm(&*document);
|
||||
|
||||
window
|
||||
.upcast::<GlobalScope>()
|
||||
.perform_a_dom_garbage_collection_checkpoint();
|
||||
|
@ -1684,6 +1691,7 @@ impl ScriptThread {
|
|||
}
|
||||
|
||||
for (_, document) in self.documents.borrow().iter() {
|
||||
let _realm = enter_realm(&*document);
|
||||
document.animations().send_pending_events(document.window());
|
||||
}
|
||||
}
|
||||
|
@ -1786,7 +1794,7 @@ impl ScriptThread {
|
|||
DispatchStorageEvent(id, ..) => Some(id),
|
||||
ReportCSSError(id, ..) => Some(id),
|
||||
Reload(id, ..) => Some(id),
|
||||
PaintMetric(..) => None,
|
||||
PaintMetric(id, ..) => Some(id),
|
||||
ExitFullScreen(id, ..) => Some(id),
|
||||
MediaSessionAction(..) => None,
|
||||
SetWebGPUPort(..) => None,
|
||||
|
@ -2070,7 +2078,13 @@ impl ScriptThread {
|
|||
|
||||
fn handle_msg_from_script(&self, msg: MainThreadScriptMsg) {
|
||||
match msg {
|
||||
MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task, _, _)) => task.run_box(),
|
||||
MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task, pipeline_id, _)) => {
|
||||
let _realm = pipeline_id.and_then(|id| {
|
||||
let global = self.documents.borrow().find_global(id);
|
||||
global.map(|global| enter_realm(&*global))
|
||||
});
|
||||
task.run_box()
|
||||
},
|
||||
MainThreadScriptMsg::Common(CommonScriptMsg::CollectReports(chan)) => {
|
||||
self.collect_reports(chan)
|
||||
},
|
||||
|
@ -3277,6 +3291,8 @@ impl ScriptThread {
|
|||
incomplete.inherited_secure_context,
|
||||
);
|
||||
|
||||
let _realm = enter_realm(&*window);
|
||||
|
||||
// Initialize the browsing context for the window.
|
||||
let window_proxy = self.local_window_proxy(
|
||||
&window,
|
||||
|
@ -3460,6 +3476,8 @@ impl ScriptThread {
|
|||
);
|
||||
}
|
||||
|
||||
let _realm = enter_realm(&*window);
|
||||
|
||||
// Assuming all CompositionEvent are generated by user interactions.
|
||||
ScriptThread::set_user_interacting(true);
|
||||
match event {
|
||||
|
@ -3978,7 +3996,7 @@ impl ScriptThread {
|
|||
.documents
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|(_id, document)| document.global())
|
||||
.map(|(_id, document)| DomRoot::from_ref(document.window().upcast()))
|
||||
.collect();
|
||||
|
||||
self.microtask_queue.checkpoint(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue