<!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>[207575] trunk</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/207575">207575</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2016-10-19 16:31:14 -0700 (Wed, 19 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for sequences and dictionaries in unions
https://bugs.webkit.org/show_bug.cgi?id=163695

Reviewed by Chris Dumez.

Source/WebCore:

Tests:
 - Updated js/dom/webidl-type-mapping.html

* bindings/generic/IDLTypes.h:
Add additional helper predicates and fix formatting.

* bindings/js/JSDOMBinding.h:
Export hasIteratorMethod for use in testing.

* bindings/js/JSDOMConvert.h:
- Change return type of Converter&lt;IDLDictionary&lt;T&gt;&gt; to T, from Optional&lt;T&gt;.
- Add support for unions conversion step 12 (parts 1-3).

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateDefaultValue):
Support complex default value computations for unions using the convert infrastructure.

(GenerateParametersCheck):
(GenerateConstructorDefinition):
Remove incorrect .value() calls now that Converter&lt;IDLDictionary&lt;T&gt;&gt; returns T.

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

* testing/TypeConversions.h:
(WebCore::TypeConversions::setTypeConversionsDictionary):
(WebCore::TypeConversions::typeConversionsDictionaryLongValue):
(WebCore::TypeConversions::typeConversionsDictionaryStringValue):
(WebCore::TypeConversions::typeConversionsDictionarySequenceValue):
(WebCore::TypeConversions::typeConversionsDictionaryUnionType):
* testing/TypeConversions.idl:
Add some complex types to allow testing IDL conversions from tests.

LayoutTests:

* js/dom/webidl-type-mapping-expected.txt:
* js/dom/webidl-type-mapping.html:
Add tests for more complex conversions.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsdomwebidltypemappingexpectedtxt">trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdomwebidltypemappinghtml">trunk/LayoutTests/js/dom/webidl-type-mapping.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsgenericIDLTypesh">trunk/Source/WebCore/bindings/generic/IDLTypes.h</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="#trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm">trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestEventConstructorcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingTypeConversionsh">trunk/Source/WebCore/testing/TypeConversions.h</a></li>
<li><a href="#trunkSourceWebCoretestingTypeConversionsidl">trunk/Source/WebCore/testing/TypeConversions.idl</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/LayoutTests/ChangeLog        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-10-19  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        Add support for sequences and dictionaries in unions
+        https://bugs.webkit.org/show_bug.cgi?id=163695
+
+        Reviewed by Chris Dumez.
+
+        * js/dom/webidl-type-mapping-expected.txt:
+        * js/dom/webidl-type-mapping.html:
+        Add tests for more complex conversions.
+
</ins><span class="cx"> 2016-10-19  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Marking platform/mac-wk2/plugins/muted-state.html as failing.
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomwebidltypemappingexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -1059,6 +1059,24 @@
</span><span class="cx"> converter.testString = undefined
</span><span class="cx"> PASS converter.testUSVString is &quot;undefined&quot;
</span><span class="cx"> PASS converter.testString is &quot;undefined&quot;
</span><ins>+converter.setTypeConversionsDictionary({ longValue: 1 })
+PASS converter.typeConversionsDictionaryLongValue is 1
+converter.setTypeConversionsDictionary({ stringValue: 'hello' })
+PASS converter.typeConversionsDictionaryStringValue is 'hello'
+converter.setTypeConversionsDictionary({ sequenceValue: ['hi', 'there'] })
+PASS converter.typeConversionsDictionarySequenceValue is ['hi', 'there']
+converter.setTypeConversionsDictionary({ unionValue: document })
+PASS converter.typeConversionsDictionaryUnionType is 'node'
+converter.setTypeConversionsDictionary({ unionValue: ['a', 'sequence'] })
+PASS converter.typeConversionsDictionaryUnionType is 'sequence'
+converter.setTypeConversionsDictionary({ unionValue: { longValue: 1 } })
+PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
+converter.setTypeConversionsDictionary({ unionValue: null })
+PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
+converter.setTypeConversionsDictionary({ unionValue: undefined })
+PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
+converter.setTypeConversionsDictionary({ })
+PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomwebidltypemappinghtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/webidl-type-mapping.html (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/webidl-type-mapping.html        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/LayoutTests/js/dom/webidl-type-mapping.html        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -586,5 +586,25 @@
</span><span class="cx">     shouldBeEqualToString(&quot;converter.testString&quot;, value);
</span><span class="cx"> });
</span><span class="cx"> 
</span><ins>+evalAndLog(&quot;converter.setTypeConversionsDictionary({ longValue: 1 })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionaryLongValue&quot;, &quot;1&quot;);
+evalAndLog(&quot;converter.setTypeConversionsDictionary({ stringValue: 'hello' })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionaryStringValue&quot;, &quot;'hello'&quot;);
+evalAndLog(&quot;converter.setTypeConversionsDictionary({ sequenceValue: ['hi', 'there'] })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionarySequenceValue&quot;, &quot;['hi', 'there']&quot;);
+
+evalAndLog(&quot;converter.setTypeConversionsDictionary({ unionValue: document })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionaryUnionType&quot;, &quot;'node'&quot;);
+evalAndLog(&quot;converter.setTypeConversionsDictionary({ unionValue: ['a', 'sequence'] })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionaryUnionType&quot;, &quot;'sequence'&quot;);
+evalAndLog(&quot;converter.setTypeConversionsDictionary({ unionValue: { longValue: 1 } })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionaryUnionType&quot;, &quot;'dictionary'&quot;);
+evalAndLog(&quot;converter.setTypeConversionsDictionary({ unionValue: null })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionaryUnionType&quot;, &quot;'dictionary'&quot;);
+evalAndLog(&quot;converter.setTypeConversionsDictionary({ unionValue: undefined })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionaryUnionType&quot;, &quot;'dictionary'&quot;);
+evalAndLog(&quot;converter.setTypeConversionsDictionary({ })&quot;);
+shouldBe(&quot;converter.typeConversionsDictionaryUnionType&quot;, &quot;'dictionary'&quot;);
+
</ins><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/ChangeLog        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2016-10-19  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        Add support for sequences and dictionaries in unions
+        https://bugs.webkit.org/show_bug.cgi?id=163695
+
+        Reviewed by Chris Dumez.
+
+        Tests:
+         - Updated js/dom/webidl-type-mapping.html
+
+        * bindings/generic/IDLTypes.h:
+        Add additional helper predicates and fix formatting.
+
+        * bindings/js/JSDOMBinding.h:
+        Export hasIteratorMethod for use in testing.
+
+        * bindings/js/JSDOMConvert.h:
+        - Change return type of Converter&lt;IDLDictionary&lt;T&gt;&gt; to T, from Optional&lt;T&gt;.
+        - Add support for unions conversion step 12 (parts 1-3).
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateDefaultValue):
+        Support complex default value computations for unions using the convert infrastructure.
+
+        (GenerateParametersCheck):
+        (GenerateConstructorDefinition):
+        Remove incorrect .value() calls now that Converter&lt;IDLDictionary&lt;T&gt;&gt; returns T.
+
+        * bindings/scripts/test/JS/JSTestEventConstructor.cpp:
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        Update bindings test results.
+
+        * testing/TypeConversions.h:
+        (WebCore::TypeConversions::setTypeConversionsDictionary):
+        (WebCore::TypeConversions::typeConversionsDictionaryLongValue):
+        (WebCore::TypeConversions::typeConversionsDictionaryStringValue):
+        (WebCore::TypeConversions::typeConversionsDictionarySequenceValue):
+        (WebCore::TypeConversions::typeConversionsDictionaryUnionType):
+        * testing/TypeConversions.idl:
+        Add some complex types to allow testing IDL conversions from tests.
+
</ins><span class="cx"> 2016-10-19  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Annotate more DOM and HTML IDLs with CEReactions
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsgenericIDLTypesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/generic/IDLTypes.h (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/generic/IDLTypes.h        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/generic/IDLTypes.h        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -123,16 +123,25 @@
</span><span class="cx"> 
</span><span class="cx"> // Helper predicates
</span><span class="cx"> 
</span><del>-template &lt;typename T&gt;
</del><ins>+template&lt;typename T&gt;
</ins><span class="cx"> struct IsIDLInterface : public std::integral_constant&lt;bool, WTF::IsTemplate&lt;T, IDLInterface&gt;::value&gt; { };
</span><span class="cx"> 
</span><del>-template &lt;typename T&gt;
</del><ins>+template&lt;typename T&gt;
</ins><span class="cx"> struct IsIDLDictionary : public std::integral_constant&lt;bool, WTF::IsTemplate&lt;T, IDLDictionary&gt;::value&gt; { };
</span><span class="cx"> 
</span><del>-template &lt;typename T&gt;
</del><ins>+template&lt;typename T&gt;
+struct IsIDLEnumeration : public std::integral_constant&lt;bool, WTF::IsTemplate&lt;T, IDLEnumeration&gt;::value&gt; { };
+
+template&lt;typename T&gt;
+struct IsIDLSequence : public std::integral_constant&lt;bool, WTF::IsTemplate&lt;T, IDLSequence&gt;::value&gt; { };
+
+template&lt;typename T&gt;
+struct IsIDLFrozenArray : public std::integral_constant&lt;bool, WTF::IsTemplate&lt;T, IDLFrozenArray&gt;::value&gt; { };
+
+template&lt;typename T&gt;
</ins><span class="cx"> struct IsIDLNumber : public std::integral_constant&lt;bool, WTF::IsBaseOfTemplate&lt;IDLNumber, T&gt;::value&gt; { };
</span><span class="cx"> 
</span><del>-template &lt;typename T&gt;
</del><ins>+template&lt;typename T&gt;
</ins><span class="cx"> struct IsIDLInteger : public std::integral_constant&lt;bool, WTF::IsBaseOfTemplate&lt;IDLInteger, T&gt;::value&gt; { };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -301,7 +301,7 @@
</span><span class="cx"> RefPtr&lt;JSC::Float64Array&gt; toFloat64Array(JSC::JSValue);
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T, typename JSType&gt; Vector&lt;Ref&lt;T&gt;&gt; toRefNativeArray(JSC::ExecState&amp;, JSC::JSValue);
</span><del>-bool hasIteratorMethod(JSC::ExecState&amp;, JSC::JSValue);
</del><ins>+WEBCORE_EXPORT bool hasIteratorMethod(JSC::ExecState&amp;, JSC::JSValue);
</ins><span class="cx"> 
</span><span class="cx"> bool shouldAllowAccessToNode(JSC::ExecState*, Node*);
</span><span class="cx"> bool shouldAllowAccessToFrame(JSC::ExecState*, Frame*);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMConverth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMConvert.h        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvert.h        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -408,7 +408,7 @@
</span><span class="cx"> // MARK: Dictionary type
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt; struct Converter&lt;IDLDictionary&lt;T&gt;&gt; : DefaultConverter&lt;IDLDictionary&lt;T&gt;&gt; {
</span><del>-    using ReturnType = Optional&lt;T&gt;;
</del><ins>+    using ReturnType = T;
</ins><span class="cx"> 
</span><span class="cx">     static ReturnType convert(JSC::ExecState&amp; state, JSC::JSValue value)
</span><span class="cx">     {
</span><span class="lines">@@ -476,18 +476,34 @@
</span><span class="cx">     using TypeList = typename Type::TypeList;
</span><span class="cx">     using ReturnType = typename Type::ImplementationType;
</span><span class="cx"> 
</span><del>-    using DictionaryTypeList = brigand::find&lt;TypeList, IsIDLDictionary&lt;brigand::_1&gt;&gt;;
-    using DictionaryType = ConditionalFront&lt;DictionaryTypeList, brigand::size&lt;DictionaryTypeList&gt;::value != 0&gt;;
-    static_assert(brigand::size&lt;DictionaryTypeList&gt;::value == 0 || brigand::size&lt;DictionaryTypeList&gt;::value == 1, &quot;There can be 0 or 1 dictionary types in an IDLUnion.&quot;);
</del><ins>+    using NumericTypeList = brigand::filter&lt;TypeList, IsIDLNumber&lt;brigand::_1&gt;&gt;;
+    static constexpr size_t numberOfNumericTypes = brigand::size&lt;NumericTypeList&gt;::value;
+    static_assert(numberOfNumericTypes == 0 || numberOfNumericTypes == 1, &quot;There can be 0 or 1 numeric types in an IDLUnion.&quot;);
+    using NumericType = ConditionalFront&lt;NumericTypeList, numberOfNumericTypes != 0&gt;;
</ins><span class="cx"> 
</span><del>-    using NumericTypeList = brigand::find&lt;TypeList, IsIDLNumber&lt;brigand::_1&gt;&gt;;
-    using NumericType = ConditionalFront&lt;NumericTypeList, brigand::size&lt;NumericTypeList&gt;::value != 0&gt;;
-    static_assert(brigand::size&lt;NumericTypeList&gt;::value == 0 || brigand::size&lt;NumericTypeList&gt;::value == 1, &quot;There can be 0 or 1 numeric types in an IDLUnion.&quot;);
</del><ins>+    // FIXME: This should also check for IDLEnumeration&lt;T&gt;.
+    using StringTypeList = brigand::filter&lt;TypeList, std::is_base_of&lt;IDLString, brigand::_1&gt;&gt;;
+    static constexpr size_t numberOfStringTypes = brigand::size&lt;StringTypeList&gt;::value;
+    static_assert(numberOfStringTypes == 0 || numberOfStringTypes == 1, &quot;There can be 0 or 1 string types in an IDLUnion.&quot;);
+    using StringType = ConditionalFront&lt;StringTypeList, numberOfStringTypes != 0&gt;;
</ins><span class="cx"> 
</span><del>-    using StringTypeList = brigand::find&lt;TypeList, std::is_base_of&lt;IDLString, brigand::_1&gt;&gt;;
-    using StringType = ConditionalFront&lt;StringTypeList, brigand::size&lt;StringTypeList&gt;::value != 0&gt;;
-    static_assert(brigand::size&lt;StringTypeList&gt;::value == 0 || brigand::size&lt;StringTypeList&gt;::value == 1, &quot;There can be 0 or 1 string types in an IDLUnion.&quot;);
</del><ins>+    using SequenceTypeList = brigand::filter&lt;TypeList, IsIDLSequence&lt;brigand::_1&gt;&gt;;
+    static constexpr size_t numberOfSequenceTypes = brigand::size&lt;SequenceTypeList&gt;::value;
+    static_assert(numberOfSequenceTypes == 0 || numberOfSequenceTypes == 1, &quot;There can be 0 or 1 sequence types in an IDLUnion.&quot;);
+    using SequenceType = ConditionalFront&lt;SequenceTypeList, numberOfSequenceTypes != 0&gt;;
</ins><span class="cx"> 
</span><ins>+    using FrozenArrayTypeList = brigand::filter&lt;TypeList, IsIDLFrozenArray&lt;brigand::_1&gt;&gt;;
+    static constexpr size_t numberOfFrozenArrayTypes = brigand::size&lt;FrozenArrayTypeList&gt;::value;
+    static_assert(numberOfFrozenArrayTypes == 0 || numberOfFrozenArrayTypes == 1, &quot;There can be 0 or 1 FrozenArray types in an IDLUnion.&quot;);
+    using FrozenArrayType = ConditionalFront&lt;FrozenArrayTypeList, numberOfFrozenArrayTypes != 0&gt;;
+
+    using DictionaryTypeList = brigand::filter&lt;TypeList, IsIDLDictionary&lt;brigand::_1&gt;&gt;;
+    static constexpr size_t numberOfDictionaryTypes = brigand::size&lt;DictionaryTypeList&gt;::value;
+    static_assert(numberOfDictionaryTypes == 0 || numberOfDictionaryTypes == 1, &quot;There can be 0 or 1 dictionary types in an IDLUnion.&quot;);
+    using DictionaryType = ConditionalFront&lt;DictionaryTypeList, numberOfDictionaryTypes != 0&gt;;
+
+    static constexpr bool hasObjectType = (numberOfSequenceTypes + numberOfFrozenArrayTypes + numberOfDictionaryTypes) &gt; 0;
+
</ins><span class="cx">     using InterfaceTypeList = brigand::filter&lt;TypeList, IsIDLInterface&lt;brigand::_1&gt;&gt;;
</span><span class="cx"> 
</span><span class="cx">     static ReturnType convert(JSC::ExecState&amp; state, JSC::JSValue value)
</span><span class="lines">@@ -505,7 +521,7 @@
</span><span class="cx">         // NOTE: Union is expected to be pre-flattented.
</span><span class="cx">         
</span><span class="cx">         // 3. If V is null or undefined, and types includes a dictionary type, then return the result of converting V to that dictionary type.
</span><del>-        constexpr bool hasDictionaryType = brigand::size&lt;DictionaryTypeList&gt;::value != 0;
</del><ins>+        constexpr bool hasDictionaryType = numberOfDictionaryTypes != 0;
</ins><span class="cx">         if (hasDictionaryType) {
</span><span class="cx">             if (value.isUndefinedOrNull())
</span><span class="cx">                 return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, DictionaryType, hasDictionaryType&gt;::convert(state, value).value());
</span><span class="lines">@@ -535,8 +551,57 @@
</span><span class="cx">                 return WTFMove(returnValue.value());
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        // FIXME: Add support for steps 5 - 12.
-        
</del><ins>+        // FIXME: Add support for steps 5 - 11.
+
+        // 12. If V is any kind of object except for a native RegExp object, then:
+        if (hasObjectType) {
+            if (value.isCell()) {
+                JSC::JSCell* cell = value.asCell();
+                if (cell-&gt;isObject() &amp;&amp; cell-&gt;type() != JSC::RegExpObjectType) {
+                    // FIXME: We should be able to optimize the following code by making use
+                    // of the fact that we have proved that the value is an object. 
+                
+                    //     1. If types includes a sequence type, then:
+                    //         1. Let method be the result of GetMethod(V, @@iterator).
+                    //         2. ReturnIfAbrupt(method).
+                    //         3. If method is not undefined, return the result of creating a
+                    //            sequence of that type from V and method.        
+                    constexpr bool hasSequenceType = numberOfSequenceTypes != 0;
+                    if (hasSequenceType) {
+                        bool hasIterator = hasIteratorMethod(state, value);
+                        RETURN_IF_EXCEPTION(scope, ReturnType());
+                        if (hasIterator)
+                            return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, SequenceType, hasSequenceType&gt;::convert(state, value).value());
+                    }
+
+                    //     2. If types includes a frozen array type, then:
+                    //         1. Let method be the result of GetMethod(V, @@iterator).
+                    //         2. ReturnIfAbrupt(method).
+                    //         3. If method is not undefined, return the result of creating a
+                    //            frozen array of that type from V and method.
+                    constexpr bool hasFrozenArrayType = numberOfFrozenArrayTypes != 0;
+                    if (hasFrozenArrayType) {
+                        bool hasIterator = hasIteratorMethod(state, value);
+                        RETURN_IF_EXCEPTION(scope, ReturnType());
+                        if (hasIterator)
+                            return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, FrozenArrayType, hasFrozenArrayType&gt;::convert(state, value).value());
+                    }
+
+                    //     3. If types includes a dictionary type, then return the result of
+                    //        converting V to that dictionary type.
+                    if (hasDictionaryType)
+                        return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, DictionaryType, hasDictionaryType&gt;::convert(state, value).value());
+
+                    //     4. If types includes a record type, then return the result of converting V to that record type.
+                    //         (FIXME: Add support for record types and step 12.4)
+                    //     5. If types includes a callback interface type, then return the result of converting V to that interface type.
+                    //         (FIXME: Add support for callback interface type and step 12.5)
+                    //     6. If types includes object, then return the IDL value that is a reference to the object V.
+                    //         (FIXME: Add support for object and step 12.6)
+                }
+            }
+        }
+
</ins><span class="cx">         // 13. If V is a Boolean value, then:
</span><span class="cx">         //     1. If types includes a boolean, then return the result of converting V to boolean.
</span><span class="cx">         constexpr bool hasBooleanType = brigand::any&lt;TypeList, std::is_same&lt;IDLBoolean, brigand::_1&gt;&gt;::value;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -1008,7 +1008,12 @@
</span><span class="cx">         return $className . &quot;::&quot; . $enumerationValueName;
</span><span class="cx">     }
</span><span class="cx">     if ($defaultValue eq &quot;null&quot;) {
</span><del>-        return &quot;Nullopt&quot; if $signature-&gt;idlType-&gt;isUnion;
</del><ins>+        if ($signature-&gt;idlType-&gt;isUnion) {
+            return &quot;Nullopt&quot; if $signature-&gt;idlType-&gt;isNullable;
+
+            my $IDLType = GetIDLType($interface, $signature-&gt;idlType);
+            return &quot;convert&lt;${IDLType}&gt;(state, jsNull());&quot;;
+        }
</ins><span class="cx">         return &quot;jsNull()&quot; if $signature-&gt;type eq &quot;any&quot;;
</span><span class="cx">         return &quot;nullptr&quot; if $codeGenerator-&gt;IsWrapperType($signature-&gt;type) || $codeGenerator-&gt;IsTypedArrayType($signature-&gt;type);
</span><span class="cx">         return &quot;String()&quot; if $codeGenerator-&gt;IsStringType($signature-&gt;type);
</span><span class="lines">@@ -4364,7 +4369,7 @@
</span><span class="cx">             if ($codeGenerator-&gt;IsTypedArrayType($type) and $parameter-&gt;type ne &quot;ArrayBuffer&quot;) {
</span><span class="cx">                $value = $shouldPassByReference ? &quot;$name.releaseNonNull()&quot; : &quot;WTFMove($name)&quot;;
</span><span class="cx">             } elsif ($codeGenerator-&gt;IsDictionaryType($type)) {
</span><del>-                $value = &quot;${name}.value()&quot;;
</del><ins>+                $value = &quot;${name}&quot;;
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -5763,7 +5768,7 @@
</span><span class="cx">                 if (ShouldPassWrapperByReference($parameter, $interface)) {
</span><span class="cx">                     push(@constructorArgList, &quot;*&quot; . $parameter-&gt;name);
</span><span class="cx">                 } elsif ($codeGenerator-&gt;IsDictionaryType($parameter-&gt;type)) {
</span><del>-                    push(@constructorArgList, $parameter-&gt;name . &quot;.value()&quot;);
</del><ins>+                    push(@constructorArgList, $parameter-&gt;name);
</ins><span class="cx">                 } else {
</span><span class="cx">                     push(@constructorArgList, &quot;WTFMove(&quot; . $parameter-&gt;name . &quot;)&quot;);
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestEventConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx">     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><span class="cx">     auto eventInitDict = convert&lt;IDLDictionary&lt;TestEventConstructor::Init&gt;&gt;(*state, state-&gt;argument(1));
</span><span class="cx">     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><del>-    auto object = TestEventConstructor::create(WTFMove(type), eventInitDict.value());
</del><ins>+    auto object = TestEventConstructor::create(WTFMove(type), eventInitDict);
</ins><span class="cx">     return JSValue::encode(toJSNewlyCreated(state, castedThis-&gt;globalObject(), WTFMove(object)));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -7710,7 +7710,7 @@
</span><span class="cx">         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
</span><span class="cx">     auto init = convert&lt;IDLDictionary&lt;TestObj::Dictionary&gt;&gt;(*state, state-&gt;uncheckedArgument(0));
</span><span class="cx">     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><del>-    impl.attachShadowRoot(init.value());
</del><ins>+    impl.attachShadowRoot(init);
</ins><span class="cx">     return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -7730,7 +7730,7 @@
</span><span class="cx">         return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
</span><span class="cx">     auto dict = convert&lt;IDLDictionary&lt;DictionaryImplName&gt;&gt;(*state, state-&gt;uncheckedArgument(0));
</span><span class="cx">     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><del>-    impl.operationWithExternalDictionaryParameter(dict.value());
</del><ins>+    impl.operationWithExternalDictionaryParameter(dict);
</ins><span class="cx">     return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoretestingTypeConversionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/TypeConversions.h (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/TypeConversions.h        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/testing/TypeConversions.h        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -26,8 +26,11 @@
</span><span class="cx"> #ifndef TypeConversions_h
</span><span class="cx"> #define TypeConversions_h
</span><span class="cx"> 
</span><ins>+#include &quot;Node.h&quot;
</ins><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><ins>+#include &lt;wtf/Variant.h&gt;
+#include &lt;wtf/Vector.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -36,6 +39,24 @@
</span><span class="cx"> public:
</span><span class="cx">     static Ref&lt;TypeConversions&gt; create() { return adoptRef(*new TypeConversions()); }
</span><span class="cx"> 
</span><ins>+    enum class UnionType {
+        Node,
+        Sequence,
+        Dictionary
+    };
+
+    struct OtherDictionary {
+        int longValue;
+        String stringValue;
+    };
+
+    struct Dictionary {
+        int longValue;
+        String stringValue;
+        Vector&lt;String&gt; sequenceValue;
+        Variant&lt;RefPtr&lt;Node&gt;, Vector&lt;String&gt;, OtherDictionary&gt; unionValue;
+    };
+
</ins><span class="cx">     long testLong() { return m_long; }
</span><span class="cx">     void setTestLong(long value) { m_long = value; }
</span><span class="cx">     long testEnforceRangeLong() { return m_long; }
</span><span class="lines">@@ -77,21 +98,46 @@
</span><span class="cx">     const String&amp; testUSVString() const { return m_usvstring; }
</span><span class="cx">     void setTestUSVString(const String&amp; usvstring) { m_usvstring = usvstring; }
</span><span class="cx"> 
</span><ins>+    void setTypeConversionsDictionary(Dictionary&amp; dictionary)
+    {
+        m_typeConversionsDictionaryLongValue = dictionary.longValue;
+        m_typeConversionsDictionaryStringValue = dictionary.stringValue;
+        m_typeConversionsDictionarySequenceValue = dictionary.sequenceValue;
+        m_typeConversionsDictionaryUnionValue = dictionary.unionValue;
+    }
+
+    int typeConversionsDictionaryLongValue() { return m_typeConversionsDictionaryLongValue; }
+    String typeConversionsDictionaryStringValue() { return m_typeConversionsDictionaryStringValue; }
+    Vector&lt;String&gt; typeConversionsDictionarySequenceValue() { return m_typeConversionsDictionarySequenceValue; }
+    UnionType typeConversionsDictionaryUnionType()
+    {
+        return WTF::visit(WTF::makeVisitor(
+            [](const RefPtr&lt;Node&gt;&amp;) -&gt; UnionType { return UnionType::Node; },
+            [](const Vector&lt;String&gt;&amp;) -&gt; UnionType { return UnionType::Sequence; },
+            [](const OtherDictionary&amp;) -&gt; UnionType { return UnionType::Dictionary; }
+        ), m_typeConversionsDictionaryUnionValue);
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     TypeConversions()
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    long m_long;
-    unsigned long m_unsignedLong;
-    long long m_longLong;
-    unsigned long long m_unsignedLongLong;
-    int8_t m_byte;
-    uint8_t m_octet;
-    int16_t m_short;
-    uint16_t m_UnsignedShort;
</del><ins>+    long m_long { 0 };
+    unsigned long m_unsignedLong { 0 };
+    long long m_longLong { 0 };
+    unsigned long long m_unsignedLongLong { 0 };
+    int8_t m_byte { 0 };
+    uint8_t m_octet { 0 };
+    int16_t m_short { 0 };
+    uint16_t m_UnsignedShort { 0 };
</ins><span class="cx">     String m_string;
</span><span class="cx">     String m_usvstring;
</span><ins>+    
+    int m_typeConversionsDictionaryLongValue { 0 };
+    String m_typeConversionsDictionaryStringValue;
+    Vector&lt;String&gt; m_typeConversionsDictionarySequenceValue;
+    Variant&lt;RefPtr&lt;Node&gt;, Vector&lt;String&gt;, OtherDictionary&gt; m_typeConversionsDictionaryUnionValue;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoretestingTypeConversionsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/TypeConversions.idl (207574 => 207575)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/TypeConversions.idl        2016-10-19 23:01:22 UTC (rev 207574)
+++ trunk/Source/WebCore/testing/TypeConversions.idl        2016-10-19 23:31:14 UTC (rev 207575)
</span><span class="lines">@@ -23,6 +23,8 @@
</span><span class="cx">  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><ins>+enum UnionType { &quot;node&quot;, &quot;sequence&quot;, &quot;dictionary&quot; };
+
</ins><span class="cx"> [
</span><span class="cx">     NoInterfaceObject,
</span><span class="cx">     ImplementationLacksVTable,
</span><span class="lines">@@ -50,4 +52,22 @@
</span><span class="cx"> 
</span><span class="cx">     attribute DOMString testString;
</span><span class="cx">     attribute USVString testUSVString;
</span><ins>+    
+    void setTypeConversionsDictionary(TypeConversionsDictionary d);
+    readonly attribute long typeConversionsDictionaryLongValue;
+    readonly attribute DOMString typeConversionsDictionaryStringValue;
+    readonly attribute sequence&lt;DOMString&gt; typeConversionsDictionarySequenceValue;
+    readonly attribute UnionType typeConversionsDictionaryUnionType; 
</ins><span class="cx"> };
</span><ins>+
+dictionary TypeConversionsOtherDictionary {
+    long longValue = 0;
+    DOMString stringValue = &quot;&quot;;
+};
+
+dictionary TypeConversionsDictionary {
+    long longValue = 0;
+    DOMString stringValue = &quot;&quot;;
+    sequence&lt;DOMString&gt; sequenceValue = [];
+    (Node or sequence&lt;DOMString&gt; or TypeConversionsOtherDictionary) unionValue = null;
+};
</ins></span></pre>
</div>
</div>

</body>
</html>