diff --git a/mozjs-sys/src/jsgc.rs b/mozjs-sys/src/jsgc.rs index 46dad4b2b1..1c6ac1dd07 100644 --- a/mozjs-sys/src/jsgc.rs +++ b/mozjs-sys/src/jsgc.rs @@ -2,8 +2,6 @@ * 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/. */ -use crate::glue::CallPropertyDescriptorTracer; -use crate::jsapi::js::TraceValueArray; use crate::jsapi::JS; use crate::jsapi::{jsid, JSFunction, JSObject, JSScript, JSString, JSTracer}; use crate::jsid::VoidId; @@ -67,9 +65,9 @@ impl RootKind for JS::Value { const KIND: JS::RootKind = JS::RootKind::Value; } -impl RootKind for T { +impl RootKind for T { type Vtable = *const RootedVFTable; - const VTABLE: Self::Vtable = &::VTABLE; + const VTABLE: Self::Vtable = &::VTABLE; const KIND: JS::RootKind = JS::RootKind::Traceable; } @@ -92,40 +90,25 @@ impl RootedVFTable { pub const PADDING: [usize; 2] = [0, 0]; } -/// `Rooted` with a T that uses the Traceable RootKind uses dynamic dispatch on the C++ side -/// for custom tracing. This trait provides trace logic via a vtable when creating a Rust instance -/// of the object. -pub unsafe trait TraceableTrace: Sized { +/// Marker trait that allows any type that implements the [trace::Traceable] trait to be used +/// with the [Rooted] type. +/// +/// `Rooted` relies on dynamic dispatch in C++ when T uses the Traceable RootKind. +/// This trait initializes the vtable when creating a Rust instance of the Rooted object. +pub trait Rootable: crate::trace::Traceable + Sized { const VTABLE: RootedVFTable = RootedVFTable { padding: RootedVFTable::PADDING, - trace: Self::trace, + trace: ::trace, }; unsafe extern "C" fn trace(this: *mut c_void, trc: *mut JSTracer, _name: *const c_char) { let rooted = this as *mut Rooted; let rooted = rooted.as_mut().unwrap(); - Self::do_trace(&mut rooted.ptr, trc); + ::trace(&mut rooted.ptr, trc); } - - /// Used by `TraceableTrace` implementer to trace its contents. - /// Corresponds to virtual `trace` call in a `Rooted` that inherits from - /// StackRootedTraceableBase (C++). - unsafe fn do_trace(&mut self, trc: *mut JSTracer); } -unsafe impl TraceableTrace for Option { - unsafe fn do_trace(&mut self, trc: *mut JSTracer) { - if let Some(inner) = self.as_mut() { - inner.do_trace(trc) - } - } -} - -unsafe impl TraceableTrace for JS::PropertyDescriptor { - unsafe fn do_trace(&mut self, trc: *mut JSTracer) { - CallPropertyDescriptorTracer(trc, self); - } -} +impl Rootable for Option {} // The C++ representation of Rooted inherits from StackRootedBase, which // contains the actual pointers that get manipulated. The Rust representation @@ -152,6 +135,7 @@ pub struct Rooted { pub ptr: T, } +/// Trait that provides a GC-safe default value for the given type, if one exists. pub trait Initialize: Sized { /// Create a default value. If there is no meaningful default possible, returns None. /// SAFETY: @@ -275,6 +259,8 @@ impl GCMethods for JS::Value { } } +impl Rootable for JS::PropertyDescriptor {} + impl Initialize for JS::PropertyDescriptor { unsafe fn initial() -> Option { Some(JS::PropertyDescriptor::default()) @@ -311,11 +297,7 @@ impl ValueArray { } } -unsafe impl TraceableTrace for ValueArray { - unsafe fn do_trace(&mut self, trc: *mut JSTracer) { - TraceValueArray(trc, N, self.get_mut_ptr()); - } -} +impl Rootable for ValueArray {} impl Initialize for ValueArray { unsafe fn initial() -> Option { diff --git a/mozjs-sys/src/trace.rs b/mozjs-sys/src/trace.rs index a0489067a2..f013ed379c 100644 --- a/mozjs-sys/src/trace.rs +++ b/mozjs-sys/src/trace.rs @@ -4,7 +4,7 @@ use crate::glue::{ CallBigIntTracer, CallFunctionTracer, CallIdTracer, CallObjectTracer, CallScriptTracer, - CallStringTracer, CallSymbolTracer, CallValueRootTracer, CallValueTracer, + CallStringTracer, CallSymbolTracer, CallValueRootTracer, CallValueTracer, CallPropertyDescriptorTracer }; use crate::jsapi::js::TraceValueArray; use crate::jsapi::JS::{PropertyDescriptor, Value}; @@ -123,29 +123,10 @@ unsafe impl Traceable for Heap { } } -unsafe impl Traceable for Heap { +unsafe impl Traceable for PropertyDescriptor { #[inline] unsafe fn trace(&self, trc: *mut JSTracer) { - let desc = &*self.get_unsafe(); - CallValueTracer( - trc, - &desc.value_ as *const _ as *mut Heap, - c"PropertyDescriptor::value".as_ptr(), - ); - if !desc.getter_.is_null() { - CallObjectTracer( - trc, - &desc.getter_ as *const _ as *mut Heap<*mut JSObject>, - c"PropertyDescriptor::getter".as_ptr(), - ); - } - if !desc.setter_.is_null() { - CallObjectTracer( - trc, - &desc.setter_ as *const _ as *mut Heap<*mut JSObject>, - c"PropertyDescriptor::setter".as_ptr(), - ); - } + CallPropertyDescriptorTracer(trc, self as *const _ as *mut _); } } diff --git a/mozjs/src/gc/mod.rs b/mozjs/src/gc/mod.rs index f1edd6b05b..6701823e7a 100644 --- a/mozjs/src/gc/mod.rs +++ b/mozjs/src/gc/mod.rs @@ -2,7 +2,8 @@ pub use crate::gc::collections::*; pub use crate::gc::custom::*; pub use crate::gc::root::*; pub use crate::gc::trace::*; -pub use mozjs_sys::jsgc::{GCMethods, RootKind, TraceableTrace}; +pub use mozjs_sys::jsgc::{GCMethods, RootKind, Rootable, Initialize}; +pub use mozjs_sys::trace::Traceable; mod collections; mod custom;