зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
dace0b2e39
Коммит
0f0181c55e
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче