style: Use helper function to set length and copy into nsTArrays of PODs from Rust.

Differential Revision: https://phabricator.services.mozilla.com/D8058
This commit is contained in:
Cameron McCormack 2018-10-09 08:49:51 +00:00 committed by Emilio Cobos Álvarez
parent d960db340c
commit 4e174ace3b
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
3 changed files with 40 additions and 55 deletions

View file

@ -82,9 +82,9 @@ impl<T> nsTArray<T> {
/// Resize and set the length of the array to `len`.
///
/// unsafe because the array may contain uninitialized members.
/// unsafe because this may leave the array with uninitialized elements.
///
/// This will not call constructors, if you need that, either manually add
/// This will not call constructors. If you need that, either manually add
/// bindings or run the typed `EnsureCapacity` call on the gecko side.
pub unsafe fn set_len(&mut self, len: u32) {
// this can leak
@ -96,6 +96,8 @@ impl<T> nsTArray<T> {
/// Resizes an array containing only POD elements
///
/// unsafe because this may leave the array with uninitialized elements.
///
/// This will not leak since it only works on POD types (and thus doesn't assert)
pub unsafe fn set_len_pod(&mut self, len: u32)
where
@ -105,4 +107,17 @@ impl<T> nsTArray<T> {
let header = self.header_mut();
header.mLength = len;
}
/// Collects the given iterator into this array.
///
/// Not unsafe because we won't leave uninitialized elements in the array.
pub fn assign_from_iter_pod<I>(&mut self, iter: I)
where
T: Copy,
I: ExactSizeIterator + Iterator<Item = T>,
{
debug_assert!(iter.len() <= 0xFFFFFFFF);
unsafe { self.set_len_pod(iter.len() as u32); }
self.iter_mut().zip(iter).for_each(|(r, v)| *r = v);
}
}

View file

@ -1373,35 +1373,22 @@ impl Clone for ${style_struct.gecko_struct_name} {
}
</%def>
<%def name="impl_font_settings(ident, tag_type, value_type, gecko_value_type)">
<%def name="impl_font_settings(ident, gecko_type, tag_type, value_type, gecko_value_type)">
<%
gecko_ffi_name = to_camel_case_lower(ident)
%>
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
let current_settings = &mut self.gecko.mFont.${gecko_ffi_name};
current_settings.clear_pod();
unsafe { current_settings.set_len_pod(v.0.len() as u32) };
for (current, other) in current_settings.iter_mut().zip(v.0.iter()) {
current.mTag = other.tag.0;
current.mValue = other.value as ${gecko_value_type};
}
let iter = v.0.iter().map(|other| structs::${gecko_type} {
mTag: other.tag.0,
mValue: other.value as ${gecko_value_type},
});
self.gecko.mFont.${gecko_ffi_name}.assign_from_iter_pod(iter);
}
pub fn copy_${ident}_from(&mut self, other: &Self) {
let current_settings = &mut self.gecko.mFont.${gecko_ffi_name};
let other_settings = &other.gecko.mFont.${gecko_ffi_name};
let settings_length = other_settings.len() as u32;
current_settings.clear_pod();
unsafe { current_settings.set_len_pod(settings_length) };
for (current, other) in current_settings.iter_mut().zip(other_settings.iter()) {
current.mTag = other.mTag;
current.mValue = other.mValue;
}
let iter = other.gecko.mFont.${gecko_ffi_name}.iter().map(|s| *s);
self.gecko.mFont.${gecko_ffi_name}.assign_from_iter_pod(iter);
}
pub fn reset_${ident}(&mut self, other: &Self) {
@ -2274,8 +2261,8 @@ fn static_assert() {
// Negative numbers are invalid at parse time, but <integer> is still an
// i32.
<% impl_font_settings("font_feature_settings", "FeatureTagValue", "i32", "u32") %>
<% impl_font_settings("font_variation_settings", "VariationValue", "f32", "f32") %>
<% impl_font_settings("font_feature_settings", "gfxFontFeature", "FeatureTagValue", "i32", "u32") %>
<% impl_font_settings("font_variation_settings", "gfxFontVariation", "VariationValue", "f32", "f32") %>
pub fn fixup_none_generic(&mut self, device: &Device) {
self.gecko.mFont.systemFont = false;
@ -3213,28 +3200,16 @@ fn static_assert() {
where I: IntoIterator<Item = longhands::scroll_snap_coordinate::computed_value::single_value::T>,
I::IntoIter: ExactSizeIterator
{
let v = v.into_iter();
unsafe { self.gecko.mScrollSnapCoordinate.set_len_pod(v.len() as u32); }
for (gecko, servo) in self.gecko.mScrollSnapCoordinate
.iter_mut()
.zip(v) {
gecko.mXPosition = servo.horizontal.into();
gecko.mYPosition = servo.vertical.into();
}
let iter = v.into_iter().map(|c| structs::mozilla::Position {
mXPosition: c.horizontal.into(),
mYPosition: c.vertical.into(),
});
self.gecko.mScrollSnapCoordinate.assign_from_iter_pod(iter);
}
pub fn copy_scroll_snap_coordinate_from(&mut self, other: &Self) {
unsafe {
self.gecko.mScrollSnapCoordinate
.set_len_pod(other.gecko.mScrollSnapCoordinate.len() as u32);
}
for (this, that) in self.gecko.mScrollSnapCoordinate
.iter_mut()
.zip(other.gecko.mScrollSnapCoordinate.iter()) {
*this = *that;
}
let iter = other.gecko.mScrollSnapCoordinate.iter().map(|c| *c);
self.gecko.mScrollSnapCoordinate.assign_from_iter_pod(iter);
}
pub fn reset_scroll_snap_coordinate(&mut self, other: &Self) {
@ -4995,12 +4970,12 @@ fn set_style_svg_path(
Gecko_NewStyleSVGPath(shape_source);
&mut shape_source.__bindgen_anon_1.mSVGPath.as_mut().mPtr.as_mut().unwrap()
};
unsafe { gecko_path.mPath.set_len(servo_path.commands().len() as u32) };
debug_assert_eq!(gecko_path.mPath.len(), servo_path.commands().len());
for (servo, gecko) in servo_path.commands().iter().zip(gecko_path.mPath.iter_mut()) {
let iter = servo_path.commands().iter().map(|command| {
// unsafe: cbindgen ensures the representation is the same.
*gecko = unsafe { transmute(*servo) };
}
unsafe { transmute(*command) }
});
gecko_path.mPath.assign_from_iter_pod(iter);
// Setup fill-rule.
// unsafe: cbindgen ensures the representation is the same.

View file

@ -179,12 +179,7 @@ impl Parse for VectorValues {
#[cfg(feature = "gecko")]
impl ToGeckoFontFeatureValues for VectorValues {
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
unsafe {
array.set_len_pod(self.0.len() as u32);
}
for (dest, value) in array.iter_mut().zip(self.0.iter()) {
*dest = *value;
}
array.assign_from_iter_pod(self.0.iter().map(|v| *v));
}
}