diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-10-23 17:26:28 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-23 17:26:28 -0500 |
commit | 0e6946fd9c279425e66721e6eb2b1e323e4c640f (patch) | |
tree | 91e7ae8f7b596ad1efd3df101a4ed2203b39d5f7 | |
parent | 00784fe5e1f6410a928655d606ccaf73f37984b7 (diff) | |
parent | 2d3331fbd43320c28c4c5e777ebc324456c0b771 (diff) | |
download | servo-0e6946fd9c279425e66721e6eb2b1e323e4c640f.tar.gz servo-0e6946fd9c279425e66721e6eb2b1e323e4c640f.zip |
Auto merge of #18993 - mystor:nsstring2, r=mystor
Move nsstring from gecko into servo/support/gecko/nsstring
This is the servo side of bug 1403213.
Take 2 of #18941 which got backed out because we botched the landing of the gecko side and I wasn't able to fix it in time.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18993)
<!-- Reviewable:end -->
-rw-r--r-- | Cargo.lock | 6 | ||||
-rw-r--r-- | components/style/Cargo.toml | 6 | ||||
-rw-r--r-- | components/style/lib.rs | 2 | ||||
-rw-r--r-- | ports/geckolib/Cargo.toml | 2 | ||||
-rw-r--r-- | servo-tidy.toml | 1 | ||||
-rw-r--r-- | support/gecko/nsstring/Cargo.toml (renamed from components/style/gecko_bindings/nsstring_vendor/Cargo.toml) | 9 | ||||
-rw-r--r-- | support/gecko/nsstring/src/lib.rs (renamed from components/style/gecko_bindings/nsstring_vendor/src/lib.rs) | 198 |
7 files changed, 200 insertions, 24 deletions
diff --git a/Cargo.lock b/Cargo.lock index 064537870f1..461d4de2eb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1071,7 +1071,7 @@ dependencies = [ "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", - "nsstring_vendor 0.1.0", + "nsstring 0.1.0", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.19.0", "servo_arc 0.0.1", @@ -2080,7 +2080,7 @@ dependencies = [ ] [[package]] -name = "nsstring_vendor" +name = "nsstring" version = "0.1.0" dependencies = [ "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3177,7 +3177,7 @@ dependencies = [ "malloc_size_of 0.0.1", "malloc_size_of_derive 0.0.1", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "nsstring_vendor 0.1.0", + "nsstring 0.1.0", "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 6c692a743c8..821b8eb7120 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -16,7 +16,7 @@ path = "lib.rs" doctest = false [features] -gecko = ["nsstring_vendor", "num_cpus", +gecko = ["nsstring", "num_cpus", "style_traits/gecko", "fallible/known_system_malloc"] use_bindgen = ["bindgen", "regex", "toml"] servo = ["serde", "style_traits/servo", "servo_atoms", "servo_config", "html5ever", @@ -26,7 +26,7 @@ servo = ["serde", "style_traits/servo", "servo_atoms", "servo_config", "html5eve #"arrayvec/use_union" "servo_url"] -gecko_debug = ["nsstring_vendor/gecko_debug"] +gecko_debug = ["nsstring/gecko_debug"] [dependencies] app_units = "0.5.5" @@ -50,7 +50,7 @@ log = "0.3" malloc_size_of = { path = "../malloc_size_of" } malloc_size_of_derive = { path = "../malloc_size_of_derive" } matches = "0.1" -nsstring_vendor = {path = "gecko_bindings/nsstring_vendor", optional = true} +nsstring = {path = "../../support/gecko/nsstring", optional = true} num_cpus = {version = "1.1.0", optional = true} num-integer = "0.1.32" num-traits = "0.1.32" diff --git a/components/style/lib.rs b/components/style/lib.rs index 505bbb97e4b..b7a7a0ecbab 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -64,7 +64,7 @@ extern crate lru_cache; #[macro_use] extern crate matches; #[cfg(feature = "gecko")] -pub extern crate nsstring_vendor as nsstring; +pub extern crate nsstring; #[cfg(feature = "gecko")] extern crate num_cpus; extern crate num_integer; extern crate num_traits; diff --git a/ports/geckolib/Cargo.toml b/ports/geckolib/Cargo.toml index a68ec26da03..23b12ac2963 100644 --- a/ports/geckolib/Cargo.toml +++ b/ports/geckolib/Cargo.toml @@ -20,7 +20,7 @@ env_logger = {version = "0.4", default-features = false} # disable `regex` to re libc = "0.2" log = {version = "0.3.5", features = ["release_max_level_info"]} malloc_size_of = {path = "../../components/malloc_size_of"} -nsstring_vendor = {path = "../../components/style/gecko_bindings/nsstring_vendor"} +nsstring = {path = "../../support/gecko/nsstring"} parking_lot = "0.4" # Turn on gecko_like_types because of so that crates which use this # crate and also dev-depend on stylo_tests get reasonable behavior diff --git a/servo-tidy.toml b/servo-tidy.toml index 0f344339605..aa9af94a77d 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -80,7 +80,6 @@ directories = [ # Generated and upstream code combined with our own. Could use cleanup "./target", "./ports/cef", - "./components/style/gecko_bindings/nsstring_vendor/", ] # Directories that are checked for correct file extension diff --git a/components/style/gecko_bindings/nsstring_vendor/Cargo.toml b/support/gecko/nsstring/Cargo.toml index 5aca14f7c2e..e445848f50c 100644 --- a/components/style/gecko_bindings/nsstring_vendor/Cargo.toml +++ b/support/gecko/nsstring/Cargo.toml @@ -1,15 +1,12 @@ [package] -name = "nsstring_vendor" +name = "nsstring" version = "0.1.0" authors = ["nobody@mozilla.com"] license = "MPL-2.0" description = "Rust bindings to xpcom string types" - -# Revendoring nsstring from m-c into Servo +[features] +gecko_debug = [] [dependencies] bitflags = "0.8" - -[features] -gecko_debug = [] diff --git a/components/style/gecko_bindings/nsstring_vendor/src/lib.rs b/support/gecko/nsstring/src/lib.rs index 5f287b236de..a7e9b3026cd 100644 --- a/components/style/gecko_bindings/nsstring_vendor/src/lib.rs +++ b/support/gecko/nsstring/src/lib.rs @@ -118,16 +118,16 @@ #[macro_use] extern crate bitflags; -use std::ops::{Deref, DerefMut}; -use std::marker::PhantomData; use std::borrow; -use std::slice; -use std::mem; -use std::fmt; use std::cmp; +use std::fmt; +use std::marker::PhantomData; +use std::mem; +use std::ops::{Deref, DerefMut}; +use std::os::raw::c_void; +use std::slice; use std::str; use std::u32; -use std::os::raw::c_void; /////////////////////////////////// // Internal Implementation Flags // @@ -138,7 +138,7 @@ mod data_flags { // While this has the same layout as u16, it cannot be passed // over FFI safely as a u16. #[repr(C)] - pub flags DataFlags : u16 { + pub flags DataFlags: u16 { const TERMINATED = 1 << 0, // IsTerminated returns true const VOIDED = 1 << 1, // IsVoid returns true const SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer @@ -154,15 +154,15 @@ mod class_flags { // While this has the same layout as u16, it cannot be passed // over FFI safely as a u16. #[repr(C)] - pub flags ClassFlags : u16 { + pub flags ClassFlags: u16 { const INLINE = 1 << 0, // |this|'s buffer is inline const NULL_TERMINATED = 1 << 1, // |this| requires its buffer is null-terminated } } } -use data_flags::DataFlags; use class_flags::ClassFlags; +use data_flags::DataFlags; //////////////////////////////////// // Generic String Bindings Macros // @@ -183,6 +183,7 @@ macro_rules! define_string_types { drop = $drop: ident; assign = $assign: ident, $fallible_assign: ident; + take_from = $take_from: ident, $fallible_take_from: ident; append = $append: ident, $fallible_append: ident; set_length = $set_length: ident, $fallible_set_length: ident; begin_writing = $begin_writing: ident, $fallible_begin_writing: ident; @@ -274,6 +275,25 @@ macro_rules! define_string_types { } } + /// Take the value of `other` and set `self`, overwriting any value + /// currently stored. The passed-in string will be truncated. + pub fn take_from(&mut self, other: &mut $AString) { + unsafe { $take_from(self, other) }; + } + + /// Take the value of `other` and set `self`, overwriting any value + /// currently stored. If this function fails, the source string will + /// be left untouched, otherwise it will be truncated. + /// + /// Returns Ok(()) on success, and Err(()) if the allocation failed. + pub fn fallible_take_from(&mut self, other: &mut $AString) -> Result<(), ()> { + if unsafe { $fallible_take_from(self, other) } { + Ok(()) + } else { + Err(()) + } + } + /// Append the value of `other` into self. pub fn append<T: $StringLike + ?Sized>(&mut self, other: &T) { unsafe { $append(self, other.adapt().as_ptr()) }; @@ -780,6 +800,7 @@ define_string_types! { drop = Gecko_FinalizeCString; assign = Gecko_AssignCString, Gecko_FallibleAssignCString; + take_from = Gecko_TakeFromCString, Gecko_FallibleTakeFromCString; append = Gecko_AppendCString, Gecko_FallibleAppendCString; set_length = Gecko_SetLengthCString, Gecko_FallibleSetLengthCString; begin_writing = Gecko_BeginWritingCString, Gecko_FallibleBeginWritingCString; @@ -913,6 +934,7 @@ define_string_types! { drop = Gecko_FinalizeString; assign = Gecko_AssignString, Gecko_FallibleAssignString; + take_from = Gecko_TakeFromString, Gecko_FallibleTakeFromString; append = Gecko_AppendString, Gecko_FallibleAppendString; set_length = Gecko_SetLengthString, Gecko_FallibleSetLengthString; begin_writing = Gecko_BeginWritingString, Gecko_FallibleBeginWritingString; @@ -998,10 +1020,12 @@ extern "C" { fn Gecko_FinalizeCString(this: *mut nsACString); fn Gecko_AssignCString(this: *mut nsACString, other: *const nsACString); + fn Gecko_TakeFromCString(this: *mut nsACString, other: *mut nsACString); fn Gecko_AppendCString(this: *mut nsACString, other: *const nsACString); fn Gecko_SetLengthCString(this: *mut nsACString, length: u32); fn Gecko_BeginWritingCString(this: *mut nsACString) -> *mut u8; fn Gecko_FallibleAssignCString(this: *mut nsACString, other: *const nsACString) -> bool; + fn Gecko_FallibleTakeFromCString(this: *mut nsACString, other: *mut nsACString) -> bool; fn Gecko_FallibleAppendCString(this: *mut nsACString, other: *const nsACString) -> bool; fn Gecko_FallibleSetLengthCString(this: *mut nsACString, length: u32) -> bool; fn Gecko_FallibleBeginWritingCString(this: *mut nsACString) -> *mut u8; @@ -1009,10 +1033,12 @@ extern "C" { fn Gecko_FinalizeString(this: *mut nsAString); fn Gecko_AssignString(this: *mut nsAString, other: *const nsAString); + fn Gecko_TakeFromString(this: *mut nsAString, other: *mut nsAString); fn Gecko_AppendString(this: *mut nsAString, other: *const nsAString); fn Gecko_SetLengthString(this: *mut nsAString, length: u32); fn Gecko_BeginWritingString(this: *mut nsAString) -> *mut u16; fn Gecko_FallibleAssignString(this: *mut nsAString, other: *const nsAString) -> bool; + fn Gecko_FallibleTakeFromString(this: *mut nsAString, other: *mut nsAString) -> bool; fn Gecko_FallibleAppendString(this: *mut nsAString, other: *const nsAString) -> bool; fn Gecko_FallibleSetLengthString(this: *mut nsAString, length: u32) -> bool; fn Gecko_FallibleBeginWritingString(this: *mut nsAString) -> *mut u16; @@ -1023,3 +1049,157 @@ extern "C" { fn Gecko_FallibleAppendUTF16toCString(this: *mut nsACString, other: *const nsAString) -> bool; fn Gecko_FallibleAppendUTF8toString(this: *mut nsAString, other: *const nsACString) -> bool; } + +////////////////////////////////////// +// Repr Validation Helper Functions // +////////////////////////////////////// + +pub mod test_helpers { + //! This module only exists to help with ensuring that the layout of the + //! structs inside of rust and C++ are identical. + //! + //! It is public to ensure that these testing functions are avaliable to + //! gtest code. + + use std::mem; + use super::{class_flags, data_flags}; + use super::{nsCStr, nsCString, nsCStringRepr}; + use super::{nsStr, nsString, nsStringRepr}; + + /// Generates an #[no_mangle] extern "C" function which returns the size and + /// alignment of the given type with the given name. + macro_rules! size_align_check { + ($T:ty, $fname:ident) => { + #[no_mangle] + #[allow(non_snake_case)] + pub extern fn $fname(size: *mut usize, align: *mut usize) { + unsafe { + *size = mem::size_of::<$T>(); + *align = mem::align_of::<$T>(); + } + } + }; + ($T:ty, $U:ty, $V:ty, $fname:ident) => { + #[no_mangle] + #[allow(non_snake_case)] + pub extern fn $fname(size: *mut usize, align: *mut usize) { + unsafe { + *size = mem::size_of::<$T>(); + *align = mem::align_of::<$T>(); + + assert_eq!(*size, mem::size_of::<$U>()); + assert_eq!(*align, mem::align_of::<$U>()); + assert_eq!(*size, mem::size_of::<$V>()); + assert_eq!(*align, mem::align_of::<$V>()); + } + } + } + } + + size_align_check!(nsStringRepr, nsString, nsStr<'static>, + Rust_Test_ReprSizeAlign_nsString); + size_align_check!(nsCStringRepr, nsCString, nsCStr<'static>, + Rust_Test_ReprSizeAlign_nsCString); + + /// Generates a $[no_mangle] extern "C" function which returns the size, + /// alignment and offset in the parent struct of a given member, with the + /// given name. + /// + /// This method can trigger Undefined Behavior if the accessing the member + /// $member on a given type would use that type's `Deref` implementation. + macro_rules! member_check { + ($T:ty, $member:ident, $method:ident) => { + #[no_mangle] + #[allow(non_snake_case)] + pub extern fn $method(size: *mut usize, + align: *mut usize, + offset: *mut usize) { + unsafe { + // Create a temporary value of type T to get offsets, sizes + // and aligns off of + let tmp: $T = mem::zeroed(); + *size = mem::size_of_val(&tmp.$member); + *align = mem::align_of_val(&tmp.$member); + *offset = + (&tmp.$member as *const _ as usize) - + (&tmp as *const _ as usize); + mem::forget(tmp); + } + } + }; + ($T:ty, $U:ty, $V:ty, $member:ident, $method:ident) => { + #[no_mangle] + #[allow(non_snake_case)] + pub extern fn $method(size: *mut usize, + align: *mut usize, + offset: *mut usize) { + unsafe { + // Create a temporary value of type T to get offsets, sizes + // and alignments from. + let tmp: $T = mem::zeroed(); + *size = mem::size_of_val(&tmp.$member); + *align = mem::align_of_val(&tmp.$member); + *offset = + (&tmp.$member as *const _ as usize) - + (&tmp as *const _ as usize); + mem::forget(tmp); + + let tmp: $U = mem::zeroed(); + assert_eq!(*size, mem::size_of_val(&tmp.hdr.$member)); + assert_eq!(*align, mem::align_of_val(&tmp.hdr.$member)); + assert_eq!(*offset, + (&tmp.hdr.$member as *const _ as usize) - + (&tmp as *const _ as usize)); + mem::forget(tmp); + + let tmp: $V = mem::zeroed(); + assert_eq!(*size, mem::size_of_val(&tmp.hdr.$member)); + assert_eq!(*align, mem::align_of_val(&tmp.hdr.$member)); + assert_eq!(*offset, + (&tmp.hdr.$member as *const _ as usize) - + (&tmp as *const _ as usize)); + mem::forget(tmp); + } + } + } + } + + member_check!(nsStringRepr, nsString, nsStr<'static>, + data, Rust_Test_Member_nsString_mData); + member_check!(nsStringRepr, nsString, nsStr<'static>, + length, Rust_Test_Member_nsString_mLength); + member_check!(nsStringRepr, nsString, nsStr<'static>, + dataflags, Rust_Test_Member_nsString_mDataFlags); + member_check!(nsStringRepr, nsString, nsStr<'static>, + classflags, Rust_Test_Member_nsString_mClassFlags); + member_check!(nsCStringRepr, nsCString, nsCStr<'static>, + data, Rust_Test_Member_nsCString_mData); + member_check!(nsCStringRepr, nsCString, nsCStr<'static>, + length, Rust_Test_Member_nsCString_mLength); + member_check!(nsCStringRepr, nsCString, nsCStr<'static>, + dataflags, Rust_Test_Member_nsCString_mDataFlags); + member_check!(nsCStringRepr, nsCString, nsCStr<'static>, + classflags, Rust_Test_Member_nsCString_mClassFlags); + + #[no_mangle] + #[allow(non_snake_case)] + pub extern fn Rust_Test_NsStringFlags(f_terminated: *mut u16, + f_voided: *mut u16, + f_shared: *mut u16, + f_owned: *mut u16, + f_inline: *mut u16, + f_literal: *mut u16, + f_class_inline: *mut u16, + f_class_null_terminated: *mut u16) { + unsafe { + *f_terminated = data_flags::TERMINATED.bits(); + *f_voided = data_flags::VOIDED.bits(); + *f_shared = data_flags::SHARED.bits(); + *f_owned = data_flags::OWNED.bits(); + *f_inline = data_flags::INLINE.bits(); + *f_literal = data_flags::LITERAL.bits(); + *f_class_inline = class_flags::INLINE.bits(); + *f_class_null_terminated = class_flags::NULL_TERMINATED.bits(); + } + } +} |