From 9f6b772bbb8433e7961640f5d9b96e55f360b574 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 23 Aug 2016 16:34:37 +0530 Subject: [PATCH 1/7] Make Arc helpers into methods --- components/style/gecko_conversions.rs | 8 +- components/style/properties/gecko.mako.rs | 5 +- ports/geckolib/gecko_bindings/sugar/refptr.rs | 116 +++++++++--------- ports/geckolib/glue.rs | 90 ++++++-------- ports/geckolib/wrapper.rs | 11 +- 5 files changed, 110 insertions(+), 120 deletions(-) diff --git a/components/style/gecko_conversions.rs b/components/style/gecko_conversions.rs index 9739e1d6697..ec74adc0888 100644 --- a/components/style/gecko_conversions.rs +++ b/components/style/gecko_conversions.rs @@ -11,17 +11,19 @@ use app_units::Au; use gecko_bindings::bindings::{RawServoStyleSheet, ServoComputedValues}; use gecko_bindings::structs::nsStyleCoord_CalcValue; -use gecko_bindings::sugar::refptr::HasArcFFI; +use gecko_bindings::sugar::refptr::{HasArcFFI, HasFFI}; use properties::ComputedValues; use stylesheets::Stylesheet; use values::computed::{CalcLengthOrPercentage, LengthOrPercentage}; -unsafe impl HasArcFFI for Stylesheet { +unsafe impl HasFFI for Stylesheet { type FFIType = RawServoStyleSheet; } -unsafe impl HasArcFFI for ComputedValues { +unsafe impl HasArcFFI for Stylesheet {} +unsafe impl HasFFI for ComputedValues { type FFIType = ServoComputedValues; } +unsafe impl HasArcFFI for ComputedValues {} impl From for nsStyleCoord_CalcValue { fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 38896677800..65d2173e08c 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -27,7 +27,6 @@ use gecko_bindings::bindings::{Gecko_FontFamilyList_Clear, Gecko_InitializeImage use gecko_bindings::bindings::ServoComputedValuesBorrowed; use gecko_bindings::structs; use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut}; -use gecko_bindings::sugar::refptr::HasArcFFI; use gecko_values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba}; use gecko_values::convert_rgba_to_nscolor; use gecko_values::round_border_to_device_pixels; @@ -1715,8 +1714,8 @@ fn static_assert() { #[allow(non_snake_case, unused_variables)] pub extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values: ServoComputedValuesBorrowed) -> *const ${style_struct.gecko_ffi_name} { - ComputedValues::with(computed_values, |values| values.get_${style_struct.name_lower}().get_gecko() - as *const ${style_struct.gecko_ffi_name}) + computed_values.as_arc::().get_${style_struct.name_lower}().get_gecko() + as *const ${style_struct.gecko_ffi_name} } diff --git a/ports/geckolib/gecko_bindings/sugar/refptr.rs b/ports/geckolib/gecko_bindings/sugar/refptr.rs index 9d4eef9fd27..faa47190c6b 100644 --- a/ports/geckolib/gecko_bindings/sugar/refptr.rs +++ b/ports/geckolib/gecko_bindings/sugar/refptr.rs @@ -7,55 +7,24 @@ use std::mem::{forget, transmute}; use std::ptr; use std::sync::Arc; +/// Indicates that a given Servo type has a corresponding +/// Gecko FFI type +/// The correspondence is not defined at this stage, +/// use HasArcFFI or similar traits to define it +pub unsafe trait HasFFI : Sized { + type FFIType: Sized; +} + /// Helper trait for conversions between FFI Strong/Borrowed types and Arcs /// /// Should be implemented by types which are passed over FFI as Arcs /// via Strong and Borrowed -pub unsafe trait HasArcFFI where Self: Sized { - /// Gecko's name for the type - /// This is equivalent to ArcInner - type FFIType: Sized; - - /// Given a non-null borrowed FFI reference, this produces a temporary - /// Arc which is borrowed by the given closure and used. - /// Panics on null. - fn with(raw: Borrowed, cb: F) -> Output - where F: FnOnce(&Arc) -> Output { - Self::maybe_with(raw, |opt| cb(opt.unwrap())) - } - - /// Given a maybe-null borrowed FFI reference, this produces a temporary - /// Option (None if null) which is borrowed by the given closure and used - fn maybe_with(maybe_raw: Borrowed, cb: F) -> Output - where F: FnOnce(Option<&Arc>) -> Output { - cb(Self::borrowed_as(&maybe_raw)) - } - - /// Given a non-null strong FFI reference, converts it into an Arc. - /// Panics on null. - fn into(ptr: Strong) -> Arc { - assert!(!ptr.is_null()); - unsafe { transmute(ptr) } - } - - fn borrowed_as<'a>(ptr: &'a Borrowed<'a, Self::FFIType>) -> Option<&'a Arc> { - unsafe { - if ptr.is_null() { - None - } else { - Some(transmute::<&Borrowed<_>, &Arc<_>>(ptr)) - } - } - } - - /// Converts an Arc into a strong FFI reference. - fn from_arc(owned: Arc) -> Strong { - unsafe { transmute(owned) } - } - +pub unsafe trait HasArcFFI : HasFFI { + // these methods can't be on Borrowed because it leads to an unspecified + // impl parameter /// Artificially increments the refcount of a borrowed Arc over FFI. unsafe fn addref(ptr: Borrowed) { - Self::with(ptr, |arc| forget(arc.clone())); + forget(ptr.as_arc::().clone()) } /// Given a (possibly null) borrowed FFI reference, decrements the refcount. @@ -63,22 +32,10 @@ pub unsafe trait HasArcFFI where Self: Sized { /// know that a strong reference to the backing Arc is disappearing /// (usually on the C++ side) without running the Arc destructor. unsafe fn release(ptr: Borrowed) { - if let Some(arc) = Self::borrowed_as(&ptr) { + if let Some(arc) = ptr.as_arc_opt::() { let _: Arc<_> = ptr::read(arc as *const Arc<_>); } } - - /// Produces a borrowed FFI reference by borrowing an Arc. - fn to_borrowed<'a>(arc: &'a Arc) - -> Borrowed<'a, Self::FFIType> { - let borrowedptr = arc as *const Arc as *const Borrowed<'a, Self::FFIType>; - unsafe { ptr::read(borrowedptr) } - } - - /// Produces a null strong FFI reference - fn null_strong() -> Strong { - unsafe { transmute(ptr::null::()) } - } } #[repr(C)] @@ -100,6 +57,22 @@ impl<'a, T> Borrowed<'a, T> { pub fn is_null(&self) -> bool { self.ptr == ptr::null() } + + pub fn as_arc_opt(&self) -> Option<&Arc> where U: HasArcFFI { + unsafe { + if self.is_null() { + None + } else { + Some(transmute::<&Borrowed<_>, &Arc<_>>(self)) + } + } + } + + /// Converts a borrowed FFI reference to a borrowed Arc. + /// Panics on null + pub fn as_arc(&self) -> &Arc where U: HasArcFFI { + self.as_arc_opt().unwrap() + } } #[repr(C)] @@ -114,4 +87,35 @@ impl Strong { pub fn is_null(&self) -> bool { self.ptr == ptr::null() } + + /// Given a non-null strong FFI reference, converts it into an Arc. + /// Panics on null. + pub fn into_arc(self) -> Arc where U: HasArcFFI { + assert!(!self.is_null()); + unsafe { transmute(self) } + } + + /// Produces a null strong FFI reference + pub fn null_strong() -> Self { + unsafe { transmute(ptr::null::()) } + } +} + +pub unsafe trait FFIArcHelpers { + type Inner: HasArcFFI; + /// Converts an Arc into a strong FFI reference. + fn into_strong(self) -> Strong<::FFIType>; + /// Produces a borrowed FFI reference by borrowing an Arc. + fn as_borrowed(&self) -> Borrowed<::FFIType>; +} + +unsafe impl FFIArcHelpers for Arc { + type Inner = T; + fn into_strong(self) -> Strong { + unsafe {transmute(self)} + } + fn as_borrowed(&self) -> Borrowed { + let borrowedptr = self as *const Arc as *const Borrowed; + unsafe { ptr::read(borrowedptr) } + } } diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 0874b0a44b9..fdbb2f95b65 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -19,7 +19,7 @@ use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; use gecko_bindings::structs::ServoElementSnapshot; use gecko_bindings::structs::nsRestyleHint; use gecko_bindings::structs::{SheetParsingMode, nsIAtom}; -use gecko_bindings::sugar::refptr::HasArcFFI; +use gecko_bindings::sugar::refptr::{FFIArcHelpers, HasArcFFI, HasFFI, Strong}; use gecko_string_cache::Atom; use snapshot::GeckoElementSnapshot; use std::mem::transmute; @@ -176,22 +176,20 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8, pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: *mut RawServoStyleSet, raw_sheet: RawServoStyleSheetBorrowed) { let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); - Stylesheet::with(raw_sheet, |sheet| { - data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); - data.stylesheets.push(sheet.clone()); - data.stylesheets_changed = true; - }); + let sheet = raw_sheet.as_arc(); + data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); + data.stylesheets.push(sheet.clone()); + data.stylesheets_changed = true; } #[no_mangle] pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: *mut RawServoStyleSet, raw_sheet: RawServoStyleSheetBorrowed) { let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); - Stylesheet::with(raw_sheet, |sheet| { - data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); - data.stylesheets.insert(0, sheet.clone()); - data.stylesheets_changed = true; - }) + let sheet = raw_sheet.as_arc(); + data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); + data.stylesheets.insert(0, sheet.clone()); + data.stylesheets_changed = true; } #[no_mangle] @@ -199,29 +197,26 @@ pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: *mut RawServoS raw_sheet: RawServoStyleSheetBorrowed, raw_reference: RawServoStyleSheetBorrowed) { let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); - Stylesheet::with(raw_sheet, |sheet| { - Stylesheet::with(raw_reference, |reference| { - data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); - let index = data.stylesheets.iter().position(|x| arc_ptr_eq(x, reference)).unwrap(); - data.stylesheets.insert(index, sheet.clone()); - data.stylesheets_changed = true; - }) - }) + let sheet = raw_sheet.as_arc(); + let reference = raw_reference.as_arc(); + data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); + let index = data.stylesheets.iter().position(|x| arc_ptr_eq(x, reference)).unwrap(); + data.stylesheets.insert(index, sheet.clone()); + data.stylesheets_changed = true; } #[no_mangle] pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: *mut RawServoStyleSet, raw_sheet: RawServoStyleSheetBorrowed) { let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); - Stylesheet::with(raw_sheet, |sheet| { - data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); - data.stylesheets_changed = true; - }); + let sheet = raw_sheet.as_arc(); + data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); + data.stylesheets_changed = true; } #[no_mangle] pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool { - Stylesheet::with(raw_sheet, |sheet| !sheet.rules.is_empty()) + !raw_sheet.as_arc::().rules.is_empty() } #[no_mangle] @@ -249,7 +244,7 @@ pub extern "C" fn Servo_ComputedValues_Get(node: *mut RawGeckoNode) Arc::new(ComputedValues::initial_values().clone()) }, }; - ComputedValues::from_arc(arc_cv) + arc_cv.into_strong() } #[no_mangle] @@ -265,10 +260,9 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ true); - ComputedValues::maybe_with(parent_style_or_null, |maybe_parent| { - let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent); - new_computed.map_or(ComputedValues::null_strong(), |c| ComputedValues::from_arc(c)) - }) + let maybe_parent = parent_style_or_null.as_arc_opt(); + let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent); + new_computed.map_or(Strong::null_strong(), |c| c.into_strong()) } #[no_mangle] @@ -282,9 +276,9 @@ pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoCo let parent_or_null = || { if is_probe { - ComputedValues::null_strong() + Strong::null_strong() } else { - ComputedValues::from_arc(ComputedValues::with(parent_style, |parent| parent.clone())) + parent_style.as_arc::().clone().into_strong() } }; @@ -305,14 +299,13 @@ pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoCo .and_then(|data| { data.per_pseudo.get(&pseudo).map(|c| c.clone()) }); - maybe_computed.map_or_else(parent_or_null, ComputedValues::from_arc) + maybe_computed.map_or_else(parent_or_null, FFIArcHelpers::into_strong) } PseudoElementCascadeType::Lazy => { - ComputedValues::with(parent_style, |parent| { - data.stylist - .lazily_compute_pseudo_element_style(&element, &pseudo, parent) - .map_or_else(parent_or_null, ComputedValues::from_arc) - }) + let parent = parent_style.as_arc::(); + data.stylist + .lazily_compute_pseudo_element_style(&element, &pseudo, parent) + .map_or_else(parent_or_null, FFIArcHelpers::into_strong) } PseudoElementCascadeType::Precomputed => { unreachable!("Anonymous pseudo found in \ @@ -327,9 +320,9 @@ pub extern "C" fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValues let style = if parent_style.is_null() { Arc::new(ComputedValues::initial_values().clone()) } else { - ComputedValues::with(parent_style, ComputedValues::inherit_from) + ComputedValues::inherit_from(parent_style.as_arc()) }; - ComputedValues::from_arc(style) + style.into_strong() } #[no_mangle] @@ -367,20 +360,21 @@ pub struct GeckoDeclarationBlock { pub immutable: AtomicBool, } -unsafe impl HasArcFFI for GeckoDeclarationBlock { +unsafe impl HasFFI for GeckoDeclarationBlock { type FFIType = ServoDeclarationBlock; } +unsafe impl HasArcFFI for GeckoDeclarationBlock {} #[no_mangle] pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32, cache: *mut nsHTMLCSSStyleSheet) -> ServoDeclarationBlockStrong { let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) }; - GeckoDeclarationBlock::from_arc(Arc::new(GeckoDeclarationBlock { + Arc::new(GeckoDeclarationBlock { declarations: GeckoElement::parse_style_attribute(value).map(Arc::new), cache: AtomicPtr::new(cache), immutable: AtomicBool::new(false), - })) + }).into_strong() } #[no_mangle] @@ -396,23 +390,17 @@ pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationB #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_GetCache(declarations: ServoDeclarationBlockBorrowed) -> *mut nsHTMLCSSStyleSheet { - GeckoDeclarationBlock::with(declarations, |declarations| { - declarations.cache.load(Ordering::Relaxed) - }) + declarations.as_arc::().cache.load(Ordering::Relaxed) } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_SetImmutable(declarations: ServoDeclarationBlockBorrowed) { - GeckoDeclarationBlock::with(declarations, |declarations| { - declarations.immutable.store(true, Ordering::Relaxed) - }) + declarations.as_arc::().immutable.store(true, Ordering::Relaxed) } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_ClearCachePointer(declarations: ServoDeclarationBlockBorrowed) { - GeckoDeclarationBlock::with(declarations, |declarations| { - declarations.cache.store(ptr::null_mut(), Ordering::Relaxed) - }); + declarations.as_arc::().cache.store(ptr::null_mut(), Ordering::Relaxed) } #[no_mangle] diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index 712febe446d..b6f5dbae753 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -25,7 +25,7 @@ use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsEle use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; use gecko_bindings::structs::{nsIAtom, nsChangeHint, nsStyleContext}; -use gecko_bindings::sugar::refptr::HasArcFFI; +use gecko_bindings::sugar::refptr::FFIArcHelpers; use gecko_string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; use glue::GeckoDeclarationBlock; use libc::uintptr_t; @@ -109,7 +109,7 @@ impl TRestyleDamage for GeckoRestyleDamage { fn compute(source: &nsStyleContext, new_style: &Arc) -> Self { let context = source as *const nsStyleContext as *mut nsStyleContext; - let hint = unsafe { Gecko_CalcStyleDifference(context, ComputedValues::to_borrowed(new_style)) }; + let hint = unsafe { Gecko_CalcStyleDifference(context, new_style.as_borrowed()) }; GeckoRestyleDamage(hint) } @@ -474,11 +474,8 @@ impl<'le> TElement for GeckoElement<'le> { if declarations.is_null() { None } else { - let opt_ptr = GeckoDeclarationBlock::with(declarations, |declarations| { - // Use a raw pointer to extend the lifetime - declarations.declarations.as_ref().map(|r| r as *const Arc<_>) - }); - opt_ptr.map(|ptr| unsafe { &*ptr }) + let declarations = declarations.as_arc::(); + declarations.declarations.as_ref().map(|r| r as *const Arc<_>).map(|ptr| unsafe { &*ptr }) } } From db7156526f1e54613b18011947dbca757e7e345b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 23 Aug 2016 19:18:00 +0530 Subject: [PATCH 2/7] Allow for regular non-arc borrowed types, use for StyleSet --- ports/geckolib/binding_tools/regen.py | 18 ++++++++++ ports/geckolib/data.rs | 10 +++--- ports/geckolib/gecko_bindings/bindings.rs | 18 +++++----- ports/geckolib/gecko_bindings/sugar/refptr.rs | 21 ++++++++++- ports/geckolib/glue.rs | 36 +++++++++---------- 5 files changed, 72 insertions(+), 31 deletions(-) diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index 770c756dedc..1e767ff1701 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -153,6 +153,12 @@ COMPILATION_TARGETS = { "servo_arc_types": [ "ServoComputedValues", "RawServoStyleSheet", "ServoDeclarationBlock" + ], + "servo_borrowed_types": [ + "RawServoStyleSet", + ], + "servo_borrowed_mut_types": [ + "RawServoStyleSet", ] }, @@ -325,6 +331,18 @@ def build(objdir, target_name, debug, debugger, kind_name=None, flags.append("{}Borrowed".format(ty)) flags.append("--raw-line") flags.append("pub type {0}Borrowed<'a> = ::sugar::refptr::Borrowed<'a, {0}>;".format(ty)) + if "servo_borrowed_types" in current_target: + for ty in current_target["servo_borrowed_types"]: + flags.append("-blacklist-type") + flags.append("{}Borrowed".format(ty)) + flags.append("-raw-line") + flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) + if "servo_borrowed_mut_types" in current_target: + for ty in current_target["servo_borrowed_mut_types"]: + flags.append("-blacklist-type") + flags.append("{}BorrowedMut".format(ty)) + flags.append("-raw-line") + flags.append("pub type {0}BorrowedMut<'a> = &'a mut {0};".format(ty)) if "structs_types" in current_target: for ty in current_target["structs_types"]: ty_fragments = ty.split("::") diff --git a/ports/geckolib/data.rs b/ports/geckolib/data.rs index d1abe67f9bd..769e8b7e79d 100644 --- a/ports/geckolib/data.rs +++ b/ports/geckolib/data.rs @@ -4,6 +4,7 @@ use euclid::size::TypedSize2D; use gecko_bindings::bindings::RawServoStyleSet; +use gecko_bindings::sugar::refptr::{HasSimpleFFI, HasFFI}; use num_cpus; use std::cmp; use std::collections::HashMap; @@ -77,10 +78,6 @@ impl PerDocumentStyleData { } } - pub fn borrow_mut_from_raw<'a>(data: *mut RawServoStyleSet) -> &'a mut Self { - unsafe { &mut *(data as *mut PerDocumentStyleData) } - } - pub fn flush_stylesheets(&mut self) { // The stylist wants to be flushed if either the stylesheets change or the // device dimensions change. When we add support for media queries, we'll @@ -93,6 +90,11 @@ impl PerDocumentStyleData { } } +unsafe impl HasFFI for PerDocumentStyleData { + type FFIType = RawServoStyleSet; +} +unsafe impl HasSimpleFFI for PerDocumentStyleData {} + impl Drop for PerDocumentStyleData { fn drop(&mut self) { if let Some(ref mut queue) = self.work_queue { diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 4a45f41d046..26bf82e6894 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -11,6 +11,8 @@ pub type RawServoStyleSheetStrong = ::sugar::refptr::Strong; pub type RawServoStyleSheetBorrowed<'a> = ::sugar::refptr::Borrowed<'a, RawServoStyleSheet>; pub type ServoDeclarationBlockStrong = ::sugar::refptr::Strong; pub type ServoDeclarationBlockBorrowed<'a> = ::sugar::refptr::Borrowed<'a, ServoDeclarationBlock>; +pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; +pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; use structs::nsStyleFont; unsafe impl Send for nsStyleFont {} unsafe impl Sync for nsStyleFont {} @@ -474,12 +476,12 @@ extern "C" { pub fn Servo_StyleSet_Drop(set: *mut RawServoStyleSet); pub fn Servo_StyleSet_AppendStyleSheet(set: *mut RawServoStyleSet, sheet: RawServoStyleSheetBorrowed); - pub fn Servo_StyleSet_PrependStyleSheet(set: *mut RawServoStyleSet, + pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowedMut, sheet: RawServoStyleSheetBorrowed); - pub fn Servo_StyleSet_RemoveStyleSheet(set: *mut RawServoStyleSet, + pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowedMut, sheet: RawServoStyleSheetBorrowed); - pub fn Servo_StyleSet_InsertStyleSheetBefore(set: *mut RawServoStyleSet, + pub fn Servo_StyleSet_InsertStyleSheetBefore(set: RawServoStyleSetBorrowedMut, sheet: RawServoStyleSheetBorrowed, reference: @@ -505,7 +507,7 @@ extern "C" { pub fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowed, pseudoTag: *mut nsIAtom, - set: *mut RawServoStyleSet) + set: RawServoStyleSetBorrowedMut) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoComputedValuesBorrowed, @@ -513,7 +515,7 @@ extern "C" { *mut RawGeckoElement, pseudo_tag: *mut nsIAtom, set: - *mut RawServoStyleSet, + RawServoStyleSetBorrowedMut, is_probe: bool) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_Inherit(parent_style: @@ -527,12 +529,12 @@ extern "C" { pub fn Servo_Shutdown(); pub fn Servo_ComputeRestyleHint(element: *mut RawGeckoElement, snapshot: *mut ServoElementSnapshot, - set: *mut RawServoStyleSet) + set: RawServoStyleSetBorrowedMut) -> nsRestyleHint; pub fn Servo_RestyleDocument(doc: *mut RawGeckoDocument, - set: *mut RawServoStyleSet); + set: RawServoStyleSetBorrowedMut); pub fn Servo_RestyleSubtree(node: *mut RawGeckoNode, - set: *mut RawServoStyleSet); + set: RawServoStyleSetBorrowedMut); pub fn Servo_GetStyleFont(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleFont; pub fn Servo_GetStyleColor(computed_values: ServoComputedValuesBorrowed) diff --git a/ports/geckolib/gecko_bindings/sugar/refptr.rs b/ports/geckolib/gecko_bindings/sugar/refptr.rs index faa47190c6b..a70ad3d20ad 100644 --- a/ports/geckolib/gecko_bindings/sugar/refptr.rs +++ b/ports/geckolib/gecko_bindings/sugar/refptr.rs @@ -15,10 +15,29 @@ pub unsafe trait HasFFI : Sized { type FFIType: Sized; } +/// Indicates that a given Servo type has the same layout +/// as the corresponding HasFFI::FFIType type +pub unsafe trait HasSimpleFFI : HasFFI { + fn as_ffi(&self) -> &Self::FFIType { + unsafe { transmute(self) } + } + fn as_ffi_mut(&mut self) -> &mut Self::FFIType { + unsafe { transmute(self) } + } + fn from_ffi(ffi: &Self::FFIType) -> &Self { + unsafe { transmute(ffi) } + } + fn from_ffi_mut(ffi: &mut Self::FFIType) -> &mut Self { + unsafe { transmute(ffi) } + } +} + /// Helper trait for conversions between FFI Strong/Borrowed types and Arcs /// /// Should be implemented by types which are passed over FFI as Arcs /// via Strong and Borrowed +/// +/// In this case, the FFIType is the rough equivalent of ArcInner pub unsafe trait HasArcFFI : HasFFI { // these methods can't be on Borrowed because it leads to an unspecified // impl parameter @@ -112,7 +131,7 @@ pub unsafe trait FFIArcHelpers { unsafe impl FFIArcHelpers for Arc { type Inner = T; fn into_strong(self) -> Strong { - unsafe {transmute(self)} + unsafe { transmute(self) } } fn as_borrowed(&self) -> Borrowed { let borrowedptr = self as *const Arc as *const Borrowed; diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index fdbb2f95b65..404a1e6fe22 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -8,8 +8,8 @@ use app_units::Au; use data::{NUM_THREADS, PerDocumentStyleData}; use env_logger; use euclid::Size2D; -use gecko_bindings::bindings::RawServoStyleSet; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; +use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSetBorrowedMut}; use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong}; use gecko_bindings::bindings::{ServoDeclarationBlock, ServoNodeData, ThreadSafePrincipalHolder}; @@ -19,7 +19,7 @@ use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; use gecko_bindings::structs::ServoElementSnapshot; use gecko_bindings::structs::nsRestyleHint; use gecko_bindings::structs::{SheetParsingMode, nsIAtom}; -use gecko_bindings::sugar::refptr::{FFIArcHelpers, HasArcFFI, HasFFI, Strong}; +use gecko_bindings::sugar::refptr::{FFIArcHelpers, HasArcFFI, HasSimpleFFI, HasFFI, Strong}; use gecko_string_cache::Atom; use snapshot::GeckoElementSnapshot; use std::mem::transmute; @@ -69,7 +69,7 @@ pub extern "C" fn Servo_Shutdown() -> () { unsafe { ComputedValues::shutdown(); } } -fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) { +fn restyle_subtree(node: GeckoNode, raw_data: RawServoStyleSetBorrowedMut) { debug_assert!(node.is_element() || node.is_text_node()); // Force the creation of our lazily-constructed initial computed values on @@ -82,7 +82,7 @@ fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) { ComputedValues::initial_values(); // The stylist consumes stylesheets lazily. - let per_doc_data = unsafe { &mut *(raw_data as *mut PerDocumentStyleData) }; + let per_doc_data = PerDocumentStyleData::from_ffi_mut(raw_data); per_doc_data.flush_stylesheets(); let local_context_data = @@ -113,13 +113,13 @@ fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) { #[no_mangle] pub extern "C" fn Servo_RestyleSubtree(node: *mut RawGeckoNode, - raw_data: *mut RawServoStyleSet) -> () { + raw_data: RawServoStyleSetBorrowedMut) -> () { let node = unsafe { GeckoNode::from_raw(node) }; restyle_subtree(node, raw_data); } #[no_mangle] -pub extern "C" fn Servo_RestyleDocument(doc: *mut RawGeckoDocument, raw_data: *mut RawServoStyleSet) -> () { +pub extern "C" fn Servo_RestyleDocument(doc: *mut RawGeckoDocument, raw_data: RawServoStyleSetBorrowedMut) -> () { let document = unsafe { GeckoDocument::from_raw(doc) }; let node = match document.root_node() { Some(x) => x, @@ -173,9 +173,9 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8, } #[no_mangle] -pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: *mut RawServoStyleSet, +pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowedMut, raw_sheet: RawServoStyleSheetBorrowed) { - let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); + let data = PerDocumentStyleData::from_ffi_mut(raw_data); let sheet = raw_sheet.as_arc(); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets.push(sheet.clone()); @@ -183,9 +183,9 @@ pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: *mut RawServoStyleSe } #[no_mangle] -pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: *mut RawServoStyleSet, +pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowedMut, raw_sheet: RawServoStyleSheetBorrowed) { - let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); + let data = PerDocumentStyleData::from_ffi_mut(raw_data); let sheet = raw_sheet.as_arc(); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets.insert(0, sheet.clone()); @@ -193,10 +193,10 @@ pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: *mut RawServoStyleS } #[no_mangle] -pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: *mut RawServoStyleSet, +pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowedMut, raw_sheet: RawServoStyleSheetBorrowed, raw_reference: RawServoStyleSheetBorrowed) { - let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); + let data = PerDocumentStyleData::from_ffi_mut(raw_data); let sheet = raw_sheet.as_arc(); let reference = raw_reference.as_arc(); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); @@ -206,9 +206,9 @@ pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: *mut RawServoS } #[no_mangle] -pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: *mut RawServoStyleSet, +pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorrowedMut, raw_sheet: RawServoStyleSheetBorrowed) { - let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); + let data = PerDocumentStyleData::from_ffi_mut(raw_data); let sheet = raw_sheet.as_arc(); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets_changed = true; @@ -250,10 +250,10 @@ pub extern "C" fn Servo_ComputedValues_Get(node: *mut RawGeckoNode) #[no_mangle] pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowed, pseudo_tag: *mut nsIAtom, - raw_data: *mut RawServoStyleSet) + raw_data: RawServoStyleSetBorrowedMut) -> ServoComputedValuesStrong { // The stylist consumes stylesheets lazily. - let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); + let data = PerDocumentStyleData::from_ffi_mut(raw_data); data.flush_stylesheets(); let atom = Atom::from(pseudo_tag); @@ -269,7 +269,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoComputedValuesBorrowed, match_element: *mut RawGeckoElement, pseudo_tag: *mut nsIAtom, - raw_data: *mut RawServoStyleSet, + raw_data: RawServoStyleSetBorrowedMut, is_probe: bool) -> ServoComputedValuesStrong { debug_assert!(!match_element.is_null()); @@ -286,7 +286,7 @@ pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoCo let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ false); // The stylist consumes stylesheets lazily. - let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); + let data = PerDocumentStyleData::from_ffi_mut(raw_data); data.flush_stylesheets(); let element = unsafe { GeckoElement::from_raw(match_element) }; From 8bed07292c0a36673e72080f0ba18d98f35b31a4 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 23 Aug 2016 20:10:08 +0530 Subject: [PATCH 3/7] Add bindings for owned types, use for servostyleset --- ports/geckolib/binding_tools/regen.py | 15 ++++---- ports/geckolib/data.rs | 3 +- ports/geckolib/gecko_bindings/bindings.rs | 7 ++-- ports/geckolib/gecko_bindings/sugar/refptr.rs | 36 +++++++++++++++++++ ports/geckolib/glue.rs | 14 ++++---- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index 1e767ff1701..08ae548205c 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -154,12 +154,9 @@ COMPILATION_TARGETS = { "ServoComputedValues", "RawServoStyleSheet", "ServoDeclarationBlock" ], - "servo_borrowed_types": [ + "servo_owned_types": [ "RawServoStyleSet", ], - "servo_borrowed_mut_types": [ - "RawServoStyleSet", - ] }, "atoms": { @@ -331,18 +328,20 @@ def build(objdir, target_name, debug, debugger, kind_name=None, flags.append("{}Borrowed".format(ty)) flags.append("--raw-line") flags.append("pub type {0}Borrowed<'a> = ::sugar::refptr::Borrowed<'a, {0}>;".format(ty)) - if "servo_borrowed_types" in current_target: - for ty in current_target["servo_borrowed_types"]: + if "servo_owned_types" in current_target: + for ty in current_target["servo_owned_types"]: flags.append("-blacklist-type") flags.append("{}Borrowed".format(ty)) flags.append("-raw-line") flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) - if "servo_borrowed_mut_types" in current_target: - for ty in current_target["servo_borrowed_mut_types"]: flags.append("-blacklist-type") flags.append("{}BorrowedMut".format(ty)) flags.append("-raw-line") flags.append("pub type {0}BorrowedMut<'a> = &'a mut {0};".format(ty)) + flags.append("-blacklist-type") + flags.append("{}Owned".format(ty)) + flags.append("-raw-line") + flags.append("pub type {0}Owned = ::sugar::refptr::Owned<{0}>;".format(ty)) if "structs_types" in current_target: for ty in current_target["structs_types"]: ty_fragments = ty.split("::") diff --git a/ports/geckolib/data.rs b/ports/geckolib/data.rs index 769e8b7e79d..893206901a4 100644 --- a/ports/geckolib/data.rs +++ b/ports/geckolib/data.rs @@ -4,7 +4,7 @@ use euclid::size::TypedSize2D; use gecko_bindings::bindings::RawServoStyleSet; -use gecko_bindings::sugar::refptr::{HasSimpleFFI, HasFFI}; +use gecko_bindings::sugar::refptr::{HasBoxFFI, HasFFI, HasSimpleFFI}; use num_cpus; use std::cmp; use std::collections::HashMap; @@ -94,6 +94,7 @@ unsafe impl HasFFI for PerDocumentStyleData { type FFIType = RawServoStyleSet; } unsafe impl HasSimpleFFI for PerDocumentStyleData {} +unsafe impl HasBoxFFI for PerDocumentStyleData {} impl Drop for PerDocumentStyleData { fn drop(&mut self) { diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 26bf82e6894..3696b30fd42 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -13,6 +13,7 @@ pub type ServoDeclarationBlockStrong = ::sugar::refptr::Strong = ::sugar::refptr::Borrowed<'a, ServoDeclarationBlock>; pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; +pub type RawServoStyleSetOwned = ::sugar::refptr::Owned; use structs::nsStyleFont; unsafe impl Send for nsStyleFont {} unsafe impl Sync for nsStyleFont {} @@ -472,9 +473,9 @@ extern "C" { pub fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed); pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed) -> bool; - pub fn Servo_StyleSet_Init() -> *mut RawServoStyleSet; - pub fn Servo_StyleSet_Drop(set: *mut RawServoStyleSet); - pub fn Servo_StyleSet_AppendStyleSheet(set: *mut RawServoStyleSet, + pub fn Servo_StyleSet_Init() -> RawServoStyleSetOwned; + pub fn Servo_StyleSet_Drop(set: RawServoStyleSetOwned); + pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowedMut, sheet: RawServoStyleSheetBorrowed); pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowedMut, sheet: diff --git a/ports/geckolib/gecko_bindings/sugar/refptr.rs b/ports/geckolib/gecko_bindings/sugar/refptr.rs index a70ad3d20ad..2030ccbe807 100644 --- a/ports/geckolib/gecko_bindings/sugar/refptr.rs +++ b/ports/geckolib/gecko_bindings/sugar/refptr.rs @@ -4,6 +4,7 @@ use std::marker::PhantomData; use std::mem::{forget, transmute}; +use std::ops::{Deref, DerefMut}; use std::ptr; use std::sync::Arc; @@ -32,6 +33,14 @@ pub unsafe trait HasSimpleFFI : HasFFI { } } +/// Indicates that the given Servo type is passed over FFI +/// as a Box +pub unsafe trait HasBoxFFI : HasSimpleFFI { + fn into_ffi(self: Box) -> Owned { + unsafe { transmute(self) } + } +} + /// Helper trait for conversions between FFI Strong/Borrowed types and Arcs /// /// Should be implemented by types which are passed over FFI as Arcs @@ -138,3 +147,30 @@ unsafe impl FFIArcHelpers for Arc { unsafe { ptr::read(borrowedptr) } } } + +#[repr(C)] +/// Gecko-FFI-safe owned pointer +/// Cannot be null +pub struct Owned { + ptr: *mut T, + _marker: PhantomData, +} + +impl Owned { + pub fn into_box(self) -> Box where U: HasBoxFFI { + unsafe { transmute(self) } + } +} + +impl Deref for Owned { + type Target = T; + fn deref(&self) -> &T { + unsafe { &*self.ptr } + } +} + +impl DerefMut for Owned { + fn deref_mut(&mut self) -> &mut T { + unsafe { &mut *self.ptr } + } +} diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 404a1e6fe22..4431a6b55b1 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -10,6 +10,7 @@ use env_logger; use euclid::Size2D; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSetBorrowedMut}; +use gecko_bindings::bindings::RawServoStyleSetOwned; use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong}; use gecko_bindings::bindings::{ServoDeclarationBlock, ServoNodeData, ThreadSafePrincipalHolder}; @@ -19,7 +20,8 @@ use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; use gecko_bindings::structs::ServoElementSnapshot; use gecko_bindings::structs::nsRestyleHint; use gecko_bindings::structs::{SheetParsingMode, nsIAtom}; -use gecko_bindings::sugar::refptr::{FFIArcHelpers, HasArcFFI, HasSimpleFFI, HasFFI, Strong}; +use gecko_bindings::sugar::refptr::{FFIArcHelpers, HasArcFFI, HasBoxFFI}; +use gecko_bindings::sugar::refptr::{HasSimpleFFI, HasFFI, Strong}; use gecko_string_cache::Atom; use snapshot::GeckoElementSnapshot; use std::mem::transmute; @@ -336,16 +338,14 @@ pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) } #[no_mangle] -pub extern "C" fn Servo_StyleSet_Init() -> *mut RawServoStyleSet { +pub extern "C" fn Servo_StyleSet_Init() -> RawServoStyleSetOwned { let data = Box::new(PerDocumentStyleData::new()); - Box::into_raw(data) as *mut RawServoStyleSet + data.into_ffi() } #[no_mangle] -pub extern "C" fn Servo_StyleSet_Drop(data: *mut RawServoStyleSet) -> () { - unsafe { - let _ = Box::::from_raw(data as *mut PerDocumentStyleData); - } +pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) -> () { + let _ = data.into_box::(); } pub struct GeckoDeclarationBlock { From 36c63db5d4ed8a854ef89dea8d8a603c1d0fb458 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 23 Aug 2016 20:27:20 +0530 Subject: [PATCH 4/7] Rename sugar::refptr to sugar::ownership --- components/style/gecko_conversions.rs | 2 +- ports/geckolib/binding_tools/regen.py | 18 +++++++++--------- ports/geckolib/data.rs | 2 +- ports/geckolib/gecko_bindings/bindings.rs | 14 +++++++------- ports/geckolib/gecko_bindings/sugar/mod.rs | 2 +- .../sugar/{refptr.rs => ownership.rs} | 0 ports/geckolib/glue.rs | 4 ++-- ports/geckolib/wrapper.rs | 2 +- 8 files changed, 22 insertions(+), 22 deletions(-) rename ports/geckolib/gecko_bindings/sugar/{refptr.rs => ownership.rs} (100%) diff --git a/components/style/gecko_conversions.rs b/components/style/gecko_conversions.rs index ec74adc0888..71457a7dc3a 100644 --- a/components/style/gecko_conversions.rs +++ b/components/style/gecko_conversions.rs @@ -11,7 +11,7 @@ use app_units::Au; use gecko_bindings::bindings::{RawServoStyleSheet, ServoComputedValues}; use gecko_bindings::structs::nsStyleCoord_CalcValue; -use gecko_bindings::sugar::refptr::{HasArcFFI, HasFFI}; +use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI}; use properties::ComputedValues; use stylesheets::Stylesheet; use values::computed::{CalcLengthOrPercentage, LengthOrPercentage}; diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index 08ae548205c..556e2d184c7 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -323,25 +323,25 @@ def build(objdir, target_name, debug, debugger, kind_name=None, flags.append("--blacklist-type") flags.append("{}Strong".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}Strong = ::sugar::refptr::Strong<{0}>;".format(ty)) + flags.append("pub type {0}Strong = ::sugar::ownership::Strong<{0}>;".format(ty)) flags.append("--blacklist-type") flags.append("{}Borrowed".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}Borrowed<'a> = ::sugar::refptr::Borrowed<'a, {0}>;".format(ty)) + flags.append("pub type {0}Borrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;".format(ty)) if "servo_owned_types" in current_target: for ty in current_target["servo_owned_types"]: - flags.append("-blacklist-type") + flags.append("--blacklist-type") flags.append("{}Borrowed".format(ty)) - flags.append("-raw-line") + flags.append("--raw-line") flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) - flags.append("-blacklist-type") + flags.append("--blacklist-type") flags.append("{}BorrowedMut".format(ty)) - flags.append("-raw-line") + flags.append("--raw-line") flags.append("pub type {0}BorrowedMut<'a> = &'a mut {0};".format(ty)) - flags.append("-blacklist-type") + flags.append("--blacklist-type") flags.append("{}Owned".format(ty)) - flags.append("-raw-line") - flags.append("pub type {0}Owned = ::sugar::refptr::Owned<{0}>;".format(ty)) + flags.append("--raw-line") + flags.append("pub type {0}Owned = ::sugar::ownership::Owned<{0}>;".format(ty)) if "structs_types" in current_target: for ty in current_target["structs_types"]: ty_fragments = ty.split("::") diff --git a/ports/geckolib/data.rs b/ports/geckolib/data.rs index 893206901a4..6b279510982 100644 --- a/ports/geckolib/data.rs +++ b/ports/geckolib/data.rs @@ -4,7 +4,7 @@ use euclid::size::TypedSize2D; use gecko_bindings::bindings::RawServoStyleSet; -use gecko_bindings::sugar::refptr::{HasBoxFFI, HasFFI, HasSimpleFFI}; +use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; use num_cpus; use std::cmp; use std::collections::HashMap; diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 3696b30fd42..546a27b14b1 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -5,15 +5,15 @@ pub enum nsINode {} pub enum nsIDocument {} pub enum nsIPrincipal {} pub enum nsIURI {} -pub type ServoComputedValuesStrong = ::sugar::refptr::Strong; -pub type ServoComputedValuesBorrowed<'a> = ::sugar::refptr::Borrowed<'a, ServoComputedValues>; -pub type RawServoStyleSheetStrong = ::sugar::refptr::Strong; -pub type RawServoStyleSheetBorrowed<'a> = ::sugar::refptr::Borrowed<'a, RawServoStyleSheet>; -pub type ServoDeclarationBlockStrong = ::sugar::refptr::Strong; -pub type ServoDeclarationBlockBorrowed<'a> = ::sugar::refptr::Borrowed<'a, ServoDeclarationBlock>; +pub type ServoComputedValuesStrong = ::sugar::ownership::Strong; +pub type ServoComputedValuesBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoComputedValues>; +pub type RawServoStyleSheetStrong = ::sugar::ownership::Strong; +pub type RawServoStyleSheetBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawServoStyleSheet>; +pub type ServoDeclarationBlockStrong = ::sugar::ownership::Strong; +pub type ServoDeclarationBlockBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoDeclarationBlock>; pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; -pub type RawServoStyleSetOwned = ::sugar::refptr::Owned; +pub type RawServoStyleSetOwned = ::sugar::ownership::Owned; use structs::nsStyleFont; unsafe impl Send for nsStyleFont {} unsafe impl Sync for nsStyleFont {} diff --git a/ports/geckolib/gecko_bindings/sugar/mod.rs b/ports/geckolib/gecko_bindings/sugar/mod.rs index a4c6b1b98c2..a451d67a06d 100644 --- a/ports/geckolib/gecko_bindings/sugar/mod.rs +++ b/ports/geckolib/gecko_bindings/sugar/mod.rs @@ -6,4 +6,4 @@ mod ns_css_shadow_array; mod ns_style_auto_array; pub mod ns_style_coord; mod ns_t_array; -pub mod refptr; +pub mod ownership; diff --git a/ports/geckolib/gecko_bindings/sugar/refptr.rs b/ports/geckolib/gecko_bindings/sugar/ownership.rs similarity index 100% rename from ports/geckolib/gecko_bindings/sugar/refptr.rs rename to ports/geckolib/gecko_bindings/sugar/ownership.rs diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 4431a6b55b1..ce339a4fbf1 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -20,8 +20,8 @@ use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; use gecko_bindings::structs::ServoElementSnapshot; use gecko_bindings::structs::nsRestyleHint; use gecko_bindings::structs::{SheetParsingMode, nsIAtom}; -use gecko_bindings::sugar::refptr::{FFIArcHelpers, HasArcFFI, HasBoxFFI}; -use gecko_bindings::sugar::refptr::{HasSimpleFFI, HasFFI, Strong}; +use gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasBoxFFI}; +use gecko_bindings::sugar::ownership::{HasSimpleFFI, HasFFI, Strong}; use gecko_string_cache::Atom; use snapshot::GeckoElementSnapshot; use std::mem::transmute; diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index b6f5dbae753..b4c055e34e5 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -25,7 +25,7 @@ use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsEle use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; use gecko_bindings::structs::{nsIAtom, nsChangeHint, nsStyleContext}; -use gecko_bindings::sugar::refptr::FFIArcHelpers; +use gecko_bindings::sugar::ownership::FFIArcHelpers; use gecko_string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; use glue::GeckoDeclarationBlock; use libc::uintptr_t; From de90f5fce801d9d2171900b361a422a83c35a3a2 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 24 Aug 2016 17:52:15 +0530 Subject: [PATCH 5/7] Add MaybeOwned, and use for ServoNodeData. More docs. --- ports/geckolib/binding_tools/regen.py | 26 ++- ports/geckolib/gecko_bindings/bindings.rs | 15 +- .../gecko_bindings/sugar/ownership.rs | 155 +++++++++++++++++- ports/geckolib/glue.rs | 10 +- ports/geckolib/wrapper.rs | 42 +++-- 5 files changed, 216 insertions(+), 32 deletions(-) diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index 556e2d184c7..d293d5047ec 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -150,12 +150,16 @@ COMPILATION_TARGETS = { "void_types": [ "nsINode", "nsIDocument", "nsIPrincipal", "nsIURI", ], - "servo_arc_types": [ + "servo_maybe_arc_types": [ "ServoComputedValues", "RawServoStyleSheet", "ServoDeclarationBlock" ], "servo_owned_types": [ "RawServoStyleSet", + "RawGeckoNode", + ], + "servo_maybe_owned_types": [ + "ServoNodeData", ], }, @@ -318,8 +322,8 @@ def build(objdir, target_name, debug, debugger, kind_name=None, for ty in current_target["void_types"]: flags.append("--raw-line") flags.append("pub enum {} {{}}".format(ty)) - if "servo_arc_types" in current_target: - for ty in current_target["servo_arc_types"]: + if "servo_maybe_arc_types" in current_target: + for ty in current_target["servo_maybe_arc_types"]: flags.append("--blacklist-type") flags.append("{}Strong".format(ty)) flags.append("--raw-line") @@ -342,6 +346,22 @@ def build(objdir, target_name, debug, debugger, kind_name=None, flags.append("{}Owned".format(ty)) flags.append("--raw-line") flags.append("pub type {0}Owned = ::sugar::ownership::Owned<{0}>;".format(ty)) + if "servo_maybe_owned_types" in current_target: + for ty in current_target["servo_maybe_owned_types"]: + flags.append("--blacklist-type") + flags.append("{}Borrowed".format(ty)) + flags.append("--raw-line") + flags.append("pub type {0}Borrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;" + .format(ty)) + flags.append("--blacklist-type") + flags.append("{}BorrowedMut".format(ty)) + flags.append("--raw-line") + flags.append("pub type {0}BorrowedMut<'a> = ::sugar::ownership::BorrowedMut<'a, {0}>;" + .format(ty)) + flags.append("--blacklist-type") + flags.append("{}Owned".format(ty)) + flags.append("--raw-line") + flags.append("pub type {0}Owned = ::sugar::ownership::MaybeOwned<{0}>;".format(ty)) if "structs_types" in current_target: for ty in current_target["structs_types"]: ty_fragments = ty.split("::") diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 546a27b14b1..52c11df627d 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -14,6 +14,12 @@ pub type ServoDeclarationBlockBorrowed<'a> = ::sugar::ownership::Borrowed<'a, Se pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; pub type RawServoStyleSetOwned = ::sugar::ownership::Owned; +pub type RawGeckoNodeBorrowed<'a> = &'a RawGeckoNode; +pub type RawGeckoNodeBorrowedMut<'a> = &'a mut RawGeckoNode; +pub type RawGeckoNodeOwned = ::sugar::ownership::Owned; +pub type ServoNodeDataBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoNodeData>; +pub type ServoNodeDataBorrowedMut<'a> = ::sugar::ownership::BorrowedMut<'a, ServoNodeData>; +pub type ServoNodeDataOwned = ::sugar::ownership::MaybeOwned; use structs::nsStyleFont; unsafe impl Send for nsStyleFont {} unsafe impl Sync for nsStyleFont {} @@ -267,9 +273,10 @@ extern "C" { -> u32; pub fn Gecko_GetServoDeclarationBlock(element: *mut RawGeckoElement) -> ServoDeclarationBlockBorrowed; - pub fn Gecko_GetNodeData(node: *mut RawGeckoNode) -> *mut ServoNodeData; - pub fn Gecko_SetNodeData(node: *mut RawGeckoNode, - data: *mut ServoNodeData); + pub fn Gecko_GetNodeData(node: RawGeckoNodeBorrowed) + -> ServoNodeDataBorrowed; + pub fn Gecko_SetNodeData(node: RawGeckoNodeBorrowedMut, + data: ServoNodeDataOwned); pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32) -> *mut nsIAtom; pub fn Gecko_AddRefAtom(aAtom: *mut nsIAtom); @@ -459,7 +466,7 @@ extern "C" { pub fn Gecko_CopyConstruct_nsStyleEffects(ptr: *mut nsStyleEffects, other: *const nsStyleEffects); pub fn Gecko_Destroy_nsStyleEffects(ptr: *mut nsStyleEffects); - pub fn Servo_NodeData_Drop(data: *mut ServoNodeData); + pub fn Servo_NodeData_Drop(data: ServoNodeDataOwned); pub fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8, length: u32, parsing_mode: SheetParsingMode, base_bytes: *const u8, diff --git a/ports/geckolib/gecko_bindings/sugar/ownership.rs b/ports/geckolib/gecko_bindings/sugar/ownership.rs index 2030ccbe807..46a7500819c 100644 --- a/ports/geckolib/gecko_bindings/sugar/ownership.rs +++ b/ports/geckolib/gecko_bindings/sugar/ownership.rs @@ -19,15 +19,35 @@ pub unsafe trait HasFFI : Sized { /// Indicates that a given Servo type has the same layout /// as the corresponding HasFFI::FFIType type pub unsafe trait HasSimpleFFI : HasFFI { + #[inline] + /// Given a Servo-side reference, converts it to an + /// FFI-safe reference which can be passed to Gecko + /// + /// &ServoType -> &GeckoType fn as_ffi(&self) -> &Self::FFIType { unsafe { transmute(self) } } + #[inline] + /// Given a Servo-side mutable reference, converts it to an + /// FFI-safe mutable reference which can be passed to Gecko + /// + /// &mut ServoType -> &mut GeckoType fn as_ffi_mut(&mut self) -> &mut Self::FFIType { unsafe { transmute(self) } } + #[inline] + /// Given an FFI-safe reference obtained from Gecko + /// converts it to a Servo-side reference + /// + /// &GeckoType -> &ServoType fn from_ffi(ffi: &Self::FFIType) -> &Self { unsafe { transmute(ffi) } } + #[inline] + /// Given an FFI-safe mutable reference obtained from Gecko + /// converts it to a Servo-side mutable reference + /// + /// &mut GeckoType -> &mut ServoType fn from_ffi_mut(ffi: &mut Self::FFIType) -> &mut Self { unsafe { transmute(ffi) } } @@ -36,6 +56,7 @@ pub unsafe trait HasSimpleFFI : HasFFI { /// Indicates that the given Servo type is passed over FFI /// as a Box pub unsafe trait HasBoxFFI : HasSimpleFFI { + #[inline] fn into_ffi(self: Box) -> Owned { unsafe { transmute(self) } } @@ -67,25 +88,47 @@ pub unsafe trait HasArcFFI : HasFFI { } #[repr(C)] -/// Gecko-FFI-safe borrowed Arc (&T where T is an ArcInner). +/// Gecko-FFI-safe borrowed type /// This can be null. pub struct Borrowed<'a, T: 'a> { ptr: *const T, _marker: PhantomData<&'a T>, } +#[repr(C)] +/// Gecko-FFI-safe mutably borrowed type +/// This can be null. +pub struct BorrowedMut<'a, T: 'a> { + ptr: *mut T, + _marker: PhantomData<&'a mut T>, +} + // manual impls because derive doesn't realize that `T: Clone` isn't necessary impl<'a, T> Copy for Borrowed<'a, T> {} impl<'a, T> Clone for Borrowed<'a, T> { + #[inline] fn clone(&self) -> Self { *self } } impl<'a, T> Borrowed<'a, T> { + #[inline] pub fn is_null(&self) -> bool { self.ptr == ptr::null() } + #[inline] + /// Like Deref, but gives an Option + pub fn borrow_opt(self) -> Option<&'a T> { + if self.is_null() { + None + } else { + Some(unsafe { &*self.ptr }) + } + } + + #[inline] + /// Borrowed -> Option<&Arc> pub fn as_arc_opt(&self) -> Option<&Arc> where U: HasArcFFI { unsafe { if self.is_null() { @@ -96,11 +139,71 @@ impl<'a, T> Borrowed<'a, T> { } } + #[inline] /// Converts a borrowed FFI reference to a borrowed Arc. - /// Panics on null + /// Panics on null. + /// + /// &Borrowed -> &Arc pub fn as_arc(&self) -> &Arc where U: HasArcFFI { self.as_arc_opt().unwrap() } + + #[inline] + /// Borrowed -> Borrowed + pub fn as_ffi(&self) -> Borrowed<::FFIType> where Self: HasSimpleFFI { + unsafe { transmute(self) } + } + + #[inline] + /// Borrowed -> Borrowed + pub fn from_ffi(self) -> Borrowed<'a, U> where U: HasSimpleFFI { + unsafe { transmute(self) } + } + + #[inline] + /// Borrowed -> &ServoType + pub fn as_servo_ref(self) -> Option<&'a U> where U: HasSimpleFFI { + self.borrow_opt().map(HasSimpleFFI::from_ffi) + } +} + +impl<'a, T> BorrowedMut<'a, T> { + #[inline] + /// Like DerefMut, but gives an Option + pub fn borrow_mut_opt(self) -> Option<&'a mut T> { + // We have two choices for the signature here, it can either be + // Self -> Option<&'a mut T> or + // &'b mut Self -> Option<'b mut T> + // The former consumes the BorrowedMut (which isn't Copy), + // which can be annoying. The latter only temporarily + // borrows it, so the return value can't exit the scope + // even if Self has a longer lifetime ('a) + // + // This is basically the implicit "reborrow" pattern used with &mut + // not cleanly translating to our custom types. + + // I've chosen the former solution -- you can manually convert back + // if you need to reuse the BorrowedMut. + if self.is_null() { + None + } else { + Some(unsafe { &mut *self.ptr }) + } + } + + #[inline] + /// BorrowedMut -> &mut ServoType + pub fn as_servo_mut_ref(self) -> Option<&'a mut U> where U: HasSimpleFFI { + self.borrow_mut_opt().map(HasSimpleFFI::from_ffi_mut) + } +} + +// technically not +impl<'a, T> Deref for BorrowedMut<'a, T> { + type Target = Borrowed<'a, T>; + fn deref(&self) -> &Self::Target { + unsafe { transmute(self) } + } } #[repr(C)] @@ -112,17 +215,23 @@ pub struct Strong { } impl Strong { + #[inline] pub fn is_null(&self) -> bool { self.ptr == ptr::null() } - /// Given a non-null strong FFI reference, converts it into an Arc. + #[inline] + /// Given a non-null strong FFI reference, + /// converts it into a servo-side Arc /// Panics on null. + /// + /// Strong -> Arc pub fn into_arc(self) -> Arc where U: HasArcFFI { assert!(!self.is_null()); unsafe { transmute(self) } } + #[inline] /// Produces a null strong FFI reference pub fn null_strong() -> Self { unsafe { transmute(ptr::null::()) } @@ -132,16 +241,22 @@ impl Strong { pub unsafe trait FFIArcHelpers { type Inner: HasArcFFI; /// Converts an Arc into a strong FFI reference. + /// + /// Arc -> Strong fn into_strong(self) -> Strong<::FFIType>; /// Produces a borrowed FFI reference by borrowing an Arc. + /// + /// &Arc -> Borrowed fn as_borrowed(&self) -> Borrowed<::FFIType>; } unsafe impl FFIArcHelpers for Arc { type Inner = T; + #[inline] fn into_strong(self) -> Strong { unsafe { transmute(self) } } + #[inline] fn as_borrowed(&self) -> Borrowed { let borrowedptr = self as *const Arc as *const Borrowed; unsafe { ptr::read(borrowedptr) } @@ -157,9 +272,13 @@ pub struct Owned { } impl Owned { + /// Owned -> Box pub fn into_box(self) -> Box where U: HasBoxFFI { unsafe { transmute(self) } } + pub fn maybe(self) -> MaybeOwned { + unsafe { transmute(self) } + } } impl Deref for Owned { @@ -174,3 +293,33 @@ impl DerefMut for Owned { unsafe { &mut *self.ptr } } } + +#[repr(C)] +/// Gecko-FFI-safe owned pointer +/// Can be null +pub struct MaybeOwned { + ptr: *mut T, + _marker: PhantomData, +} + +impl MaybeOwned { + pub fn is_null(&self) -> bool { + self.ptr == ptr::null_mut() + } + /// MaybeOwned -> Option> + pub fn into_box_opt(self) -> Option> where U: HasBoxFFI { + if self.is_null() { + None + } else { + Some(unsafe { transmute(self) }) + } + } + + pub fn borrow(&self) -> Borrowed { + unsafe { transmute(self) } + } + + pub fn borrow_mut(&self) -> BorrowedMut { + unsafe { transmute(self) } + } +} diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index ce339a4fbf1..95696089349 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -10,10 +10,10 @@ use env_logger; use euclid::Size2D; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSetBorrowedMut}; -use gecko_bindings::bindings::RawServoStyleSetOwned; +use gecko_bindings::bindings::{RawServoStyleSetOwned, ServoNodeDataOwned}; use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong}; -use gecko_bindings::bindings::{ServoDeclarationBlock, ServoNodeData, ThreadSafePrincipalHolder}; +use gecko_bindings::bindings::{ServoDeclarationBlock, ThreadSafePrincipalHolder}; use gecko_bindings::bindings::{ServoDeclarationBlockBorrowed, ServoDeclarationBlockStrong}; use gecko_bindings::bindings::{ThreadSafeURIHolder, nsHTMLCSSStyleSheet}; use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; @@ -136,10 +136,8 @@ pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 { } #[no_mangle] -pub extern "C" fn Servo_NodeData_Drop(data: *mut ServoNodeData) -> () { - unsafe { - let _ = Box::::from_raw(data as *mut NonOpaqueStyleData); - } +pub extern "C" fn Servo_NodeData_Drop(data: ServoNodeDataOwned) -> () { + let _ = data.into_box_opt::(); } #[no_mangle] diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index b4c055e34e5..74e2e47fed7 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -25,7 +25,8 @@ use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsEle use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; use gecko_bindings::structs::{nsIAtom, nsChangeHint, nsStyleContext}; -use gecko_bindings::sugar::ownership::FFIArcHelpers; +use gecko_bindings::sugar::ownership::Borrowed; +use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI, FFIArcHelpers}; use gecko_string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; use glue::GeckoDeclarationBlock; use libc::uintptr_t; @@ -53,8 +54,19 @@ use style::selector_matching::DeclarationBlock; use style::sink::Push; use url::Url; -pub type NonOpaqueStyleData = RefCell; -pub type NonOpaqueStyleDataPtr = *mut NonOpaqueStyleData; +pub struct NonOpaqueStyleData(RefCell); + +unsafe impl HasFFI for NonOpaqueStyleData { + type FFIType = ServoNodeData; +} +unsafe impl HasSimpleFFI for NonOpaqueStyleData {} +unsafe impl HasBoxFFI for NonOpaqueStyleData {} + +impl NonOpaqueStyleData { + pub fn new() -> Self { + NonOpaqueStyleData(RefCell::new(PrivateStyleData::new())) + } +} // Important: We don't currently refcount the DOM, because the wrapper lifetime // magic guarantees that our LayoutFoo references won't outlive the root, and @@ -79,17 +91,18 @@ impl<'ln> GeckoNode<'ln> { GeckoNode::from_raw(n as *const RawGeckoNode as *mut RawGeckoNode) } - fn get_node_data(&self) -> NonOpaqueStyleDataPtr { + fn get_node_data(&self) -> Borrowed { unsafe { - Gecko_GetNodeData(self.node) as NonOpaqueStyleDataPtr + // XXXManishearth should GeckoNode just contain an &'ln RawGeckoNode? + Borrowed::from_ffi(Gecko_GetNodeData(&*self.node)) } } pub fn initialize_data(self) { unsafe { if self.get_node_data().is_null() { - let ptr: NonOpaqueStyleDataPtr = Box::into_raw(Box::new(RefCell::new(PrivateStyleData::new()))); - Gecko_SetNodeData(self.node, ptr as *mut ServoNodeData); + let ptr = Box::new(NonOpaqueStyleData::new()); + Gecko_SetNodeData(&mut *self.node, ptr.into_ffi().maybe()); } } } @@ -212,7 +225,7 @@ impl<'ln> TNode for GeckoNode<'ln> { fn is_dirty(&self) -> bool { // Return true unconditionally if we're not yet styled. This is a hack // and should go away soon. - if unsafe { Gecko_GetNodeData(self.node) }.is_null() { + if self.get_node_data().is_null() { return true; } @@ -231,7 +244,7 @@ impl<'ln> TNode for GeckoNode<'ln> { fn has_dirty_descendants(&self) -> bool { // Return true unconditionally if we're not yet styled. This is a hack // and should go away soon. - if unsafe { Gecko_GetNodeData(self.node) }.is_null() { + if self.get_node_data().is_null() { return true; } let flags = unsafe { Gecko_GetNodeFlags(self.node) }; @@ -259,21 +272,18 @@ impl<'ln> TNode for GeckoNode<'ln> { #[inline(always)] unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData> { - self.get_node_data().as_ref().map(|d| d.as_unsafe_cell().get() as *const PrivateStyleData) + self.get_node_data().borrow_opt().map(|d| d.0.as_unsafe_cell().get() + as *const PrivateStyleData) } #[inline(always)] fn borrow_data(&self) -> Option> { - unsafe { - self.get_node_data().as_ref().map(|d| d.borrow()) - } + self.get_node_data().borrow_opt().map(|d| d.0.borrow()) } #[inline(always)] fn mutate_data(&self) -> Option> { - unsafe { - self.get_node_data().as_ref().map(|d| d.borrow_mut()) - } + self.get_node_data().borrow_opt().map(|d| d.0.borrow_mut()) } fn restyle_damage(self) -> Self::ConcreteRestyleDamage { From 0d4c5674ec06e7e4b6484b70af4d8ea3c9b1a9ba Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 24 Aug 2016 22:29:46 +0530 Subject: [PATCH 6/7] Handle RawGeckoElement and friends, add support for types which are used in both maybe-null and non-null forms --- components/style/properties/gecko.mako.rs | 6 +- ports/geckolib/binding_tools/regen.py | 30 ++- ports/geckolib/gecko_bindings/bindings.rs | 239 ++++++++++-------- .../gecko_bindings/sugar/ownership.rs | 2 +- ports/geckolib/glue.rs | 78 +++--- ports/geckolib/wrapper.rs | 161 +++++------- 6 files changed, 260 insertions(+), 256 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 65d2173e08c..70509de16da 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -24,7 +24,7 @@ use gecko_bindings::bindings::{Gecko_EnsureImageLayersLength, Gecko_CreateGradie use gecko_bindings::bindings::{Gecko_CopyImageValueFrom, Gecko_CopyFontFamilyFrom}; use gecko_bindings::bindings::{Gecko_FontFamilyList_AppendGeneric, Gecko_FontFamilyList_AppendNamed}; use gecko_bindings::bindings::{Gecko_FontFamilyList_Clear, Gecko_InitializeImageLayer}; -use gecko_bindings::bindings::ServoComputedValuesBorrowed; +use gecko_bindings::bindings::ServoComputedValuesMaybeBorrowed; use gecko_bindings::structs; use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut}; use gecko_values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba}; @@ -1712,8 +1712,8 @@ fn static_assert() { <%def name="define_ffi_struct_accessor(style_struct)"> #[no_mangle] #[allow(non_snake_case, unused_variables)] -pub extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values: ServoComputedValuesBorrowed) - -> *const ${style_struct.gecko_ffi_name} { +pub extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const ${style_struct.gecko_ffi_name} { computed_values.as_arc::().get_${style_struct.name_lower}().get_gecko() as *const ${style_struct.gecko_ffi_name} } diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index d293d5047ec..31d9857e793 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -156,11 +156,15 @@ COMPILATION_TARGETS = { ], "servo_owned_types": [ "RawServoStyleSet", - "RawGeckoNode", ], "servo_maybe_owned_types": [ "ServoNodeData", ], + "servo_immutable_borrow_types": [ + "RawGeckoNode", + "RawGeckoElement", + "RawGeckoDocument", + ], }, "atoms": { @@ -329,9 +333,19 @@ def build(objdir, target_name, debug, debugger, kind_name=None, flags.append("--raw-line") flags.append("pub type {0}Strong = ::sugar::ownership::Strong<{0}>;".format(ty)) flags.append("--blacklist-type") + flags.append("{}MaybeBorrowed".format(ty)) + flags.append("-raw-line") + flags.append("pub type {0}MaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;".format(ty)) + if "servo_immutable_borrow_types" in current_target: + for ty in current_target["servo_immutable_borrow_types"]: + flags.append("-blacklist-type") flags.append("{}Borrowed".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}Borrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;".format(ty)) + flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) + flags.append("--blacklist-type") + flags.append("{}MaybeBorrowed".format(ty)) + flags.append("--raw-line") + flags.append("pub type {0}MaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;".format(ty)) if "servo_owned_types" in current_target: for ty in current_target["servo_owned_types"]: flags.append("--blacklist-type") @@ -349,19 +363,19 @@ def build(objdir, target_name, debug, debugger, kind_name=None, if "servo_maybe_owned_types" in current_target: for ty in current_target["servo_maybe_owned_types"]: flags.append("--blacklist-type") - flags.append("{}Borrowed".format(ty)) + flags.append("{}MaybeBorrowed".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}Borrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;" + flags.append("pub type {0}MaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;" .format(ty)) flags.append("--blacklist-type") - flags.append("{}BorrowedMut".format(ty)) + flags.append("{}MaybeBorrowedMut".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}BorrowedMut<'a> = ::sugar::ownership::BorrowedMut<'a, {0}>;" + flags.append("pub type {0}MaybeBorrowedMut<'a> = ::sugar::ownership::BorrowedMut<'a, {0}>;" .format(ty)) flags.append("--blacklist-type") - flags.append("{}Owned".format(ty)) + flags.append("{}MaybeOwned".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}Owned = ::sugar::ownership::MaybeOwned<{0}>;".format(ty)) + flags.append("pub type {0}MaybeOwned = ::sugar::ownership::MaybeOwned<{0}>;".format(ty)) if "structs_types" in current_target: for ty in current_target["structs_types"]: ty_fragments = ty.split("::") diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 52c11df627d..876303f52ba 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -6,20 +6,23 @@ pub enum nsIDocument {} pub enum nsIPrincipal {} pub enum nsIURI {} pub type ServoComputedValuesStrong = ::sugar::ownership::Strong; -pub type ServoComputedValuesBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoComputedValues>; +pub type ServoComputedValuesMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoComputedValues>; pub type RawServoStyleSheetStrong = ::sugar::ownership::Strong; -pub type RawServoStyleSheetBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawServoStyleSheet>; +pub type RawServoStyleSheetMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawServoStyleSheet>; pub type ServoDeclarationBlockStrong = ::sugar::ownership::Strong; -pub type ServoDeclarationBlockBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoDeclarationBlock>; +pub type ServoDeclarationBlockMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoDeclarationBlock>; +pub type RawGeckoNodeBorrowed<'a> = &'a RawGeckoNode; +pub type RawGeckoNodeMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoNode>; +pub type RawGeckoElementBorrowed<'a> = &'a RawGeckoElement; +pub type RawGeckoElementMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoElement>; +pub type RawGeckoDocumentBorrowed<'a> = &'a RawGeckoDocument; +pub type RawGeckoDocumentMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoDocument>; pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; pub type RawServoStyleSetOwned = ::sugar::ownership::Owned; -pub type RawGeckoNodeBorrowed<'a> = &'a RawGeckoNode; -pub type RawGeckoNodeBorrowedMut<'a> = &'a mut RawGeckoNode; -pub type RawGeckoNodeOwned = ::sugar::ownership::Owned; -pub type ServoNodeDataBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoNodeData>; -pub type ServoNodeDataBorrowedMut<'a> = ::sugar::ownership::BorrowedMut<'a, ServoNodeData>; -pub type ServoNodeDataOwned = ::sugar::ownership::MaybeOwned; +pub type ServoNodeDataMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoNodeData>; +pub type ServoNodeDataMaybeBorrowedMut<'a> = ::sugar::ownership::BorrowedMut<'a, ServoNodeData>; +pub type ServoNodeDataMaybeOwned = ::sugar::ownership::MaybeOwned; use structs::nsStyleFont; unsafe impl Send for nsStyleFont {} unsafe impl Sync for nsStyleFont {} @@ -182,26 +185,31 @@ pub enum StyleChildrenIterator { } pub type ThreadSafePrincipalHolder = nsMainThreadPtrHolder; pub type ThreadSafeURIHolder = nsMainThreadPtrHolder; extern "C" { - pub fn Gecko_ChildrenCount(node: *mut RawGeckoNode) -> u32; - pub fn Gecko_NodeIsElement(node: *mut RawGeckoNode) -> bool; - pub fn Gecko_GetParentNode(node: *mut RawGeckoNode) -> *mut RawGeckoNode; - pub fn Gecko_GetFirstChild(node: *mut RawGeckoNode) -> *mut RawGeckoNode; - pub fn Gecko_GetLastChild(node: *mut RawGeckoNode) -> *mut RawGeckoNode; - pub fn Gecko_GetPrevSibling(node: *mut RawGeckoNode) -> *mut RawGeckoNode; - pub fn Gecko_GetNextSibling(node: *mut RawGeckoNode) -> *mut RawGeckoNode; - pub fn Gecko_GetParentElement(element: *mut RawGeckoElement) - -> *mut RawGeckoElement; - pub fn Gecko_GetFirstChildElement(element: *mut RawGeckoElement) - -> *mut RawGeckoElement; - pub fn Gecko_GetLastChildElement(element: *mut RawGeckoElement) - -> *mut RawGeckoElement; - pub fn Gecko_GetPrevSiblingElement(element: *mut RawGeckoElement) - -> *mut RawGeckoElement; - pub fn Gecko_GetNextSiblingElement(element: *mut RawGeckoElement) - -> *mut RawGeckoElement; - pub fn Gecko_GetDocumentElement(document: *mut RawGeckoDocument) - -> *mut RawGeckoElement; - pub fn Gecko_MaybeCreateStyleChildrenIterator(node: *mut RawGeckoNode) + pub fn Gecko_ChildrenCount(node: RawGeckoNodeBorrowed) -> u32; + pub fn Gecko_NodeIsElement(node: RawGeckoNodeBorrowed) -> bool; + pub fn Gecko_GetParentNode(node: RawGeckoNodeBorrowed) + -> RawGeckoNodeMaybeBorrowed; + pub fn Gecko_GetFirstChild(node: RawGeckoNodeBorrowed) + -> RawGeckoNodeMaybeBorrowed; + pub fn Gecko_GetLastChild(node: RawGeckoNodeBorrowed) + -> RawGeckoNodeMaybeBorrowed; + pub fn Gecko_GetPrevSibling(node: RawGeckoNodeBorrowed) + -> RawGeckoNodeMaybeBorrowed; + pub fn Gecko_GetNextSibling(node: RawGeckoNodeBorrowed) + -> RawGeckoNodeMaybeBorrowed; + pub fn Gecko_GetParentElement(element: RawGeckoElementBorrowed) + -> RawGeckoElementMaybeBorrowed; + pub fn Gecko_GetFirstChildElement(element: RawGeckoElementBorrowed) + -> RawGeckoElementMaybeBorrowed; + pub fn Gecko_GetLastChildElement(element: RawGeckoElementBorrowed) + -> RawGeckoElementMaybeBorrowed; + pub fn Gecko_GetPrevSiblingElement(element: RawGeckoElementBorrowed) + -> RawGeckoElementMaybeBorrowed; + pub fn Gecko_GetNextSiblingElement(element: RawGeckoElementBorrowed) + -> RawGeckoElementMaybeBorrowed; + pub fn Gecko_GetDocumentElement(document: RawGeckoDocumentBorrowed) + -> RawGeckoElementMaybeBorrowed; + pub fn Gecko_MaybeCreateStyleChildrenIterator(node: RawGeckoNodeBorrowed) -> *mut StyleChildrenIterator; pub fn Gecko_DropStyleChildrenIterator(it: *mut StyleChildrenIterator); pub fn Gecko_GetNextStyleChild(it: *mut StyleChildrenIterator) @@ -209,36 +217,38 @@ extern "C" { pub fn Gecko_ElementState(element: *mut RawGeckoElement) -> u8; pub fn Gecko_IsHTMLElementInHTMLDocument(element: *mut RawGeckoElement) -> bool; - pub fn Gecko_IsLink(element: *mut RawGeckoElement) -> bool; - pub fn Gecko_IsTextNode(node: *mut RawGeckoNode) -> bool; - pub fn Gecko_IsVisitedLink(element: *mut RawGeckoElement) -> bool; - pub fn Gecko_IsUnvisitedLink(element: *mut RawGeckoElement) -> bool; - pub fn Gecko_IsRootElement(element: *mut RawGeckoElement) -> bool; - pub fn Gecko_LocalName(element: *mut RawGeckoElement) -> *mut nsIAtom; - pub fn Gecko_Namespace(element: *mut RawGeckoElement) -> *mut nsIAtom; - pub fn Gecko_GetElementId(element: *mut RawGeckoElement) -> *mut nsIAtom; - pub fn Gecko_AtomAttrValue(element: *mut RawGeckoElement, + pub fn Gecko_IsLink(element: RawGeckoElementBorrowed) -> bool; + pub fn Gecko_IsTextNode(node: RawGeckoNodeBorrowed) -> bool; + pub fn Gecko_IsVisitedLink(element: RawGeckoElementBorrowed) -> bool; + pub fn Gecko_IsUnvisitedLink(element: RawGeckoElementBorrowed) -> bool; + pub fn Gecko_IsRootElement(element: RawGeckoElementBorrowed) -> bool; + pub fn Gecko_LocalName(element: RawGeckoElementBorrowed) -> *mut nsIAtom; + pub fn Gecko_Namespace(element: RawGeckoElementBorrowed) -> *mut nsIAtom; + pub fn Gecko_GetElementId(element: RawGeckoElementBorrowed) + -> *mut nsIAtom; + pub fn Gecko_AtomAttrValue(element: RawGeckoElementBorrowed, attribute: *mut nsIAtom) -> *mut nsIAtom; - pub fn Gecko_HasAttr(element: *mut RawGeckoElement, ns: *mut nsIAtom, + pub fn Gecko_HasAttr(element: RawGeckoElementBorrowed, ns: *mut nsIAtom, name: *mut nsIAtom) -> bool; - pub fn Gecko_AttrEquals(element: *mut RawGeckoElement, ns: *mut nsIAtom, - name: *mut nsIAtom, str: *mut nsIAtom, - ignoreCase: bool) -> bool; - pub fn Gecko_AttrDashEquals(element: *mut RawGeckoElement, + pub fn Gecko_AttrEquals(element: RawGeckoElementBorrowed, + ns: *mut nsIAtom, name: *mut nsIAtom, + str: *mut nsIAtom, ignoreCase: bool) -> bool; + pub fn Gecko_AttrDashEquals(element: RawGeckoElementBorrowed, ns: *mut nsIAtom, name: *mut nsIAtom, str: *mut nsIAtom) -> bool; - pub fn Gecko_AttrIncludes(element: *mut RawGeckoElement, ns: *mut nsIAtom, - name: *mut nsIAtom, str: *mut nsIAtom) -> bool; - pub fn Gecko_AttrHasSubstring(element: *mut RawGeckoElement, + pub fn Gecko_AttrIncludes(element: RawGeckoElementBorrowed, + ns: *mut nsIAtom, name: *mut nsIAtom, + str: *mut nsIAtom) -> bool; + pub fn Gecko_AttrHasSubstring(element: RawGeckoElementBorrowed, ns: *mut nsIAtom, name: *mut nsIAtom, str: *mut nsIAtom) -> bool; - pub fn Gecko_AttrHasPrefix(element: *mut RawGeckoElement, + pub fn Gecko_AttrHasPrefix(element: RawGeckoElementBorrowed, ns: *mut nsIAtom, name: *mut nsIAtom, str: *mut nsIAtom) -> bool; - pub fn Gecko_AttrHasSuffix(element: *mut RawGeckoElement, + pub fn Gecko_AttrHasSuffix(element: RawGeckoElementBorrowed, ns: *mut nsIAtom, name: *mut nsIAtom, str: *mut nsIAtom) -> bool; - pub fn Gecko_ClassOrClassList(element: *mut RawGeckoElement, + pub fn Gecko_ClassOrClassList(element: RawGeckoElementBorrowed, class_: *mut *mut nsIAtom, classList: *mut *mut *mut nsIAtom) -> u32; pub fn Gecko_SnapshotAtomAttrValue(element: *mut ServoElementSnapshot, @@ -271,12 +281,12 @@ extern "C" { class_: *mut *mut nsIAtom, classList: *mut *mut *mut nsIAtom) -> u32; - pub fn Gecko_GetServoDeclarationBlock(element: *mut RawGeckoElement) - -> ServoDeclarationBlockBorrowed; + pub fn Gecko_GetServoDeclarationBlock(element: RawGeckoElementBorrowed) + -> ServoDeclarationBlockMaybeBorrowed; pub fn Gecko_GetNodeData(node: RawGeckoNodeBorrowed) - -> ServoNodeDataBorrowed; - pub fn Gecko_SetNodeData(node: RawGeckoNodeBorrowedMut, - data: ServoNodeDataOwned); + -> ServoNodeDataMaybeBorrowed; + pub fn Gecko_SetNodeData(node: RawGeckoNodeBorrowed, + data: ServoNodeDataMaybeOwned); pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32) -> *mut nsIAtom; pub fn Gecko_AddRefAtom(aAtom: *mut nsIAtom); @@ -320,16 +330,17 @@ extern "C" { principal: *mut ThreadSafePrincipalHolder); pub fn Gecko_CopyMozBindingFrom(des: *mut nsStyleDisplay, src: *const nsStyleDisplay); - pub fn Gecko_GetNodeFlags(node: *mut RawGeckoNode) -> u32; - pub fn Gecko_SetNodeFlags(node: *mut RawGeckoNode, flags: u32); - pub fn Gecko_UnsetNodeFlags(node: *mut RawGeckoNode, flags: u32); - pub fn Gecko_GetStyleContext(node: *mut RawGeckoNode, + pub fn Gecko_GetNodeFlags(node: RawGeckoNodeBorrowed) -> u32; + pub fn Gecko_SetNodeFlags(node: RawGeckoNodeBorrowed, flags: u32); + pub fn Gecko_UnsetNodeFlags(node: RawGeckoNodeBorrowed, flags: u32); + pub fn Gecko_GetStyleContext(node: RawGeckoNodeBorrowed, aPseudoTagOrNull: *mut nsIAtom) -> *mut nsStyleContext; pub fn Gecko_CalcStyleDifference(oldstyle: *mut nsStyleContext, - newstyle: ServoComputedValuesBorrowed) + newstyle: + ServoComputedValuesMaybeBorrowed) -> nsChangeHint; - pub fn Gecko_StoreStyleDifference(node: *mut RawGeckoNode, + pub fn Gecko_StoreStyleDifference(node: RawGeckoNodeBorrowed, change: nsChangeHint); pub fn Gecko_EnsureTArrayCapacity(array: *mut ::std::os::raw::c_void, capacity: usize, elem_size: usize); @@ -466,7 +477,7 @@ extern "C" { pub fn Gecko_CopyConstruct_nsStyleEffects(ptr: *mut nsStyleEffects, other: *const nsStyleEffects); pub fn Gecko_Destroy_nsStyleEffects(ptr: *mut nsStyleEffects); - pub fn Servo_NodeData_Drop(data: ServoNodeDataOwned); + pub fn Servo_NodeData_Drop(data: ServoNodeDataMaybeOwned); pub fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8, length: u32, parsing_mode: SheetParsingMode, base_bytes: *const u8, @@ -476,49 +487,49 @@ extern "C" { principal: *mut ThreadSafePrincipalHolder) -> RawServoStyleSheetStrong; - pub fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetBorrowed); - pub fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed); - pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed) + pub fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetMaybeBorrowed); + pub fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetMaybeBorrowed); + pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetMaybeBorrowed) -> bool; pub fn Servo_StyleSet_Init() -> RawServoStyleSetOwned; pub fn Servo_StyleSet_Drop(set: RawServoStyleSetOwned); pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowedMut, - sheet: RawServoStyleSheetBorrowed); + sheet: RawServoStyleSheetMaybeBorrowed); pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowedMut, sheet: - RawServoStyleSheetBorrowed); + RawServoStyleSheetMaybeBorrowed); pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowedMut, - sheet: RawServoStyleSheetBorrowed); + sheet: RawServoStyleSheetMaybeBorrowed); pub fn Servo_StyleSet_InsertStyleSheetBefore(set: RawServoStyleSetBorrowedMut, sheet: - RawServoStyleSheetBorrowed, + RawServoStyleSheetMaybeBorrowed, reference: - RawServoStyleSheetBorrowed); + RawServoStyleSheetMaybeBorrowed); pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32, cache: *mut nsHTMLCSSStyleSheet) -> ServoDeclarationBlockStrong; pub fn Servo_DeclarationBlock_AddRef(declarations: - ServoDeclarationBlockBorrowed); + ServoDeclarationBlockMaybeBorrowed); pub fn Servo_DeclarationBlock_Release(declarations: - ServoDeclarationBlockBorrowed); + ServoDeclarationBlockMaybeBorrowed); pub fn Servo_DeclarationBlock_GetCache(declarations: - ServoDeclarationBlockBorrowed) + ServoDeclarationBlockMaybeBorrowed) -> *mut nsHTMLCSSStyleSheet; pub fn Servo_DeclarationBlock_SetImmutable(declarations: - ServoDeclarationBlockBorrowed); + ServoDeclarationBlockMaybeBorrowed); pub fn Servo_DeclarationBlock_ClearCachePointer(declarations: - ServoDeclarationBlockBorrowed); + ServoDeclarationBlockMaybeBorrowed); pub fn Servo_CSSSupports(name: *const u8, name_length: u32, value: *const u8, value_length: u32) -> bool; - pub fn Servo_ComputedValues_Get(node: *mut RawGeckoNode) + pub fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: - ServoComputedValuesBorrowed, + ServoComputedValuesMaybeBorrowed, pseudoTag: *mut nsIAtom, set: RawServoStyleSetBorrowedMut) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_GetForPseudoElement(parent_style: - ServoComputedValuesBorrowed, + ServoComputedValuesMaybeBorrowed, match_element: *mut RawGeckoElement, pseudo_tag: *mut nsIAtom, @@ -527,76 +538,92 @@ extern "C" { is_probe: bool) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_Inherit(parent_style: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_AddRef(computed_values: - ServoComputedValuesBorrowed); + ServoComputedValuesMaybeBorrowed); pub fn Servo_ComputedValues_Release(computed_values: - ServoComputedValuesBorrowed); + ServoComputedValuesMaybeBorrowed); pub fn Servo_Initialize(); pub fn Servo_Shutdown(); pub fn Servo_ComputeRestyleHint(element: *mut RawGeckoElement, snapshot: *mut ServoElementSnapshot, set: RawServoStyleSetBorrowedMut) -> nsRestyleHint; - pub fn Servo_RestyleDocument(doc: *mut RawGeckoDocument, + pub fn Servo_RestyleDocument(doc: RawGeckoDocumentBorrowed, set: RawServoStyleSetBorrowedMut); - pub fn Servo_RestyleSubtree(node: *mut RawGeckoNode, + pub fn Servo_RestyleSubtree(node: RawGeckoNodeBorrowed, set: RawServoStyleSetBorrowedMut); - pub fn Servo_GetStyleFont(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleFont(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleFont; - pub fn Servo_GetStyleColor(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleColor(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleColor; - pub fn Servo_GetStyleList(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleList(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleList; - pub fn Servo_GetStyleText(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleText(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleText; pub fn Servo_GetStyleVisibility(computed_values: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> *const nsStyleVisibility; pub fn Servo_GetStyleUserInterface(computed_values: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> *const nsStyleUserInterface; pub fn Servo_GetStyleTableBorder(computed_values: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> *const nsStyleTableBorder; - pub fn Servo_GetStyleSVG(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleSVG(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleSVG; pub fn Servo_GetStyleVariables(computed_values: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> *const nsStyleVariables; pub fn Servo_GetStyleBackground(computed_values: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> *const nsStyleBackground; pub fn Servo_GetStylePosition(computed_values: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> *const nsStylePosition; pub fn Servo_GetStyleTextReset(computed_values: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> *const nsStyleTextReset; - pub fn Servo_GetStyleDisplay(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleDisplay(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleDisplay; - pub fn Servo_GetStyleContent(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleContent(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleContent; - pub fn Servo_GetStyleUIReset(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleUIReset(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleUIReset; - pub fn Servo_GetStyleTable(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleTable(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleTable; - pub fn Servo_GetStyleMargin(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleMargin(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleMargin; - pub fn Servo_GetStylePadding(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStylePadding(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStylePadding; - pub fn Servo_GetStyleBorder(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleBorder(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleBorder; - pub fn Servo_GetStyleOutline(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleOutline(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleOutline; - pub fn Servo_GetStyleXUL(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleXUL(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleXUL; pub fn Servo_GetStyleSVGReset(computed_values: - ServoComputedValuesBorrowed) + ServoComputedValuesMaybeBorrowed) -> *const nsStyleSVGReset; - pub fn Servo_GetStyleColumn(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleColumn(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleColumn; - pub fn Servo_GetStyleEffects(computed_values: ServoComputedValuesBorrowed) + pub fn Servo_GetStyleEffects(computed_values: + ServoComputedValuesMaybeBorrowed) -> *const nsStyleEffects; } diff --git a/ports/geckolib/gecko_bindings/sugar/ownership.rs b/ports/geckolib/gecko_bindings/sugar/ownership.rs index 46a7500819c..bc6273bb8a5 100644 --- a/ports/geckolib/gecko_bindings/sugar/ownership.rs +++ b/ports/geckolib/gecko_bindings/sugar/ownership.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::marker::PhantomData; -use std::mem::{forget, transmute}; +use std::mem::{forget, transmute, transmute_copy}; use std::ops::{Deref, DerefMut}; use std::ptr; use std::sync::Arc; diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 95696089349..f21c4242849 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -9,12 +9,14 @@ use data::{NUM_THREADS, PerDocumentStyleData}; use env_logger; use euclid::Size2D; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; +use gecko_bindings::bindings::RawGeckoDocumentBorrowed; +use gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoNodeBorrowed}; use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSetBorrowedMut}; -use gecko_bindings::bindings::{RawServoStyleSetOwned, ServoNodeDataOwned}; -use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; +use gecko_bindings::bindings::{RawServoStyleSetOwned, ServoNodeDataMaybeOwned}; +use gecko_bindings::bindings::{RawServoStyleSheetMaybeBorrowed, ServoComputedValuesMaybeBorrowed}; use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong}; use gecko_bindings::bindings::{ServoDeclarationBlock, ThreadSafePrincipalHolder}; -use gecko_bindings::bindings::{ServoDeclarationBlockBorrowed, ServoDeclarationBlockStrong}; +use gecko_bindings::bindings::{ServoDeclarationBlockMaybeBorrowed, ServoDeclarationBlockStrong}; use gecko_bindings::bindings::{ThreadSafeURIHolder, nsHTMLCSSStyleSheet}; use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; use gecko_bindings::structs::ServoElementSnapshot; @@ -114,15 +116,15 @@ fn restyle_subtree(node: GeckoNode, raw_data: RawServoStyleSetBorrowedMut) { } #[no_mangle] -pub extern "C" fn Servo_RestyleSubtree(node: *mut RawGeckoNode, +pub extern "C" fn Servo_RestyleSubtree(node: RawGeckoNodeBorrowed, raw_data: RawServoStyleSetBorrowedMut) -> () { - let node = unsafe { GeckoNode::from_raw(node) }; + let node = GeckoNode(node); restyle_subtree(node, raw_data); } #[no_mangle] -pub extern "C" fn Servo_RestyleDocument(doc: *mut RawGeckoDocument, raw_data: RawServoStyleSetBorrowedMut) -> () { - let document = unsafe { GeckoDocument::from_raw(doc) }; +pub extern "C" fn Servo_RestyleDocument(doc: RawGeckoDocumentBorrowed, raw_data: RawServoStyleSetBorrowedMut) -> () { + let document = GeckoDocument(doc); let node = match document.root_node() { Some(x) => x, None => return, @@ -136,7 +138,7 @@ pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 { } #[no_mangle] -pub extern "C" fn Servo_NodeData_Drop(data: ServoNodeDataOwned) -> () { +pub extern "C" fn Servo_NodeData_Drop(data: ServoNodeDataMaybeOwned) -> () { let _ = data.into_box_opt::(); } @@ -174,7 +176,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8, #[no_mangle] pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowedMut, - raw_sheet: RawServoStyleSheetBorrowed) { + raw_sheet: RawServoStyleSheetMaybeBorrowed) { let data = PerDocumentStyleData::from_ffi_mut(raw_data); let sheet = raw_sheet.as_arc(); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); @@ -184,7 +186,7 @@ pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorr #[no_mangle] pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowedMut, - raw_sheet: RawServoStyleSheetBorrowed) { + raw_sheet: RawServoStyleSheetMaybeBorrowed) { let data = PerDocumentStyleData::from_ffi_mut(raw_data); let sheet = raw_sheet.as_arc(); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); @@ -194,8 +196,8 @@ pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBor #[no_mangle] pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowedMut, - raw_sheet: RawServoStyleSheetBorrowed, - raw_reference: RawServoStyleSheetBorrowed) { + raw_sheet: RawServoStyleSheetMaybeBorrowed, + raw_reference: RawServoStyleSheetMaybeBorrowed) { let data = PerDocumentStyleData::from_ffi_mut(raw_data); let sheet = raw_sheet.as_arc(); let reference = raw_reference.as_arc(); @@ -207,7 +209,7 @@ pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleS #[no_mangle] pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorrowedMut, - raw_sheet: RawServoStyleSheetBorrowed) { + raw_sheet: RawServoStyleSheetMaybeBorrowed) { let data = PerDocumentStyleData::from_ffi_mut(raw_data); let sheet = raw_sheet.as_arc(); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); @@ -215,24 +217,24 @@ pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorr } #[no_mangle] -pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool { +pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetMaybeBorrowed) -> bool { !raw_sheet.as_arc::().rules.is_empty() } #[no_mangle] -pub extern "C" fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetBorrowed) -> () { +pub extern "C" fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetMaybeBorrowed) -> () { unsafe { Stylesheet::addref(sheet) }; } #[no_mangle] -pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed) -> () { +pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetMaybeBorrowed) -> () { unsafe { Stylesheet::release(sheet) }; } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_Get(node: *mut RawGeckoNode) +pub extern "C" fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed) -> ServoComputedValuesStrong { - let node = unsafe { GeckoNode::from_raw(node) }; + let node = unsafe { GeckoNode(node) }; let arc_cv = match node.borrow_data().map_or(None, |data| data.style.clone()) { Some(style) => style, None => { @@ -248,7 +250,7 @@ pub extern "C" fn Servo_ComputedValues_Get(node: *mut RawGeckoNode) } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowed, +pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesMaybeBorrowed, pseudo_tag: *mut nsIAtom, raw_data: RawServoStyleSetBorrowedMut) -> ServoComputedValuesStrong { @@ -266,13 +268,13 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoComputedValuesBorrowed, - match_element: *mut RawGeckoElement, - pseudo_tag: *mut nsIAtom, - raw_data: RawServoStyleSetBorrowedMut, - is_probe: bool) +pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoComputedValuesMaybeBorrowed, + match_element: RawGeckoElementBorrowed, + pseudo_tag: *mut nsIAtom, + raw_data: RawServoStyleSetBorrowedMut, + is_probe: bool) -> ServoComputedValuesStrong { - debug_assert!(!match_element.is_null()); + debug_assert!(!(match_element as *const _).is_null()); let parent_or_null = || { if is_probe { @@ -289,7 +291,7 @@ pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoCo let data = PerDocumentStyleData::from_ffi_mut(raw_data); data.flush_stylesheets(); - let element = unsafe { GeckoElement::from_raw(match_element) }; + let element = unsafe { GeckoElement(match_element) }; match GeckoSelectorImpl::pseudo_element_cascade_type(&pseudo) { @@ -315,7 +317,7 @@ pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoCo } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValuesBorrowed) +pub extern "C" fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValuesMaybeBorrowed) -> ServoComputedValuesStrong { let style = if parent_style.is_null() { Arc::new(ComputedValues::initial_values().clone()) @@ -326,12 +328,12 @@ pub extern "C" fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValues } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed) -> () { +pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesMaybeBorrowed) -> () { unsafe { ComputedValues::addref(ptr) }; } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) -> () { +pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesMaybeBorrowed) -> () { unsafe { ComputedValues::release(ptr) }; } @@ -376,28 +378,28 @@ pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32, } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: ServoDeclarationBlockBorrowed) { +pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: ServoDeclarationBlockMaybeBorrowed) { unsafe { GeckoDeclarationBlock::addref(declarations) }; } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationBlockBorrowed) { +pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationBlockMaybeBorrowed) { unsafe { GeckoDeclarationBlock::release(declarations) }; } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_GetCache(declarations: ServoDeclarationBlockBorrowed) +pub extern "C" fn Servo_DeclarationBlock_GetCache(declarations: ServoDeclarationBlockMaybeBorrowed) -> *mut nsHTMLCSSStyleSheet { declarations.as_arc::().cache.load(Ordering::Relaxed) } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_SetImmutable(declarations: ServoDeclarationBlockBorrowed) { +pub extern "C" fn Servo_DeclarationBlock_SetImmutable(declarations: ServoDeclarationBlockMaybeBorrowed) { declarations.as_arc::().immutable.store(true, Ordering::Relaxed) } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_ClearCachePointer(declarations: ServoDeclarationBlockBorrowed) { +pub extern "C" fn Servo_DeclarationBlock_ClearCachePointer(declarations: ServoDeclarationBlockMaybeBorrowed) { declarations.as_arc::().cache.store(ptr::null_mut(), Ordering::Relaxed) } @@ -417,12 +419,12 @@ pub extern "C" fn Servo_CSSSupports(property: *const u8, property_length: u32, } #[no_mangle] -pub extern "C" fn Servo_ComputeRestyleHint(element: *mut RawGeckoElement, +pub extern "C" fn Servo_ComputeRestyleHint(element: RawGeckoElementBorrowed, snapshot: *mut ServoElementSnapshot, - raw_data: *mut RawServoStyleSet) -> nsRestyleHint { - let per_doc_data = unsafe { &mut *(raw_data as *mut PerDocumentStyleData) }; + raw_data: RawServoStyleSetBorrowedMut) -> nsRestyleHint { + let per_doc_data = PerDocumentStyleData::from_ffi_mut(raw_data); let snapshot = unsafe { GeckoElementSnapshot::from_raw(snapshot) }; - let element = unsafe { GeckoElement::from_raw(element) }; + let element = unsafe { GeckoElement(element) }; // NB: This involves an FFI call, we can get rid of it easily if needed. let current_state = element.get_state(); diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index 74e2e47fed7..a3856b6a612 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -23,6 +23,8 @@ use gecko_bindings::bindings::{Gecko_IsLink, Gecko_IsRootElement, Gecko_IsTextNo use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink}; use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetNodeData}; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; +use gecko_bindings::bindings::RawGeckoDocumentBorrowed; +use gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoNodeBorrowed}; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; use gecko_bindings::structs::{nsIAtom, nsChangeHint, nsStyleContext}; use gecko_bindings::sugar::ownership::Borrowed; @@ -74,35 +76,20 @@ impl NonOpaqueStyleData { // could implement refcounting if need be (at a potentially non-trivial // performance cost) by implementing Drop and making LayoutFoo non-Copy. #[derive(Clone, Copy)] -pub struct GeckoNode<'ln> { - node: *mut RawGeckoNode, - chain: PhantomData<&'ln ()>, -} +pub struct GeckoNode<'ln>(pub &'ln RawGeckoNode); impl<'ln> GeckoNode<'ln> { - pub unsafe fn from_raw(n: *mut RawGeckoNode) -> GeckoNode<'ln> { - GeckoNode { - node: n, - chain: PhantomData, - } - } - - unsafe fn from_ref(n: &RawGeckoNode) -> GeckoNode<'ln> { - GeckoNode::from_raw(n as *const RawGeckoNode as *mut RawGeckoNode) - } - fn get_node_data(&self) -> Borrowed { - unsafe { - // XXXManishearth should GeckoNode just contain an &'ln RawGeckoNode? - Borrowed::from_ffi(Gecko_GetNodeData(&*self.node)) - } + unsafe { + Borrowed::from_ffi(Gecko_GetNodeData(&*self.0)) + } } pub fn initialize_data(self) { unsafe { if self.get_node_data().is_null() { let ptr = Box::new(NonOpaqueStyleData::new()); - Gecko_SetNodeData(&mut *self.node, ptr.into_ffi().maybe()); + Gecko_SetNodeData(self.0, ptr.into_ffi().maybe()); } } } @@ -149,22 +136,22 @@ impl<'ln> TNode for GeckoNode<'ln> { type ConcreteChildrenIterator = GeckoChildrenIterator<'ln>; fn to_unsafe(&self) -> UnsafeNode { - (self.node as usize, 0) + (self.0 as *const _ as usize, 0) } unsafe fn from_unsafe(n: &UnsafeNode) -> Self { - GeckoNode::from_raw(n.0 as *mut RawGeckoNode) + GeckoNode(&*(n.0 as *mut RawGeckoNode)) } fn is_text_node(&self) -> bool { unsafe { - Gecko_IsTextNode(self.node) + Gecko_IsTextNode(self.0) } } fn is_element(&self) -> bool { unsafe { - Gecko_NodeIsElement(self.node) + Gecko_NodeIsElement(self.0) } } @@ -177,7 +164,7 @@ impl<'ln> TNode for GeckoNode<'ln> { } fn children(self) -> GeckoChildrenIterator<'ln> { - let maybe_iter = unsafe { Gecko_MaybeCreateStyleChildrenIterator(self.node) }; + let maybe_iter = unsafe { Gecko_MaybeCreateStyleChildrenIterator(self.0) }; if !maybe_iter.is_null() { GeckoChildrenIterator::GeckoIterator(maybe_iter) } else { @@ -186,7 +173,7 @@ impl<'ln> TNode for GeckoNode<'ln> { } fn opaque(&self) -> OpaqueNode { - let ptr: uintptr_t = self.node as uintptr_t; + let ptr: uintptr_t = self.0 as *const _ as uintptr_t; OpaqueNode(ptr) } @@ -204,7 +191,7 @@ impl<'ln> TNode for GeckoNode<'ln> { fn as_element(&self) -> Option> { if self.is_element() { - unsafe { Some(GeckoElement::from_raw(self.node as *mut RawGeckoElement)) } + unsafe { Some(GeckoElement(&*(self.0 as *const _ as *const RawGeckoElement))) } } else { None } @@ -229,15 +216,15 @@ impl<'ln> TNode for GeckoNode<'ln> { return true; } - let flags = unsafe { Gecko_GetNodeFlags(self.node) }; + let flags = unsafe { Gecko_GetNodeFlags(self.0) }; flags & (NODE_IS_DIRTY_FOR_SERVO as u32) != 0 } unsafe fn set_dirty(&self, value: bool) { if value { - Gecko_SetNodeFlags(self.node, NODE_IS_DIRTY_FOR_SERVO as u32) + Gecko_SetNodeFlags(self.0, NODE_IS_DIRTY_FOR_SERVO as u32) } else { - Gecko_UnsetNodeFlags(self.node, NODE_IS_DIRTY_FOR_SERVO as u32) + Gecko_UnsetNodeFlags(self.0, NODE_IS_DIRTY_FOR_SERVO as u32) } } @@ -247,15 +234,15 @@ impl<'ln> TNode for GeckoNode<'ln> { if self.get_node_data().is_null() { return true; } - let flags = unsafe { Gecko_GetNodeFlags(self.node) }; + let flags = unsafe { Gecko_GetNodeFlags(self.0) }; flags & (NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32) != 0 } unsafe fn set_dirty_descendants(&self, value: bool) { if value { - Gecko_SetNodeFlags(self.node, NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32) + Gecko_SetNodeFlags(self.0, NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32) } else { - Gecko_UnsetNodeFlags(self.node, NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32) + Gecko_UnsetNodeFlags(self.0, NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32) } } @@ -292,36 +279,36 @@ impl<'ln> TNode for GeckoNode<'ln> { } fn set_restyle_damage(self, damage: Self::ConcreteRestyleDamage) { - unsafe { Gecko_StoreStyleDifference(self.node, damage.0) } + unsafe { Gecko_StoreStyleDifference(self.0, damage.0) } } fn parent_node(&self) -> Option> { unsafe { - Gecko_GetParentNode(self.node).as_ref().map(|n| GeckoNode::from_ref(n)) + Gecko_GetParentNode(self.0).borrow_opt().map(|n| GeckoNode(n)) } } fn first_child(&self) -> Option> { unsafe { - Gecko_GetFirstChild(self.node).as_ref().map(|n| GeckoNode::from_ref(n)) + Gecko_GetFirstChild(self.0).borrow_opt().map(|n| GeckoNode(n)) } } fn last_child(&self) -> Option> { unsafe { - Gecko_GetLastChild(self.node).as_ref().map(|n| GeckoNode::from_ref(n)) + Gecko_GetLastChild(self.0).borrow_opt().map(|n| GeckoNode(n)) } } fn prev_sibling(&self) -> Option> { unsafe { - Gecko_GetPrevSibling(self.node).as_ref().map(|n| GeckoNode::from_ref(n)) + Gecko_GetPrevSibling(self.0).borrow_opt().map(|n| GeckoNode(n)) } } fn next_sibling(&self) -> Option> { unsafe { - Gecko_GetNextSibling(self.node).as_ref().map(|n| GeckoNode::from_ref(n)) + Gecko_GetNextSibling(self.0).borrow_opt().map(|n| GeckoNode(n)) } } @@ -337,7 +324,7 @@ impl<'ln> TNode for GeckoNode<'ln> { unsafe { let atom_ptr = pseudo.map(|p| p.as_atom().as_ptr()) .unwrap_or(ptr::null_mut()); - let context_ptr = Gecko_GetStyleContext(self.node, atom_ptr); + let context_ptr = Gecko_GetStyleContext(self.0, atom_ptr); context_ptr.as_ref() } } @@ -389,38 +376,26 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> { } #[derive(Clone, Copy)] -pub struct GeckoDocument<'ld> { - document: *mut RawGeckoDocument, - chain: PhantomData<&'ld ()>, -} - -impl<'ld> GeckoDocument<'ld> { - pub unsafe fn from_raw(doc: *mut RawGeckoDocument) -> GeckoDocument<'ld> { - GeckoDocument { - document: doc, - chain: PhantomData, - } - } -} +pub struct GeckoDocument<'ld>(pub &'ld RawGeckoDocument); impl<'ld> TDocument for GeckoDocument<'ld> { type ConcreteNode = GeckoNode<'ld>; type ConcreteElement = GeckoElement<'ld>; fn as_node(&self) -> GeckoNode<'ld> { - unsafe { GeckoNode::from_raw(self.document as *mut RawGeckoNode) } + unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) } } fn root_node(&self) -> Option> { unsafe { - Gecko_GetDocumentElement(self.document).as_ref().map(|el| GeckoElement::from_ref(el).as_node()) + Gecko_GetDocumentElement(self.0).borrow_opt().map(|el| GeckoElement(el).as_node()) } } fn drain_modified_elements(&self) -> Vec<(GeckoElement<'ld>, GeckoElementSnapshot)> { unimplemented!() /* - let elements = unsafe { self.document.drain_modified_elements() }; + let elements = unsafe { self.0.drain_modified_elements() }; elements.into_iter().map(|(el, snapshot)| (ServoLayoutElement::from_layout_js(el), snapshot)).collect()*/ } fn will_paint(&self) { unimplemented!() } @@ -428,10 +403,7 @@ impl<'ld> TDocument for GeckoDocument<'ld> { } #[derive(Clone, Copy)] -pub struct GeckoElement<'le> { - element: *mut RawGeckoElement, - chain: PhantomData<&'le ()>, -} +pub struct GeckoElement<'le>(pub &'le RawGeckoElement); impl<'le> fmt::Debug for GeckoElement<'le> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -444,17 +416,6 @@ impl<'le> fmt::Debug for GeckoElement<'le> { } impl<'le> GeckoElement<'le> { - pub unsafe fn from_raw(el: *mut RawGeckoElement) -> GeckoElement<'le> { - GeckoElement { - element: el, - chain: PhantomData, - } - } - - unsafe fn from_ref(el: &RawGeckoElement) -> GeckoElement<'le> { - GeckoElement::from_raw(el as *const RawGeckoElement as *mut RawGeckoElement) - } - pub fn parse_style_attribute(value: &str) -> Option { // FIXME(bholley): Real base URL and error reporter. let base_url = &*DUMMY_BASE_URL; @@ -476,11 +437,11 @@ impl<'le> TElement for GeckoElement<'le> { type ConcreteDocument = GeckoDocument<'le>; fn as_node(&self) -> Self::ConcreteNode { - unsafe { GeckoNode::from_raw(self.element as *mut RawGeckoNode) } + unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) } } fn style_attribute(&self) -> Option<&Arc> { - let declarations = unsafe { Gecko_GetServoDeclarationBlock(self.element) }; + let declarations = unsafe { Gecko_GetServoDeclarationBlock(self.0) }; if declarations.is_null() { None } else { @@ -491,14 +452,14 @@ impl<'le> TElement for GeckoElement<'le> { fn get_state(&self) -> ElementState { unsafe { - ElementState::from_bits_truncate(Gecko_ElementState(self.element) as u16) + ElementState::from_bits_truncate(Gecko_ElementState(self.0) as u16) } } #[inline] fn has_attr(&self, namespace: &Namespace, attr: &Atom) -> bool { unsafe { - bindings::Gecko_HasAttr(self.element, + bindings::Gecko_HasAttr(self.0, namespace.0.as_ptr(), attr.as_ptr()) } @@ -507,7 +468,7 @@ impl<'le> TElement for GeckoElement<'le> { #[inline] fn attr_equals(&self, namespace: &Namespace, attr: &Atom, val: &Atom) -> bool { unsafe { - bindings::Gecko_AttrEquals(self.element, + bindings::Gecko_AttrEquals(self.0, namespace.0.as_ptr(), attr.as_ptr(), val.as_ptr(), @@ -518,7 +479,7 @@ impl<'le> TElement for GeckoElement<'le> { impl<'le> PartialEq for GeckoElement<'le> { fn eq(&self, other: &Self) -> bool { - self.element == other.element + self.0 as *const _ == other.0 as *const _ } } @@ -533,37 +494,37 @@ impl<'le> PresentationalHintsSynthetizer for GeckoElement<'le> { impl<'le> ::selectors::Element for GeckoElement<'le> { fn parent_element(&self) -> Option { unsafe { - Gecko_GetParentElement(self.element).as_ref().map(|el| GeckoElement::from_ref(el)) + Gecko_GetParentElement(self.0).borrow_opt().map(|el| GeckoElement(el)) } } fn first_child_element(&self) -> Option { unsafe { - Gecko_GetFirstChildElement(self.element).as_ref().map(|el| GeckoElement::from_ref(el)) + Gecko_GetFirstChildElement(self.0).borrow_opt().map(|el| GeckoElement(el)) } } fn last_child_element(&self) -> Option { unsafe { - Gecko_GetLastChildElement(self.element).as_ref().map(|el| GeckoElement::from_ref(el)) + Gecko_GetLastChildElement(self.0).borrow_opt().map(|el| GeckoElement(el)) } } fn prev_sibling_element(&self) -> Option { unsafe { - Gecko_GetPrevSiblingElement(self.element).as_ref().map(|el| GeckoElement::from_ref(el)) + Gecko_GetPrevSiblingElement(self.0).borrow_opt().map(|el| GeckoElement(el)) } } fn next_sibling_element(&self) -> Option { unsafe { - Gecko_GetNextSiblingElement(self.element).as_ref().map(|el| GeckoElement::from_ref(el)) + Gecko_GetNextSiblingElement(self.0).borrow_opt().map(|el| GeckoElement(el)) } } fn is_root(&self) -> bool { unsafe { - Gecko_IsRootElement(self.element) + Gecko_IsRootElement(self.0) } } @@ -574,22 +535,22 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { fn get_local_name(&self) -> &WeakAtom { unsafe { - WeakAtom::new(Gecko_LocalName(self.element)) + WeakAtom::new(Gecko_LocalName(self.0)) } } fn get_namespace(&self) -> &WeakNamespace { unsafe { - WeakNamespace::new(Gecko_Namespace(self.element)) + WeakNamespace::new(Gecko_Namespace(self.0)) } } fn match_non_ts_pseudo_class(&self, pseudo_class: NonTSPseudoClass) -> bool { match pseudo_class { // https://github.com/servo/servo/issues/8718 - NonTSPseudoClass::AnyLink => unsafe { Gecko_IsLink(self.element) }, - NonTSPseudoClass::Link => unsafe { Gecko_IsUnvisitedLink(self.element) }, - NonTSPseudoClass::Visited => unsafe { Gecko_IsVisitedLink(self.element) }, + NonTSPseudoClass::AnyLink => unsafe { Gecko_IsLink(self.0) }, + NonTSPseudoClass::Link => unsafe { Gecko_IsUnvisitedLink(self.0) }, + NonTSPseudoClass::Visited => unsafe { Gecko_IsVisitedLink(self.0) }, NonTSPseudoClass::Active | NonTSPseudoClass::Focus | NonTSPseudoClass::Hover | @@ -608,7 +569,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { fn get_id(&self) -> Option { let ptr = unsafe { - bindings::Gecko_AtomAttrValue(self.element, + bindings::Gecko_AtomAttrValue(self.0, atom!("id").as_ptr()) }; @@ -620,7 +581,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { } fn has_class(&self, name: &Atom) -> bool { - snapshot_helpers::has_class(self.element, + snapshot_helpers::has_class(self.0, name, Gecko_ClassOrClassList) } @@ -628,14 +589,14 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { fn each_class(&self, callback: F) where F: FnMut(&Atom) { - snapshot_helpers::each_class(self.element, + snapshot_helpers::each_class(self.0, callback, Gecko_ClassOrClassList) } fn is_html_element_in_html_document(&self) -> bool { unsafe { - Gecko_IsHTMLElementInHTMLDocument(self.element) + Gecko_IsHTMLElementInHTMLDocument(self.0) } } } @@ -667,14 +628,14 @@ impl<'le> ::selectors::MatchAttr for GeckoElement<'le> { fn match_attr_has(&self, attr: &AttrSelector) -> bool { unsafe { - bindings::Gecko_HasAttr(self.element, + bindings::Gecko_HasAttr(self.0, attr.ns_or_null(), attr.select_name(self.is_html_element_in_html_document())) } } fn match_attr_equals(&self, attr: &AttrSelector, value: &Atom) -> bool { unsafe { - bindings::Gecko_AttrEquals(self.element, + bindings::Gecko_AttrEquals(self.0, attr.ns_or_null(), attr.select_name(self.is_html_element_in_html_document()), value.as_ptr(), @@ -683,7 +644,7 @@ impl<'le> ::selectors::MatchAttr for GeckoElement<'le> { } fn match_attr_equals_ignore_ascii_case(&self, attr: &AttrSelector, value: &Atom) -> bool { unsafe { - bindings::Gecko_AttrEquals(self.element, + bindings::Gecko_AttrEquals(self.0, attr.ns_or_null(), attr.select_name(self.is_html_element_in_html_document()), value.as_ptr(), @@ -692,7 +653,7 @@ impl<'le> ::selectors::MatchAttr for GeckoElement<'le> { } fn match_attr_includes(&self, attr: &AttrSelector, value: &Atom) -> bool { unsafe { - bindings::Gecko_AttrIncludes(self.element, + bindings::Gecko_AttrIncludes(self.0, attr.ns_or_null(), attr.select_name(self.is_html_element_in_html_document()), value.as_ptr()) @@ -700,7 +661,7 @@ impl<'le> ::selectors::MatchAttr for GeckoElement<'le> { } fn match_attr_dash(&self, attr: &AttrSelector, value: &Atom) -> bool { unsafe { - bindings::Gecko_AttrDashEquals(self.element, + bindings::Gecko_AttrDashEquals(self.0, attr.ns_or_null(), attr.select_name(self.is_html_element_in_html_document()), value.as_ptr()) @@ -708,7 +669,7 @@ impl<'le> ::selectors::MatchAttr for GeckoElement<'le> { } fn match_attr_prefix(&self, attr: &AttrSelector, value: &Atom) -> bool { unsafe { - bindings::Gecko_AttrHasPrefix(self.element, + bindings::Gecko_AttrHasPrefix(self.0, attr.ns_or_null(), attr.select_name(self.is_html_element_in_html_document()), value.as_ptr()) @@ -716,7 +677,7 @@ impl<'le> ::selectors::MatchAttr for GeckoElement<'le> { } fn match_attr_substring(&self, attr: &AttrSelector, value: &Atom) -> bool { unsafe { - bindings::Gecko_AttrHasSubstring(self.element, + bindings::Gecko_AttrHasSubstring(self.0, attr.ns_or_null(), attr.select_name(self.is_html_element_in_html_document()), value.as_ptr()) @@ -724,7 +685,7 @@ impl<'le> ::selectors::MatchAttr for GeckoElement<'le> { } fn match_attr_suffix(&self, attr: &AttrSelector, value: &Atom) -> bool { unsafe { - bindings::Gecko_AttrHasSuffix(self.element, + bindings::Gecko_AttrHasSuffix(self.0, attr.ns_or_null(), attr.select_name(self.is_html_element_in_html_document()), value.as_ptr()) From f72cd7ffbc4997fc49394abbc3772652a8623f61 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 25 Aug 2016 21:13:49 +0530 Subject: [PATCH 7/7] Review fixes and bindings resync --- components/style/properties/gecko.mako.rs | 4 +- ports/geckolib/binding_tools/regen.py | 60 +++-- ports/geckolib/gecko_bindings/bindings.rs | 215 +++++++++--------- .../gecko_bindings/sugar/ownership.rs | 108 +++++++-- ports/geckolib/glue.rs | 82 +++---- ports/geckolib/wrapper.rs | 17 +- 6 files changed, 293 insertions(+), 193 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 70509de16da..0799981f7a8 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -24,7 +24,7 @@ use gecko_bindings::bindings::{Gecko_EnsureImageLayersLength, Gecko_CreateGradie use gecko_bindings::bindings::{Gecko_CopyImageValueFrom, Gecko_CopyFontFamilyFrom}; use gecko_bindings::bindings::{Gecko_FontFamilyList_AppendGeneric, Gecko_FontFamilyList_AppendNamed}; use gecko_bindings::bindings::{Gecko_FontFamilyList_Clear, Gecko_InitializeImageLayer}; -use gecko_bindings::bindings::ServoComputedValuesMaybeBorrowed; +use gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull; use gecko_bindings::structs; use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut}; use gecko_values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba}; @@ -1713,7 +1713,7 @@ fn static_assert() { #[no_mangle] #[allow(non_snake_case, unused_variables)] pub extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values: - ServoComputedValuesMaybeBorrowed) -> *const ${style_struct.gecko_ffi_name} { + ServoComputedValuesBorrowedOrNull) -> *const ${style_struct.gecko_ffi_name} { computed_values.as_arc::().get_${style_struct.name_lower}().get_gecko() as *const ${style_struct.gecko_ffi_name} } diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index 31d9857e793..0ff54c16031 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -150,15 +150,14 @@ COMPILATION_TARGETS = { "void_types": [ "nsINode", "nsIDocument", "nsIPrincipal", "nsIURI", ], - "servo_maybe_arc_types": [ + "servo_nullable_arc_types": [ "ServoComputedValues", "RawServoStyleSheet", "ServoDeclarationBlock" ], "servo_owned_types": [ "RawServoStyleSet", - ], - "servo_maybe_owned_types": [ "ServoNodeData", + "StyleChildrenIterator", ], "servo_immutable_borrow_types": [ "RawGeckoNode", @@ -283,6 +282,22 @@ def build(objdir, target_name, debug, debugger, kind_name=None, flags = [] + # This makes an FFI-safe void type that can't be matched on + # &VoidType is UB to have, because you can match on it + # to produce a reachable unreachable. If it's wrapped in + # a struct as a private field it becomes okay again + # + # Not 100% sure of how safe this is, but it's what we're using + # in the XPCOM ffi too + # https://github.com/nikomatsakis/rust-memory-model/issues/2 + def zero_size_type(ty, flags): + flags.append("--blacklist-type") + flags.append(ty) + flags.append("--raw-line") + flags.append("enum {0}Void{{ }}".format(ty)) + flags.append("--raw-line") + flags.append("pub struct {0}({0}Void);".format(ty)) + if "flags" in current_target: flags.extend(current_target["flags"]) @@ -326,26 +341,32 @@ def build(objdir, target_name, debug, debugger, kind_name=None, for ty in current_target["void_types"]: flags.append("--raw-line") flags.append("pub enum {} {{}}".format(ty)) - if "servo_maybe_arc_types" in current_target: - for ty in current_target["servo_maybe_arc_types"]: + if "servo_nullable_arc_types" in current_target: + for ty in current_target["servo_nullable_arc_types"]: flags.append("--blacklist-type") flags.append("{}Strong".format(ty)) flags.append("--raw-line") flags.append("pub type {0}Strong = ::sugar::ownership::Strong<{0}>;".format(ty)) flags.append("--blacklist-type") - flags.append("{}MaybeBorrowed".format(ty)) - flags.append("-raw-line") - flags.append("pub type {0}MaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;".format(ty)) + flags.append("{}BorrowedOrNull".format(ty)) + flags.append("--raw-line") + flags.append("pub type {0}BorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, {0}>;".format(ty)) + flags.append("--blacklist-type") + flags.append("{}Borrowed".format(ty)) + flags.append("--raw-line") + flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) + zero_size_type(ty, flags) if "servo_immutable_borrow_types" in current_target: for ty in current_target["servo_immutable_borrow_types"]: - flags.append("-blacklist-type") + flags.append("--blacklist-type") flags.append("{}Borrowed".format(ty)) flags.append("--raw-line") flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) flags.append("--blacklist-type") - flags.append("{}MaybeBorrowed".format(ty)) + flags.append("{}BorrowedOrNull".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}MaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;".format(ty)) + flags.append("pub type {0}BorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, {0}>;".format(ty)) + zero_size_type(ty, flags) if "servo_owned_types" in current_target: for ty in current_target["servo_owned_types"]: flags.append("--blacklist-type") @@ -360,22 +381,21 @@ def build(objdir, target_name, debug, debugger, kind_name=None, flags.append("{}Owned".format(ty)) flags.append("--raw-line") flags.append("pub type {0}Owned = ::sugar::ownership::Owned<{0}>;".format(ty)) - if "servo_maybe_owned_types" in current_target: - for ty in current_target["servo_maybe_owned_types"]: flags.append("--blacklist-type") - flags.append("{}MaybeBorrowed".format(ty)) + flags.append("{}BorrowedOrNull".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}MaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, {0}>;" + flags.append("pub type {0}BorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, {0}>;" .format(ty)) flags.append("--blacklist-type") - flags.append("{}MaybeBorrowedMut".format(ty)) + flags.append("{}BorrowedMutOrNull".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}MaybeBorrowedMut<'a> = ::sugar::ownership::BorrowedMut<'a, {0}>;" + flags.append("pub type {0}BorrowedMutOrNull<'a> = ::sugar::ownership::BorrowedMut<'a, {0}>;" .format(ty)) flags.append("--blacklist-type") - flags.append("{}MaybeOwned".format(ty)) + flags.append("{}OwnedOrNull".format(ty)) flags.append("--raw-line") - flags.append("pub type {0}MaybeOwned = ::sugar::ownership::MaybeOwned<{0}>;".format(ty)) + flags.append("pub type {0}OwnedOrNull = ::sugar::ownership::OwnedOrNull<{0}>;".format(ty)) + zero_size_type(ty, flags) if "structs_types" in current_target: for ty in current_target["structs_types"]: ty_fragments = ty.split("::") @@ -405,7 +425,7 @@ def build(objdir, target_name, debug, debugger, kind_name=None, # TODO: support more files, that's the whole point of this. assert len(current_target["files"]) == 1 - clang_flags.append(current_target["files"][0].format(objdir)) + flags.append(current_target["files"][0].format(objdir)) flags = bindgen + flags + ["--"] + clang_flags diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 876303f52ba..54fc98b6287 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -6,23 +6,56 @@ pub enum nsIDocument {} pub enum nsIPrincipal {} pub enum nsIURI {} pub type ServoComputedValuesStrong = ::sugar::ownership::Strong; -pub type ServoComputedValuesMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoComputedValues>; +pub type ServoComputedValuesBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, ServoComputedValues>; +pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues; +enum ServoComputedValuesVoid{ } +pub struct ServoComputedValues(ServoComputedValuesVoid); pub type RawServoStyleSheetStrong = ::sugar::ownership::Strong; -pub type RawServoStyleSheetMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawServoStyleSheet>; +pub type RawServoStyleSheetBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, RawServoStyleSheet>; +pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet; +enum RawServoStyleSheetVoid{ } +pub struct RawServoStyleSheet(RawServoStyleSheetVoid); pub type ServoDeclarationBlockStrong = ::sugar::ownership::Strong; -pub type ServoDeclarationBlockMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoDeclarationBlock>; +pub type ServoDeclarationBlockBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, ServoDeclarationBlock>; +pub type ServoDeclarationBlockBorrowed<'a> = &'a ServoDeclarationBlock; +enum ServoDeclarationBlockVoid{ } +pub struct ServoDeclarationBlock(ServoDeclarationBlockVoid); pub type RawGeckoNodeBorrowed<'a> = &'a RawGeckoNode; -pub type RawGeckoNodeMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoNode>; +pub type RawGeckoNodeBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoNode>; +enum RawGeckoNodeVoid{ } +pub struct RawGeckoNode(RawGeckoNodeVoid); pub type RawGeckoElementBorrowed<'a> = &'a RawGeckoElement; -pub type RawGeckoElementMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoElement>; +pub type RawGeckoElementBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoElement>; +enum RawGeckoElementVoid{ } +pub struct RawGeckoElement(RawGeckoElementVoid); pub type RawGeckoDocumentBorrowed<'a> = &'a RawGeckoDocument; -pub type RawGeckoDocumentMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoDocument>; +pub type RawGeckoDocumentBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, RawGeckoDocument>; +enum RawGeckoDocumentVoid{ } +pub struct RawGeckoDocument(RawGeckoDocumentVoid); pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; pub type RawServoStyleSetOwned = ::sugar::ownership::Owned; -pub type ServoNodeDataMaybeBorrowed<'a> = ::sugar::ownership::Borrowed<'a, ServoNodeData>; -pub type ServoNodeDataMaybeBorrowedMut<'a> = ::sugar::ownership::BorrowedMut<'a, ServoNodeData>; -pub type ServoNodeDataMaybeOwned = ::sugar::ownership::MaybeOwned; +pub type RawServoStyleSetBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, RawServoStyleSet>; +pub type RawServoStyleSetBorrowedMutOrNull<'a> = ::sugar::ownership::BorrowedMut<'a, RawServoStyleSet>; +pub type RawServoStyleSetOwnedOrNull = ::sugar::ownership::OwnedOrNull; +enum RawServoStyleSetVoid{ } +pub struct RawServoStyleSet(RawServoStyleSetVoid); +pub type ServoNodeDataBorrowed<'a> = &'a ServoNodeData; +pub type ServoNodeDataBorrowedMut<'a> = &'a mut ServoNodeData; +pub type ServoNodeDataOwned = ::sugar::ownership::Owned; +pub type ServoNodeDataBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, ServoNodeData>; +pub type ServoNodeDataBorrowedMutOrNull<'a> = ::sugar::ownership::BorrowedMut<'a, ServoNodeData>; +pub type ServoNodeDataOwnedOrNull = ::sugar::ownership::OwnedOrNull; +enum ServoNodeDataVoid{ } +pub struct ServoNodeData(ServoNodeDataVoid); +pub type StyleChildrenIteratorBorrowed<'a> = &'a StyleChildrenIterator; +pub type StyleChildrenIteratorBorrowedMut<'a> = &'a mut StyleChildrenIterator; +pub type StyleChildrenIteratorOwned = ::sugar::ownership::Owned; +pub type StyleChildrenIteratorBorrowedOrNull<'a> = ::sugar::ownership::Borrowed<'a, StyleChildrenIterator>; +pub type StyleChildrenIteratorBorrowedMutOrNull<'a> = ::sugar::ownership::BorrowedMut<'a, StyleChildrenIterator>; +pub type StyleChildrenIteratorOwnedOrNull = ::sugar::ownership::OwnedOrNull; +enum StyleChildrenIteratorVoid{ } +pub struct StyleChildrenIterator(StyleChildrenIteratorVoid); use structs::nsStyleFont; unsafe impl Send for nsStyleFont {} unsafe impl Sync for nsStyleFont {} @@ -171,51 +204,42 @@ use structs::StyleBasicShapeType; use structs::StyleBasicShape; use structs::nsCSSShadowArray; -pub type RawGeckoNode = nsINode; pub enum Element { } -pub type RawGeckoElement = Element; -pub type RawGeckoDocument = nsIDocument; -pub enum ServoNodeData { } -pub enum ServoComputedValues { } -pub enum RawServoStyleSheet { } -pub enum RawServoStyleSet { } pub enum nsHTMLCSSStyleSheet { } -pub enum ServoDeclarationBlock { } -pub enum StyleChildrenIterator { } pub type ThreadSafePrincipalHolder = nsMainThreadPtrHolder; pub type ThreadSafeURIHolder = nsMainThreadPtrHolder; extern "C" { pub fn Gecko_ChildrenCount(node: RawGeckoNodeBorrowed) -> u32; pub fn Gecko_NodeIsElement(node: RawGeckoNodeBorrowed) -> bool; pub fn Gecko_GetParentNode(node: RawGeckoNodeBorrowed) - -> RawGeckoNodeMaybeBorrowed; + -> RawGeckoNodeBorrowedOrNull; pub fn Gecko_GetFirstChild(node: RawGeckoNodeBorrowed) - -> RawGeckoNodeMaybeBorrowed; + -> RawGeckoNodeBorrowedOrNull; pub fn Gecko_GetLastChild(node: RawGeckoNodeBorrowed) - -> RawGeckoNodeMaybeBorrowed; + -> RawGeckoNodeBorrowedOrNull; pub fn Gecko_GetPrevSibling(node: RawGeckoNodeBorrowed) - -> RawGeckoNodeMaybeBorrowed; + -> RawGeckoNodeBorrowedOrNull; pub fn Gecko_GetNextSibling(node: RawGeckoNodeBorrowed) - -> RawGeckoNodeMaybeBorrowed; + -> RawGeckoNodeBorrowedOrNull; pub fn Gecko_GetParentElement(element: RawGeckoElementBorrowed) - -> RawGeckoElementMaybeBorrowed; + -> RawGeckoElementBorrowedOrNull; pub fn Gecko_GetFirstChildElement(element: RawGeckoElementBorrowed) - -> RawGeckoElementMaybeBorrowed; + -> RawGeckoElementBorrowedOrNull; pub fn Gecko_GetLastChildElement(element: RawGeckoElementBorrowed) - -> RawGeckoElementMaybeBorrowed; + -> RawGeckoElementBorrowedOrNull; pub fn Gecko_GetPrevSiblingElement(element: RawGeckoElementBorrowed) - -> RawGeckoElementMaybeBorrowed; + -> RawGeckoElementBorrowedOrNull; pub fn Gecko_GetNextSiblingElement(element: RawGeckoElementBorrowed) - -> RawGeckoElementMaybeBorrowed; + -> RawGeckoElementBorrowedOrNull; pub fn Gecko_GetDocumentElement(document: RawGeckoDocumentBorrowed) - -> RawGeckoElementMaybeBorrowed; + -> RawGeckoElementBorrowedOrNull; pub fn Gecko_MaybeCreateStyleChildrenIterator(node: RawGeckoNodeBorrowed) - -> *mut StyleChildrenIterator; - pub fn Gecko_DropStyleChildrenIterator(it: *mut StyleChildrenIterator); - pub fn Gecko_GetNextStyleChild(it: *mut StyleChildrenIterator) - -> *mut RawGeckoNode; - pub fn Gecko_ElementState(element: *mut RawGeckoElement) -> u8; - pub fn Gecko_IsHTMLElementInHTMLDocument(element: *mut RawGeckoElement) + -> StyleChildrenIteratorOwnedOrNull; + pub fn Gecko_DropStyleChildrenIterator(it: StyleChildrenIteratorOwned); + pub fn Gecko_GetNextStyleChild(it: StyleChildrenIteratorBorrowed) + -> RawGeckoNodeBorrowedOrNull; + pub fn Gecko_ElementState(element: RawGeckoElementBorrowed) -> u8; + pub fn Gecko_IsHTMLElementInHTMLDocument(element: RawGeckoElementBorrowed) -> bool; pub fn Gecko_IsLink(element: RawGeckoElementBorrowed) -> bool; pub fn Gecko_IsTextNode(node: RawGeckoNodeBorrowed) -> bool; @@ -282,11 +306,11 @@ extern "C" { classList: *mut *mut *mut nsIAtom) -> u32; pub fn Gecko_GetServoDeclarationBlock(element: RawGeckoElementBorrowed) - -> ServoDeclarationBlockMaybeBorrowed; + -> ServoDeclarationBlockBorrowedOrNull; pub fn Gecko_GetNodeData(node: RawGeckoNodeBorrowed) - -> ServoNodeDataMaybeBorrowed; + -> ServoNodeDataBorrowedOrNull; pub fn Gecko_SetNodeData(node: RawGeckoNodeBorrowed, - data: ServoNodeDataMaybeOwned); + data: ServoNodeDataOwned); pub fn Gecko_Atomize(aString: *const ::std::os::raw::c_char, aLength: u32) -> *mut nsIAtom; pub fn Gecko_AddRefAtom(aAtom: *mut nsIAtom); @@ -337,8 +361,7 @@ extern "C" { aPseudoTagOrNull: *mut nsIAtom) -> *mut nsStyleContext; pub fn Gecko_CalcStyleDifference(oldstyle: *mut nsStyleContext, - newstyle: - ServoComputedValuesMaybeBorrowed) + newstyle: ServoComputedValuesBorrowed) -> nsChangeHint; pub fn Gecko_StoreStyleDifference(node: RawGeckoNodeBorrowed, change: nsChangeHint); @@ -477,7 +500,7 @@ extern "C" { pub fn Gecko_CopyConstruct_nsStyleEffects(ptr: *mut nsStyleEffects, other: *const nsStyleEffects); pub fn Gecko_Destroy_nsStyleEffects(ptr: *mut nsStyleEffects); - pub fn Servo_NodeData_Drop(data: ServoNodeDataMaybeOwned); + pub fn Servo_NodeData_Drop(data: ServoNodeDataOwned); pub fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8, length: u32, parsing_mode: SheetParsingMode, base_bytes: *const u8, @@ -487,143 +510,129 @@ extern "C" { principal: *mut ThreadSafePrincipalHolder) -> RawServoStyleSheetStrong; - pub fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetMaybeBorrowed); - pub fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetMaybeBorrowed); - pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetMaybeBorrowed) + pub fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetBorrowed); + pub fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed); + pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed) -> bool; pub fn Servo_StyleSet_Init() -> RawServoStyleSetOwned; pub fn Servo_StyleSet_Drop(set: RawServoStyleSetOwned); pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowedMut, - sheet: RawServoStyleSheetMaybeBorrowed); + sheet: RawServoStyleSheetBorrowed); pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowedMut, sheet: - RawServoStyleSheetMaybeBorrowed); + RawServoStyleSheetBorrowed); pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowedMut, - sheet: RawServoStyleSheetMaybeBorrowed); - pub fn Servo_StyleSet_InsertStyleSheetBefore(set: RawServoStyleSetBorrowedMut, + sheet: RawServoStyleSheetBorrowed); + pub fn Servo_StyleSet_InsertStyleSheetBefore(set: + RawServoStyleSetBorrowedMut, sheet: - RawServoStyleSheetMaybeBorrowed, + RawServoStyleSheetBorrowed, reference: - RawServoStyleSheetMaybeBorrowed); + RawServoStyleSheetBorrowed); pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32, cache: *mut nsHTMLCSSStyleSheet) -> ServoDeclarationBlockStrong; pub fn Servo_DeclarationBlock_AddRef(declarations: - ServoDeclarationBlockMaybeBorrowed); + ServoDeclarationBlockBorrowed); pub fn Servo_DeclarationBlock_Release(declarations: - ServoDeclarationBlockMaybeBorrowed); + ServoDeclarationBlockBorrowed); pub fn Servo_DeclarationBlock_GetCache(declarations: - ServoDeclarationBlockMaybeBorrowed) + ServoDeclarationBlockBorrowed) -> *mut nsHTMLCSSStyleSheet; pub fn Servo_DeclarationBlock_SetImmutable(declarations: - ServoDeclarationBlockMaybeBorrowed); + ServoDeclarationBlockBorrowed); pub fn Servo_DeclarationBlock_ClearCachePointer(declarations: - ServoDeclarationBlockMaybeBorrowed); + ServoDeclarationBlockBorrowed); pub fn Servo_CSSSupports(name: *const u8, name_length: u32, value: *const u8, value_length: u32) -> bool; pub fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: - ServoComputedValuesMaybeBorrowed, + ServoComputedValuesBorrowedOrNull, pseudoTag: *mut nsIAtom, - set: RawServoStyleSetBorrowedMut) + set: + RawServoStyleSetBorrowedMut) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_GetForPseudoElement(parent_style: - ServoComputedValuesMaybeBorrowed, + ServoComputedValuesBorrowed, match_element: - *mut RawGeckoElement, + RawGeckoElementBorrowed, pseudo_tag: *mut nsIAtom, set: RawServoStyleSetBorrowedMut, is_probe: bool) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_Inherit(parent_style: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowedOrNull) -> ServoComputedValuesStrong; pub fn Servo_ComputedValues_AddRef(computed_values: - ServoComputedValuesMaybeBorrowed); + ServoComputedValuesBorrowed); pub fn Servo_ComputedValues_Release(computed_values: - ServoComputedValuesMaybeBorrowed); + ServoComputedValuesBorrowed); pub fn Servo_Initialize(); pub fn Servo_Shutdown(); pub fn Servo_ComputeRestyleHint(element: *mut RawGeckoElement, snapshot: *mut ServoElementSnapshot, - set: RawServoStyleSetBorrowedMut) + set: RawServoStyleSetBorrowed) -> nsRestyleHint; pub fn Servo_RestyleDocument(doc: RawGeckoDocumentBorrowed, set: RawServoStyleSetBorrowedMut); pub fn Servo_RestyleSubtree(node: RawGeckoNodeBorrowed, set: RawServoStyleSetBorrowedMut); - pub fn Servo_GetStyleFont(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleFont(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleFont; - pub fn Servo_GetStyleColor(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleColor(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleColor; - pub fn Servo_GetStyleList(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleList(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleList; - pub fn Servo_GetStyleText(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleText(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleText; pub fn Servo_GetStyleVisibility(computed_values: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowed) -> *const nsStyleVisibility; pub fn Servo_GetStyleUserInterface(computed_values: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowed) -> *const nsStyleUserInterface; pub fn Servo_GetStyleTableBorder(computed_values: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowed) -> *const nsStyleTableBorder; - pub fn Servo_GetStyleSVG(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleSVG(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleSVG; pub fn Servo_GetStyleVariables(computed_values: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowed) -> *const nsStyleVariables; pub fn Servo_GetStyleBackground(computed_values: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowed) -> *const nsStyleBackground; pub fn Servo_GetStylePosition(computed_values: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowed) -> *const nsStylePosition; pub fn Servo_GetStyleTextReset(computed_values: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowed) -> *const nsStyleTextReset; - pub fn Servo_GetStyleDisplay(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleDisplay(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleDisplay; - pub fn Servo_GetStyleContent(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleContent(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleContent; - pub fn Servo_GetStyleUIReset(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleUIReset(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleUIReset; - pub fn Servo_GetStyleTable(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleTable(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleTable; - pub fn Servo_GetStyleMargin(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleMargin(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleMargin; - pub fn Servo_GetStylePadding(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStylePadding(computed_values: ServoComputedValuesBorrowed) -> *const nsStylePadding; - pub fn Servo_GetStyleBorder(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleBorder(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleBorder; - pub fn Servo_GetStyleOutline(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleOutline(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleOutline; - pub fn Servo_GetStyleXUL(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleXUL(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleXUL; pub fn Servo_GetStyleSVGReset(computed_values: - ServoComputedValuesMaybeBorrowed) + ServoComputedValuesBorrowed) -> *const nsStyleSVGReset; - pub fn Servo_GetStyleColumn(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleColumn(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleColumn; - pub fn Servo_GetStyleEffects(computed_values: - ServoComputedValuesMaybeBorrowed) + pub fn Servo_GetStyleEffects(computed_values: ServoComputedValuesBorrowed) -> *const nsStyleEffects; } diff --git a/ports/geckolib/gecko_bindings/sugar/ownership.rs b/ports/geckolib/gecko_bindings/sugar/ownership.rs index bc6273bb8a5..39b4cf59f41 100644 --- a/ports/geckolib/gecko_bindings/sugar/ownership.rs +++ b/ports/geckolib/gecko_bindings/sugar/ownership.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::marker::PhantomData; -use std::mem::{forget, transmute, transmute_copy}; +use std::mem::{forget, transmute}; use std::ops::{Deref, DerefMut}; use std::ptr; use std::sync::Arc; @@ -71,20 +71,43 @@ pub unsafe trait HasBoxFFI : HasSimpleFFI { pub unsafe trait HasArcFFI : HasFFI { // these methods can't be on Borrowed because it leads to an unspecified // impl parameter - /// Artificially increments the refcount of a borrowed Arc over FFI. - unsafe fn addref(ptr: Borrowed) { - forget(ptr.as_arc::().clone()) + /// Artificially increments the refcount of a (possibly null) borrowed Arc over FFI. + unsafe fn addref_opt(ptr: Borrowed) { + forget(ptr.as_arc_opt::().clone()) } /// Given a (possibly null) borrowed FFI reference, decrements the refcount. /// Unsafe since it doesn't consume the backing Arc. Run it only when you /// know that a strong reference to the backing Arc is disappearing /// (usually on the C++ side) without running the Arc destructor. - unsafe fn release(ptr: Borrowed) { + unsafe fn release_opt(ptr: Borrowed) { if let Some(arc) = ptr.as_arc_opt::() { let _: Arc<_> = ptr::read(arc as *const Arc<_>); } } + + /// Artificially increments the refcount of a borrowed Arc over FFI. + unsafe fn addref(ptr: &Self::FFIType) { + forget(Self::as_arc(&ptr).clone()) + } + + /// Given a non-null borrowed FFI reference, decrements the refcount. + /// Unsafe since it doesn't consume the backing Arc. Run it only when you + /// know that a strong reference to the backing Arc is disappearing + /// (usually on the C++ side) without running the Arc destructor. + unsafe fn release(ptr: &Self::FFIType) { + let _: Arc<_> = ptr::read(Self::as_arc(&ptr) as *const Arc<_>); + } + #[inline] + /// Converts a borrowed FFI reference to a borrowed Arc. + /// + /// &GeckoType -> &Arc + fn as_arc<'a>(ptr: &'a &Self::FFIType) -> &'a Arc { + debug_assert!(!(ptr as *const _).is_null()); + unsafe { + transmute::<&&Self::FFIType, &Arc>(ptr) + } + } } #[repr(C)] @@ -113,7 +136,7 @@ impl<'a, T> Clone for Borrowed<'a, T> { impl<'a, T> Borrowed<'a, T> { #[inline] - pub fn is_null(&self) -> bool { + pub fn is_null(self) -> bool { self.ptr == ptr::null() } @@ -150,7 +173,7 @@ impl<'a, T> Borrowed<'a, T> { #[inline] /// Borrowed -> Borrowed - pub fn as_ffi(&self) -> Borrowed<::FFIType> where Self: HasSimpleFFI { + pub fn as_ffi(self) -> Borrowed<'a, ::FFIType> where Self: HasSimpleFFI { unsafe { transmute(self) } } @@ -165,6 +188,13 @@ impl<'a, T> Borrowed<'a, T> { pub fn as_servo_ref(self) -> Option<&'a U> where U: HasSimpleFFI { self.borrow_opt().map(HasSimpleFFI::from_ffi) } + + pub fn null() -> Borrowed<'static, T> { + Borrowed { + ptr: ptr::null_mut(), + _marker: PhantomData + } + } } impl<'a, T> BorrowedMut<'a, T> { @@ -196,9 +226,17 @@ impl<'a, T> BorrowedMut<'a, T> { pub fn as_servo_mut_ref(self) -> Option<&'a mut U> where U: HasSimpleFFI { self.borrow_mut_opt().map(HasSimpleFFI::from_ffi_mut) } + + pub fn null_mut() -> BorrowedMut<'static, T> { + BorrowedMut { + ptr: ptr::null_mut(), + _marker: PhantomData + } + } } -// technically not +// technically not how we're supposed to use +// Deref, but that's a minor style issue impl<'a, T> Deref for BorrowedMut<'a, T> { type Target = Borrowed<'a, T>; fn deref(&self) -> &Self::Target { @@ -209,6 +247,8 @@ impl<'a, T> Deref for BorrowedMut<'a, T> { #[repr(C)] /// Gecko-FFI-safe Arc (T is an ArcInner). /// This can be null. +/// Leaks on drop. Please don't drop this. +/// TODO: Add destructor bomb once drop flags are gone pub struct Strong { ptr: *const T, _marker: PhantomData, @@ -227,13 +267,26 @@ impl Strong { /// /// Strong -> Arc pub fn into_arc(self) -> Arc where U: HasArcFFI { - assert!(!self.is_null()); - unsafe { transmute(self) } + self.into_arc_opt().unwrap() + } + + #[inline] + /// Given a strong FFI reference, + /// converts it into a servo-side Arc + /// Returns None on null. + /// + /// Strong -> Arc + pub fn into_arc_opt(self) -> Option> where U: HasArcFFI { + if self.is_null() { + None + } else { + unsafe { Some(transmute(self)) } + } } #[inline] /// Produces a null strong FFI reference - pub fn null_strong() -> Self { + pub fn null() -> Self { unsafe { transmute(ptr::null::()) } } } @@ -244,10 +297,14 @@ pub unsafe trait FFIArcHelpers { /// /// Arc -> Strong fn into_strong(self) -> Strong<::FFIType>; - /// Produces a borrowed FFI reference by borrowing an Arc. + /// Produces a (nullable) borrowed FFI reference by borrowing an Arc. /// /// &Arc -> Borrowed - fn as_borrowed(&self) -> Borrowed<::FFIType>; + fn as_borrowed_opt(&self) -> Borrowed<::FFIType>; + /// Produces a borrowed FFI reference by borrowing an Arc. + /// + /// &Arc -> &GeckoType + fn as_borrowed(&self) -> &::FFIType; } unsafe impl FFIArcHelpers for Arc { @@ -257,15 +314,21 @@ unsafe impl FFIArcHelpers for Arc { unsafe { transmute(self) } } #[inline] - fn as_borrowed(&self) -> Borrowed { + fn as_borrowed_opt(&self) -> Borrowed { let borrowedptr = self as *const Arc as *const Borrowed; unsafe { ptr::read(borrowedptr) } } + #[inline] + fn as_borrowed(&self) -> &T::FFIType { + let borrowedptr = self as *const Arc as *const & T::FFIType; + unsafe { ptr::read(borrowedptr) } + } } #[repr(C)] /// Gecko-FFI-safe owned pointer /// Cannot be null +/// Leaks on drop. Please don't drop this. pub struct Owned { ptr: *mut T, _marker: PhantomData, @@ -276,7 +339,7 @@ impl Owned { pub fn into_box(self) -> Box where U: HasBoxFFI { unsafe { transmute(self) } } - pub fn maybe(self) -> MaybeOwned { + pub fn maybe(self) -> OwnedOrNull { unsafe { transmute(self) } } } @@ -297,16 +360,16 @@ impl DerefMut for Owned { #[repr(C)] /// Gecko-FFI-safe owned pointer /// Can be null -pub struct MaybeOwned { +pub struct OwnedOrNull { ptr: *mut T, _marker: PhantomData, } -impl MaybeOwned { +impl OwnedOrNull { pub fn is_null(&self) -> bool { self.ptr == ptr::null_mut() } - /// MaybeOwned -> Option> + /// OwnedOrNull -> Option> pub fn into_box_opt(self) -> Option> where U: HasBoxFFI { if self.is_null() { None @@ -315,6 +378,15 @@ impl MaybeOwned { } } + /// OwnedOrNull -> Option> + pub fn into_owned_opt(self) -> Option> { + if self.is_null() { + None + } else { + Some(unsafe { transmute(self) }) + } + } + pub fn borrow(&self) -> Borrowed { unsafe { transmute(self) } } diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index f21c4242849..685d594d0e7 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -8,16 +8,16 @@ use app_units::Au; use data::{NUM_THREADS, PerDocumentStyleData}; use env_logger; use euclid::Size2D; -use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::bindings::RawGeckoDocumentBorrowed; +use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoNodeBorrowed}; use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSetBorrowedMut}; -use gecko_bindings::bindings::{RawServoStyleSetOwned, ServoNodeDataMaybeOwned}; -use gecko_bindings::bindings::{RawServoStyleSheetMaybeBorrowed, ServoComputedValuesMaybeBorrowed}; +use gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned, ServoNodeDataOwned}; +use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong}; -use gecko_bindings::bindings::{ServoDeclarationBlock, ThreadSafePrincipalHolder}; -use gecko_bindings::bindings::{ServoDeclarationBlockMaybeBorrowed, ServoDeclarationBlockStrong}; -use gecko_bindings::bindings::{ThreadSafeURIHolder, nsHTMLCSSStyleSheet}; +use gecko_bindings::bindings::{ServoComputedValuesBorrowedOrNull, ServoDeclarationBlock}; +use gecko_bindings::bindings::{ServoDeclarationBlockBorrowed, ServoDeclarationBlockStrong}; +use gecko_bindings::bindings::{ThreadSafePrincipalHolder, ThreadSafeURIHolder, nsHTMLCSSStyleSheet}; use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; use gecko_bindings::structs::ServoElementSnapshot; use gecko_bindings::structs::nsRestyleHint; @@ -138,8 +138,8 @@ pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 { } #[no_mangle] -pub extern "C" fn Servo_NodeData_Drop(data: ServoNodeDataMaybeOwned) -> () { - let _ = data.into_box_opt::(); +pub extern "C" fn Servo_NodeData_Drop(data: ServoNodeDataOwned) -> () { + let _ = data.into_box::(); } #[no_mangle] @@ -176,9 +176,9 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8, #[no_mangle] pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowedMut, - raw_sheet: RawServoStyleSheetMaybeBorrowed) { + raw_sheet: RawServoStyleSheetBorrowed) { let data = PerDocumentStyleData::from_ffi_mut(raw_data); - let sheet = raw_sheet.as_arc(); + let sheet = HasArcFFI::as_arc(&raw_sheet); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets.push(sheet.clone()); data.stylesheets_changed = true; @@ -186,9 +186,9 @@ pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorr #[no_mangle] pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowedMut, - raw_sheet: RawServoStyleSheetMaybeBorrowed) { + raw_sheet: RawServoStyleSheetBorrowed) { let data = PerDocumentStyleData::from_ffi_mut(raw_data); - let sheet = raw_sheet.as_arc(); + let sheet = HasArcFFI::as_arc(&raw_sheet); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets.insert(0, sheet.clone()); data.stylesheets_changed = true; @@ -196,11 +196,11 @@ pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBor #[no_mangle] pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowedMut, - raw_sheet: RawServoStyleSheetMaybeBorrowed, - raw_reference: RawServoStyleSheetMaybeBorrowed) { + raw_sheet: RawServoStyleSheetBorrowed, + raw_reference: RawServoStyleSheetBorrowed) { let data = PerDocumentStyleData::from_ffi_mut(raw_data); - let sheet = raw_sheet.as_arc(); - let reference = raw_reference.as_arc(); + let sheet = HasArcFFI::as_arc(&raw_sheet); + let reference = HasArcFFI::as_arc(&raw_reference); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); let index = data.stylesheets.iter().position(|x| arc_ptr_eq(x, reference)).unwrap(); data.stylesheets.insert(index, sheet.clone()); @@ -209,25 +209,25 @@ pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleS #[no_mangle] pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorrowedMut, - raw_sheet: RawServoStyleSheetMaybeBorrowed) { + raw_sheet: RawServoStyleSheetBorrowed) { let data = PerDocumentStyleData::from_ffi_mut(raw_data); - let sheet = raw_sheet.as_arc(); + let sheet = HasArcFFI::as_arc(&raw_sheet); data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets_changed = true; } #[no_mangle] -pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetMaybeBorrowed) -> bool { - !raw_sheet.as_arc::().rules.is_empty() +pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool { + !Stylesheet::as_arc(&raw_sheet).rules.is_empty() } #[no_mangle] -pub extern "C" fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetMaybeBorrowed) -> () { +pub extern "C" fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetBorrowed) -> () { unsafe { Stylesheet::addref(sheet) }; } #[no_mangle] -pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetMaybeBorrowed) -> () { +pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed) -> () { unsafe { Stylesheet::release(sheet) }; } @@ -250,7 +250,7 @@ pub extern "C" fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed) } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesMaybeBorrowed, +pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull, pseudo_tag: *mut nsIAtom, raw_data: RawServoStyleSetBorrowedMut) -> ServoComputedValuesStrong { @@ -264,11 +264,11 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: let maybe_parent = parent_style_or_null.as_arc_opt(); let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent); - new_computed.map_or(Strong::null_strong(), |c| c.into_strong()) + new_computed.map_or(Strong::null(), |c| c.into_strong()) } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoComputedValuesMaybeBorrowed, +pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoComputedValuesBorrowed, match_element: RawGeckoElementBorrowed, pseudo_tag: *mut nsIAtom, raw_data: RawServoStyleSetBorrowedMut, @@ -278,9 +278,9 @@ pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoCo let parent_or_null = || { if is_probe { - Strong::null_strong() + Strong::null() } else { - parent_style.as_arc::().clone().into_strong() + ComputedValues::as_arc(&parent_style).clone().into_strong() } }; @@ -304,7 +304,7 @@ pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoCo maybe_computed.map_or_else(parent_or_null, FFIArcHelpers::into_strong) } PseudoElementCascadeType::Lazy => { - let parent = parent_style.as_arc::(); + let parent = ComputedValues::as_arc(&parent_style); data.stylist .lazily_compute_pseudo_element_style(&element, &pseudo, parent) .map_or_else(parent_or_null, FFIArcHelpers::into_strong) @@ -317,7 +317,7 @@ pub extern "C" fn Servo_ComputedValues_GetForPseudoElement(parent_style: ServoCo } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValuesMaybeBorrowed) +pub extern "C" fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValuesBorrowedOrNull) -> ServoComputedValuesStrong { let style = if parent_style.is_null() { Arc::new(ComputedValues::initial_values().clone()) @@ -328,12 +328,12 @@ pub extern "C" fn Servo_ComputedValues_Inherit(parent_style: ServoComputedValues } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesMaybeBorrowed) -> () { +pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed) -> () { unsafe { ComputedValues::addref(ptr) }; } #[no_mangle] -pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesMaybeBorrowed) -> () { +pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) -> () { unsafe { ComputedValues::release(ptr) }; } @@ -378,29 +378,29 @@ pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32, } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: ServoDeclarationBlockMaybeBorrowed) { +pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: ServoDeclarationBlockBorrowed) { unsafe { GeckoDeclarationBlock::addref(declarations) }; } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationBlockMaybeBorrowed) { +pub extern "C" fn Servo_DeclarationBlock_Release(declarations: ServoDeclarationBlockBorrowed) { unsafe { GeckoDeclarationBlock::release(declarations) }; } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_GetCache(declarations: ServoDeclarationBlockMaybeBorrowed) +pub extern "C" fn Servo_DeclarationBlock_GetCache(declarations: ServoDeclarationBlockBorrowed) -> *mut nsHTMLCSSStyleSheet { - declarations.as_arc::().cache.load(Ordering::Relaxed) + GeckoDeclarationBlock::as_arc(&declarations).cache.load(Ordering::Relaxed) } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_SetImmutable(declarations: ServoDeclarationBlockMaybeBorrowed) { - declarations.as_arc::().immutable.store(true, Ordering::Relaxed) +pub extern "C" fn Servo_DeclarationBlock_SetImmutable(declarations: ServoDeclarationBlockBorrowed) { + GeckoDeclarationBlock::as_arc(&declarations).immutable.store(true, Ordering::Relaxed) } #[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_ClearCachePointer(declarations: ServoDeclarationBlockMaybeBorrowed) { - declarations.as_arc::().cache.store(ptr::null_mut(), Ordering::Relaxed) +pub extern "C" fn Servo_DeclarationBlock_ClearCachePointer(declarations: ServoDeclarationBlockBorrowed) { + GeckoDeclarationBlock::as_arc(&declarations).cache.store(ptr::null_mut(), Ordering::Relaxed) } #[no_mangle] @@ -421,8 +421,8 @@ pub extern "C" fn Servo_CSSSupports(property: *const u8, property_length: u32, #[no_mangle] pub extern "C" fn Servo_ComputeRestyleHint(element: RawGeckoElementBorrowed, snapshot: *mut ServoElementSnapshot, - raw_data: RawServoStyleSetBorrowedMut) -> nsRestyleHint { - let per_doc_data = PerDocumentStyleData::from_ffi_mut(raw_data); + raw_data: RawServoStyleSetBorrowed) -> nsRestyleHint { + let per_doc_data = PerDocumentStyleData::from_ffi(raw_data); let snapshot = unsafe { GeckoElementSnapshot::from_raw(snapshot) }; let element = unsafe { GeckoElement(element) }; diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index a3856b6a612..d976728393d 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -23,7 +23,6 @@ use gecko_bindings::bindings::{Gecko_IsLink, Gecko_IsRootElement, Gecko_IsTextNo use gecko_bindings::bindings::{Gecko_IsUnvisitedLink, Gecko_IsVisitedLink}; use gecko_bindings::bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetNodeData}; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; -use gecko_bindings::bindings::RawGeckoDocumentBorrowed; use gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoNodeBorrowed}; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; use gecko_bindings::structs::{nsIAtom, nsChangeHint, nsStyleContext}; @@ -89,7 +88,7 @@ impl<'ln> GeckoNode<'ln> { unsafe { if self.get_node_data().is_null() { let ptr = Box::new(NonOpaqueStyleData::new()); - Gecko_SetNodeData(self.0, ptr.into_ffi().maybe()); + Gecko_SetNodeData(self.0, ptr.into_ffi()); } } } @@ -165,8 +164,8 @@ impl<'ln> TNode for GeckoNode<'ln> { fn children(self) -> GeckoChildrenIterator<'ln> { let maybe_iter = unsafe { Gecko_MaybeCreateStyleChildrenIterator(self.0) }; - if !maybe_iter.is_null() { - GeckoChildrenIterator::GeckoIterator(maybe_iter) + if let Some(iter) = maybe_iter.into_owned_opt() { + GeckoChildrenIterator::GeckoIterator(iter) } else { GeckoChildrenIterator::Current(self.first_child()) } @@ -346,14 +345,14 @@ impl<'ln> TNode for GeckoNode<'ln> { // (heavier-weight) Gecko-implemented iterator. pub enum GeckoChildrenIterator<'a> { Current(Option>), - GeckoIterator(*mut bindings::StyleChildrenIterator), + GeckoIterator(bindings::StyleChildrenIteratorOwned), } impl<'a> Drop for GeckoChildrenIterator<'a> { fn drop(&mut self) { - if let GeckoChildrenIterator::GeckoIterator(it) = *self { + if let GeckoChildrenIterator::GeckoIterator(ref it) = *self { unsafe { - Gecko_DropStyleChildrenIterator(it); + Gecko_DropStyleChildrenIterator(ptr::read(it as *const _)); } } } @@ -368,8 +367,8 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> { *self = GeckoChildrenIterator::Current(next); curr }, - GeckoChildrenIterator::GeckoIterator(it) => unsafe { - Gecko_GetNextStyleChild(it).as_ref().map(|n| GeckoNode::from_ref(n)) + GeckoChildrenIterator::GeckoIterator(ref it) => unsafe { + Gecko_GetNextStyleChild(&it).borrow_opt().map(GeckoNode) } } }