diff options
author | yvt <i@yvt.jp> | 2021-07-10 17:24:27 +0900 |
---|---|---|
committer | yvt <i@yvt.jp> | 2021-07-10 17:55:42 +0900 |
commit | 01a7de50ab1843d85295f9dccad7f4c099e7208c (patch) | |
tree | ee53fb6e8889deb7b880ee969e6c662e6128d210 /components/script/dom/bindings/trace.rs | |
parent | ff8d2cdbbfc7a9dc7f38b7dd47cb350fde39388f (diff) | |
parent | 94b613fbdaa2b98f2179fc0bbda13c64e6fa0d38 (diff) | |
download | servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.tar.gz servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.zip |
Merge remote-tracking branch 'upstream/master' into feat-cow-infra
`tests/wpt/web-platform-tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html`
was reverted to the upstream version.
Diffstat (limited to 'components/script/dom/bindings/trace.rs')
-rw-r--r-- | components/script/dom/bindings/trace.rs | 773 |
1 files changed, 607 insertions, 166 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 1bc9c165fb1..02b72fc3c2d 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -1,6 +1,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Utilities for tracing JS-managed values. //! @@ -18,9 +18,9 @@ //! 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 +//! For example, for fields of type `Dom<T>`, `Dom<T>::trace()` calls //! `trace_reflector()`. -//! 4. `trace_reflector()` calls `JS::TraceEdge()` with a +//! 4. `trace_reflector()` calls `Dom::TraceEdge()` with a //! pointer to the `JSObject` for the reflector. This notifies the GC, which //! will add the object to the graph, and will trace that object as well. //! 5. When the GC finishes tracing, it [`finalizes`](../index.html#destruction) @@ -29,85 +29,157 @@ //! The `unsafe_no_jsmanaged_fields!()` macro adds an empty implementation of //! `JSTraceable` to a datatype. +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::error::Error; +use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; +use crate::dom::bindings::reflector::{DomObject, Reflector}; +use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::str::{DOMString, USVString}; +use crate::dom::bindings::utils::WindowProxyHandler; +use crate::dom::gpubuffer::GPUBufferState; +use crate::dom::gpucanvascontext::WebGPUContextId; +use crate::dom::gpucommandencoder::GPUCommandEncoderState; +use crate::dom::htmlimageelement::SourceSet; +use crate::dom::htmlmediaelement::{HTMLMediaElementFetchContext, MediaFrameRenderer}; +use crate::dom::identityhub::Identities; +use crate::script_runtime::{ContextForRequestInterrupt, StreamConsumer}; +use crate::script_thread::IncompleteParserContexts; +use crate::task::TaskBox; use app_units::Au; -use canvas_traits::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle}; -use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle, RepetitionStyle}; +use canvas_traits::canvas::{ + CanvasGradientStop, CanvasId, LinearGradientStyle, RadialGradientStyle, +}; +use canvas_traits::canvas::{ + CompositionOrBlending, Direction, LineCapStyle, LineJoinStyle, RepetitionStyle, TextAlign, + TextBaseline, +}; +use canvas_traits::webgl::WebGLVertexArrayId; +use canvas_traits::webgl::{ + ActiveAttribInfo, ActiveUniformBlockInfo, ActiveUniformInfo, GlType, TexDataType, TexFormat, +}; +use canvas_traits::webgl::{GLLimits, WebGLQueryId, WebGLSamplerId}; +use canvas_traits::webgl::{WebGLBufferId, WebGLChan, WebGLContextId, WebGLError}; +use canvas_traits::webgl::{WebGLFramebufferId, WebGLMsgSender, WebGLPipeline, WebGLProgramId}; +use canvas_traits::webgl::{WebGLReceiver, WebGLRenderbufferId, WebGLSLVersion, WebGLSender}; +use canvas_traits::webgl::{WebGLShaderId, WebGLSyncId, WebGLTextureId, WebGLVersion}; +use content_security_policy::CspList; +use crossbeam_channel::{Receiver, Sender}; use cssparser::RGBA; use devtools_traits::{CSSError, TimelineMarkerType, WorkerId}; -use dom::abstractworker::SharedRt; -use dom::bindings::cell::DOMRefCell; -use dom::bindings::js::{JS, Root}; -use dom::bindings::refcounted::{Trusted, TrustedPromise}; -use dom::bindings::reflector::{DomObject, Reflector}; -use dom::bindings::str::{DOMString, USVString}; -use dom::bindings::utils::WindowProxyHandler; -use dom::document::PendingRestyle; -use encoding::types::EncodingRef; -use euclid::{Matrix2D, Matrix4D, Point2D}; -use euclid::length::Length as EuclidLength; -use euclid::rect::Rect; -use euclid::size::Size2D; -use html5ever::tokenizer::buffer_queue::BufferQueue; -use html5ever_atoms::{Prefix, LocalName, Namespace, QualName}; -use hyper::header::Headers; -use hyper::method::Method; -use hyper::mime::Mime; -use hyper::status::StatusCode; +use embedder_traits::{EventLoopWaker, MediaMetadata}; +use encoding_rs::{Decoder, Encoding}; +use euclid::default::{Point2D, Rect, Rotation3D, Transform2D}; +use euclid::Length as EuclidLength; +use html5ever::buffer_queue::BufferQueue; +use html5ever::{LocalName, Namespace, Prefix, QualName}; +use http::header::HeaderMap; +use hyper::Method; +use hyper::StatusCode; +use indexmap::IndexMap; use ipc_channel::ipc::{IpcReceiver, IpcSender}; -use js::glue::{CallObjectTracer, CallValueTracer}; -use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind}; +use js::glue::{CallObjectTracer, CallScriptTracer, CallStringTracer, CallValueTracer}; +use js::jsapi::{ + GCTraceKindToAscii, Heap, JSObject, JSScript, JSString, JSTracer, JobQueue, TraceKind, +}; use js::jsval::JSVal; -use js::rust::Runtime; -use msg::constellation_msg::{FrameId, FrameType, PipelineId}; -use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; +use js::rust::{GCMethods, Handle, Runtime}; +use js::typedarray::TypedArray; +use js::typedarray::TypedArrayElement; +use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; +use media::WindowGLContext; +use metrics::{InteractiveMetrics, InteractiveWindow}; +use mime::Mime; +use msg::constellation_msg::{ + BlobId, BroadcastChannelRouterId, BrowsingContextId, HistoryStateId, MessagePortId, + MessagePortRouterId, PipelineId, TopLevelBrowsingContextId, +}; +use msg::constellation_msg::{ServiceWorkerId, ServiceWorkerRegistrationId}; use net_traits::filemanager_thread::RelativePos; use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache::{ImageCache, PendingImageId}; -use net_traits::request::{Request, RequestInit}; -use net_traits::response::{Response, ResponseBody}; +use net_traits::request::{CredentialsMode, ParserMetadata, Referrer, Request, RequestBuilder}; use net_traits::response::HttpsState; +use net_traits::response::{Response, ResponseBody}; use net_traits::storage_thread::StorageType; -use offscreen_gl_context::GLLimits; -use parking_lot::RwLock; +use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceFetchTiming, ResourceThreads}; +use parking_lot::{Mutex as ParkMutex, 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::message::PendingRestyle; use script_layout_interface::rpc::LayoutRPC; -use script_traits::{DocumentActivity, TimerEventId, TimerSource, TouchpadPressurePhase}; -use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType}; +use script_layout_interface::StyleAndOpaqueLayoutData; +use script_traits::serializable::BlobImpl; +use script_traits::transferable::MessagePortImpl; +use script_traits::{ + DocumentActivity, DrawAPaintImageResult, MediaSessionActionType, ScriptToConstellationChan, + TimerEventId, TimerSource, UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData, + WindowSizeType, +}; use selectors::matching::ElementSelectorFlags; use serde::{Deserialize, Serialize}; +use servo_arc::Arc as ServoArc; use servo_atoms::Atom; +use servo_media::audio::analyser_node::AnalysisEngine; +use servo_media::audio::buffer_source_node::AudioBuffer; +use servo_media::audio::context::AudioContext; +use servo_media::audio::graph::NodeId; +use servo_media::audio::panner_node::{DistanceModel, PanningModel}; +use servo_media::audio::param::ParamType; +use servo_media::player::audio::AudioRenderer; +use servo_media::player::video::VideoFrame; +use servo_media::player::Player; +use servo_media::streams::registry::MediaStreamId; +use servo_media::streams::MediaStreamType; +use servo_media::webrtc::WebRtcController; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use smallvec::SmallVec; +use std::borrow::Cow; use std::cell::{Cell, RefCell, UnsafeCell}; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::hash::{BuildHasher, Hash}; -use std::ops::{Deref, DerefMut}; +use std::mem; +use std::num::NonZeroU64; +use std::ops::{Deref, DerefMut, Range}; use std::path::PathBuf; use std::rc::Rc; -use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicBool, AtomicUsize}; -use std::sync::mpsc::{Receiver, Sender}; -use std::time::{SystemTime, Instant}; +use std::sync::{Arc, Mutex}; +use std::thread::JoinHandle; +use std::time::{Instant, SystemTime}; +use style::animation::DocumentAnimationSet; use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto}; +use style::author_styles::AuthorStyles; use style::context::QuirksMode; +use style::dom::OpaqueNode; use style::element_state::*; -use style::keyframes::Keyframe; use style::media_queries::MediaList; +use style::properties::style_structs::Font; use style::properties::PropertyDeclarationBlock; use style::selector_parser::{PseudoElement, Snapshot}; -use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked}; -use style::stylesheets::{CssRules, FontFaceRule, KeyframesRule, MediaRule}; -use style::stylesheets::{NamespaceRule, StyleRule, ImportRule, SupportsRule}; +use style::shared_lock::{Locked as StyleLocked, SharedRwLock as StyleSharedRwLock}; +use style::stylesheet_set::{AuthorStylesheetSet, DocumentStylesheetSet}; +use style::stylesheets::keyframes_rule::Keyframe; +use style::stylesheets::{CssRules, FontFaceRule, KeyframesRule, MediaRule, Stylesheet}; +use style::stylesheets::{ImportRule, NamespaceRule, StyleRule, SupportsRule, ViewportRule}; +use style::stylist::CascadeData; use style::values::specified::Length; -use style::viewport::ViewportRule; -use time::Duration; +use tendril::fmt::UTF8; +use tendril::stream::LossyDecoder; +use tendril::{StrTendril, TendrilSink}; +use time::{Duration, Timespec, Tm}; use uuid::Uuid; -use webrender_traits::{WebGLBufferId, WebGLError, WebGLFramebufferId, WebGLProgramId}; -use webrender_traits::{WebGLRenderbufferId, WebGLShaderId, WebGLTextureId}; -use webvr_traits::WebVRGamepadHand; +use webgpu::{ + wgpu::command::{ComputePass, RenderBundleEncoder, RenderPass}, + WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout, WebGPUBuffer, + WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePipeline, WebGPUDevice, + WebGPUPipelineLayout, WebGPUQueue, WebGPURenderBundle, WebGPURenderPipeline, WebGPUSampler, + WebGPUShaderModule, WebGPUTexture, WebGPUTextureView, +}; +use webrender_api::{DocumentId, ExternalImageId, ImageKey}; +use webxr_api::{Finger, Hand, Ray, View}; + +unsafe_no_jsmanaged_fields!(Tm); +unsafe_no_jsmanaged_fields!(JoinHandle<()>); /// A trait to allow tracing (only) DOM objects. pub unsafe trait JSTraceable { @@ -115,14 +187,52 @@ pub unsafe trait JSTraceable { unsafe fn trace(&self, trc: *mut JSTracer); } +unsafe_no_jsmanaged_fields!(Box<dyn TaskBox>, Box<dyn EventLoopWaker>); + +unsafe_no_jsmanaged_fields!(IncompleteParserContexts); + +unsafe_no_jsmanaged_fields!(MessagePortImpl); +unsafe_no_jsmanaged_fields!(MessagePortId); +unsafe_no_jsmanaged_fields!(MessagePortRouterId); + +unsafe_no_jsmanaged_fields!(ServiceWorkerId); +unsafe_no_jsmanaged_fields!(ServiceWorkerRegistrationId); + +unsafe_no_jsmanaged_fields!(BroadcastChannelRouterId); + +unsafe_no_jsmanaged_fields!(BlobId); +unsafe_no_jsmanaged_fields!(BlobImpl); + unsafe_no_jsmanaged_fields!(CSSError); -unsafe_no_jsmanaged_fields!(EncodingRef); +unsafe_no_jsmanaged_fields!(&'static Encoding); + +unsafe_no_jsmanaged_fields!(Decoder); unsafe_no_jsmanaged_fields!(Reflector); unsafe_no_jsmanaged_fields!(Duration); +unsafe_no_jsmanaged_fields!(TexDataType, TexFormat); + +unsafe_no_jsmanaged_fields!(*mut JobQueue); + +unsafe_no_jsmanaged_fields!(Cow<'static, str>); + +unsafe_no_jsmanaged_fields!(CspList); + +/// Trace a `JSScript`. +pub fn trace_script(tracer: *mut JSTracer, description: &str, script: &Heap<*mut JSScript>) { + unsafe { + trace!("tracing {}", description); + CallScriptTracer( + tracer, + script.ptr.get() as *mut _, + GCTraceKindToAscii(TraceKind::Script), + ); + } +} + /// Trace a `JSVal`. pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) { unsafe { @@ -131,9 +241,11 @@ pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) } trace!("tracing value {}", description); - CallValueTracer(tracer, - val.ptr.get() as *mut _, - GCTraceKindToAscii(val.get().trace_kind())); + CallValueTracer( + tracer, + val.ptr.get() as *mut _, + GCTraceKindToAscii(val.get().trace_kind()), + ); } } @@ -148,9 +260,23 @@ pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Ref pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: &Heap<*mut JSObject>) { unsafe { trace!("tracing {}", description); - CallObjectTracer(tracer, - obj.ptr.get() as *mut _, - GCTraceKindToAscii(TraceKind::Object)); + CallObjectTracer( + tracer, + obj.ptr.get() as *mut _, + GCTraceKindToAscii(TraceKind::Object), + ); + } +} + +/// Trace a `JSString`. +pub fn trace_string(tracer: *mut JSTracer, description: &str, s: &Heap<*mut JSString>) { + unsafe { + trace!("tracing {}", description); + CallStringTracer( + tracer, + s.ptr.get() as *mut _, + GCTraceKindToAscii(TraceKind::String), + ); } } @@ -166,12 +292,32 @@ unsafe impl<T: JSTraceable> JSTraceable for Arc<T> { } } +unsafe impl<T: JSTraceable> JSTraceable for ServoArc<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { + (**self).trace(trc) + } +} + +unsafe impl<T: JSTraceable> JSTraceable for RwLock<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { + self.read().trace(trc) + } +} + unsafe impl<T: JSTraceable + ?Sized> JSTraceable for Box<T> { unsafe fn trace(&self, trc: *mut JSTracer) { (**self).trace(trc) } } +unsafe impl<T: JSTraceable> JSTraceable for [T] { + unsafe fn trace(&self, trc: *mut JSTracer) { + for e in self.iter() { + e.trace(trc); + } + } +} + unsafe impl<T: JSTraceable + Copy> JSTraceable for Cell<T> { unsafe fn trace(&self, trc: *mut JSTracer) { self.get().trace(trc) @@ -184,9 +330,24 @@ unsafe impl<T: JSTraceable> JSTraceable for UnsafeCell<T> { } } -unsafe impl<T: JSTraceable> JSTraceable for DOMRefCell<T> { +unsafe impl<T: JSTraceable> JSTraceable for DomRefCell<T> { unsafe fn trace(&self, trc: *mut JSTracer) { - (*self).borrow_for_gc_trace().trace(trc) + (*self).borrow().trace(trc) + } +} + +unsafe impl<T: JSTraceable> JSTraceable for RefCell<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { + (*self).borrow().trace(trc) + } +} + +unsafe impl JSTraceable for Heap<*mut JSScript> { + unsafe fn trace(&self, trc: *mut JSTracer) { + if self.get().is_null() { + return; + } + trace_script(trc, "heap script", self); } } @@ -199,6 +360,15 @@ unsafe impl JSTraceable for Heap<*mut JSObject> { } } +unsafe impl JSTraceable for Heap<*mut JSString> { + unsafe fn trace(&self, trc: *mut JSTracer) { + if self.get().is_null() { + return; + } + trace_string(trc, "heap string", self); + } +} + unsafe impl JSTraceable for Heap<JSVal> { unsafe fn trace(&self, trc: *mut JSTracer) { trace_jsval(trc, "heap value", self); @@ -225,7 +395,22 @@ unsafe impl<T: JSTraceable> JSTraceable for VecDeque<T> { } } -unsafe impl<T: JSTraceable> JSTraceable for (T, T, T, T) { +unsafe impl<T: JSTraceable + Eq + Hash> JSTraceable for indexmap::IndexSet<T> { + #[inline] + unsafe fn trace(&self, trc: *mut JSTracer) { + for e in self.iter() { + e.trace(trc); + } + } +} + +unsafe impl<A, B, C, D> JSTraceable for (A, B, C, D) +where + A: JSTraceable, + B: JSTraceable, + C: JSTraceable, + D: JSTraceable, +{ unsafe fn trace(&self, trc: *mut JSTracer) { self.0.trace(trc); self.1.trace(trc); @@ -263,9 +448,10 @@ unsafe impl<T: JSTraceable, U: JSTraceable> JSTraceable for Result<T, U> { } unsafe impl<K, V, S> JSTraceable for HashMap<K, V, S> - where K: Hash + Eq + JSTraceable, - V: JSTraceable, - S: BuildHasher +where + K: Hash + Eq + JSTraceable, + V: JSTraceable, + S: BuildHasher, { #[inline] unsafe fn trace(&self, trc: *mut JSTracer) { @@ -277,8 +463,9 @@ unsafe impl<K, V, S> JSTraceable for HashMap<K, V, S> } unsafe impl<T, S> JSTraceable for HashSet<T, S> - where T: Hash + Eq + JSTraceable, - S: BuildHasher +where + T: Hash + Eq + JSTraceable, + S: BuildHasher, { #[inline] unsafe fn trace(&self, trc: *mut JSTracer) { @@ -298,6 +485,21 @@ unsafe impl<K: Ord + JSTraceable, V: JSTraceable> JSTraceable for BTreeMap<K, V> } } +unsafe impl<K, V, S> JSTraceable for IndexMap<K, V, S> +where + K: Hash + Eq + JSTraceable, + V: JSTraceable, + S: BuildHasher, +{ + #[inline] + unsafe fn trace(&self, trc: *mut JSTracer) { + for (k, v) in &*self { + k.trace(trc); + v.trace(trc); + } + } +} + unsafe impl<A: JSTraceable, B: JSTraceable> JSTraceable for (A, B) { #[inline] unsafe fn trace(&self, trc: *mut JSTracer) { @@ -317,34 +519,48 @@ unsafe impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, } } +unsafe_no_jsmanaged_fields!(ActiveAttribInfo); +unsafe_no_jsmanaged_fields!(ActiveUniformInfo); +unsafe_no_jsmanaged_fields!(ActiveUniformBlockInfo); unsafe_no_jsmanaged_fields!(bool, f32, f64, String, AtomicBool, AtomicUsize, Uuid, char); unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64); unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64); +unsafe_no_jsmanaged_fields!(NonZeroU64); +unsafe_no_jsmanaged_fields!(Error); unsafe_no_jsmanaged_fields!(ServoUrl, ImmutableOrigin, MutableOrigin); -unsafe_no_jsmanaged_fields!(Image, ImageMetadata, ImageCache, PendingImageId); +unsafe_no_jsmanaged_fields!(Image, ImageMetadata, dyn ImageCache, PendingImageId); 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); +unsafe_no_jsmanaged_fields!(Font); // These three are interdependent, if you plan to put jsmanaged data // in one of these make sure it is propagated properly to containing structs -unsafe_no_jsmanaged_fields!(DocumentActivity, FrameId, FrameType, WindowSizeData, WindowSizeType, PipelineId); +unsafe_no_jsmanaged_fields!(DocumentActivity, WindowSizeData, WindowSizeType); +unsafe_no_jsmanaged_fields!( + BrowsingContextId, + HistoryStateId, + PipelineId, + TopLevelBrowsingContextId +); 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!(BufferQueue, QuirksMode, StrTendril); unsafe_no_jsmanaged_fields!(Runtime); -unsafe_no_jsmanaged_fields!(Headers, Method); +unsafe_no_jsmanaged_fields!(ContextForRequestInterrupt); +unsafe_no_jsmanaged_fields!(HeaderMap, Method); unsafe_no_jsmanaged_fields!(WindowProxyHandler); -unsafe_no_jsmanaged_fields!(UntrustedNodeAddress); +unsafe_no_jsmanaged_fields!(UntrustedNodeAddress, OpaqueNode); 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!(TextAlign, TextBaseline, Direction); unsafe_no_jsmanaged_fields!(RepetitionStyle); -unsafe_no_jsmanaged_fields!(WebGLError, GLLimits); +unsafe_no_jsmanaged_fields!(WebGLError, GLLimits, GlType); unsafe_no_jsmanaged_fields!(TimeProfilerChan); unsafe_no_jsmanaged_fields!(MemProfilerChan); unsafe_no_jsmanaged_fields!(PseudoElement); @@ -357,14 +573,16 @@ unsafe_no_jsmanaged_fields!(AttrIdentifier); unsafe_no_jsmanaged_fields!(AttrValue); unsafe_no_jsmanaged_fields!(Snapshot); unsafe_no_jsmanaged_fields!(PendingRestyle); +unsafe_no_jsmanaged_fields!(Stylesheet); unsafe_no_jsmanaged_fields!(HttpsState); unsafe_no_jsmanaged_fields!(Request); -unsafe_no_jsmanaged_fields!(RequestInit); -unsafe_no_jsmanaged_fields!(SharedRt); +unsafe_no_jsmanaged_fields!(RequestBuilder); unsafe_no_jsmanaged_fields!(StyleSharedRwLock); -unsafe_no_jsmanaged_fields!(TouchpadPressurePhase); unsafe_no_jsmanaged_fields!(USVString); +unsafe_no_jsmanaged_fields!(Referrer); unsafe_no_jsmanaged_fields!(ReferrerPolicy); +unsafe_no_jsmanaged_fields!(CredentialsMode); +unsafe_no_jsmanaged_fields!(ParserMetadata); unsafe_no_jsmanaged_fields!(Response); unsafe_no_jsmanaged_fields!(ResponseBody); unsafe_no_jsmanaged_fields!(ResourceThreads); @@ -372,17 +590,93 @@ 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!(StyleAndOpaqueLayoutData); unsafe_no_jsmanaged_fields!(PathBuf); -unsafe_no_jsmanaged_fields!(CSSErrorReporter); +unsafe_no_jsmanaged_fields!(DrawAPaintImageResult); +unsafe_no_jsmanaged_fields!(DocumentId); +unsafe_no_jsmanaged_fields!(ImageKey); +unsafe_no_jsmanaged_fields!(ExternalImageId); unsafe_no_jsmanaged_fields!(WebGLBufferId); +unsafe_no_jsmanaged_fields!(WebGLChan); unsafe_no_jsmanaged_fields!(WebGLFramebufferId); +unsafe_no_jsmanaged_fields!(WebGLMsgSender); +unsafe_no_jsmanaged_fields!(WebGLPipeline); unsafe_no_jsmanaged_fields!(WebGLProgramId); +unsafe_no_jsmanaged_fields!(WebGLQueryId); unsafe_no_jsmanaged_fields!(WebGLRenderbufferId); +unsafe_no_jsmanaged_fields!(WebGLSamplerId); unsafe_no_jsmanaged_fields!(WebGLShaderId); +unsafe_no_jsmanaged_fields!(WebGLSyncId); unsafe_no_jsmanaged_fields!(WebGLTextureId); +unsafe_no_jsmanaged_fields!(WebGLVertexArrayId); +unsafe_no_jsmanaged_fields!(WebGLVersion); +unsafe_no_jsmanaged_fields!(WebGLSLVersion); +unsafe_no_jsmanaged_fields!(Arc<ParkMutex<Identities>>); +unsafe_no_jsmanaged_fields!(WebGPU); +unsafe_no_jsmanaged_fields!(WebGPUAdapter); +unsafe_no_jsmanaged_fields!(WebGPUBuffer); +unsafe_no_jsmanaged_fields!(WebGPUBindGroup); +unsafe_no_jsmanaged_fields!(WebGPUBindGroupLayout); +unsafe_no_jsmanaged_fields!(WebGPUComputePipeline); +unsafe_no_jsmanaged_fields!(WebGPURenderPipeline); +unsafe_no_jsmanaged_fields!(WebGPURenderBundle); +unsafe_no_jsmanaged_fields!(WebGPUPipelineLayout); +unsafe_no_jsmanaged_fields!(WebGPUQueue); +unsafe_no_jsmanaged_fields!(WebGPUShaderModule); +unsafe_no_jsmanaged_fields!(WebGPUSampler); +unsafe_no_jsmanaged_fields!(WebGPUTexture); +unsafe_no_jsmanaged_fields!(WebGPUTextureView); +unsafe_no_jsmanaged_fields!(WebGPUContextId); +unsafe_no_jsmanaged_fields!(WebGPUCommandBuffer); +unsafe_no_jsmanaged_fields!(WebGPUCommandEncoder); +unsafe_no_jsmanaged_fields!(WebGPUDevice); +unsafe_no_jsmanaged_fields!(Option<RenderPass>); +unsafe_no_jsmanaged_fields!(Option<RenderBundleEncoder>); +unsafe_no_jsmanaged_fields!(Option<ComputePass>); +unsafe_no_jsmanaged_fields!(GPUBufferState); +unsafe_no_jsmanaged_fields!(GPUCommandEncoderState); +unsafe_no_jsmanaged_fields!(Range<u64>); unsafe_no_jsmanaged_fields!(MediaList); -unsafe_no_jsmanaged_fields!(WebVRGamepadHand); +unsafe_no_jsmanaged_fields!( + webxr_api::Registry, + webxr_api::Session, + webxr_api::Frame, + webxr_api::LayerId, + webxr_api::InputSource, + webxr_api::InputId, + webxr_api::Joint, + webxr_api::HitTestId, + webxr_api::HitTestResult +); +unsafe_no_jsmanaged_fields!(ScriptToConstellationChan); +unsafe_no_jsmanaged_fields!(InteractiveMetrics); +unsafe_no_jsmanaged_fields!(InteractiveWindow); +unsafe_no_jsmanaged_fields!(CanvasId); +unsafe_no_jsmanaged_fields!(SourceSet); +unsafe_no_jsmanaged_fields!(AudioBuffer); +unsafe_no_jsmanaged_fields!(Arc<Mutex<AudioContext>>); +unsafe_no_jsmanaged_fields!(NodeId); +unsafe_no_jsmanaged_fields!(AnalysisEngine, DistanceModel, PanningModel, ParamType); +unsafe_no_jsmanaged_fields!(Arc<Mutex<dyn Player>>); +unsafe_no_jsmanaged_fields!(WebRtcController); +unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType); +unsafe_no_jsmanaged_fields!(Mutex<MediaFrameRenderer>); +unsafe_no_jsmanaged_fields!(ResourceFetchTiming); +unsafe_no_jsmanaged_fields!(Timespec); +unsafe_no_jsmanaged_fields!(HTMLMediaElementFetchContext); +unsafe_no_jsmanaged_fields!(Rotation3D<f64>, Transform2D<f32>); +unsafe_no_jsmanaged_fields!(Point2D<f32>, Rect<Au>); +unsafe_no_jsmanaged_fields!(Rect<f32>); +unsafe_no_jsmanaged_fields!(CascadeData); +unsafe_no_jsmanaged_fields!(WindowGLContext); +unsafe_no_jsmanaged_fields!(VideoFrame); +unsafe_no_jsmanaged_fields!(WebGLContextId); +unsafe_no_jsmanaged_fields!(Arc<Mutex<dyn AudioRenderer>>); +unsafe_no_jsmanaged_fields!(MediaSessionActionType); +unsafe_no_jsmanaged_fields!(MediaMetadata); +unsafe_no_jsmanaged_fields!(WebrenderIpcSender); +unsafe_no_jsmanaged_fields!(StreamConsumer); +unsafe_no_jsmanaged_fields!(DocumentAnimationSet); unsafe impl<'a> JSTraceable for &'a str { #[inline] @@ -398,7 +692,10 @@ unsafe impl<A, B> JSTraceable for fn(A) -> B { } } -unsafe impl<T> JSTraceable for IpcSender<T> where T: Deserialize + Serialize { +unsafe impl<T> JSTraceable for IpcSender<T> +where + T: for<'de> Deserialize<'de> + Serialize, +{ #[inline] unsafe fn trace(&self, _: *mut JSTracer) { // Do nothing @@ -406,7 +703,7 @@ unsafe impl<T> JSTraceable for IpcSender<T> where T: Deserialize + Serialize { } // Safe thanks to the Send bound. -unsafe impl JSTraceable for Box<LayoutRPC + Send + 'static> { +unsafe impl JSTraceable for Box<dyn LayoutRPC + Send + 'static> { #[inline] unsafe fn trace(&self, _: *mut JSTracer) { // Do nothing @@ -420,7 +717,10 @@ unsafe impl JSTraceable for () { } } -unsafe impl<T> JSTraceable for IpcReceiver<T> where T: Deserialize + Serialize { +unsafe impl<T> JSTraceable for IpcReceiver<T> +where + T: for<'de> Deserialize<'de> + Serialize, +{ #[inline] unsafe fn trace(&self, _: *mut JSTracer) { // Do nothing @@ -448,21 +748,62 @@ unsafe impl<T: Send> JSTraceable for Sender<T> { } } -unsafe impl JSTraceable for Matrix2D<f32> { +unsafe impl<T: Send> JSTraceable for WebGLReceiver<T> +where + T: for<'de> Deserialize<'de> + Serialize, +{ + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T: Send> JSTraceable for WebGLSender<T> +where + T: for<'de> Deserialize<'de> + Serialize, +{ + #[inline] + unsafe fn trace(&self, _: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<U> JSTraceable for euclid::Vector2D<f32, U> { #[inline] unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -unsafe impl JSTraceable for Matrix4D<f64> { +unsafe impl<T, U> JSTraceable for euclid::Scale<f32, T, U> { #[inline] unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -unsafe impl JSTraceable for Point2D<f32> { +unsafe impl<T, U> JSTraceable for euclid::RigidTransform3D<f32, T, U> { + #[inline] + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T, U> JSTraceable for euclid::RigidTransform3D<f64, T, U> { + #[inline] + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T, U> JSTraceable for euclid::Transform3D<f32, T, U> { + #[inline] + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<T, U> JSTraceable for euclid::Transform3D<f64, T, U> { #[inline] unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing @@ -476,30 +817,45 @@ unsafe impl<T> JSTraceable for EuclidLength<u64, T> { } } -unsafe impl JSTraceable for Rect<Au> { +unsafe impl<U> JSTraceable for euclid::Size2D<i32, U> { #[inline] unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -unsafe impl JSTraceable for Rect<f32> { +unsafe impl<U> JSTraceable for euclid::Size2D<f32, U> { #[inline] unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -unsafe impl JSTraceable for Size2D<i32> { +unsafe impl<U> JSTraceable for euclid::Size2D<u32, U> { #[inline] unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing } } -unsafe impl JSTraceable for Mutex<Option<SharedRt>> { +unsafe impl<U> JSTraceable for euclid::Rect<i32, U> { + #[inline] unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. + // Do nothing + } +} + +unsafe impl<Space> JSTraceable for Ray<Space> { + #[inline] + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing + } +} + +unsafe impl<Eye> JSTraceable for View<Eye> { + #[inline] + unsafe fn trace(&self, _trc: *mut JSTracer) { + // Do nothing } } @@ -569,50 +925,144 @@ unsafe impl JSTraceable for StyleLocked<PropertyDeclarationBlock> { } } -unsafe impl JSTraceable for RwLock<SharedRt> { +unsafe impl JSTraceable for StyleLocked<MediaList> { unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing. } } -unsafe impl JSTraceable for StyleLocked<MediaList> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. +unsafe impl<T> JSTraceable for TypedArray<T, Box<Heap<*mut JSObject>>> +where + T: TypedArrayElement, +{ + unsafe fn trace(&self, trc: *mut JSTracer) { + self.underlying_object().trace(trc); + } +} + +unsafe impl<S> JSTraceable for DocumentStylesheetSet<S> +where + S: JSTraceable + ::style::stylesheets::StylesheetInDocument + PartialEq + 'static, +{ + unsafe fn trace(&self, tracer: *mut JSTracer) { + for (s, _origin) in self.iter() { + s.trace(tracer) + } + } +} + +unsafe impl<S> JSTraceable for AuthorStylesheetSet<S> +where + S: JSTraceable + ::style::stylesheets::StylesheetInDocument + PartialEq + 'static, +{ + unsafe fn trace(&self, tracer: *mut JSTracer) { + for s in self.iter() { + s.trace(tracer) + } + } +} + +unsafe impl<S> JSTraceable for AuthorStyles<S> +where + S: JSTraceable + ::style::stylesheets::StylesheetInDocument + PartialEq + 'static, +{ + unsafe fn trace(&self, tracer: *mut JSTracer) { + self.stylesheets.trace(tracer) + } +} + +unsafe impl<Sink> JSTraceable for LossyDecoder<Sink> +where + Sink: JSTraceable + TendrilSink<UTF8>, +{ + unsafe fn trace(&self, tracer: *mut JSTracer) { + self.inner_sink().trace(tracer); + } +} + +unsafe impl<J> JSTraceable for Hand<J> +where + J: JSTraceable, +{ + #[inline] + unsafe fn trace(&self, trc: *mut JSTracer) { + // exhaustive match so we don't miss new fields + let Hand { + ref wrist, + ref thumb_metacarpal, + ref thumb_phalanx_proximal, + ref thumb_phalanx_distal, + ref thumb_phalanx_tip, + ref index, + ref middle, + ref ring, + ref little, + } = *self; + wrist.trace(trc); + thumb_metacarpal.trace(trc); + thumb_phalanx_proximal.trace(trc); + thumb_phalanx_distal.trace(trc); + thumb_phalanx_tip.trace(trc); + index.trace(trc); + middle.trace(trc); + ring.trace(trc); + little.trace(trc); + } +} + +unsafe impl<J> JSTraceable for Finger<J> +where + J: JSTraceable, +{ + #[inline] + unsafe fn trace(&self, trc: *mut JSTracer) { + // exhaustive match so we don't miss new fields + let Finger { + ref metacarpal, + ref phalanx_proximal, + ref phalanx_intermediate, + ref phalanx_distal, + ref phalanx_tip, + } = *self; + metacarpal.trace(trc); + phalanx_proximal.trace(trc); + phalanx_intermediate.trace(trc); + phalanx_distal.trace(trc); + phalanx_tip.trace(trc); } } /// Holds a set of JSTraceables that need to be rooted struct RootedTraceableSet { - set: Vec<*const JSTraceable>, + set: Vec<*const dyn JSTraceable>, } thread_local!( /// TLV Holds a set of JSTraceables that need to be rooted - static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = - RefCell::new(RootedTraceableSet::new()); + static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = RefCell::new(RootedTraceableSet::new()); ); impl RootedTraceableSet { fn new() -> RootedTraceableSet { - RootedTraceableSet { - set: vec![], - } + RootedTraceableSet { set: vec![] } } - unsafe fn remove(traceable: *const JSTraceable) { + unsafe fn remove(traceable: *const dyn JSTraceable) { ROOTED_TRACEABLES.with(|ref traceables| { let mut traceables = traceables.borrow_mut(); - let idx = - match traceables.set.iter() - .rposition(|x| *x == traceable) { - Some(idx) => idx, - None => unreachable!(), - }; + let idx = match traceables + .set + .iter() + .rposition(|x| *x as *const () == traceable as *const ()) + { + Some(idx) => idx, + None => unreachable!(), + }; traceables.set.remove(idx); }); } - unsafe fn add(traceable: *const JSTraceable) { + unsafe fn add(traceable: *const dyn JSTraceable) { ROOTED_TRACEABLES.with(|ref traceables| { traceables.borrow_mut().set.push(traceable); }) @@ -627,41 +1077,11 @@ impl RootedTraceableSet { /// Roots any JSTraceable thing /// -/// If you have a valid DomObject, use Root. -/// If you have GC things like *mut JSObject or JSVal, use rooted!. -/// If you have an arbitrary number of DomObjects to root, use rooted_vec!. -/// If you know what you're doing, use this. -#[derive(JSTraceable)] -pub struct RootedTraceable<'a, T: 'static + JSTraceable> { - ptr: &'a T, -} - -impl<'a, T: JSTraceable + 'static> RootedTraceable<'a, T> { - /// Root a JSTraceable thing for the life of this RootedTraceable - pub fn new(traceable: &'a T) -> RootedTraceable<'a, T> { - unsafe { - RootedTraceableSet::add(traceable); - } - RootedTraceable { - ptr: traceable, - } - } -} - -impl<'a, T: JSTraceable + 'static> Drop for RootedTraceable<'a, T> { - fn drop(&mut self) { - unsafe { - RootedTraceableSet::remove(self.ptr); - } - } -} - -/// Roots any JSTraceable thing -/// -/// If you have a valid DomObject, use Root. +/// If you have a valid DomObject, use DomRoot. /// If you have GC things like *mut JSObject or JSVal, use rooted!. /// If you have an arbitrary number of DomObjects to root, use rooted_vec!. /// If you know what you're doing, use this. +#[unrooted_must_root_lint::allow_unrooted_interior] pub struct RootedTraceableBox<T: 'static + JSTraceable> { ptr: *mut T, } @@ -673,32 +1093,58 @@ unsafe impl<T: JSTraceable + 'static> JSTraceable for RootedTraceableBox<T> { } impl<T: JSTraceable + 'static> RootedTraceableBox<T> { - /// Root a JSTraceable thing for the life of this RootedTraceable + /// DomRoot a JSTraceable thing for the life of this RootedTraceableBox pub fn new(traceable: T) -> RootedTraceableBox<T> { - let traceable = Box::into_raw(box traceable); + Self::from_box(Box::new(traceable)) + } + + /// Consumes a boxed JSTraceable and roots it for the life of this RootedTraceableBox. + pub fn from_box(boxed_traceable: Box<T>) -> RootedTraceableBox<T> { + let traceable = Box::into_raw(boxed_traceable); unsafe { RootedTraceableSet::add(traceable); } - RootedTraceableBox { - ptr: traceable, - } + RootedTraceableBox { ptr: traceable } + } +} + +impl<T> RootedTraceableBox<Heap<T>> +where + Heap<T>: JSTraceable + 'static, + T: GCMethods + Copy, +{ + pub fn handle(&self) -> Handle<T> { + unsafe { Handle::from_raw((*self.ptr).handle()) } + } +} + +impl<T: JSTraceable + MallocSizeOf> MallocSizeOf for RootedTraceableBox<T> { + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + // Briefly resurrect the real Box value so we can rely on the existing calculations. + // Then immediately forget about it again to avoid dropping the box. + let inner = unsafe { Box::from_raw(self.ptr) }; + let size = inner.size_of(ops); + mem::forget(inner); + size + } +} + +impl<T: JSTraceable + Default> Default for RootedTraceableBox<T> { + fn default() -> RootedTraceableBox<T> { + RootedTraceableBox::new(T::default()) } } impl<T: JSTraceable> Deref for RootedTraceableBox<T> { type Target = T; fn deref(&self) -> &T { - unsafe { - &*self.ptr - } + unsafe { &*self.ptr } } } impl<T: JSTraceable> DerefMut for RootedTraceableBox<T> { fn deref_mut(&mut self) -> &mut T { - unsafe { - &mut *self.ptr - } + unsafe { &mut *self.ptr } } } @@ -714,10 +1160,10 @@ impl<T: JSTraceable + 'static> Drop for RootedTraceableBox<T> { /// A vector of items to be rooted with `RootedVec`. /// Guaranteed to be empty when not rooted. /// Usage: `rooted_vec!(let mut v);` or if you have an -/// iterator of `Root`s, `rooted_vec!(let v <- iterator);`. +/// iterator of `DomRoot`s, `rooted_vec!(let v <- iterator);`. #[allow(unrooted_must_root)] #[derive(JSTraceable)] -#[allow_unrooted_interior] +#[unrooted_must_root_lint::allow_unrooted_interior] pub struct RootableVec<T: JSTraceable> { v: Vec<T>, } @@ -725,14 +1171,12 @@ pub struct RootableVec<T: JSTraceable> { impl<T: JSTraceable> RootableVec<T> { /// Create a vector of items of type T that can be rooted later. pub fn new_unrooted() -> RootableVec<T> { - RootableVec { - v: vec![], - } + RootableVec { v: vec![] } } } /// A vector of items that are rooted for the lifetime 'a. -#[allow_unrooted_interior] +#[unrooted_must_root_lint::allow_unrooted_interior] pub struct RootedVec<'a, T: 'static + JSTraceable> { root: &'a mut RootableVec<T>, } @@ -744,25 +1188,22 @@ impl<'a, T: 'static + JSTraceable> RootedVec<'a, T> { unsafe { RootedTraceableSet::add(root); } - RootedVec { - root: root, - } + RootedVec { root: root } } } -impl<'a, T: 'static + JSTraceable + DomObject> RootedVec<'a, JS<T>> { - /// Create a vector of items of type JS<T> that is rooted for +impl<'a, T: 'static + JSTraceable + DomObject> RootedVec<'a, Dom<T>> { + /// Create a vector of items of type Dom<T> that is rooted for /// the lifetime of this struct - pub fn from_iter<I>(root: &'a mut RootableVec<JS<T>>, iter: I) -> Self - where I: Iterator<Item = Root<T>> + pub fn from_iter<I>(root: &'a mut RootableVec<Dom<T>>, iter: I) -> Self + where + I: Iterator<Item = DomRoot<T>>, { unsafe { RootedTraceableSet::add(root); } - root.v.extend(iter.map(|item| JS::from_ref(&*item))); - RootedVec { - root: root, - } + root.v.extend(iter.map(|item| Dom::from_ref(&*item))); + RootedVec { root: root } } } |