Bug 1295762 - Part 2: Add tests to ensure that the layout of rust's ns[C]String matches C++'s, r=froydnj

MozReview-Commit-ID: FH18iSXkhX5
This commit is contained in:
Michael Layzell 2016-08-19 15:47:26 -04:00
Родитель dace0b2e39
Коммит 0f0181c55e
2 изменённых файлов: 324 добавлений и 0 удалений

Просмотреть файл

@ -10,6 +10,162 @@ extern "C" {
}
}
extern "C" void Rust_Test_StringReprInformation(size_t* size,
size_t* align,
size_t* dataOff,
size_t* dataSize,
size_t* lengthOff,
size_t* lengthSize,
size_t* flagsOff,
size_t* flagsSize);
TEST(RustNsString, StringRepr) {
class nsStringHack : public nsString {
public:
static void RunTest() {
size_t size, align, dataOff, dataSize, lengthOff, lengthSize, flagsOff, flagsSize;
Rust_Test_StringReprInformation(&size, &align,
&dataOff, &dataSize,
&lengthOff, &lengthSize,
&flagsOff, &flagsSize);
EXPECT_EQ(sizeof(nsString), sizeof(nsStringHack));
EXPECT_EQ(size, sizeof(nsStringHack));
EXPECT_EQ(align, alignof(nsStringHack));
EXPECT_EQ(dataOff, offsetof(nsStringHack, mData));
EXPECT_EQ(dataSize, sizeof(mozilla::DeclVal<nsStringHack>().mData));
EXPECT_EQ(lengthOff, offsetof(nsStringHack, mLength));
EXPECT_EQ(lengthSize, sizeof(mozilla::DeclVal<nsStringHack>().mLength));
EXPECT_EQ(flagsOff, offsetof(nsStringHack, mFlags));
EXPECT_EQ(flagsSize, sizeof(mozilla::DeclVal<nsStringHack>().mFlags));
}
};
nsStringHack::RunTest();
}
extern "C" void Rust_Test_CStringReprInformation(size_t* size,
size_t* align,
size_t* dataOff,
size_t* dataSize,
size_t* lengthOff,
size_t* lengthSize,
size_t* flagsOff,
size_t* flagsSize);
TEST(RustNsString, CStringRepr) {
class nsCStringHack : public nsCString {
public:
static void RunTest() {
size_t size, align, dataOff, dataSize, lengthOff, lengthSize, flagsOff, flagsSize;
Rust_Test_CStringReprInformation(&size, &align,
&dataOff, &dataSize,
&lengthOff, &lengthSize,
&flagsOff, &flagsSize);
EXPECT_EQ(sizeof(nsCString), sizeof(nsCStringHack));
EXPECT_EQ(size, sizeof(nsCStringHack));
EXPECT_EQ(align, alignof(nsCStringHack));
EXPECT_EQ(dataOff, offsetof(nsCStringHack, mData));
EXPECT_EQ(dataSize, sizeof(mozilla::DeclVal<nsCStringHack>().mData));
EXPECT_EQ(lengthOff, offsetof(nsCStringHack, mLength));
EXPECT_EQ(lengthSize, sizeof(mozilla::DeclVal<nsCStringHack>().mLength));
EXPECT_EQ(flagsOff, offsetof(nsCStringHack, mFlags));
EXPECT_EQ(flagsSize, sizeof(mozilla::DeclVal<nsCStringHack>().mFlags));
}
};
nsCStringHack::RunTest();
}
extern "C" void Rust_Test_FixedStringReprInformation(size_t* size,
size_t* align,
size_t* baseOff,
size_t* baseSize,
size_t* capacityOff,
size_t* capacitySize,
size_t* bufferOff,
size_t* bufferSize);
TEST(RustNsString, FixedStringRepr) {
class nsFixedStringHack : public nsFixedString {
public:
static void RunTest() {
size_t size, align, baseOff, baseSize, capacityOff, capacitySize, bufferOff, bufferSize;
Rust_Test_FixedStringReprInformation(&size, &align,
&baseOff, &baseSize,
&capacityOff, &capacitySize,
&bufferOff, &bufferSize);
EXPECT_EQ(sizeof(nsFixedString), sizeof(nsFixedStringHack));
EXPECT_EQ(size, sizeof(nsFixedStringHack));
EXPECT_EQ(align, alignof(nsFixedStringHack));
EXPECT_EQ(baseOff, (size_t)0);
EXPECT_EQ(baseSize, sizeof(nsString));
EXPECT_EQ(capacityOff, offsetof(nsFixedStringHack, mFixedCapacity));
EXPECT_EQ(capacitySize, sizeof(mozilla::DeclVal<nsFixedStringHack>().mFixedCapacity));
EXPECT_EQ(bufferOff, offsetof(nsFixedStringHack, mFixedBuf));
EXPECT_EQ(bufferSize, sizeof(mozilla::DeclVal<nsFixedStringHack>().mFixedBuf));
}
};
nsFixedStringHack::RunTest();
}
extern "C" void Rust_Test_FixedCStringReprInformation(size_t* size,
size_t* align,
size_t* baseOff,
size_t* baseSize,
size_t* capacityOff,
size_t* capacitySize,
size_t* bufferOff,
size_t* bufferSize);
TEST(RustNsString, FixedCStringRepr) {
class nsFixedCStringHack : public nsFixedCString {
public:
static void RunTest() {
size_t size, align, baseOff, baseSize, capacityOff, capacitySize, bufferOff, bufferSize;
Rust_Test_FixedCStringReprInformation(&size, &align,
&baseOff, &baseSize,
&capacityOff, &capacitySize,
&bufferOff, &bufferSize);
EXPECT_EQ(sizeof(nsFixedCString), sizeof(nsFixedCStringHack));
EXPECT_EQ(size, sizeof(nsFixedCStringHack));
EXPECT_EQ(align, alignof(nsFixedCStringHack));
EXPECT_EQ(baseOff, (size_t)0);
EXPECT_EQ(baseSize, sizeof(nsCString));
EXPECT_EQ(capacityOff, offsetof(nsFixedCStringHack, mFixedCapacity));
EXPECT_EQ(capacitySize, sizeof(mozilla::DeclVal<nsFixedCStringHack>().mFixedCapacity));
EXPECT_EQ(bufferOff, offsetof(nsFixedCStringHack, mFixedBuf));
EXPECT_EQ(bufferSize, sizeof(mozilla::DeclVal<nsFixedCStringHack>().mFixedBuf));
}
};
nsFixedCStringHack::RunTest();
}
extern "C" void Rust_Test_NsStringFlags(uint32_t* f_none,
uint32_t* f_terminated,
uint32_t* f_voided,
uint32_t* f_shared,
uint32_t* f_owned,
uint32_t* f_fixed,
uint32_t* f_literal,
uint32_t* f_class_fixed);
TEST(RustNsString, NsStringFlags) {
uint32_t f_none, f_terminated, f_voided, f_shared, f_owned, f_fixed, f_literal, f_class_fixed;
Rust_Test_NsStringFlags(&f_none, &f_terminated,
&f_voided, &f_shared,
&f_owned, &f_fixed,
&f_literal, &f_class_fixed);
EXPECT_EQ(f_none, nsAString::F_NONE);
EXPECT_EQ(f_none, nsACString::F_NONE);
EXPECT_EQ(f_terminated, nsAString::F_TERMINATED);
EXPECT_EQ(f_terminated, nsACString::F_TERMINATED);
EXPECT_EQ(f_voided, nsAString::F_VOIDED);
EXPECT_EQ(f_voided, nsACString::F_VOIDED);
EXPECT_EQ(f_shared, nsAString::F_SHARED);
EXPECT_EQ(f_shared, nsACString::F_SHARED);
EXPECT_EQ(f_owned, nsAString::F_OWNED);
EXPECT_EQ(f_owned, nsACString::F_OWNED);
EXPECT_EQ(f_fixed, nsAString::F_FIXED);
EXPECT_EQ(f_fixed, nsACString::F_FIXED);
EXPECT_EQ(f_literal, nsAString::F_LITERAL);
EXPECT_EQ(f_literal, nsACString::F_LITERAL);
EXPECT_EQ(f_class_fixed, nsAString::F_CLASS_FIXED);
EXPECT_EQ(f_class_fixed, nsACString::F_CLASS_FIXED);
}
extern "C" void Rust_StringFromCpp(const nsACString* aCStr, const nsAString* aStr);
TEST(RustNsString, StringFromCpp) {
nsAutoCString foo;

Просмотреть файл

@ -727,3 +727,171 @@ extern "C" {
fn Gecko_AppendUTF16toCString(this: *mut nsACString, other: *const nsAString);
fn Gecko_AppendUTF8toString(this: *mut nsAString, other: *const nsACString);
}
//////////////////////////////////////
// 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 super::{
nsFixedCStringRepr,
nsFixedStringRepr,
nsCStringRepr,
nsStringRepr,
F_NONE,
F_TERMINATED,
F_VOIDED,
F_SHARED,
F_OWNED,
F_FIXED,
F_LITERAL,
F_CLASS_FIXED,
};
use std::mem;
// A helper macro for finding the offset of a member of a struct. This macro is
// unsafe to use, because it can trigger UB if the type T's `Deref`
// implementation is implicitly used to access the member $m.
macro_rules! offset_of {
($T:ty, $m:ident) => {
{
let tmp: $T = mem::zeroed();
let offset =
(&tmp.$m as *const _ as usize) -
(&tmp as *const _ as usize);
mem::forget(tmp);
offset
}
}
}
// A helper macro for finding the size of a member of a struct. This macro is
// unsafe to use, because it can trigger UB if the type T's `Deref`
// implementation is implicitly used to access the member $m.
macro_rules! size_of_member {
($T:ty, $m:ident) => {
{
let tmp: $T = mem::zeroed();
let size = mem::size_of_val(&tmp.$m);
mem::forget(tmp);
size
}
}
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn Rust_Test_CStringReprInformation(size: *mut usize,
align: *mut usize,
data_off: *mut usize,
data_size: *mut usize,
length_off: *mut usize,
length_size: *mut usize,
flags_off: *mut usize,
flags_size: *mut usize) {
unsafe {
*size = mem::size_of::<nsCStringRepr>();
*align = mem::align_of::<nsCStringRepr>();
*data_off = offset_of!(nsCStringRepr, data);
*data_size = size_of_member!(nsCStringRepr, data);
*length_off = offset_of!(nsCStringRepr, length);
*length_size = size_of_member!(nsCStringRepr, length);
*flags_off = offset_of!(nsCStringRepr, flags);
*flags_size = size_of_member!(nsCStringRepr, flags);
}
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn Rust_Test_StringReprInformation(size: *mut usize,
align: *mut usize,
data_off: *mut usize,
data_size: *mut usize,
length_off: *mut usize,
length_size: *mut usize,
flags_off: *mut usize,
flags_size: *mut usize) {
unsafe {
*size = mem::size_of::<nsStringRepr>();
*align = mem::align_of::<nsStringRepr>();
*data_off = offset_of!(nsStringRepr, data);
*data_size = size_of_member!(nsStringRepr, data);
*length_off = offset_of!(nsStringRepr, length);
*length_size = size_of_member!(nsStringRepr, length);
*flags_off = offset_of!(nsStringRepr, flags);
*flags_size = size_of_member!(nsStringRepr, flags);
}
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn Rust_Test_FixedCStringReprInformation(size: *mut usize,
align: *mut usize,
base_off: *mut usize,
base_size: *mut usize,
capacity_off: *mut usize,
capacity_size: *mut usize,
buffer_off: *mut usize,
buffer_size: *mut usize) {
unsafe {
*size = mem::size_of::<nsFixedCStringRepr>();
*align = mem::align_of::<nsFixedCStringRepr>();
*base_off = offset_of!(nsFixedCStringRepr, base);
*base_size = size_of_member!(nsFixedCStringRepr, base);
*capacity_off = offset_of!(nsFixedCStringRepr, capacity);
*capacity_size = size_of_member!(nsFixedCStringRepr, capacity);
*buffer_off = offset_of!(nsFixedCStringRepr, buffer);
*buffer_size = size_of_member!(nsFixedCStringRepr, buffer);
}
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn Rust_Test_FixedStringReprInformation(size: *mut usize,
align: *mut usize,
base_off: *mut usize,
base_size: *mut usize,
capacity_off: *mut usize,
capacity_size: *mut usize,
buffer_off: *mut usize,
buffer_size: *mut usize) {
unsafe {
*size = mem::size_of::<nsFixedStringRepr>();
*align = mem::align_of::<nsFixedStringRepr>();
*base_off = offset_of!(nsFixedStringRepr, base);
*base_size = size_of_member!(nsFixedStringRepr, base);
*capacity_off = offset_of!(nsFixedStringRepr, capacity);
*capacity_size = size_of_member!(nsFixedStringRepr, capacity);
*buffer_off = offset_of!(nsFixedStringRepr, buffer);
*buffer_size = size_of_member!(nsFixedStringRepr, buffer);
}
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn Rust_Test_NsStringFlags(f_none: *mut u32,
f_terminated: *mut u32,
f_voided: *mut u32,
f_shared: *mut u32,
f_owned: *mut u32,
f_fixed: *mut u32,
f_literal: *mut u32,
f_class_fixed: *mut u32) {
unsafe {
*f_none = F_NONE;
*f_terminated = F_TERMINATED;
*f_voided = F_VOIDED;
*f_shared = F_SHARED;
*f_owned = F_OWNED;
*f_fixed = F_FIXED;
*f_literal = F_LITERAL;
*f_class_fixed = F_CLASS_FIXED;
}
}
}