aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock6
-rw-r--r--components/style/Cargo.toml6
-rw-r--r--components/style/lib.rs2
-rw-r--r--ports/geckolib/Cargo.toml2
-rw-r--r--servo-tidy.toml1
-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();
+ }
+ }
+}