Bug 1312338 part 2 - Use nsACString to pass string parameters in binding functions. r?Manishearth draft
authorXidorn Quan <me@upsuper.org>
Mon, 24 Oct 2016 22:33:39 +1100
changeset 428622 afa0ef5d5df91107feab4a536ea151d665d8f5b1
parent 428620 58980527b68e8413f891c0ac554fb9a145d2e40c
child 534789 944b9147da2eebc23dd22b41201cd112532330a2
push id33370
push userxquan@mozilla.com
push dateMon, 24 Oct 2016 11:36:30 +0000
reviewersManishearth
bugs1312338
milestone52.0a1
Bug 1312338 part 2 - Use nsACString to pass string parameters in binding functions. r?Manishearth MozReview-Commit-ID: BRKZBQJCrMQ
dom/animation/KeyframeUtils.cpp
layout/style/CSS.cpp
layout/style/ServoBindingList.h
layout/style/ServoDeclarationBlock.cpp
layout/style/ServoStyleSheet.cpp
servo/components/style/binding_tools/regen.py
servo/components/style/gecko_bindings/bindings.rs
servo/ports/geckolib/glue.rs
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -1003,21 +1003,18 @@ MakePropertyValuePair(nsCSSPropertyID aP
       new ThreadSafeURIHolder(aDocument->GetDocumentURI());
     RefPtr<ThreadSafePrincipalHolder> principal =
       new ThreadSafePrincipalHolder(aDocument->NodePrincipal());
 
     nsCString baseString;
     aDocument->GetDocumentURI()->GetSpec(baseString);
 
     RefPtr<RawServoDeclarationBlock> servoDeclarationBlock =
-      Servo_ParseProperty(
-        reinterpret_cast<const uint8_t*>(name.get()), name.Length(),
-        reinterpret_cast<const uint8_t*>(value.get()), value.Length(),
-        reinterpret_cast<const uint8_t*>(baseString.get()), baseString.Length(),
-        base, referrer, principal).Consume();
+      Servo_ParseProperty(&name, &value, &baseString,
+                          base, referrer, principal).Consume();
 
     if (servoDeclarationBlock) {
       result.mServoDeclarationBlock = servoDeclarationBlock.forget();
       return result;
     }
   }
 
   nsCSSValue value;
--- a/layout/style/CSS.cpp
+++ b/layout/style/CSS.cpp
@@ -60,21 +60,17 @@ CSS::Supports(const GlobalObject& aGloba
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return false;
   }
 
   if (info.mStyleBackendType == StyleBackendType::Servo) {
     NS_ConvertUTF16toUTF8 property(aProperty);
     NS_ConvertUTF16toUTF8 value(aValue);
-
-    return Servo_CSSSupports(reinterpret_cast<const uint8_t*>(property.get()),
-                             property.Length(),
-                             reinterpret_cast<const uint8_t*>(value.get()),
-                             value.Length());
+    return Servo_CSSSupports(&property, &value);
   }
 
   nsCSSParser parser;
   return parser.EvaluateSupportsDeclaration(aProperty, aValue, info.mDocURI,
                                             info.mBaseURI, info.mPrincipal);
 }
 
 /* static */ bool
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -18,19 +18,19 @@
  * before including this file.
  */
 
 // Node data
 SERVO_BINDING_FUNC(Servo_Node_ClearNodeData, void, RawGeckoNodeBorrowed node)
 
 // Styleset and Stylesheet management
 SERVO_BINDING_FUNC(Servo_StyleSheet_FromUTF8Bytes, RawServoStyleSheetStrong,
-                   const uint8_t* bytes, uint32_t length,
+                   const nsACString* data,
                    mozilla::css::SheetParsingMode parsing_mode,
-                   const uint8_t* base_bytes, uint32_t base_length,
+                   const nsACString* base_url,
                    ThreadSafeURIHolder* base,
                    ThreadSafeURIHolder* referrer,
                    ThreadSafePrincipalHolder* principal)
 SERVO_BINDING_FUNC(Servo_StyleSheet_AddRef, void,
                    RawServoStyleSheetBorrowed sheet)
 SERVO_BINDING_FUNC(Servo_StyleSheet_Release, void,
                    RawServoStyleSheetBorrowed sheet)
 SERVO_BINDING_FUNC(Servo_StyleSheet_HasRules, bool,
@@ -45,48 +45,42 @@ SERVO_BINDING_FUNC(Servo_StyleSet_Remove
                    RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
 SERVO_BINDING_FUNC(Servo_StyleSet_InsertStyleSheetBefore, void,
                    RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet,
                    RawServoStyleSheetBorrowed reference)
 
 // Animations API
 SERVO_BINDING_FUNC(Servo_ParseProperty,
                    RawServoDeclarationBlockStrong,
-                   const uint8_t* property_bytes,
-                   uint32_t property_length,
-                   const uint8_t* value_bytes,
-                   uint32_t value_length,
-                   const uint8_t* base_bytes,
-                   uint32_t base_length,
-                   ThreadSafeURIHolder* base,
+                   const nsACString* property, const nsACString* value,
+                   const nsACString* base_url, ThreadSafeURIHolder* base,
                    ThreadSafeURIHolder* referrer,
                    ThreadSafePrincipalHolder* principal)
 SERVO_BINDING_FUNC(Servo_RestyleWithAddedDeclaration,
                    ServoComputedValuesStrong,
                    RawServoDeclarationBlockBorrowed declarations,
                    ServoComputedValuesBorrowed previous_style)
 
 // Style attribute
 SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
-                   const uint8_t* bytes, uint32_t length)
+                   const nsACString* data)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_AddRef, void,
                    RawServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Release, void,
                    RawServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Equals, bool,
                    RawServoDeclarationBlockBorrowed a,
                    RawServoDeclarationBlockBorrowed b)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SerializeOneValue, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsString* buffer)
 
 // CSS supports()
 SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
-                   const uint8_t* name, uint32_t name_length,
-                   const uint8_t* value, uint32_t value_length)
+                   const nsACString* name, const nsACString* value)
 
 // Computed style data
 SERVO_BINDING_FUNC(Servo_ComputedValues_Get, ServoComputedValuesStrong,
                    RawGeckoNodeBorrowed node)
 SERVO_BINDING_FUNC(Servo_ComputedValues_GetForAnonymousBox,
                    ServoComputedValuesStrong,
                    ServoComputedValuesBorrowedOrNull parent_style_or_null,
                    nsIAtom* pseudoTag, RawServoStyleSetBorrowed set)
--- a/layout/style/ServoDeclarationBlock.cpp
+++ b/layout/style/ServoDeclarationBlock.cpp
@@ -8,15 +8,15 @@
 #include "mozilla/ServoBindings.h"
 
 namespace mozilla {
 
 /* static */ already_AddRefed<ServoDeclarationBlock>
 ServoDeclarationBlock::FromStyleAttribute(const nsAString& aString)
 {
   NS_ConvertUTF16toUTF8 value(aString);
-  RefPtr<RawServoDeclarationBlock> raw = Servo_ParseStyleAttribute(
-      reinterpret_cast<const uint8_t*>(value.get()), value.Length()).Consume();
+  RefPtr<RawServoDeclarationBlock>
+    raw = Servo_ParseStyleAttribute(&value).Consume();
   RefPtr<ServoDeclarationBlock> decl = new ServoDeclarationBlock(raw.forget());
   return decl.forget();
 }
 
 } // namespace mozilla
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -70,21 +70,18 @@ ServoStyleSheet::ParseSheet(const nsAStr
   RefPtr<ThreadSafePrincipalHolder> principal =
     new ThreadSafePrincipalHolder(aSheetPrincipal);
 
   nsCString baseString;
   nsresult rv = aBaseURI->GetSpec(baseString);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ConvertUTF16toUTF8 input(aInput);
-  mSheet = Servo_StyleSheet_FromUTF8Bytes(
-      reinterpret_cast<const uint8_t*>(input.get()), input.Length(),
-      mParsingMode,
-      reinterpret_cast<const uint8_t*>(baseString.get()), baseString.Length(),
-      base, referrer, principal).Consume();
+  mSheet = Servo_StyleSheet_FromUTF8Bytes(&input, mParsingMode, &baseString,
+                                          base, referrer, principal).Consume();
 
   return NS_OK;
 }
 
 void
 ServoStyleSheet::DropSheet()
 {
   mSheet = nullptr;
--- a/servo/components/style/binding_tools/regen.py
+++ b/servo/components/style/binding_tools/regen.py
@@ -228,17 +228,23 @@ COMPILATION_TARGETS = {
                 "gecko": "ServoNodeData",
                 "servo": "OpaqueStyleData"
             }
         ],
     },
     # Generation of the ffi bindings.
     "bindings": {
         "target_dir": "../gecko_bindings",
-        "raw_lines": [],
+        "blacklist_types": [
+            "nsACString_internal",
+        ],
+        "raw_lines": [
+            "pub use nsstring::nsACString;",
+            "type nsACString_internal = nsACString;",
+        ],
         "flags": [
             "--ignore-methods",
         ],
         "match_headers": [
             "ServoBindingList.h",
             "ServoBindings.h",
             "nsStyleStructList.h",
         ],
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -1,10 +1,12 @@
 /* automatically generated by rust-bindgen */
 
+pub use nsstring::nsACString;
+type nsACString_internal = nsACString;
 pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>;
 pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;
 pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;
 enum ServoComputedValuesVoid{ }
 pub struct ServoComputedValues(ServoComputedValuesVoid);
 pub type RawServoStyleSheetStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheet>;
 pub type RawServoStyleSheetBorrowedOrNull<'a> = Option<&'a RawServoStyleSheet>;
 pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet;
@@ -825,20 +827,20 @@ extern "C" {
 }
 extern "C" {
     pub fn Gecko_Destroy_nsStyleEffects(ptr: *mut nsStyleEffects);
 }
 extern "C" {
     pub fn Servo_Node_ClearNodeData(node: RawGeckoNodeBorrowed);
 }
 extern "C" {
-    pub fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8, length: u32,
+    pub fn Servo_StyleSheet_FromUTF8Bytes(data: *const nsACString_internal,
                                           parsing_mode: SheetParsingMode,
-                                          base_bytes: *const u8,
-                                          base_length: u32,
+                                          base_url:
+                                              *const nsACString_internal,
                                           base: *mut ThreadSafeURIHolder,
                                           referrer: *mut ThreadSafeURIHolder,
                                           principal:
                                               *mut ThreadSafePrincipalHolder)
      -> RawServoStyleSheetStrong;
 }
 extern "C" {
     pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed)
@@ -864,49 +866,48 @@ extern "C" {
     pub fn Servo_StyleSet_InsertStyleSheetBefore(set:
                                                      RawServoStyleSetBorrowed,
                                                  sheet:
                                                      RawServoStyleSheetBorrowed,
                                                  reference:
                                                      RawServoStyleSheetBorrowed);
 }
 extern "C" {
-    pub fn Servo_ParseProperty(property_bytes: *const u8,
-                               property_length: u32, value_bytes: *const u8,
-                               value_length: u32, base_bytes: *const u8,
-                               base_length: u32,
+    pub fn Servo_ParseProperty(property: *const nsACString_internal,
+                               value: *const nsACString_internal,
+                               base_url: *const nsACString_internal,
                                base: *mut ThreadSafeURIHolder,
                                referrer: *mut ThreadSafeURIHolder,
                                principal: *mut ThreadSafePrincipalHolder)
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
     pub fn Servo_RestyleWithAddedDeclaration(declarations:
                                                  RawServoDeclarationBlockBorrowed,
                                              previous_style:
                                                  ServoComputedValuesBorrowed)
      -> ServoComputedValuesStrong;
 }
 extern "C" {
-    pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32)
+    pub fn Servo_ParseStyleAttribute(data: *const nsACString_internal)
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed,
                                          b: RawServoDeclarationBlockBorrowed)
      -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SerializeOneValue(declarations:
                                                         RawServoDeclarationBlockBorrowed,
                                                     buffer: *mut nsString);
 }
 extern "C" {
-    pub fn Servo_CSSSupports(name: *const u8, name_length: u32,
-                             value: *const u8, value_length: u32) -> bool;
+    pub fn Servo_CSSSupports(name: *const nsACString_internal,
+                             value: *const nsACString_internal) -> bool;
 }
 extern "C" {
     pub fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed)
      -> ServoComputedValuesStrong;
 }
 extern "C" {
     pub fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
                                                        ServoComputedValuesBorrowedOrNull,
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -3,18 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use app_units::Au;
 use cssparser::{Parser, ToCss};
 use env_logger;
 use euclid::Size2D;
 use parking_lot::RwLock;
 use std::mem::transmute;
-use std::slice;
-use std::str::from_utf8_unchecked;
 use std::sync::{Arc, Mutex};
 use style::arc_ptr_eq;
 use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
 use style::dom::{NodeInfo, TElement, TNode};
 use style::error_reporting::StdoutErrorReporter;
 use style::gecko::data::{NUM_THREADS, PerDocumentStyleData};
 use style::gecko::selector_impl::{GeckoSelectorImpl, PseudoElement};
 use style::gecko::snapshot::GeckoElementSnapshot;
@@ -24,16 +22,17 @@ use style::gecko::wrapper::DUMMY_BASE_UR
 use style::gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoNodeBorrowed};
 use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
 use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
 use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
 use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
 use style::gecko_bindings::bindings::{ThreadSafePrincipalHolder, ThreadSafeURIHolder};
 use style::gecko_bindings::bindings::Gecko_Utf8SliceToString;
 use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
+use style::gecko_bindings::bindings::nsACString;
 use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom};
 use style::gecko_bindings::structs::ServoElementSnapshot;
 use style::gecko_bindings::structs::nsRestyleHint;
 use style::gecko_bindings::structs::nsString;
 use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasBoxFFI};
 use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
 use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
 use style::parallel;
@@ -156,34 +155,32 @@ pub extern "C" fn Servo_StyleWorkerThrea
 
 #[no_mangle]
 pub extern "C" fn Servo_Node_ClearNodeData(node: RawGeckoNodeBorrowed) -> () {
     let node = GeckoNode(node);
     node.clear_data();
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(bytes: *const u8,
-                                                length: u32,
-                                                mode: SheetParsingMode,
-                                                base_bytes: *const u8,
-                                                base_length: u32,
-                                                base: *mut ThreadSafeURIHolder,
-                                                referrer: *mut ThreadSafeURIHolder,
-                                                principal: *mut ThreadSafePrincipalHolder)
-                                                -> RawServoStyleSheetStrong {
-    let input = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
+pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(data: *const nsACString,
+                                                 mode: SheetParsingMode,
+                                                 base_url: *const nsACString,
+                                                 base: *mut ThreadSafeURIHolder,
+                                                 referrer: *mut ThreadSafeURIHolder,
+                                                 principal: *mut ThreadSafePrincipalHolder)
+                                                 -> RawServoStyleSheetStrong {
+    let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
 
     let origin = match mode {
         SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
         SheetParsingMode::eUserSheetFeatures => Origin::User,
         SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
     };
 
-    let base_str = unsafe { from_utf8_unchecked(slice::from_raw_parts(base_bytes, base_length as usize)) };
+    let base_str = unsafe { base_url.as_ref().unwrap().as_str_unchecked() };
     let url = Url::parse(base_str).unwrap();
     let extra_data = unsafe { ParserContextExtraData {
         base: Some(GeckoArcURI::new(base)),
         referrer: Some(GeckoArcURI::new(referrer)),
         principal: Some(GeckoArcPrincipal::new(principal)),
     }};
     let sheet = Arc::new(Stylesheet::from_str(input, url, origin, Box::new(StdoutErrorReporter),
                                               extra_data));
@@ -361,63 +358,54 @@ pub extern "C" fn Servo_StyleSet_Init() 
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) -> () {
     let _ = data.into_box::<PerDocumentStyleData>();
 }
 
 
 #[no_mangle]
-pub extern "C" fn Servo_ParseProperty(property_bytes: *const u8,
-                                      property_length: u32,
-                                      value_bytes: *const u8,
-                                      value_length: u32,
-                                      base_bytes: *const u8,
-                                      base_length: u32,
-                                      base: *mut ThreadSafeURIHolder,
+pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const nsACString,
+                                      base_url: *const nsACString, base: *mut ThreadSafeURIHolder,
                                       referrer: *mut ThreadSafeURIHolder,
                                       principal: *mut ThreadSafePrincipalHolder)
                                       -> RawServoDeclarationBlockStrong {
     // All this string wrangling is temporary until the Gecko string bindings land (bug 1294742).
-    let name = unsafe { from_utf8_unchecked(slice::from_raw_parts(property_bytes,
-                                                                  property_length as usize)) };
-    let value_str = unsafe { from_utf8_unchecked(slice::from_raw_parts(value_bytes,
-                                                                       value_length as usize)) };
-    let base_str = unsafe { from_utf8_unchecked(slice::from_raw_parts(base_bytes,
-                                                                      base_length as usize)) };
+    let name = unsafe { property.as_ref().unwrap().as_str_unchecked() };
+    let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
+    let base_str = unsafe { base_url.as_ref().unwrap().as_str_unchecked() };
     let base_url = Url::parse(base_str).unwrap();
     let extra_data = unsafe { ParserContextExtraData {
         base: Some(GeckoArcURI::new(base)),
         referrer: Some(GeckoArcURI::new(referrer)),
         principal: Some(GeckoArcPrincipal::new(principal)),
     }};
 
     let context = ParserContext::new_with_extra_data(Origin::Author, &base_url,
                                                      Box::new(StdoutErrorReporter),
                                                      extra_data);
 
     let mut results = vec![];
-    match PropertyDeclaration::parse(name, &context, &mut Parser::new(value_str),
+    match PropertyDeclaration::parse(name, &context, &mut Parser::new(value),
                                      &mut results, false) {
         PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {},
         _ => return RawServoDeclarationBlockStrong::null(),
     }
 
     let results = results.into_iter().map(|r| (r, Importance::Normal)).collect();
 
     Arc::new(RwLock::new(PropertyDeclarationBlock {
         declarations: results,
         important_count: 0,
     })).into_strong()
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32)
-                                            -> RawServoDeclarationBlockStrong {
-    let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
+pub extern "C" fn Servo_ParseStyleAttribute(data: *const nsACString) -> RawServoDeclarationBlockStrong {
+    let value = unsafe { data.as_ref().unwrap().as_str_unchecked() };
     Arc::new(RwLock::new(GeckoElement::parse_style_attribute(value))).into_strong()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: RawServoDeclarationBlockBorrowed) {
     unsafe { RwLock::<PropertyDeclarationBlock>::addref(declarations) };
 }
 
@@ -461,20 +449,19 @@ pub extern "C" fn Servo_DeclarationBlock
     // FIXME: Once we have nsString bindings for Servo (bug 1294742), we should be able to drop
     // this and fill in |buffer| directly.
     unsafe {
         Gecko_Utf8SliceToString(buffer, value.as_ptr(), length);
     }
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_CSSSupports(property: *const u8, property_length: u32,
-                                    value: *const u8, value_length: u32) -> bool {
-    let property = unsafe { from_utf8_unchecked(slice::from_raw_parts(property, property_length as usize)) };
-    let value    = unsafe { from_utf8_unchecked(slice::from_raw_parts(value, value_length as usize)) };
+pub extern "C" fn Servo_CSSSupports(property: *const nsACString, value: *const nsACString) -> bool {
+    let property = unsafe { property.as_ref().unwrap().as_str_unchecked() };
+    let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
 
     let base_url = &*DUMMY_BASE_URL;
     let extra_data = ParserContextExtraData::default();
 
     match parse_one_declaration(&property, &value, &base_url, Box::new(StdoutErrorReporter), extra_data) {
         Ok(decls) => !decls.is_empty(),
         Err(()) => false,
     }