mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Make LonghandId just be the discriminants of PropertyDeclaration 🐉🐲
This relies on the fact that `#[repr(u16)]` on enums ensure the discriminant will be the very first field of the enum value. This has always been the case, but it has been formally defined only since https://github.com/rust-lang/rfcs/pull/2195. https://bugzilla.mozilla.org/show_bug.cgi?id=1428285
This commit is contained in:
parent
1ec5164900
commit
42ea822edf
1 changed files with 45 additions and 29 deletions
|
@ -203,6 +203,8 @@ pub mod animated_properties {
|
||||||
}
|
}
|
||||||
|
|
||||||
<%
|
<%
|
||||||
|
from itertools import groupby
|
||||||
|
|
||||||
variants = []
|
variants = []
|
||||||
for property in data.longhands:
|
for property in data.longhands:
|
||||||
if property.predefined_type and not property.is_vector and not property.is_gecko_size_type_hack:
|
if property.predefined_type and not property.is_vector and not property.is_gecko_size_type_hack:
|
||||||
|
@ -216,7 +218,33 @@ pub mod animated_properties {
|
||||||
"type": ty,
|
"type": ty,
|
||||||
"doc": "`" + property.name + "`",
|
"doc": "`" + property.name + "`",
|
||||||
})
|
})
|
||||||
variants += [
|
|
||||||
|
groups = {}
|
||||||
|
keyfunc = lambda x: x["type"]
|
||||||
|
sortkeys = {}
|
||||||
|
for ty, group in groupby(sorted(variants, key=keyfunc), keyfunc):
|
||||||
|
group = [v["name"] for v in group]
|
||||||
|
groups[ty] = group
|
||||||
|
for v in group:
|
||||||
|
if len(group) == 1:
|
||||||
|
sortkeys[v] = (1, v, "")
|
||||||
|
else:
|
||||||
|
sortkeys[v] = (len(group), ty, v)
|
||||||
|
variants.sort(key=lambda x: sortkeys[x["name"]])
|
||||||
|
|
||||||
|
# It is extremely important to sort the `data.longhands` array here so
|
||||||
|
# that it is in the same order as `variants`, for `LonghandId` and
|
||||||
|
# `PropertyDeclarationId` to coincide.
|
||||||
|
data.longhands.sort(key=lambda x: sortkeys[x.camel_case])
|
||||||
|
%>
|
||||||
|
|
||||||
|
// WARNING: It is *really* important for the variants of `LonghandId`
|
||||||
|
// and `PropertyDeclaration` to be defined in the exact same order,
|
||||||
|
// with the exception of `CSSWideKeyword`, `WithVariables` and `Custom`,
|
||||||
|
// which don't exist in `LonghandId`.
|
||||||
|
|
||||||
|
<%
|
||||||
|
extra = [
|
||||||
{
|
{
|
||||||
"name": "CSSWideKeyword",
|
"name": "CSSWideKeyword",
|
||||||
"type": "WideKeywordDeclaration",
|
"type": "WideKeywordDeclaration",
|
||||||
|
@ -233,6 +261,9 @@ pub mod animated_properties {
|
||||||
"doc": "A custom property declaration.",
|
"doc": "A custom property declaration.",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
for v in extra:
|
||||||
|
variants.append(v)
|
||||||
|
groups[v["type"]] = [v["name"]]
|
||||||
%>
|
%>
|
||||||
|
|
||||||
/// Servo's representation for a property declaration.
|
/// Servo's representation for a property declaration.
|
||||||
|
@ -246,15 +277,6 @@ pub enum PropertyDeclaration {
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
|
||||||
<%
|
|
||||||
from itertools import groupby
|
|
||||||
|
|
||||||
groups = {}
|
|
||||||
keyfunc = lambda x: x["type"]
|
|
||||||
for ty, group in groupby(sorted(variants, key=keyfunc), keyfunc):
|
|
||||||
groups[ty] = list(group)
|
|
||||||
%>
|
|
||||||
|
|
||||||
impl Clone for PropertyDeclaration {
|
impl Clone for PropertyDeclaration {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -269,11 +291,11 @@ impl Clone for PropertyDeclaration {
|
||||||
match *self {
|
match *self {
|
||||||
% for ty, variants in groups.iteritems():
|
% for ty, variants in groups.iteritems():
|
||||||
% if len(variants) == 1:
|
% if len(variants) == 1:
|
||||||
${variants[0]["name"]}(ref value) => {
|
${variants[0]}(ref value) => {
|
||||||
${variants[0]["name"]}(value.clone())
|
${variants[0]}(value.clone())
|
||||||
}
|
}
|
||||||
% else:
|
% else:
|
||||||
${" | ".join("{}(ref value)".format(v["name"]) for v in variants)} => {
|
${" | ".join("{}(ref value)".format(v) for v in variants)} => {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut out = ManuallyDrop::new(mem::uninitialized());
|
let mut out = ManuallyDrop::new(mem::uninitialized());
|
||||||
ptr::write(
|
ptr::write(
|
||||||
|
@ -376,7 +398,7 @@ impl<'a> Iterator for LonghandIdSetIterator<'a> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let id: LonghandId = unsafe { mem::transmute(self.cur as ${"u16" if product == "gecko" else "u8"}) };
|
let id: LonghandId = unsafe { mem::transmute(self.cur as u16) };
|
||||||
self.cur += 1;
|
self.cur += 1;
|
||||||
|
|
||||||
if self.longhands.contains(id) {
|
if self.longhands.contains(id) {
|
||||||
|
@ -583,6 +605,7 @@ bitflags! {
|
||||||
|
|
||||||
/// An identifier for a given longhand property.
|
/// An identifier for a given longhand property.
|
||||||
#[derive(Clone, Copy, Eq, Hash, MallocSizeOf, PartialEq)]
|
#[derive(Clone, Copy, Eq, Hash, MallocSizeOf, PartialEq)]
|
||||||
|
#[repr(u16)]
|
||||||
pub enum LonghandId {
|
pub enum LonghandId {
|
||||||
% for i, property in enumerate(data.longhands):
|
% for i, property in enumerate(data.longhands):
|
||||||
/// ${property.name}
|
/// ${property.name}
|
||||||
|
@ -1623,23 +1646,16 @@ impl PropertyDeclaration {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
let longhand_id = match *self {
|
// This is just fine because PropertyDeclarationId and LonghandId
|
||||||
|
// have corresponding discriminants.
|
||||||
|
let id = unsafe { *(self as *const _ as *const LonghandId) };
|
||||||
|
debug_assert_eq!(id, match *self {
|
||||||
% for property in data.longhands:
|
% for property in data.longhands:
|
||||||
PropertyDeclaration::${property.camel_case}(..) => {
|
PropertyDeclaration::${property.camel_case}(..) => LonghandId::${property.camel_case},
|
||||||
LonghandId::${property.camel_case}
|
|
||||||
}
|
|
||||||
% endfor
|
% endfor
|
||||||
PropertyDeclaration::CSSWideKeyword(..) |
|
_ => id,
|
||||||
PropertyDeclaration::WithVariables(..) |
|
});
|
||||||
PropertyDeclaration::Custom(..) => {
|
PropertyDeclarationId::Longhand(id)
|
||||||
debug_assert!(false, "unreachable");
|
|
||||||
// This value is never used, but having an expression of the same "shape"
|
|
||||||
// as for other variants helps the optimizer compile this `match` expression
|
|
||||||
// to a lookup table.
|
|
||||||
LonghandId::BackgroundColor
|
|
||||||
}
|
|
||||||
};
|
|
||||||
PropertyDeclarationId::Longhand(longhand_id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_variables_from_shorthand(&self, shorthand: ShorthandId) -> Option< &str> {
|
fn with_variables_from_shorthand(&self, shorthand: ShorthandId) -> Option< &str> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue