mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Use safe JSContext in MicrotaskQueue
This commit is contained in:
parent
b18fa8b8a7
commit
6d444afd9e
4 changed files with 27 additions and 39 deletions
|
@ -677,23 +677,17 @@ impl GlobalScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a microtask checkpoint.
|
/// Perform a microtask checkpoint.
|
||||||
#[allow(unsafe_code)]
|
|
||||||
pub fn perform_a_microtask_checkpoint(&self) {
|
pub fn perform_a_microtask_checkpoint(&self) {
|
||||||
unsafe {
|
self.microtask_queue.checkpoint(
|
||||||
self.microtask_queue.checkpoint(
|
self.get_cx(),
|
||||||
*self.get_cx(),
|
|_| Some(DomRoot::from_ref(self)),
|
||||||
|_| Some(DomRoot::from_ref(self)),
|
vec![DomRoot::from_ref(self)],
|
||||||
vec![DomRoot::from_ref(self)],
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enqueue a microtask for subsequent execution.
|
/// Enqueue a microtask for subsequent execution.
|
||||||
#[allow(unsafe_code)]
|
|
||||||
pub fn enqueue_microtask(&self, job: Microtask) {
|
pub fn enqueue_microtask(&self, job: Microtask) {
|
||||||
unsafe {
|
self.microtask_queue.enqueue(job, self.get_cx());
|
||||||
self.microtask_queue.enqueue(job, *self.get_cx());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new sender/receiver pair that can be used to implement an on-demand
|
/// Create a new sender/receiver pair that can be used to implement an on-demand
|
||||||
|
|
|
@ -14,9 +14,9 @@ use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::htmlimageelement::ImageElementMicrotask;
|
use crate::dom::htmlimageelement::ImageElementMicrotask;
|
||||||
use crate::dom::htmlmediaelement::MediaElementMicrotask;
|
use crate::dom::htmlmediaelement::MediaElementMicrotask;
|
||||||
use crate::dom::mutationobserver::MutationObserver;
|
use crate::dom::mutationobserver::MutationObserver;
|
||||||
use crate::script_runtime::notify_about_rejected_promises;
|
use crate::script_runtime::{notify_about_rejected_promises, JSContext};
|
||||||
use crate::script_thread::ScriptThread;
|
use crate::script_thread::ScriptThread;
|
||||||
use js::jsapi::{JSContext, JobQueueIsEmpty, JobQueueMayNotBeEmpty};
|
use js::jsapi::{JobQueueIsEmpty, JobQueueMayNotBeEmpty};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -56,17 +56,17 @@ impl MicrotaskQueue {
|
||||||
/// Add a new microtask to this queue. It will be invoked as part of the next
|
/// Add a new microtask to this queue. It will be invoked as part of the next
|
||||||
/// microtask checkpoint.
|
/// microtask checkpoint.
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub unsafe fn enqueue(&self, job: Microtask, cx: *mut JSContext) {
|
pub fn enqueue(&self, job: Microtask, cx: JSContext) {
|
||||||
self.microtask_queue.borrow_mut().push(job);
|
self.microtask_queue.borrow_mut().push(job);
|
||||||
JobQueueMayNotBeEmpty(cx);
|
unsafe { JobQueueMayNotBeEmpty(*cx) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#perform-a-microtask-checkpoint>
|
/// <https://html.spec.whatwg.org/multipage/#perform-a-microtask-checkpoint>
|
||||||
/// Perform a microtask checkpoint, executing all queued microtasks until the queue is empty.
|
/// Perform a microtask checkpoint, executing all queued microtasks until the queue is empty.
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub unsafe fn checkpoint<F>(
|
pub fn checkpoint<F>(
|
||||||
&self,
|
&self,
|
||||||
cx: *mut JSContext,
|
cx: JSContext,
|
||||||
target_provider: F,
|
target_provider: F,
|
||||||
globalscopes: Vec<DomRoot<GlobalScope>>,
|
globalscopes: Vec<DomRoot<GlobalScope>>,
|
||||||
) where
|
) where
|
||||||
|
@ -86,7 +86,7 @@ impl MicrotaskQueue {
|
||||||
|
|
||||||
for (idx, job) in pending_queue.iter().enumerate() {
|
for (idx, job) in pending_queue.iter().enumerate() {
|
||||||
if idx == pending_queue.len() - 1 && self.microtask_queue.borrow().is_empty() {
|
if idx == pending_queue.len() - 1 && self.microtask_queue.borrow().is_empty() {
|
||||||
JobQueueIsEmpty(cx);
|
unsafe { JobQueueIsEmpty(*cx) };
|
||||||
}
|
}
|
||||||
|
|
||||||
match *job {
|
match *job {
|
||||||
|
|
|
@ -172,6 +172,7 @@ unsafe extern "C" fn enqueue_promise_job(
|
||||||
_allocation_site: HandleObject,
|
_allocation_site: HandleObject,
|
||||||
incumbent_global: HandleObject,
|
incumbent_global: HandleObject,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
let cx = JSContext::from_ptr(cx);
|
||||||
wrap_panic(
|
wrap_panic(
|
||||||
AssertUnwindSafe(|| {
|
AssertUnwindSafe(|| {
|
||||||
let microtask_queue = &*(extra as *const MicrotaskQueue);
|
let microtask_queue = &*(extra as *const MicrotaskQueue);
|
||||||
|
@ -179,7 +180,7 @@ unsafe extern "C" fn enqueue_promise_job(
|
||||||
let pipeline = global.pipeline_id();
|
let pipeline = global.pipeline_id();
|
||||||
microtask_queue.enqueue(
|
microtask_queue.enqueue(
|
||||||
Microtask::Promise(EnqueuedPromiseCallback {
|
Microtask::Promise(EnqueuedPromiseCallback {
|
||||||
callback: PromiseJobCallback::new(JSContext::from_ptr(cx), job.get()),
|
callback: PromiseJobCallback::new(cx, job.get()),
|
||||||
pipeline,
|
pipeline,
|
||||||
}),
|
}),
|
||||||
cx,
|
cx,
|
||||||
|
|
|
@ -910,16 +910,13 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#await-a-stable-state
|
// https://html.spec.whatwg.org/multipage/#await-a-stable-state
|
||||||
#[allow(unsafe_code)]
|
|
||||||
pub fn await_stable_state(task: Microtask) {
|
pub fn await_stable_state(task: Microtask) {
|
||||||
SCRIPT_THREAD_ROOT.with(|root| {
|
SCRIPT_THREAD_ROOT.with(|root| {
|
||||||
if let Some(script_thread) = root.get() {
|
if let Some(script_thread) = root.get() {
|
||||||
unsafe {
|
let script_thread = unsafe { &*script_thread };
|
||||||
let script_thread = &*script_thread;
|
script_thread
|
||||||
script_thread
|
.microtask_queue
|
||||||
.microtask_queue
|
.enqueue(task, script_thread.get_cx());
|
||||||
.enqueue(task, *script_thread.get_cx());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3776,17 +3773,15 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
pub fn enqueue_microtask(job: Microtask) {
|
pub fn enqueue_microtask(job: Microtask) {
|
||||||
SCRIPT_THREAD_ROOT.with(|root| unsafe {
|
SCRIPT_THREAD_ROOT.with(|root| {
|
||||||
let script_thread = &*root.get().unwrap();
|
let script_thread = unsafe { &*root.get().unwrap() };
|
||||||
script_thread
|
script_thread
|
||||||
.microtask_queue
|
.microtask_queue
|
||||||
.enqueue(job, *script_thread.get_cx());
|
.enqueue(job, script_thread.get_cx());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
fn perform_a_microtask_checkpoint(&self) {
|
fn perform_a_microtask_checkpoint(&self) {
|
||||||
let globals = self
|
let globals = self
|
||||||
.documents
|
.documents
|
||||||
|
@ -3795,13 +3790,11 @@ impl ScriptThread {
|
||||||
.map(|(_id, document)| document.global())
|
.map(|(_id, document)| document.global())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
unsafe {
|
self.microtask_queue.checkpoint(
|
||||||
self.microtask_queue.checkpoint(
|
self.get_cx(),
|
||||||
*self.get_cx(),
|
|id| self.documents.borrow().find_global(id),
|
||||||
|id| self.documents.borrow().find_global(id),
|
globals,
|
||||||
globals,
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue