<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[207829] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/207829">207829</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2016-10-25 11:35:03 -0700 (Tue, 25 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[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&lt;IDLNullable&lt;T&gt;&gt;::convert):
Use new functions to detect and extract nullable values.

(WebCore::Converter&lt;IDLBufferSource&gt;::convert):
Moved to be with the other converters.

(WebCore::Converter&lt;IDLDate&gt;::convert):
(WebCore::JSConverter&lt;IDLDate&gt;::convert):
Added.

* bindings/js/JSDOMIterator.h:
(WebCore::jsPair):
(WebCore::iteratorCreate):
(WebCore::IteratorTraits&gt;::asJS):
(WebCore::appendForEachArguments):
(WebCore::iteratorForEach):
(WebCore::IteratorTraits&gt;::destroy):
(WebCore::IteratorTraits&gt;::next):
(WebCore::IteratorTraits&gt;::finishCreation):
(WebCore::IteratorInspector::decltype): Deleted.
(WebCore::IteratorInspector::test): Deleted.
(WebCore::JSDOMIterator&lt;JSWrapper&gt;::asJS): Deleted.
(WebCore::JSDOMIterator&lt;JSWrapper&gt;::destroy): Deleted.
(WebCore::JSDOMIterator&lt;JSWrapper&gt;::next): Deleted.
(WebCore::JSDOMIteratorPrototype&lt;JSWrapper&gt;::next): Deleted.
(WebCore::JSDOMIteratorPrototype&lt;JSWrapper&gt;::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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulespluginsQuickTimePluginReplacementmm">trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm</a></li>
<li><a href="#trunkSourceWebCorebindingsgenericIDLTypesh">trunk/Source/WebCore/bindings/generic/IDLTypes.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp">trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSCSSStyleDeclarationCustomcpp">trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSCustomElementInterfacecpp">trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingcpp">trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingh">trunk/Source/WebCore/bindings/js/JSDOMBinding.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMConverth">trunk/Source/WebCore/bindings/js/JSDOMConvert.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMIteratorh">trunk/Source/WebCore/bindings/js/JSDOMIterator.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptsIDLParserpm">trunk/Source/WebCore/bindings/scripts/IDLParser.pm</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestIterablecpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIterable.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestNodecpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,114 @@
</span><ins>+2016-10-24  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        [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&lt;IDLNullable&lt;T&gt;&gt;::convert):
+        Use new functions to detect and extract nullable values.
+
+        (WebCore::Converter&lt;IDLBufferSource&gt;::convert):
+        Moved to be with the other converters.
+
+        (WebCore::Converter&lt;IDLDate&gt;::convert):
+        (WebCore::JSConverter&lt;IDLDate&gt;::convert):
+        Added.
+
+        * bindings/js/JSDOMIterator.h:
+        (WebCore::jsPair):
+        (WebCore::iteratorCreate):
+        (WebCore::IteratorTraits&gt;::asJS):
+        (WebCore::appendForEachArguments):
+        (WebCore::iteratorForEach):
+        (WebCore::IteratorTraits&gt;::destroy):
+        (WebCore::IteratorTraits&gt;::next):
+        (WebCore::IteratorTraits&gt;::finishCreation):
+        (WebCore::IteratorInspector::decltype): Deleted.
+        (WebCore::IteratorInspector::test): Deleted.
+        (WebCore::JSDOMIterator&lt;JSWrapper&gt;::asJS): Deleted.
+        (WebCore::JSDOMIterator&lt;JSWrapper&gt;::destroy): Deleted.
+        (WebCore::JSDOMIterator&lt;JSWrapper&gt;::next): Deleted.
+        (WebCore::JSDOMIteratorPrototype&lt;JSWrapper&gt;::next): Deleted.
+        (WebCore::JSDOMIteratorPrototype&lt;JSWrapper&gt;::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.
+
</ins><span class="cx"> 2016-10-25  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [MediaStream] Add &quot;has capture device&quot; bit to media state flags
</span></span></pre></div>
<a id="trunkSourceWebCoreModulespluginsQuickTimePluginReplacementmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -210,8 +210,8 @@
</span><span class="cx">     argList.append(toJS(exec, globalObject, &amp;root));
</span><span class="cx">     argList.append(toJS(exec, globalObject, m_parentElement));
</span><span class="cx">     argList.append(toJS(exec, globalObject, this));
</span><del>-    argList.append(toJS&lt;String&gt;(exec, globalObject, m_names));
-    argList.append(toJS&lt;String&gt;(exec, globalObject, m_values));
</del><ins>+    argList.append(toJS&lt;IDLSequence&lt;IDLNullable&lt;IDLDOMString&gt;&gt;&gt;(*exec, *globalObject, m_names));
+    argList.append(toJS&lt;IDLSequence&lt;IDLNullable&lt;IDLDOMString&gt;&gt;&gt;(*exec, *globalObject, m_values));
</ins><span class="cx">     JSC::JSValue replacement = call(exec, replacementObject, callType, callData, globalObject, argList);
</span><span class="cx">     if (UNLIKELY(scope.exception())) {
</span><span class="cx">         scope.clearException();
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsgenericIDLTypesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/generic/IDLTypes.h (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -41,11 +41,13 @@
</span><span class="cx"> template&lt;typename T&gt;
</span><span class="cx"> struct IDLType {
</span><span class="cx">     using ImplementationType = T;
</span><ins>+
</ins><span class="cx">     using NullableType = Optional&lt;ImplementationType&gt;;
</span><ins>+    static NullableType nullValue() { return Nullopt; }
+    static bool isNullValue(const NullableType&amp; value) { return !value; }
+    static ImplementationType extractValueFromNullable(const NullableType&amp; value) { return value.value(); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-struct IDLDummy;
-
</del><span class="cx"> // IDLUnsupportedType is a special type that serves as a base class for currently unsupported types.
</span><span class="cx"> struct IDLUnsupportedType : IDLType&lt;void&gt; { };
</span><span class="cx"> 
</span><span class="lines">@@ -78,6 +80,9 @@
</span><span class="cx"> 
</span><span class="cx"> struct IDLString : IDLType&lt;String&gt; {
</span><span class="cx">     using NullableType = String;
</span><ins>+    static String nullValue() { return String(); }
+    static bool isNullValue(const String&amp; value) { return value.isNull(); }
+    static const String&amp; extractValueFromNullable(const String&amp; value) { return value; }
</ins><span class="cx"> };
</span><span class="cx"> struct IDLDOMString : IDLString { };
</span><span class="cx"> struct IDLByteString : IDLUnsupportedType { };
</span><span class="lines">@@ -87,7 +92,11 @@
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt; struct IDLInterface : IDLType&lt;RefPtr&lt;T&gt;&gt; {
</span><span class="cx">     using RawType = T;
</span><ins>+
</ins><span class="cx">     using NullableType = RefPtr&lt;T&gt;;
</span><ins>+    static RefPtr&lt;T&gt; nullValue() { return nullptr; }
+    static bool isNullValue(const RefPtr&lt;T&gt;&amp; value) { return !value; }
+    static const RefPtr&lt;T&gt;&amp; extractValueFromNullable(const RefPtr&lt;T&gt;&amp; value) { return value; }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt; struct IDLDictionary : IDLType&lt;T&gt; { };
</span><span class="lines">@@ -119,6 +128,15 @@
</span><span class="cx">     using TypeList = brigand::list&lt;Ts...&gt;;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+// Non-WebIDL extensions
+
+struct IDLDate : IDLType&lt;double&gt; { 
+    using NullableType = double;
+    static double nullValue() { return std::numeric_limits&lt;double&gt;::quiet_NaN(); }
+    static bool isNullValue(double value) { return std::isnan(value); }
+    static double extractValueFromNullable(double value) { return value; }
+};
+
</ins><span class="cx"> struct IDLBufferSource : IDLType&lt;BufferSource&gt; { };
</span><span class="cx"> 
</span><span class="cx"> // Helper predicates
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -107,9 +107,9 @@
</span><span class="cx">     case KeyType::String:
</span><span class="cx">         return jsStringWithCache(&amp;state, key-&gt;string());
</span><span class="cx">     case KeyType::Date:
</span><del>-        // FIXME: This should probably be jsDate() as per:
</del><ins>+        // FIXME: This should probably be toJS&lt;IDLDate&gt;(...) as per:
</ins><span class="cx">         // http://w3c.github.io/IndexedDB/#request-convert-a-key-to-a-value
</span><del>-        return jsDateOrNull(&amp;state, key-&gt;date());
</del><ins>+        return toJS&lt;IDLNullable&lt;IDLDate&gt;&gt;(state, key-&gt;date());
</ins><span class="cx">     case KeyType::Number:
</span><span class="cx">         return jsNumber(key-&gt;number());
</span><span class="cx">     case KeyType::Min:
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSCSSStyleDeclarationCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -283,9 +283,9 @@
</span><span class="cx"> static inline JSValue stylePropertyGetter(ExecState&amp; state, JSCSSStyleDeclaration&amp; thisObject, CSSPropertyID propertyID, const RefPtr&lt;CSSValue&gt;&amp; value)
</span><span class="cx"> {
</span><span class="cx">     if (value)
</span><del>-        return jsStringOrNull(&amp;state, value-&gt;cssText());
</del><ins>+        return toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(state, value-&gt;cssText());
</ins><span class="cx">     // If the property is a shorthand property (such as &quot;padding&quot;), it can only be accessed using getPropertyValue.
</span><del>-    return jsStringWithCache(&amp;state, thisObject.wrapped().getPropertyValueInternal(propertyID));
</del><ins>+    return toJS&lt;IDLDOMString&gt;(state, thisObject.wrapped().getPropertyValueInternal(propertyID));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline JSValue stylePropertyGetter(ExecState&amp; state, JSCSSStyleDeclaration&amp; thisObject, CSSPropertyID propertyID)
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSCustomElementInterfacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -289,10 +289,10 @@
</span><span class="cx"> void JSCustomElementInterface::invokeAttributeChangedCallback(Element&amp; element, const QualifiedName&amp; attributeName, const AtomicString&amp; oldValue, const AtomicString&amp; newValue)
</span><span class="cx"> {
</span><span class="cx">     invokeCallback(element, m_attributeChangedCallback.get(), [&amp;](ExecState* state, JSDOMGlobalObject*, MarkedArgumentBuffer&amp; args) {
</span><del>-        args.append(jsStringWithCache(state, attributeName.localName()));
-        args.append(jsStringOrNull(state, oldValue));
-        args.append(jsStringOrNull(state, newValue));
-        args.append(jsStringOrNull(state, attributeName.namespaceURI()));
</del><ins>+        args.append(toJS&lt;IDLDOMString&gt;(*state, attributeName.localName()));
+        args.append(toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(*state, oldValue));
+        args.append(toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(*state, newValue));
+        args.append(toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(*state, attributeName.namespaceURI()));
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -64,13 +64,6 @@
</span><span class="cx">     JSDOMWindow::commonVM().addImpureProperty(propertyName);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSValue jsStringOrNull(ExecState* exec, const String&amp; s)
-{
-    if (s.isNull())
-        return jsNull();
-    return jsStringWithCache(exec, s);
-}
-
</del><span class="cx"> JSValue jsOwnedStringOrNull(ExecState* exec, const String&amp; s)
</span><span class="cx"> {
</span><span class="cx">     if (s.isNull())
</span><span class="lines">@@ -90,13 +83,6 @@
</span><span class="cx">     return jsStringWithCache(exec, url.string());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSValue jsStringOrNull(ExecState* exec, const URL&amp; url)
-{
-    if (url.isNull())
-        return jsNull();
-    return jsStringWithCache(exec, url.string());
-}
-
</del><span class="cx"> JSValue jsStringOrUndefined(ExecState* exec, const URL&amp; url)
</span><span class="cx"> {
</span><span class="cx">     if (url.isNull())
</span><span class="lines">@@ -171,14 +157,6 @@
</span><span class="cx">     return DateInstance::create(exec-&gt;vm(), exec-&gt;lexicalGlobalObject()-&gt;dateStructure(), value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-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-&gt;vm(), exec-&gt;lexicalGlobalObject()-&gt;dateStructure(), value);
-}
-
</del><span class="cx"> double valueToDate(ExecState* exec, JSValue value)
</span><span class="cx"> {
</span><span class="cx">     if (value.isNumber())
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -202,9 +202,6 @@
</span><span class="cx"> 
</span><span class="cx"> JSC::JSValue jsString(JSC::ExecState*, const URL&amp;); // empty if the URL is null
</span><span class="cx"> 
</span><del>-JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&amp;); // null if the string is null
-JSC::JSValue jsStringOrNull(JSC::ExecState*, const URL&amp;); // null if the URL is null
-
</del><span class="cx"> JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const String&amp;); // undefined if the string is null
</span><span class="cx"> JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const URL&amp;); // undefined if the URL is null
</span><span class="cx"> 
</span><span class="lines">@@ -257,7 +254,6 @@
</span><span class="cx"> WEBCORE_EXPORT uint64_t toUInt64(JSC::ExecState&amp;, JSC::JSValue);
</span><span class="cx"> 
</span><span class="cx"> JSC::JSValue jsDate(JSC::ExecState*, double value);
</span><del>-JSC::JSValue jsDateOrNull(JSC::ExecState*, double value);
</del><span class="cx"> 
</span><span class="cx"> // NaN if the value can't be converted to a date.
</span><span class="cx"> double valueToDate(JSC::ExecState*, JSC::JSValue);
</span><span class="lines">@@ -273,17 +269,12 @@
</span><span class="cx"> template&lt;typename T&gt; JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, RefPtr&lt;T&gt;&amp;&amp;);
</span><span class="cx"> template&lt;typename T&gt; JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const Vector&lt;T&gt;&amp;);
</span><span class="cx"> template&lt;typename T&gt; JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const Vector&lt;RefPtr&lt;T&gt;&gt;&amp;);
</span><del>-JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const String&amp;);
</del><span class="cx"> JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, const JSC::PrivateName&amp;);
</span><span class="cx"> 
</span><span class="cx"> JSC::JSValue toJSIterator(JSC::ExecState&amp;, JSDOMGlobalObject&amp;, JSC::JSValue);
</span><span class="cx"> template&lt;typename T&gt; JSC::JSValue toJSIterator(JSC::ExecState&amp;, JSDOMGlobalObject&amp;, const T&amp;);
</span><del>-
</del><span class="cx"> JSC::JSValue toJSIteratorEnd(JSC::ExecState&amp;);
</span><span class="cx"> 
</span><del>-JSC::JSValue jsPair(JSC::ExecState&amp;, JSDOMGlobalObject*, JSC::JSValue, JSC::JSValue);
-template&lt;typename FirstType, typename SecondType&gt; JSC::JSValue jsPair(JSC::ExecState&amp;, JSDOMGlobalObject*, const FirstType&amp;, const SecondType&amp;);
-
</del><span class="cx"> RefPtr&lt;JSC::ArrayBufferView&gt; toArrayBufferView(JSC::JSValue);
</span><span class="cx"> RefPtr&lt;JSC::Int8Array&gt; toInt8Array(JSC::JSValue);
</span><span class="cx"> RefPtr&lt;JSC::Int16Array&gt; toInt16Array(JSC::JSValue);
</span><span class="lines">@@ -405,9 +396,6 @@
</span><span class="cx"> // ExceptionOr handling.
</span><span class="cx"> void propagateException(JSC::ExecState&amp;, JSC::ThrowScope&amp;, ExceptionOr&lt;void&gt;&amp;&amp;);
</span><span class="cx"> template&lt;typename T&gt; JSC::JSValue toJS(JSC::ExecState&amp;, JSDOMGlobalObject&amp;, JSC::ThrowScope&amp;, ExceptionOr&lt;T&gt;&amp;&amp;);
</span><del>-JSC::JSValue toJSDate(JSC::ExecState&amp;, JSC::ThrowScope&amp;, ExceptionOr&lt;double&gt;&amp;&amp;);
-JSC::JSValue toJSNullableDate(JSC::ExecState&amp;, JSC::ThrowScope&amp;, ExceptionOr&lt;Optional&lt;double&gt;&gt;&amp;&amp;);
-JSC::JSValue toJSNullableString(JSC::ExecState&amp;, JSC::ThrowScope&amp;, ExceptionOr&lt;String&gt;&amp;&amp;);
</del><span class="cx"> template&lt;typename T&gt; JSC::JSValue toJSNewlyCreated(JSC::ExecState&amp;, JSDOMGlobalObject&amp;, JSC::ThrowScope&amp;, ExceptionOr&lt;T&gt;&amp;&amp; value);
</span><span class="cx"> 
</span><span class="cx"> // Inline functions and template definitions.
</span><span class="lines">@@ -683,11 +671,6 @@
</span><span class="cx">     return array;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject*, const String&amp; value)
-{
-    return jsStringOrNull(exec, value);
-}
-
</del><span class="cx"> inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject*, const JSC::PrivateName&amp; privateName)
</span><span class="cx"> {
</span><span class="cx">     return JSC::Symbol::create(exec-&gt;vm(), privateName.uid());
</span><span class="lines">@@ -708,19 +691,6 @@
</span><span class="cx">     return createIteratorResultObject(&amp;state, JSC::jsUndefined(), true);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline JSC::JSValue jsPair(JSC::ExecState&amp; state, JSDOMGlobalObject* globalObject, JSC::JSValue value1, JSC::JSValue value2)
-{
-    JSC::MarkedArgumentBuffer args;
-    args.append(value1);
-    args.append(value2);
-    return constructArray(&amp;state, 0, globalObject, args);
-}
-
-template&lt;typename FirstType, typename SecondType&gt; inline JSC::JSValue jsPair(JSC::ExecState&amp; state, JSDOMGlobalObject* globalObject, const FirstType&amp; value1, const SecondType&amp; value2)
-{
-    return jsPair(state, globalObject, toJS(&amp;state, globalObject, value1), toJS(&amp;state, globalObject, value2));
-}
-
</del><span class="cx"> inline RefPtr&lt;JSC::ArrayBufferView&gt; toArrayBufferView(JSC::JSValue value)
</span><span class="cx"> {
</span><span class="cx">     auto* wrapper = JSC::jsDynamicCast&lt;JSC::JSArrayBufferView*&gt;(value);
</span><span class="lines">@@ -817,13 +787,4 @@
</span><span class="cx">     return toJSNewlyCreated(&amp;state, &amp;globalObject, value.releaseReturnValue());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline JSC::JSValue toJSNullableString(JSC::ExecState&amp; state, JSC::ThrowScope&amp; throwScope, ExceptionOr&lt;String&gt;&amp;&amp; value)
-{
-    if (UNLIKELY(value.hasException())) {
-        propagateException(state, throwScope, value.releaseException());
-        return { };
-    }
-    return jsStringOrNull(&amp;state, value.releaseReturnValue());
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMConverth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -164,10 +164,8 @@
</span><span class="cx">         // NOTE: Handled elsewhere.
</span><span class="cx"> 
</span><span class="cx">         // 2. Otherwise, if V is null or undefined, then return the IDL nullable type T? value null.
</span><del>-        if (value.isUndefinedOrNull()) {
-            // FIXME: Should we make it part of the IDLType to provide the null value?
-            return ReturnType();
-        }
</del><ins>+        if (value.isUndefinedOrNull())
+            return T::nullValue();
</ins><span class="cx"> 
</span><span class="cx">         // 3. Otherwise, return the result of converting V using the rules for the inner IDL type T.
</span><span class="cx">         return Converter&lt;T&gt;::convert(state, value);
</span><span class="lines">@@ -180,26 +178,23 @@
</span><span class="cx">     static constexpr bool needsState = JSConverter&lt;T&gt;::needsState;
</span><span class="cx">     static constexpr bool needsGlobalObject = JSConverter&lt;T&gt;::needsGlobalObject;
</span><span class="cx"> 
</span><del>-    // 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.
</del><span class="cx">     static JSC::JSValue convert(const ImplementationType&amp; value)
</span><span class="cx">     {
</span><del>-        if (!value)
</del><ins>+        if (T::isNullValue(value))
</ins><span class="cx">             return JSC::jsNull();
</span><del>-        return JSConverter&lt;T&gt;::convert(value.value());
</del><ins>+        return JSConverter&lt;T&gt;::convert(T::extractValueFromNullable(value));
</ins><span class="cx">     }
</span><span class="cx">     static JSC::JSValue convert(JSC::ExecState&amp; state, const ImplementationType&amp; value)
</span><span class="cx">     {
</span><del>-        if (!value)
</del><ins>+        if (T::isNullValue(value))
</ins><span class="cx">             return JSC::jsNull();
</span><del>-        return JSConverter&lt;T&gt;::convert(state, value.value());
</del><ins>+        return JSConverter&lt;T&gt;::convert(state, T::extractValueFromNullable(value));
</ins><span class="cx">     }
</span><span class="cx">     static JSC::JSValue convert(JSC::ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, const ImplementationType&amp; value)
</span><span class="cx">     {
</span><del>-        if (!value)
</del><ins>+        if (T::isNullValue(value))
</ins><span class="cx">             return JSC::jsNull();
</span><del>-        return JSConverter&lt;T&gt;::convert(state, globalObject, value.value());
</del><ins>+        return JSConverter&lt;T&gt;::convert(state, globalObject, T::extractValueFromNullable(value));
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -1010,6 +1005,47 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // MARK: -
</span><ins>+// MARK: BufferSource type
+
+template&lt;&gt; struct Converter&lt;IDLBufferSource&gt; : DefaultConverter&lt;IDLBufferSource&gt; {
+    using ReturnType = BufferSource;
+
+    static ReturnType convert(JSC::ExecState&amp; state, JSC::JSValue value)
+    {
+        JSC::VM&amp; vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        if (JSC::ArrayBuffer* buffer = JSC::toArrayBuffer(value))
+            return { static_cast&lt;uint8_t*&gt;(buffer-&gt;data()), buffer-&gt;byteLength() };
+        if (RefPtr&lt;JSC::ArrayBufferView&gt; bufferView = toArrayBufferView(value))
+            return { static_cast&lt;uint8_t*&gt;(bufferView-&gt;baseAddress()), bufferView-&gt;byteLength() };
+
+        throwTypeError(&amp;state, scope, ASCIILiteral(&quot;Only ArrayBuffer and ArrayBufferView objects can be passed as BufferSource arguments&quot;));
+        return { nullptr, 0 };
+    }
+};
+
+// MARK: -
+// MARK: Date type
+
+template&lt;&gt; struct Converter&lt;IDLDate&gt; : DefaultConverter&lt;IDLDate&gt; {
+    static double convert(JSC::ExecState&amp; state, JSC::JSValue value)
+    {
+        return valueToDate(&amp;state, value);
+    }
+};
+
+template&lt;&gt; struct JSConverter&lt;IDLDate&gt; {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(JSC::ExecState&amp; state, double value)
+    {
+        return jsDate(&amp;state, value);
+    }
+};
+
+// MARK: -
</ins><span class="cx"> // MARK: Support for variadic tail convertions
</span><span class="cx"> 
</span><span class="cx"> namespace Detail {
</span><span class="lines">@@ -1076,25 +1112,4 @@
</span><span class="cx">     return { length, WTFMove(result) };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// MARK: -
-// MARK: BufferSource type
-
-template&lt;&gt; struct Converter&lt;IDLBufferSource&gt; : DefaultConverter&lt;IDLBufferSource&gt; {
-    using ReturnType = BufferSource;
-
-    static ReturnType convert(JSC::ExecState&amp; state, JSC::JSValue value)
-    {
-        JSC::VM&amp; vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        if (JSC::ArrayBuffer* buffer = JSC::toArrayBuffer(value))
-            return { static_cast&lt;uint8_t*&gt;(buffer-&gt;data()), buffer-&gt;byteLength() };
-        if (RefPtr&lt;JSC::ArrayBufferView&gt; bufferView = toArrayBufferView(value))
-            return { static_cast&lt;uint8_t*&gt;(bufferView-&gt;baseAddress()), bufferView-&gt;byteLength() };
-
-        throwTypeError(&amp;state, scope, ASCIILiteral(&quot;Only ArrayBuffer and ArrayBufferView objects can be passed as BufferSource arguments&quot;));
-        return { nullptr, 0 };
-    }
-};
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMIterator.h (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -24,8 +24,7 @@
</span><span class="cx">  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-#ifndef JSDOMIterator_h
-#define JSDOMIterator_h
</del><ins>+#pragma once
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;JSDOMBinding.h&quot;
</span><span class="cx"> #include &lt;runtime/IteratorPrototype.h&gt;
</span><span class="lines">@@ -36,8 +35,15 @@
</span><span class="cx"> 
</span><span class="cx"> void addValueIterableMethods(JSC::JSGlobalObject&amp;, JSC::JSObject&amp;);
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-class JSDOMIteratorPrototype : public JSC::JSNonFinalObject {
</del><ins>+enum class JSDOMIteratorType { Set, Map };
+
+// struct IteratorTraits {
+//     static constexpr JSDOMIteratorType type = [Map|Set];
+//     using KeyType = [IDLType|void];
+//     using ValueType = [IDLType];
+// };
+
+template&lt;typename JSWrapper, typename IteratorTraits&gt; class JSDOMIteratorPrototype : public JSC::JSNonFinalObject {
</ins><span class="cx"> public:
</span><span class="cx">     using Base = JSC::JSNonFinalObject;
</span><span class="cx">     using DOMWrapped = typename JSWrapper::DOMWrapped;
</span><span class="lines">@@ -64,24 +70,18 @@
</span><span class="cx">     void finishCreation(JSC::VM&amp;, JSC::JSGlobalObject*);
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template&lt;typename IteratorValue&gt;
-class IteratorInspector {
-private:
-    template&lt;typename T&gt; static constexpr auto test(int) -&gt; decltype(std::declval&lt;T&gt;()-&gt;key, std::declval&lt;T&gt;()-&gt;value, bool()) { return true; }
-    template&lt;typename T&gt; static constexpr bool test(...) { return false; }
-public:
-    static constexpr bool isMap = test&lt;IteratorValue&gt;(0);
-    static constexpr bool isSet = !isMap;
-};
-
</del><span class="cx"> enum class IterationKind { Key, Value, KeyValue };
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-class JSDOMIterator: public JSDOMObject {
</del><ins>+template&lt;typename JSWrapper, typename IteratorTraits&gt; class JSDOMIterator : public JSDOMObject {
</ins><span class="cx"> public:
</span><del>-    using DOMWrapped = typename std::remove_reference&lt;decltype(std::declval&lt;JSWrapper&gt;().wrapped())&gt;::type;
</del><span class="cx">     using Base = JSDOMObject;
</span><span class="cx"> 
</span><ins>+    using Wrapper = JSWrapper;
+    using Traits = IteratorTraits;
+
+    using DOMWrapped = typename Wrapper::DOMWrapped;
+    using Prototype = JSDOMIteratorPrototype&lt;Wrapper, Traits&gt;;
+
</ins><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><span class="cx">     static JSC::Structure* createStructure(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
</span><span class="lines">@@ -96,10 +96,9 @@
</span><span class="cx">         return instance;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static JSDOMIteratorPrototype&lt;JSWrapper&gt;* createPrototype(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject)
</del><ins>+    static Prototype* createPrototype(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject)
</ins><span class="cx">     {
</span><del>-        return JSDOMIteratorPrototype&lt;JSWrapper&gt;::create(vm, globalObject,
-            JSDOMIteratorPrototype&lt;JSWrapper&gt;::createStructure(vm, globalObject, globalObject-&gt;iteratorPrototype()));
</del><ins>+        return Prototype::create(vm, globalObject, Prototype::createStructure(vm, globalObject, globalObject-&gt;iteratorPrototype()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     JSC::JSValue next(JSC::ExecState&amp;);
</span><span class="lines">@@ -112,10 +111,8 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    template&lt;typename IteratorValue&gt; typename std::enable_if&lt;IteratorInspector&lt;IteratorValue&gt;::isMap, JSC::JSValue&gt;::type
-    asJS(JSC::ExecState&amp;, IteratorValue&amp;);
-    template&lt;typename IteratorValue&gt; typename std::enable_if&lt;IteratorInspector&lt;IteratorValue&gt;::isSet, JSC::JSValue&gt;::type
-    asJS(JSC::ExecState&amp;, IteratorValue&amp;);
</del><ins>+    template&lt;typename IteratorValue, typename T = Traits&gt; typename std::enable_if&lt;T::type == JSDOMIteratorType::Map, JSC::JSValue&gt;::type asJS(JSC::ExecState&amp;, IteratorValue&amp;);
+    template&lt;typename IteratorValue, typename T = Traits&gt; typename std::enable_if&lt;T::type == JSDOMIteratorType::Set, JSC::JSValue&gt;::type asJS(JSC::ExecState&amp;, IteratorValue&amp;);
</ins><span class="cx"> 
</span><span class="cx">     static void destroy(JSC::JSCell*);
</span><span class="cx"> 
</span><span class="lines">@@ -123,61 +120,91 @@
</span><span class="cx">     IterationKind m_kind;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-JSC::JSValue iteratorCreate(JSWrapper&amp;, IterationKind);
-template&lt;typename JSWrapper&gt;
-JSC::JSValue iteratorForEach(JSC::ExecState&amp;, JSWrapper&amp;, JSC::ThrowScope&amp;);
</del><ins>+inline JSC::JSValue jsPair(JSC::ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, JSC::JSValue value1, JSC::JSValue value2)
+{
+    JSC::MarkedArgumentBuffer arguments;
+    arguments.append(value1);
+    arguments.append(value2);
+    return constructArray(&amp;state, nullptr, &amp;globalObject, arguments);
+}
</ins><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-JSC::JSValue iteratorCreate(JSWrapper&amp; thisObject, IterationKind kind)
</del><ins>+template&lt;typename FirstType, typename SecondType, typename T, typename U&gt; 
+inline JSC::JSValue jsPair(JSC::ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, const T&amp; value1, const U&amp; value2)
</ins><span class="cx"> {
</span><ins>+    return jsPair(state, globalObject, toJS&lt;FirstType&gt;(state, globalObject, value1), toJS&lt;SecondType&gt;(state, globalObject, value2));
+}
+
+template&lt;typename JSIterator&gt;
+JSC::JSValue iteratorCreate(typename JSIterator::Wrapper&amp;, IterationKind);
+template&lt;typename JSIterator&gt;
+JSC::JSValue iteratorForEach(JSC::ExecState&amp;, typename JSIterator::Wrapper&amp;, JSC::ThrowScope&amp;);
+
+template&lt;typename JSIterator&gt;
+JSC::JSValue iteratorCreate(typename JSIterator::Wrapper&amp; thisObject, IterationKind kind)
+{
</ins><span class="cx">     ASSERT(thisObject.globalObject());
</span><span class="cx">     JSDOMGlobalObject&amp; globalObject = *thisObject.globalObject();
</span><del>-    return JSDOMIterator&lt;JSWrapper&gt;::create(globalObject.vm(), getDOMStructure&lt;JSDOMIterator&lt;JSWrapper&gt;&gt;(globalObject.vm(), globalObject), thisObject, kind);
</del><ins>+    return JSIterator::create(globalObject.vm(), getDOMStructure&lt;JSIterator&gt;(globalObject.vm(), globalObject), thisObject, kind);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-template&lt;typename IteratorValue&gt; inline typename std::enable_if&lt;IteratorInspector&lt;IteratorValue&gt;::isMap, JSC::JSValue&gt;::type
-JSDOMIterator&lt;JSWrapper&gt;::asJS(JSC::ExecState&amp; state, IteratorValue&amp; value)
</del><ins>+template&lt;typename JSWrapper, typename IteratorTraits&gt;
+template&lt;typename IteratorValue, typename T&gt; 
+inline typename std::enable_if&lt;T::type == JSDOMIteratorType::Map, JSC::JSValue&gt;::type JSDOMIterator&lt;JSWrapper, IteratorTraits&gt;::asJS(JSC::ExecState&amp; state, IteratorValue&amp; value)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(value);
</span><del>-    if (m_kind != IterationKind::KeyValue)
-        return toJS(&amp;state, globalObject(), (m_kind == IterationKind::Key) ? value-&gt;key : value-&gt;value);
-
-    return jsPair(state, globalObject(), value-&gt;key, value-&gt;value);
</del><ins>+    
+    switch (m_kind) {
+    case IterationKind::Key:
+        return toJS&lt;typename Traits::KeyType&gt;(state, *globalObject(), value-&gt;key);
+    case IterationKind::Value:
+        return toJS&lt;typename Traits::ValueType&gt;(state, *globalObject(), value-&gt;value);
+    case IterationKind::KeyValue:
+        return jsPair&lt;typename Traits::KeyType, typename Traits::ValueType&gt;(state, *globalObject(), value-&gt;key, value-&gt;value);
+    };
+    
+    ASSERT_NOT_REACHED();
+    return { };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-template&lt;typename IteratorValue&gt; inline typename std::enable_if&lt;IteratorInspector&lt;IteratorValue&gt;::isSet, JSC::JSValue&gt;::type
-JSDOMIterator&lt;JSWrapper&gt;::asJS(JSC::ExecState&amp; state, IteratorValue&amp; value)
</del><ins>+template&lt;typename JSWrapper, typename IteratorTraits&gt;
+template&lt;typename IteratorValue, typename T&gt;
+inline typename std::enable_if&lt;T::type == JSDOMIteratorType::Set, JSC::JSValue&gt;::type JSDOMIterator&lt;JSWrapper, IteratorTraits&gt;::asJS(JSC::ExecState&amp; state, IteratorValue&amp; value)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(value);
</span><del>-    JSC::JSValue result = toJS(&amp;state, globalObject(), *value);
-    if (m_kind != IterationKind::KeyValue)
</del><ins>+
+    auto globalObject = this-&gt;globalObject();
+    auto result = toJS&lt;typename Traits::ValueType&gt;(state, *globalObject, value);
+
+    switch (m_kind) {
+    case IterationKind::Key:
+    case IterationKind::Value:
</ins><span class="cx">         return result;
</span><ins>+    case IterationKind::KeyValue:
+        return jsPair(state, *globalObject, result, result);
+    };
</ins><span class="cx"> 
</span><del>-    return jsPair(state, globalObject(), result, result);
</del><ins>+    ASSERT_NOT_REACHED();
+    return { };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename IteratorValue&gt; typename std::enable_if&lt;IteratorInspector&lt;IteratorValue&gt;::isMap, void&gt;::type
-appendForEachArguments(JSC::ExecState&amp; state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer&amp; arguments, IteratorValue&amp; value)
</del><ins>+template&lt;typename JSIterator, typename IteratorValue&gt;
+typename std::enable_if&lt;JSIterator::Traits::type == JSDOMIteratorType::Map, void&gt;::type appendForEachArguments(JSC::ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, JSC::MarkedArgumentBuffer&amp; arguments, IteratorValue&amp; value)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(value);
</span><del>-    arguments.append(toJS(&amp;state, globalObject, value-&gt;value));
-    arguments.append(toJS(&amp;state, globalObject, value-&gt;key));
</del><ins>+    arguments.append(toJS&lt;typename JSIterator::Traits::ValueType&gt;(state, globalObject, value-&gt;value));
+    arguments.append(toJS&lt;typename JSIterator::Traits::KeyType&gt;(state, globalObject, value-&gt;key));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename IteratorValue&gt; typename std::enable_if&lt;IteratorInspector&lt;IteratorValue&gt;::isSet, void&gt;::type
-appendForEachArguments(JSC::ExecState&amp; state, JSDOMGlobalObject* globalObject, JSC::MarkedArgumentBuffer&amp; arguments, IteratorValue&amp; value)
</del><ins>+template&lt;typename JSIterator, typename IteratorValue&gt; 
+typename std::enable_if&lt;JSIterator::Traits::type == JSDOMIteratorType::Set, void&gt;::type appendForEachArguments(JSC::ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, JSC::MarkedArgumentBuffer&amp; arguments, IteratorValue&amp; value)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(value);
</span><del>-    JSC::JSValue argument = toJS(&amp;state, globalObject, *value);
</del><ins>+    auto argument = toJS&lt;typename JSIterator::Traits::ValueType&gt;(state, globalObject, value);
</ins><span class="cx">     arguments.append(argument);
</span><span class="cx">     arguments.append(argument);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-JSC::JSValue iteratorForEach(JSC::ExecState&amp; state, JSWrapper&amp; thisObject, JSC::ThrowScope&amp; scope)
</del><ins>+template&lt;typename JSIterator&gt; JSC::JSValue iteratorForEach(JSC::ExecState&amp; state, typename JSIterator::Wrapper&amp; thisObject, JSC::ThrowScope&amp; scope)
</ins><span class="cx"> {
</span><span class="cx">     JSC::JSValue callback = state.argument(0);
</span><span class="cx">     JSC::JSValue thisValue = state.argument(1);
</span><span class="lines">@@ -190,7 +217,7 @@
</span><span class="cx">     auto iterator = thisObject.wrapped().createIterator();
</span><span class="cx">     while (auto value = iterator.next()) {
</span><span class="cx">         JSC::MarkedArgumentBuffer arguments;
</span><del>-        appendForEachArguments(state, thisObject.globalObject(), arguments, value);
</del><ins>+        appendForEachArguments&lt;JSIterator&gt;(state, *thisObject.globalObject(), arguments, value);
</ins><span class="cx">         arguments.append(&amp;thisObject);
</span><span class="cx">         JSC::call(&amp;state, callback, callType, callData, thisValue, arguments);
</span><span class="cx">         if (UNLIKELY(scope.exception()))
</span><span class="lines">@@ -199,15 +226,15 @@
</span><span class="cx">     return JSC::jsUndefined();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-void JSDOMIterator&lt;JSWrapper&gt;::destroy(JSCell* cell)
</del><ins>+template&lt;typename JSWrapper, typename IteratorTraits&gt;
+void JSDOMIterator&lt;JSWrapper, IteratorTraits&gt;::destroy(JSCell* cell)
</ins><span class="cx"> {
</span><del>-    JSDOMIterator&lt;JSWrapper&gt;* thisObject = JSC::jsCast&lt;JSDOMIterator&lt;JSWrapper&gt;*&gt;(cell);
-    thisObject-&gt;JSDOMIterator&lt;JSWrapper&gt;::~JSDOMIterator();
</del><ins>+    JSDOMIterator&lt;JSWrapper, IteratorTraits&gt;* thisObject = JSC::jsCast&lt;JSDOMIterator&lt;JSWrapper, IteratorTraits&gt;*&gt;(cell);
+    thisObject-&gt;JSDOMIterator&lt;JSWrapper, IteratorTraits&gt;::~JSDOMIterator();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-JSC::JSValue JSDOMIterator&lt;JSWrapper&gt;::next(JSC::ExecState&amp; state)
</del><ins>+template&lt;typename JSWrapper, typename IteratorTraits&gt;
+JSC::JSValue JSDOMIterator&lt;JSWrapper, IteratorTraits&gt;::next(JSC::ExecState&amp; state)
</ins><span class="cx"> {
</span><span class="cx">     if (m_iterator) {
</span><span class="cx">         auto iteratorValue = m_iterator-&gt;next();
</span><span class="lines">@@ -218,13 +245,13 @@
</span><span class="cx">     return createIteratorResultObject(&amp;state, JSC::jsUndefined(), true);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-JSC::EncodedJSValue JSC_HOST_CALL JSDOMIteratorPrototype&lt;JSWrapper&gt;::next(JSC::ExecState* state)
</del><ins>+template&lt;typename JSWrapper, typename IteratorTraits&gt;
+JSC::EncodedJSValue JSC_HOST_CALL JSDOMIteratorPrototype&lt;JSWrapper, IteratorTraits&gt;::next(JSC::ExecState* state)
</ins><span class="cx"> {
</span><span class="cx">     JSC::VM&amp; vm = state-&gt;vm();
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><del>-    auto iterator = JSC::jsDynamicCast&lt;JSDOMIterator&lt;JSWrapper&gt;*&gt;(state-&gt;thisValue());
</del><ins>+    auto iterator = JSC::jsDynamicCast&lt;JSDOMIterator&lt;JSWrapper, IteratorTraits&gt;*&gt;(state-&gt;thisValue());
</ins><span class="cx">     if (!iterator)
</span><span class="cx">         return JSC::JSValue::encode(throwTypeError(state, scope, ASCIILiteral(&quot;Cannot call next() on a non-Iterator object&quot;)));
</span><span class="cx"> 
</span><span class="lines">@@ -231,8 +258,8 @@
</span><span class="cx">     return JSC::JSValue::encode(iterator-&gt;next(*state));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename JSWrapper&gt;
-void JSDOMIteratorPrototype&lt;JSWrapper&gt;::finishCreation(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject)
</del><ins>+template&lt;typename JSWrapper, typename IteratorTraits&gt;
+void JSDOMIteratorPrototype&lt;JSWrapper, IteratorTraits&gt;::finishCreation(JSC::VM&amp; vm, JSC::JSGlobalObject* globalObject)
</ins><span class="cx"> {
</span><span class="cx">     Base::finishCreation(vm);
</span><span class="cx">     ASSERT(inherits(info()));
</span><span class="lines">@@ -241,5 +268,3 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span><del>-
-#endif // !defined(JSDOMIterator_h)
</del></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -4865,15 +4865,29 @@
</span><span class="cx"> 
</span><span class="cx">     return unless IsKeyValueIterableInterface($interface);
</span><span class="cx"> 
</span><ins>+    my $iteratorName = &quot;${interfaceName}Iterator&quot;;
+    my $iteratorPrototypeName = &quot;${interfaceName}IteratorPrototype&quot;;
+
+    my $iteratorTraitsName = &quot;${interfaceName}IteratorTraits&quot;;
+    my $iteratorTraitsType = $interface-&gt;iterable-&gt;isKeyValue ? &quot;JSDOMIteratorType::Map&quot; : &quot;JSDOMIteratorType::Set&quot;;
+    my $iteratorTraitsKeyType = $interface-&gt;iterable-&gt;isKeyValue ? GetIDLType($interface, $interface-&gt;iterable-&gt;idlKeyType) : &quot;void&quot;;
+    my $iteratorTraitsValueType = GetIDLType($interface, $interface-&gt;iterable-&gt;idlValueType);
+
</ins><span class="cx">     push(@implContent,  &lt;&lt;END);
</span><del>-using ${interfaceName}Iterator = JSDOMIterator&lt;${className}&gt;;
-using ${interfaceName}IteratorPrototype = JSDOMIteratorPrototype&lt;${className}&gt;;
</del><ins>+struct ${iteratorTraitsName} {
+    static constexpr JSDOMIteratorType type = ${iteratorTraitsType};
+    using KeyType = ${iteratorTraitsKeyType};
+    using ValueType = ${iteratorTraitsValueType};
+};
</ins><span class="cx"> 
</span><ins>+using ${iteratorName} = JSDOMIterator&lt;${className}, ${iteratorTraitsName}&gt;;
+using ${iteratorPrototypeName} = JSDOMIteratorPrototype&lt;${className}, ${iteratorTraitsName}&gt;;
+
</ins><span class="cx"> template&lt;&gt;
</span><del>-const JSC::ClassInfo ${interfaceName}Iterator::s_info = { &quot;${visibleInterfaceName} Iterator&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(${interfaceName}Iterator) };
</del><ins>+const JSC::ClassInfo ${iteratorName}::s_info = { &quot;${visibleInterfaceName} Iterator&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(${iteratorName}) };
</ins><span class="cx"> 
</span><span class="cx"> template&lt;&gt;
</span><del>-const JSC::ClassInfo ${interfaceName}IteratorPrototype::s_info = { &quot;${visibleInterfaceName} Iterator&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(${interfaceName}IteratorPrototype) };
</del><ins>+const JSC::ClassInfo ${iteratorPrototypeName}::s_info = { &quot;${visibleInterfaceName} Iterator&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(${iteratorPrototypeName}) };
</ins><span class="cx"> 
</span><span class="cx"> END
</span><span class="cx"> 
</span><span class="lines">@@ -4885,7 +4899,7 @@
</span><span class="cx">             push(@implContent,  &lt;&lt;END);
</span><span class="cx"> static inline EncodedJSValue ${functionName}Caller(ExecState* state, JS$interfaceName* thisObject, JSC::ThrowScope&amp; throwScope)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorForEach&lt;${className}&gt;(*state, *thisObject, throwScope));
</del><ins>+    return JSValue::encode(iteratorForEach&lt;${iteratorName}&gt;(*state, *thisObject, throwScope));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> END
</span><span class="lines">@@ -4898,7 +4912,7 @@
</span><span class="cx">             push(@implContent,  &lt;&lt;END);
</span><span class="cx"> static inline EncodedJSValue ${functionName}Caller(ExecState*, JS$interfaceName* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;${className}&gt;(*thisObject, IterationKind::${iterationKind}));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;${iteratorName}&gt;(*thisObject, IterationKind::${iterationKind}));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> END
</span><span class="lines">@@ -5047,6 +5061,10 @@
</span><span class="cx">         &quot;DOMString&quot; =&gt; &quot;IDLDOMString&quot;,
</span><span class="cx">         &quot;ByteString&quot; =&gt; &quot;IDLByteString&quot;,
</span><span class="cx">         &quot;USVString&quot; =&gt; &quot;IDLUSVString&quot;,
</span><ins>+        
+        # Non-WebIDL extensions
+        &quot;Date&quot; =&gt; &quot;IDLDate&quot;,
+        &quot;BufferSource&quot; =&gt; &quot;IDLBufferSource&quot;,
</ins><span class="cx">     );
</span><span class="cx"> 
</span><span class="cx">     return $IDLTypes{$idlType-&gt;name} if exists $IDLTypes{$idlType-&gt;name};
</span><span class="lines">@@ -5055,7 +5073,6 @@
</span><span class="cx">     return &quot;IDLSequence&lt;&quot; . GetIDLType($interface, @{$idlType-&gt;subtypes}[0]) . &quot;&gt;&quot; if $codeGenerator-&gt;IsSequenceType($idlType-&gt;name);
</span><span class="cx">     return &quot;IDLFrozenArray&lt;&quot; . GetIDLType($interface, @{$idlType-&gt;subtypes}[0]) . &quot;&gt;&quot; if $codeGenerator-&gt;IsFrozenArrayType($idlType-&gt;name);
</span><span class="cx">     return &quot;IDLUnion&lt;&quot; . join(&quot;, &quot;, GetIDLUnionMemberTypes($interface, $idlType)) . &quot;&gt;&quot; if $idlType-&gt;isUnion;
</span><del>-    return &quot;IDLBufferSource&quot; if $idlType-&gt;name eq &quot;BufferSource&quot;;
</del><span class="cx">     return &quot;IDLInterface&lt;&quot; . $idlType-&gt;name . &quot;&gt;&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -5177,9 +5194,10 @@
</span><span class="cx">     my $idlType = shift;
</span><span class="cx"> 
</span><span class="cx">     return 1 if $idlType-&gt;isUnion;
</span><del>-    return 1 if $idlType-&gt;name eq &quot;BufferSource&quot;;
</del><span class="cx">     return 1 if $idlType-&gt;name eq &quot;any&quot;;
</span><span class="cx">     return 1 if $idlType-&gt;name eq &quot;boolean&quot;;
</span><ins>+    return 1 if $idlType-&gt;name eq &quot;Date&quot;;
+    return 1 if $idlType-&gt;name eq &quot;BufferSource&quot;;
</ins><span class="cx">     return 1 if $codeGenerator-&gt;IsIntegerType($idlType-&gt;name);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsFloatingPointType($idlType-&gt;name);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsSequenceOrFrozenArrayType($idlType-&gt;name);
</span><span class="lines">@@ -5241,7 +5259,6 @@
</span><span class="cx">         return (&quot;Dictionary($statePointer, $value)&quot;, 0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return (&quot;valueToDate($statePointer, $value)&quot;, 1) if $type eq &quot;Date&quot;;
</del><span class="cx">     return (&quot;to$type($value)&quot;, 1) if $codeGenerator-&gt;IsTypedArrayType($type);
</span><span class="cx">     return (&quot;parseEnumeration&lt;&quot; . GetEnumerationClassName($type, $interface) . &quot;&gt;($stateReference, $value)&quot;, 1) if $codeGenerator-&gt;IsEnumType($type);
</span><span class="cx"> 
</span><span class="lines">@@ -5258,11 +5275,10 @@
</span><span class="cx"> sub NativeToJSValueIsHandledByDOMConvert
</span><span class="cx"> {
</span><span class="cx">     my ($idlType) = @_;
</span><del>-
-    return 0 if $idlType-&gt;isNullable &amp;&amp; ($codeGenerator-&gt;IsStringType($idlType-&gt;name) || $codeGenerator-&gt;IsEnumType($idlType-&gt;name));
</del><span class="cx">     
</span><span class="cx">     return 1 if $idlType-&gt;name eq &quot;any&quot;;
</span><span class="cx">     return 1 if $idlType-&gt;name eq &quot;boolean&quot;;
</span><ins>+    return 1 if $idlType-&gt;name eq &quot;Date&quot;;
</ins><span class="cx">     return 1 if $codeGenerator-&gt;IsIntegerType($idlType-&gt;name);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsFloatingPointType($idlType-&gt;name);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsStringType($idlType-&gt;name);
</span><span class="lines">@@ -5282,6 +5298,7 @@
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsSequenceOrFrozenArrayType($idlType-&gt;name);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsStringType($idlType-&gt;name);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsEnumType($idlType-&gt;name);
</span><ins>+    return 1 if $idlType-&gt;name eq &quot;Date&quot;;
</ins><span class="cx"> 
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="lines">@@ -5360,18 +5377,6 @@
</span><span class="cx">         return &quot;toJS&lt;$IDLType&gt;(&quot; . join(&quot;, &quot;, @conversionArguments) . &quot;)&quot;;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return &quot;toJSNullableDate($stateReference, throwScope, $value)&quot; if $type eq &quot;Date&quot; &amp;&amp; $isNullable &amp;&amp; $mayThrowException;
-    return &quot;jsDateOrNull($statePointer, $value)&quot; if $type eq &quot;Date&quot; &amp;&amp; $isNullable;
-    return &quot;toJSDate($stateReference, throwScope, $value)&quot; if $type eq &quot;Date&quot; &amp;&amp; $mayThrowException;
-    return &quot;jsDate($statePointer, $value)&quot; if $type eq &quot;Date&quot;;
-
-    if ($codeGenerator-&gt;IsStringType($type)) {
-        AddToImplIncludes(&quot;URL.h&quot;, $conditional);
-        return &quot;toJSNullableString($stateReference, throwScope, $value)&quot; if $isNullable &amp;&amp; $mayThrowException;
-        return &quot;jsStringOrNull($statePointer, $value)&quot; if $isNullable;
-        assert(&quot;Unhandled string type&quot;);
-    }
-
</del><span class="cx">     if ($type eq &quot;SerializedScriptValue&quot;) {
</span><span class="cx">         AddToImplIncludes(&quot;SerializedScriptValue.h&quot;, $conditional);
</span><span class="cx">         return &quot;$value ? $value-&gt;deserialize($stateReference, $globalObject) : jsNull()&quot;;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsIDLParserpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/IDLParser.pm (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -103,8 +103,10 @@
</span><span class="cx"> # Used to represent Iterable interfaces
</span><span class="cx"> struct( domIterable =&gt; {
</span><span class="cx">     isKeyValue =&gt; '$',# Is map iterable or set iterable
</span><del>-    keyType =&gt; '$',   # Key type for map iterables
-    valueType =&gt; '$', # Value type for map or set iterables
</del><ins>+    keyType =&gt; '$',   # Key type name for map iterables (DEPRECATED - please use idlKeyType)
+    valueType =&gt; '$', # Value type name for map or set iterables (DEPRECATED - please use idlValueType)
+    idlKeyType =&gt; '$',   # Key type for map iterables
+    idlValueType =&gt; '$', # Value type for map or set iterables
</ins><span class="cx">     functions =&gt; '@', # Iterable functions (entries, keys, values, [Symbol.Iterator], forEach)
</span><span class="cx">     extendedAttributes =&gt; '$', # Extended attributes
</span><span class="cx"> });
</span><span class="lines">@@ -1514,15 +1516,21 @@
</span><span class="cx">     push(@{$newDataNode-&gt;functions}, $forEachFunction);
</span><span class="cx"> 
</span><span class="cx">     $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
</span><del>-    my $type1 = $self-&gt;getToken()-&gt;value();
</del><ins>+    my $type1 = $self-&gt;parseType();
+
</ins><span class="cx">     if ($self-&gt;nextToken()-&gt;value() eq &quot;,&quot;) {
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;,&quot;, __LINE__);
</span><ins>+
+        my $type2 = $self-&gt;parseType();
</ins><span class="cx">         $newDataNode-&gt;isKeyValue(1);
</span><del>-        $newDataNode-&gt;keyType($type1);
-        $newDataNode-&gt;valueType($self-&gt;getToken()-&gt;value());
</del><ins>+        $newDataNode-&gt;idlKeyType($type1);
+        $newDataNode-&gt;keyType($type1-&gt;name);
+        $newDataNode-&gt;idlValueType($type2);
+        $newDataNode-&gt;valueType($type2-&gt;name);
</ins><span class="cx">     } else {
</span><span class="cx">         $newDataNode-&gt;isKeyValue(0);
</span><del>-        $newDataNode-&gt;valueType($type1);
</del><ins>+        $newDataNode-&gt;idlValueType($type1);
+        $newDataNode-&gt;valueType($type1-&gt;name);
</ins><span class="cx">     }
</span><span class="cx">     $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestIterablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIterable.cpp (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -163,9 +163,15 @@
</span><span class="cx">     return getDOMConstructor&lt;JSTestIterableConstructor&gt;(vm, *jsCast&lt;const JSDOMGlobalObject*&gt;(globalObject));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-using TestIterableIterator = JSDOMIterator&lt;JSTestIterable&gt;;
-using TestIterableIteratorPrototype = JSDOMIteratorPrototype&lt;JSTestIterable&gt;;
</del><ins>+struct TestIterableIteratorTraits {
+    static constexpr JSDOMIteratorType type = JSDOMIteratorType::Set;
+    using KeyType = void;
+    using ValueType = IDLInterface&lt;TestNode&gt;;
+};
</ins><span class="cx"> 
</span><ins>+using TestIterableIterator = JSDOMIterator&lt;JSTestIterable, TestIterableIteratorTraits&gt;;
+using TestIterableIteratorPrototype = JSDOMIteratorPrototype&lt;JSTestIterable, TestIterableIteratorTraits&gt;;
+
</ins><span class="cx"> template&lt;&gt;
</span><span class="cx"> const JSC::ClassInfo TestIterableIterator::s_info = { &quot;TestIterable Iterator&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(TestIterableIterator) };
</span><span class="cx"> 
</span><span class="lines">@@ -174,7 +180,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestIterablePrototypeFunctionSymbolIteratorCaller(ExecState*, JSTestIterable* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;JSTestIterable&gt;(*thisObject, IterationKind::Value));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;TestIterableIterator&gt;(*thisObject, IterationKind::Value));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionSymbolIterator(JSC::ExecState* state)
</span><span class="lines">@@ -184,7 +190,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestIterablePrototypeFunctionEntriesCaller(ExecState*, JSTestIterable* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;JSTestIterable&gt;(*thisObject, IterationKind::KeyValue));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;TestIterableIterator&gt;(*thisObject, IterationKind::KeyValue));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionEntries(JSC::ExecState* state)
</span><span class="lines">@@ -194,7 +200,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestIterablePrototypeFunctionKeysCaller(ExecState*, JSTestIterable* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;JSTestIterable&gt;(*thisObject, IterationKind::Key));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;TestIterableIterator&gt;(*thisObject, IterationKind::Key));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionKeys(JSC::ExecState* state)
</span><span class="lines">@@ -204,7 +210,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestIterablePrototypeFunctionValuesCaller(ExecState*, JSTestIterable* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;JSTestIterable&gt;(*thisObject, IterationKind::Value));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;TestIterableIterator&gt;(*thisObject, IterationKind::Value));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionValues(JSC::ExecState* state)
</span><span class="lines">@@ -214,7 +220,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestIterablePrototypeFunctionForEachCaller(ExecState* state, JSTestIterable* thisObject, JSC::ThrowScope&amp; throwScope)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorForEach&lt;JSTestIterable&gt;(*state, *thisObject, throwScope));
</del><ins>+    return JSValue::encode(iteratorForEach&lt;TestIterableIterator&gt;(*state, *thisObject, throwScope));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestIterablePrototypeFunctionForEach(JSC::ExecState* state)
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -264,9 +264,15 @@
</span><span class="cx">     return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-using TestNodeIterator = JSDOMIterator&lt;JSTestNode&gt;;
-using TestNodeIteratorPrototype = JSDOMIteratorPrototype&lt;JSTestNode&gt;;
</del><ins>+struct TestNodeIteratorTraits {
+    static constexpr JSDOMIteratorType type = JSDOMIteratorType::Set;
+    using KeyType = void;
+    using ValueType = IDLInterface&lt;TestNode&gt;;
+};
</ins><span class="cx"> 
</span><ins>+using TestNodeIterator = JSDOMIterator&lt;JSTestNode, TestNodeIteratorTraits&gt;;
+using TestNodeIteratorPrototype = JSDOMIteratorPrototype&lt;JSTestNode, TestNodeIteratorTraits&gt;;
+
</ins><span class="cx"> template&lt;&gt;
</span><span class="cx"> const JSC::ClassInfo TestNodeIterator::s_info = { &quot;TestNode Iterator&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(TestNodeIterator) };
</span><span class="cx"> 
</span><span class="lines">@@ -275,7 +281,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestNodePrototypeFunctionSymbolIteratorCaller(ExecState*, JSTestNode* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;JSTestNode&gt;(*thisObject, IterationKind::Value));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;TestNodeIterator&gt;(*thisObject, IterationKind::Value));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionSymbolIterator(JSC::ExecState* state)
</span><span class="lines">@@ -285,7 +291,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestNodePrototypeFunctionEntriesCaller(ExecState*, JSTestNode* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;JSTestNode&gt;(*thisObject, IterationKind::KeyValue));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;TestNodeIterator&gt;(*thisObject, IterationKind::KeyValue));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionEntries(JSC::ExecState* state)
</span><span class="lines">@@ -295,7 +301,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestNodePrototypeFunctionKeysCaller(ExecState*, JSTestNode* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;JSTestNode&gt;(*thisObject, IterationKind::Key));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;TestNodeIterator&gt;(*thisObject, IterationKind::Key));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionKeys(JSC::ExecState* state)
</span><span class="lines">@@ -305,7 +311,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestNodePrototypeFunctionValuesCaller(ExecState*, JSTestNode* thisObject, JSC::ThrowScope&amp;)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorCreate&lt;JSTestNode&gt;(*thisObject, IterationKind::Value));
</del><ins>+    return JSValue::encode(iteratorCreate&lt;TestNodeIterator&gt;(*thisObject, IterationKind::Value));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionValues(JSC::ExecState* state)
</span><span class="lines">@@ -315,7 +321,7 @@
</span><span class="cx"> 
</span><span class="cx"> static inline EncodedJSValue jsTestNodePrototypeFunctionForEachCaller(ExecState* state, JSTestNode* thisObject, JSC::ThrowScope&amp; throwScope)
</span><span class="cx"> {
</span><del>-    return JSValue::encode(iteratorForEach&lt;JSTestNode&gt;(*state, *thisObject, throwScope));
</del><ins>+    return JSValue::encode(iteratorForEach&lt;TestNodeIterator&gt;(*state, *thisObject, throwScope));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestNodePrototypeFunctionForEach(JSC::ExecState* state)
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (207828 => 207829)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -3130,7 +3130,7 @@
</span><span class="cx">     UNUSED_PARAM(throwScope);
</span><span class="cx">     UNUSED_PARAM(state);
</span><span class="cx">     auto&amp; impl = thisObject.wrapped();
</span><del>-    JSValue result = jsStringOrNull(&amp;state, impl.nullableStringAttribute());
</del><ins>+    JSValue result = toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(state, impl.nullableStringAttribute());
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3162,7 +3162,7 @@
</span><span class="cx">     UNUSED_PARAM(throwScope);
</span><span class="cx">     UNUSED_PARAM(state);
</span><span class="cx">     auto&amp; impl = thisObject.wrapped();
</span><del>-    JSValue result = jsStringOrNull(&amp;state, impl.nullableStringSettableAttribute());
</del><ins>+    JSValue result = toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(state, impl.nullableStringSettableAttribute());
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3178,7 +3178,7 @@
</span><span class="cx">     UNUSED_PARAM(throwScope);
</span><span class="cx">     UNUSED_PARAM(state);
</span><span class="cx">     auto&amp; impl = thisObject.wrapped();
</span><del>-    JSValue result = jsStringOrNull(&amp;state, impl.nullableUSVStringSettableAttribute());
</del><ins>+    JSValue result = toJS&lt;IDLNullable&lt;IDLUSVString&gt;&gt;(state, impl.nullableUSVStringSettableAttribute());
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -5128,7 +5128,7 @@
</span><span class="cx">     UNUSED_PARAM(state);
</span><span class="cx">     UNUSED_PARAM(throwScope);
</span><span class="cx">     auto&amp; impl = castedThis-&gt;wrapped();
</span><del>-    JSValue result = jsStringOrNull(state, impl.nullableStringMethod());
</del><ins>+    JSValue result = toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(*state, impl.nullableStringMethod());
</ins><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -5137,7 +5137,7 @@
</span><span class="cx">     VM&amp; vm = state-&gt;vm();
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx">     UNUSED_PARAM(throwScope);
</span><del>-    JSValue result = jsStringOrNull(state, TestObj::nullableStringStaticMethod());
</del><ins>+    JSValue result = toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(*state, TestObj::nullableStringStaticMethod());
</ins><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -5157,7 +5157,7 @@
</span><span class="cx">         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
</span><span class="cx">     auto index = convert&lt;IDLUnsignedLong&gt;(*state, state-&gt;uncheckedArgument(0), NormalConversion);
</span><span class="cx">     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><del>-    JSValue result = jsStringOrNull(state, impl.nullableStringSpecialMethod(WTFMove(index)));
</del><ins>+    JSValue result = toJS&lt;IDLNullable&lt;IDLDOMString&gt;&gt;(*state, impl.nullableStringSpecialMethod(WTFMove(index)));
</ins><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>