<!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>[208893] 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/208893">208893</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2016-11-18 13:47:42 -0800 (Fri, 18 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WebIDL] Add support for record types
https://bugs.webkit.org/show_bug.cgi?id=164935

Reviewed by Tim Horton.

Source/WebCore:

Add support for WebIDLs record types. We map them to HashMap&lt;String, {OtherType}&gt;.

* bindings/generic/IDLTypes.h:
- Add IDLRecord type and helper predicate.
- Remove IDLRegExp which is no longer in WebIDL and we never supported.

* bindings/js/JSDOMBinding.cpp:
(WebCore::stringToByteString):
(WebCore::identifierToByteString):
(WebCore::valueToByteString):
(WebCore::hasUnpairedSurrogate):
(WebCore::stringToUSVString):
(WebCore::identifierToUSVString):
(WebCore::valueToUSVString):
* bindings/js/JSDOMBinding.h:
Refactor ByteString and USVString conversion to support converting from
either a JSValue or Identifier.

* bindings/js/JSDOMConvert.h:
(WebCore::DetailConverter&lt;IDLRecord&lt;K, V&gt;&gt;):
(WebCore::JSConverter&lt;IDLRecord&lt;K, V&gt;&gt;):
Add conversion support for record types. Use Detail::IdentifierConverter helper
to convert identifiers to strings using the correct conversion rules.

(WebCore::Converter&lt;IDLUnion&lt;T...&gt;&gt;::convert):
Update comments in union conversion to match current spec. Remove check
for regular expressions and add support for record types.

* bindings/scripts/CodeGenerator.pm:
(IsRefPtrType):
Add record and union types to the list of things that aren't RefPtrs.

(IsRecordType):
Add predicate for testing if a type is a record.

(IsWrapperType):
Remove check for union. This is now handled in the IsRefPtrType check.

(SkipIncludeHeader): Deleted.
(GetSequenceInnerType): Deleted.
(GetFrozenArrayInnerType): Deleted.
(GetSequenceOrFrozenArrayInnerType): Deleted.
Remove no longer necessary functions.

* bindings/scripts/CodeGeneratorJS.pm:
(AddIncludesForImplementationType):
Remove check for includes to skip. This is now only called for interfaces, which should be included
unconditionally.

(AddToIncludesForIDLType):
Add includes and recursive includes for record types.

(GenerateOverloadedFunctionOrConstructor):
Update to account for records.

(GetGnuVTableRefForInterface):
(GetGnuVTableNameForInterface):
(GetGnuMangledNameForInterface):
(GetWinVTableNameForInterface):
(GetWinMangledNameForInterface):
Strength-reduce GetNativeTypeForConversions and GetNamespaceForInterface into their callers.

(GetBaseIDLType):
Add support for IDLRecord. Remove call to GetIDLInterfaceName now that is simply the type name.

(GetNativeType):
Simplify sequence/FrozenArray support and add record support.

(GetNativeInnerType):
Generalize GetNativeVectorInnerType to work for record types as well.

(ShouldPassWrapperByReference):
Moved so native type accessors can be together.

(NativeToJSValueDOMConvertNeedsState):
(NativeToJSValueDOMConvertNeedsGlobalObject):
Add record support.

(GetNativeTypeForConversions): Deleted.
(GetNamespaceForInterface): Deleted.
(GetNativeVectorType): Deleted.
(GetIDLInterfaceName): Deleted.
(GetNativeVectorInnerType): Deleted.
Remove unneeded functions.

* bindings/scripts/IDLParser.pm:
(typeDescription):
Add helper useful for debugging, that constructs the string form of a type.

(typeByApplyingTypedefs):
Add missing call to typeByApplyingTypedefs (this is noted by a fix in JSTestCallbackFunctionWithTypedefs.h)

(parseNonAnyType):
Remove unused $subtypeName variables and add support for parsing record types.

* bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp:
* bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h:
* bindings/scripts/test/JS/JSTestObj.cpp:
* bindings/scripts/test/TestObj.idl:
Add tests for records and update results.

* testing/TypeConversions.h:
(WebCore::TypeConversions::testLongRecord):
(WebCore::TypeConversions::setTestLongRecord):
(WebCore::TypeConversions::testNodeRecord):
(WebCore::TypeConversions::setTestNodeRecord):
(WebCore::TypeConversions::testSequenceRecord):
(WebCore::TypeConversions::setTestSequenceRecord):
* testing/TypeConversions.idl:
Add record types so it can be tested from layout tests.

LayoutTests:

* js/dom/webidl-type-mapping-expected.txt:
* js/dom/webidl-type-mapping.html:
Add tests for WebIDL record types.</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="#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="#trunkSourceWebCorebindingsscriptsCodeGeneratorpm">trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm</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="#trunkSourceWebCorebindingsscriptstestJSJSTestCallbackFunctionWithTypedefscpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestCallbackFunctionWithTypedefsh">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp">trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsscriptstestTestObjidl">trunk/Source/WebCore/bindings/scripts/test/TestObj.idl</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 (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/LayoutTests/ChangeLog        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-11-18  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        [WebIDL] Add support for record types
+        https://bugs.webkit.org/show_bug.cgi?id=164935
+
+        Reviewed by Tim Horton.
+
+        * js/dom/webidl-type-mapping-expected.txt:
+        * js/dom/webidl-type-mapping.html:
+        Add tests for WebIDL record types.
+
</ins><span class="cx"> 2016-11-17  Jiewen Tan  &lt;jiewen_tan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Update SubtleCrypto::encrypt to match the latest spec
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomwebidltypemappingexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/LayoutTests/js/dom/webidl-type-mapping-expected.txt        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -1075,6 +1075,8 @@
</span><span class="cx"> PASS converter.testUSVString is &quot;undefined&quot;
</span><span class="cx"> PASS converter.testString is &quot;undefined&quot;
</span><span class="cx"> PASS converter.testByteString is &quot;undefined&quot;
</span><ins>+
+Testing union conversion
</ins><span class="cx"> converter.testUnion = 'hello'
</span><span class="cx"> PASS converter.testUnion is 'hello'
</span><span class="cx"> PASS typeof converter.testUnion is 'string'
</span><span class="lines">@@ -1123,6 +1125,71 @@
</span><span class="cx"> PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
</span><span class="cx"> converter.setTypeConversionsDictionary({ })
</span><span class="cx"> PASS converter.typeConversionsDictionaryUnionType is 'dictionary'
</span><ins>+
+Testing record conversion
+converter.testLongRecord = { key: 1, key2: 2 }
+PASS converter.testLongRecord is an instance of Object
+PASS converter.testLongRecord.hasOwnProperty('key') is true
+PASS 'key' in converter.testLongRecord is true
+PASS converter.testLongRecord['key'] is 1
+PASS converter.testLongRecord.hasOwnProperty('key2') is true
+PASS 'key2' in converter.testLongRecord is true
+PASS converter.testLongRecord['key2'] is 2
+converter.testLongRecord = undefined
+PASS converter.testLongRecord is an instance of Object
+converter.testLongRecord = null
+PASS converter.testLongRecord is an instance of Object
+PASS converter.testLongRecord = 1 threw exception TypeError: Type error.
+PASS converter.testLongRecord = { key: { valueOf:function() { throw new Error(); } } } threw exception Error.
+var o = { otherKey: 2 }; Object.defineProperty(o, 'key', { enumerable: false, value: 1 }); converter.testLongRecord = o;
+PASS converter.testLongRecord.hasOwnProperty('key') is false
+PASS converter.testLongRecord.hasOwnProperty('otherKey') is true
+PASS converter.testLongRecord['otherKey'] is 2
+var o = { otherKey: 2 }; Object.defineProperty(o, 'key', { get: function() { return 1; }, enumerable: true }); converter.testLongRecord = o;
+PASS converter.testLongRecord.hasOwnProperty('key') is true
+PASS converter.testLongRecord['key'] is 1
+PASS converter.testLongRecord.hasOwnProperty('otherKey') is true
+PASS converter.testLongRecord['otherKey'] is 2
+PASS var o = { otherKey: 2 }; Object.defineProperty(o, 'key', { get: function() { throw new Error();; }, enumerable: true }); converter.testLongRecord = o; threw exception Error.
+converter.testNodeRecord = { key: document, key2: document.documentElement }
+PASS converter.testNodeRecord.hasOwnProperty('key') is true
+PASS 'key' in converter.testNodeRecord is true
+PASS converter.testNodeRecord['key'] is document
+PASS converter.testNodeRecord.hasOwnProperty('key2') is true
+PASS 'key2' in converter.testNodeRecord is true
+PASS converter.testNodeRecord['key2'] is document.documentElement
+PASS converter.testNodeRecord = { key: 'hello' } threw exception TypeError: Type error.
+converter.testLongRecord = {'í €': 1 }
+PASS converter.testLongRecord['í €'] is 1
+converter.testNodeRecord = {'í €': document }
+PASS converter.testNodeRecord['�'] is document
+converter.testLongRecord = {'í°€': 1 }
+PASS converter.testLongRecord['í°€'] is 1
+converter.testNodeRecord = {'í°€': document }
+PASS converter.testNodeRecord['�'] is document
+converter.testLongRecord = {'í €': 1 }
+PASS converter.testLongRecord['í €\0'] is 1
+converter.testNodeRecord = {'í €': document }
+PASS converter.testNodeRecord['�\0'] is document
+converter.testLongRecord = {'í°€': 1 }
+PASS converter.testLongRecord['í°€\0'] is 1
+converter.testNodeRecord = {'í°€': document }
+PASS converter.testNodeRecord['�\0'] is document
+converter.testLongRecord = {'í°€í €': 1 }
+PASS converter.testLongRecord['í°€í €'] is 1
+converter.testNodeRecord = {'í°€í €': document }
+PASS converter.testNodeRecord['��'] is document
+converter.testLongRecord = {'𝄞': 1 }
+PASS converter.testLongRecord['𝄞'] is 1
+converter.testNodeRecord = {'𝄞': document }
+PASS converter.testNodeRecord['𝄞'] is document
+converter.testSequenceRecord = { key: ['value', 'other value'] }
+PASS converter.testSequenceRecord.hasOwnProperty('key') is true
+PASS 'key' in converter.testSequenceRecord is true
+PASS converter.testSequenceRecord['key'] is ['value', 'other value']
+PASS converter.testSequenceRecord = { 'Ā': ['value'] } threw exception TypeError: Type error.
+converter.testSequenceRecord = { 'ÿ': ['value'] }
+PASS converter.testSequenceRecord['ÿ'] is ['value']
</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 (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/webidl-type-mapping.html        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/LayoutTests/js/dom/webidl-type-mapping.html        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -598,7 +598,8 @@
</span><span class="cx">     shouldBeEqualToString(&quot;converter.testByteString&quot;, value);
</span><span class="cx"> });
</span><span class="cx"> 
</span><del>-
</del><ins>+debug(&quot;&quot;);
+debug(&quot;Testing union conversion&quot;)
</ins><span class="cx"> evalAndLog(&quot;converter.testUnion = 'hello'&quot;);
</span><span class="cx"> shouldBe(&quot;converter.testUnion&quot;, &quot;'hello'&quot;);
</span><span class="cx"> shouldBe(&quot;typeof converter.testUnion&quot;, &quot;'string'&quot;);
</span><span class="lines">@@ -650,5 +651,68 @@
</span><span class="cx"> evalAndLog(&quot;converter.setTypeConversionsDictionary({ })&quot;);
</span><span class="cx"> shouldBe(&quot;converter.typeConversionsDictionaryUnionType&quot;, &quot;'dictionary'&quot;);
</span><span class="cx"> 
</span><ins>+
+debug(&quot;&quot;);
+debug(&quot;Testing record conversion&quot;)
+
+// testLongRecord is a record&lt;DOMString, long&gt; attribute
+// testNodeRecord is a record&lt;USVString, Node&gt; attribute
+// testSequenceRecord is a record&lt;ByteString, sequence&lt;DOMString&gt;&gt; attribute
+
+evalAndLog(&quot;converter.testLongRecord = { key: 1, key2: 2 }&quot;);
+shouldBeType(&quot;converter.testLongRecord&quot;, &quot;Object&quot;);
+shouldBeTrue(&quot;converter.testLongRecord.hasOwnProperty('key')&quot;);
+shouldBeTrue(&quot;'key' in converter.testLongRecord&quot;);
+shouldBe(&quot;converter.testLongRecord['key']&quot;, &quot;1&quot;);
+shouldBeTrue(&quot;converter.testLongRecord.hasOwnProperty('key2')&quot;);
+shouldBeTrue(&quot;'key2' in converter.testLongRecord&quot;);
+shouldBe(&quot;converter.testLongRecord['key2']&quot;, &quot;2&quot;);
+evalAndLog(&quot;converter.testLongRecord = undefined&quot;);
+shouldBeType(&quot;converter.testLongRecord&quot;, &quot;Object&quot;);
+evalAndLog(&quot;converter.testLongRecord = null&quot;);
+shouldBeType(&quot;converter.testLongRecord&quot;, &quot;Object&quot;);
+shouldThrow(&quot;converter.testLongRecord = 1&quot;);
+shouldThrow(&quot;converter.testLongRecord = { key: { valueOf:function() { throw new Error(); } } }&quot;);
+evalAndLog(&quot;var o = { otherKey: 2 }; Object.defineProperty(o, 'key', { enumerable: false, value: 1 }); converter.testLongRecord = o;&quot;);
+shouldBeFalse(&quot;converter.testLongRecord.hasOwnProperty('key')&quot;);
+shouldBeTrue(&quot;converter.testLongRecord.hasOwnProperty('otherKey')&quot;);
+shouldBe(&quot;converter.testLongRecord['otherKey']&quot;, &quot;2&quot;);
+evalAndLog(&quot;var o = { otherKey: 2 }; Object.defineProperty(o, 'key', { get: function() { return 1; }, enumerable: true }); converter.testLongRecord = o;&quot;);
+shouldBeTrue(&quot;converter.testLongRecord.hasOwnProperty('key')&quot;);
+shouldBe(&quot;converter.testLongRecord['key']&quot;, &quot;1&quot;);
+shouldBeTrue(&quot;converter.testLongRecord.hasOwnProperty('otherKey')&quot;);
+shouldBe(&quot;converter.testLongRecord['otherKey']&quot;, &quot;2&quot;);
+shouldThrow(&quot;var o = { otherKey: 2 }; Object.defineProperty(o, 'key', { get: function() { throw new Error();; }, enumerable: true }); converter.testLongRecord = o;&quot;);
+
+evalAndLog(&quot;converter.testNodeRecord = { key: document, key2: document.documentElement }&quot;);
+shouldBeTrue(&quot;converter.testNodeRecord.hasOwnProperty('key')&quot;);
+shouldBeTrue(&quot;'key' in converter.testNodeRecord&quot;);
+shouldBe(&quot;converter.testNodeRecord['key']&quot;, &quot;document&quot;);
+shouldBeTrue(&quot;converter.testNodeRecord.hasOwnProperty('key2')&quot;);
+shouldBeTrue(&quot;'key2' in converter.testNodeRecord&quot;);
+shouldBe(&quot;converter.testNodeRecord['key2']&quot;, &quot;document.documentElement&quot;);
+shouldThrow(&quot;converter.testNodeRecord = { key: 'hello' }&quot;);
+
+[{input: &quot;\uD800&quot;, expected: &quot;\uFFFD&quot;},
+ {input: &quot;\uDC00&quot;, expected: &quot;\uFFFD&quot;},
+ {input: &quot;\uD800\u0000&quot;, expected: &quot;\uFFFD\u0000&quot;},
+ {input: &quot;\uDC00\u0000&quot;, expected: &quot;\uFFFD\u0000&quot;},
+ {input: &quot;\uDC00\uD800&quot;, expected: &quot;\uFFFD\uFFFD&quot;},
+ {input: &quot;\uD834\uDD1E&quot;, expected: &quot;\uD834\uDD1E&quot;},
+].forEach(function(test) {
+    evalAndLog(&quot;converter.testLongRecord = {'&quot; + test.input + &quot;': 1 }&quot;);
+    shouldBe(&quot;converter.testLongRecord['&quot; + test.input + &quot;']&quot;, &quot;1&quot;);
+    evalAndLog(&quot;converter.testNodeRecord = {'&quot; + test.input + &quot;': document }&quot;);
+    shouldBe(&quot;converter.testNodeRecord['&quot; + test.expected + &quot;']&quot;, &quot;document&quot;);
+});
+
+evalAndLog(&quot;converter.testSequenceRecord = { key: ['value', 'other value'] }&quot;);
+shouldBeTrue(&quot;converter.testSequenceRecord.hasOwnProperty('key')&quot;);
+shouldBeTrue(&quot;'key' in converter.testSequenceRecord&quot;);
+shouldBe(&quot;converter.testSequenceRecord['key']&quot;, &quot;['value', 'other value']&quot;);
+shouldThrow(&quot;converter.testSequenceRecord = { '\u0100': ['value'] }&quot;);
+evalAndLog(&quot;converter.testSequenceRecord = { '\u00FF': ['value'] }&quot;);
+shouldBe(&quot;converter.testSequenceRecord['\u00FF']&quot;, &quot;['value']&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 (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/ChangeLog        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -1,3 +1,121 @@
</span><ins>+2016-11-18  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        [WebIDL] Add support for record types
+        https://bugs.webkit.org/show_bug.cgi?id=164935
+
+        Reviewed by Tim Horton.
+
+        Add support for WebIDLs record types. We map them to HashMap&lt;String, {OtherType}&gt;.
+
+        * bindings/generic/IDLTypes.h:
+        - Add IDLRecord type and helper predicate.
+        - Remove IDLRegExp which is no longer in WebIDL and we never supported.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::stringToByteString):
+        (WebCore::identifierToByteString):
+        (WebCore::valueToByteString):
+        (WebCore::hasUnpairedSurrogate):
+        (WebCore::stringToUSVString):
+        (WebCore::identifierToUSVString):
+        (WebCore::valueToUSVString):
+        * bindings/js/JSDOMBinding.h:
+        Refactor ByteString and USVString conversion to support converting from
+        either a JSValue or Identifier.
+
+        * bindings/js/JSDOMConvert.h:
+        (WebCore::DetailConverter&lt;IDLRecord&lt;K, V&gt;&gt;):
+        (WebCore::JSConverter&lt;IDLRecord&lt;K, V&gt;&gt;):
+        Add conversion support for record types. Use Detail::IdentifierConverter helper
+        to convert identifiers to strings using the correct conversion rules.
+
+        (WebCore::Converter&lt;IDLUnion&lt;T...&gt;&gt;::convert):
+        Update comments in union conversion to match current spec. Remove check
+        for regular expressions and add support for record types.
+
+        * bindings/scripts/CodeGenerator.pm:
+        (IsRefPtrType):
+        Add record and union types to the list of things that aren't RefPtrs.
+
+        (IsRecordType):
+        Add predicate for testing if a type is a record.
+
+        (IsWrapperType):
+        Remove check for union. This is now handled in the IsRefPtrType check.
+
+        (SkipIncludeHeader): Deleted.
+        (GetSequenceInnerType): Deleted.
+        (GetFrozenArrayInnerType): Deleted.
+        (GetSequenceOrFrozenArrayInnerType): Deleted.
+        Remove no longer necessary functions.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (AddIncludesForImplementationType):
+        Remove check for includes to skip. This is now only called for interfaces, which should be included
+        unconditionally.
+
+        (AddToIncludesForIDLType):
+        Add includes and recursive includes for record types.
+
+        (GenerateOverloadedFunctionOrConstructor):
+        Update to account for records.
+
+        (GetGnuVTableRefForInterface):
+        (GetGnuVTableNameForInterface):
+        (GetGnuMangledNameForInterface):
+        (GetWinVTableNameForInterface):
+        (GetWinMangledNameForInterface):
+        Strength-reduce GetNativeTypeForConversions and GetNamespaceForInterface into their callers.
+
+        (GetBaseIDLType):
+        Add support for IDLRecord. Remove call to GetIDLInterfaceName now that is simply the type name.
+
+        (GetNativeType):
+        Simplify sequence/FrozenArray support and add record support.
+
+        (GetNativeInnerType):
+        Generalize GetNativeVectorInnerType to work for record types as well.
+
+        (ShouldPassWrapperByReference):
+        Moved so native type accessors can be together.
+
+        (NativeToJSValueDOMConvertNeedsState):
+        (NativeToJSValueDOMConvertNeedsGlobalObject):
+        Add record support.
+
+        (GetNativeTypeForConversions): Deleted.
+        (GetNamespaceForInterface): Deleted.
+        (GetNativeVectorType): Deleted.
+        (GetIDLInterfaceName): Deleted.
+        (GetNativeVectorInnerType): Deleted.
+        Remove unneeded functions.
+
+        * bindings/scripts/IDLParser.pm:
+        (typeDescription):
+        Add helper useful for debugging, that constructs the string form of a type.
+
+        (typeByApplyingTypedefs):
+        Add missing call to typeByApplyingTypedefs (this is noted by a fix in JSTestCallbackFunctionWithTypedefs.h)
+
+        (parseNonAnyType):
+        Remove unused $subtypeName variables and add support for parsing record types.
+
+        * bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp:
+        * bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h:
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        * bindings/scripts/test/TestObj.idl:
+        Add tests for records and update results.
+
+        * testing/TypeConversions.h:
+        (WebCore::TypeConversions::testLongRecord):
+        (WebCore::TypeConversions::setTestLongRecord):
+        (WebCore::TypeConversions::testNodeRecord):
+        (WebCore::TypeConversions::setTestNodeRecord):
+        (WebCore::TypeConversions::testSequenceRecord):
+        (WebCore::TypeConversions::setTestSequenceRecord):
+        * testing/TypeConversions.idl:
+        Add record types so it can be tested from layout tests.
+
</ins><span class="cx"> 2016-11-18  Dave Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Parser] Support font-variation-settings
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsgenericIDLTypesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/generic/IDLTypes.h (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/generic/IDLTypes.h        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/generic/IDLTypes.h        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/Brigand.h&gt;
</span><ins>+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -116,11 +117,15 @@
</span><span class="cx">     using InnerType = T;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+template&lt;typename K, typename V&gt; struct IDLRecord : IDLType&lt;HashMap&lt;typename K::ImplementationType, typename V::ImplementationType&gt;&gt; {
+    using KeyType = K;
+    using ValueType = V;
+};
+
</ins><span class="cx"> template&lt;typename T&gt; struct IDLPromise : IDLType&lt;DOMPromise&lt;T&gt;&gt; {
</span><span class="cx">     using InnerType = T;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-struct IDLRegExp : IDLUnsupportedType { };
</del><span class="cx"> struct IDLError : IDLUnsupportedType { };
</span><span class="cx"> struct IDLDOMException : IDLUnsupportedType { };
</span><span class="cx"> 
</span><span class="lines">@@ -158,6 +163,9 @@
</span><span class="cx"> struct IsIDLFrozenArray : public std::integral_constant&lt;bool, WTF::IsTemplate&lt;T, IDLFrozenArray&gt;::value&gt; { };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt;
</span><ins>+struct IsIDLRecord : public std::integral_constant&lt;bool, WTF::IsTemplate&lt;T, IDLRecord&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><span class="cx"> template&lt;typename T&gt;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -90,35 +90,26 @@
</span><span class="cx">     return jsStringWithCache(exec, url.string());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline bool hasUnpairedSurrogate(StringView string)
</del><ins>+static inline String stringToByteString(ExecState&amp; state, JSC::ThrowScope&amp; scope, String&amp;&amp; string)
</ins><span class="cx"> {
</span><del>-    // Fast path for 8-bit strings; they can't have any surrogates.
-    if (string.is8Bit())
-        return false;
-    for (auto codePoint : string.codePoints()) {
-        if (U_IS_SURROGATE(codePoint))
-            return true;
</del><ins>+    if (!string.containsOnlyLatin1()) {
+        throwTypeError(&amp;state, scope);
+        return { };
</ins><span class="cx">     }
</span><del>-    return false;
</del><ins>+
+    return string;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-String valueToByteString(ExecState&amp; state, JSValue value)
</del><ins>+String identifierToByteString(ExecState&amp; state, const Identifier&amp; identifier)
</ins><span class="cx"> {
</span><span class="cx">     VM&amp; vm = state.vm();
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><del>-    String string = value.toWTFString(&amp;state);
-    RETURN_IF_EXCEPTION(scope, { });
-
-    if (!string.containsOnlyLatin1()) {
-        throwTypeError(&amp;state, scope);
-        return { };
-    }
-
-    return string;
</del><ins>+    String string = identifier.string();
+    return stringToByteString(state, scope, WTFMove(string));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-String valueToUSVString(ExecState&amp; state, JSValue value)
</del><ins>+String valueToByteString(ExecState&amp; state, JSValue value)
</ins><span class="cx"> {
</span><span class="cx">     VM&amp; vm = state.vm();
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="lines">@@ -126,6 +117,23 @@
</span><span class="cx">     String string = value.toWTFString(&amp;state);
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, { });
</span><span class="cx"> 
</span><ins>+    return stringToByteString(state, scope, WTFMove(string));
+}
+
+static inline bool hasUnpairedSurrogate(StringView string)
+{
+    // Fast path for 8-bit strings; they can't have any surrogates.
+    if (string.is8Bit())
+        return false;
+    for (auto codePoint : string.codePoints()) {
+        if (U_IS_SURROGATE(codePoint))
+            return true;
+    }
+    return false;
+}
+
+static inline String stringToUSVString(String&amp;&amp; string)
+{
</ins><span class="cx">     // Fast path for the case where there are no unpaired surrogates.
</span><span class="cx">     if (!hasUnpairedSurrogate(string))
</span><span class="cx">         return string;
</span><span class="lines">@@ -144,6 +152,23 @@
</span><span class="cx">     return result.toString();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String identifierToUSVString(ExecState&amp;, const Identifier&amp; identifier)
+{
+    String string = identifier.string();
+    return stringToUSVString(WTFMove(string));
+}
+
+String valueToUSVString(ExecState&amp; state, JSValue value)
+{
+    VM&amp; vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    String string = value.toWTFString(&amp;state);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    return stringToUSVString(WTFMove(string));
+}
+
</ins><span class="cx"> JSValue jsDate(ExecState* exec, double value)
</span><span class="cx"> {
</span><span class="cx">     return DateInstance::create(exec-&gt;vm(), exec-&gt;lexicalGlobalObject()-&gt;dateStructure(), value);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -215,7 +215,9 @@
</span><span class="cx"> 
</span><span class="cx"> AtomicString propertyNameToAtomicString(JSC::PropertyName);
</span><span class="cx"> 
</span><ins>+WEBCORE_EXPORT String identifierToByteString(JSC::ExecState&amp;, const JSC::Identifier&amp;);
</ins><span class="cx"> WEBCORE_EXPORT String valueToByteString(JSC::ExecState&amp;, JSC::JSValue);
</span><ins>+WEBCORE_EXPORT String identifierToUSVString(JSC::ExecState&amp;, const JSC::Identifier&amp;);
</ins><span class="cx"> WEBCORE_EXPORT String valueToUSVString(JSC::ExecState&amp;, JSC::JSValue);
</span><span class="cx"> 
</span><span class="cx"> int32_t finiteInt32Value(JSC::JSValue, JSC::ExecState*, bool&amp; okay);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMConverth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMConvert.h        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvert.h        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -856,6 +856,137 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // MARK: -
</span><ins>+// MARK: Record type
+
+namespace Detail {
+    template&lt;typename IDLStringType&gt;
+    struct IdentifierConverter;
+
+    template&lt;&gt; struct IdentifierConverter&lt;IDLDOMString&gt; {
+        static String convert(JSC::ExecState&amp;, const JSC::Identifier&amp; identifier)
+        {
+            return identifier.string();
+        }
+    };
+
+    template&lt;&gt; struct IdentifierConverter&lt;IDLByteString&gt; {
+        static String convert(JSC::ExecState&amp; state, const JSC::Identifier&amp; identifier)
+        {
+            return identifierToByteString(state, identifier);
+        }
+    };
+
+    template&lt;&gt; struct IdentifierConverter&lt;IDLUSVString&gt; {
+        static String convert(JSC::ExecState&amp; state, const JSC::Identifier&amp; identifier)
+        {
+            return identifierToUSVString(state, identifier);
+        }
+    };
+}
+
+template&lt;typename K, typename V&gt; struct Converter&lt;IDLRecord&lt;K, V&gt;&gt; : DefaultConverter&lt;IDLRecord&lt;K, V&gt;&gt; {
+    using ReturnType = typename IDLRecord&lt;K, V&gt;::ImplementationType;
+    using KeyType = typename K::ImplementationType;
+    using ValueType = typename V::ImplementationType;
+
+    static ReturnType convert(JSC::ExecState&amp; state, JSC::JSValue value)
+    {
+        auto&amp; vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        // 1. Let result be a new empty instance of record&lt;K, V&gt;.
+        // 2. If Type(O) is Undefined or Null, return result.
+        if (value.isUndefinedOrNull())
+            return { };
+        
+        // 3. If Type(O) is not Object, throw a TypeError.
+        if (!value.isObject()) {
+            throwTypeError(&amp;state, scope);
+            return { };
+        }
+        
+        JSC::JSObject* object = JSC::asObject(value);
+    
+        ReturnType result;
+    
+        // 4. Let keys be ? O.[[OwnPropertyKeys]]().
+        JSC::PropertyNameArray keys(&amp;vm, JSC::PropertyNameMode::Strings);
+        object-&gt;getOwnPropertyNames(object, &amp;state, keys, JSC::EnumerationMode());
+        RETURN_IF_EXCEPTION(scope, { });
+
+        // 5. Repeat, for each element key of keys in List order:
+        for (auto&amp; key : keys) {
+            // 1. Let desc be ? O.[[GetOwnProperty]](key).
+            JSC::PropertyDescriptor descriptor;
+            bool didGetDescriptor = object-&gt;getOwnPropertyDescriptor(&amp;state, key, descriptor);
+            RETURN_IF_EXCEPTION(scope, { });
+
+            if (!didGetDescriptor)
+                continue;
+
+            // 2. If desc is not undefined and desc.[[Enumerable]] is true:
+            
+            // FIXME: Do we need to check for enumerable / undefined, or is this handled by the default
+            // enumeration mode?
+
+            if (!descriptor.value().isUndefined() &amp;&amp; descriptor.enumerable()) {
+                // 1. Let typedKey be key converted to an IDL value of type K.
+                auto typedKey = Detail::IdentifierConverter&lt;K&gt;::convert(state, key);
+
+                // 2. Let value be ? Get(O, key).
+                auto subValue = object-&gt;get(&amp;state, key);
+                RETURN_IF_EXCEPTION(scope, { });
+
+                // 3. Let typedValue be value converted to an IDL value of type V.
+                auto typedValue = Converter&lt;V&gt;::convert(state, subValue);
+                RETURN_IF_EXCEPTION(scope, { });
+                
+                // 4. If typedKey is already a key in result, set its value to typedValue.
+                // Note: This can happen when O is a proxy object.
+                // 5. Otherwise, append to result a mapping (typedKey, typedValue).
+                result.set(typedKey, typedValue);
+            }
+        }
+
+        // 6. Return result.
+        return result;
+    }
+};
+
+template&lt;typename K, typename V&gt; struct JSConverter&lt;IDLRecord&lt;K, V&gt;&gt; {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    template&lt;typename ValueType&gt;
+    static JSC::JSValue convert(JSC::ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, const HashMap&lt;String, ValueType&gt;&amp; map)
+    {
+        auto&amp; vm = state.vm();
+    
+        // 1. Let result be ! ObjectCreate(%ObjectPrototype%).
+        auto result = constructEmptyObject(&amp;state);
+        
+        // 2. Repeat, for each mapping (key, value) in D:
+        for (const auto&amp; keyValuePair : map) {
+            // 1. Let esKey be key converted to an ECMAScript value.
+            // Note, this step is not required, as we need the key to be
+            // an Identifier, not a JSValue.
+
+            // 2. Let esValue be value converted to an ECMAScript value.
+            auto esValue = toJS&lt;V&gt;(state, globalObject, keyValuePair.value);
+
+            // 3. Let created be ! CreateDataProperty(result, esKey, esValue).
+            bool created = result-&gt;putDirect(vm, JSC::Identifier::fromString(&amp;vm, keyValuePair.key), esValue);
+
+            // 4. Assert: created is true.
+            ASSERT_UNUSED(created, created);
+        }
+
+        // 3. Return result.
+        return result;
+    }
+};
+
+// MARK: -
</ins><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><span class="lines">@@ -958,10 +1089,17 @@
</span><span class="cx">     using DictionaryTypeList = brigand::filter&lt;TypeList, IsIDLDictionary&lt;brigand::_1&gt;&gt;;
</span><span class="cx">     static constexpr size_t numberOfDictionaryTypes = brigand::size&lt;DictionaryTypeList&gt;::value;
</span><span class="cx">     static_assert(numberOfDictionaryTypes == 0 || numberOfDictionaryTypes == 1, &quot;There can be 0 or 1 dictionary types in an IDLUnion.&quot;);
</span><del>-    using DictionaryType = ConditionalFront&lt;DictionaryTypeList, numberOfDictionaryTypes != 0&gt;;
</del><ins>+    static constexpr bool hasDictionaryType = numberOfDictionaryTypes != 0;
+    using DictionaryType = ConditionalFront&lt;DictionaryTypeList, hasDictionaryType&gt;;
</ins><span class="cx"> 
</span><del>-    static constexpr bool hasObjectType = (numberOfSequenceTypes + numberOfFrozenArrayTypes + numberOfDictionaryTypes) &gt; 0;
</del><ins>+    using RecordTypeList = brigand::filter&lt;TypeList, IsIDLRecord&lt;brigand::_1&gt;&gt;;
+    static constexpr size_t numberOfRecordTypes = brigand::size&lt;RecordTypeList&gt;::value;
+    static_assert(numberOfRecordTypes == 0 || numberOfRecordTypes == 1, &quot;There can be 0 or 1 record types in an IDLUnion.&quot;);
+    static constexpr bool hasRecordType = numberOfRecordTypes != 0;
+    using RecordType = ConditionalFront&lt;RecordTypeList, hasRecordType&gt;;
</ins><span class="cx"> 
</span><ins>+    static constexpr bool hasObjectType = (numberOfSequenceTypes + numberOfFrozenArrayTypes + numberOfDictionaryTypes + numberOfRecordTypes) &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">@@ -978,11 +1116,17 @@
</span><span class="cx">         // 2. Let types be the flattened member types of the union type.
</span><span class="cx">         // NOTE: Union is expected to be pre-flattented.
</span><span class="cx">         
</span><del>-        // 3. If V is null or undefined, and types includes a dictionary type, then return the result of converting V to that dictionary type.
-        constexpr bool hasDictionaryType = numberOfDictionaryTypes != 0;
-        if (hasDictionaryType) {
-            if (value.isUndefinedOrNull())
-                return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, DictionaryType, hasDictionaryType&gt;::convert(state, value).value());
</del><ins>+        // 3. If V is null or undefined then:
+        if (hasDictionaryType || hasRecordType) {
+            if (value.isUndefinedOrNull()) {
+                //     1. 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());
+                
+                //     2. If types includes a record type, then return the result of converting V to that record type.
+                if (hasRecordType)
+                    return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, RecordType, hasRecordType&gt;::convert(state, value).value());
+            }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // 4. If V is a platform object, then:
</span><span class="lines">@@ -1011,13 +1155,13 @@
</span><span class="cx">                 return WTFMove(returnValue.value());
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        // FIXME: Add support for steps 5 - 11.
</del><ins>+        // FIXME: Add support for steps 5 - 10.
</ins><span class="cx"> 
</span><del>-        // 12. If V is any kind of object except for a native RegExp object, then:
</del><ins>+        // 11. If V is any kind of object, then:
</ins><span class="cx">         if (hasObjectType) {
</span><span class="cx">             if (value.isCell()) {
</span><span class="cx">                 JSC::JSCell* cell = value.asCell();
</span><del>-                if (cell-&gt;isObject() &amp;&amp; cell-&gt;type() != JSC::RegExpObjectType) {
</del><ins>+                if (cell-&gt;isObject()) {
</ins><span class="cx">                     // FIXME: We should be able to optimize the following code by making use
</span><span class="cx">                     // of the fact that we have proved that the value is an object. 
</span><span class="cx">                 
</span><span class="lines">@@ -1053,7 +1197,9 @@
</span><span class="cx">                         return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, DictionaryType, hasDictionaryType&gt;::convert(state, value).value());
</span><span class="cx"> 
</span><span class="cx">                     //     4. If types includes a record type, then return the result of converting V to that record type.
</span><del>-                    //         (FIXME: Add support for record types and step 12.4)
</del><ins>+                    if (hasRecordType)
+                        return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, RecordType, hasRecordType&gt;::convert(state, value).value());
+
</ins><span class="cx">                     //     5. If types includes a callback interface type, then return the result of converting V to that interface type.
</span><span class="cx">                     //         (FIXME: Add support for callback interface type and step 12.5)
</span><span class="cx">                     //     6. If types includes object, then return the IDL value that is a reference to the object V.
</span><span class="lines">@@ -1062,7 +1208,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        // 13. If V is a Boolean value, then:
</del><ins>+        // 12. If V is a Boolean value, then:
</ins><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 class="cx">         if (hasBooleanType) {
</span><span class="lines">@@ -1070,7 +1216,7 @@
</span><span class="cx">                 return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, IDLBoolean, hasBooleanType&gt;::convert(state, value).value());
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        // 14. If V is a Number value, then:
</del><ins>+        // 13. If V is a Number value, then:
</ins><span class="cx">         //     1. If types includes a numeric type, then return the result of converting V to that numeric type.
</span><span class="cx">         constexpr bool hasNumericType = brigand::size&lt;NumericTypeList&gt;::value != 0;
</span><span class="cx">         if (hasNumericType) {
</span><span class="lines">@@ -1078,20 +1224,20 @@
</span><span class="cx">                 return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, NumericType, hasNumericType&gt;::convert(state, value).value());
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        // 15. If types includes a string type, then return the result of converting V to that type.
</del><ins>+        // 14. If types includes a string type, then return the result of converting V to that type.
</ins><span class="cx">         constexpr bool hasStringType = brigand::size&lt;StringTypeList&gt;::value != 0;
</span><span class="cx">         if (hasStringType)
</span><span class="cx">             return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, StringType, hasStringType&gt;::convert(state, value).value());
</span><span class="cx"> 
</span><del>-        // 16. If types includes a numeric type, then return the result of converting V to that numeric type.
</del><ins>+        // 15. If types includes a numeric type, then return the result of converting V to that numeric type.
</ins><span class="cx">         if (hasNumericType)
</span><span class="cx">             return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, NumericType, hasNumericType&gt;::convert(state, value).value());
</span><span class="cx"> 
</span><del>-        // 17. If types includes a boolean, then return the result of converting V to boolean.
</del><ins>+        // 16. If types includes a boolean, then return the result of converting V to boolean.
</ins><span class="cx">         if (hasBooleanType)
</span><span class="cx">             return std::move&lt;WTF::CheckMoveParameter&gt;(ConditionalConverter&lt;ReturnType, IDLBoolean, hasBooleanType&gt;::convert(state, value).value());
</span><span class="cx"> 
</span><del>-        // 18. Throw a TypeError.
</del><ins>+        // 17. Throw a TypeError.
</ins><span class="cx">         throwTypeError(&amp;state, scope);
</span><span class="cx">         return ReturnType();
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -352,23 +352,6 @@
</span><span class="cx"> 
</span><span class="cx"> # Helpers for all CodeGenerator***.pm modules
</span><span class="cx"> 
</span><del>-sub SkipIncludeHeader
-{
-    my ($object, $typeName) = @_;
-
-    # FIXME: This is a lot like !IsRefPtrType. Maybe they could share code?
-
-    return 1 if $primitiveTypeHash{$typeName};
-    return 1 if $integerTypeHash{$typeName};
-    return 1 if $floatingPointTypeHash{$typeName};
-    return 1 if $typedArrayTypes{$typeName};
-    return 1 if $stringTypeHash{$typeName};
-    return 1 if $typeName eq &quot;BufferSource&quot;;
-    return 1 if $typeName eq &quot;any&quot;;
-
-    return 0;
-}
-
</del><span class="cx"> sub IsNumericType
</span><span class="cx"> {
</span><span class="cx">     my ($object, $type) = @_;
</span><span class="lines">@@ -616,7 +599,9 @@
</span><span class="cx">     return 0 if $object-&gt;IsDictionaryType($type);
</span><span class="cx">     return 0 if $object-&gt;IsEnumType($type);
</span><span class="cx">     return 0 if $object-&gt;IsSequenceOrFrozenArrayType($type);
</span><ins>+    return 0 if $object-&gt;IsRecordType($type);
</ins><span class="cx">     return 0 if $object-&gt;IsStringType($type);
</span><ins>+    return 0 if $type-&gt;isUnion;
</ins><span class="cx">     return 0 if $type-&gt;name eq &quot;any&quot;;
</span><span class="cx"> 
</span><span class="cx">     return 1;
</span><span class="lines">@@ -656,15 +641,6 @@
</span><span class="cx">     return $type-&gt;name eq &quot;sequence&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub GetSequenceInnerType
-{
-    my ($object, $type) = @_;
-
-    assert(&quot;Not a type&quot;) if ref($type) ne &quot;IDLType&quot;;
-
-    return @{$type-&gt;subtypes}[0];
-}
-
</del><span class="cx"> sub IsFrozenArrayType
</span><span class="cx"> {
</span><span class="cx">     my ($object, $type) = @_;
</span><span class="lines">@@ -674,15 +650,6 @@
</span><span class="cx">     return $type-&gt;name eq &quot;FrozenArray&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub GetFrozenArrayInnerType
-{
-    my ($object, $type) = @_;
-
-    assert(&quot;Not a type&quot;) if ref($type) ne &quot;IDLType&quot;;
-
-    return @{$type-&gt;subtypes}[0];
-}
-
</del><span class="cx"> sub IsSequenceOrFrozenArrayType
</span><span class="cx"> {
</span><span class="cx">     my ($object, $type) = @_;
</span><span class="lines">@@ -692,13 +659,13 @@
</span><span class="cx">     return $object-&gt;IsSequenceType($type) || $object-&gt;IsFrozenArrayType($type);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub GetSequenceOrFrozenArrayInnerType
</del><ins>+sub IsRecordType
</ins><span class="cx"> {
</span><span class="cx">     my ($object, $type) = @_;
</span><span class="cx"> 
</span><span class="cx">     assert(&quot;Not a type&quot;) if ref($type) ne &quot;IDLType&quot;;
</span><span class="cx"> 
</span><del>-    return @{$type-&gt;subtypes}[0];
</del><ins>+    return $type-&gt;name eq &quot;record&quot;;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> # These match WK_lcfirst and WK_ucfirst defined in builtins_generator.py.
</span><span class="lines">@@ -897,7 +864,6 @@
</span><span class="cx">     return 0 if !$object-&gt;IsRefPtrType($type);
</span><span class="cx">     return 0 if $object-&gt;IsTypedArrayType($type);
</span><span class="cx">     return 0 if $type-&gt;name eq &quot;BufferSource&quot;;
</span><del>-    return 0 if $type-&gt;name eq &quot;UNION&quot;;
</del><span class="cx">     return 0 if $webCoreTypeHash{$type-&gt;name};
</span><span class="cx"> 
</span><span class="cx">     return 1;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsCodeGeneratorJSpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -261,8 +261,6 @@
</span><span class="cx"> {
</span><span class="cx">     my ($implementationType, $includesRef) = @_;
</span><span class="cx"> 
</span><del>-    return if $codeGenerator-&gt;SkipIncludeHeader($implementationType);
-
</del><span class="cx">     $includesRef-&gt;{&quot;${implementationType}.h&quot;} = 1;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -299,20 +297,22 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if ($codeGenerator-&gt;IsRecordType($type)) {
+        AddToIncludes(&quot;&lt;wtf/HashMap.h&gt;&quot;, $includesRef, $conditional);
+        AddToIncludesForIDLType(@{$type-&gt;subtypes}[0], $includesRef, $conditional);
+        AddToIncludesForIDLType(@{$type-&gt;subtypes}[1], $includesRef, $conditional);
+        return;
+    }
+
</ins><span class="cx">     if ($codeGenerator-&gt;IsWrapperType($type) || $codeGenerator-&gt;IsExternalDictionaryType($type) || $codeGenerator-&gt;IsExternalEnumType($type)) {
</span><span class="cx">         AddToIncludes(&quot;JS&quot; . $type-&gt;name . &quot;.h&quot;, $includesRef, $conditional);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    if ($type-&gt;name eq &quot;SerializedScriptValue&quot;) {
-        AddToIncludes(&quot;SerializedScriptValue.h&quot;, $includesRef, $conditional);
</del><ins>+    if ($type-&gt;name eq &quot;SerializedScriptValue&quot; || $type-&gt;name eq &quot;Dictionary&quot;) {
+        AddToIncludes($type-&gt;name . &quot;.h&quot;, $includesRef, $conditional);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><del>-
-    if ($type-&gt;name eq &quot;Dictionary&quot;) {
-        AddToIncludes(&quot;Dictionary.h&quot;, $includesRef, $conditional);
-        return;
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub AddToImplIncludes
</span><span class="lines">@@ -2169,20 +2169,20 @@
</span><span class="cx">         my ($type, $optionality) = @_;
</span><span class="cx">         return $optionality eq &quot;optional&quot;;
</span><span class="cx">     };
</span><del>-    my $isDictionaryParameter = sub {
</del><ins>+    my $isDictionaryOrRecordParameter = sub {
</ins><span class="cx">         my ($type, $optionality) = @_;
</span><del>-        return $type-&gt;name eq &quot;Dictionary&quot; || $codeGenerator-&gt;IsDictionaryType($type);
</del><ins>+        return $type-&gt;name eq &quot;Dictionary&quot; || $codeGenerator-&gt;IsDictionaryType($type) || $codeGenerator-&gt;IsRecordType($type);
</ins><span class="cx">     };
</span><del>-    my $isNullableOrDictionaryParameterOrUnionContainingOne = sub {
</del><ins>+    my $isNullableOrDictionaryOrRecordOrUnionContainingOne = sub {
</ins><span class="cx">         my ($type, $optionality) = @_;
</span><span class="cx">         return 1 if $type-&gt;isNullable;
</span><span class="cx">         if ($type-&gt;isUnion) {
</span><span class="cx">             for my $subtype (GetFlattenedMemberTypes($type)) {
</span><del>-                return 1 if $type-&gt;isNullable || &amp;$isDictionaryParameter($subtype, $optionality);
</del><ins>+                return 1 if $type-&gt;isNullable || &amp;$isDictionaryOrRecordParameter($subtype, $optionality);
</ins><span class="cx">             }
</span><span class="cx">             return 0;
</span><span class="cx">         } else {
</span><del>-            return &amp;$isDictionaryParameter($type, $optionality);
</del><ins>+            return &amp;$isDictionaryOrRecordParameter($type, $optionality);
</ins><span class="cx">         }
</span><span class="cx">     };
</span><span class="cx">     my $isRegExpOrObjectParameter = sub {
</span><span class="lines">@@ -2206,9 +2206,9 @@
</span><span class="cx">         my ($type, $optionality) = @_;
</span><span class="cx">         return $codeGenerator-&gt;IsSequenceOrFrozenArrayType($type);
</span><span class="cx">     };
</span><del>-    my $isDictionaryOrObjectOrCallbackInterfaceParameter = sub {
</del><ins>+    my $isDictionaryOrRecordOrObjectOrCallbackInterfaceParameter = sub {
</ins><span class="cx">         my ($type, $optionality) = @_;
</span><del>-        return 1 if &amp;$isDictionaryParameter($type, $optionality);
</del><ins>+        return 1 if &amp;$isDictionaryOrRecordParameter($type, $optionality);
</ins><span class="cx">         return 1 if $type-&gt;name eq &quot;object&quot;;
</span><span class="cx">         return 1 if $codeGenerator-&gt;IsCallbackInterface($type) &amp;&amp; !$codeGenerator-&gt;IsCallbackFunction($type);
</span><span class="cx">         return 0;
</span><span class="lines">@@ -2260,7 +2260,7 @@
</span><span class="cx">             my $overload = GetOverloadThatMatchesIgnoringUnionSubtypes($S, $d, \&amp;$isOptionalParameter);
</span><span class="cx">             &amp;$generateOverloadCallIfNecessary($overload, &quot;distinguishingArg.isUndefined()&quot;);
</span><span class="cx"> 
</span><del>-            $overload = GetOverloadThatMatchesIgnoringUnionSubtypes($S, $d, \&amp;$isNullableOrDictionaryParameterOrUnionContainingOne);
</del><ins>+            $overload = GetOverloadThatMatchesIgnoringUnionSubtypes($S, $d, \&amp;$isNullableOrDictionaryOrRecordOrUnionContainingOne);
</ins><span class="cx">             &amp;$generateOverloadCallIfNecessary($overload, &quot;distinguishingArg.isUndefinedOrNull()&quot;);
</span><span class="cx"> 
</span><span class="cx">             for my $tuple (@{$S}) {
</span><span class="lines">@@ -2296,7 +2296,7 @@
</span><span class="cx">             $overload = GetOverloadThatMatches($S, $d, \&amp;$isSequenceOrFrozenArrayParameter);
</span><span class="cx">             &amp;$generateOverloadCallIfNecessary($overload, &quot;hasIteratorMethod(*state, distinguishingArg)&quot;);
</span><span class="cx"> 
</span><del>-            $overload = GetOverloadThatMatches($S, $d, \&amp;$isDictionaryOrObjectOrCallbackInterfaceParameter);
</del><ins>+            $overload = GetOverloadThatMatches($S, $d, \&amp;$isDictionaryOrRecordOrObjectOrCallbackInterfaceParameter);
</ins><span class="cx">             &amp;$generateOverloadCallIfNecessary($overload, &quot;distinguishingArg.isObject() &amp;&amp; asObject(distinguishingArg)-&gt;type() != RegExpObjectType&quot;);
</span><span class="cx"> 
</span><span class="cx">             my $booleanOverload = GetOverloadThatMatches($S, $d, \&amp;$isBooleanParameter);
</span><span class="lines">@@ -2372,13 +2372,6 @@
</span><span class="cx">     return $result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub GetNativeTypeForConversions
-{
-    my $interface = shift;
-
-    return $interface-&gt;type-&gt;name;
-}
-
</del><span class="cx"> # See http://refspecs.linux-foundation.org/cxxabi-1.83.html.
</span><span class="cx"> sub GetGnuVTableRefForInterface
</span><span class="cx"> {
</span><span class="lines">@@ -2387,7 +2380,7 @@
</span><span class="cx">     if (!$vtableName) {
</span><span class="cx">         return &quot;0&quot;;
</span><span class="cx">     }
</span><del>-    my $typename = GetNativeTypeForConversions($interface);
</del><ins>+    my $typename = $interface-&gt;type-&gt;name;
</ins><span class="cx">     my $offset = GetGnuVTableOffsetForType($typename);
</span><span class="cx">     return &quot;&amp;&quot; . $vtableName . &quot;[&quot; . $offset . &quot;]&quot;;
</span><span class="cx"> }
</span><span class="lines">@@ -2395,7 +2388,7 @@
</span><span class="cx"> sub GetGnuVTableNameForInterface
</span><span class="cx"> {
</span><span class="cx">     my $interface = shift;
</span><del>-    my $typename = GetNativeTypeForConversions($interface);
</del><ins>+    my $typename = $interface-&gt;type-&gt;name;
</ins><span class="cx">     my $templatePosition = index($typename, &quot;&lt;&quot;);
</span><span class="cx">     return &quot;&quot; if $templatePosition != -1;
</span><span class="cx">     return &quot;&quot; if GetImplementationLacksVTableForInterface($interface);
</span><span class="lines">@@ -2406,13 +2399,13 @@
</span><span class="cx"> sub GetGnuMangledNameForInterface
</span><span class="cx"> {
</span><span class="cx">     my $interface = shift;
</span><del>-    my $typename = GetNativeTypeForConversions($interface);
</del><ins>+    my $typename = $interface-&gt;type-&gt;name;
</ins><span class="cx">     my $templatePosition = index($typename, &quot;&lt;&quot;);
</span><span class="cx">     if ($templatePosition != -1) {
</span><span class="cx">         return &quot;&quot;;
</span><span class="cx">     }
</span><span class="cx">     my $mangledType = length($typename) . $typename;
</span><del>-    my $namespace = GetNamespaceForInterface($interface);
</del><ins>+    my $namespace = &quot;WebCore&quot;;
</ins><span class="cx">     my $mangledNamespace =  &quot;N&quot; . length($namespace) . $namespace;
</span><span class="cx">     return $mangledNamespace . $mangledType . &quot;E&quot;;
</span><span class="cx"> }
</span><span class="lines">@@ -2456,7 +2449,7 @@
</span><span class="cx"> sub GetWinVTableNameForInterface
</span><span class="cx"> {
</span><span class="cx">     my $interface = shift;
</span><del>-    my $typename = GetNativeTypeForConversions($interface);
</del><ins>+    my $typename = $interface-&gt;type-&gt;name;
</ins><span class="cx">     my $templatePosition = index($typename, &quot;&lt;&quot;);
</span><span class="cx">     return &quot;&quot; if $templatePosition != -1;
</span><span class="cx">     return &quot;&quot; if GetImplementationLacksVTableForInterface($interface);
</span><span class="lines">@@ -2467,17 +2460,11 @@
</span><span class="cx"> sub GetWinMangledNameForInterface
</span><span class="cx"> {
</span><span class="cx">     my $interface = shift;
</span><del>-    my $typename = GetNativeTypeForConversions($interface);
-    my $namespace = GetNamespaceForInterface($interface);
</del><ins>+    my $typename = $interface-&gt;type-&gt;name;
+    my $namespace = &quot;WebCore&quot;;
</ins><span class="cx">     return $typename . &quot;@&quot; . $namespace . &quot;@@&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub GetNamespaceForInterface
-{
-    my $interface = shift;
-    return &quot;WebCore&quot;;
-}
-
</del><span class="cx"> sub GetImplementationLacksVTableForInterface
</span><span class="cx"> {
</span><span class="cx">     my $interface = shift;
</span><span class="lines">@@ -5054,6 +5041,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> my %nativeType = (
</span><ins>+    &quot;ByteString&quot; =&gt; &quot;String&quot;,
</ins><span class="cx">     &quot;DOMString&quot; =&gt; &quot;String&quot;,
</span><span class="cx">     &quot;USVString&quot; =&gt; &quot;String&quot;,
</span><span class="cx">     &quot;Date&quot; =&gt; &quot;double&quot;,
</span><span class="lines">@@ -5077,16 +5065,6 @@
</span><span class="cx">     &quot;unsigned short&quot; =&gt; &quot;uint16_t&quot;,
</span><span class="cx"> );
</span><span class="cx"> 
</span><del>-sub GetNativeVectorType
-{
-    my ($type) = @_;
-
-    die &quot;This should only be called for sequence or array types&quot; unless $codeGenerator-&gt;IsSequenceOrFrozenArrayType($type);
-
-    my $innerType = $codeGenerator-&gt;GetSequenceOrFrozenArrayInnerType($type);
-    return &quot;Vector&lt;&quot; . GetNativeVectorInnerType($innerType) . &quot;&gt;&quot;;
-}
-
</del><span class="cx"> # http://heycam.github.io/webidl/#dfn-flattened-union-member-types
</span><span class="cx"> sub GetFlattenedMemberTypes
</span><span class="cx"> {
</span><span class="lines">@@ -5138,13 +5116,6 @@
</span><span class="cx">     return @idlUnionMemberTypes;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub GetIDLInterfaceName
-{
-    my ($type) = @_;
-
-    return $type-&gt;name;
-}
-
</del><span class="cx"> sub GetBaseIDLType
</span><span class="cx"> {
</span><span class="cx">     my ($interface, $type) = @_;
</span><span class="lines">@@ -5178,8 +5149,9 @@
</span><span class="cx">     return &quot;IDLDictionary&lt;&quot; . GetDictionaryClassName($type, $interface) . &quot;&gt;&quot; if $codeGenerator-&gt;IsDictionaryType($type);
</span><span class="cx">     return &quot;IDLSequence&lt;&quot; . GetIDLType($interface, @{$type-&gt;subtypes}[0]) . &quot;&gt;&quot; if $codeGenerator-&gt;IsSequenceType($type);
</span><span class="cx">     return &quot;IDLFrozenArray&lt;&quot; . GetIDLType($interface, @{$type-&gt;subtypes}[0]) . &quot;&gt;&quot; if $codeGenerator-&gt;IsFrozenArrayType($type);
</span><ins>+    return &quot;IDLRecord&lt;&quot; . GetIDLType($interface, @{$type-&gt;subtypes}[0]) . &quot;, &quot; . GetIDLType($interface, @{$type-&gt;subtypes}[1]) . &quot;&gt;&quot; if $codeGenerator-&gt;IsRecordType($type);
</ins><span class="cx">     return &quot;IDLUnion&lt;&quot; . join(&quot;, &quot;, GetIDLUnionMemberTypes($interface, $type)) . &quot;&gt;&quot; if $type-&gt;isUnion;
</span><del>-    return &quot;IDLInterface&lt;&quot; . GetIDLInterfaceName($type) . &quot;&gt;&quot;;
</del><ins>+    return &quot;IDLInterface&lt;&quot; . $type-&gt;name . &quot;&gt;&quot;;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub GetIDLType
</span><span class="lines">@@ -5203,30 +5175,25 @@
</span><span class="cx"> 
</span><span class="cx">     return GetEnumerationClassName($type, $interface) if $codeGenerator-&gt;IsEnumType($type);
</span><span class="cx">     return GetDictionaryClassName($type, $interface) if $codeGenerator-&gt;IsDictionaryType($type);
</span><del>-    return GetNativeVectorType($type) if $codeGenerator-&gt;IsSequenceOrFrozenArrayType($type);
</del><ins>+    return &quot;Vector&lt;&quot; . GetNativeInnerType(@{$type-&gt;subtypes}[0], $interface) . &quot;&gt;&quot; if $codeGenerator-&gt;IsSequenceOrFrozenArrayType($type);
+    return &quot;HashMap&lt;&quot; . GetNativeInnerType(@{$type-&gt;subtypes}[0], $interface) . &quot;, &quot; . GetNativeInnerType(@{$type-&gt;subtypes}[1], $interface) . &quot;&gt;&quot; if $codeGenerator-&gt;IsRecordType($type);
</ins><span class="cx"> 
</span><span class="cx">     return &quot;RefPtr&lt;${typeName}&gt;&quot; if $codeGenerator-&gt;IsTypedArrayType($type) and $typeName ne &quot;ArrayBuffer&quot;;
</span><span class="cx">     return &quot;${typeName}*&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-sub ShouldPassWrapperByReference
</del><ins>+sub GetNativeInnerType
</ins><span class="cx"> {
</span><del>-    my ($parameter, $interface) = @_;
</del><ins>+    my ($innerType, $interface) = @_;
</ins><span class="cx"> 
</span><del>-    return 0 if $codeGenerator-&gt;IsCallbackInterface($parameter-&gt;type) || $codeGenerator-&gt;IsCallbackFunction($parameter-&gt;type);
-
-    my $nativeType = GetNativeType($interface, $parameter-&gt;type);
-    return $codeGenerator-&gt;ShouldPassWrapperByReference($parameter) &amp;&amp; (substr($nativeType, -1) eq '*' || $nativeType =~ /^RefPtr/);
-}
-
-sub GetNativeVectorInnerType
-{
-    my $innerType = shift;
-
</del><span class="cx">     my $innerTypeName = $innerType-&gt;name;
</span><span class="cx"> 
</span><span class="cx">     return $nativeType{$innerTypeName} if exists $nativeType{$innerTypeName};
</span><del>-    return GetDictionaryClassName($innerType) if $codeGenerator-&gt;IsDictionaryType($innerType);
</del><ins>+
+    return GetEnumerationClassName($innerType, $interface) if $codeGenerator-&gt;IsEnumType($innerType);
+    return GetDictionaryClassName($innerType, $interface) if $codeGenerator-&gt;IsDictionaryType($innerType);
+    return &quot;Vector&lt;&quot; . GetNativeInnerType(@{$innerType-&gt;subtypes}[0], $interface) . &quot;&gt;&quot; if $codeGenerator-&gt;IsSequenceOrFrozenArrayType($innerType);
+    return &quot;HashMap&lt;&quot; . GetNativeInnerType(@{$innerType-&gt;subtypes}[0], $interface) . &quot;, &quot; . GetNativeInnerType(@{$innerType-&gt;subtypes}[1], $interface) . &quot;&gt;&quot; if $codeGenerator-&gt;IsRecordType($innerType);
</ins><span class="cx">     return &quot;RefPtr&lt;$innerTypeName&gt;&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -5246,6 +5213,16 @@
</span><span class="cx">     return GetNativeType($interface, $type);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+sub ShouldPassWrapperByReference
+{
+    my ($parameter, $interface) = @_;
+
+    return 0 if $codeGenerator-&gt;IsCallbackInterface($parameter-&gt;type) || $codeGenerator-&gt;IsCallbackFunction($parameter-&gt;type);
+
+    my $nativeType = GetNativeType($interface, $parameter-&gt;type);
+    return $codeGenerator-&gt;ShouldPassWrapperByReference($parameter) &amp;&amp; (substr($nativeType, -1) eq '*' || $nativeType =~ /^RefPtr/);
+}
+
</ins><span class="cx"> sub GetIntegerConversionConfiguration
</span><span class="cx"> {
</span><span class="cx">     my $context = shift;
</span><span class="lines">@@ -5375,6 +5352,7 @@
</span><span class="cx">     # FIXME: This should actually check if all the sub-objects of the union need the state.
</span><span class="cx">     return 1 if $type-&gt;isUnion;
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsSequenceOrFrozenArrayType($type);
</span><ins>+    return 1 if $codeGenerator-&gt;IsRecordType($type);
</ins><span class="cx">     return 1 if $codeGenerator-&gt;IsStringType($type);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsEnumType($type);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsWrapperType($type);
</span><span class="lines">@@ -5391,6 +5369,7 @@
</span><span class="cx">     # FIXME: This should actually check if all the sub-objects of the union need the global object.
</span><span class="cx">     return 1 if $type-&gt;isUnion;
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsSequenceOrFrozenArrayType($type);
</span><ins>+    return 1 if $codeGenerator-&gt;IsRecordType($type);
</ins><span class="cx">     return 1 if $codeGenerator-&gt;IsWrapperType($type);
</span><span class="cx">     return 1 if $codeGenerator-&gt;IsTypedArrayType($type);
</span><span class="cx"> 
</span><span class="lines">@@ -6029,7 +6008,6 @@
</span><span class="cx">         push(@$outputArray, &quot;\n&quot;);
</span><span class="cx">     }
</span><span class="cx">     push(@$outputArray, &quot;template&lt;&gt; const ClassInfo ${constructorClassName}::s_info = { \&quot;${visibleInterfaceName}\&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n&quot;);
</span><del>- 
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> sub HasCustomConstructor
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptsIDLParserpm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/IDLParser.pm (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/IDLParser.pm        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/scripts/IDLParser.pm        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -383,6 +383,17 @@
</span><span class="cx">     return $type;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+sub typeDescription
+{
+    my $type = shift;
+
+    if (scalar @{$type-&gt;subtypes}) {
+        return $type-&gt;name . '&lt;' . join(', ', map { typeDescription($_) } @{$type-&gt;subtypes}) . '&gt;' . ($type-&gt;isNullable ? &quot;?&quot; : &quot;&quot;);
+    }
+
+    return $type-&gt;name . ($type-&gt;isNullable ? &quot;?&quot; : &quot;&quot;);
+}
+
</ins><span class="cx"> sub makeSimpleType
</span><span class="cx"> {
</span><span class="cx">     my $typeName = shift;
</span><span class="lines">@@ -528,7 +539,7 @@
</span><span class="cx">         my $clonedType = $self-&gt;cloneType($typedef-&gt;type);
</span><span class="cx">         $clonedType-&gt;isNullable($clonedType-&gt;isNullable || $type-&gt;isNullable);
</span><span class="cx"> 
</span><del>-        return $clonedType;
</del><ins>+        return $self-&gt;typeByApplyingTypedefs($clonedType);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     return $type;
</span><span class="lines">@@ -2101,7 +2112,6 @@
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
</span><span class="cx"> 
</span><span class="cx">         my $subtype = $self-&gt;parseType();
</span><del>-        my $subtypeName = $subtype-&gt;name;
</del><span class="cx"> 
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
</span><span class="cx"> 
</span><span class="lines">@@ -2115,7 +2125,6 @@
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
</span><span class="cx"> 
</span><span class="cx">         my $subtype = $self-&gt;parseType();
</span><del>-        my $subtypeName = $subtype-&gt;name;
</del><span class="cx"> 
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
</span><span class="cx"> 
</span><span class="lines">@@ -2129,7 +2138,6 @@
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
</span><span class="cx"> 
</span><span class="cx">         my $subtype = $self-&gt;parseReturnType();
</span><del>-        my $subtypeName = $subtype-&gt;name;
</del><span class="cx"> 
</span><span class="cx">         $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
</span><span class="cx"> 
</span><span class="lines">@@ -2138,6 +2146,25 @@
</span><span class="cx"> 
</span><span class="cx">         return $type;
</span><span class="cx">     }
</span><ins>+    if ($next-&gt;value() eq &quot;record&quot;) {
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;record&quot;, __LINE__);
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&lt;&quot;, __LINE__);
+
+        my $keyType = IDLType-&gt;new();
+        $keyType-&gt;name($self-&gt;parseStringType());
+
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;,&quot;, __LINE__);
+
+        my $valueType = $self-&gt;parseType();
+
+        $self-&gt;assertTokenValue($self-&gt;getToken(), &quot;&gt;&quot;, __LINE__);
+
+        $type-&gt;name(&quot;record&quot;);
+        push(@{$type-&gt;subtypes}, $keyType);
+        push(@{$type-&gt;subtypes}, $valueType);
+
+        return $type;
+    }
</ins><span class="cx">     if ($next-&gt;type() == IdentifierToken) {
</span><span class="cx">         my $identifier = $self-&gt;getToken();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestCallbackFunctionWithTypedefscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -22,7 +22,6 @@
</span><span class="cx"> #include &quot;JSTestCallbackFunctionWithTypedefs.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSDOMConvert.h&quot;
</span><del>-#include &quot;JSLONG.h&quot;
</del><span class="cx"> #include &quot;ScriptExecutionContext.h&quot;
</span><span class="cx"> #include &lt;runtime/JSArray.h&gt;
</span><span class="cx"> #include &lt;runtime/JSLock.h&gt;
</span><span class="lines">@@ -52,7 +51,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JSTestCallbackFunctionWithTypedefs::handleEvent(Vector&lt;RefPtr&lt;LONG&gt;&gt; sequenceArg, int32_t longArg)
</del><ins>+bool JSTestCallbackFunctionWithTypedefs::handleEvent(Vector&lt;int32_t&gt; sequenceArg, int32_t longArg)
</ins><span class="cx"> {
</span><span class="cx">     if (!canInvokeCallback())
</span><span class="cx">         return true;
</span><span class="lines">@@ -63,7 +62,7 @@
</span><span class="cx"> 
</span><span class="cx">     ExecState* state = m_data-&gt;globalObject()-&gt;globalExec();
</span><span class="cx">     MarkedArgumentBuffer args;
</span><del>-    args.append(toJS&lt;IDLSequence&lt;IDLNullable&lt;IDLInterface&lt;LONG&gt;&gt;&gt;&gt;(*state, *m_data-&gt;globalObject(), sequenceArg));
</del><ins>+    args.append(toJS&lt;IDLSequence&lt;IDLNullable&lt;IDLLong&gt;&gt;&gt;(*state, *m_data-&gt;globalObject(), sequenceArg));
</ins><span class="cx">     args.append(toJS&lt;IDLLong&gt;(longArg));
</span><span class="cx"> 
</span><span class="cx">     NakedPtr&lt;JSC::Exception&gt; returnedException;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestCallbackFunctionWithTypedefsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.h        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx">     JSCallbackDataStrong* callbackData() { return m_data; }
</span><span class="cx"> 
</span><span class="cx">     // Functions
</span><del>-    virtual bool handleEvent(Vector&lt;RefPtr&lt;LONG&gt;&gt; sequenceArg, int32_t longArg);
</del><ins>+    virtual bool handleEvent(Vector&lt;int32_t&gt; sequenceArg, int32_t longArg);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     JSTestCallbackFunctionWithTypedefs(JSC::JSObject* callback, JSDOMGlobalObject*);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestJSJSTestObjcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -66,6 +66,7 @@
</span><span class="cx"> #include &lt;runtime/ObjectConstructor.h&gt;
</span><span class="cx"> #include &lt;runtime/PropertyNameArray.h&gt;
</span><span class="cx"> #include &lt;wtf/GetPtr.h&gt;
</span><ins>+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #include &lt;wtf/Variant.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(Condition1)
</span><span class="lines">@@ -963,8 +964,12 @@
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithUSVStringArg(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithNullableUSVStringArg(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithUSVStringArgTreatingNullAsEmptyString(JSC::ExecState*);
</span><ins>+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithByteStringArg(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithNullableByteStringArg(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithByteStringArgTreatingNullAsEmptyString(JSC::ExecState*);
</ins><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionSerializedValue(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOptionsObject(JSC::ExecState*);
</span><ins>+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithRecord(JSC::ExecState*);
</ins><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithException(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithExceptionReturningLong(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithExceptionReturningObject(JSC::ExecState*);
</span><span class="lines">@@ -1015,6 +1020,7 @@
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapper(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapperIsNull(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalXPathNSResolver(JSC::ExecState*);
</span><ins>+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalRecord(JSC::ExecState*);
</ins><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithCallbackArg(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithNonCallbackArgAndCallbackArg(JSC::ExecState*);
</span><span class="cx"> JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithCallbackAndOptionalArg(JSC::ExecState*);
</span><span class="lines">@@ -1130,6 +1136,18 @@
</span><span class="cx"> bool setJSTestObjStringAttrTreatingNullAsEmptyString(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
</span><span class="cx"> JSC::EncodedJSValue jsTestObjUsvstringAttrTreatingNullAsEmptyString(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
</span><span class="cx"> bool setJSTestObjUsvstringAttrTreatingNullAsEmptyString(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
</span><ins>+JSC::EncodedJSValue jsTestObjByteStringAttrTreatingNullAsEmptyString(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestObjByteStringAttrTreatingNullAsEmptyString(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+JSC::EncodedJSValue jsTestObjStringLongRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestObjStringLongRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+JSC::EncodedJSValue jsTestObjUsvstringLongRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestObjUsvstringLongRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+JSC::EncodedJSValue jsTestObjUsvstringLongRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestObjUsvstringLongRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+JSC::EncodedJSValue jsTestObjStringObjRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestObjStringObjRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+JSC::EncodedJSValue jsTestObjStringNullableObjRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestObjStringNullableObjRecordAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
</ins><span class="cx"> JSC::EncodedJSValue jsTestObjImplementationEnumAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
</span><span class="cx"> bool setJSTestObjImplementationEnumAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
</span><span class="cx"> JSC::EncodedJSValue jsTestObjXMLObjAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
</span><span class="lines">@@ -1247,6 +1265,8 @@
</span><span class="cx"> bool setJSTestObjNullableStringSettableAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
</span><span class="cx"> JSC::EncodedJSValue jsTestObjNullableUSVStringSettableAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
</span><span class="cx"> bool setJSTestObjNullableUSVStringSettableAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
</span><ins>+JSC::EncodedJSValue jsTestObjNullableByteStringSettableAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestObjNullableByteStringSettableAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
</ins><span class="cx"> JSC::EncodedJSValue jsTestObjNullableStringValue(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
</span><span class="cx"> bool setJSTestObjNullableStringValue(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
</span><span class="cx"> JSC::EncodedJSValue jsTestObjAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
</span><span class="lines">@@ -1455,6 +1475,12 @@
</span><span class="cx">     { &quot;lenientTestObjAttr&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjLenientTestObjAttr), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjLenientTestObjAttr) } },
</span><span class="cx">     { &quot;stringAttrTreatingNullAsEmptyString&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjStringAttrTreatingNullAsEmptyString), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjStringAttrTreatingNullAsEmptyString) } },
</span><span class="cx">     { &quot;usvstringAttrTreatingNullAsEmptyString&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjUsvstringAttrTreatingNullAsEmptyString), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjUsvstringAttrTreatingNullAsEmptyString) } },
</span><ins>+    { &quot;byteStringAttrTreatingNullAsEmptyString&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjByteStringAttrTreatingNullAsEmptyString), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjByteStringAttrTreatingNullAsEmptyString) } },
+    { &quot;stringLongRecordAttr&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjStringLongRecordAttr), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjStringLongRecordAttr) } },
+    { &quot;usvstringLongRecordAttr&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjUsvstringLongRecordAttr), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjUsvstringLongRecordAttr) } },
+    { &quot;usvstringLongRecordAttr&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjUsvstringLongRecordAttr), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjUsvstringLongRecordAttr) } },
+    { &quot;stringObjRecordAttr&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjStringObjRecordAttr), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjStringObjRecordAttr) } },
+    { &quot;stringNullableObjRecordAttr&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjStringNullableObjRecordAttr), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjStringNullableObjRecordAttr) } },
</ins><span class="cx">     { &quot;implementationEnumAttr&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjImplementationEnumAttr), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjImplementationEnumAttr) } },
</span><span class="cx">     { &quot;XMLObjAttr&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjXMLObjAttr), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjXMLObjAttr) } },
</span><span class="cx">     { &quot;create&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjCreate), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjCreate) } },
</span><span class="lines">@@ -1534,6 +1560,7 @@
</span><span class="cx">     { &quot;nullableLongSettableAttribute&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjNullableLongSettableAttribute), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjNullableLongSettableAttribute) } },
</span><span class="cx">     { &quot;nullableStringSettableAttribute&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjNullableStringSettableAttribute), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjNullableStringSettableAttribute) } },
</span><span class="cx">     { &quot;nullableUSVStringSettableAttribute&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjNullableUSVStringSettableAttribute), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjNullableUSVStringSettableAttribute) } },
</span><ins>+    { &quot;nullableByteStringSettableAttribute&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjNullableByteStringSettableAttribute), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjNullableByteStringSettableAttribute) } },
</ins><span class="cx">     { &quot;nullableStringValue&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjNullableStringValue), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjNullableStringValue) } },
</span><span class="cx">     { &quot;attribute&quot;, ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjAttribute), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(0) } },
</span><span class="cx">     { &quot;attributeWithReservedEnumType&quot;, CustomAccessor, NoIntrinsic, { (intptr_t)static_cast&lt;PropertySlot::GetValueFunc&gt;(jsTestObjAttributeWithReservedEnumType), (intptr_t) static_cast&lt;PutPropertySlot::PutValueFunc&gt;(setJSTestObjAttributeWithReservedEnumType) } },
</span><span class="lines">@@ -1569,8 +1596,12 @@
</span><span class="cx">     { &quot;methodWithUSVStringArg&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithUSVStringArg), (intptr_t) (1) } },
</span><span class="cx">     { &quot;methodWithNullableUSVStringArg&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithNullableUSVStringArg), (intptr_t) (1) } },
</span><span class="cx">     { &quot;methodWithUSVStringArgTreatingNullAsEmptyString&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithUSVStringArgTreatingNullAsEmptyString), (intptr_t) (1) } },
</span><ins>+    { &quot;methodWithByteStringArg&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithByteStringArg), (intptr_t) (1) } },
+    { &quot;methodWithNullableByteStringArg&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithNullableByteStringArg), (intptr_t) (1) } },
+    { &quot;methodWithByteStringArgTreatingNullAsEmptyString&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithByteStringArgTreatingNullAsEmptyString), (intptr_t) (1) } },
</ins><span class="cx">     { &quot;serializedValue&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionSerializedValue), (intptr_t) (1) } },
</span><span class="cx">     { &quot;optionsObject&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionOptionsObject), (intptr_t) (1) } },
</span><ins>+    { &quot;methodWithRecord&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithRecord), (intptr_t) (1) } },
</ins><span class="cx">     { &quot;methodWithException&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithException), (intptr_t) (0) } },
</span><span class="cx">     { &quot;methodWithExceptionReturningLong&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithExceptionReturningLong), (intptr_t) (0) } },
</span><span class="cx">     { &quot;methodWithExceptionReturningObject&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithExceptionReturningObject), (intptr_t) (0) } },
</span><span class="lines">@@ -1630,6 +1661,7 @@
</span><span class="cx">     { &quot;methodWithOptionalNullableWrapper&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapper), (intptr_t) (0) } },
</span><span class="cx">     { &quot;methodWithOptionalNullableWrapperIsNull&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapperIsNull), (intptr_t) (0) } },
</span><span class="cx">     { &quot;methodWithOptionalXPathNSResolver&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithOptionalXPathNSResolver), (intptr_t) (0) } },
</span><ins>+    { &quot;methodWithOptionalRecord&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithOptionalRecord), (intptr_t) (0) } },
</ins><span class="cx">     { &quot;methodWithCallbackArg&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithCallbackArg), (intptr_t) (1) } },
</span><span class="cx">     { &quot;methodWithNonCallbackArgAndCallbackArg&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithNonCallbackArgAndCallbackArg), (intptr_t) (2) } },
</span><span class="cx">     { &quot;methodWithCallbackAndOptionalArg&quot;, JSC::Function, NoIntrinsic, { (intptr_t)static_cast&lt;NativeFunction&gt;(jsTestObjPrototypeFunctionMethodWithCallbackAndOptionalArg), (intptr_t) (0) } },
</span><span class="lines">@@ -2217,6 +2249,102 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline JSValue jsTestObjByteStringAttrTreatingNullAsEmptyStringGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsTestObjByteStringAttrTreatingNullAsEmptyString(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSTestObj&gt;::attribute&lt;jsTestObjByteStringAttrTreatingNullAsEmptyStringGetter&gt;(state, thisValue, &quot;byteStringAttrTreatingNullAsEmptyString&quot;);
+}
+
+static inline JSValue jsTestObjByteStringAttrTreatingNullAsEmptyStringGetter(ExecState&amp; state, JSTestObj&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto&amp; impl = thisObject.wrapped();
+    JSValue result = toJS&lt;IDLByteString&gt;(state, impl.byteStringAttrTreatingNullAsEmptyString());
+    return result;
+}
+
+static inline JSValue jsTestObjStringLongRecordAttrGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsTestObjStringLongRecordAttr(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSTestObj&gt;::attribute&lt;jsTestObjStringLongRecordAttrGetter&gt;(state, thisValue, &quot;stringLongRecordAttr&quot;);
+}
+
+static inline JSValue jsTestObjStringLongRecordAttrGetter(ExecState&amp; state, JSTestObj&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto&amp; impl = thisObject.wrapped();
+    JSValue result = toJS&lt;IDLRecord&lt;IDLDOMString, IDLLong&gt;&gt;(state, *thisObject.globalObject(), impl.stringLongRecordAttr());
+    return result;
+}
+
+static inline JSValue jsTestObjUsvstringLongRecordAttrGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsTestObjUsvstringLongRecordAttr(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSTestObj&gt;::attribute&lt;jsTestObjUsvstringLongRecordAttrGetter&gt;(state, thisValue, &quot;usvstringLongRecordAttr&quot;);
+}
+
+static inline JSValue jsTestObjUsvstringLongRecordAttrGetter(ExecState&amp; state, JSTestObj&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto&amp; impl = thisObject.wrapped();
+    JSValue result = toJS&lt;IDLRecord&lt;IDLUSVString, IDLLong&gt;&gt;(state, *thisObject.globalObject(), impl.usvstringLongRecordAttr());
+    return result;
+}
+
+static inline JSValue jsTestObjUsvstringLongRecordAttrGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsTestObjUsvstringLongRecordAttr(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSTestObj&gt;::attribute&lt;jsTestObjUsvstringLongRecordAttrGetter&gt;(state, thisValue, &quot;usvstringLongRecordAttr&quot;);
+}
+
+static inline JSValue jsTestObjUsvstringLongRecordAttrGetter(ExecState&amp; state, JSTestObj&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto&amp; impl = thisObject.wrapped();
+    JSValue result = toJS&lt;IDLRecord&lt;IDLByteString, IDLLong&gt;&gt;(state, *thisObject.globalObject(), impl.usvstringLongRecordAttr());
+    return result;
+}
+
+static inline JSValue jsTestObjStringObjRecordAttrGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsTestObjStringObjRecordAttr(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSTestObj&gt;::attribute&lt;jsTestObjStringObjRecordAttrGetter&gt;(state, thisValue, &quot;stringObjRecordAttr&quot;);
+}
+
+static inline JSValue jsTestObjStringObjRecordAttrGetter(ExecState&amp; state, JSTestObj&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto&amp; impl = thisObject.wrapped();
+    JSValue result = toJS&lt;IDLRecord&lt;IDLDOMString, IDLInterface&lt;TestObj&gt;&gt;&gt;(state, *thisObject.globalObject(), impl.stringObjRecordAttr());
+    return result;
+}
+
+static inline JSValue jsTestObjStringNullableObjRecordAttrGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsTestObjStringNullableObjRecordAttr(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSTestObj&gt;::attribute&lt;jsTestObjStringNullableObjRecordAttrGetter&gt;(state, thisValue, &quot;stringNullableObjRecordAttr&quot;);
+}
+
+static inline JSValue jsTestObjStringNullableObjRecordAttrGetter(ExecState&amp; state, JSTestObj&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto&amp; impl = thisObject.wrapped();
+    JSValue result = toJS&lt;IDLRecord&lt;IDLDOMString, IDLNullable&lt;IDLInterface&lt;TestObj&gt;&gt;&gt;&gt;(state, *thisObject.globalObject(), impl.stringNullableObjRecordAttr());
+    return result;
+}
+
</ins><span class="cx"> static inline JSValue jsTestObjImplementationEnumAttrGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue jsTestObjImplementationEnumAttr(ExecState* state, EncodedJSValue thisValue, PropertyName)
</span><span class="lines">@@ -3143,6 +3271,22 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline JSValue jsTestObjNullableByteStringSettableAttributeGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
+
+EncodedJSValue jsTestObjNullableByteStringSettableAttribute(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller&lt;JSTestObj&gt;::attribute&lt;jsTestObjNullableByteStringSettableAttributeGetter&gt;(state, thisValue, &quot;nullableByteStringSettableAttribute&quot;);
+}
+
+static inline JSValue jsTestObjNullableByteStringSettableAttributeGetter(ExecState&amp; state, JSTestObj&amp; thisObject, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto&amp; impl = thisObject.wrapped();
+    JSValue result = toJS&lt;IDLNullable&lt;IDLByteString&gt;&gt;(state, impl.nullableByteStringSettableAttribute());
+    return result;
+}
+
</ins><span class="cx"> static inline JSValue jsTestObjNullableStringValueGetter(ExecState&amp;, JSTestObj&amp;, ThrowScope&amp; throwScope);
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue jsTestObjNullableStringValue(ExecState* state, EncodedJSValue thisValue, PropertyName)
</span><span class="lines">@@ -3633,6 +3777,120 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+static inline bool setJSTestObjByteStringAttrTreatingNullAsEmptyStringFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
+
+bool setJSTestObjByteStringAttrTreatingNullAsEmptyString(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    return BindingCaller&lt;JSTestObj&gt;::setAttribute&lt;setJSTestObjByteStringAttrTreatingNullAsEmptyStringFunction&gt;(state, thisValue, encodedValue, &quot;byteStringAttrTreatingNullAsEmptyString&quot;);
+}
+
+static inline bool setJSTestObjByteStringAttrTreatingNullAsEmptyStringFunction(ExecState&amp; state, JSTestObj&amp; thisObject, JSValue value, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = thisObject.wrapped();
+    auto nativeValue = convert&lt;IDLByteString&gt;(state, value, StringConversionConfiguration::TreatNullAsEmptyString);
+    RETURN_IF_EXCEPTION(throwScope, false);
+    impl.setByteStringAttrTreatingNullAsEmptyString(WTFMove(nativeValue));
+    return true;
+}
+
+
+static inline bool setJSTestObjStringLongRecordAttrFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
+
+bool setJSTestObjStringLongRecordAttr(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    return BindingCaller&lt;JSTestObj&gt;::setAttribute&lt;setJSTestObjStringLongRecordAttrFunction&gt;(state, thisValue, encodedValue, &quot;stringLongRecordAttr&quot;);
+}
+
+static inline bool setJSTestObjStringLongRecordAttrFunction(ExecState&amp; state, JSTestObj&amp; thisObject, JSValue value, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = thisObject.wrapped();
+    auto nativeValue = convert&lt;IDLRecord&lt;IDLDOMString, IDLLong&gt;&gt;(state, value);
+    RETURN_IF_EXCEPTION(throwScope, false);
+    impl.setStringLongRecordAttr(WTFMove(nativeValue));
+    return true;
+}
+
+
+static inline bool setJSTestObjUsvstringLongRecordAttrFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
+
+bool setJSTestObjUsvstringLongRecordAttr(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    return BindingCaller&lt;JSTestObj&gt;::setAttribute&lt;setJSTestObjUsvstringLongRecordAttrFunction&gt;(state, thisValue, encodedValue, &quot;usvstringLongRecordAttr&quot;);
+}
+
+static inline bool setJSTestObjUsvstringLongRecordAttrFunction(ExecState&amp; state, JSTestObj&amp; thisObject, JSValue value, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = thisObject.wrapped();
+    auto nativeValue = convert&lt;IDLRecord&lt;IDLUSVString, IDLLong&gt;&gt;(state, value);
+    RETURN_IF_EXCEPTION(throwScope, false);
+    impl.setUsvstringLongRecordAttr(WTFMove(nativeValue));
+    return true;
+}
+
+
+static inline bool setJSTestObjUsvstringLongRecordAttrFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
+
+bool setJSTestObjUsvstringLongRecordAttr(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    return BindingCaller&lt;JSTestObj&gt;::setAttribute&lt;setJSTestObjUsvstringLongRecordAttrFunction&gt;(state, thisValue, encodedValue, &quot;usvstringLongRecordAttr&quot;);
+}
+
+static inline bool setJSTestObjUsvstringLongRecordAttrFunction(ExecState&amp; state, JSTestObj&amp; thisObject, JSValue value, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = thisObject.wrapped();
+    auto nativeValue = convert&lt;IDLRecord&lt;IDLByteString, IDLLong&gt;&gt;(state, value);
+    RETURN_IF_EXCEPTION(throwScope, false);
+    impl.setUsvstringLongRecordAttr(WTFMove(nativeValue));
+    return true;
+}
+
+
+static inline bool setJSTestObjStringObjRecordAttrFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
+
+bool setJSTestObjStringObjRecordAttr(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    return BindingCaller&lt;JSTestObj&gt;::setAttribute&lt;setJSTestObjStringObjRecordAttrFunction&gt;(state, thisValue, encodedValue, &quot;stringObjRecordAttr&quot;);
+}
+
+static inline bool setJSTestObjStringObjRecordAttrFunction(ExecState&amp; state, JSTestObj&amp; thisObject, JSValue value, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = thisObject.wrapped();
+    auto nativeValue = convert&lt;IDLRecord&lt;IDLDOMString, IDLInterface&lt;TestObj&gt;&gt;&gt;(state, value);
+    RETURN_IF_EXCEPTION(throwScope, false);
+    impl.setStringObjRecordAttr(WTFMove(nativeValue));
+    return true;
+}
+
+
+static inline bool setJSTestObjStringNullableObjRecordAttrFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
+
+bool setJSTestObjStringNullableObjRecordAttr(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    return BindingCaller&lt;JSTestObj&gt;::setAttribute&lt;setJSTestObjStringNullableObjRecordAttrFunction&gt;(state, thisValue, encodedValue, &quot;stringNullableObjRecordAttr&quot;);
+}
+
+static inline bool setJSTestObjStringNullableObjRecordAttrFunction(ExecState&amp; state, JSTestObj&amp; thisObject, JSValue value, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = thisObject.wrapped();
+    auto nativeValue = convert&lt;IDLRecord&lt;IDLDOMString, IDLNullable&lt;IDLInterface&lt;TestObj&gt;&gt;&gt;&gt;(state, value);
+    RETURN_IF_EXCEPTION(throwScope, false);
+    impl.setStringNullableObjRecordAttr(WTFMove(nativeValue));
+    return true;
+}
+
+
</ins><span class="cx"> static inline bool setJSTestObjImplementationEnumAttrFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
</span><span class="cx"> 
</span><span class="cx"> bool setJSTestObjImplementationEnumAttr(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
</span><span class="lines">@@ -4536,6 +4794,25 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+static inline bool setJSTestObjNullableByteStringSettableAttributeFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
+
+bool setJSTestObjNullableByteStringSettableAttribute(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    return BindingCaller&lt;JSTestObj&gt;::setAttribute&lt;setJSTestObjNullableByteStringSettableAttributeFunction&gt;(state, thisValue, encodedValue, &quot;nullableByteStringSettableAttribute&quot;);
+}
+
+static inline bool setJSTestObjNullableByteStringSettableAttributeFunction(ExecState&amp; state, JSTestObj&amp; thisObject, JSValue value, ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = thisObject.wrapped();
+    auto nativeValue = convert&lt;IDLNullable&lt;IDLByteString&gt;&gt;(state, value, StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, false);
+    impl.setNullableByteStringSettableAttribute(WTFMove(nativeValue));
+    return true;
+}
+
+
</ins><span class="cx"> static inline bool setJSTestObjNullableStringValueFunction(ExecState&amp;, JSTestObj&amp;, JSValue, ThrowScope&amp;);
</span><span class="cx"> 
</span><span class="cx"> bool setJSTestObjNullableStringValue(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
</span><span class="lines">@@ -5211,6 +5488,66 @@
</span><span class="cx">     return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithByteStringArgCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithByteStringArg(ExecState* state)
+{
+    return BindingCaller&lt;JSTestObj&gt;::callOperation&lt;jsTestObjPrototypeFunctionMethodWithByteStringArgCaller&gt;(state, &quot;methodWithByteStringArg&quot;);
+}
+
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithByteStringArgCaller(JSC::ExecState* state, JSTestObj* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = castedThis-&gt;wrapped();
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto str = convert&lt;IDLByteString&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.methodWithByteStringArg(WTFMove(str));
+    return JSValue::encode(jsUndefined());
+}
+
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithNullableByteStringArgCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithNullableByteStringArg(ExecState* state)
+{
+    return BindingCaller&lt;JSTestObj&gt;::callOperation&lt;jsTestObjPrototypeFunctionMethodWithNullableByteStringArgCaller&gt;(state, &quot;methodWithNullableByteStringArg&quot;);
+}
+
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithNullableByteStringArgCaller(JSC::ExecState* state, JSTestObj* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = castedThis-&gt;wrapped();
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto str = convert&lt;IDLNullable&lt;IDLByteString&gt;&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::Normal);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.methodWithNullableByteStringArg(WTFMove(str));
+    return JSValue::encode(jsUndefined());
+}
+
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithByteStringArgTreatingNullAsEmptyStringCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithByteStringArgTreatingNullAsEmptyString(ExecState* state)
+{
+    return BindingCaller&lt;JSTestObj&gt;::callOperation&lt;jsTestObjPrototypeFunctionMethodWithByteStringArgTreatingNullAsEmptyStringCaller&gt;(state, &quot;methodWithByteStringArgTreatingNullAsEmptyString&quot;);
+}
+
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithByteStringArgTreatingNullAsEmptyStringCaller(JSC::ExecState* state, JSTestObj* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = castedThis-&gt;wrapped();
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto str = convert&lt;IDLByteString&gt;(*state, state-&gt;uncheckedArgument(0), StringConversionConfiguration::TreatNullAsEmptyString);
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.methodWithByteStringArgTreatingNullAsEmptyString(WTFMove(str));
+    return JSValue::encode(jsUndefined());
+}
+
</ins><span class="cx"> static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionSerializedValueCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&amp;);
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionSerializedValue(ExecState* state)
</span><span class="lines">@@ -5251,6 +5588,26 @@
</span><span class="cx">     return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithRecordCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithRecord(ExecState* state)
+{
+    return BindingCaller&lt;JSTestObj&gt;::callOperation&lt;jsTestObjPrototypeFunctionMethodWithRecordCaller&gt;(state, &quot;methodWithRecord&quot;);
+}
+
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithRecordCaller(JSC::ExecState* state, JSTestObj* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = castedThis-&gt;wrapped();
+    if (UNLIKELY(state-&gt;argumentCount() &lt; 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto recordParameter = convert&lt;IDLRecord&lt;IDLDOMString, IDLLong&gt;&gt;(*state, state-&gt;uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.methodWithRecord(WTFMove(recordParameter));
+    return JSValue::encode(jsUndefined());
+}
+
</ins><span class="cx"> static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithExceptionCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&amp;);
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithException(ExecState* state)
</span><span class="lines">@@ -6159,6 +6516,24 @@
</span><span class="cx">     return JSValue::encode(jsUndefined());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithOptionalRecordCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&amp;);
+
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalRecord(ExecState* state)
+{
+    return BindingCaller&lt;JSTestObj&gt;::callOperation&lt;jsTestObjPrototypeFunctionMethodWithOptionalRecordCaller&gt;(state, &quot;methodWithOptionalRecord&quot;);
+}
+
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithOptionalRecordCaller(JSC::ExecState* state, JSTestObj* castedThis, JSC::ThrowScope&amp; throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto&amp; impl = castedThis-&gt;wrapped();
+    auto record = state-&gt;argument(0).isUndefined() ? Nullopt : convert&lt;IDLNullable&lt;IDLRecord&lt;IDLDOMString, IDLLong&gt;&gt;&gt;(*state, state-&gt;uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.methodWithOptionalRecord(WTFMove(record));
+    return JSValue::encode(jsUndefined());
+}
+
</ins><span class="cx"> static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithCallbackArgCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&amp;);
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithCallbackArg(ExecState* state)
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsscriptstestTestObjidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/scripts/test/TestObj.idl (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/scripts/test/TestObj.idl        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/bindings/scripts/test/TestObj.idl        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -58,28 +58,30 @@
</span><span class="cx">     static attribute DOMString         staticStringAttr;
</span><span class="cx">     static readonly attribute TestSubObjConstructor TestSubObj;
</span><span class="cx">     [EnabledBySetting=TestSetting] attribute TestSubObjConstructor TestSubObjEnabledBySetting;
</span><del>-    attribute TestEnumType             enumAttr;
-    attribute byte                     byteAttr;
-    attribute octet                    octetAttr;
-    [Unscopable] attribute short                    shortAttr;
-    [Clamp] attribute short            clampedShortAttr;
-    [EnforceRange] attribute short     enforceRangeShortAttr;
-    attribute unsigned short           unsignedShortAttr;
-    attribute long                     longAttr;
-    attribute long long                longLongAttr;
-    attribute unsigned long long       unsignedLongLongAttr;
-    attribute DOMString                stringAttr;
-#if defined(TESTING_JS)
-    attribute USVString                usvstringAttr;
-#endif
-    attribute TestObj                  testObjAttr;
-    attribute TestObj?                 testNullableObjAttr;
-    [LenientThis] attribute TestObj    lenientTestObjAttr;
</del><ins>+    attribute TestEnumType enumAttr;
+    attribute byte byteAttr;
+    attribute octet octetAttr;
+    [Unscopable] attribute short shortAttr;
+    [Clamp] attribute short clampedShortAttr;
+    [EnforceRange] attribute short enforceRangeShortAttr;
+    attribute unsigned short unsignedShortAttr;
+    attribute long longAttr;
+    attribute long long longLongAttr;
+    attribute unsigned long long unsignedLongLongAttr;
+    attribute DOMString stringAttr;
+    attribute USVString usvstringAttr;
+    attribute TestObj testObjAttr;
+    attribute TestObj? testNullableObjAttr;
+    [LenientThis] attribute TestObj lenientTestObjAttr;
</ins><span class="cx">     [Unforgeable] readonly attribute DOMString unforgeableAttr;
</span><span class="cx">     [TreatNullAs=EmptyString] attribute DOMString stringAttrTreatingNullAsEmptyString;
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     [TreatNullAs=EmptyString] attribute USVString usvstringAttrTreatingNullAsEmptyString;
</span><del>-#endif
</del><ins>+    [TreatNullAs=EmptyString] attribute ByteString byteStringAttrTreatingNullAsEmptyString;
+    attribute record&lt;DOMString, long&gt; stringLongRecordAttr;
+    attribute record&lt;USVString, long&gt; usvstringLongRecordAttr;
+    attribute record&lt;ByteString, long&gt; usvstringLongRecordAttr;
+    attribute record&lt;DOMString, TestObj&gt; stringObjRecordAttr;
+    attribute record&lt;DOMString, TestObj?&gt; stringNullableObjRecordAttr;
</ins><span class="cx"> 
</span><span class="cx">     attribute TestEnumTypeWithAlternateImplementationName implementationEnumAttr;
</span><span class="cx"> 
</span><span class="lines">@@ -89,16 +91,12 @@
</span><span class="cx"> 
</span><span class="cx">     // Reflected DOM attributes
</span><span class="cx">     [Reflect] attribute DOMString reflectedStringAttr;
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     [Reflect] attribute USVString reflectedUSVStringAttr;
</span><del>-#endif
</del><span class="cx">     [Reflect] attribute long reflectedIntegralAttr;
</span><span class="cx">     [Reflect] attribute unsigned long reflectedUnsignedIntegralAttr;
</span><span class="cx">     [Reflect] attribute boolean reflectedBooleanAttr;
</span><span class="cx">     [Reflect, URL] attribute DOMString reflectedURLAttr;
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     [Reflect, URL] attribute USVString reflectedUSVURLAttr;
</span><del>-#endif
</del><span class="cx">     [Reflect=customContentStringAttr] attribute DOMString reflectedStringAttr;
</span><span class="cx">     [Reflect=customContentIntegralAttr] attribute long reflectedCustomIntegralAttr;
</span><span class="cx">     [Reflect=customContentBooleanAttr] attribute boolean reflectedCustomBooleanAttr;
</span><span class="lines">@@ -142,15 +140,19 @@
</span><span class="cx">     void methodWithOptionalEnumArgAndDefaultValue(optional TestEnumType enumArg = &quot;EnumValue1&quot;);
</span><span class="cx">     [MayThrowException] TestObj methodThatRequiresAllArgsAndThrows(DOMString strArg, TestObj objArg);
</span><span class="cx"> 
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     void methodWithUSVStringArg(USVString str);
</span><span class="cx">     void methodWithNullableUSVStringArg(USVString? str);
</span><span class="cx">     void methodWithUSVStringArgTreatingNullAsEmptyString([TreatNullAs=EmptyString] USVString str);
</span><del>-#endif
</del><span class="cx"> 
</span><ins>+    void methodWithByteStringArg(ByteString str);
+    void methodWithNullableByteStringArg(ByteString? str);
+    void methodWithByteStringArgTreatingNullAsEmptyString([TreatNullAs=EmptyString] ByteString str);
+
</ins><span class="cx">     void serializedValue(SerializedScriptValue serializedArg);
</span><span class="cx">     void optionsObject(Dictionary oo, optional Dictionary ooo);
</span><span class="cx"> 
</span><ins>+    void methodWithRecord(record&lt;DOMString, long&gt; recordParameter);
+
</ins><span class="cx">     // Exceptions
</span><span class="cx">     [MayThrowException] void methodWithException();
</span><span class="cx">     [MayThrowException] long methodWithExceptionReturningLong();
</span><span class="lines">@@ -210,9 +212,7 @@
</span><span class="cx">     void    methodWithNonOptionalArgAndOptionalArg(long nonOpt, optional long opt);
</span><span class="cx">     void    methodWithNonOptionalArgAndTwoOptionalArgs(long nonOpt, optional long opt1, optional long opt2);
</span><span class="cx">     void    methodWithOptionalString(optional DOMString str);
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     void    methodWithOptionalUSVString(optional USVString str);
</span><del>-#endif
</del><span class="cx">     void    methodWithOptionalAtomicString([AtomicString] optional DOMString str);
</span><span class="cx">     void    methodWithOptionalStringAndDefaultValue(optional DOMString str = &quot;foo&quot;);
</span><span class="cx">     void    methodWithOptionalAtomicStringAndDefaultValue([AtomicString] optional DOMString str = &quot;foo&quot;);
</span><span class="lines">@@ -220,9 +220,7 @@
</span><span class="cx">     void    methodWithOptionalStringIsUndefined(optional DOMString str = &quot;undefined&quot;);
</span><span class="cx">     void    methodWithOptionalAtomicStringIsNull([AtomicString] optional DOMString str = null);
</span><span class="cx">     void    methodWithOptionalStringIsEmptyString(optional DOMString str = &quot;&quot;);
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     void    methodWithOptionalUSVStringIsEmptyString(optional USVString str = &quot;&quot;);
</span><del>-#endif
</del><span class="cx">     void    methodWithOptionalAtomicStringIsEmptyString([AtomicString] optional DOMString str = &quot;&quot;);
</span><span class="cx">     void    methodWithOptionalDoubleIsNaN(optional unrestricted double number = NaN);
</span><span class="cx">     void    methodWithOptionalFloatIsNaN(optional unrestricted float number = NaN);
</span><span class="lines">@@ -238,8 +236,8 @@
</span><span class="cx">     void    methodWithOptionalNullableWrapper(optional TestObj? obj);
</span><span class="cx">     void    methodWithOptionalNullableWrapperIsNull(optional TestObj? obj = null);
</span><span class="cx">     void    methodWithOptionalXPathNSResolver(optional XPathNSResolver? resolver);
</span><ins>+    void    methodWithOptionalRecord(optional record&lt;DOMString, long&gt;? record = null);
</ins><span class="cx"> 
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     // Callback interface parameters.
</span><span class="cx">     void    methodWithCallbackArg(TestCallbackInterface callback);
</span><span class="cx">     void    methodWithNonCallbackArgAndCallbackArg(long nonCallback, TestCallbackInterface callback);
</span><span class="lines">@@ -253,7 +251,6 @@
</span><span class="cx">     // static methods with 'Callback' extended attribute
</span><span class="cx">     static void    staticMethodWithCallbackAndOptionalArg(optional TestCallbackInterface? callback);
</span><span class="cx">     static void    staticMethodWithCallbackArg(TestCallbackInterface callback);
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     // 'Conditional' extended attribute
</span><span class="cx">     [Conditional=Condition1] attribute long conditionalAttr1;
</span><span class="lines">@@ -271,14 +268,11 @@
</span><span class="cx"> 
</span><span class="cx">     [Conditional=Condition1] const unsigned short CONDITIONAL_CONST = 0;
</span><span class="cx"> 
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     [CachedAttribute] readonly attribute any cachedAttribute1;
</span><span class="cx">     [CachedAttribute] readonly attribute any cachedAttribute2;
</span><del>-#endif
</del><span class="cx">     
</span><span class="cx">     attribute any anyAttribute;
</span><span class="cx"> 
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     // Overloads
</span><span class="cx">     void    overloadedMethod(TestObj? objArg, DOMString strArg);
</span><span class="cx">     void    overloadedMethod(TestObj? objArg, optional long longArg);
</span><span class="lines">@@ -316,7 +310,6 @@
</span><span class="cx"> 
</span><span class="cx">     void overloadWithNullableNonDistinguishingParameter(TestObj? obj, TestNode node);
</span><span class="cx">     void overloadWithNullableNonDistinguishingParameter(TestNode? node, long index);
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     // Class methods within JavaScript (like what's used for IDBKeyRange).
</span><span class="cx">     static void classMethod();
</span><span class="lines">@@ -330,7 +323,6 @@
</span><span class="cx">     void classMethodWithClamp([Clamp] unsigned short objArgsShort, [Clamp] unsigned long objArgsLong);
</span><span class="cx">     void classMethodWithEnforceRange([EnforceRange] unsigned short objArgsShort, [EnforceRange] unsigned long objArgsLong);
</span><span class="cx"> 
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     void methodWithUnsignedLongSequence(sequence&lt;unsigned long&gt; unsignedLongSequence);
</span><span class="cx">     [MayThrowException] sequence&lt;DOMString&gt; stringArrayFunction(sequence&lt;DOMString&gt; values);
</span><span class="cx">     [MayThrowException] DOMStringList domStringListFunction(DOMStringList values);
</span><span class="lines">@@ -338,7 +330,6 @@
</span><span class="cx">     void methodWithAndWithoutNullableSequence(sequence&lt;unsigned long&gt; arrayArg, sequence&lt;unsigned long&gt;? nullableArrayArg);
</span><span class="cx"> 
</span><span class="cx">     Element? getElementById([RequiresExistingAtomicString] DOMString elementId);
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     [CheckSecurityForNode] readonly attribute Document contentDocument;
</span><span class="cx">     [CheckSecurityForNode, MayThrowException] SVGDocument getSVGDocument();
</span><span class="lines">@@ -389,9 +380,8 @@
</span><span class="cx"> 
</span><span class="cx">     attribute long? nullableLongSettableAttribute;
</span><span class="cx">     attribute DOMString? nullableStringSettableAttribute;
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     attribute USVString? nullableUSVStringSettableAttribute;
</span><del>-#endif
</del><ins>+    attribute ByteString? nullableByteStringSettableAttribute;
</ins><span class="cx"> 
</span><span class="cx">     [GetterMayThrowException] attribute long? nullableStringValue;
</span><span class="cx"> 
</span><span class="lines">@@ -418,7 +408,6 @@
</span><span class="cx">     [PutForwards=name] readonly attribute TestNode putForwardsAttribute;
</span><span class="cx">     [PutForwards=name] readonly attribute TestNode? putForwardsNullableAttribute;
</span><span class="cx"> 
</span><del>-#if defined(TESTING_JS)
</del><span class="cx">     // Overloading with conditionals.
</span><span class="cx">     [Conditional=CONDITION1] void conditionalOverload(DOMString str);
</span><span class="cx">     [Conditional=CONDITION2] void conditionalOverload(long a);
</span><span class="lines">@@ -425,7 +414,6 @@
</span><span class="cx"> 
</span><span class="cx">     void singleConditionalOverload(DOMString str);
</span><span class="cx">     [Conditional=CONDITION] void singleConditionalOverload(long a);
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     void attachShadowRoot(TestDictionary init);
</span><span class="cx">     void operationWithExternalDictionaryParameter(TestStandaloneDictionary dict);
</span></span></pre></div>
<a id="trunkSourceWebCoretestingTypeConversionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/TypeConversions.h (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/TypeConversions.h        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/testing/TypeConversions.h        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Node.h&quot;
</span><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><ins>+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/Variant.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="lines">@@ -101,6 +102,13 @@
</span><span class="cx">     const String&amp; testByteString() const { return m_byteString; }
</span><span class="cx">     void setTestByteString(const String&amp; byteString) { m_byteString = byteString; }
</span><span class="cx"> 
</span><ins>+    const HashMap&lt;String, int&gt;&amp; testLongRecord() const { return m_longRecord; }
+    void setTestLongRecord(const HashMap&lt;String, int&gt;&amp; value) { m_longRecord = value; }
+    const HashMap&lt;String, RefPtr&lt;Node&gt;&gt;&amp; testNodeRecord() const { return m_nodeRecord; }
+    void setTestNodeRecord(const HashMap&lt;String, RefPtr&lt;Node&gt;&gt;&amp; value) { m_nodeRecord = value; }
+    const HashMap&lt;String, Vector&lt;String&gt;&gt;&amp; testSequenceRecord() const { return m_sequenceRecord; }
+    void setTestSequenceRecord(const HashMap&lt;String, Vector&lt;String&gt;&gt;&amp; value) { m_sequenceRecord = value; }
+
</ins><span class="cx">     using TestUnion = Variant&lt;String, int, bool, RefPtr&lt;Node&gt;, Vector&lt;int&gt;&gt;;
</span><span class="cx">     const TestUnion&amp; testUnion() const { return m_union; }
</span><span class="cx">     void setTestUnion(const TestUnion&amp; value) { m_union = value; }
</span><span class="lines">@@ -142,6 +150,9 @@
</span><span class="cx">     String m_string;
</span><span class="cx">     String m_usvstring;
</span><span class="cx">     String m_byteString;
</span><ins>+    HashMap&lt;String, int&gt; m_longRecord;
+    HashMap&lt;String, RefPtr&lt;Node&gt;&gt; m_nodeRecord;
+    HashMap&lt;String, Vector&lt;String&gt;&gt; m_sequenceRecord;
</ins><span class="cx">     TestUnion m_union;
</span><span class="cx">     
</span><span class="cx">     int m_typeConversionsDictionaryLongValue { 0 };
</span></span></pre></div>
<a id="trunkSourceWebCoretestingTypeConversionsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/TypeConversions.idl (208892 => 208893)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/TypeConversions.idl        2016-11-18 21:41:40 UTC (rev 208892)
+++ trunk/Source/WebCore/testing/TypeConversions.idl        2016-11-18 21:47:42 UTC (rev 208893)
</span><span class="lines">@@ -54,6 +54,10 @@
</span><span class="cx">     attribute ByteString testByteString;
</span><span class="cx">     attribute USVString testUSVString;
</span><span class="cx"> 
</span><ins>+    attribute record&lt;DOMString, long&gt; testLongRecord;
+    attribute record&lt;USVString, Node&gt; testNodeRecord;
+    attribute record&lt;ByteString, sequence&lt;DOMString&gt;&gt; testSequenceRecord;
+
</ins><span class="cx">     attribute (DOMString or long or boolean or Node or sequence&lt;long&gt;) testUnion;
</span><span class="cx">     
</span><span class="cx">     void setTypeConversionsDictionary(TypeConversionsDictionary d);
</span></span></pre>
</div>
</div>

</body>
</html>