mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Move CustomTraceable to script_bindings. (#35988)
* script: Move CustomTraceable to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Move record binding support to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Address clippy warnings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
d35da38a2f
commit
c8d8787959
15 changed files with 340 additions and 277 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -6382,22 +6382,30 @@ name = "script_bindings"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.0",
|
"bitflags 2.9.0",
|
||||||
|
"crossbeam-channel",
|
||||||
"cssparser",
|
"cssparser",
|
||||||
"html5ever",
|
"html5ever",
|
||||||
|
"indexmap",
|
||||||
"jstraceable_derive",
|
"jstraceable_derive",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"malloc_size_of_derive",
|
"malloc_size_of_derive",
|
||||||
"mozjs",
|
"mozjs",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"parking_lot",
|
||||||
"phf_codegen",
|
"phf_codegen",
|
||||||
"phf_shared",
|
"phf_shared",
|
||||||
"regex",
|
"regex",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"servo_arc",
|
||||||
"servo_config",
|
"servo_config",
|
||||||
"servo_malloc_size_of",
|
"servo_malloc_size_of",
|
||||||
|
"smallvec",
|
||||||
"style",
|
"style",
|
||||||
"stylo_atoms",
|
"stylo_atoms",
|
||||||
|
"tendril",
|
||||||
|
"webxr-api",
|
||||||
|
"xml5ever",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -42,7 +42,7 @@ use js::glue::GetProxyReservedSlot;
|
||||||
use js::jsapi::{Heap, IsWindowProxy, JS_IsExceptionPending, JSContext, JSObject};
|
use js::jsapi::{Heap, IsWindowProxy, JS_IsExceptionPending, JSContext, JSObject};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::wrappers::{IsArrayObject, JS_GetProperty, JS_HasProperty};
|
use js::rust::wrappers::{IsArrayObject, JS_GetProperty, JS_HasProperty};
|
||||||
use js::rust::{HandleId, HandleObject, HandleValue, MutableHandleValue};
|
use js::rust::{HandleObject, HandleValue, MutableHandleValue};
|
||||||
use num_traits::Float;
|
use num_traits::Float;
|
||||||
pub(crate) use script_bindings::conversions::*;
|
pub(crate) use script_bindings::conversions::*;
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ use crate::dom::bindings::error::{Error, Fallible};
|
||||||
use crate::dom::bindings::num::Finite;
|
use crate::dom::bindings::num::Finite;
|
||||||
use crate::dom::bindings::reflector::DomObject;
|
use crate::dom::bindings::reflector::DomObject;
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::DOMString;
|
|
||||||
use crate::dom::bindings::trace::{JSTraceable, RootedTraceableBox};
|
use crate::dom::bindings::trace::{JSTraceable, RootedTraceableBox};
|
||||||
use crate::dom::bindings::utils::DOMClass;
|
use crate::dom::bindings::utils::DOMClass;
|
||||||
use crate::dom::filelist::FileList;
|
use crate::dom::filelist::FileList;
|
||||||
|
@ -122,24 +121,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert `id` to a `DOMString`. Returns `None` if `id` is not a string or
|
|
||||||
/// integer.
|
|
||||||
///
|
|
||||||
/// Handling of invalid UTF-16 in strings depends on the relevant option.
|
|
||||||
pub(crate) unsafe fn jsid_to_string(cx: *mut JSContext, id: HandleId) -> Option<DOMString> {
|
|
||||||
let id_raw = *id;
|
|
||||||
if id_raw.is_string() {
|
|
||||||
let jsstr = std::ptr::NonNull::new(id_raw.to_string()).unwrap();
|
|
||||||
return Some(jsstring_to_str(cx, jsstr));
|
|
||||||
}
|
|
||||||
|
|
||||||
if id_raw.is_int() {
|
|
||||||
return Some(id_raw.to_int().to_string().into());
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) use script_bindings::conversions::is_dom_proxy;
|
pub(crate) use script_bindings::conversions::is_dom_proxy;
|
||||||
|
|
||||||
/// Get a `*const libc::c_void` for the given DOM object, unless it is a DOM
|
/// Get a `*const libc::c_void` for the given DOM object, unless it is a DOM
|
||||||
|
|
|
@ -99,6 +99,7 @@ pub(crate) mod module {
|
||||||
JSCLASS_RESERVED_SLOTS_MASK, jsapi, typedarray,
|
JSCLASS_RESERVED_SLOTS_MASK, jsapi, typedarray,
|
||||||
};
|
};
|
||||||
pub(crate) use script_bindings::constant::{ConstantSpec, ConstantVal};
|
pub(crate) use script_bindings::constant::{ConstantSpec, ConstantVal};
|
||||||
|
pub(crate) use script_bindings::record::Record;
|
||||||
pub(crate) use servo_config::pref;
|
pub(crate) use servo_config::pref;
|
||||||
|
|
||||||
pub(crate) use super::base::*;
|
pub(crate) use super::base::*;
|
||||||
|
@ -144,7 +145,6 @@ pub(crate) mod module {
|
||||||
pub(crate) use crate::dom::bindings::proxyhandler::{
|
pub(crate) use crate::dom::bindings::proxyhandler::{
|
||||||
ensure_expando_object, get_expando_object, set_property_descriptor,
|
ensure_expando_object, get_expando_object, set_property_descriptor,
|
||||||
};
|
};
|
||||||
pub(crate) use crate::dom::bindings::record::Record;
|
|
||||||
pub(crate) use crate::dom::bindings::reflector::{
|
pub(crate) use crate::dom::bindings::reflector::{
|
||||||
DomObjectIteratorWrap, DomObjectWrap, Reflector,
|
DomObjectIteratorWrap, DomObjectWrap, Reflector,
|
||||||
};
|
};
|
||||||
|
|
|
@ -154,7 +154,6 @@ pub(crate) mod namespace;
|
||||||
pub(crate) mod num;
|
pub(crate) mod num;
|
||||||
pub(crate) mod principals;
|
pub(crate) mod principals;
|
||||||
pub(crate) mod proxyhandler;
|
pub(crate) mod proxyhandler;
|
||||||
pub(crate) mod record;
|
|
||||||
pub(crate) mod refcounted;
|
pub(crate) mod refcounted;
|
||||||
pub(crate) mod reflector;
|
pub(crate) mod reflector;
|
||||||
pub(crate) mod root;
|
pub(crate) mod root;
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
//! The `unsafe_no_jsmanaged_fields!()` macro adds an empty implementation of
|
//! The `unsafe_no_jsmanaged_fields!()` macro adds an empty implementation of
|
||||||
//! `JSTraceable` to a datatype.
|
//! `JSTraceable` to a datatype.
|
||||||
|
|
||||||
use std::cell::OnceCell;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::RandomState;
|
use std::collections::hash_map::RandomState;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
@ -37,8 +36,6 @@ use std::hash::{BuildHasher, Hash};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use crossbeam_channel::Sender;
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
/// A trait to allow tracing (only) DOM objects.
|
/// A trait to allow tracing (only) DOM objects.
|
||||||
pub(crate) use js::gc::Traceable as JSTraceable;
|
pub(crate) use js::gc::Traceable as JSTraceable;
|
||||||
pub(crate) use js::gc::{RootableVec, RootedVec};
|
pub(crate) use js::gc::{RootableVec, RootedVec};
|
||||||
|
@ -47,17 +44,7 @@ use js::jsapi::{GCTraceKindToAscii, Heap, JSScript, JSString, JSTracer, TraceKin
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
use js::rust::{GCMethods, Handle};
|
use js::rust::{GCMethods, Handle};
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
use parking_lot::RwLock;
|
|
||||||
pub(crate) use script_bindings::trace::*;
|
pub(crate) use script_bindings::trace::*;
|
||||||
use servo_arc::Arc as ServoArc;
|
|
||||||
use smallvec::SmallVec;
|
|
||||||
use style::author_styles::AuthorStyles;
|
|
||||||
use style::stylesheet_set::{AuthorStylesheetSet, DocumentStylesheetSet};
|
|
||||||
use tendril::TendrilSink;
|
|
||||||
use tendril::fmt::UTF8;
|
|
||||||
use tendril::stream::LossyDecoder;
|
|
||||||
#[cfg(feature = "webxr")]
|
|
||||||
use webxr_api::{Finger, Hand};
|
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
|
@ -69,48 +56,12 @@ use crate::script_runtime::StreamConsumer;
|
||||||
use crate::script_thread::IncompleteParserContexts;
|
use crate::script_thread::IncompleteParserContexts;
|
||||||
use crate::task::TaskBox;
|
use crate::task::TaskBox;
|
||||||
|
|
||||||
/// A trait to allow tracing only DOM sub-objects.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// This trait is unsafe; if it is implemented incorrectly, the GC may end up collecting objects
|
|
||||||
/// that are still reachable.
|
|
||||||
pub(crate) unsafe trait CustomTraceable {
|
|
||||||
/// Trace `self`.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The `JSTracer` argument must point to a valid `JSTracer` in memory. In addition,
|
|
||||||
/// implementors of this method must ensure that all active objects are properly traced
|
|
||||||
/// or else the garbage collector may end up collecting objects that are still reachable.
|
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T: CustomTraceable> CustomTraceable for Box<T> {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
|
||||||
(**self).trace(trc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T: CustomTraceable> CustomTraceable for DomRefCell<T> {
|
unsafe impl<T: CustomTraceable> CustomTraceable for DomRefCell<T> {
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
(*self).borrow().trace(trc)
|
(*self).borrow().trace(trc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: JSTraceable> CustomTraceable for OnceCell<T> {
|
|
||||||
unsafe fn trace(&self, tracer: *mut JSTracer) {
|
|
||||||
if let Some(value) = self.get() {
|
|
||||||
value.trace(tracer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T> CustomTraceable for Sender<T> {
|
|
||||||
unsafe fn trace(&self, _: *mut JSTracer) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrapper type for nop traceble
|
/// Wrapper type for nop traceble
|
||||||
///
|
///
|
||||||
/// SAFETY: Inner type must not impl JSTraceable
|
/// SAFETY: Inner type must not impl JSTraceable
|
||||||
|
@ -298,59 +249,12 @@ pub(crate) fn trace_string(tracer: *mut JSTracer, description: &str, s: &Heap<*m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: JSTraceable> CustomTraceable for ServoArc<T> {
|
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
|
||||||
(**self).trace(trc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T: JSTraceable> CustomTraceable for RwLock<T> {
|
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
|
||||||
self.read().trace(trc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T: JSTraceable> JSTraceable for DomRefCell<T> {
|
unsafe impl<T: JSTraceable> JSTraceable for DomRefCell<T> {
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
(*self).borrow().trace(trc)
|
(*self).borrow().trace(trc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: JSTraceable + Eq + Hash> CustomTraceable for indexmap::IndexSet<T> {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
|
||||||
for e in self.iter() {
|
|
||||||
e.trace(trc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXXManishearth Check if the following three are optimized to no-ops
|
|
||||||
// if e.trace() is a no-op (e.g it is an unsafe_no_jsmanaged_fields type)
|
|
||||||
unsafe impl<T: JSTraceable + 'static> CustomTraceable for SmallVec<[T; 1]> {
|
|
||||||
#[inline]
|
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
|
||||||
for e in self.iter() {
|
|
||||||
e.trace(trc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<K, V, S> CustomTraceable 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_no_jsmanaged_fields!(TrustedPromise);
|
unsafe_no_jsmanaged_fields!(TrustedPromise);
|
||||||
|
|
||||||
unsafe_no_jsmanaged_fields!(WindowProxyHandler);
|
unsafe_no_jsmanaged_fields!(WindowProxyHandler);
|
||||||
|
@ -365,100 +269,6 @@ unsafe impl<T: DomObject> JSTraceable for Trusted<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<S> CustomTraceable 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> CustomTraceable 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> CustomTraceable 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> CustomTraceable for LossyDecoder<Sink>
|
|
||||||
where
|
|
||||||
Sink: JSTraceable + TendrilSink<UTF8>,
|
|
||||||
{
|
|
||||||
unsafe fn trace(&self, tracer: *mut JSTracer) {
|
|
||||||
self.inner_sink().trace(tracer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "webxr")]
|
|
||||||
unsafe impl<J> CustomTraceable 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "webxr")]
|
|
||||||
unsafe impl<J> CustomTraceable 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Roots any JSTraceable thing
|
/// Roots any JSTraceable thing
|
||||||
///
|
///
|
||||||
/// If you have a valid DomObject, use DomRoot.
|
/// If you have a valid DomObject, use DomRoot.
|
||||||
|
|
|
@ -12,14 +12,13 @@ use html5ever::buffer_queue::BufferQueue;
|
||||||
use html5ever::serialize::TraversalScope::IncludeNode;
|
use html5ever::serialize::TraversalScope::IncludeNode;
|
||||||
use html5ever::serialize::{AttrRef, Serialize, Serializer, TraversalScope};
|
use html5ever::serialize::{AttrRef, Serialize, Serializer, TraversalScope};
|
||||||
use html5ever::tokenizer::{Tokenizer as HtmlTokenizer, TokenizerOpts, TokenizerResult};
|
use html5ever::tokenizer::{Tokenizer as HtmlTokenizer, TokenizerOpts, TokenizerResult};
|
||||||
use html5ever::tree_builder::{Tracer as HtmlTracer, TreeBuilder, TreeBuilderOpts};
|
use html5ever::tree_builder::{TreeBuilder, TreeBuilderOpts};
|
||||||
use js::jsapi::JSTracer;
|
use script_bindings::trace::CustomTraceable;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
|
use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
|
||||||
use crate::dom::bindings::inheritance::{Castable, CharacterDataTypeId, NodeTypeId};
|
use crate::dom::bindings::inheritance::{Castable, CharacterDataTypeId, NodeTypeId};
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
use crate::dom::bindings::trace::{CustomTraceable, JSTraceable};
|
|
||||||
use crate::dom::characterdata::CharacterData;
|
use crate::dom::characterdata::CharacterData;
|
||||||
use crate::dom::document::Document;
|
use crate::dom::document::Document;
|
||||||
use crate::dom::documentfragment::DocumentFragment;
|
use crate::dom::documentfragment::DocumentFragment;
|
||||||
|
@ -103,28 +102,6 @@ impl Tokenizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe impl CustomTraceable for HtmlTokenizer<TreeBuilder<Dom<Node>, Sink>> {
|
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
|
||||||
struct Tracer(*mut JSTracer);
|
|
||||||
let tracer = Tracer(trc);
|
|
||||||
|
|
||||||
impl HtmlTracer for Tracer {
|
|
||||||
type Handle = Dom<Node>;
|
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
|
||||||
fn trace_handle(&self, node: &Dom<Node>) {
|
|
||||||
unsafe {
|
|
||||||
node.trace(self.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let tree_builder = &self.sink;
|
|
||||||
tree_builder.trace_handles(&tracer);
|
|
||||||
tree_builder.sink.trace(trc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_element<S: Serializer>(node: &Element, serializer: &mut S) -> io::Result<()> {
|
fn start_element<S: Serializer>(node: &Element, serializer: &mut S) -> io::Result<()> {
|
||||||
let name = QualName::new(None, node.namespace().clone(), node.local_name().clone());
|
let name = QualName::new(None, node.namespace().clone(), node.local_name().clone());
|
||||||
let attrs = node
|
let attrs = node
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use base::id::{PipelineId, WebViewId};
|
use base::id::{PipelineId, WebViewId};
|
||||||
use content_security_policy::Destination;
|
use content_security_policy::Destination;
|
||||||
|
@ -30,13 +31,29 @@ use crate::script_module::ScriptFetchOptions;
|
||||||
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
|
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
|
||||||
pub(crate) struct Tokenizer {
|
pub(crate) struct Tokenizer {
|
||||||
#[ignore_malloc_size_of = "Defined in html5ever"]
|
#[ignore_malloc_size_of = "Defined in html5ever"]
|
||||||
inner: HtmlTokenizer<PrefetchSink>,
|
inner: TraceableTokenizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TraceableTokenizer(HtmlTokenizer<PrefetchSink>);
|
||||||
|
|
||||||
|
impl Deref for TraceableTokenizer {
|
||||||
|
type Target = HtmlTokenizer<PrefetchSink>;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe impl CustomTraceable for HtmlTokenizer<PrefetchSink> {
|
unsafe impl JSTraceable for TraceableTokenizer {
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
self.sink.trace(trc)
|
CustomTraceable::trace(&self.0, trc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
unsafe impl CustomTraceable for PrefetchSink {
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
<Self as JSTraceable>::trace(self, trc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +75,7 @@ impl Tokenizer {
|
||||||
insecure_requests_policy: document.insecure_requests_policy(),
|
insecure_requests_policy: document.insecure_requests_policy(),
|
||||||
};
|
};
|
||||||
let options = Default::default();
|
let options = Default::default();
|
||||||
let inner = HtmlTokenizer::new(sink, options);
|
let inner = TraceableTokenizer(HtmlTokenizer::new(sink, options));
|
||||||
Tokenizer { inner }
|
Tokenizer { inner }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +108,7 @@ struct PrefetchSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The prefetch tokenizer produces trivial results
|
/// The prefetch tokenizer produces trivial results
|
||||||
|
#[derive(Clone, Copy, JSTraceable)]
|
||||||
struct PrefetchHandle;
|
struct PrefetchHandle;
|
||||||
|
|
||||||
impl TokenSink for PrefetchSink {
|
impl TokenSink for PrefetchSink {
|
||||||
|
|
|
@ -7,14 +7,13 @@
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
use html5ever::tokenizer::TokenizerResult;
|
use html5ever::tokenizer::TokenizerResult;
|
||||||
use js::jsapi::JSTracer;
|
use script_bindings::trace::CustomTraceable;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use xml5ever::buffer_queue::BufferQueue;
|
use xml5ever::buffer_queue::BufferQueue;
|
||||||
use xml5ever::tokenizer::XmlTokenizer;
|
use xml5ever::tokenizer::XmlTokenizer;
|
||||||
use xml5ever::tree_builder::{Tracer as XmlTracer, XmlTreeBuilder};
|
use xml5ever::tree_builder::XmlTreeBuilder;
|
||||||
|
|
||||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||||
use crate::dom::bindings::trace::{CustomTraceable, JSTraceable};
|
|
||||||
use crate::dom::document::Document;
|
use crate::dom::document::Document;
|
||||||
use crate::dom::htmlscriptelement::HTMLScriptElement;
|
use crate::dom::htmlscriptelement::HTMLScriptElement;
|
||||||
use crate::dom::node::Node;
|
use crate::dom::node::Node;
|
||||||
|
@ -59,25 +58,3 @@ impl Tokenizer {
|
||||||
&self.inner.sink.sink.base_url
|
&self.inner.sink.sink.base_url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe impl CustomTraceable for XmlTokenizer<XmlTreeBuilder<Dom<Node>, Sink>> {
|
|
||||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
|
||||||
struct Tracer(*mut JSTracer);
|
|
||||||
let tracer = Tracer(trc);
|
|
||||||
|
|
||||||
impl XmlTracer for Tracer {
|
|
||||||
type Handle = Dom<Node>;
|
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
|
||||||
fn trace_handle(&self, node: &Dom<Node>) {
|
|
||||||
unsafe {
|
|
||||||
node.trace(self.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let tree_builder = &self.sink;
|
|
||||||
tree_builder.trace_handles(&tracer);
|
|
||||||
tree_builder.sink.trace(trc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ use js::jsapi::{Heap, JS_NewPlainObject, JSObject};
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
use js::rust::{CustomAutoRooterGuard, HandleObject, HandleValue, MutableHandleValue};
|
use js::rust::{CustomAutoRooterGuard, HandleObject, HandleValue, MutableHandleValue};
|
||||||
use js::typedarray::{self, Uint8ClampedArray};
|
use js::typedarray::{self, Uint8ClampedArray};
|
||||||
|
use script_bindings::record::Record;
|
||||||
use script_traits::serializable::BlobImpl;
|
use script_traits::serializable::BlobImpl;
|
||||||
use servo_config::prefs;
|
use servo_config::prefs;
|
||||||
|
|
||||||
|
@ -35,7 +36,6 @@ use crate::dom::bindings::codegen::UnionTypes::{
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::error::{Error, Fallible};
|
use crate::dom::bindings::error::{Error, Fallible};
|
||||||
use crate::dom::bindings::num::Finite;
|
use crate::dom::bindings::num::Finite;
|
||||||
use crate::dom::bindings::record::Record;
|
|
||||||
use crate::dom::bindings::refcounted::TrustedPromise;
|
use crate::dom::bindings::refcounted::TrustedPromise;
|
||||||
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
|
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
|
|
|
@ -22,8 +22,10 @@ serde_json = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = { workspace = true }
|
bitflags = { workspace = true }
|
||||||
|
crossbeam-channel = { workspace = true }
|
||||||
cssparser = { workspace = true }
|
cssparser = { workspace = true }
|
||||||
html5ever = { workspace = true }
|
html5ever = { workspace = true }
|
||||||
|
indexmap = { workspace = true }
|
||||||
js = { workspace = true }
|
js = { workspace = true }
|
||||||
jstraceable_derive = { path = "../jstraceable_derive" }
|
jstraceable_derive = { path = "../jstraceable_derive" }
|
||||||
libc = { workspace = true }
|
libc = { workspace = true }
|
||||||
|
@ -31,15 +33,21 @@ log = { workspace = true }
|
||||||
malloc_size_of = { workspace = true }
|
malloc_size_of = { workspace = true }
|
||||||
malloc_size_of_derive = { workspace = true }
|
malloc_size_of_derive = { workspace = true }
|
||||||
num-traits = { workspace = true }
|
num-traits = { workspace = true }
|
||||||
|
parking_lot = { workspace = true }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
|
servo_arc = { workspace = true }
|
||||||
|
smallvec = { workspace = true }
|
||||||
stylo_atoms = { workspace = true }
|
stylo_atoms = { workspace = true }
|
||||||
servo_config = { path = "../config" }
|
servo_config = { path = "../config" }
|
||||||
style = { workspace = true }
|
style = { workspace = true }
|
||||||
|
tendril = { version = "0.4.1", features = ["encoding_rs"] }
|
||||||
|
webxr-api = { workspace = true, optional = true }
|
||||||
|
xml5ever = { workspace = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
bluetooth = []
|
bluetooth = []
|
||||||
webgpu = []
|
webgpu = []
|
||||||
webxr = []
|
webxr = ["webxr-api"]
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(crown)'] }
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(crown)'] }
|
||||||
|
|
|
@ -2287,7 +2287,7 @@ class CGImports(CGWrapper):
|
||||||
extras += [descriptor.path, descriptor.bindingPath]
|
extras += [descriptor.path, descriptor.bindingPath]
|
||||||
parentName = descriptor.getParentName()
|
parentName = descriptor.getParentName()
|
||||||
elif t.isType() and t.isRecord():
|
elif t.isType() and t.isRecord():
|
||||||
extras += ['crate::dom::bindings::record::Record']
|
extras += ['script_bindings::record::Record']
|
||||||
elif isinstance(t, IDLPromiseType):
|
elif isinstance(t, IDLPromiseType):
|
||||||
extras += ['crate::dom::promise::Promise']
|
extras += ['crate::dom::promise::Promise']
|
||||||
else:
|
else:
|
||||||
|
@ -2643,7 +2643,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
|
||||||
'crate::dom::bindings::import::base::*',
|
'crate::dom::bindings::import::base::*',
|
||||||
'crate::dom::bindings::codegen::DomTypes::DomTypes',
|
'crate::dom::bindings::codegen::DomTypes::DomTypes',
|
||||||
'crate::dom::bindings::conversions::windowproxy_from_handlevalue',
|
'crate::dom::bindings::conversions::windowproxy_from_handlevalue',
|
||||||
'crate::dom::bindings::record::Record',
|
'script_bindings::record::Record',
|
||||||
'crate::dom::types::*',
|
'crate::dom::types::*',
|
||||||
'crate::dom::windowproxy::WindowProxy',
|
'crate::dom::windowproxy::WindowProxy',
|
||||||
'js::typedarray',
|
'js::typedarray',
|
||||||
|
|
|
@ -18,8 +18,8 @@ use js::jsapi::{
|
||||||
};
|
};
|
||||||
use js::jsval::{ObjectValue, StringValue, UndefinedValue};
|
use js::jsval::{ObjectValue, StringValue, UndefinedValue};
|
||||||
use js::rust::{
|
use js::rust::{
|
||||||
HandleValue, MutableHandleValue, ToString, get_object_class, is_dom_class, is_dom_object,
|
HandleId, HandleValue, MutableHandleValue, ToString, get_object_class, is_dom_class,
|
||||||
maybe_wrap_value,
|
is_dom_object, maybe_wrap_value,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::inheritance::Castable;
|
use crate::inheritance::Castable;
|
||||||
|
@ -387,3 +387,24 @@ where
|
||||||
}
|
}
|
||||||
root_from_object(v.get().to_object(), cx)
|
root_from_object(v.get().to_object(), cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert `id` to a `DOMString`. Returns `None` if `id` is not a string or
|
||||||
|
/// integer.
|
||||||
|
///
|
||||||
|
/// Handling of invalid UTF-16 in strings depends on the relevant option.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// - cx must point to a non-null, valid JSContext instance.
|
||||||
|
pub unsafe fn jsid_to_string(cx: *mut JSContext, id: HandleId) -> Option<DOMString> {
|
||||||
|
let id_raw = *id;
|
||||||
|
if id_raw.is_string() {
|
||||||
|
let jsstr = std::ptr::NonNull::new(id_raw.to_string()).unwrap();
|
||||||
|
return Some(jsstring_to_str(cx, jsstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
if id_raw.is_int() {
|
||||||
|
return Some(id_raw.to_int().to_string().into());
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ pub mod error;
|
||||||
pub mod inheritance;
|
pub mod inheritance;
|
||||||
pub mod iterable;
|
pub mod iterable;
|
||||||
pub mod like;
|
pub mod like;
|
||||||
|
pub mod record;
|
||||||
pub mod reflector;
|
pub mod reflector;
|
||||||
pub mod root;
|
pub mod root;
|
||||||
pub mod script_runtime;
|
pub mod script_runtime;
|
||||||
|
@ -51,3 +52,5 @@ pub mod codegen {
|
||||||
// Since they are used in derive macros,
|
// Since they are used in derive macros,
|
||||||
// it is useful that they are accessible at the root of the crate.
|
// it is useful that they are accessible at the root of the crate.
|
||||||
pub(crate) use js::gc::Traceable as JSTraceable;
|
pub(crate) use js::gc::Traceable as JSTraceable;
|
||||||
|
|
||||||
|
pub(crate) use crate::trace::CustomTraceable;
|
||||||
|
|
|
@ -17,14 +17,20 @@ use js::jsapi::{
|
||||||
JSITER_SYMBOLS, JSPROP_ENUMERATE, PropertyDescriptor,
|
JSITER_SYMBOLS, JSPROP_ENUMERATE, PropertyDescriptor,
|
||||||
};
|
};
|
||||||
use js::jsval::{ObjectValue, UndefinedValue};
|
use js::jsval::{ObjectValue, UndefinedValue};
|
||||||
|
use js::rooted;
|
||||||
use js::rust::wrappers::{GetPropertyKeys, JS_DefineUCProperty2, JS_GetPropertyById, JS_IdToValue};
|
use js::rust::wrappers::{GetPropertyKeys, JS_DefineUCProperty2, JS_GetPropertyById, JS_IdToValue};
|
||||||
use js::rust::{HandleId, HandleValue, IdVector, MutableHandleValue};
|
use js::rust::{HandleId, HandleValue, IdVector, MutableHandleValue};
|
||||||
|
|
||||||
use crate::dom::bindings::conversions::jsid_to_string;
|
use crate::conversions::jsid_to_string;
|
||||||
use crate::dom::bindings::str::{ByteString, DOMString, USVString};
|
use crate::str::{ByteString, DOMString, USVString};
|
||||||
|
|
||||||
pub(crate) trait RecordKey: Eq + Hash + Sized {
|
pub trait RecordKey: Eq + Hash + Sized {
|
||||||
fn to_utf16_vec(&self) -> Vec<u16>;
|
fn to_utf16_vec(&self) -> Vec<u16>;
|
||||||
|
|
||||||
|
/// Attempt to extract a key from a JS id.
|
||||||
|
/// # Safety
|
||||||
|
/// - cx must point to a non-null, valid JSContext.
|
||||||
|
#[allow(clippy::result_unit_err)]
|
||||||
unsafe fn from_id(cx: *mut JSContext, id: HandleId) -> Result<ConversionResult<Self>, ()>;
|
unsafe fn from_id(cx: *mut JSContext, id: HandleId) -> Result<ConversionResult<Self>, ()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,14 +77,14 @@ impl RecordKey for ByteString {
|
||||||
|
|
||||||
/// The `Record` (open-ended dictionary) type.
|
/// The `Record` (open-ended dictionary) type.
|
||||||
#[derive(Clone, JSTraceable)]
|
#[derive(Clone, JSTraceable)]
|
||||||
pub(crate) struct Record<K: RecordKey, V> {
|
pub struct Record<K: RecordKey, V> {
|
||||||
#[custom_trace]
|
#[custom_trace]
|
||||||
map: IndexMap<K, V>,
|
map: IndexMap<K, V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: RecordKey, V> Record<K, V> {
|
impl<K: RecordKey, V> Record<K, V> {
|
||||||
/// Create an empty `Record`.
|
/// Create an empty `Record`.
|
||||||
pub(crate) fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Record {
|
Record {
|
||||||
map: IndexMap::new(),
|
map: IndexMap::new(),
|
||||||
}
|
}
|
|
@ -2,9 +2,32 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::cell::OnceCell;
|
||||||
|
use std::hash::{BuildHasher, Hash};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
|
use html5ever::interface::{Tracer as HtmlTracer, TreeSink};
|
||||||
|
use html5ever::tokenizer::{TokenSink, Tokenizer};
|
||||||
|
use html5ever::tree_builder::TreeBuilder;
|
||||||
|
use indexmap::IndexMap;
|
||||||
use js::glue::CallObjectTracer;
|
use js::glue::CallObjectTracer;
|
||||||
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
|
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
|
||||||
|
use parking_lot::RwLock;
|
||||||
|
use servo_arc::Arc as ServoArc;
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
use style::author_styles::AuthorStyles;
|
||||||
|
use style::stylesheet_set::{AuthorStylesheetSet, DocumentStylesheetSet};
|
||||||
|
use tendril::TendrilSink;
|
||||||
|
use tendril::fmt::UTF8;
|
||||||
|
use tendril::stream::LossyDecoder;
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
use webxr_api::{Finger, Hand};
|
||||||
|
use xml5ever::interface::TreeSink as XmlTreeSink;
|
||||||
|
use xml5ever::tokenizer::XmlTokenizer;
|
||||||
|
use xml5ever::tree_builder::{Tracer as XmlTracer, XmlTreeBuilder};
|
||||||
|
|
||||||
|
use crate::JSTraceable;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::reflector::Reflector;
|
use crate::reflector::Reflector;
|
||||||
use crate::str::{DOMString, USVString};
|
use crate::str::{DOMString, USVString};
|
||||||
|
@ -53,3 +76,235 @@ macro_rules! unsafe_no_jsmanaged_fields(
|
||||||
unsafe_no_jsmanaged_fields!(DOMString);
|
unsafe_no_jsmanaged_fields!(DOMString);
|
||||||
unsafe_no_jsmanaged_fields!(USVString);
|
unsafe_no_jsmanaged_fields!(USVString);
|
||||||
unsafe_no_jsmanaged_fields!(Error);
|
unsafe_no_jsmanaged_fields!(Error);
|
||||||
|
|
||||||
|
/// A trait to allow tracing only DOM sub-objects.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This trait is unsafe; if it is implemented incorrectly, the GC may end up collecting objects
|
||||||
|
/// that are still reachable.
|
||||||
|
pub unsafe trait CustomTraceable {
|
||||||
|
/// Trace `self`.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The `JSTracer` argument must point to a valid `JSTracer` in memory. In addition,
|
||||||
|
/// implementors of this method must ensure that all active objects are properly traced
|
||||||
|
/// or else the garbage collector may end up collecting objects that are still reachable.
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: CustomTraceable> CustomTraceable for Box<T> {
|
||||||
|
#[inline]
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
(**self).trace(trc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: JSTraceable> CustomTraceable for OnceCell<T> {
|
||||||
|
unsafe fn trace(&self, tracer: *mut JSTracer) {
|
||||||
|
if let Some(value) = self.get() {
|
||||||
|
value.trace(tracer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T> CustomTraceable for Sender<T> {
|
||||||
|
unsafe fn trace(&self, _: *mut JSTracer) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: JSTraceable> CustomTraceable for ServoArc<T> {
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
(**self).trace(trc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: JSTraceable> CustomTraceable for RwLock<T> {
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
self.read().trace(trc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: JSTraceable + Eq + Hash> CustomTraceable for indexmap::IndexSet<T> {
|
||||||
|
#[inline]
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
for e in self.iter() {
|
||||||
|
e.trace(trc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXXManishearth Check if the following three are optimized to no-ops
|
||||||
|
// if e.trace() is a no-op (e.g it is an unsafe_no_jsmanaged_fields type)
|
||||||
|
unsafe impl<T: JSTraceable + 'static> CustomTraceable for SmallVec<[T; 1]> {
|
||||||
|
#[inline]
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
for e in self.iter() {
|
||||||
|
e.trace(trc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<K, V, S> CustomTraceable 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<S> CustomTraceable 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> CustomTraceable 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> CustomTraceable 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> CustomTraceable for LossyDecoder<Sink>
|
||||||
|
where
|
||||||
|
Sink: JSTraceable + TendrilSink<UTF8>,
|
||||||
|
{
|
||||||
|
unsafe fn trace(&self, tracer: *mut JSTracer) {
|
||||||
|
self.inner_sink().trace(tracer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
unsafe impl<J> CustomTraceable 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "webxr")]
|
||||||
|
unsafe impl<J> CustomTraceable 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<Handle: JSTraceable + Clone, Sink: TreeSink<Handle = Handle> + JSTraceable>
|
||||||
|
CustomTraceable for TreeBuilder<Handle, Sink>
|
||||||
|
{
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
struct Tracer<Handle>(*mut JSTracer, PhantomData<Handle>);
|
||||||
|
let tracer = Tracer::<Handle>(trc, PhantomData);
|
||||||
|
|
||||||
|
impl<Handle: JSTraceable> HtmlTracer for Tracer<Handle> {
|
||||||
|
type Handle = Handle;
|
||||||
|
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||||
|
fn trace_handle(&self, node: &Handle) {
|
||||||
|
unsafe {
|
||||||
|
node.trace(self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.trace_handles(&tracer);
|
||||||
|
self.sink.trace(trc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
unsafe impl<Handle: JSTraceable + Clone, Sink: TokenSink<Handle = Handle> + CustomTraceable>
|
||||||
|
CustomTraceable for Tokenizer<Sink>
|
||||||
|
{
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
self.sink.trace(trc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
unsafe impl<Handle: JSTraceable + Clone, Sink: JSTraceable + XmlTreeSink<Handle = Handle>>
|
||||||
|
CustomTraceable for XmlTokenizer<XmlTreeBuilder<Handle, Sink>>
|
||||||
|
{
|
||||||
|
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
struct Tracer<Handle>(*mut JSTracer, PhantomData<Handle>);
|
||||||
|
let tracer = Tracer(trc, PhantomData);
|
||||||
|
|
||||||
|
impl<Handle: JSTraceable> XmlTracer for Tracer<Handle> {
|
||||||
|
type Handle = Handle;
|
||||||
|
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||||
|
fn trace_handle(&self, node: &Handle) {
|
||||||
|
unsafe {
|
||||||
|
node.trace(self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let tree_builder = &self.sink;
|
||||||
|
tree_builder.trace_handles(&tracer);
|
||||||
|
tree_builder.sink.trace(trc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue