aboutsummaryrefslogtreecommitdiffstats
path: root/components/style/gecko_string_cache
diff options
context:
space:
mode:
authorCameron McCormack <cam@mcc.id.au>2019-01-07 09:50:25 +0000
committerEmilio Cobos Álvarez <emilio@crisal.io>2019-01-11 00:50:46 +0100
commit03507801cfb7b90bcfaee5da901d406cb94ebdb1 (patch)
tree3386ee264ef1a507152e7b8e6fc3d99636014b29 /components/style/gecko_string_cache
parent63fd707bd342d614fa620415bb1062b3a40a2488 (diff)
downloadservo-03507801cfb7b90bcfaee5da901d406cb94ebdb1.tar.gz
servo-03507801cfb7b90bcfaee5da901d406cb94ebdb1.zip
style: Make GkAtoms opaque to avoid lld-link.exe errors.
Differential Revision: https://phabricator.services.mozilla.com/D15800
Diffstat (limited to 'components/style/gecko_string_cache')
-rw-r--r--components/style/gecko_string_cache/mod.rs29
1 files changed, 26 insertions, 3 deletions
diff --git a/components/style/gecko_string_cache/mod.rs b/components/style/gecko_string_cache/mod.rs
index d06091df80b..197eca1640c 100644
--- a/components/style/gecko_string_cache/mod.rs
+++ b/components/style/gecko_string_cache/mod.rs
@@ -15,7 +15,9 @@ use crate::gecko_bindings::bindings::Gecko_Atomize;
use crate::gecko_bindings::bindings::Gecko_Atomize16;
use crate::gecko_bindings::bindings::Gecko_ReleaseAtom;
use crate::gecko_bindings::structs::{nsAtom, nsDynamicAtom, nsStaticAtom};
+use crate::gecko_bindings::structs::root::mozilla::detail::GkAtoms_Atoms_AtomsCount;
use crate::gecko_bindings::structs::root::mozilla::detail::gGkAtoms;
+use crate::gecko_bindings::structs::root::mozilla::detail::kGkAtomsArrayOffset;
use nsstring::{nsAString, nsStr};
use precomputed_hash::PrecomputedHash;
use std::borrow::{Borrow, Cow};
@@ -57,11 +59,32 @@ pub struct Atom(usize);
/// where `'a` is the lifetime of something that holds a strong reference to that atom.
pub struct WeakAtom(nsAtom);
+/// The number of static atoms we have.
+const STATIC_ATOM_COUNT: usize = GkAtoms_Atoms_AtomsCount as usize;
+
+/// Returns the Gecko static atom array.
+///
+/// We have this rather than use rust-bindgen to generate
+/// mozilla::detail::gGkAtoms and then just reference gGkAtoms.mAtoms, so we
+/// avoid a problem with lld-link.exe on Windows.
+///
+/// https://bugzilla.mozilla.org/show_bug.cgi?id=1517685
+#[inline]
+fn static_atoms() -> &'static [nsStaticAtom; STATIC_ATOM_COUNT] {
+ unsafe {
+ let addr = &gGkAtoms as *const _ as usize + kGkAtomsArrayOffset as usize;
+ &*(addr as *const _)
+ }
+}
+
+/// Returns whether the specified address points to one of the nsStaticAtom
+/// objects in the Gecko static atom array.
#[inline]
fn valid_static_atom_addr(addr: usize) -> bool {
unsafe {
- let start = gGkAtoms.mAtoms.get_unchecked(0) as *const _;
- let end = gGkAtoms.mAtoms.get_unchecked(gGkAtoms.mAtoms.len()) as *const _;
+ let atoms = static_atoms();
+ let start = atoms.get_unchecked(0) as *const _;
+ let end = atoms.get_unchecked(STATIC_ATOM_COUNT) as *const _;
let in_range = addr >= start as usize && addr < end as usize;
let aligned = addr % mem::align_of::<nsStaticAtom>() == 0;
in_range && aligned
@@ -341,7 +364,7 @@ impl Atom {
/// checking in release builds.
#[inline]
pub unsafe fn from_index(index: u16) -> Self {
- let ptr = gGkAtoms.mAtoms.get_unchecked(index as usize) as *const _;
+ let ptr = static_atoms().get_unchecked(index as usize) as *const _;
let handle = make_static_handle(ptr);
let atom = Atom(handle);
debug_assert!(valid_static_atom_addr(ptr as usize));