From 6d3c0bf763d0ed1f69c42122444ef0598ee13d5c Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 4 Mar 2014 16:38:05 +0100 Subject: [PATCH 1/6] Reorder implementations in conversions.rs. --- .../script/dom/bindings/conversions.rs | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs index 116b74e8efa..c6908ac40f6 100644 --- a/src/components/script/dom/bindings/conversions.rs +++ b/src/components/script/dom/bindings/conversions.rs @@ -26,39 +26,18 @@ unsafe fn convert_from_jsval( } -impl JSValConvertible for i64 { +impl JSValConvertible for bool { fn to_jsval(&self) -> JSVal { - unsafe { - RUST_DOUBLE_TO_JSVAL(*self as f64) + if *self { + JSVAL_TRUE + } else { + JSVAL_FALSE } } - fn from_jsval(cx: *JSContext, val: JSVal) -> Option { - unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) } - } -} - -impl JSValConvertible for u32 { - fn to_jsval(&self) -> JSVal { - unsafe { - RUST_UINT_TO_JSVAL(*self) - } - } - - fn from_jsval(cx: *JSContext, val: JSVal) -> Option { - unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) } - } -} - -impl JSValConvertible for i32 { - fn to_jsval(&self) -> JSVal { - unsafe { - RUST_UINT_TO_JSVAL(*self as u32) - } - } - - fn from_jsval(cx: *JSContext, val: JSVal) -> Option { - unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) } + fn from_jsval(cx: *JSContext, val: JSVal) -> Option { + let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) }; + result.map(|b| b != 0) } } @@ -74,18 +53,39 @@ impl JSValConvertible for u16 { } } -impl JSValConvertible for bool { +impl JSValConvertible for i32 { fn to_jsval(&self) -> JSVal { - if *self { - JSVAL_TRUE - } else { - JSVAL_FALSE + unsafe { + RUST_UINT_TO_JSVAL(*self as u32) } } - fn from_jsval(cx: *JSContext, val: JSVal) -> Option { - let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) }; - result.map(|b| b != 0) + fn from_jsval(cx: *JSContext, val: JSVal) -> Option { + unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) } + } +} + +impl JSValConvertible for u32 { + fn to_jsval(&self) -> JSVal { + unsafe { + RUST_UINT_TO_JSVAL(*self) + } + } + + fn from_jsval(cx: *JSContext, val: JSVal) -> Option { + unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) } + } +} + +impl JSValConvertible for i64 { + fn to_jsval(&self) -> JSVal { + unsafe { + RUST_DOUBLE_TO_JSVAL(*self as f64) + } + } + + fn from_jsval(cx: *JSContext, val: JSVal) -> Option { + unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) } } } From 595cd96f24359f5f143b4fe95f5f7c5bff426615 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 4 Mar 2014 17:01:30 +0100 Subject: [PATCH 2/6] Extend and update primitive conversions. --- .../script/dom/bindings/conversions.rs | 64 +++++++++++++++++-- src/components/script/dom/testbinding.rs | 3 + .../script/dom/webidls/TestBinding.webidl | 8 +-- 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs index c6908ac40f6..bed52b0338d 100644 --- a/src/components/script/dom/bindings/conversions.rs +++ b/src/components/script/dom/bindings/conversions.rs @@ -3,10 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use js::jsapi::{JSVal, JSBool, JSContext}; -use js::jsapi::{JS_ValueToInt64, JS_ValueToECMAInt32, JS_ValueToECMAUint32}; +use js::jsapi::{JS_ValueToUint64, JS_ValueToInt64}; +use js::jsapi::{JS_ValueToECMAUint32, JS_ValueToECMAInt32}; use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean}; use js::{JSVAL_FALSE, JSVAL_TRUE}; -use js::glue::{RUST_UINT_TO_JSVAL, RUST_DOUBLE_TO_JSVAL}; +use js::glue::{RUST_INT_TO_JSVAL, RUST_UINT_TO_JSVAL, RUST_JS_NumberValue}; pub trait JSValConvertible { fn to_jsval(&self) -> JSVal; @@ -41,6 +42,45 @@ impl JSValConvertible for bool { } } +impl JSValConvertible for i8 { + fn to_jsval(&self) -> JSVal { + unsafe { + RUST_INT_TO_JSVAL(*self as i32) + } + } + + fn from_jsval(cx: *JSContext, val: JSVal) -> Option { + let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }; + result.map(|v| v as i8) + } +} + +impl JSValConvertible for u8 { + fn to_jsval(&self) -> JSVal { + unsafe { + RUST_INT_TO_JSVAL(*self as i32) + } + } + + fn from_jsval(cx: *JSContext, val: JSVal) -> Option { + let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }; + result.map(|v| v as u8) + } +} + +impl JSValConvertible for i16 { + fn to_jsval(&self) -> JSVal { + unsafe { + RUST_INT_TO_JSVAL(*self as i32) + } + } + + fn from_jsval(cx: *JSContext, val: JSVal) -> Option { + let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }; + result.map(|v| v as i16) + } +} + impl JSValConvertible for u16 { fn to_jsval(&self) -> JSVal { unsafe { @@ -56,7 +96,7 @@ impl JSValConvertible for u16 { impl JSValConvertible for i32 { fn to_jsval(&self) -> JSVal { unsafe { - RUST_UINT_TO_JSVAL(*self as u32) + RUST_INT_TO_JSVAL(*self) } } @@ -80,7 +120,7 @@ impl JSValConvertible for u32 { impl JSValConvertible for i64 { fn to_jsval(&self) -> JSVal { unsafe { - RUST_DOUBLE_TO_JSVAL(*self as f64) + RUST_JS_NumberValue(*self as f64) } } @@ -89,10 +129,22 @@ impl JSValConvertible for i64 { } } +impl JSValConvertible for u64 { + fn to_jsval(&self) -> JSVal { + unsafe { + RUST_JS_NumberValue(*self as f64) + } + } + + fn from_jsval(cx: *JSContext, val: JSVal) -> Option { + unsafe { convert_from_jsval(cx, val, JS_ValueToUint64) } + } +} + impl JSValConvertible for f32 { fn to_jsval(&self) -> JSVal { unsafe { - RUST_DOUBLE_TO_JSVAL(*self as f64) + RUST_JS_NumberValue(*self as f64) } } @@ -105,7 +157,7 @@ impl JSValConvertible for f32 { impl JSValConvertible for f64 { fn to_jsval(&self) -> JSVal { unsafe { - RUST_DOUBLE_TO_JSVAL(*self as f64) + RUST_JS_NumberValue(*self) } } diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs index c19b41fa303..361710ad17f 100644 --- a/src/components/script/dom/testbinding.rs +++ b/src/components/script/dom/testbinding.rs @@ -13,8 +13,11 @@ impl TestBinding { pub fn BooleanAttribute(&self) -> bool { false } pub fn SetBooleanAttribute(&self, _: bool) {} pub fn ByteAttribute(&self) -> i8 { 0 } + pub fn SetByteAttribute(&self, _: i8) {} pub fn OctetAttribute(&self) -> u8 { 0 } + pub fn SetOctetAttribute(&self, _: u8) {} pub fn ShortAttribute(&self) -> i16 { 0 } + pub fn SetShortAttribute(&self, _: i16) {} pub fn UnsignedShortAttribute(&self) -> u16 { 0 } pub fn SetUnsignedShortAttribute(&self, _: u16) {} pub fn LongAttribute(&self) -> i32 { 0 } diff --git a/src/components/script/dom/webidls/TestBinding.webidl b/src/components/script/dom/webidls/TestBinding.webidl index b43b455cef0..34dd569e8ee 100644 --- a/src/components/script/dom/webidls/TestBinding.webidl +++ b/src/components/script/dom/webidls/TestBinding.webidl @@ -4,14 +4,14 @@ interface TestBinding { attribute boolean booleanAttribute; - readonly attribute byte byteAttribute; - readonly attribute octet octetAttribute; - readonly attribute short shortAttribute; + attribute byte byteAttribute; + attribute octet octetAttribute; + attribute short shortAttribute; attribute unsigned short unsignedShortAttribute; attribute long longAttribute; attribute unsigned long unsignedLongAttribute; attribute long long longLongAttribute; - readonly attribute unsigned long long unsignedLongLongAttribute; + attribute unsigned long long unsignedLongLongAttribute; attribute float floatAttribute; attribute double doubleAttribute; }; From 3d28f31ea90aab51f0535fd3aef455230a1db899 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 4 Mar 2014 17:08:56 +0100 Subject: [PATCH 3/6] Use JSValConvertible::to_jsval from codegen. --- .../dom/bindings/codegen/CodegenRust.py | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 7492723eca4..3950b522877 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1606,27 +1606,9 @@ if %(resultStr)s.is_null() { return ("if (%s.IsNull()) {\n" % result + CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" + "}\n" + recTemplate, recInfal) - - tag = type.tag() - - if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, IDLType.Tags.int16, - IDLType.Tags.uint16, IDLType.Tags.int32]: - return (setValue("RUST_INT_TO_JSVAL(%s as i32)" % result), True) - elif tag in [IDLType.Tags.int64, IDLType.Tags.uint64, IDLType.Tags.float, - IDLType.Tags.double]: - # XXXbz will cast to double do the "even significand" thing that webidl - # calls for for 64-bit ints? Do we care? - return (setValue("RUST_JS_NumberValue(%s as f64)" % result), True) + return (setValue("(%s).to_jsval()" % result), True) - elif tag == IDLType.Tags.uint32: - return (setValue("RUST_UINT_TO_JSVAL(%s)" % result), True) - - elif tag == IDLType.Tags.bool: - return (setValue("RUST_BOOLEAN_TO_JSVAL(%s as JSBool)" % result), True) - - else: - raise TypeError("Need to learn to wrap primitive: %s" % type) def wrapForType(type, descriptorProvider, templateValues): """ From d063601ba0758a5b88b6f6b2a4f99593e71aa07c Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 4 Mar 2014 17:19:49 +0100 Subject: [PATCH 4/6] Implement support for returning nullable primitive types. --- .../dom/bindings/codegen/CodegenRust.py | 6 ++--- src/components/script/dom/testbinding.rs | 23 +++++++++++++++++++ .../script/dom/webidls/TestBinding.webidl | 12 ++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 3950b522877..20cbe1080ef 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1601,9 +1601,9 @@ if %(resultStr)s.is_null() { if type.nullable(): (recTemplate, recInfal) = getWrapTemplateForType(type.inner, descriptorProvider, - "%s.Value()" % result, successCode, + "%s.unwrap()" % result, successCode, isCreator, exceptionCode) - return ("if (%s.IsNull()) {\n" % result + + return ("if (%s.is_none()) {\n" % result + CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" + "}\n" + recTemplate, recInfal) @@ -1667,7 +1667,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): if returnType.isPrimitive() and returnType.tag() in builtinNames: result = CGGeneric(builtinNames[returnType.tag()]) if returnType.nullable(): - result = CGWrapper(result, pre="Nullable<", post=">") + result = CGWrapper(result, pre="Option<", post=">") return result, False if returnType.isString(): result = CGGeneric("DOMString") diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs index 361710ad17f..4aceb57bec2 100644 --- a/src/components/script/dom/testbinding.rs +++ b/src/components/script/dom/testbinding.rs @@ -32,6 +32,29 @@ impl TestBinding { pub fn SetFloatAttribute(&self, _: f32) {} pub fn DoubleAttribute(&self) -> f64 { 0. } pub fn SetDoubleAttribute(&self, _: f64) {} + + pub fn GetBooleanAttributeNullable(&self) -> Option { Some(false) } + pub fn SetBooleanAttributeNullable(&self, _: Option) {} + pub fn GetByteAttributeNullable(&self) -> Option { Some(0) } + pub fn SetByteAttributeNullable(&self, _: Option) {} + pub fn GetOctetAttributeNullable(&self) -> Option { Some(0) } + pub fn SetOctetAttributeNullable(&self, _: Option) {} + pub fn GetShortAttributeNullable(&self) -> Option { Some(0) } + pub fn SetShortAttributeNullable(&self, _: Option) {} + pub fn GetUnsignedShortAttributeNullable(&self) -> Option { Some(0) } + pub fn SetUnsignedShortAttributeNullable(&self, _: Option) {} + pub fn GetLongAttributeNullable(&self) -> Option { Some(0) } + pub fn SetLongAttributeNullable(&self, _: Option) {} + pub fn GetUnsignedLongAttributeNullable(&self) -> Option { Some(0) } + pub fn SetUnsignedLongAttributeNullable(&self, _: Option) {} + pub fn GetLongLongAttributeNullable(&self) -> Option { Some(0) } + pub fn SetLongLongAttributeNullable(&self, _: Option) {} + pub fn GetUnsignedLongLongAttributeNullable(&self) -> Option { Some(0) } + pub fn SetUnsignedLongLongAttributeNullable(&self, _: Option) {} + pub fn GetFloatAttributeNullable(&self) -> Option { Some(0.) } + pub fn SetFloatAttributeNullable(&self, _: Option) {} + pub fn GetDoubleAttributeNullable(&self) -> Option { Some(0.) } + pub fn SetDoubleAttributeNullable(&self, _: Option) {} } impl Reflectable for TestBinding { diff --git a/src/components/script/dom/webidls/TestBinding.webidl b/src/components/script/dom/webidls/TestBinding.webidl index 34dd569e8ee..8086a2bead9 100644 --- a/src/components/script/dom/webidls/TestBinding.webidl +++ b/src/components/script/dom/webidls/TestBinding.webidl @@ -14,4 +14,16 @@ interface TestBinding { attribute unsigned long long unsignedLongLongAttribute; attribute float floatAttribute; attribute double doubleAttribute; + + attribute boolean? booleanAttributeNullable; + attribute byte? byteAttributeNullable; + attribute octet? octetAttributeNullable; + attribute short? shortAttributeNullable; + attribute unsigned short? unsignedShortAttributeNullable; + attribute long? longAttributeNullable; + attribute unsigned long? unsignedLongAttributeNullable; + attribute long long? longLongAttributeNullable; + attribute unsigned long long? unsignedLongLongAttributeNullable; + attribute float? floatAttributeNullable; + attribute double? doubleAttributeNullable; }; From aa9a61a78c240528d5ee7f229e4bac9254407e5e Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 4 Mar 2014 18:34:24 +0100 Subject: [PATCH 5/6] Add tests for optional primitive arguments. --- src/components/script/dom/testbinding.rs | 35 +++++++++++++++++++ .../script/dom/webidls/TestBinding.webidl | 33 +++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs index 4aceb57bec2..b26fc90fb47 100644 --- a/src/components/script/dom/testbinding.rs +++ b/src/components/script/dom/testbinding.rs @@ -55,6 +55,41 @@ impl TestBinding { pub fn SetFloatAttributeNullable(&self, _: Option) {} pub fn GetDoubleAttributeNullable(&self) -> Option { Some(0.) } pub fn SetDoubleAttributeNullable(&self, _: Option) {} + + // FIXME (issue #1813) Doesn't currently compile. + // pub fn PassOptionalBoolean(&self, _: Option) {} + // pub fn PassOptionalByte(&self, _: Option) {} + // pub fn PassOptionalOctet(&self, _: Option) {} + // pub fn PassOptionalShort(&self, _: Option) {} + // pub fn PassOptionalUnsignedShort(&self, _: Option) {} + // pub fn PassOptionalLong(&self, _: Option) {} + // pub fn PassOptionalUnsignedLong(&self, _: Option) {} + // pub fn PassOptionalLongLong(&self, _: Option) {} + // pub fn PassOptionalUnsignedLongLong(&self, _: Option) {} + // pub fn PassOptionalFloat(&self, _: Option) {} + // pub fn PassOptionalDouble(&self, _: Option) {} + + pub fn PassOptionalBooleanWithDefault(&self, _: bool) {} + pub fn PassOptionalByteWithDefault(&self, _: i8) {} + pub fn PassOptionalOctetWithDefault(&self, _: u8) {} + pub fn PassOptionalShortWithDefault(&self, _: i16) {} + pub fn PassOptionalUnsignedShortWithDefault(&self, _: u16) {} + pub fn PassOptionalLongWithDefault(&self, _: i32) {} + pub fn PassOptionalUnsignedLongWithDefault(&self, _: u32) {} + pub fn PassOptionalLongLongWithDefault(&self, _: i64) {} + pub fn PassOptionalUnsignedLongLongWithDefault(&self, _: u64) {} + + pub fn PassOptionalNullableBooleanWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableByteWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableOctetWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableShortWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableUnsignedShortWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableLongWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableUnsignedLongWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableLongLongWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableUnsignedLongLongWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableFloatWithDefault(&self, _: Option) {} + pub fn PassOptionalNullableDoubleWithDefault(&self, _: Option) {} } impl Reflectable for TestBinding { diff --git a/src/components/script/dom/webidls/TestBinding.webidl b/src/components/script/dom/webidls/TestBinding.webidl index 8086a2bead9..94530b6cf1d 100644 --- a/src/components/script/dom/webidls/TestBinding.webidl +++ b/src/components/script/dom/webidls/TestBinding.webidl @@ -26,4 +26,37 @@ interface TestBinding { attribute unsigned long long? unsignedLongLongAttributeNullable; attribute float? floatAttributeNullable; attribute double? doubleAttributeNullable; + + // FIXME (issue #1813) Doesn't currently compile. + // void passOptionalBoolean(optional boolean arg); + // void passOptionalByte(optional byte arg); + // void passOptionalOctet(optional octet arg); + // void passOptionalShort(optional short arg); + // void passOptionalUnsignedShort(optional unsigned short arg); + // void passOptionalLong(optional long arg); + // void passOptionalUnsignedLong(optional unsigned long arg); + // void passOptionalLongLong(optional long long arg); + // void passOptionalUnsignedLongLong(optional unsigned long long arg); + // void passOptionalFloat(optional float arg); + // void passOptionalDouble(optional double arg); + + void passOptionalBooleanWithDefault(optional boolean arg = false); + void passOptionalByteWithDefault(optional byte arg = 0); + void passOptionalOctetWithDefault(optional octet arg = 19); + void passOptionalShortWithDefault(optional short arg = 5); + void passOptionalUnsignedShortWithDefault(optional unsigned short arg = 2); + void passOptionalLongWithDefault(optional long arg = 7); + void passOptionalUnsignedLongWithDefault(optional unsigned long arg = 6); + void passOptionalLongLongWithDefault(optional long long arg = -12); + void passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 17); + + void passOptionalNullableBooleanWithDefault(optional boolean? arg = null); + void passOptionalNullableByteWithDefault(optional byte? arg = null); + void passOptionalNullableOctetWithDefault(optional octet? arg = null); + void passOptionalNullableShortWithDefault(optional short? arg = null); + void passOptionalNullableUnsignedShortWithDefault(optional unsigned short? arg = null); + void passOptionalNullableLongWithDefault(optional long? arg = null); + void passOptionalNullableUnsignedLongWithDefault(optional unsigned long? arg = null); + void passOptionalNullableLongLongWithDefault(optional long long? arg = null); + void passOptionalNullableUnsignedLongLongWithDefault(optional unsigned long long? arg = null); }; From 1608f842e99593242d2ff6aa33dc34ea709e46af Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 4 Mar 2014 18:55:58 +0100 Subject: [PATCH 6/6] Rewrite the codegen for nullable primitives to use JSValConvertible. --- .../dom/bindings/codegen/CodegenRust.py | 35 ++++++++----------- .../script/dom/bindings/conversions.rs | 21 ++++++++++- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 20cbe1080ef..2c9b346db96 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1233,23 +1233,24 @@ for (uint32_t i = 0; i < length; ++i) { failureCode = 'return 0' if type.nullable(): - dataLoc = "${declName}.SetValue()" - nullCondition = "(RUST_JSVAL_IS_NULL(${val}) != 0 || RUST_JSVAL_IS_VOID(${val}) != 0)" - if defaultValue is not None and isinstance(defaultValue, IDLNullValue): - nullCondition = "!(${haveValue}) || " + nullCondition - successVal = "val_" + successVal = "v" if preSuccess or postSuccess: successVal = preSuccess + successVal + postSuccess #XXXjdm support conversionBehavior here template = ( - "if (%s) {\n" - " ${declName} = None;\n" - "} else {\n" - " match JSValConvertible::from_jsval(cx, ${val}) {\n" - " Some(val_) => ${declName} = Some(%s),\n" - " None => %s\n" - " }\n" - "}" % (nullCondition, successVal, failureCode)) + "match JSValConvertible::from_jsval(cx, ${val}) {\n" + " Some(v) => ${declName} = %s,\n" + " None => %s\n" + "}" % (successVal, failureCode)) + + if defaultValue is not None and isinstance(defaultValue, IDLNullValue): + template = CGWrapper(CGIndenter(CGGeneric(template)), + pre="if ${haveValue} {\n", + post=("\n" + "} else {\n" + " ${declName} = None;\n" + "}")).define() + declType = CGGeneric("Option<" + typeName + ">") else: assert(defaultValue is None or @@ -1599,14 +1600,6 @@ if %(resultStr)s.is_null() { if not type.isPrimitive(): raise TypeError("Need to learn to wrap %s" % type) - if type.nullable(): - (recTemplate, recInfal) = getWrapTemplateForType(type.inner, descriptorProvider, - "%s.unwrap()" % result, successCode, - isCreator, exceptionCode) - return ("if (%s.is_none()) {\n" % result + - CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" + - "}\n" + recTemplate, recInfal) - return (setValue("(%s).to_jsval()" % result), True) diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs index bed52b0338d..2a59b52791b 100644 --- a/src/components/script/dom/bindings/conversions.rs +++ b/src/components/script/dom/bindings/conversions.rs @@ -6,8 +6,9 @@ use js::jsapi::{JSVal, JSBool, JSContext}; use js::jsapi::{JS_ValueToUint64, JS_ValueToInt64}; use js::jsapi::{JS_ValueToECMAUint32, JS_ValueToECMAInt32}; use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean}; -use js::{JSVAL_FALSE, JSVAL_TRUE}; +use js::{JSVAL_FALSE, JSVAL_TRUE, JSVAL_NULL}; use js::glue::{RUST_INT_TO_JSVAL, RUST_UINT_TO_JSVAL, RUST_JS_NumberValue}; +use js::glue::{RUST_JSVAL_IS_NULL, RUST_JSVAL_IS_VOID}; pub trait JSValConvertible { fn to_jsval(&self) -> JSVal; @@ -165,3 +166,21 @@ impl JSValConvertible for f64 { unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) } } } + +impl JSValConvertible for Option { + fn to_jsval(&self) -> JSVal { + match self { + &Some(ref value) => value.to_jsval(), + &None => JSVAL_NULL, + } + } + + fn from_jsval(cx: *JSContext, value: JSVal) -> Option> { + if unsafe { RUST_JSVAL_IS_NULL(value) != 0 || RUST_JSVAL_IS_VOID(value) != 0 } { + Some(None) + } else { + let result: Option = JSValConvertible::from_jsval(cx, value); + result.map(|v| Some(v)) + } + } +}