Use safe JSContext in MicrotaskQueue

This commit is contained in:
marmeladema 2019-07-27 17:45:17 +01:00
parent b18fa8b8a7
commit 6d444afd9e
4 changed files with 27 additions and 39 deletions

View file

@ -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

View file

@ -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 {

View file

@ -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,

View file

@ -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, )
)
}
} }
} }