diff options
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 5 | ||||
-rw-r--r-- | components/script/dom/bindings/conversions.rs | 42 | ||||
-rw-r--r-- | components/script/dom/bindings/mod.rs | 1 | ||||
-rw-r--r-- | components/script/dom/bindings/num.rs | 43 | ||||
-rw-r--r-- | components/script/dom/testbinding.rs | 53 |
5 files changed, 114 insertions, 30 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 934f3a7af82..16544054f86 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -81,9 +81,9 @@ builtinNames = { IDLType.Tags.uint32: 'u32', IDLType.Tags.uint64: 'u64', IDLType.Tags.unrestricted_float: 'f32', - IDLType.Tags.float: 'f32', + IDLType.Tags.float: 'Finite<f32>', IDLType.Tags.unrestricted_double: 'f64', - IDLType.Tags.double: 'f64' + IDLType.Tags.double: 'Finite<f64>' } numericTags = [ @@ -4688,6 +4688,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::proxyhandler', 'dom::bindings::proxyhandler::{fill_property_descriptor, get_expando_object}', 'dom::bindings::proxyhandler::{get_property_descriptor}', + 'dom::bindings::num::Finite', 'dom::bindings::str::ByteString', 'dom::bindings::str::USVString', 'libc', diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 0087e2135e0..b8cb3ccb84d 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -17,9 +17,9 @@ //! | long long | `i64` | //! | unsigned long long | `u64` | //! | unrestricted float | `f32` | -//! | float | `f32` | +//! | float | `Finite<f32>` | //! | unrestricted double | `f64` | -//! | double | `f64` | +//! | double | `Finite<f64>` | //! | DOMString | `DOMString` | //! | USVString | `USVString` | //! | ByteString | `ByteString` | @@ -34,6 +34,7 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::js::{JSRef, Root, Unrooted}; +use dom::bindings::num::Finite; use dom::bindings::str::{ByteString, USVString}; use dom::bindings::utils::{Reflectable, Reflector, DOMClass}; use util::str::DOMString; @@ -256,6 +257,24 @@ impl FromJSValConvertible for f32 { } } +impl ToJSValConvertible for Finite<f32> { + fn to_jsval(&self, cx: *mut JSContext) -> JSVal { + let value = self.clone().unwrap(); + value.to_jsval(cx) + } +} + +impl FromJSValConvertible for Finite<f32> { + type Config = (); + fn from_jsval(cx: *mut JSContext, val: JSVal, option: ()) -> Result<Finite<f32>, ()> { + let result = FromJSValConvertible::from_jsval(cx, val, option); + let result = result.and_then(|v| { + Finite::<f32>::new(v).ok_or(()) + }); + result + } +} + impl ToJSValConvertible for f64 { fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { unsafe { @@ -271,6 +290,25 @@ impl FromJSValConvertible for f64 { } } +impl ToJSValConvertible for Finite<f64> { + #[inline] + fn to_jsval(&self, cx: *mut JSContext) -> JSVal { + let value = self.clone().unwrap(); + value.to_jsval(cx) + } +} + +impl FromJSValConvertible for Finite<f64> { + type Config = (); + fn from_jsval(cx: *mut JSContext, val: JSVal, option: ()) -> Result<Finite<f64>, ()> { + let result = FromJSValConvertible::from_jsval(cx, val, option); + let result = result.and_then(|v| { + Finite::<f64>::new(v).ok_or(()) + }); + result + } +} + impl ToJSValConvertible for str { fn to_jsval(&self, cx: *mut JSContext) -> JSVal { unsafe { diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index 2775f513525..f2cfb642131 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -37,6 +37,7 @@ pub mod callback; pub mod error; pub mod conversions; pub mod proxyhandler; +pub mod num; pub mod str; pub mod structuredclone; pub mod trace; diff --git a/components/script/dom/bindings/num.rs b/components/script/dom/bindings/num.rs new file mode 100644 index 00000000000..353a395784b --- /dev/null +++ b/components/script/dom/bindings/num.rs @@ -0,0 +1,43 @@ +/* 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/. */ + +//! The `Finite<T>` struct. + +use core::nonzero::Zeroable; +use std::num::Float; +use std::ops::Deref; + +/// Encapsulates the IDL restricted float type. +#[derive(Clone,Eq,PartialEq)] +#[jstraceable] +pub struct Finite<T: Float>(T); + +unsafe impl<T: Float> Zeroable for Finite<T> {} + +impl<T: Float> Finite<T> { + /// Create a new `Finite<T: Float>` safely. + pub fn new(value: T) -> Option<Finite<T>> { + if value.is_finite() { + Some(Finite(value)) + } else { + None + } + } + + /// Create a new `Finite<T: Float>`. + #[inline] + pub fn wrap(value: T) -> Finite<T> { + assert!(value.is_finite(), "Finite<T> doesn't encapsulate unrestricted value."); + Finite(value) + } +} + +impl<T: Float> Deref for Finite<T> { + type Target = T; + + fn deref(&self) -> &T { + let &Finite(ref value) = self; + value + } +} diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index a5c448726a6..2b42f26f294 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -14,6 +14,7 @@ use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong::eLong; use dom::bindings::global::GlobalField; use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::num::Finite; use dom::bindings::str::{ByteString, USVString}; use dom::bindings::utils::{Reflector, Reflectable}; use dom::blob::Blob; @@ -51,12 +52,12 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn SetUnsignedLongLongAttribute(self, _: u64) {} fn UnrestrictedFloatAttribute(self) -> f32 { 0. } fn SetUnrestrictedFloatAttribute(self, _: f32) {} - fn FloatAttribute(self) -> f32 { 0. } - fn SetFloatAttribute(self, _: f32) {} + fn FloatAttribute(self) -> Finite<f32> { Finite::wrap(0.) } + fn SetFloatAttribute(self, _: Finite<f32>) {} fn UnrestrictedDoubleAttribute(self) -> f64 { 0. } fn SetUnrestrictedDoubleAttribute(self, _: f64) {} - fn DoubleAttribute(self) -> f64 { 0. } - fn SetDoubleAttribute(self, _: f64) {} + fn DoubleAttribute(self) -> Finite<f64> { Finite::wrap(0.) } + fn SetDoubleAttribute(self, _: Finite<f64>) {} fn StringAttribute(self) -> DOMString { "".to_owned() } fn SetStringAttribute(self, _: DOMString) {} fn UsvstringAttribute(self) -> USVString { USVString("".to_owned()) } @@ -98,12 +99,12 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn SetUnsignedLongLongAttributeNullable(self, _: Option<u64>) {} fn GetUnrestrictedFloatAttributeNullable(self) -> Option<f32> { Some(0.) } fn SetUnrestrictedFloatAttributeNullable(self, _: Option<f32>) {} - fn GetFloatAttributeNullable(self) -> Option<f32> { Some(0.) } - fn SetFloatAttributeNullable(self, _: Option<f32>) {} + fn GetFloatAttributeNullable(self) -> Option<Finite<f32>> { Some(Finite::wrap(0.)) } + fn SetFloatAttributeNullable(self, _: Option<Finite<f32>>) {} fn GetUnrestrictedDoubleAttributeNullable(self) -> Option<f64> { Some(0.) } fn SetUnrestrictedDoubleAttributeNullable(self, _: Option<f64>) {} - fn GetDoubleAttributeNullable(self) -> Option<f64> { Some(0.) } - fn SetDoubleAttributeNullable(self, _: Option<f64>) {} + fn GetDoubleAttributeNullable(self) -> Option<Finite<f64>> { Some(Finite::wrap(0.)) } + fn SetDoubleAttributeNullable(self, _: Option<Finite<f64>>) {} fn GetByteStringAttributeNullable(self) -> Option<ByteString> { Some(ByteString::new(vec!())) } fn SetByteStringAttributeNullable(self, _: Option<ByteString>) {} fn GetStringAttributeNullable(self) -> Option<DOMString> { Some("".to_owned()) } @@ -134,9 +135,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn ReceiveLongLong(self) -> i64 { 0 } fn ReceiveUnsignedLongLong(self) -> u64 { 0 } fn ReceiveUnrestrictedFloat(self) -> f32 { 0. } - fn ReceiveFloat(self) -> f32 { 0. } + fn ReceiveFloat(self) -> Finite<f32> { Finite::wrap(0.) } fn ReceiveUnrestrictedDouble(self) -> f64 { 0. } - fn ReceiveDouble(self) -> f64 { 0. } + fn ReceiveDouble(self) -> Finite<f64> { Finite::wrap(0.) } fn ReceiveString(self) -> DOMString { "".to_owned() } fn ReceiveUsvstring(self) -> USVString { USVString("".to_owned()) } fn ReceiveByteString(self) -> ByteString { ByteString::new(vec!()) } @@ -159,9 +160,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn ReceiveNullableLongLong(self) -> Option<i64> { Some(0) } fn ReceiveNullableUnsignedLongLong(self) -> Option<u64> { Some(0) } fn ReceiveNullableUnrestrictedFloat(self) -> Option<f32> { Some(0.) } - fn ReceiveNullableFloat(self) -> Option<f32> { Some(0.) } + fn ReceiveNullableFloat(self) -> Option<Finite<f32>> { Some(Finite::wrap(0.)) } fn ReceiveNullableUnrestrictedDouble(self) -> Option<f64> { Some(0.) } - fn ReceiveNullableDouble(self) -> Option<f64> { Some(0.) } + fn ReceiveNullableDouble(self) -> Option<Finite<f64>> { Some(Finite::wrap(0.)) } fn ReceiveNullableString(self) -> Option<DOMString> { Some("".to_owned()) } fn ReceiveNullableUsvstring(self) -> Option<USVString> { Some(USVString("".to_owned())) } fn ReceiveNullableByteString(self) -> Option<ByteString> { Some(ByteString::new(vec!())) } @@ -183,9 +184,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassLongLong(self, _: i64) {} fn PassUnsignedLongLong(self, _: u64) {} fn PassUnrestrictedFloat(self, _: f32) {} - fn PassFloat(self, _: f32) {} + fn PassFloat(self, _: Finite<f32>) {} fn PassUnrestrictedDouble(self, _: f64) {} - fn PassDouble(self, _: f64) {} + fn PassDouble(self, _: Finite<f64>) {} fn PassString(self, _: DOMString) {} fn PassUsvstring(self, _: USVString) {} fn PassByteString(self, _: ByteString) {} @@ -208,9 +209,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassNullableLongLong(self, _: Option<i64>) {} fn PassNullableUnsignedLongLong(self, _: Option<u64>) {} fn PassNullableUnrestrictedFloat(self, _: Option<f32>) {} - fn PassNullableFloat(self, _: Option<f32>) {} + fn PassNullableFloat(self, _: Option<Finite<f32>>) {} fn PassNullableUnrestrictedDouble(self, _: Option<f64>) {} - fn PassNullableDouble(self, _: Option<f64>) {} + fn PassNullableDouble(self, _: Option<Finite<f64>>) {} fn PassNullableString(self, _: Option<DOMString>) {} fn PassNullableUsvstring(self, _: Option<USVString>) {} fn PassNullableByteString(self, _: Option<ByteString>) {} @@ -231,9 +232,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassOptionalLongLong(self, _: Option<i64>) {} fn PassOptionalUnsignedLongLong(self, _: Option<u64>) {} fn PassOptionalUnrestrictedFloat(self, _: Option<f32>) {} - fn PassOptionalFloat(self, _: Option<f32>) {} + fn PassOptionalFloat(self, _: Option<Finite<f32>>) {} fn PassOptionalUnrestrictedDouble(self, _: Option<f64>) {} - fn PassOptionalDouble(self, _: Option<f64>) {} + fn PassOptionalDouble(self, _: Option<Finite<f64>>) {} fn PassOptionalString(self, _: Option<DOMString>) {} fn PassOptionalUsvstring(self, _: Option<USVString>) {} fn PassOptionalByteString(self, _: Option<ByteString>) {} @@ -255,9 +256,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassOptionalNullableLongLong(self, _: Option<Option<i64>>) {} fn PassOptionalNullableUnsignedLongLong(self, _: Option<Option<u64>>) {} fn PassOptionalNullableUnrestrictedFloat(self, _: Option<Option<f32>>) {} - fn PassOptionalNullableFloat(self, _: Option<Option<f32>>) {} + fn PassOptionalNullableFloat(self, _: Option<Option<Finite<f32>>>) {} fn PassOptionalNullableUnrestrictedDouble(self, _: Option<Option<f64>>) {} - fn PassOptionalNullableDouble(self, _: Option<Option<f64>>) {} + fn PassOptionalNullableDouble(self, _: Option<Option<Finite<f64>>>) {} fn PassOptionalNullableString(self, _: Option<Option<DOMString>>) {} fn PassOptionalNullableUsvstring(self, _: Option<Option<USVString>>) {} fn PassOptionalNullableByteString(self, _: Option<Option<ByteString>>) {} @@ -291,9 +292,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassOptionalNullableLongLongWithDefault(self, _: Option<i64>) {} fn PassOptionalNullableUnsignedLongLongWithDefault(self, _: Option<u64>) {} // fn PassOptionalNullableUnrestrictedFloatWithDefault(self, _: Option<f32>) {} - // fn PassOptionalNullableFloatWithDefault(self, _: Option<f32>) {} + // fn PassOptionalNullableFloatWithDefault(self, _: Option<Finite<f32>>) {} // fn PassOptionalNullableUnrestrictedDoubleWithDefault(self, _: Option<f64>) {} - // fn PassOptionalNullableDoubleWithDefault(self, _: Option<f64>) {} + // fn PassOptionalNullableDoubleWithDefault(self, _: Option<Finite<f64>>) {} fn PassOptionalNullableStringWithDefault(self, _: Option<DOMString>) {} fn PassOptionalNullableUsvstringWithDefault(self, _: Option<USVString>) {} fn PassOptionalNullableByteStringWithDefault(self, _: Option<ByteString>) {} @@ -315,9 +316,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassOptionalNullableLongLongWithNonNullDefault(self, _: Option<i64>) {} fn PassOptionalNullableUnsignedLongLongWithNonNullDefault(self, _: Option<u64>) {} // fn PassOptionalNullableUnrestrictedFloatWithNonNullDefault(self, _: Option<f32>) {} - // fn PassOptionalNullableFloatWithNonNullDefault(self, _: Option<f32>) {} + // fn PassOptionalNullableFloatWithNonNullDefault(self, _: Option<Finite<f32>>) {} // fn PassOptionalNullableUnrestrictedDoubleWithNonNullDefault(self, _: Option<f64>) {} - // fn PassOptionalNullableDoubleWithNonNullDefault(self, _: Option<f64>) {} + // fn PassOptionalNullableDoubleWithNonNullDefault(self, _: Option<Finite<f64>>) {} fn PassOptionalNullableStringWithNonNullDefault(self, _: Option<DOMString>) {} fn PassOptionalNullableUsvstringWithNonNullDefault(self, _: Option<USVString>) {} // fn PassOptionalNullableEnumWithNonNullDefault(self, _: Option<TestEnum>) {} @@ -332,9 +333,9 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassVariadicLongLong(self, _: Vec<i64>) {} fn PassVariadicUnsignedLongLong(self, _: Vec<u64>) {} fn PassVariadicUnrestrictedFloat(self, _: Vec<f32>) {} - fn PassVariadicFloat(self, _: Vec<f32>) {} + fn PassVariadicFloat(self, _: Vec<Finite<f32>>) {} fn PassVariadicUnrestrictedDouble(self, _: Vec<f64>) {} - fn PassVariadicDouble(self, _: Vec<f64>) {} + fn PassVariadicDouble(self, _: Vec<Finite<f64>>) {} fn PassVariadicString(self, _: Vec<DOMString>) {} fn PassVariadicUsvstring(self, _: Vec<USVString>) {} fn PassVariadicByteString(self, _: Vec<ByteString>) {} |