Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bindings for calc() #12465

Merged
merged 6 commits into from Jul 20, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! This module contains conversion helpers between Servo and Gecko types
//! Ideally, it would be in geckolib itself, but coherence
//! forces us to keep the traits and implementations here

This comment has been minimized.

@heycam

heycam Jul 18, 2016

Member

Question: all uses of these two From impls are going to be in the geckolib crate, so why can't they live in ports/geckolib/values.rs?

This comment has been minimized.

@emilio

emilio Jul 18, 2016

Member

I think it is because you can only implement them either where CalcLengthOrPercentage is defined or where nsStyleCoord_CalcValue is defined, and doing it in gecko_bindings is impossible because is in the other way of the dependency chain.

Other solution would be to implement a custom trait as GeckoStyleCoordConvertible is. I'm fine with any of both options, either using the standard From and paying this price, or using a custom type :)

This comment has been minimized.

@bholley

bholley Jul 18, 2016

Contributor

I think I would prefer a custom trait if it means that we can keep this logic in geckolib.


use app_units::Au;
use gecko_bindings::structs::nsStyleCoord_CalcValue;
use values::computed::CalcLengthOrPercentage;

impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
let has_percentage = other.percentage.is_some();
nsStyleCoord_CalcValue {
mLength: other.length.map_or(0, |l| l.0),
mPercent: other.percentage.unwrap_or(0.0),
mHasPercent: has_percentage,
}
}
}

impl From<nsStyleCoord_CalcValue> for CalcLengthOrPercentage {
fn from(other: nsStyleCoord_CalcValue) -> CalcLengthOrPercentage {
let percentage = if other.mHasPercent {
Some(other.mPercent)
} else {
None
};
CalcLengthOrPercentage {
length: Some(Au(other.mLength)),
percentage: percentage,
}
}
}
@@ -81,6 +81,8 @@ pub mod dom;
pub mod element_state;
pub mod error_reporting;
pub mod font_face;
#[cfg(feature = "gecko")]
pub mod gecko_conversions;
pub mod keyframes;
pub mod logical_geometry;
pub mod matching;
@@ -123,6 +123,16 @@ unsafe impl Sync for nsStyleImageLayers {}
impl HeapSizeOf for nsStyleImageLayers { fn heap_size_of_children(&self) -> usize { 0 } }
use structs::nsStyleImageLayers_Layer as Layer;
use structs::nsStyleImageLayers_LayerType as LayerType;
use structs::nsStyleUnit;
unsafe impl Send for nsStyleUnit {}
unsafe impl Sync for nsStyleUnit {}
impl HeapSizeOf for nsStyleUnit { fn heap_size_of_children(&self) -> usize { 0 } }
use structs::nsStyleUnion;
unsafe impl Send for nsStyleUnion {}
unsafe impl Sync for nsStyleUnion {}
impl HeapSizeOf for nsStyleUnion { fn heap_size_of_children(&self) -> usize { 0 } }
use structs::nsStyleCoord_CalcValue as CalcValue;
use structs::nsStyleCoord_Calc as Calc;
use structs::SheetParsingMode;
use structs::nsMainThreadPtrHandle;
use structs::nsMainThreadPtrHolder;
@@ -255,6 +265,13 @@ extern "C" {
len: usize);
pub fn Gecko_InitializeImageLayer(layer: *mut Layer,
layer_type: LayerType);
pub fn Gecko_ResetStyleCoord(unit: *mut nsStyleUnit,
value: *mut nsStyleUnion);
pub fn Gecko_SetStyleCoordCalcValue(unit: *mut nsStyleUnit,
value: *mut nsStyleUnion,
calc: CalcValue);
pub fn Gecko_AddRefCalcArbitraryThread(aPtr: *mut Calc);
pub fn Gecko_ReleaseCalcArbitraryThread(aPtr: *mut Calc);
pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8, length: u32,
parsing_mode: SheetParsingMode,
base: *mut ThreadSafeURIHolder,
@@ -276,7 +293,7 @@ extern "C" {
pub fn Servo_StyleSheetHasRules(sheet: *mut RawServoStyleSheet) -> bool;
pub fn Servo_InitStyleSet() -> *mut RawServoStyleSet;
pub fn Servo_DropStyleSet(set: *mut RawServoStyleSet);
pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32,
pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u8,
cache: *mut nsHTMLCSSStyleSheet)
-> *mut ServoDeclarationBlock;
pub fn Servo_DropDeclarationBlock(declarations:
@@ -1537,15 +1537,30 @@ pub struct nsWritingIterator<CharT> {
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsStringComparator;
pub struct nsStringComparator {
pub _vftable: *const _vftable_nsStringComparator,
}
#[repr(C)]
pub struct _vftable_nsStringComparator {
pub _bindgen_empty_ctype_warning_fix: u64,
}
impl ::std::clone::Clone for nsStringComparator {
fn clone(&self) -> Self { *self }
}
#[test]
fn bindgen_test_layout_nsStringComparator() {
assert_eq!(::std::mem::size_of::<nsStringComparator>() , 8usize);
assert_eq!(::std::mem::align_of::<nsStringComparator>() , 8usize);
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsDefaultStringComparator {
pub _base: nsStringComparator,
}
#[repr(C)]
pub struct _vftable_nsDefaultStringComparator {
pub _base: _vftable_nsStringComparator,
}
impl ::std::clone::Clone for nsDefaultStringComparator {
fn clone(&self) -> Self { *self }
}
@@ -1575,15 +1590,30 @@ fn bindgen_test_layout_nsAString_internal() {
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsCStringComparator;
pub struct nsCStringComparator {
pub _vftable: *const _vftable_nsCStringComparator,
}
#[repr(C)]
pub struct _vftable_nsCStringComparator {
pub _bindgen_empty_ctype_warning_fix: u64,
}
impl ::std::clone::Clone for nsCStringComparator {
fn clone(&self) -> Self { *self }
}
#[test]
fn bindgen_test_layout_nsCStringComparator() {
assert_eq!(::std::mem::size_of::<nsCStringComparator>() , 8usize);
assert_eq!(::std::mem::align_of::<nsCStringComparator>() , 8usize);
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsDefaultCStringComparator {
pub _base: nsCStringComparator,
}
#[repr(C)]
pub struct _vftable_nsDefaultCStringComparator {
pub _base: _vftable_nsCStringComparator,
}
impl ::std::clone::Clone for nsDefaultCStringComparator {
fn clone(&self) -> Self { *self }
}
@@ -1620,6 +1650,10 @@ fn bindgen_test_layout_nsACString_internal() {
pub struct nsCaseInsensitiveCStringComparator {
pub _base: nsCStringComparator,
}
#[repr(C)]
pub struct _vftable_nsCaseInsensitiveCStringComparator {
pub _base: _vftable_nsCStringComparator,
}
impl ::std::clone::Clone for nsCaseInsensitiveCStringComparator {
fn clone(&self) -> Self { *self }
}
@@ -2211,10 +2245,21 @@ pub struct nsTArray<T> {
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsCOMPtr_helper;
pub struct nsCOMPtr_helper {
pub _vftable: *const _vftable_nsCOMPtr_helper,
}
#[repr(C)]
pub struct _vftable_nsCOMPtr_helper {
pub _bindgen_empty_ctype_warning_fix: u64,
}
impl ::std::clone::Clone for nsCOMPtr_helper {
fn clone(&self) -> Self { *self }
}
#[test]
fn bindgen_test_layout_nsCOMPtr_helper() {
assert_eq!(::std::mem::size_of::<nsCOMPtr_helper>() , 8usize);
assert_eq!(::std::mem::align_of::<nsCOMPtr_helper>() , 8usize);
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsQueryInterface {
@@ -4840,12 +4885,11 @@ fn bindgen_test_layout_nsStyleCoord_CalcValue() {
#[derive(Debug)]
pub struct nsStyleCoord_Calc {
pub _base: nsStyleCoord_CalcValue,
pub mRefCnt: nsAutoRefCnt,
pub _mOwningThread: nsAutoOwningThread,
pub mRefCnt: ThreadSafeAutoRefCnt,
}
#[test]
fn bindgen_test_layout_nsStyleCoord_Calc() {
assert_eq!(::std::mem::size_of::<nsStyleCoord_Calc>() , 32usize);
assert_eq!(::std::mem::size_of::<nsStyleCoord_Calc>() , 24usize);
assert_eq!(::std::mem::align_of::<nsStyleCoord_Calc>() , 8usize);
}
#[repr(u32)]
@@ -1537,15 +1537,30 @@ pub struct nsWritingIterator<CharT> {
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsStringComparator;
pub struct nsStringComparator {
pub _vftable: *const _vftable_nsStringComparator,
}
#[repr(C)]
pub struct _vftable_nsStringComparator {
pub _bindgen_empty_ctype_warning_fix: u64,
}
impl ::std::clone::Clone for nsStringComparator {
fn clone(&self) -> Self { *self }
}
#[test]
fn bindgen_test_layout_nsStringComparator() {
assert_eq!(::std::mem::size_of::<nsStringComparator>() , 8usize);
assert_eq!(::std::mem::align_of::<nsStringComparator>() , 8usize);
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsDefaultStringComparator {
pub _base: nsStringComparator,
}
#[repr(C)]
pub struct _vftable_nsDefaultStringComparator {
pub _base: _vftable_nsStringComparator,
}
impl ::std::clone::Clone for nsDefaultStringComparator {
fn clone(&self) -> Self { *self }
}
@@ -1575,15 +1590,30 @@ fn bindgen_test_layout_nsAString_internal() {
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsCStringComparator;
pub struct nsCStringComparator {
pub _vftable: *const _vftable_nsCStringComparator,
}
#[repr(C)]
pub struct _vftable_nsCStringComparator {
pub _bindgen_empty_ctype_warning_fix: u64,
}
impl ::std::clone::Clone for nsCStringComparator {
fn clone(&self) -> Self { *self }
}
#[test]
fn bindgen_test_layout_nsCStringComparator() {
assert_eq!(::std::mem::size_of::<nsCStringComparator>() , 8usize);
assert_eq!(::std::mem::align_of::<nsCStringComparator>() , 8usize);
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsDefaultCStringComparator {
pub _base: nsCStringComparator,
}
#[repr(C)]
pub struct _vftable_nsDefaultCStringComparator {
pub _base: _vftable_nsCStringComparator,
}
impl ::std::clone::Clone for nsDefaultCStringComparator {
fn clone(&self) -> Self { *self }
}
@@ -1620,6 +1650,10 @@ fn bindgen_test_layout_nsACString_internal() {
pub struct nsCaseInsensitiveCStringComparator {
pub _base: nsCStringComparator,
}
#[repr(C)]
pub struct _vftable_nsCaseInsensitiveCStringComparator {
pub _base: _vftable_nsCStringComparator,
}
impl ::std::clone::Clone for nsCaseInsensitiveCStringComparator {
fn clone(&self) -> Self { *self }
}
@@ -2211,10 +2245,21 @@ pub struct nsTArray<T> {
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsCOMPtr_helper;
pub struct nsCOMPtr_helper {
pub _vftable: *const _vftable_nsCOMPtr_helper,
}
#[repr(C)]
pub struct _vftable_nsCOMPtr_helper {
pub _bindgen_empty_ctype_warning_fix: u64,
}
impl ::std::clone::Clone for nsCOMPtr_helper {
fn clone(&self) -> Self { *self }
}
#[test]
fn bindgen_test_layout_nsCOMPtr_helper() {
assert_eq!(::std::mem::size_of::<nsCOMPtr_helper>() , 8usize);
assert_eq!(::std::mem::align_of::<nsCOMPtr_helper>() , 8usize);
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsQueryInterface {
@@ -4819,12 +4864,11 @@ fn bindgen_test_layout_nsStyleCoord_CalcValue() {
#[derive(Debug)]
pub struct nsStyleCoord_Calc {
pub _base: nsStyleCoord_CalcValue,
pub mRefCnt: nsAutoRefCnt,
pub _mOwningThread: nsAutoOwningThread,
pub mRefCnt: ThreadSafeAutoRefCnt,
}
#[test]
fn bindgen_test_layout_nsStyleCoord_Calc() {
assert_eq!(::std::mem::size_of::<nsStyleCoord_Calc>() , 32usize);
assert_eq!(::std::mem::size_of::<nsStyleCoord_Calc>() , 24usize);
assert_eq!(::std::mem::align_of::<nsStyleCoord_Calc>() , 8usize);
}
#[repr(u32)]
@@ -3,4 +3,5 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

mod ns_style_auto_array;
mod ns_style_coord;
mod ns_t_array;
@@ -0,0 +1,54 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use bindings::{Gecko_ResetStyleCoord, Gecko_SetStyleCoordCalcValue, Gecko_AddRefCalcArbitraryThread};
use std::mem::transmute;
use structs::{nsStyleCoord_CalcValue, nsStyleCoord_Calc, nsStyleUnit, nsStyleUnion, nsStyleCoord};

// Functions here are unsafe because it is possible to use the wrong nsStyleUnit
// FIXME we should be pairing up nsStyleUnion and nsStyleUnit somehow
// nsStyleCoord is one way to do it, but there are other structs using pairs
// of union and unit too

This comment has been minimized.

@bholley

bholley Jul 18, 2016

Contributor

Yeah, the main reason for the separation is that in Gecko, we sometimes have tuples of these things, and the unions and units are stored in separate arrays. Maybe we could have some sort of temporary struct that we synthesize (unsafely) and pass around (safely)? Would that impose a performance cost?

This comment has been minimized.

@Manishearth

Manishearth Jul 19, 2016

Author Member

Yes, this is the plan. Shouldn't have a perf cost (because we pass them in as arguments anyway); and I bet llvm will optimize it away even if it did.

A slight issue with this abstraction is that it's still technically unsafe because folks can always modify the values in nsStyleCoord directly. I could try to make those private via bindgen stuff, though.

This comment has been minimized.

@bholley

bholley Jul 19, 2016

Contributor

I was imagining that we'd create a some temporary tuple struct that isn't actually nsStyleCoord, but if we can make that nsStyleCoord itself with similar properties, that's even better.


impl nsStyleUnion {
/// Clean up any resources used by an nsStyleUnit
/// Currently, this only happens if the nsStyleUnit
/// is a Calc
pub unsafe fn reset(&mut self, unit: &mut nsStyleUnit) {
if *unit == nsStyleUnit::eStyleUnit_Calc {
Gecko_ResetStyleCoord(unit, self);
}
}

/// Set internal value to a calc() value
/// reset() the union before calling this
pub unsafe fn set_calc_value(&mut self, unit: &mut nsStyleUnit, v: nsStyleCoord_CalcValue) {
// Calc should have been cleaned up
debug_assert!(*unit != nsStyleUnit::eStyleUnit_Calc);
Gecko_SetStyleCoordCalcValue(unit, self, v);
}

pub unsafe fn get_calc(&self) -> nsStyleCoord_CalcValue {
(*self.as_calc())._base
}

pub unsafe fn addref_if_calc(&mut self, unit: &nsStyleUnit) {
if *unit == nsStyleUnit::eStyleUnit_Calc {
Gecko_AddRefCalcArbitraryThread(self.as_calc_mut());
}
}

unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc {
transmute(*self.mPointer.as_mut() as *mut nsStyleCoord_Calc)
}
unsafe fn as_calc(&self) -> &nsStyleCoord_Calc {
transmute(*self.mPointer.as_ref() as *const nsStyleCoord_Calc)
}
}

impl nsStyleCoord {
pub unsafe fn addref_if_calc(&mut self) {
self.mValue.addref_if_calc(&self.mUnit);
}
}
@@ -120,6 +120,8 @@
"nsStyleEffects", "nsStyleImage", "nsStyleGradient",
"nsStyleCoord", "nsStyleGradientStop", "nsStyleImageLayers",
"nsStyleImageLayers::Layer", "nsStyleImageLayers::LayerType",
"nsStyleUnit", "nsStyleUnion", "nsStyleCoord::CalcValue",
"nsStyleCoord::Calc",

"SheetParsingMode", "nsMainThreadPtrHandle",
"nsMainThreadPtrHolder", "nscolor", "nsFont", "FontFamilyList",
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.