Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (200919 => 200920)
--- trunk/Source/WebCore/bindings/js/JSDOMConvert.h 2016-05-14 16:54:07 UTC (rev 200919)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvert.h 2016-05-14 17:56:01 UTC (rev 200920)
@@ -32,17 +32,22 @@
enum class ShouldAllowNonFinite { No, Yes };
+template<typename T, typename U = T> using EnableIfIntegralType = typename std::enable_if<std::is_integral<T>::value, U>::type;
+template<typename T, typename U = T> using EnableIfFloatingPointType = typename std::enable_if<std::is_floating_point<T>::value, U>::type;
+
template<typename T, typename Enable = void> struct Converter;
template<typename T> T convert(JSC::ExecState&, JSC::JSValue);
-template<typename T> T convert(JSC::ExecState&, JSC::JSValue, IntegerConversionConfiguration);
-template<typename T> T convert(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite);
+template<typename T> EnableIfIntegralType<T> convert(JSC::ExecState&, JSC::JSValue, IntegerConversionConfiguration);
+template<typename T> EnableIfFloatingPointType<T> convert(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite);
template<typename T> typename Converter<T>::OptionalValue convertOptional(JSC::ExecState&, JSC::JSValue);
template<typename T, typename U> T convertOptional(JSC::ExecState&, JSC::JSValue, U&& defaultValue);
-template<typename T> typename Converter<T>::OptionalValue convertOptional(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite);
-template<typename T, typename U> T convertOptional(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite, U&& defaultValue);
+template<typename T> EnableIfIntegralType<T, Optional<T>> convertOptional(JSC::ExecState&, JSC::JSValue, IntegerConversionConfiguration);
+template<typename T> EnableIfFloatingPointType<T, Optional<T>> convertOptional(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite);
+template<typename T, typename U> EnableIfIntegralType<T> convertOptional(JSC::ExecState&, JSC::JSValue, IntegerConversionConfiguration, U&& defaultValue);
+template<typename T, typename U> EnableIfFloatingPointType<T> convertOptional(JSC::ExecState&, JSC::JSValue, ShouldAllowNonFinite, U&& defaultValue);
// This is where the implementation of the things declared above begins:
@@ -51,18 +56,17 @@
return Converter<T>::convert(state, value);
}
-template<typename T> T convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration)
+template<typename T> inline EnableIfIntegralType<T> convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration)
{
return Converter<T>::convert(state, value, configuration);
}
-template<typename T> inline T convert(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
+template<typename T> inline EnableIfFloatingPointType<T> convert(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
{
- static_assert(std::is_same<T, float>::value || std::is_same<T, double>::value, "ShouldAllowNonFinite can only be used with float or double");
return Converter<T>::convert(state, value, allow);
}
-template<typename T> typename Converter<T>::OptionalValue inline convertOptional(JSC::ExecState& state, JSC::JSValue value)
+template<typename T> inline typename Converter<T>::OptionalValue convertOptional(JSC::ExecState& state, JSC::JSValue value)
{
return value.isUndefined() ? typename Converter<T>::OptionalValue() : convert<T>(state, value);
}
@@ -72,16 +76,26 @@
return value.isUndefined() ? std::forward<U>(defaultValue) : convert<T>(state, value);
}
-template<typename T> typename Converter<T>::OptionalValue inline convertOptional(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
+template<typename T> inline EnableIfFloatingPointType<T, Optional<T>> convertOptional(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow)
{
- return value.isUndefined() ? typename Converter<T>::OptionalValue() : convert<T>(state, value, allow);
+ return value.isUndefined() ? Optional<T>() : convert<T>(state, value, allow);
}
-template<typename T, typename U> inline T convertOptional(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow, U&& defaultValue)
+template<typename T, typename U> inline EnableIfFloatingPointType<T> convertOptional(JSC::ExecState& state, JSC::JSValue value, ShouldAllowNonFinite allow, U&& defaultValue)
{
return value.isUndefined() ? std::forward<U>(defaultValue) : convert<T>(state, value, allow);
}
+template<typename T> inline EnableIfIntegralType<T, Optional<T>> convertOptional(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration)
+{
+ return value.isUndefined() ? Optional<T>() : convert<T>(state, value, configuration);
+}
+
+template<typename T, typename U> inline EnableIfIntegralType<T> convertOptional(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration, U&& defaultValue)
+{
+ return value.isUndefined() ? std::forward<U>(defaultValue) : convert<T>(state, value, configuration);
+}
+
template<typename T> struct DefaultConverter {
using OptionalValue = Optional<T>;
};
Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (200919 => 200920)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2016-05-14 16:54:07 UTC (rev 200919)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2016-05-14 17:56:01 UTC (rev 200920)
@@ -455,7 +455,7 @@
template<> TestObj::Dictionary convert<TestObj::Dictionary>(ExecState& state, JSValue value)
{
if (value.isUndefinedOrNull())
- return { { }, TestObj::EnumType::EnumValue1, TestObj::EnumType::EmptyString, "defaultString", { }, false, { }, { }, { }, { }, 0, 0, { }, { }, 0, 0 };
+ return { { }, TestObj::EnumType::EnumValue1, TestObj::EnumType::EmptyString, "defaultString", { }, false, { }, { }, { }, { }, 0, 0, { }, { }, 0, 0, { }, { }, { }, 0, { }, 0, { }, 0, { }, 0, { }, 0 };
auto* object = value.getObject();
if (UNLIKELY(!object || object->type() == RegExpObjectType)) {
throwTypeError(&state);
@@ -507,7 +507,43 @@
if (UNLIKELY(state.hadException()))
return { };
auto unrestrictedFloatWithDefault = convertOptional<float>(state, object->get(&state, Identifier::fromString(&state, "unrestrictedFloatWithDefault")), ShouldAllowNonFinite::Yes, 0);
- return { WTFMove(enumerationValueWithoutDefault), WTFMove(enumerationValueWithDefault), WTFMove(enumerationValueWithEmptyStringDefault), WTFMove(stringWithDefault), WTFMove(stringWithoutDefault), WTFMove(booleanWithDefault), WTFMove(booleanWithoutDefault), WTFMove(sequenceOfStrings), WTFMove(restrictedDouble), WTFMove(unrestrictedDouble), WTFMove(restrictedDoubleWithDefault), WTFMove(unrestrictedDoubleWithDefault), WTFMove(restrictedFloat), WTFMove(unrestrictedFloat), WTFMove(restrictedFloatWithDefault), WTFMove(unrestrictedFloatWithDefault) };
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto smallIntegerClamped = convertOptional<int8_t>(state, object->get(&state, Identifier::fromString(&state, "smallIntegerClamped")), Clamp);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto smallIntegerWithDefault = convertOptional<int8_t>(state, object->get(&state, Identifier::fromString(&state, "smallIntegerWithDefault")), NormalConversion);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto smallUnsignedIntegerEnforcedRange = convertOptional<uint8_t>(state, object->get(&state, Identifier::fromString(&state, "smallUnsignedIntegerEnforcedRange")), EnforceRange);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto smallUnsignedIntegerWithDefault = convertOptional<uint8_t>(state, object->get(&state, Identifier::fromString(&state, "smallUnsignedIntegerWithDefault")), NormalConversion, 0);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto integer = convertOptional<int32_t>(state, object->get(&state, Identifier::fromString(&state, "integer")), NormalConversion);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto integerWithDefault = convertOptional<int32_t>(state, object->get(&state, Identifier::fromString(&state, "integerWithDefault")), NormalConversion, 0);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto unsignedInteger = convertOptional<uint32_t>(state, object->get(&state, Identifier::fromString(&state, "unsignedInteger")), NormalConversion);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto unsignedIntegerWithDefault = convertOptional<uint32_t>(state, object->get(&state, Identifier::fromString(&state, "unsignedIntegerWithDefault")), NormalConversion, 0);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto largeInteger = convertOptional<int64_t>(state, object->get(&state, Identifier::fromString(&state, "largeInteger")), NormalConversion);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto largeIntegerWithDefault = convertOptional<int64_t>(state, object->get(&state, Identifier::fromString(&state, "largeIntegerWithDefault")), NormalConversion, 0);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto unsignedLargeInteger = convertOptional<uint64_t>(state, object->get(&state, Identifier::fromString(&state, "unsignedLargeInteger")), NormalConversion);
+ if (UNLIKELY(state.hadException()))
+ return { };
+ auto unsignedLargeIntegerWithDefault = convertOptional<uint64_t>(state, object->get(&state, Identifier::fromString(&state, "unsignedLargeIntegerWithDefault")), NormalConversion, 0);
+ return { WTFMove(enumerationValueWithoutDefault), WTFMove(enumerationValueWithDefault), WTFMove(enumerationValueWithEmptyStringDefault), WTFMove(stringWithDefault), WTFMove(stringWithoutDefault), WTFMove(booleanWithDefault), WTFMove(booleanWithoutDefault), WTFMove(sequenceOfStrings), WTFMove(restrictedDouble), WTFMove(unrestrictedDouble), WTFMove(restrictedDoubleWithDefault), WTFMove(unrestrictedDoubleWithDefault), WTFMove(restrictedFloat), WTFMove(unrestrictedFloat), WTFMove(restrictedFloatWithDefault), WTFMove(unrestrictedFloatWithDefault), WTFMove(smallIntegerClamped), WTFMove(smallIntegerWithDefault), WTFMove(smallUnsignedIntegerEnforcedRange), WTFMove(smallUnsignedIntegerWithDefault), WTFMove(integer), WTFMove(integerWithDefault), WTFMove(unsignedInteger), WTFMove(unsignedIntegerWithDefault), WTFMove(largeInteger), WTFMove(largeIntegerWithDefault), WTFMove(unsignedLargeInteger), WTFMove(unsignedLargeIntegerWithDefault) };
}
template<> TestObj::DictionaryThatShouldNotTolerateNull convert<TestObj::DictionaryThatShouldNotTolerateNull>(ExecState& state, JSValue value)