diff options
22 files changed, 390 insertions, 235 deletions
diff --git a/components/jstraceable_derive/lib.rs b/components/jstraceable_derive/lib.rs index 527c517ef07..3d3c785d971 100644 --- a/components/jstraceable_derive/lib.rs +++ b/components/jstraceable_derive/lib.rs @@ -41,10 +41,11 @@ fn expand_string(input: &str) -> String { } let tokens = quote! { - impl #impl_generics ::dom::bindings::trace::JSTraceable for #name #ty_generics #where_clause { + #[allow(unsafe_code)] + unsafe impl #impl_generics ::dom::bindings::trace::JSTraceable for #name #ty_generics #where_clause { #[inline] #[allow(unused_variables, unused_imports)] - fn trace(&self, tracer: *mut ::js::jsapi::JSTracer) { + unsafe fn trace(&self, tracer: *mut ::js::jsapi::JSTracer) { use ::dom::bindings::trace::JSTraceable; match *self { #match_body diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 9e6a0f1e528..1b1ef4596d6 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use devtools_traits::{AutoMargins, CONSOLE_API, CachedConsoleMessage, CachedConsoleMessageTypes}; -use devtools_traits::{ComputedNodeLayout, ConsoleAPI, PageError, ScriptToDevtoolsControlMsg}; +use devtools_traits::{ComputedNodeLayout, ConsoleAPI, PageError}; use devtools_traits::{EvaluateJSReply, Modification, NodeInfo, PAGE_ERROR, TimelineMarker}; use devtools_traits::TimelineMarkerType; use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods; @@ -17,6 +17,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::reflector::Reflectable; use dom::bindings::str::DOMString; +use dom::document::AnimationFrameCallback; use dom::element::Element; use dom::globalscope::GlobalScope; use dom::node::{Node, window_from_node}; @@ -253,11 +254,7 @@ pub fn handle_request_animation_frame(documents: &Documents, id: PipelineId, actor_name: String) { if let Some(doc) = documents.find_document(id) { - let devtools_sender = doc.window().upcast::<GlobalScope>().devtools_chan().unwrap().clone(); - doc.request_animation_frame(box move |time| { - let msg = ScriptToDevtoolsControlMsg::FramerateTick(actor_name, time); - devtools_sender.send(msg).unwrap(); - }); + doc.request_animation_frame(AnimationFrameCallback::DevtoolsFramerateTick { actor_name }); } } diff --git a/components/script/docs/JS-Servos-only-GC.md b/components/script/docs/JS-Servos-only-GC.md index e7237853217..c8129241a84 100644 --- a/components/script/docs/JS-Servos-only-GC.md +++ b/components/script/docs/JS-Servos-only-GC.md @@ -122,8 +122,8 @@ which has an area, and the trait provides a way to get that object's area. Now let's look at the `JSTraceable` trait, which we use for tracing: ```rust -pub trait JSTraceable { - fn trace(&self, trc: *mut JSTracer); +pub unsafe trait JSTraceable { + unsafe fn trace(&self, trc: *mut JSTracer); } ``` @@ -182,7 +182,7 @@ pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Ref } impl<T: Reflectable> JSTraceable for JS<T> { - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { trace_reflector(trc, "", unsafe { (**self.ptr).reflector() }); } } diff --git a/components/script/dom/abstractworkerglobalscope.rs b/components/script/dom/abstractworkerglobalscope.rs index e584e41c62a..dc4bf15c89e 100644 --- a/components/script/dom/abstractworkerglobalscope.rs +++ b/components/script/dom/abstractworkerglobalscope.rs @@ -5,6 +5,7 @@ use dom::abstractworker::WorkerScriptMsg; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::Reflectable; +use dom::bindings::trace::JSTraceable; use script_runtime::{ScriptChan, CommonScriptMsg, ScriptPort}; use std::sync::mpsc::{Receiver, Sender}; @@ -17,7 +18,7 @@ pub struct SendableWorkerScriptChan<T: Reflectable> { pub worker: Trusted<T>, } -impl<T: Reflectable + 'static> ScriptChan for SendableWorkerScriptChan<T> { +impl<T: JSTraceable + Reflectable + 'static> ScriptChan for SendableWorkerScriptChan<T> { fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> { self.sender.send((self.worker.clone(), msg)).map_err(|_| ()) } @@ -39,7 +40,7 @@ pub struct WorkerThreadWorkerChan<T: Reflectable> { pub worker: Trusted<T>, } -impl<T: Reflectable + 'static> ScriptChan for WorkerThreadWorkerChan<T> { +impl<T: JSTraceable + Reflectable + 'static> ScriptChan for WorkerThreadWorkerChan<T> { fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> { self.sender .send((self.worker.clone(), WorkerScriptMsg::Common(msg))) diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 528b1213ccb..9ddf3fc46fc 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -105,10 +105,10 @@ impl<T: Reflectable> Deref for JS<T> { } } -impl<T: Reflectable> JSTraceable for JS<T> { - fn trace(&self, trc: *mut JSTracer) { +unsafe impl<T: Reflectable> JSTraceable for JS<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { #[cfg(debug_assertions)] - let trace_str = format!("for {} on heap", unsafe { type_name::<T>() }); + let trace_str = format!("for {} on heap", type_name::<T>()); #[cfg(debug_assertions)] let trace_info = &trace_str[..]; #[cfg(not(debug_assertions))] @@ -116,7 +116,7 @@ impl<T: Reflectable> JSTraceable for JS<T> { trace_reflector(trc, trace_info, - unsafe { (**self.ptr).reflector() }); + (**self.ptr).reflector()); } } diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 8323c6996ae..6da8e9a1c5f 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -15,7 +15,7 @@ //! This is typically derived via a `#[dom_struct]` //! (implies `#[derive(JSTraceable)]`) annotation. //! Non-JS-managed types have an empty inline `trace()` method, -//! achieved via `no_jsmanaged_fields!` or similar. +//! achieved via `unsafe_no_jsmanaged_fields!` or similar. //! 3. For all fields, `Foo::trace()` //! calls `trace()` on the field. //! For example, for fields of type `JS<T>`, `JS<T>::trace()` calls @@ -26,14 +26,14 @@ //! 5. When the GC finishes tracing, it [`finalizes`](../index.html#destruction) //! any reflectors that were not reachable. //! -//! The `no_jsmanaged_fields!()` macro adds an empty implementation of `JSTraceable` to -//! a datatype. +//! The `unsafe_no_jsmanaged_fields!()` macro adds an empty implementation of +//! `JSTraceable` to a datatype. +use app_units::Au; use canvas_traits::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle}; use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle, RepetitionStyle}; use cssparser::RGBA; -use devtools_traits::CSSError; -use devtools_traits::WorkerId; +use devtools_traits::{CSSError, TimelineMarkerType, WorkerId}; use dom::abstractworker::SharedRt; use dom::bindings::cell::DOMRefCell; use dom::bindings::js::{JS, Root}; @@ -70,35 +70,38 @@ use net_traits::response::{Response, ResponseBody}; use net_traits::response::HttpsState; use net_traits::storage_thread::StorageType; use offscreen_gl_context::GLLimits; +use parking_lot::RwLock; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; use script_layout_interface::OpaqueStyleAndLayoutData; use script_layout_interface::reporter::CSSErrorReporter; use script_layout_interface::rpc::LayoutRPC; -use script_runtime::ScriptChan; use script_traits::{TimerEventId, TimerSource, TouchpadPressurePhase}; use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType}; use serde::{Deserialize, Serialize}; use servo_atoms::Atom; use servo_url::ServoUrl; use smallvec::SmallVec; -use std::boxed::FnBox; use std::cell::{Cell, UnsafeCell}; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::hash::{BuildHasher, Hash}; use std::ops::{Deref, DerefMut}; use std::path::PathBuf; use std::rc::Rc; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicBool, AtomicUsize}; use std::sync::mpsc::{Receiver, Sender}; use std::time::{SystemTime, Instant}; use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto}; use style::element_state::*; +use style::font_face::FontFaceRule; +use style::keyframes::Keyframe; use style::media_queries::MediaList; use style::properties::PropertyDeclarationBlock; use style::selector_parser::{PseudoElement, Snapshot}; +use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule}; use style::values::specified::Length; +use style::viewport::ViewportRule; use time::Duration; use url::Origin as UrlOrigin; use uuid::Uuid; @@ -106,18 +109,18 @@ use webrender_traits::{WebGLBufferId, WebGLError, WebGLFramebufferId, WebGLProgr use webrender_traits::{WebGLRenderbufferId, WebGLShaderId, WebGLTextureId}; /// A trait to allow tracing (only) DOM objects. -pub trait JSTraceable { +pub unsafe trait JSTraceable { /// Trace `self`. - fn trace(&self, trc: *mut JSTracer); + unsafe fn trace(&self, trc: *mut JSTracer); } -no_jsmanaged_fields!(CSSError); +unsafe_no_jsmanaged_fields!(CSSError); -no_jsmanaged_fields!(EncodingRef); +unsafe_no_jsmanaged_fields!(EncodingRef); -no_jsmanaged_fields!(Reflector); +unsafe_no_jsmanaged_fields!(Reflector); -no_jsmanaged_fields!(Duration); +unsafe_no_jsmanaged_fields!(Duration); /// Trace a `JSVal`. pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) { @@ -154,40 +157,44 @@ pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: &Heap<*mut JS } } -impl<T: JSTraceable> JSTraceable for Rc<T> { - fn trace(&self, trc: *mut JSTracer) { +unsafe impl<T: JSTraceable> JSTraceable for Rc<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { (**self).trace(trc) } } -impl<T: JSTraceable + ?Sized> JSTraceable for Box<T> { - fn trace(&self, trc: *mut JSTracer) { +unsafe impl<T: JSTraceable> JSTraceable for Arc<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { (**self).trace(trc) } } -impl<T: JSTraceable + Copy> JSTraceable for Cell<T> { - fn trace(&self, trc: *mut JSTracer) { +unsafe impl<T: JSTraceable + ?Sized> JSTraceable for Box<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { + (**self).trace(trc) + } +} + +unsafe impl<T: JSTraceable + Copy> JSTraceable for Cell<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { self.get().trace(trc) } } -impl<T: JSTraceable> JSTraceable for UnsafeCell<T> { - fn trace(&self, trc: *mut JSTracer) { - unsafe { (*self.get()).trace(trc) } +unsafe impl<T: JSTraceable> JSTraceable for UnsafeCell<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { + (*self.get()).trace(trc) } } -impl<T: JSTraceable> JSTraceable for DOMRefCell<T> { - fn trace(&self, trc: *mut JSTracer) { - unsafe { - (*self).borrow_for_gc_trace().trace(trc) - } +unsafe impl<T: JSTraceable> JSTraceable for DOMRefCell<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { + (*self).borrow_for_gc_trace().trace(trc) } } -impl JSTraceable for Heap<*mut JSObject> { - fn trace(&self, trc: *mut JSTracer) { +unsafe impl JSTraceable for Heap<*mut JSObject> { + unsafe fn trace(&self, trc: *mut JSTracer) { if self.get().is_null() { return; } @@ -195,34 +202,34 @@ impl JSTraceable for Heap<*mut JSObject> { } } -impl JSTraceable for Heap<JSVal> { - fn trace(&self, trc: *mut JSTracer) { +unsafe impl JSTraceable for Heap<JSVal> { + unsafe fn trace(&self, trc: *mut JSTracer) { trace_jsval(trc, "heap value", self); } } // XXXManishearth Check if the following three are optimized to no-ops -// if e.trace() is a no-op (e.g it is an no_jsmanaged_fields type) -impl<T: JSTraceable> JSTraceable for Vec<T> { +// if e.trace() is a no-op (e.g it is an unsafe_no_jsmanaged_fields type) +unsafe impl<T: JSTraceable> JSTraceable for Vec<T> { #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { for e in &*self { e.trace(trc); } } } -impl<T: JSTraceable> JSTraceable for VecDeque<T> { +unsafe impl<T: JSTraceable> JSTraceable for VecDeque<T> { #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { for e in &*self { e.trace(trc); } } } -impl<T: JSTraceable> JSTraceable for (T, T, T, T) { - fn trace(&self, trc: *mut JSTracer) { +unsafe impl<T: JSTraceable> JSTraceable for (T, T, T, T) { + unsafe fn trace(&self, trc: *mut JSTracer) { self.0.trace(trc); self.1.trace(trc); self.2.trace(trc); @@ -231,26 +238,26 @@ impl<T: JSTraceable> JSTraceable for (T, T, T, T) { } // XXXManishearth Check if the following three are optimized to no-ops -// if e.trace() is a no-op (e.g it is an no_jsmanaged_fields type) -impl<T: JSTraceable + 'static> JSTraceable for SmallVec<[T; 1]> { +// if e.trace() is a no-op (e.g it is an unsafe_no_jsmanaged_fields type) +unsafe impl<T: JSTraceable + 'static> JSTraceable for SmallVec<[T; 1]> { #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { for e in self.iter() { e.trace(trc); } } } -impl<T: JSTraceable> JSTraceable for Option<T> { +unsafe impl<T: JSTraceable> JSTraceable for Option<T> { #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { self.as_ref().map(|e| e.trace(trc)); } } -impl<T: JSTraceable, U: JSTraceable> JSTraceable for Result<T, U> { +unsafe impl<T: JSTraceable, U: JSTraceable> JSTraceable for Result<T, U> { #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { match *self { Ok(ref inner) => inner.trace(trc), Err(ref inner) => inner.trace(trc), @@ -258,13 +265,13 @@ impl<T: JSTraceable, U: JSTraceable> JSTraceable for Result<T, U> { } } -impl<K, V, S> JSTraceable for HashMap<K, V, S> +unsafe impl<K, V, S> JSTraceable for HashMap<K, V, S> where K: Hash + Eq + JSTraceable, V: JSTraceable, S: BuildHasher { #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { for (k, v) in &*self { k.trace(trc); v.trace(trc); @@ -272,9 +279,21 @@ impl<K, V, S> JSTraceable for HashMap<K, V, S> } } -impl<K: Ord + JSTraceable, V: JSTraceable> JSTraceable for BTreeMap<K, V> { +unsafe impl<T, S> JSTraceable for HashSet<T, S> + where T: Hash + Eq + JSTraceable, + S: BuildHasher +{ #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { + for v in &*self { + v.trace(trc); + } + } +} + +unsafe impl<K: Ord + JSTraceable, V: JSTraceable> JSTraceable for BTreeMap<K, V> { + #[inline] + unsafe fn trace(&self, trc: *mut JSTracer) { for (k, v) in self { k.trace(trc); v.trace(trc); @@ -282,18 +301,18 @@ impl<K: Ord + JSTraceable, V: JSTraceable> JSTraceable for BTreeMap<K, V> { } } -impl<A: JSTraceable, B: JSTraceable> JSTraceable for (A, B) { +unsafe impl<A: JSTraceable, B: JSTraceable> JSTraceable for (A, B) { #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { let (ref a, ref b) = *self; a.trace(trc); b.trace(trc); } } -impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, B, C) { +unsafe impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, B, C) { #[inline] - fn trace(&self, trc: *mut JSTracer) { + unsafe fn trace(&self, trc: *mut JSTracer) { let (ref a, ref b, ref c) = *self; a.trace(trc); b.trace(trc); @@ -301,139 +320,258 @@ impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, B, C) { } } -no_jsmanaged_fields!(bool, f32, f64, String, ServoUrl, AtomicBool, AtomicUsize, UrlOrigin, Uuid, char); -no_jsmanaged_fields!(usize, u8, u16, u32, u64); -no_jsmanaged_fields!(isize, i8, i16, i32, i64); -no_jsmanaged_fields!(Sender<T>); -no_jsmanaged_fields!(Receiver<T>); -no_jsmanaged_fields!(Point2D<T>); -no_jsmanaged_fields!(Rect<T>); -no_jsmanaged_fields!(Size2D<T>); -no_jsmanaged_fields!(Arc<T>); -no_jsmanaged_fields!(Image, ImageMetadata, ImageCacheChan, ImageCacheThread); -no_jsmanaged_fields!(Metadata); -no_jsmanaged_fields!(NetworkError); -no_jsmanaged_fields!(Atom, Prefix, LocalName, Namespace, QualName); -no_jsmanaged_fields!(Trusted<T: Reflectable>); -no_jsmanaged_fields!(TrustedPromise); -no_jsmanaged_fields!(PropertyDeclarationBlock); -no_jsmanaged_fields!(HashSet<T>); +unsafe_no_jsmanaged_fields!(bool, f32, f64, String, ServoUrl, AtomicBool, AtomicUsize, UrlOrigin, Uuid, char); +unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64); +unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64); +unsafe_no_jsmanaged_fields!(Image, ImageMetadata, ImageCacheChan, ImageCacheThread); +unsafe_no_jsmanaged_fields!(Metadata); +unsafe_no_jsmanaged_fields!(NetworkError); +unsafe_no_jsmanaged_fields!(Atom, Prefix, LocalName, Namespace, QualName); +unsafe_no_jsmanaged_fields!(TrustedPromise); +unsafe_no_jsmanaged_fields!(PropertyDeclarationBlock); // These three are interdependent, if you plan to put jsmanaged data // in one of these make sure it is propagated properly to containing structs -no_jsmanaged_fields!(FrameId, FrameType, WindowSizeData, WindowSizeType, PipelineId); -no_jsmanaged_fields!(TimerEventId, TimerSource); -no_jsmanaged_fields!(WorkerId); -no_jsmanaged_fields!(BufferQueue, QuirksMode); -no_jsmanaged_fields!(Runtime); -no_jsmanaged_fields!(Headers, Method); -no_jsmanaged_fields!(WindowProxyHandler); -no_jsmanaged_fields!(UntrustedNodeAddress); -no_jsmanaged_fields!(LengthOrPercentageOrAuto); -no_jsmanaged_fields!(RGBA); -no_jsmanaged_fields!(EuclidLength<Unit, T>); -no_jsmanaged_fields!(Matrix2D<T>); -no_jsmanaged_fields!(Matrix4D<T>); -no_jsmanaged_fields!(StorageType); -no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle); -no_jsmanaged_fields!(LineCapStyle, LineJoinStyle, CompositionOrBlending); -no_jsmanaged_fields!(RepetitionStyle); -no_jsmanaged_fields!(WebGLError, GLLimits); -no_jsmanaged_fields!(TimeProfilerChan); -no_jsmanaged_fields!(MemProfilerChan); -no_jsmanaged_fields!(PseudoElement); -no_jsmanaged_fields!(Length); -no_jsmanaged_fields!(ElementState); -no_jsmanaged_fields!(DOMString); -no_jsmanaged_fields!(Mime); -no_jsmanaged_fields!(AttrIdentifier); -no_jsmanaged_fields!(AttrValue); -no_jsmanaged_fields!(Snapshot); -no_jsmanaged_fields!(PendingRestyle); -no_jsmanaged_fields!(HttpsState); -no_jsmanaged_fields!(Request); -no_jsmanaged_fields!(RequestInit); -no_jsmanaged_fields!(SharedRt); -no_jsmanaged_fields!(TouchpadPressurePhase); -no_jsmanaged_fields!(USVString); -no_jsmanaged_fields!(ReferrerPolicy); -no_jsmanaged_fields!(Response); -no_jsmanaged_fields!(ResponseBody); -no_jsmanaged_fields!(ResourceThreads); -no_jsmanaged_fields!(StatusCode); -no_jsmanaged_fields!(SystemTime); -no_jsmanaged_fields!(Instant); -no_jsmanaged_fields!(RelativePos); -no_jsmanaged_fields!(OpaqueStyleAndLayoutData); -no_jsmanaged_fields!(PathBuf); -no_jsmanaged_fields!(CSSErrorReporter); -no_jsmanaged_fields!(WebGLBufferId); -no_jsmanaged_fields!(WebGLFramebufferId); -no_jsmanaged_fields!(WebGLProgramId); -no_jsmanaged_fields!(WebGLRenderbufferId); -no_jsmanaged_fields!(WebGLShaderId); -no_jsmanaged_fields!(WebGLTextureId); -no_jsmanaged_fields!(MediaList); - -impl JSTraceable for Box<ScriptChan + Send> { +unsafe_no_jsmanaged_fields!(FrameId, FrameType, WindowSizeData, WindowSizeType, PipelineId); +unsafe_no_jsmanaged_fields!(TimerEventId, TimerSource); +unsafe_no_jsmanaged_fields!(TimelineMarkerType); +unsafe_no_jsmanaged_fields!(WorkerId); +unsafe_no_jsmanaged_fields!(BufferQueue, QuirksMode); +unsafe_no_jsmanaged_fields!(Runtime); +unsafe_no_jsmanaged_fields!(Headers, Method); +unsafe_no_jsmanaged_fields!(WindowProxyHandler); +unsafe_no_jsmanaged_fields!(UntrustedNodeAddress); +unsafe_no_jsmanaged_fields!(LengthOrPercentageOrAuto); +unsafe_no_jsmanaged_fields!(RGBA); +unsafe_no_jsmanaged_fields!(StorageType); +unsafe_no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle); +unsafe_no_jsmanaged_fields!(LineCapStyle, LineJoinStyle, CompositionOrBlending); +unsafe_no_jsmanaged_fields!(RepetitionStyle); +unsafe_no_jsmanaged_fields!(WebGLError, GLLimits); +unsafe_no_jsmanaged_fields!(TimeProfilerChan); +unsafe_no_jsmanaged_fields!(MemProfilerChan); +unsafe_no_jsmanaged_fields!(PseudoElement); +unsafe_no_jsmanaged_fields!(Length); +unsafe_no_jsmanaged_fields!(ElementState); +unsafe_no_jsmanaged_fields!(DOMString); +unsafe_no_jsmanaged_fields!(Mime); +unsafe_no_jsmanaged_fields!(AttrIdentifier); +unsafe_no_jsmanaged_fields!(AttrValue); +unsafe_no_jsmanaged_fields!(Snapshot); +unsafe_no_jsmanaged_fields!(PendingRestyle); +unsafe_no_jsmanaged_fields!(HttpsState); +unsafe_no_jsmanaged_fields!(Request); +unsafe_no_jsmanaged_fields!(RequestInit); +unsafe_no_jsmanaged_fields!(SharedRt); +unsafe_no_jsmanaged_fields!(TouchpadPressurePhase); +unsafe_no_jsmanaged_fields!(USVString); +unsafe_no_jsmanaged_fields!(ReferrerPolicy); +unsafe_no_jsmanaged_fields!(Response); +unsafe_no_jsmanaged_fields!(ResponseBody); +unsafe_no_jsmanaged_fields!(ResourceThreads); +unsafe_no_jsmanaged_fields!(StatusCode); +unsafe_no_jsmanaged_fields!(SystemTime); +unsafe_no_jsmanaged_fields!(Instant); +unsafe_no_jsmanaged_fields!(RelativePos); +unsafe_no_jsmanaged_fields!(OpaqueStyleAndLayoutData); +unsafe_no_jsmanaged_fields!(PathBuf); +unsafe_no_jsmanaged_fields!(CSSErrorReporter); +unsafe_no_jsmanaged_fields!(WebGLBufferId); +unsafe_no_jsmanaged_fields!(WebGLFramebufferId); +unsafe_no_jsmanaged_fields!(WebGLProgramId); +unsafe_no_jsmanaged_fields!(WebGLRenderbufferId); +unsafe_no_jsmanaged_fields!(WebGLShaderId); +unsafe_no_jsmanaged_fields!(WebGLTextureId); +unsafe_no_jsmanaged_fields!(MediaList); + +unsafe impl<'a> JSTraceable for &'a str { + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<A, B> JSTraceable for fn(A) -> B { + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T> JSTraceable for IpcSender<T> where T: Deserialize + Serialize { + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +// Safe thanks to the Send bound. +unsafe impl JSTraceable for Box<LayoutRPC + Send + 'static> { + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl JSTraceable for () { + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T> JSTraceable for IpcReceiver<T> where T: Deserialize + Serialize { + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T: Reflectable> JSTraceable for Trusted<T> { + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T: Send> JSTraceable for Receiver<T> { + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T: Send> JSTraceable for Sender<T> { #[inline] - fn trace(&self, _trc: *mut JSTracer) { + unsafe fn trace(&self, _: *mut JSTracer) { // Do nothing } } -impl JSTraceable for Box<FnBox(f64, )> { +unsafe impl JSTraceable for Matrix2D<f32> { #[inline] - fn trace(&self, _trc: *mut JSTracer) { + unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -impl<'a> JSTraceable for &'a str { +unsafe impl JSTraceable for Matrix4D<f64> { #[inline] - fn trace(&self, _: *mut JSTracer) { + unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -impl<A, B> JSTraceable for fn(A) -> B { +unsafe impl JSTraceable for Point2D<f32> { #[inline] - fn trace(&self, _: *mut JSTracer) { + unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -impl<T> JSTraceable for IpcSender<T> where T: Deserialize + Serialize { +unsafe impl<T> JSTraceable for EuclidLength<u64, T> { #[inline] - fn trace(&self, _: *mut JSTracer) { + unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -impl JSTraceable for Box<LayoutRPC + 'static> { +unsafe impl JSTraceable for Rect<Au> { #[inline] - fn trace(&self, _: *mut JSTracer) { + unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -impl JSTraceable for () { +unsafe impl JSTraceable for Rect<f32> { #[inline] - fn trace(&self, _: *mut JSTracer) { + unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -impl<T> JSTraceable for IpcReceiver<T> where T: Deserialize + Serialize { +unsafe impl JSTraceable for Size2D<i32> { #[inline] - fn trace(&self, _: *mut JSTracer) { + unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } +unsafe impl JSTraceable for Mutex<Option<SharedRt>> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<FontFaceRule> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<CssRules> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<Keyframe> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<KeyframesRule> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<MediaRule> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<NamespaceRule> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<StyleRule> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<ViewportRule> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<PropertyDeclarationBlock> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<SharedRt> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + +unsafe impl JSTraceable for RwLock<MediaList> { + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing. + } +} + /// Homemade trait object for JSTraceable things struct TraceableInfo { pub ptr: *const libc::c_void, - pub trace: fn(obj: *const libc::c_void, tracer: *mut JSTracer), + pub trace: unsafe fn(obj: *const libc::c_void, tracer: *mut JSTracer), } /// Holds a set of JSTraceables that need to be rooted @@ -474,8 +612,8 @@ impl RootedTraceableSet { unsafe fn add<T: JSTraceable>(traceable: &T) { ROOTED_TRACEABLES.with(|ref traceables| { - fn trace<T: JSTraceable>(obj: *const libc::c_void, tracer: *mut JSTracer) { - let obj: &T = unsafe { &*(obj as *const T) }; + unsafe fn trace<T: JSTraceable>(obj: *const libc::c_void, tracer: *mut JSTracer) { + let obj: &T = &*(obj as *const T); obj.trace(tracer); } diff --git a/components/script/dom/bindings/weakref.rs b/components/script/dom/bindings/weakref.rs index 761aaf7721c..68feff79180 100644 --- a/components/script/dom/bindings/weakref.rs +++ b/components/script/dom/bindings/weakref.rs @@ -133,7 +133,11 @@ impl<T: WeakReferenceable> PartialEq<T> for WeakRef<T> { } } -no_jsmanaged_fields!(WeakRef<T: WeakReferenceable>); +unsafe impl<T: WeakReferenceable> JSTraceable for WeakRef<T> { + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing. + } +} impl<T: WeakReferenceable> Drop for WeakRef<T> { fn drop(&mut self) { @@ -188,17 +192,15 @@ impl<T: WeakReferenceable> HeapSizeOf for MutableWeakRef<T> { } } -impl<T: WeakReferenceable> JSTraceable for MutableWeakRef<T> { - fn trace(&self, _: *mut JSTracer) { +unsafe impl<T: WeakReferenceable> JSTraceable for MutableWeakRef<T> { + unsafe fn trace(&self, _: *mut JSTracer) { let ptr = self.cell.get(); - unsafe { - let should_drop = match *ptr { - Some(ref value) => !value.is_alive(), - None => false, - }; - if should_drop { - mem::drop((*ptr).take().unwrap()); - } + let should_drop = match *ptr { + Some(ref value) => !value.is_alive(), + None => false, + }; + if should_drop { + mem::drop((*ptr).take().unwrap()); } } } diff --git a/components/script/dom/crypto.rs b/components/script/dom/crypto.rs index 22466f3f14c..4120456c77c 100644 --- a/components/script/dom/crypto.rs +++ b/components/script/dom/crypto.rs @@ -15,7 +15,7 @@ use js::jsapi::{JSContext, JSObject}; use js::jsapi::{JS_GetArrayBufferViewType, Type}; use rand::{OsRng, Rng}; -no_jsmanaged_fields!(OsRng); +unsafe_no_jsmanaged_fields!(OsRng); // https://developer.mozilla.org/en-US/docs/Web/API/Crypto #[dom_struct] diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index 5f594c27d8c..9c55f561806 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -16,8 +16,10 @@ use parking_lot::RwLock; use std::sync::Arc; use style::stylesheets::{CssRules, KeyframesRule, RulesMutateError}; -no_jsmanaged_fields!(RulesSource); -no_jsmanaged_fields!(CssRules); +#[allow(unsafe_code)] +unsafe_no_jsmanaged_fields!(RulesSource); + +unsafe_no_jsmanaged_fields!(CssRules); impl From<RulesMutateError> for Error { fn from(other: RulesMutateError) -> Self { diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 211927bbf9c..68777b70d39 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -3,9 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use core::nonzero::NonZero; +use devtools_traits::ScriptToDevtoolsControlMsg; use document_loader::{DocumentLoader, LoadType}; use dom::activation::{ActivationSource, synthetic_click_activation}; use dom::attr::Attr; +use dom::bindings::callback::ExceptionHandling; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods; use dom::bindings::codegen::Bindings::DocumentBinding; @@ -18,7 +20,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter; use dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceMethods; use dom::bindings::codegen::Bindings::TouchBinding::TouchMethods; -use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, WindowMethods}; +use dom::bindings::codegen::Bindings::WindowBinding::{FrameRequestCallback, ScrollBehavior, WindowMethods}; use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId}; @@ -112,7 +114,6 @@ use servo_atoms::Atom; use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; -use std::boxed::FnBox; use std::cell::{Cell, Ref, RefMut}; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -233,8 +234,7 @@ pub struct Document { animation_frame_ident: Cell<u32>, /// https://html.spec.whatwg.org/multipage/#list-of-animation-frame-callbacks /// List of animation frame callbacks - #[ignore_heap_size_of = "closures are hard"] - animation_frame_list: DOMRefCell<Vec<(u32, Option<Box<FnBox(f64)>>)>>, + animation_frame_list: DOMRefCell<Vec<(u32, Option<AnimationFrameCallback>)>>, /// Whether we're in the process of running animation callbacks. /// /// Tracking this is not necessary for correctness. Instead, it is an optimization to avoid @@ -1461,7 +1461,7 @@ impl Document { } /// https://html.spec.whatwg.org/multipage/#dom-window-requestanimationframe - pub fn request_animation_frame(&self, callback: Box<FnBox(f64)>) -> u32 { + pub fn request_animation_frame(&self, callback: AnimationFrameCallback) -> u32 { let ident = self.animation_frame_ident.get() + 1; self.animation_frame_ident.set(ident); @@ -1502,7 +1502,7 @@ impl Document { for (_, callback) in animation_frame_list.drain(..) { if let Some(callback) = callback { - callback(*timing); + callback.call(self, *timing); } } @@ -3182,3 +3182,29 @@ pub enum FocusEventType { Focus, // Element gained focus. Doesn't bubble. Blur, // Element lost focus. Doesn't bubble. } + +#[derive(HeapSizeOf, JSTraceable)] +pub enum AnimationFrameCallback { + DevtoolsFramerateTick { actor_name: String }, + FrameRequestCallback { + #[ignore_heap_size_of = "Rc is hard"] + callback: Rc<FrameRequestCallback> + }, +} + +impl AnimationFrameCallback { + fn call(&self, document: &Document, now: f64) { + match *self { + AnimationFrameCallback::DevtoolsFramerateTick { ref actor_name } => { + let msg = ScriptToDevtoolsControlMsg::FramerateTick(actor_name.clone(), now); + let devtools_sender = document.window().upcast::<GlobalScope>().devtools_chan().unwrap(); + devtools_sender.send(msg).unwrap(); + } + AnimationFrameCallback::FrameRequestCallback { ref callback } => { + // TODO(jdm): The spec says that any exceptions should be suppressed: + // https://github.com/servo/servo/issues/6928 + let _ = callback.Call__(Finite::wrap(now), ExceptionHandling::Report); + } + } + } +} diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index f0518c55f88..e158caac17e 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -50,7 +50,7 @@ use style::parser::ParserContextExtraData; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::{Stylesheet, Origin}; -no_jsmanaged_fields!(Stylesheet); +unsafe_no_jsmanaged_fields!(Stylesheet); #[dom_struct] pub struct HTMLLinkElement { diff --git a/components/script/dom/keyboardevent.rs b/components/script/dom/keyboardevent.rs index 99cc61e021f..38a25d4dc1e 100644 --- a/components/script/dom/keyboardevent.rs +++ b/components/script/dom/keyboardevent.rs @@ -19,7 +19,7 @@ use msg::constellation_msg::{Key, KeyModifiers}; use std::borrow::Cow; use std::cell::Cell; -no_jsmanaged_fields!(Key); +unsafe_no_jsmanaged_fields!(Key); #[dom_struct] pub struct KeyboardEvent { diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index 53c5bd20115..99b06bae39d 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -302,38 +302,31 @@ macro_rules! make_nonzero_dimension_setter( /// For use on non-jsmanaged types /// Use #[derive(JSTraceable)] on JS managed types -macro_rules! no_jsmanaged_fields( - ([$ty:ident; $count:expr]) => ( - impl $crate::dom::bindings::trace::JSTraceable for [$ty; $count] { - #[inline] - fn trace(&self, _: *mut ::js::jsapi::JSTracer) { - // Do nothing - } - } - ); +macro_rules! unsafe_no_jsmanaged_fields( ($($ty:ident),+) => ( $( - impl $crate::dom::bindings::trace::JSTraceable for $ty { + #[allow(unsafe_code)] + unsafe impl $crate::dom::bindings::trace::JSTraceable for $ty { #[inline] - fn trace(&self, _: *mut ::js::jsapi::JSTracer) { + unsafe fn trace(&self, _: *mut ::js::jsapi::JSTracer) { // Do nothing } } )+ ); - ($ty:ident<$($gen:ident),+>) => ( - impl<$($gen),+> $crate::dom::bindings::trace::JSTraceable for $ty<$($gen),+> { - #[inline] - fn trace(&self, _: *mut ::js::jsapi::JSTracer) { - // Do nothing - } - } - ); - ($ty:ident<$($gen:ident: $bound:ident),+>) => ( - impl<$($gen: $bound),+> $crate::dom::bindings::trace::JSTraceable for $ty<$($gen),+> { +); + +macro_rules! jsmanaged_array( + ($count:expr) => ( + #[allow(unsafe_code)] + unsafe impl<T> $crate::dom::bindings::trace::JSTraceable for [T; $count] + where T: $crate::dom::bindings::trace::JSTraceable + { #[inline] - fn trace(&self, _: *mut ::js::jsapi::JSTracer) { - // Do nothing + unsafe fn trace(&self, tracer: *mut ::js::jsapi::JSTracer) { + for v in self.iter() { + v.trace(tracer); + } } } ); diff --git a/components/script/dom/mediaquerylist.rs b/components/script/dom/mediaquerylist.rs index 8b77bc4155b..86f67cdd8a1 100644 --- a/components/script/dom/mediaquerylist.rs +++ b/components/script/dom/mediaquerylist.rs @@ -143,8 +143,9 @@ impl WeakMediaQueryListVec { } } -impl JSTraceable for WeakMediaQueryListVec { - fn trace(&self, _: *mut JSTracer) { +#[allow(unsafe_code)] +unsafe impl JSTraceable for WeakMediaQueryListVec { + unsafe fn trace(&self, _: *mut JSTracer) { self.cell.borrow_mut().retain_alive() } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index f08b1480eef..5f979bd8c9f 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -2566,7 +2566,7 @@ struct UniqueId { cell: UnsafeCell<Option<Box<Uuid>>>, } -no_jsmanaged_fields!(UniqueId); +unsafe_no_jsmanaged_fields!(UniqueId); impl HeapSizeOf for UniqueId { #[allow(unsafe_code)] diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index b2507aeab3b..723239ea3d3 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -1262,8 +1262,8 @@ impl HeapSizeOf for WeakRangeVec { } #[allow(unsafe_code)] -impl JSTraceable for WeakRangeVec { - fn trace(&self, _: *mut JSTracer) { - unsafe { (*self.cell.get()).retain_alive() } +unsafe impl JSTraceable for WeakRangeVec { + unsafe fn trace(&self, _: *mut JSTracer) { + (*self.cell.get()).retain_alive() } } diff --git a/components/script/dom/servoparser/html.rs b/components/script/dom/servoparser/html.rs index 0f806171a9b..ac6330c3ca2 100644 --- a/components/script/dom/servoparser/html.rs +++ b/components/script/dom/servoparser/html.rs @@ -96,8 +96,9 @@ impl Tokenizer { } } -impl JSTraceable for HtmlTokenizer<TreeBuilder<JS<Node>, Sink>> { - fn trace(&self, trc: *mut JSTracer) { +#[allow(unsafe_code)] +unsafe impl JSTraceable for HtmlTokenizer<TreeBuilder<JS<Node>, Sink>> { + unsafe fn trace(&self, trc: *mut JSTracer) { struct Tracer(*mut JSTracer); let tracer = Tracer(trc); @@ -105,7 +106,7 @@ impl JSTraceable for HtmlTokenizer<TreeBuilder<JS<Node>, Sink>> { type Handle = JS<Node>; #[allow(unrooted_must_root)] fn trace_handle(&self, node: &JS<Node>) { - node.trace(self.0); + unsafe { node.trace(self.0); } } } diff --git a/components/script/dom/servoparser/xml.rs b/components/script/dom/servoparser/xml.rs index 9d527ce21d1..bcbfa6c4169 100644 --- a/components/script/dom/servoparser/xml.rs +++ b/components/script/dom/servoparser/xml.rs @@ -72,8 +72,9 @@ impl Tokenizer { } } -impl JSTraceable for XmlTokenizer<XmlTreeBuilder<JS<Node>, Sink>> { - fn trace(&self, trc: *mut JSTracer) { +#[allow(unsafe_code)] +unsafe impl JSTraceable for XmlTokenizer<XmlTreeBuilder<JS<Node>, Sink>> { + unsafe fn trace(&self, trc: *mut JSTracer) { struct Tracer(*mut JSTracer); let tracer = Tracer(trc); @@ -81,7 +82,7 @@ impl JSTraceable for XmlTokenizer<XmlTreeBuilder<JS<Node>, Sink>> { type Handle = JS<Node>; #[allow(unrooted_must_root)] fn trace_handle(&self, node: JS<Node>) { - node.trace(self.0); + unsafe { node.trace(self.0); } } } diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index 9a1e4663152..ad20a127e17 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -26,7 +26,7 @@ pub enum TexParameterValue { const MAX_LEVEL_COUNT: usize = 31; const MAX_FACE_COUNT: usize = 6; -no_jsmanaged_fields!([ImageInfo; MAX_LEVEL_COUNT * MAX_FACE_COUNT]); +jsmanaged_array!(MAX_LEVEL_COUNT * MAX_FACE_COUNT); #[dom_struct] pub struct WebGLTexture { diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index c09a2111057..31daeec1f9d 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -6,7 +6,6 @@ use app_units::Au; use bluetooth_traits::BluetoothRequest; use cssparser::Parser; use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType}; -use dom::bindings::callback::ExceptionHandling; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState}; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; @@ -30,7 +29,7 @@ use dom::bindings::utils::{GlobalStaticData, WindowProxyHandler}; use dom::browsingcontext::BrowsingContext; use dom::crypto::Crypto; use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration}; -use dom::document::Document; +use dom::document::{AnimationFrameCallback, Document}; use dom::element::Element; use dom::event::Event; use dom::globalscope::GlobalScope; @@ -199,7 +198,7 @@ pub struct Window { /// A handle to perform RPC calls into the layout, quickly. #[ignore_heap_size_of = "trait objects are hard"] - layout_rpc: Box<LayoutRPC + 'static>, + layout_rpc: Box<LayoutRPC + Send + 'static>, /// The current size of the window, in pixels. window_size: Cell<Option<WindowSizeData>>, @@ -601,15 +600,8 @@ impl WindowMethods for Window { /// https://html.spec.whatwg.org/multipage/#dom-window-requestanimationframe fn RequestAnimationFrame(&self, callback: Rc<FrameRequestCallback>) -> u32 { - let doc = self.Document(); - - let callback = move |now: f64| { - // TODO: @jdm The spec says that any exceptions should be suppressed; - // https://github.com/servo/servo/issues/6928 - let _ = callback.Call__(Finite::wrap(now), ExceptionHandling::Report); - }; - - doc.request_animation_frame(Box::new(callback)) + self.Document() + .request_animation_frame(AnimationFrameCallback::FrameRequestCallback { callback }) } /// https://html.spec.whatwg.org/multipage/#dom-window-cancelanimationframe @@ -1568,7 +1560,7 @@ impl Window { parent_info: Option<(PipelineId, FrameType)>, window_size: Option<WindowSizeData>) -> Root<Window> { - let layout_rpc: Box<LayoutRPC> = { + let layout_rpc: Box<LayoutRPC + Send> = { let (rpc_send, rpc_recv) = channel(); layout_chan.send(Msg::GetRPC(rpc_send)).unwrap(); rpc_recv.recv().unwrap() diff --git a/components/script/lib.rs b/components/script/lib.rs index cf3aadf1658..e80e9553956 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -6,7 +6,7 @@ #![feature(conservative_impl_trait)] #![feature(const_fn)] #![feature(core_intrinsics)] -#![feature(fnbox)] +#![feature(field_init_shorthand)] #![feature(mpsc_select)] #![feature(nonzero)] #![feature(on_unimplemented)] diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index 154353c71e8..f65b145c4ec 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -10,7 +10,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::PromiseBinding::PromiseJobCallback; use dom::bindings::js::{Root, RootCollection, RootCollectionPtr, trace_roots}; use dom::bindings::refcounted::{LiveDOMReferences, trace_refcounted_objects}; -use dom::bindings::trace::trace_traceables; +use dom::bindings::trace::{JSTraceable, trace_traceables}; use dom::bindings::utils::DOM_CALLBACKS; use dom::globalscope::GlobalScope; use js::glue::CollectServoSizes; @@ -48,7 +48,7 @@ pub enum CommonScriptMsg { } /// A cloneable interface for communicating with an event loop. -pub trait ScriptChan { +pub trait ScriptChan: JSTraceable { /// Send a message to the associated event loop. fn send(&self, msg: CommonScriptMsg) -> Result<(), ()>; /// Clone this handle. |