Title: [207829] trunk/Source/WebCore
Revision
207829
Author
[email protected]
Date
2016-10-25 11:35:03 -0700 (Tue, 25 Oct 2016)

Log Message

[WebIDL] Move more types over to the new JSConverter based toJS functions
https://bugs.webkit.org/show_bug.cgi?id=163920

Reviewed by Darin Adler.

- Adds WebIDL-extension type IDLDate, and use it for Date conversions.
- Move JSDOMIterator over to using IDLType based conversions. Make them more
  explicit by adding a traits template argument which describes the iterator.
- Add correct parsing for WebIDL iterable, parsing the parameter types into
  domTypes.
- Support non-Optional nullable types via trait-like functions on IDLTypes.


* bindings/generic/IDLTypes.h:
(WebCore::IDLType::isNullValue):
(WebCore::IDLType::extractValueFromNullable):
(WebCore::IDLString::isNullValue):
(WebCore::IDLString::extractValueFromNullable):
(WebCore::IDLInterface::isNullValue):
(WebCore::IDLInterface::extractValueFromNullable):
(WebCore::IDLDate::isNullValue):
(WebCore::IDLDate::extractValueFromNullable):
Add isNullValue and extractValueFromNullable functions to allow non-Optional
based nullable types.
        
* Modules/plugins/QuickTimePluginReplacement.mm:
(WebCore::QuickTimePluginReplacement::installReplacement):
* bindings/js/IDBBindingUtilities.cpp:
(WebCore::toJS):
* bindings/js/JSCSSStyleDeclarationCustom.cpp:
(WebCore::stylePropertyGetter):
* bindings/js/JSCustomElementInterface.cpp:
(WebCore::JSCustomElementInterface::invokeAttributeChangedCallback):
Switch to IDLType based toJS.

* bindings/js/JSDOMBinding.cpp:
(WebCore::jsStringOrNull): Deleted.
(WebCore::jsDateOrNull): Deleted.
* bindings/js/JSDOMBinding.h:
(WebCore::jsPair): Deleted.
(WebCore::toJSNullableString): Deleted.
Remove now unusued toJS functions.

* bindings/js/JSDOMConvert.h:
(WebCore::JSConverter<IDLNullable<T>>::convert):
Use new functions to detect and extract nullable values.

(WebCore::Converter<IDLBufferSource>::convert):
Moved to be with the other converters.

(WebCore::Converter<IDLDate>::convert):
(WebCore::JSConverter<IDLDate>::convert):
Added.

* bindings/js/JSDOMIterator.h:
(WebCore::jsPair):
(WebCore::iteratorCreate):
(WebCore::IteratorTraits>::asJS):
(WebCore::appendForEachArguments):
(WebCore::iteratorForEach):
(WebCore::IteratorTraits>::destroy):
(WebCore::IteratorTraits>::next):
(WebCore::IteratorTraits>::finishCreation):
(WebCore::IteratorInspector::decltype): Deleted.
(WebCore::IteratorInspector::test): Deleted.
(WebCore::JSDOMIterator<JSWrapper>::asJS): Deleted.
(WebCore::JSDOMIterator<JSWrapper>::destroy): Deleted.
(WebCore::JSDOMIterator<JSWrapper>::next): Deleted.
(WebCore::JSDOMIteratorPrototype<JSWrapper>::next): Deleted.
(WebCore::JSDOMIteratorPrototype<JSWrapper>::finishCreation): Deleted.
Switch to new Traits based model, and have the generated code pass in 
the type (map or set) and key/value types. With the explicit types known,
we can use the new toJS functions.
        
Also, moved the jsPair functions here from JSDOMBinding.h, since this was
the only place it was used.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementationIterableFunctions):
Add iterator trait definition and update for new parameters to JSDOMIterator
and JSDOMIteratorPrototype.

(GetBaseIDLType):
Add IDLDate, and move IDLBufferSource up to the simple path.

(JSValueToNativeIsHandledByDOMConvert):
Allow Date.

(JSValueToNative):
Remove special case for Date.

(NativeToJSValueIsHandledByDOMConvert):
Allow Date and remove restriction of nullable string-like types.

(NativeToJSValueDOMConvertNeedsState):
Add Date to list of types needing state.

(NativeToJSValue):
Remove special cases for Date and nullable-strings.

* bindings/scripts/IDLParser.pm:
(parseOptionalIterableInterface):
Add correct parsing of iterable.

* bindings/scripts/test/JS/JSTestIterable.cpp:
* bindings/scripts/test/JS/JSTestNode.cpp:
* bindings/scripts/test/JS/JSTestObj.cpp:
Update test results.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (207828 => 207829)


--- trunk/Source/WebCore/ChangeLog	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/ChangeLog	2016-10-25 18:35:03 UTC (rev 207829)
@@ -1,3 +1,114 @@
+2016-10-24  Sam Weinig  <[email protected]>
+
+        [WebIDL] Move more types over to the new JSConverter based toJS functions
+        https://bugs.webkit.org/show_bug.cgi?id=163920
+
+        Reviewed by Darin Adler.
+
+        - Adds WebIDL-extension type IDLDate, and use it for Date conversions.
+        - Move JSDOMIterator over to using IDLType based conversions. Make them more
+          explicit by adding a traits template argument which describes the iterator.
+        - Add correct parsing for WebIDL iterable, parsing the parameter types into
+          domTypes.
+        - Support non-Optional nullable types via trait-like functions on IDLTypes.
+
+
+        * bindings/generic/IDLTypes.h:
+        (WebCore::IDLType::isNullValue):
+        (WebCore::IDLType::extractValueFromNullable):
+        (WebCore::IDLString::isNullValue):
+        (WebCore::IDLString::extractValueFromNullable):
+        (WebCore::IDLInterface::isNullValue):
+        (WebCore::IDLInterface::extractValueFromNullable):
+        (WebCore::IDLDate::isNullValue):
+        (WebCore::IDLDate::extractValueFromNullable):
+        Add isNullValue and extractValueFromNullable functions to allow non-Optional
+        based nullable types.
+        
+        * Modules/plugins/QuickTimePluginReplacement.mm:
+        (WebCore::QuickTimePluginReplacement::installReplacement):
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+        (WebCore::stylePropertyGetter):
+        * bindings/js/JSCustomElementInterface.cpp:
+        (WebCore::JSCustomElementInterface::invokeAttributeChangedCallback):
+        Switch to IDLType based toJS.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::jsStringOrNull): Deleted.
+        (WebCore::jsDateOrNull): Deleted.
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::jsPair): Deleted.
+        (WebCore::toJSNullableString): Deleted.
+        Remove now unusued toJS functions.
+
+        * bindings/js/JSDOMConvert.h:
+        (WebCore::JSConverter<IDLNullable<T>>::convert):
+        Use new functions to detect and extract nullable values.
+
+        (WebCore::Converter<IDLBufferSource>::convert):
+        Moved to be with the other converters.
+
+        (WebCore::Converter<IDLDate>::convert):
+        (WebCore::JSConverter<IDLDate>::convert):
+        Added.
+
+        * bindings/js/JSDOMIterator.h:
+        (WebCore::jsPair):
+        (WebCore::iteratorCreate):
+        (WebCore::IteratorTraits>::asJS):
+        (WebCore::appendForEachArguments):
+        (WebCore::iteratorForEach):
+        (WebCore::IteratorTraits>::destroy):
+        (WebCore::IteratorTraits>::next):
+        (WebCore::IteratorTraits>::finishCreation):
+        (WebCore::IteratorInspector::decltype): Deleted.
+        (WebCore::IteratorInspector::test): Deleted.
+        (WebCore::JSDOMIterator<JSWrapper>::asJS): Deleted.
+        (WebCore::JSDOMIterator<JSWrapper>::destroy): Deleted.
+        (WebCore::JSDOMIterator<JSWrapper>::next): Deleted.
+        (WebCore::JSDOMIteratorPrototype<JSWrapper>::next): Deleted.
+        (WebCore::JSDOMIteratorPrototype<JSWrapper>::finishCreation): Deleted.
+        Switch to new Traits based model, and have the generated code pass in 
+        the type (map or set) and key/value types. With the explicit types known,
+        we can use the new toJS functions.
+        
+        Also, moved the jsPair functions here from JSDOMBinding.h, since this was
+        the only place it was used.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateImplementationIterableFunctions):
+        Add iterator trait definition and update for new parameters to JSDOMIterator
+        and JSDOMIteratorPrototype.
+
+        (GetBaseIDLType):
+        Add IDLDate, and move IDLBufferSource up to the simple path.
+
+        (JSValueToNativeIsHandledByDOMConvert):
+        Allow Date.
+
+        (JSValueToNative):
+        Remove special case for Date.
+
+        (NativeToJSValueIsHandledByDOMConvert):
+        Allow Date and remove restriction of nullable string-like types.
+
+        (NativeToJSValueDOMConvertNeedsState):
+        Add Date to list of types needing state.
+
+        (NativeToJSValue):
+        Remove special cases for Date and nullable-strings.
+
+        * bindings/scripts/IDLParser.pm:
+        (parseOptionalIterableInterface):
+        Add correct parsing of iterable.
+
+        * bindings/scripts/test/JS/JSTestIterable.cpp:
+        * bindings/scripts/test/JS/JSTestNode.cpp:
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        Update test results.
+
 2016-10-25  Eric Carlson  <[email protected]>
 
         [MediaStream] Add "has capture device" bit to media state flags

Modified: trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm (207828 => 207829)


--- trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm	2016-10-25 18:35:03 UTC (rev 207829)
@@ -210,8 +210,8 @@
     argList.append(toJS(exec, globalObject, &root));
     argList.append(toJS(exec, globalObject, m_parentElement));
     argList.append(toJS(exec, globalObject, this));
-    argList.append(toJS<String>(exec, globalObject, m_names));
-    argList.append(toJS<String>(exec, globalObject, m_values));
+    argList.append(toJS<IDLSequence<IDLNullable<IDLDOMString>>>(*exec, *globalObject, m_names));
+    argList.append(toJS<IDLSequence<IDLNullable<IDLDOMString>>>(*exec, *globalObject, m_values));
     JSC::JSValue replacement = call(exec, replacementObject, callType, callData, globalObject, argList);
     if (UNLIKELY(scope.exception())) {
         scope.clearException();

Modified: trunk/Source/WebCore/bindings/generic/IDLTypes.h (207828 => 207829)


--- trunk/Source/WebCore/bindings/generic/IDLTypes.h	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/generic/IDLTypes.h	2016-10-25 18:35:03 UTC (rev 207829)
@@ -41,11 +41,13 @@
 template<typename T>
 struct IDLType {
     using ImplementationType = T;
+
     using NullableType = Optional<ImplementationType>;
+    static NullableType nullValue() { return Nullopt; }
+    static bool isNullValue(const NullableType& value) { return !value; }
+    static ImplementationType extractValueFromNullable(const NullableType& value) { return value.value(); }
 };
 
-struct IDLDummy;
-
 // IDLUnsupportedType is a special type that serves as a base class for currently unsupported types.
 struct IDLUnsupportedType : IDLType<void> { };
 
@@ -78,6 +80,9 @@
 
 struct IDLString : IDLType<String> {
     using NullableType = String;
+    static String nullValue() { return String(); }
+    static bool isNullValue(const String& value) { return value.isNull(); }
+    static const String& extractValueFromNullable(const String& value) { return value; }
 };
 struct IDLDOMString : IDLString { };
 struct IDLByteString : IDLUnsupportedType { };
@@ -87,7 +92,11 @@
 
 template<typename T> struct IDLInterface : IDLType<RefPtr<T>> {
     using RawType = T;
+
     using NullableType = RefPtr<T>;
+    static RefPtr<T> nullValue() { return nullptr; }
+    static bool isNullValue(const RefPtr<T>& value) { return !value; }
+    static const RefPtr<T>& extractValueFromNullable(const RefPtr<T>& value) { return value; }
 };
 
 template<typename T> struct IDLDictionary : IDLType<T> { };
@@ -119,6 +128,15 @@
     using TypeList = brigand::list<Ts...>;
 };
 
+// Non-WebIDL extensions
+
+struct IDLDate : IDLType<double> { 
+    using NullableType = double;
+    static double nullValue() { return std::numeric_limits<double>::quiet_NaN(); }
+    static bool isNullValue(double value) { return std::isnan(value); }
+    static double extractValueFromNullable(double value) { return value; }
+};
+
 struct IDLBufferSource : IDLType<BufferSource> { };
 
 // Helper predicates

Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp (207828 => 207829)


--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp	2016-10-25 18:35:03 UTC (rev 207829)
@@ -107,9 +107,9 @@
     case KeyType::String:
         return jsStringWithCache(&state, key->string());
     case KeyType::Date:
-        // FIXME: This should probably be jsDate() as per:
+        // FIXME: This should probably be toJS<IDLDate>(...) as per:
         // http://w3c.github.io/IndexedDB/#request-convert-a-key-to-a-value
-        return jsDateOrNull(&state, key->date());
+        return toJS<IDLNullable<IDLDate>>(state, key->date());
     case KeyType::Number:
         return jsNumber(key->number());
     case KeyType::Min:

Modified: trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp (207828 => 207829)


--- trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp	2016-10-25 18:35:03 UTC (rev 207829)
@@ -283,9 +283,9 @@
 static inline JSValue stylePropertyGetter(ExecState& state, JSCSSStyleDeclaration& thisObject, CSSPropertyID propertyID, const RefPtr<CSSValue>& value)
 {
     if (value)
-        return jsStringOrNull(&state, value->cssText());
+        return toJS<IDLNullable<IDLDOMString>>(state, value->cssText());
     // If the property is a shorthand property (such as "padding"), it can only be accessed using getPropertyValue.
-    return jsStringWithCache(&state, thisObject.wrapped().getPropertyValueInternal(propertyID));
+    return toJS<IDLDOMString>(state, thisObject.wrapped().getPropertyValueInternal(propertyID));
 }
 
 static inline JSValue stylePropertyGetter(ExecState& state, JSCSSStyleDeclaration& thisObject, CSSPropertyID propertyID)

Modified: trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp (207828 => 207829)


--- trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp	2016-10-25 18:35:03 UTC (rev 207829)
@@ -289,10 +289,10 @@
 void JSCustomElementInterface::invokeAttributeChangedCallback(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
 {
     invokeCallback(element, m_attributeChangedCallback.get(), [&](ExecState* state, JSDOMGlobalObject*, MarkedArgumentBuffer& args) {
-        args.append(jsStringWithCache(state, attributeName.localName()));
-        args.append(jsStringOrNull(state, oldValue));
-        args.append(jsStringOrNull(state, newValue));
-        args.append(jsStringOrNull(state, attributeName.namespaceURI()));
+        args.append(toJS<IDLDOMString>(*state, attributeName.localName()));
+        args.append(toJS<IDLNullable<IDLDOMString>>(*state, oldValue));
+        args.append(toJS<IDLNullable<IDLDOMString>>(*state, newValue));
+        args.append(toJS<IDLNullable<IDLDOMString>>(*state, attributeName.namespaceURI()));
     });
 }
 

Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (207828 => 207829)


--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp	2016-10-25 18:35:03 UTC (rev 207829)
@@ -64,13 +64,6 @@
     JSDOMWindow::commonVM().addImpureProperty(propertyName);
 }
 
-JSValue jsStringOrNull(ExecState* exec, const String& s)
-{
-    if (s.isNull())
-        return jsNull();
-    return jsStringWithCache(exec, s);
-}
-
 JSValue jsOwnedStringOrNull(ExecState* exec, const String& s)
 {
     if (s.isNull())
@@ -90,13 +83,6 @@
     return jsStringWithCache(exec, url.string());
 }
 
-JSValue jsStringOrNull(ExecState* exec, const URL& url)
-{
-    if (url.isNull())
-        return jsNull();
-    return jsStringWithCache(exec, url.string());
-}
-
 JSValue jsStringOrUndefined(ExecState* exec, const URL& url)
 {
     if (url.isNull())
@@ -171,14 +157,6 @@
     return DateInstance::create(exec->vm(), exec->lexicalGlobalObject()->dateStructure(), value);
 }
 
-JSValue jsDateOrNull(ExecState* exec, double value)
-{
-    // For nullable Date types, we use NaN as null value.
-    if (std::isnan(value))
-        return jsNull();
-    return DateInstance::create(exec->vm(), exec->lexicalGlobalObject()->dateStructure(), value);
-}
-
 double valueToDate(ExecState* exec, JSValue value)
 {
     if (value.isNumber())

Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (207828 => 207829)


--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2016-10-25 18:35:03 UTC (rev 207829)
@@ -202,9 +202,6 @@
 
 JSC::JSValue jsString(JSC::ExecState*, const URL&); // empty if the URL is null
 
-JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&); // null if the string is null
-JSC::JSValue jsStringOrNull(JSC::ExecState*, const URL&); // null if the URL is null
-
 JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const String&); // undefined if the string is null
 JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const URL&); // undefined if the URL is null
 
@@ -257,7 +254,6 @@
 WEBCORE_EXPORT uint64_t toUInt64(JSC::ExecState&, JSC::JSValue);
 
 JSC::JSValue jsDate(JSC::ExecState*, double value);
-JSC::JSValue jsDateOrNull(JSC::ExecState*, double value);
 
 // NaN if the value can't be converted to a date.
 double valueToDate(JSC::ExecState*, JSC::JSValue);
@@ -273,17 +269,12 @@
 template<typename T> JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, RefPtr<T>&&);
 template<typename T> JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const Vector<T>&);
 template<typename T> JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const Vector<RefPtr<T>>&);
-JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const String&);
 JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const JSC::PrivateName&);
 
 JSC::JSValue toJSIterator(JSC::ExecState&, JSDOMGlobalObject&, JSC::JSValue);
 template<typename T> JSC::JSValue toJSIterator(JSC::ExecState&, JSDOMGlobalObject&, const T&);
-
 JSC::JSValue toJSIteratorEnd(JSC::ExecState&);
 
-JSC::JSValue jsPair(JSC::ExecState&, JSDOMGlobalObject*, JSC::JSValue, JSC::JSValue);
-template<typename FirstType, typename SecondType> JSC::JSValue jsPair(JSC::ExecState&, JSDOMGlobalObject*, const FirstType&, const SecondType&);
-
 RefPtr<JSC::ArrayBufferView> toArrayBufferView(JSC::JSValue);
 RefPtr<JSC::Int8Array> toInt8Array(JSC::JSValue);
 RefPtr<JSC::Int16Array> toInt16Array(JSC::JSValue);
@@ -405,9 +396,6 @@
 // ExceptionOr handling.
 void propagateException(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<void>&&);
 template<typename T> JSC::JSValue toJS(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<T>&&);
-JSC::JSValue toJSDate(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<double>&&);
-JSC::JSValue toJSNullableDate(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<Optional<double>>&&);
-JSC::JSValue toJSNullableString(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<String>&&);
 template<typename T> JSC::JSValue toJSNewlyCreated(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<T>&& value);
 
 // Inline functions and template definitions.
@@ -683,11 +671,6 @@
     return array;
 }
 
-inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject*, const String& value)
-{
-    return jsStringOrNull(exec, value);
-}
-
 inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject*, const JSC::PrivateName& privateName)
 {
     return JSC::Symbol::create(exec->vm(), privateName.uid());
@@ -708,19 +691,6 @@
     return createIteratorResultObject(&state, JSC::jsUndefined(), true);
 }
 
-inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::JSValue value1, JSC::JSValue value2)
-{
-    JSC::MarkedArgumentBuffer args;
-    args.append(value1);
-    args.append(value2);
-    return constructArray(&state, 0, globalObject, args);
-}
-
-template<typename FirstType, typename SecondType> inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject* globalObject, const FirstType& value1, const SecondType& value2)
-{
-    return jsPair(state, globalObject, toJS(&state, globalObject, value1), toJS(&state, globalObject, value2));
-}
-
 inline RefPtr<JSC::ArrayBufferView> toArrayBufferView(JSC::JSValue value)
 {
     auto* wrapper = JSC::jsDynamicCast<JSC::JSArrayBufferView*>(value);
@@ -817,13 +787,4 @@
     return toJSNewlyCreated(&state, &globalObject, value.releaseReturnValue());
 }
 
-inline JSC::JSValue toJSNullableString(JSC::ExecState& state, JSC::ThrowScope& throwScope, ExceptionOr<String>&& value)
-{
-    if (UNLIKELY(value.hasException())) {
-        propagateException(state, throwScope, value.releaseException());
-        return { };
-    }
-    return jsStringOrNull(&state, value.releaseReturnValue());
-}
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (207828 => 207829)


--- trunk/Source/WebCore/bindings/js/JSDOMConvert.h	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvert.h	2016-10-25 18:35:03 UTC (rev 207829)
@@ -164,10 +164,8 @@
         // NOTE: Handled elsewhere.
 
         // 2. Otherwise, if V is null or undefined, then return the IDL nullable type T? value null.
-        if (value.isUndefinedOrNull()) {
-            // FIXME: Should we make it part of the IDLType to provide the null value?
-            return ReturnType();
-        }
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
 
         // 3. Otherwise, return the result of converting V using the rules for the inner IDL type T.
         return Converter<T>::convert(state, value);
@@ -180,26 +178,23 @@
     static constexpr bool needsState = JSConverter<T>::needsState;
     static constexpr bool needsGlobalObject = JSConverter<T>::needsGlobalObject;
 
-    // FIXME: These only work if ImplementationType is an Optional. We should generalize
-    // this so it can work for types that don't use Optional to represent nullness, like
-    // String and interface types.
     static JSC::JSValue convert(const ImplementationType& value)
     {
-        if (!value)
+        if (T::isNullValue(value))
             return JSC::jsNull();
-        return JSConverter<T>::convert(value.value());
+        return JSConverter<T>::convert(T::extractValueFromNullable(value));
     }
     static JSC::JSValue convert(JSC::ExecState& state, const ImplementationType& value)
     {
-        if (!value)
+        if (T::isNullValue(value))
             return JSC::jsNull();
-        return JSConverter<T>::convert(state, value.value());
+        return JSConverter<T>::convert(state, T::extractValueFromNullable(value));
     }
     static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const ImplementationType& value)
     {
-        if (!value)
+        if (T::isNullValue(value))
             return JSC::jsNull();
-        return JSConverter<T>::convert(state, globalObject, value.value());
+        return JSConverter<T>::convert(state, globalObject, T::extractValueFromNullable(value));
     }
 };
 
@@ -1010,6 +1005,47 @@
 };
 
 // MARK: -
+// MARK: BufferSource type
+
+template<> struct Converter<IDLBufferSource> : DefaultConverter<IDLBufferSource> {
+    using ReturnType = BufferSource;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        if (JSC::ArrayBuffer* buffer = JSC::toArrayBuffer(value))
+            return { static_cast<uint8_t*>(buffer->data()), buffer->byteLength() };
+        if (RefPtr<JSC::ArrayBufferView> bufferView = toArrayBufferView(value))
+            return { static_cast<uint8_t*>(bufferView->baseAddress()), bufferView->byteLength() };
+
+        throwTypeError(&state, scope, ASCIILiteral("Only ArrayBuffer and ArrayBufferView objects can be passed as BufferSource arguments"));
+        return { nullptr, 0 };
+    }
+};
+
+// MARK: -
+// MARK: Date type
+
+template<> struct Converter<IDLDate> : DefaultConverter<IDLDate> {
+    static double convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return valueToDate(&state, value);
+    }
+};
+
+template<> struct JSConverter<IDLDate> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(JSC::ExecState& state, double value)
+    {
+        return jsDate(&state, value);
+    }
+};
+
+// MARK: -
 // MARK: Support for variadic tail convertions
 
 namespace Detail {
@@ -1076,25 +1112,4 @@
     return { length, WTFMove(result) };
 }
 
-// MARK: -
-// MARK: BufferSource type
-
-template<> struct Converter<IDLBufferSource> : DefaultConverter<IDLBufferSource> {
-    using ReturnType = BufferSource;
-
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        if (JSC::ArrayBuffer* buffer = JSC::toArrayBuffer(value))
-            return { static_cast<uint8_t*>(buffer->data()), buffer->byteLength() };
-        if (RefPtr<JSC::ArrayBufferView> bufferView = toArrayBufferView(value))
-            return { static_cast<uint8_t*>(bufferView->baseAddress()), bufferView->byteLength() };
-
-        throwTypeError(&state, scope, ASCIILiteral("Only ArrayBuffer and ArrayBufferView objects can be passed as BufferSource arguments"));
-        return { nullptr, 0 };
-    }
-};
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/JSDOMIterator.h (207828 => 207829)


--- trunk/Source/WebCore/bindings/js/JSDOMIterator.h	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/js/JSDOMIterator.h	2016-10-25 18:35:03 UTC (rev 207829)
@@ -24,8 +24,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef JSDOMIterator_h
-#define JSDOMIterator_h
+#pragma once
 
 #include "JSDOMBinding.h"
 #include <runtime/IteratorPrototype.h>
@@ -36,8 +35,15 @@
 
 void addValueIterableMethods(JSC::JSGlobalObject&, JSC::JSObject&);
 
-template<typename JSWrapper>
-class JSDOMIteratorPrototype : public JSC::JSNonFinalObject {
+enum class JSDOMIteratorType { Set, Map };
+
+// struct IteratorTraits {
+//     static constexpr JSDOMIteratorType type = [Map|Set];
+//     using KeyType = [IDLType|void];
+//     using ValueType = [IDLType];
+// };
+
+template<typename JSWrapper, typename IteratorTraits> class JSDOMIteratorPrototype : public JSC::JSNonFinalObject {
 public:
     using Base = JSC::JSNonFinalObject;
     using DOMWrapped = typename JSWrapper::DOMWrapped;
@@ -64,24 +70,18 @@
     void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
 };
 
-template<typename IteratorValue>
-class IteratorInspector {
-private:
-    template<typename T> static constexpr auto test(int) -> decltype(std::declval<T>()->key, std::declval<T>()->value, bool()) { return true; }
-    template<typename T> static constexpr bool test(...) { return false; }
-public:
-    static constexpr bool isMap = test<IteratorValue>(0);
-    static constexpr bool isSet = !isMap;
-};
-
 enum class IterationKind { Key, Value, KeyValue };
 
-template<typename JSWrapper>
-class JSDOMIterator: public JSDOMObject {
+template<typename JSWrapper, typename IteratorTraits> class JSDOMIterator : public JSDOMObject {
 public:
-    using DOMWrapped = typename std::remove_reference<decltype(std::declval<JSWrapper>().wrapped())>::type;
     using Base = JSDOMObject;
 
+    using Wrapper = JSWrapper;
+    using Traits = IteratorTraits;
+
+    using DOMWrapped = typename Wrapper::DOMWrapped;
+    using Prototype = JSDOMIteratorPrototype<Wrapper, Traits>;
+
     DECLARE_INFO;
 
     static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -96,10 +96,9 @@
         return instance;
     }
 
-    static JSDOMIteratorPrototype<JSWrapper>* createPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+    static Prototype* createPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
     {
-        return JSDOMIteratorPrototype<JSWrapper>::create(vm, globalObject,
-            JSDOMIteratorPrototype<JSWrapper>::createStructure(vm, globalObject, globalObject->iteratorPrototype()));
+        return Prototype::create(vm, globalObject, Prototype::createStructure(vm, globalObject, globalObject->iteratorPrototype()));
     }
 
     JSC::JSValue next(JSC::ExecState&);
@@ -112,10 +111,8 @@
     {
     }
 
-    template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isMap, JSC::JSValue>::type
-    asJS(JSC::ExecState&, IteratorValue&);
-    template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isSet, JSC::JSValue>::type
-    asJS(JSC::ExecState&, IteratorValue&);
+    template<typename IteratorValue, typename T = Traits> typename std::enable_if<T::type == JSDOMIteratorType::Map, JSC::JSValue>::type asJS(JSC::ExecState&, IteratorValue&);
+    template<typename IteratorValue, typename T = Traits> typename std::enable_if<T::type == JSDOMIteratorType::Set, JSC::JSValue>::type asJS(JSC::ExecState&, IteratorValue&);
 
     static void destroy(JSC::JSCell*);
 
@@ -123,61 +120,91 @@
     IterationKind m_kind;
 };
 
-template<typename JSWrapper>
-JSC::JSValue iteratorCreate(JSWrapper&, IterationKind);
-template<typename JSWrapper>
-JSC::JSValue iteratorForEach(JSC::ExecState&, JSWrapper&, JSC::ThrowScope&);
+inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject& globalObject, JSC::JSValue value1, JSC::JSValue value2)
+{
+    JSC::MarkedArgumentBuffer arguments;
+    arguments.append(value1);
+    arguments.append(value2);
+    return constructArray(&state, nullptr, &globalObject, arguments);
+}
 
-template<typename JSWrapper>
-JSC::JSValue iteratorCreate(JSWrapper& thisObject, IterationKind kind)
+template<typename FirstType, typename SecondType, typename T, typename U> 
+inline JSC::JSValue jsPair(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const T& value1, const U& value2)
 {
+    return jsPair(state, globalObject, toJS<FirstType>(state, globalObject, value1), toJS<SecondType>(state, globalObject, value2));
+}
+
+template<typename JSIterator>
+JSC::JSValue iteratorCreate(typename JSIterator::Wrapper&, IterationKind);
+template<typename JSIterator>
+JSC::JSValue iteratorForEach(JSC::ExecState&, typename JSIterator::Wrapper&, JSC::ThrowScope&);
+
+template<typename JSIterator>
+JSC::JSValue iteratorCreate(typename JSIterator::Wrapper& thisObject, IterationKind kind)
+{
     ASSERT(thisObject.globalObject());
     JSDOMGlobalObject& globalObject = *thisObject.globalObject();
-    return JSDOMIterator<JSWrapper>::create(globalObject.vm(), getDOMStructure<JSDOMIterator<JSWrapper>>(globalObject.vm(), globalObject), thisObject, kind);
+    return JSIterator::create(globalObject.vm(), getDOMStructure<JSIterator>(globalObject.vm(), globalObject), thisObject, kind);
 }
 
-template<typename JSWrapper>
-template<typename IteratorValue> inline typename std::enable_if<IteratorInspector<IteratorValue>::isMap, JSC::JSValue>::type
-JSDOMIterator<JSWrapper>::asJS(JSC::ExecState& state, IteratorValue& value)
+template<typename JSWrapper, typename IteratorTraits>
+template<typename IteratorValue, typename T> 
+inline typename std::enable_if<T::type == JSDOMIteratorType::Map, JSC::JSValue>::type JSDOMIterator<JSWrapper, IteratorTraits>::asJS(JSC::ExecState& state, IteratorValue& value)
 {
     ASSERT(value);
-    if (m_kind != IterationKind::KeyValue)
-        return toJS(&state, globalObject(), (m_kind == IterationKind::Key) ? value->key : value->value);
-
-    return jsPair(state, globalObject(), value->key, value->value);
+    
+    switch (m_kind) {
+    case IterationKind::Key:
+        return toJS<typename Traits::KeyType>(state, *globalObject(), value->key);
+    case IterationKind::Value:
+        return toJS<typename Traits::ValueType>(state, *globalObject(), value->value);
+    case IterationKind::KeyValue:
+        return jsPair<typename Traits::KeyType, typename Traits::ValueType>(state, *globalObject(), value->key, value->value);
+    };
+    
+    ASSERT_NOT_REACHED();
+    return { };
 }
 
-template<typename JSWrapper>
-template<typename IteratorValue> inline typename std::enable_if<IteratorInspector<IteratorValue>::isSet, JSC::JSValue>::type
-JSDOMIterator<JSWrapper>::asJS(JSC::ExecState& state, IteratorValue& value)
+template<typename JSWrapper, typename IteratorTraits>
+template<typename IteratorValue, typename T>
+inline typename std::enable_if<T::type == JSDOMIteratorType::Set, JSC::JSValue>::type JSDOMIterator<JSWrapper, IteratorTraits>::asJS(JSC::ExecState& state, IteratorValue& value)
 {
     ASSERT(value);
-    JSC::JSValue result = toJS(&state, globalObject(), *value);
-    if (m_kind != IterationKind::KeyValue)
+
+    auto globalObject = this->globalObject();
+    auto result = toJS<typename Traits::ValueType>(state, *globalObject, value);
+
+    switch (m_kind) {
+    case IterationKind::Key:
+    case IterationKind::Value:
         return result;
+    case IterationKind::KeyValue:
+        return jsPair(state, *globalObject, result, result);
+    };
 
-    return jsPair(state, globalObject(), result, result);
+    ASSERT_NOT_REACHED();
+    return { };
 }
 
-template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isMap, void>::type
-appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value)
+template<typename JSIterator, typename IteratorValue>
+typename std::enable_if<JSIterator::Traits::type == JSDOMIteratorType::Map, void>::type appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject& globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value)
 {
     ASSERT(value);
-    arguments.append(toJS(&state, globalObject, value->value));
-    arguments.append(toJS(&state, globalObject, value->key));
+    arguments.append(toJS<typename JSIterator::Traits::ValueType>(state, globalObject, value->value));
+    arguments.append(toJS<typename JSIterator::Traits::KeyType>(state, globalObject, value->key));
 }
 
-template<typename IteratorValue> typename std::enable_if<IteratorInspector<IteratorValue>::isSet, void>::type
-appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value)
+template<typename JSIterator, typename IteratorValue> 
+typename std::enable_if<JSIterator::Traits::type == JSDOMIteratorType::Set, void>::type appendForEachArguments(JSC::ExecState& state, JSDOMGlobalObject& globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value)
 {
     ASSERT(value);
-    JSC::JSValue argument = toJS(&state, globalObject, *value);
+    auto argument = toJS<typename JSIterator::Traits::ValueType>(state, globalObject, value);
     arguments.append(argument);
     arguments.append(argument);
 }
 
-template<typename JSWrapper>
-JSC::JSValue iteratorForEach(JSC::ExecState& state, JSWrapper& thisObject, JSC::ThrowScope& scope)
+template<typename JSIterator> JSC::JSValue iteratorForEach(JSC::ExecState& state, typename JSIterator::Wrapper& thisObject, JSC::ThrowScope& scope)
 {
     JSC::JSValue callback = state.argument(0);
     JSC::JSValue thisValue = state.argument(1);
@@ -190,7 +217,7 @@
     auto iterator = thisObject.wrapped().createIterator();
     while (auto value = iterator.next()) {
         JSC::MarkedArgumentBuffer arguments;
-        appendForEachArguments(state, thisObject.globalObject(), arguments, value);
+        appendForEachArguments<JSIterator>(state, *thisObject.globalObject(), arguments, value);
         arguments.append(&thisObject);
         JSC::call(&state, callback, callType, callData, thisValue, arguments);
         if (UNLIKELY(scope.exception()))
@@ -199,15 +226,15 @@
     return JSC::jsUndefined();
 }
 
-template<typename JSWrapper>
-void JSDOMIterator<JSWrapper>::destroy(JSCell* cell)
+template<typename JSWrapper, typename IteratorTraits>
+void JSDOMIterator<JSWrapper, IteratorTraits>::destroy(JSCell* cell)
 {
-    JSDOMIterator<JSWrapper>* thisObject = JSC::jsCast<JSDOMIterator<JSWrapper>*>(cell);
-    thisObject->JSDOMIterator<JSWrapper>::~JSDOMIterator();
+    JSDOMIterator<JSWrapper, IteratorTraits>* thisObject = JSC::jsCast<JSDOMIterator<JSWrapper, IteratorTraits>*>(cell);
+    thisObject->JSDOMIterator<JSWrapper, IteratorTraits>::~JSDOMIterator();
 }
 
-template<typename JSWrapper>
-JSC::JSValue JSDOMIterator<JSWrapper>::next(JSC::ExecState& state)
+template<typename JSWrapper, typename IteratorTraits>
+JSC::JSValue JSDOMIterator<JSWrapper, IteratorTraits>::next(JSC::ExecState& state)
 {
     if (m_iterator) {
         auto iteratorValue = m_iterator->next();
@@ -218,13 +245,13 @@
     return createIteratorResultObject(&state, JSC::jsUndefined(), true);
 }
 
-template<typename JSWrapper>
-JSC::EncodedJSValue JSC_HOST_CALL JSDOMIteratorPrototype<JSWrapper>::next(JSC::ExecState* state)
+template<typename JSWrapper, typename IteratorTraits>
+JSC::EncodedJSValue JSC_HOST_CALL JSDOMIteratorPrototype<JSWrapper, IteratorTraits>::next(JSC::ExecState* state)
 {
     JSC::VM& vm = state->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    auto iterator = JSC::jsDynamicCast<JSDOMIterator<JSWrapper>*>(state->thisValue());
+    auto iterator = JSC::jsDynamicCast<JSDOMIterator<JSWrapper, IteratorTraits>*>(state->thisValue());
     if (!iterator)
         return JSC::JSValue::encode(throwTypeError(state, scope, ASCIILiteral("Cannot call next() on a non-Iterator object")));
 
@@ -231,8 +258,8 @@
     return JSC::JSValue::encode(iterator->next(*state));
 }
 
-template<typename JSWrapper>
-void JSDOMIteratorPrototype<JSWrapper>::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+template<typename JSWrapper, typename IteratorTraits>
+void JSDOMIteratorPrototype<JSWrapper, IteratorTraits>::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
@@ -241,5 +268,3 @@
 }
 
 }
-
-#endif // !defined(JSDOMIterator_h)

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (207828 => 207829)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-10-25 18:35:03 UTC (rev 207829)
@@ -4865,15 +4865,29 @@
 
     return unless IsKeyValueIterableInterface($interface);
 
+    my $iteratorName = "${interfaceName}Iterator";
+    my $iteratorPrototypeName = "${interfaceName}IteratorPrototype";
+
+    my $iteratorTraitsName = "${interfaceName}IteratorTraits";
+    my $iteratorTraitsType = $interface->iterable->isKeyValue ? "JSDOMIteratorType::Map" : "JSDOMIteratorType::Set";
+    my $iteratorTraitsKeyType = $interface->iterable->isKeyValue ? GetIDLType($interface, $interface->iterable->idlKeyType) : "void";
+    my $iteratorTraitsValueType = GetIDLType($interface, $interface->iterable->idlValueType);
+
     push(@implContent,  <<END);
-using ${interfaceName}Iterator = JSDOMIterator<${className}>;
-using ${interfaceName}IteratorPrototype = JSDOMIteratorPrototype<${className}>;
+struct ${iteratorTraitsName} {
+    static constexpr JSDOMIteratorType type = ${iteratorTraitsType};
+    using KeyType = ${iteratorTraitsKeyType};
+    using ValueType = ${iteratorTraitsValueType};
+};
 
+using ${iteratorName} = JSDOMIterator<${className}, ${iteratorTraitsName}>;
+using ${iteratorPrototypeName} = JSDOMIteratorPrototype<${className}, ${iteratorTraitsName}>;
+
 template<>
-const JSC::ClassInfo ${interfaceName}Iterator::s_info = { "${visibleInterfaceName} Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(${interfaceName}Iterator) };
+const JSC::ClassInfo ${iteratorName}::s_info = { "${visibleInterfaceName} Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(${iteratorName}) };
 
 template<>
-const JSC::ClassInfo ${interfaceName}IteratorPrototype::s_info = { "${visibleInterfaceName} Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(${interfaceName}IteratorPrototype) };
+const JSC::ClassInfo ${iteratorPrototypeName}::s_info = { "${visibleInterfaceName} Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(${iteratorPrototypeName}) };
 
 END
 
@@ -4885,7 +4899,7 @@
             push(@implContent,  <<END);
 static inline EncodedJSValue ${functionName}Caller(ExecState* state, JS$interfaceName* thisObject, JSC::ThrowScope& throwScope)
 {
-    return JSValue::encode(iteratorForEach<${className}>(*state, *thisObject, throwScope));
+    return JSValue::encode(iteratorForEach<${iteratorName}>(*state, *thisObject, throwScope));
 }
 
 END
@@ -4898,7 +4912,7 @@
             push(@implContent,  <<END);
 static inline EncodedJSValue ${functionName}Caller(ExecState*, JS$interfaceName* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<${className}>(*thisObject, IterationKind::${iterationKind}));
+    return JSValue::encode(iteratorCreate<${iteratorName}>(*thisObject, IterationKind::${iterationKind}));
 }
 
 END
@@ -5047,6 +5061,10 @@
         "DOMString" => "IDLDOMString",
         "ByteString" => "IDLByteString",
         "USVString" => "IDLUSVString",
+        
+        # Non-WebIDL extensions
+        "Date" => "IDLDate",
+        "BufferSource" => "IDLBufferSource",
     );
 
     return $IDLTypes{$idlType->name} if exists $IDLTypes{$idlType->name};
@@ -5055,7 +5073,6 @@
     return "IDLSequence<" . GetIDLType($interface, @{$idlType->subtypes}[0]) . ">" if $codeGenerator->IsSequenceType($idlType->name);
     return "IDLFrozenArray<" . GetIDLType($interface, @{$idlType->subtypes}[0]) . ">" if $codeGenerator->IsFrozenArrayType($idlType->name);
     return "IDLUnion<" . join(", ", GetIDLUnionMemberTypes($interface, $idlType)) . ">" if $idlType->isUnion;
-    return "IDLBufferSource" if $idlType->name eq "BufferSource";
     return "IDLInterface<" . $idlType->name . ">";
 }
 
@@ -5177,9 +5194,10 @@
     my $idlType = shift;
 
     return 1 if $idlType->isUnion;
-    return 1 if $idlType->name eq "BufferSource";
     return 1 if $idlType->name eq "any";
     return 1 if $idlType->name eq "boolean";
+    return 1 if $idlType->name eq "Date";
+    return 1 if $idlType->name eq "BufferSource";
     return 1 if $codeGenerator->IsIntegerType($idlType->name);
     return 1 if $codeGenerator->IsFloatingPointType($idlType->name);
     return 1 if $codeGenerator->IsSequenceOrFrozenArrayType($idlType->name);
@@ -5241,7 +5259,6 @@
         return ("Dictionary($statePointer, $value)", 0);
     }
 
-    return ("valueToDate($statePointer, $value)", 1) if $type eq "Date";
     return ("to$type($value)", 1) if $codeGenerator->IsTypedArrayType($type);
     return ("parseEnumeration<" . GetEnumerationClassName($type, $interface) . ">($stateReference, $value)", 1) if $codeGenerator->IsEnumType($type);
 
@@ -5258,11 +5275,10 @@
 sub NativeToJSValueIsHandledByDOMConvert
 {
     my ($idlType) = @_;
-
-    return 0 if $idlType->isNullable && ($codeGenerator->IsStringType($idlType->name) || $codeGenerator->IsEnumType($idlType->name));
     
     return 1 if $idlType->name eq "any";
     return 1 if $idlType->name eq "boolean";
+    return 1 if $idlType->name eq "Date";
     return 1 if $codeGenerator->IsIntegerType($idlType->name);
     return 1 if $codeGenerator->IsFloatingPointType($idlType->name);
     return 1 if $codeGenerator->IsStringType($idlType->name);
@@ -5282,6 +5298,7 @@
     return 1 if $codeGenerator->IsSequenceOrFrozenArrayType($idlType->name);
     return 1 if $codeGenerator->IsStringType($idlType->name);
     return 1 if $codeGenerator->IsEnumType($idlType->name);
+    return 1 if $idlType->name eq "Date";
 
     return 0;
 }
@@ -5360,18 +5377,6 @@
         return "toJS<$IDLType>(" . join(", ", @conversionArguments) . ")";
     }
 
-    return "toJSNullableDate($stateReference, throwScope, $value)" if $type eq "Date" && $isNullable && $mayThrowException;
-    return "jsDateOrNull($statePointer, $value)" if $type eq "Date" && $isNullable;
-    return "toJSDate($stateReference, throwScope, $value)" if $type eq "Date" && $mayThrowException;
-    return "jsDate($statePointer, $value)" if $type eq "Date";
-
-    if ($codeGenerator->IsStringType($type)) {
-        AddToImplIncludes("URL.h", $conditional);
-        return "toJSNullableString($stateReference, throwScope, $value)" if $isNullable && $mayThrowException;
-        return "jsStringOrNull($statePointer, $value)" if $isNullable;
-        assert("Unhandled string type");
-    }
-
     if ($type eq "SerializedScriptValue") {
         AddToImplIncludes("SerializedScriptValue.h", $conditional);
         return "$value ? $value->deserialize($stateReference, $globalObject) : jsNull()";

Modified: trunk/Source/WebCore/bindings/scripts/IDLParser.pm (207828 => 207829)


--- trunk/Source/WebCore/bindings/scripts/IDLParser.pm	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/scripts/IDLParser.pm	2016-10-25 18:35:03 UTC (rev 207829)
@@ -103,8 +103,10 @@
 # Used to represent Iterable interfaces
 struct( domIterable => {
     isKeyValue => '$',# Is map iterable or set iterable
-    keyType => '$',   # Key type for map iterables
-    valueType => '$', # Value type for map or set iterables
+    keyType => '$',   # Key type name for map iterables (DEPRECATED - please use idlKeyType)
+    valueType => '$', # Value type name for map or set iterables (DEPRECATED - please use idlValueType)
+    idlKeyType => '$',   # Key type for map iterables
+    idlValueType => '$', # Value type for map or set iterables
     functions => '@', # Iterable functions (entries, keys, values, [Symbol.Iterator], forEach)
     extendedAttributes => '$', # Extended attributes
 });
@@ -1514,15 +1516,21 @@
     push(@{$newDataNode->functions}, $forEachFunction);
 
     $self->assertTokenValue($self->getToken(), "<", __LINE__);
-    my $type1 = $self->getToken()->value();
+    my $type1 = $self->parseType();
+
     if ($self->nextToken()->value() eq ",") {
         $self->assertTokenValue($self->getToken(), ",", __LINE__);
+
+        my $type2 = $self->parseType();
         $newDataNode->isKeyValue(1);
-        $newDataNode->keyType($type1);
-        $newDataNode->valueType($self->getToken()->value());
+        $newDataNode->idlKeyType($type1);
+        $newDataNode->keyType($type1->name);
+        $newDataNode->idlValueType($type2);
+        $newDataNode->valueType($type2->name);
     } else {
         $newDataNode->isKeyValue(0);
-        $newDataNode->valueType($type1);
+        $newDataNode->idlValueType($type1);
+        $newDataNode->valueType($type1->name);
     }
     $self->assertTokenValue($self->getToken(), ">", __LINE__);
 

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIterable.cpp (207828 => 207829)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIterable.cpp	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIterable.cpp	2016-10-25 18:35:03 UTC (rev 207829)
@@ -163,9 +163,15 @@
     return getDOMConstructor<JSTestIterableConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
 }
 
-using TestIterableIterator = JSDOMIterator<JSTestIterable>;
-using TestIterableIteratorPrototype = JSDOMIteratorPrototype<JSTestIterable>;
+struct TestIterableIteratorTraits {
+    static constexpr JSDOMIteratorType type = JSDOMIteratorType::Set;
+    using KeyType = void;
+    using ValueType = IDLInterface<TestNode>;
+};
 
+using TestIterableIterator = JSDOMIterator<JSTestIterable, TestIterableIteratorTraits>;
+using TestIterableIteratorPrototype = JSDOMIteratorPrototype<JSTestIterable, TestIterableIteratorTraits>;
+
 template<>
 const JSC::ClassInfo TestIterableIterator::s_info = { "TestIterable Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(TestIterableIterator) };
 
@@ -174,7 +180,7 @@
 
 static inline EncodedJSValue jsTestIterablePrototypeFunctionSymbolIteratorCaller(ExecState*, JSTestIterable* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<JSTestIterable>(*thisObject, IterationKind::Value));
+    return JSValue::encode(iteratorCreate<TestIterableIterator>(*thisObject, IterationKind::Value));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionSymbolIterator(JSC::ExecState* state)
@@ -184,7 +190,7 @@
 
 static inline EncodedJSValue jsTestIterablePrototypeFunctionEntriesCaller(ExecState*, JSTestIterable* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<JSTestIterable>(*thisObject, IterationKind::KeyValue));
+    return JSValue::encode(iteratorCreate<TestIterableIterator>(*thisObject, IterationKind::KeyValue));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionEntries(JSC::ExecState* state)
@@ -194,7 +200,7 @@
 
 static inline EncodedJSValue jsTestIterablePrototypeFunctionKeysCaller(ExecState*, JSTestIterable* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<JSTestIterable>(*thisObject, IterationKind::Key));
+    return JSValue::encode(iteratorCreate<TestIterableIterator>(*thisObject, IterationKind::Key));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionKeys(JSC::ExecState* state)
@@ -204,7 +210,7 @@
 
 static inline EncodedJSValue jsTestIterablePrototypeFunctionValuesCaller(ExecState*, JSTestIterable* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<JSTestIterable>(*thisObject, IterationKind::Value));
+    return JSValue::encode(iteratorCreate<TestIterableIterator>(*thisObject, IterationKind::Value));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionValues(JSC::ExecState* state)
@@ -214,7 +220,7 @@
 
 static inline EncodedJSValue jsTestIterablePrototypeFunctionForEachCaller(ExecState* state, JSTestIterable* thisObject, JSC::ThrowScope& throwScope)
 {
-    return JSValue::encode(iteratorForEach<JSTestIterable>(*state, *thisObject, throwScope));
+    return JSValue::encode(iteratorForEach<TestIterableIterator>(*state, *thisObject, throwScope));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionForEach(JSC::ExecState* state)

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp (207828 => 207829)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp	2016-10-25 18:35:03 UTC (rev 207829)
@@ -264,9 +264,15 @@
     return JSValue::encode(jsUndefined());
 }
 
-using TestNodeIterator = JSDOMIterator<JSTestNode>;
-using TestNodeIteratorPrototype = JSDOMIteratorPrototype<JSTestNode>;
+struct TestNodeIteratorTraits {
+    static constexpr JSDOMIteratorType type = JSDOMIteratorType::Set;
+    using KeyType = void;
+    using ValueType = IDLInterface<TestNode>;
+};
 
+using TestNodeIterator = JSDOMIterator<JSTestNode, TestNodeIteratorTraits>;
+using TestNodeIteratorPrototype = JSDOMIteratorPrototype<JSTestNode, TestNodeIteratorTraits>;
+
 template<>
 const JSC::ClassInfo TestNodeIterator::s_info = { "TestNode Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(TestNodeIterator) };
 
@@ -275,7 +281,7 @@
 
 static inline EncodedJSValue jsTestNodePrototypeFunctionSymbolIteratorCaller(ExecState*, JSTestNode* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<JSTestNode>(*thisObject, IterationKind::Value));
+    return JSValue::encode(iteratorCreate<TestNodeIterator>(*thisObject, IterationKind::Value));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionSymbolIterator(JSC::ExecState* state)
@@ -285,7 +291,7 @@
 
 static inline EncodedJSValue jsTestNodePrototypeFunctionEntriesCaller(ExecState*, JSTestNode* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<JSTestNode>(*thisObject, IterationKind::KeyValue));
+    return JSValue::encode(iteratorCreate<TestNodeIterator>(*thisObject, IterationKind::KeyValue));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionEntries(JSC::ExecState* state)
@@ -295,7 +301,7 @@
 
 static inline EncodedJSValue jsTestNodePrototypeFunctionKeysCaller(ExecState*, JSTestNode* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<JSTestNode>(*thisObject, IterationKind::Key));
+    return JSValue::encode(iteratorCreate<TestNodeIterator>(*thisObject, IterationKind::Key));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionKeys(JSC::ExecState* state)
@@ -305,7 +311,7 @@
 
 static inline EncodedJSValue jsTestNodePrototypeFunctionValuesCaller(ExecState*, JSTestNode* thisObject, JSC::ThrowScope&)
 {
-    return JSValue::encode(iteratorCreate<JSTestNode>(*thisObject, IterationKind::Value));
+    return JSValue::encode(iteratorCreate<TestNodeIterator>(*thisObject, IterationKind::Value));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionValues(JSC::ExecState* state)
@@ -315,7 +321,7 @@
 
 static inline EncodedJSValue jsTestNodePrototypeFunctionForEachCaller(ExecState* state, JSTestNode* thisObject, JSC::ThrowScope& throwScope)
 {
-    return JSValue::encode(iteratorForEach<JSTestNode>(*state, *thisObject, throwScope));
+    return JSValue::encode(iteratorForEach<TestNodeIterator>(*state, *thisObject, throwScope));
 }
 
 JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionForEach(JSC::ExecState* state)

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (207828 => 207829)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-10-25 18:00:59 UTC (rev 207828)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-10-25 18:35:03 UTC (rev 207829)
@@ -3130,7 +3130,7 @@
     UNUSED_PARAM(throwScope);
     UNUSED_PARAM(state);
     auto& impl = thisObject.wrapped();
-    JSValue result = jsStringOrNull(&state, impl.nullableStringAttribute());
+    JSValue result = toJS<IDLNullable<IDLDOMString>>(state, impl.nullableStringAttribute());
     return result;
 }
 
@@ -3162,7 +3162,7 @@
     UNUSED_PARAM(throwScope);
     UNUSED_PARAM(state);
     auto& impl = thisObject.wrapped();
-    JSValue result = jsStringOrNull(&state, impl.nullableStringSettableAttribute());
+    JSValue result = toJS<IDLNullable<IDLDOMString>>(state, impl.nullableStringSettableAttribute());
     return result;
 }
 
@@ -3178,7 +3178,7 @@
     UNUSED_PARAM(throwScope);
     UNUSED_PARAM(state);
     auto& impl = thisObject.wrapped();
-    JSValue result = jsStringOrNull(&state, impl.nullableUSVStringSettableAttribute());
+    JSValue result = toJS<IDLNullable<IDLUSVString>>(state, impl.nullableUSVStringSettableAttribute());
     return result;
 }
 
@@ -5128,7 +5128,7 @@
     UNUSED_PARAM(state);
     UNUSED_PARAM(throwScope);
     auto& impl = castedThis->wrapped();
-    JSValue result = jsStringOrNull(state, impl.nullableStringMethod());
+    JSValue result = toJS<IDLNullable<IDLDOMString>>(*state, impl.nullableStringMethod());
     return JSValue::encode(result);
 }
 
@@ -5137,7 +5137,7 @@
     VM& vm = state->vm();
     auto throwScope = DECLARE_THROW_SCOPE(vm);
     UNUSED_PARAM(throwScope);
-    JSValue result = jsStringOrNull(state, TestObj::nullableStringStaticMethod());
+    JSValue result = toJS<IDLNullable<IDLDOMString>>(*state, TestObj::nullableStringStaticMethod());
     return JSValue::encode(result);
 }
 
@@ -5157,7 +5157,7 @@
         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
     auto index = convert<IDLUnsignedLong>(*state, state->uncheckedArgument(0), NormalConversion);
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    JSValue result = jsStringOrNull(state, impl.nullableStringSpecialMethod(WTFMove(index)));
+    JSValue result = toJS<IDLNullable<IDLDOMString>>(*state, impl.nullableStringSpecialMethod(WTFMove(index)));
     return JSValue::encode(result);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to