From 1a57bad2a1bdfb631aeb4dc6bc17527274d9da5a Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 14 Sep 2017 23:41:42 -0400 Subject: [PATCH] Add Rust APIs for interacting with Arc (bug 1397971). --- components/style/gecko/generated/bindings.rs | 6 +- .../style/gecko/generated/structs_debug.rs | 79 +++++++++++++++---- .../style/gecko/generated/structs_release.rs | 79 +++++++++++++++---- components/style/gecko/url.rs | 19 ++++- ports/geckolib/glue.rs | 28 ++++++- 5 files changed, 173 insertions(+), 38 deletions(-) diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index fdf32c538cd..5583ccc0061 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -19,6 +19,7 @@ use gecko_bindings::structs::mozilla::MallocSizeOf; use gecko_bindings::structs::mozilla::OriginFlags; use gecko_bindings::structs::mozilla::Side; use gecko_bindings::structs::mozilla::UniquePtr; +use gecko_bindings::structs::ServoRawOffsetArc; use gecko_bindings::structs::nsIContent; use gecko_bindings::structs::nsIDocument; use gecko_bindings::structs::nsIDocument_DocumentTheme; @@ -46,6 +47,7 @@ use gecko_bindings::structs::RawGeckoServoStyleRuleList; use gecko_bindings::structs::RawGeckoURLExtraData; use gecko_bindings::structs::RawGeckoXBLBinding; use gecko_bindings::structs::RefPtr; +use gecko_bindings::structs::RustString; use gecko_bindings::structs::CSSPseudoClassType; use gecko_bindings::structs::CSSPseudoElementType; use gecko_bindings::structs::ServoTraversalFlags; @@ -998,7 +1000,9 @@ extern "C" { pub fn Gecko_ReleaseImageValueArbitraryThread(aPtr: *mut ImageValue); } extern "C" { - pub fn Gecko_ImageValue_Create(aURI: ServoBundledURI) -> *mut ImageValue; + pub fn Gecko_ImageValue_Create(aURI: ServoBundledURI, + aURIString: ServoRawOffsetArc) + -> *mut ImageValue; } extern "C" { pub fn Gecko_SetLayerImageImageValue(image: *mut nsStyleImage, diff --git a/components/style/gecko/generated/structs_debug.rs b/components/style/gecko/generated/structs_debug.rs index 0ff3aa97058..81b6203eb6d 100644 --- a/components/style/gecko/generated/structs_debug.rs +++ b/components/style/gecko/generated/structs_debug.rs @@ -1851,17 +1851,52 @@ pub mod root { pub vtable_: *const URLValueData__bindgen_vtable, pub mRefCnt: root::mozilla::ThreadSafeAutoRefCnt, pub mURI: root::nsMainThreadPtrHandle, - pub mString: ::nsstring::nsStringRepr, pub mExtraData: root::RefPtr, pub mURIResolved: bool, pub mIsLocalRef: [u8; 2usize], pub mMightHaveRef: [u8; 2usize], + pub mStrings: root::mozilla::css::URLValueData_RustOrGeckoString, + pub mUsingRustString: bool, } pub type URLValueData_HasThreadSafeRefCnt = root::mozilla::TrueType; + #[repr(C)] + #[derive(Debug)] + pub struct URLValueData_RustOrGeckoString { + pub mString: root::__BindgenUnionField<::nsstring::nsStringRepr>, + pub mRustString: root::__BindgenUnionField<::gecko_bindings::structs::ServoRawOffsetArc>, + pub bindgen_union_field: [u64; 2usize], + } + #[test] + fn bindgen_test_layout_URLValueData_RustOrGeckoString() { + assert_eq!(::std::mem::size_of::() + , 16usize , concat ! ( + "Size of: " , stringify ! ( + URLValueData_RustOrGeckoString ) )); + assert_eq! (::std::mem::align_of::() + , 8usize , concat ! ( + "Alignment of " , stringify ! ( + URLValueData_RustOrGeckoString ) )); + assert_eq! (unsafe { + & ( + * ( 0 as * const URLValueData_RustOrGeckoString ) + ) . mString as * const _ as usize } , 0usize , + concat ! ( + "Alignment of field: " , stringify ! ( + URLValueData_RustOrGeckoString ) , "::" , + stringify ! ( mString ) )); + assert_eq! (unsafe { + & ( + * ( 0 as * const URLValueData_RustOrGeckoString ) + ) . mRustString as * const _ as usize } , 0usize , + concat ! ( + "Alignment of field: " , stringify ! ( + URLValueData_RustOrGeckoString ) , "::" , + stringify ! ( mRustString ) )); + } #[test] fn bindgen_test_layout_URLValueData() { - assert_eq!(::std::mem::size_of::() , 56usize , + assert_eq!(::std::mem::size_of::() , 64usize , concat ! ( "Size of: " , stringify ! ( URLValueData ) )); assert_eq! (::std::mem::align_of::() , 8usize , @@ -1878,39 +1913,46 @@ pub mod root { const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mURI ) )); - assert_eq! (unsafe { - & ( * ( 0 as * const URLValueData ) ) . mString as - * const _ as usize } , 24usize , concat ! ( - "Alignment of field: " , stringify ! ( - URLValueData ) , "::" , stringify ! ( mString ) - )); assert_eq! (unsafe { & ( * ( 0 as * const URLValueData ) ) . mExtraData - as * const _ as usize } , 40usize , concat ! ( + as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mExtraData ) )); assert_eq! (unsafe { & ( * ( 0 as * const URLValueData ) ) . - mURIResolved as * const _ as usize } , 48usize , + mURIResolved as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mURIResolved ) )); assert_eq! (unsafe { & ( * ( 0 as * const URLValueData ) ) . - mIsLocalRef as * const _ as usize } , 49usize , + mIsLocalRef as * const _ as usize } , 33usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mIsLocalRef ) )); assert_eq! (unsafe { & ( * ( 0 as * const URLValueData ) ) . - mMightHaveRef as * const _ as usize } , 51usize , + mMightHaveRef as * const _ as usize } , 35usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mMightHaveRef ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const URLValueData ) ) . mStrings + as * const _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( + URLValueData ) , "::" , stringify ! ( mStrings ) + )); + assert_eq! (unsafe { + & ( * ( 0 as * const URLValueData ) ) . + mUsingRustString as * const _ as usize } , 56usize + , concat ! ( + "Alignment of field: " , stringify ! ( + URLValueData ) , "::" , stringify ! ( + mUsingRustString ) )); } #[repr(C)] #[derive(Debug)] @@ -1919,7 +1961,7 @@ pub mod root { } #[test] fn bindgen_test_layout_URLValue() { - assert_eq!(::std::mem::size_of::() , 56usize , + assert_eq!(::std::mem::size_of::() , 64usize , concat ! ( "Size of: " , stringify ! ( URLValue ) )); assert_eq! (::std::mem::align_of::() , 8usize , @@ -1935,7 +1977,7 @@ pub mod root { } #[test] fn bindgen_test_layout_ImageValue() { - assert_eq!(::std::mem::size_of::() , 112usize , + assert_eq!(::std::mem::size_of::() , 120usize , concat ! ( "Size of: " , stringify ! ( ImageValue ) )); assert_eq! (::std::mem::align_of::() , 8usize , @@ -1943,12 +1985,12 @@ pub mod root { "Alignment of " , stringify ! ( ImageValue ) )); assert_eq! (unsafe { & ( * ( 0 as * const ImageValue ) ) . mRequests as - * const _ as usize } , 56usize , concat ! ( + * const _ as usize } , 64usize , concat ! ( "Alignment of field: " , stringify ! ( ImageValue ) , "::" , stringify ! ( mRequests ) )); assert_eq! (unsafe { & ( * ( 0 as * const ImageValue ) ) . mLoadedImage - as * const _ as usize } , 104usize , concat ! ( + as * const _ as usize } , 112usize , concat ! ( "Alignment of field: " , stringify ! ( ImageValue ) , "::" , stringify ! ( mLoadedImage ) )); } @@ -30038,6 +30080,11 @@ pub mod root { } | ((mHadDispatch as u8 as u8) << 6usize) & (64u64 as u8)) } } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct RustString { + _unused: [u8; 0], + } #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum nsCSSUnit { diff --git a/components/style/gecko/generated/structs_release.rs b/components/style/gecko/generated/structs_release.rs index b91938c68c2..33b34224b0f 100644 --- a/components/style/gecko/generated/structs_release.rs +++ b/components/style/gecko/generated/structs_release.rs @@ -1791,17 +1791,52 @@ pub mod root { pub vtable_: *const URLValueData__bindgen_vtable, pub mRefCnt: root::mozilla::ThreadSafeAutoRefCnt, pub mURI: root::nsMainThreadPtrHandle, - pub mString: ::nsstring::nsStringRepr, pub mExtraData: root::RefPtr, pub mURIResolved: bool, pub mIsLocalRef: [u8; 2usize], pub mMightHaveRef: [u8; 2usize], + pub mStrings: root::mozilla::css::URLValueData_RustOrGeckoString, + pub mUsingRustString: bool, } pub type URLValueData_HasThreadSafeRefCnt = root::mozilla::TrueType; + #[repr(C)] + #[derive(Debug)] + pub struct URLValueData_RustOrGeckoString { + pub mString: root::__BindgenUnionField<::nsstring::nsStringRepr>, + pub mRustString: root::__BindgenUnionField<::gecko_bindings::structs::ServoRawOffsetArc>, + pub bindgen_union_field: [u64; 2usize], + } + #[test] + fn bindgen_test_layout_URLValueData_RustOrGeckoString() { + assert_eq!(::std::mem::size_of::() + , 16usize , concat ! ( + "Size of: " , stringify ! ( + URLValueData_RustOrGeckoString ) )); + assert_eq! (::std::mem::align_of::() + , 8usize , concat ! ( + "Alignment of " , stringify ! ( + URLValueData_RustOrGeckoString ) )); + assert_eq! (unsafe { + & ( + * ( 0 as * const URLValueData_RustOrGeckoString ) + ) . mString as * const _ as usize } , 0usize , + concat ! ( + "Alignment of field: " , stringify ! ( + URLValueData_RustOrGeckoString ) , "::" , + stringify ! ( mString ) )); + assert_eq! (unsafe { + & ( + * ( 0 as * const URLValueData_RustOrGeckoString ) + ) . mRustString as * const _ as usize } , 0usize , + concat ! ( + "Alignment of field: " , stringify ! ( + URLValueData_RustOrGeckoString ) , "::" , + stringify ! ( mRustString ) )); + } #[test] fn bindgen_test_layout_URLValueData() { - assert_eq!(::std::mem::size_of::() , 56usize , + assert_eq!(::std::mem::size_of::() , 64usize , concat ! ( "Size of: " , stringify ! ( URLValueData ) )); assert_eq! (::std::mem::align_of::() , 8usize , @@ -1818,39 +1853,46 @@ pub mod root { const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mURI ) )); - assert_eq! (unsafe { - & ( * ( 0 as * const URLValueData ) ) . mString as - * const _ as usize } , 24usize , concat ! ( - "Alignment of field: " , stringify ! ( - URLValueData ) , "::" , stringify ! ( mString ) - )); assert_eq! (unsafe { & ( * ( 0 as * const URLValueData ) ) . mExtraData - as * const _ as usize } , 40usize , concat ! ( + as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mExtraData ) )); assert_eq! (unsafe { & ( * ( 0 as * const URLValueData ) ) . - mURIResolved as * const _ as usize } , 48usize , + mURIResolved as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mURIResolved ) )); assert_eq! (unsafe { & ( * ( 0 as * const URLValueData ) ) . - mIsLocalRef as * const _ as usize } , 49usize , + mIsLocalRef as * const _ as usize } , 33usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mIsLocalRef ) )); assert_eq! (unsafe { & ( * ( 0 as * const URLValueData ) ) . - mMightHaveRef as * const _ as usize } , 51usize , + mMightHaveRef as * const _ as usize } , 35usize , concat ! ( "Alignment of field: " , stringify ! ( URLValueData ) , "::" , stringify ! ( mMightHaveRef ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const URLValueData ) ) . mStrings + as * const _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( + URLValueData ) , "::" , stringify ! ( mStrings ) + )); + assert_eq! (unsafe { + & ( * ( 0 as * const URLValueData ) ) . + mUsingRustString as * const _ as usize } , 56usize + , concat ! ( + "Alignment of field: " , stringify ! ( + URLValueData ) , "::" , stringify ! ( + mUsingRustString ) )); } #[repr(C)] #[derive(Debug)] @@ -1859,7 +1901,7 @@ pub mod root { } #[test] fn bindgen_test_layout_URLValue() { - assert_eq!(::std::mem::size_of::() , 56usize , + assert_eq!(::std::mem::size_of::() , 64usize , concat ! ( "Size of: " , stringify ! ( URLValue ) )); assert_eq! (::std::mem::align_of::() , 8usize , @@ -1875,7 +1917,7 @@ pub mod root { } #[test] fn bindgen_test_layout_ImageValue() { - assert_eq!(::std::mem::size_of::() , 104usize , + assert_eq!(::std::mem::size_of::() , 112usize , concat ! ( "Size of: " , stringify ! ( ImageValue ) )); assert_eq! (::std::mem::align_of::() , 8usize , @@ -1883,12 +1925,12 @@ pub mod root { "Alignment of " , stringify ! ( ImageValue ) )); assert_eq! (unsafe { & ( * ( 0 as * const ImageValue ) ) . mRequests as - * const _ as usize } , 56usize , concat ! ( + * const _ as usize } , 64usize , concat ! ( "Alignment of field: " , stringify ! ( ImageValue ) , "::" , stringify ! ( mRequests ) )); assert_eq! (unsafe { & ( * ( 0 as * const ImageValue ) ) . mLoadedImage - as * const _ as usize } , 96usize , concat ! ( + as * const _ as usize } , 104usize , concat ! ( "Alignment of field: " , stringify ! ( ImageValue ) , "::" , stringify ! ( mLoadedImage ) )); } @@ -29606,6 +29648,11 @@ pub mod root { } | ((mHadDispatch as u8 as u8) << 6usize) & (64u64 as u8)) } } + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct RustString { + _unused: [u8; 0], + } #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum nsCSSUnit { diff --git a/components/style/gecko/url.rs b/components/style/gecko/url.rs index 04d3459aeec..ab19fab8d98 100644 --- a/components/style/gecko/url.rs +++ b/components/style/gecko/url.rs @@ -6,12 +6,13 @@ use gecko_bindings::structs::{ServoBundledURI, URLExtraData}; use gecko_bindings::structs::mozilla::css::URLValueData; +use gecko_bindings::structs::root::{nsStyleImageRequest, RustString}; use gecko_bindings::structs::root::mozilla::css::ImageValue; -use gecko_bindings::structs::root::nsStyleImageRequest; use gecko_bindings::sugar::refptr::RefPtr; use parser::ParserContext; -use servo_arc::Arc; +use servo_arc::{Arc, RawOffsetArc}; use std::fmt; +use std::mem; use style_traits::{ToCss, ParseError}; /// A specified url() value for gecko. Gecko does not eagerly resolve SpecifiedUrls. @@ -61,7 +62,14 @@ impl SpecifiedUrl { pub unsafe fn from_url_value_data(url: &URLValueData) -> Result { Ok(SpecifiedUrl { - serialization: Arc::new(url.mString.to_string()), + serialization: if url.mUsingRustString { + let arc_type = url.mStrings.mRustString.as_ref() + as *const _ as + *const RawOffsetArc; + Arc::from_raw_offset((*arc_type).clone()) + } else { + Arc::new(url.mStrings.mString.as_ref().to_string()) + }, extra_data: url.mExtraData.to_safe(), image_value: None, }) @@ -117,7 +125,10 @@ impl SpecifiedUrl { debug_assert_eq!(self.image_value, None); self.image_value = { unsafe { - let ptr = Gecko_ImageValue_Create(self.for_ffi()); + let arc_offset = Arc::into_raw_offset(self.serialization.clone()); + let ptr = Gecko_ImageValue_Create( + self.for_ffi(), + mem::transmute::<_, RawOffsetArc>(arc_offset)); // We do not expect Gecko_ImageValue_Create returns null. debug_assert!(!ptr.is_null()); Some(RefPtr::from_addrefed(ptr)) diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 2a0095d3d6e..e62ac1759bd 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -13,6 +13,7 @@ use std::cell::RefCell; use std::env; use std::fmt::Write; use std::iter; +use std::mem; use std::ptr; use style::applicable_declarations::ApplicableDeclarationBlock; use style::context::{CascadeInputs, QuirksMode, SharedStyleContext, StyleContext}; @@ -77,7 +78,7 @@ use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut; use style::gecko_bindings::structs; use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation}; use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets}; -use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleContextStrong}; +use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleContextStrong, RustString}; use style::gecko_bindings::structs::{ServoStyleSheet, SheetParsingMode, nsIAtom, nsCSSPropertyID}; use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule}; use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, PropertyValuePair}; @@ -3831,6 +3832,31 @@ pub extern "C" fn Servo_GetCustomPropertyNameAt(computed_values: ServoStyleConte true } +#[no_mangle] +pub unsafe extern "C" fn Servo_ReleaseArcStringData(string: *const RawOffsetArc) { + let string = string as *const RawOffsetArc; + // Cause RawOffsetArc::drop to run, releasing the strong reference to the string data. + let _ = ptr::read(string); +} + +#[no_mangle] +pub unsafe extern "C" fn Servo_CloneArcStringData(string: *const RawOffsetArc) + -> RawOffsetArc { + let string = string as *const RawOffsetArc; + let cloned = (*string).clone(); + mem::transmute::<_, RawOffsetArc>(cloned) +} + +#[no_mangle] +pub unsafe extern "C" fn Servo_GetArcStringData(string: *const RustString, + utf8_chars: *mut *const u8, + utf8_len: *mut u32) +{ + let string = &*(string as *const String); + *utf8_len = string.len() as u32; + *utf8_chars = string.as_ptr(); +} + #[no_mangle] pub extern "C" fn Servo_ProcessInvalidations(set: RawServoStyleSetBorrowed, element: RawGeckoElementBorrowed,