JSDOMConvert is too big. Split it up!
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Feb 2017 18:55:24 +0000 (18:55 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Feb 2017 18:55:24 +0000 (18:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=167806

Rubber-stamped by Geoff Garen.

Split JSDOMConvert up roughly by IDL type. Some are grouped for convenience, e.g. all the
string types are together, all the numeric types are together. Also moved helpers from
JSDOMBinding to their respective JSDOMConvertFoo header. For now, JSDOMConvert.h as an
umbrella of all the sub headers, but it will be removed, and the code generator taught
to include the right header in a subsequent patch.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
Add new files.

* bindings/js/IDBBindingUtilities.cpp:
* bindings/js/IDBBindingUtilities.h:
Remove toJS that takes a std::optional<IDBKeyPath>, it was unused, and update date code
to only call valueToDate once, and pass things by reference.

* bindings/js/JSDOMBinding.cpp:
* bindings/js/JSDOMBinding.h:
Move most of the conversion helpers into their respective JSDOMConvertFoo header.

* bindings/js/JSDOMConvert.h:
Leave for now, just has includes of all the broken out headers.

* bindings/js/JSDOMConvertAny.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertBase.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertBoolean.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertBufferSource.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertCallbacks.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertDate.cpp: Copied from Source/WebCore/bindings/js/JSDOMBinding.cpp.
* bindings/js/JSDOMConvertDate.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertDictionary.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertEnumeration.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertEventListener.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertIndexedDB.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertInterface.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertJSON.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertNull.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertNullable.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertNumbers.cpp: Copied from Source/WebCore/bindings/js/JSDOMBinding.cpp.
* bindings/js/JSDOMConvertNumbers.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertObject.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertRecord.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertSequences.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertSerializedScriptValue.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertStrings.cpp: Copied from Source/WebCore/bindings/js/JSDOMBinding.cpp.
* bindings/js/JSDOMConvertStrings.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertUnion.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertVariadic.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertWebGL.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
* bindings/js/JSDOMConvertXPathNSResolver.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateParametersCheck):
Add include of JSDOMConvertVariadic.h rather than JSDOMConvert.

* bindings/js/JSCryptoCustom.cpp:
* bindings/js/JSCryptoOperationData.cpp:
* bindings/js/JSImageDataCustom.cpp:
* bindings/js/ReadableStreamDefaultController.h:
* bindings/js/WebCoreTypedArrayController.cpp:
* html/canvas/WebGLAny.cpp:
* platform/mac/SerializedPlatformRepresentationMac.mm:
Add includes for specific JSDOMConvert header now that helpers have
been moved their from JSDOMBinding.h

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211821 268f45cc-cd09-0410-ab3c-d52691b4dbfc

44 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/IDBBindingUtilities.cpp
Source/WebCore/bindings/js/IDBBindingUtilities.h
Source/WebCore/bindings/js/JSCryptoCustom.cpp
Source/WebCore/bindings/js/JSCryptoOperationData.cpp
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSDOMBinding.h
Source/WebCore/bindings/js/JSDOMConvert.h
Source/WebCore/bindings/js/JSDOMConvertAny.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertBase.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertBoolean.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertBufferSource.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertCallbacks.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertDate.cpp [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertDate.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertDictionary.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertEnumeration.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertEventListener.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertIndexedDB.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertInterface.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertJSON.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertNull.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertNullable.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertNumbers.cpp [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertNumbers.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertObject.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertRecord.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertSequences.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertSerializedScriptValue.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertStrings.cpp [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertStrings.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertUnion.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertVariadic.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertWebGL.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMConvertXPathNSResolver.h [new file with mode: 0644]
Source/WebCore/bindings/js/JSImageDataCustom.cpp
Source/WebCore/bindings/js/ReadableStreamDefaultController.cpp
Source/WebCore/bindings/js/ReadableStreamDefaultController.h
Source/WebCore/bindings/js/WebCoreTypedArrayController.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/html/canvas/WebGLAny.cpp
Source/WebCore/platform/mac/SerializedPlatformRepresentationMac.mm

index 5b991e7..b1ec9e5 100644 (file)
@@ -1085,6 +1085,9 @@ set(WebCore_SOURCES
     bindings/js/JSCSSRuleCustom.cpp
     bindings/js/JSCSSRuleListCustom.cpp
     bindings/js/JSCSSStyleDeclarationCustom.cpp
+    bindings/js/JSDOMConvertDate.cpp
+    bindings/js/JSDOMConvertNumbers.cpp
+    bindings/js/JSDOMConvertStrings.cpp
     bindings/js/JSDOMIterator.cpp
     bindings/js/JSFontFaceCustom.cpp
     bindings/js/JSFontFaceSetCustom.cpp
index 93ad042..f125d45 100644 (file)
@@ -1,5 +1,76 @@
 2017-02-07  Sam Weinig  <sam@webkit.org>
 
+        JSDOMConvert is too big. Split it up!
+        https://bugs.webkit.org/show_bug.cgi?id=167806
+
+        Rubber-stamped by Geoff Garen.
+
+        Split JSDOMConvert up roughly by IDL type. Some are grouped for convenience, e.g. all the
+        string types are together, all the numeric types are together. Also moved helpers from 
+        JSDOMBinding to their respective JSDOMConvertFoo header. For now, JSDOMConvert.h as an
+        umbrella of all the sub headers, but it will be removed, and the code generator taught
+        to include the right header in a subsequent patch.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        Add new files.
+
+        * bindings/js/IDBBindingUtilities.cpp:
+        * bindings/js/IDBBindingUtilities.h:
+        Remove toJS that takes a std::optional<IDBKeyPath>, it was unused, and update date code
+        to only call valueToDate once, and pass things by reference.
+
+        * bindings/js/JSDOMBinding.cpp:
+        * bindings/js/JSDOMBinding.h:
+        Move most of the conversion helpers into their respective JSDOMConvertFoo header.
+
+        * bindings/js/JSDOMConvert.h:
+        Leave for now, just has includes of all the broken out headers.
+
+        * bindings/js/JSDOMConvertAny.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertBase.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertBoolean.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertBufferSource.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertCallbacks.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertDate.cpp: Copied from Source/WebCore/bindings/js/JSDOMBinding.cpp.
+        * bindings/js/JSDOMConvertDate.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertDictionary.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertEnumeration.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertEventListener.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertIndexedDB.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertInterface.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertJSON.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertNull.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertNullable.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertNumbers.cpp: Copied from Source/WebCore/bindings/js/JSDOMBinding.cpp.
+        * bindings/js/JSDOMConvertNumbers.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertObject.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertRecord.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertSequences.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertSerializedScriptValue.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertStrings.cpp: Copied from Source/WebCore/bindings/js/JSDOMBinding.cpp.
+        * bindings/js/JSDOMConvertStrings.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertUnion.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertVariadic.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertWebGL.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+        * bindings/js/JSDOMConvertXPathNSResolver.h: Copied from Source/WebCore/bindings/js/JSDOMConvert.h.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateParametersCheck):
+        Add include of JSDOMConvertVariadic.h rather than JSDOMConvert.
+
+        * bindings/js/JSCryptoCustom.cpp:
+        * bindings/js/JSCryptoOperationData.cpp:
+        * bindings/js/JSImageDataCustom.cpp:
+        * bindings/js/ReadableStreamDefaultController.h:
+        * bindings/js/WebCoreTypedArrayController.cpp:
+        * html/canvas/WebGLAny.cpp:
+        * platform/mac/SerializedPlatformRepresentationMac.mm:
+        Add includes for specific JSDOMConvert header now that helpers have 
+        been moved their from JSDOMBinding.h
+
+2017-02-07  Sam Weinig  <sam@webkit.org>
+
         Remove unnecessary exports on inline functions. They were causing build failures
         with some compilers.
 
index 5beaf63..c3cdf62 100644 (file)
                7C7941E41C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */; };
                7C7941E51C56C29300A4C58E /* DataDetectorsCoreSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C7941E31C56C29300A4C58E /* DataDetectorsCoreSoftLink.h */; };
                7C83DE861D04CC5D00FEBCF3 /* SpringSolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C83DE851D04CBD400FEBCF3 /* SpringSolver.h */; };
+               7C8E34AD1E4A33AF0054CE23 /* JSDOMConvertAny.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34921E4A338E0054CE23 /* JSDOMConvertAny.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34AE1E4A33AF0054CE23 /* JSDOMConvertBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34931E4A338E0054CE23 /* JSDOMConvertBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34AF1E4A33AF0054CE23 /* JSDOMConvertBoolean.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34941E4A338E0054CE23 /* JSDOMConvertBoolean.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B01E4A33AF0054CE23 /* JSDOMConvertBufferSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34951E4A338E0054CE23 /* JSDOMConvertBufferSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B11E4A33B00054CE23 /* JSDOMConvertCallbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34961E4A338E0054CE23 /* JSDOMConvertCallbacks.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B21E4A33B00054CE23 /* JSDOMConvertDate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8E34971E4A338E0054CE23 /* JSDOMConvertDate.cpp */; };
+               7C8E34B31E4A33B00054CE23 /* JSDOMConvertDate.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34981E4A338E0054CE23 /* JSDOMConvertDate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B41E4A33B00054CE23 /* JSDOMConvertDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34991E4A338E0054CE23 /* JSDOMConvertDictionary.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B51E4A33B00054CE23 /* JSDOMConvertEnumeration.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E349A1E4A338E0054CE23 /* JSDOMConvertEnumeration.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B61E4A33B00054CE23 /* JSDOMConvertEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E349B1E4A338E0054CE23 /* JSDOMConvertEventListener.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B71E4A33B00054CE23 /* JSDOMConvertIndexedDB.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E349C1E4A338E0054CE23 /* JSDOMConvertIndexedDB.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B81E4A33B00054CE23 /* JSDOMConvertInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E349D1E4A338E0054CE23 /* JSDOMConvertInterface.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34B91E4A33B00054CE23 /* JSDOMConvertJSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E349E1E4A338E0054CE23 /* JSDOMConvertJSON.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34BA1E4A33B00054CE23 /* JSDOMConvertNull.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E349F1E4A338E0054CE23 /* JSDOMConvertNull.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34BB1E4A33B00054CE23 /* JSDOMConvertNullable.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34A01E4A338E0054CE23 /* JSDOMConvertNullable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34BC1E4A33B00054CE23 /* JSDOMConvertNumbers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8E34A11E4A338E0054CE23 /* JSDOMConvertNumbers.cpp */; };
+               7C8E34BD1E4A33B00054CE23 /* JSDOMConvertNumbers.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34A21E4A338E0054CE23 /* JSDOMConvertNumbers.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34BE1E4A33B00054CE23 /* JSDOMConvertObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34A31E4A338E0054CE23 /* JSDOMConvertObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34BF1E4A33B00054CE23 /* JSDOMConvertRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34A41E4A338E0054CE23 /* JSDOMConvertRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34C01E4A33B00054CE23 /* JSDOMConvertSequences.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34A51E4A338E0054CE23 /* JSDOMConvertSequences.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34C11E4A33B00054CE23 /* JSDOMConvertSerializedScriptValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34A61E4A338E0054CE23 /* JSDOMConvertSerializedScriptValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34C21E4A33B00054CE23 /* JSDOMConvertStrings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8E34A71E4A338E0054CE23 /* JSDOMConvertStrings.cpp */; };
+               7C8E34C31E4A33B00054CE23 /* JSDOMConvertStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34A81E4A338E0054CE23 /* JSDOMConvertStrings.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34C41E4A33B00054CE23 /* JSDOMConvertUnion.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34A91E4A338E0054CE23 /* JSDOMConvertUnion.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34C51E4A33B00054CE23 /* JSDOMConvertVariadic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34AA1E4A338E0054CE23 /* JSDOMConvertVariadic.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34C61E4A33B00054CE23 /* JSDOMConvertWebGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34AB1E4A338E0054CE23 /* JSDOMConvertWebGL.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7C8E34C71E4A33B00054CE23 /* JSDOMConvertXPathNSResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C8E34AC1E4A338E0054CE23 /* JSDOMConvertXPathNSResolver.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7C8F22441DD3C2F600E92DA3 /* SVGAngleValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8F22421DD3B3B900E92DA3 /* SVGAngleValue.cpp */; };
                7C8F22471DD3D1CA00E92DA3 /* SVGPreserveAspectRatioValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8F22451DD3D1C500E92DA3 /* SVGPreserveAspectRatioValue.cpp */; };
                7C93F3491AA6BA5E00A98BAB /* CompiledContentExtension.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C93F3471AA6BA5E00A98BAB /* CompiledContentExtension.cpp */; };
                7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsCoreSoftLink.mm; sourceTree = "<group>"; };
                7C7941E31C56C29300A4C58E /* DataDetectorsCoreSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataDetectorsCoreSoftLink.h; sourceTree = "<group>"; };
                7C83DE851D04CBD400FEBCF3 /* SpringSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpringSolver.h; sourceTree = "<group>"; };
+               7C8E34921E4A338E0054CE23 /* JSDOMConvertAny.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertAny.h; sourceTree = "<group>"; };
+               7C8E34931E4A338E0054CE23 /* JSDOMConvertBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertBase.h; sourceTree = "<group>"; };
+               7C8E34941E4A338E0054CE23 /* JSDOMConvertBoolean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertBoolean.h; sourceTree = "<group>"; };
+               7C8E34951E4A338E0054CE23 /* JSDOMConvertBufferSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertBufferSource.h; sourceTree = "<group>"; };
+               7C8E34961E4A338E0054CE23 /* JSDOMConvertCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertCallbacks.h; sourceTree = "<group>"; };
+               7C8E34971E4A338E0054CE23 /* JSDOMConvertDate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMConvertDate.cpp; sourceTree = "<group>"; };
+               7C8E34981E4A338E0054CE23 /* JSDOMConvertDate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertDate.h; sourceTree = "<group>"; };
+               7C8E34991E4A338E0054CE23 /* JSDOMConvertDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertDictionary.h; sourceTree = "<group>"; };
+               7C8E349A1E4A338E0054CE23 /* JSDOMConvertEnumeration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertEnumeration.h; sourceTree = "<group>"; };
+               7C8E349B1E4A338E0054CE23 /* JSDOMConvertEventListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertEventListener.h; sourceTree = "<group>"; };
+               7C8E349C1E4A338E0054CE23 /* JSDOMConvertIndexedDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertIndexedDB.h; sourceTree = "<group>"; };
+               7C8E349D1E4A338E0054CE23 /* JSDOMConvertInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertInterface.h; sourceTree = "<group>"; };
+               7C8E349E1E4A338E0054CE23 /* JSDOMConvertJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertJSON.h; sourceTree = "<group>"; };
+               7C8E349F1E4A338E0054CE23 /* JSDOMConvertNull.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertNull.h; sourceTree = "<group>"; };
+               7C8E34A01E4A338E0054CE23 /* JSDOMConvertNullable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertNullable.h; sourceTree = "<group>"; };
+               7C8E34A11E4A338E0054CE23 /* JSDOMConvertNumbers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMConvertNumbers.cpp; sourceTree = "<group>"; };
+               7C8E34A21E4A338E0054CE23 /* JSDOMConvertNumbers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertNumbers.h; sourceTree = "<group>"; };
+               7C8E34A31E4A338E0054CE23 /* JSDOMConvertObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertObject.h; sourceTree = "<group>"; };
+               7C8E34A41E4A338E0054CE23 /* JSDOMConvertRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertRecord.h; sourceTree = "<group>"; };
+               7C8E34A51E4A338E0054CE23 /* JSDOMConvertSequences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertSequences.h; sourceTree = "<group>"; };
+               7C8E34A61E4A338E0054CE23 /* JSDOMConvertSerializedScriptValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertSerializedScriptValue.h; sourceTree = "<group>"; };
+               7C8E34A71E4A338E0054CE23 /* JSDOMConvertStrings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMConvertStrings.cpp; sourceTree = "<group>"; };
+               7C8E34A81E4A338E0054CE23 /* JSDOMConvertStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertStrings.h; sourceTree = "<group>"; };
+               7C8E34A91E4A338E0054CE23 /* JSDOMConvertUnion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertUnion.h; sourceTree = "<group>"; };
+               7C8E34AA1E4A338E0054CE23 /* JSDOMConvertVariadic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertVariadic.h; sourceTree = "<group>"; };
+               7C8E34AB1E4A338E0054CE23 /* JSDOMConvertWebGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertWebGL.h; sourceTree = "<group>"; };
+               7C8E34AC1E4A338E0054CE23 /* JSDOMConvertXPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertXPathNSResolver.h; sourceTree = "<group>"; };
                7C8F22421DD3B3B900E92DA3 /* SVGAngleValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAngleValue.cpp; sourceTree = "<group>"; };
                7C8F22431DD3B3B900E92DA3 /* SVGAngleValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAngleValue.h; sourceTree = "<group>"; };
                7C8F22451DD3D1C500E92DA3 /* SVGPreserveAspectRatioValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGPreserveAspectRatioValue.cpp; sourceTree = "<group>"; };
                        name = scripts;
                        sourceTree = "<group>";
                };
+               7C8E34911E4A33730054CE23 /* Conversions */ = {
+                       isa = PBXGroup;
+                       children = (
+                               930841331CDDB15500B0958C /* JSDOMConvert.h */,
+                               7C8E34921E4A338E0054CE23 /* JSDOMConvertAny.h */,
+                               7C8E34931E4A338E0054CE23 /* JSDOMConvertBase.h */,
+                               7C8E34941E4A338E0054CE23 /* JSDOMConvertBoolean.h */,
+                               7C8E34951E4A338E0054CE23 /* JSDOMConvertBufferSource.h */,
+                               7C8E34961E4A338E0054CE23 /* JSDOMConvertCallbacks.h */,
+                               7C8E34971E4A338E0054CE23 /* JSDOMConvertDate.cpp */,
+                               7C8E34981E4A338E0054CE23 /* JSDOMConvertDate.h */,
+                               7C8E34991E4A338E0054CE23 /* JSDOMConvertDictionary.h */,
+                               7C8E349A1E4A338E0054CE23 /* JSDOMConvertEnumeration.h */,
+                               7C8E349B1E4A338E0054CE23 /* JSDOMConvertEventListener.h */,
+                               7C8E349C1E4A338E0054CE23 /* JSDOMConvertIndexedDB.h */,
+                               7C8E349D1E4A338E0054CE23 /* JSDOMConvertInterface.h */,
+                               7C8E349E1E4A338E0054CE23 /* JSDOMConvertJSON.h */,
+                               7C8E349F1E4A338E0054CE23 /* JSDOMConvertNull.h */,
+                               7C8E34A01E4A338E0054CE23 /* JSDOMConvertNullable.h */,
+                               7C8E34A11E4A338E0054CE23 /* JSDOMConvertNumbers.cpp */,
+                               7C8E34A21E4A338E0054CE23 /* JSDOMConvertNumbers.h */,
+                               7C8E34A31E4A338E0054CE23 /* JSDOMConvertObject.h */,
+                               7C8E34A41E4A338E0054CE23 /* JSDOMConvertRecord.h */,
+                               7C8E34A51E4A338E0054CE23 /* JSDOMConvertSequences.h */,
+                               7C8E34A61E4A338E0054CE23 /* JSDOMConvertSerializedScriptValue.h */,
+                               7C8E34A71E4A338E0054CE23 /* JSDOMConvertStrings.cpp */,
+                               7C8E34A81E4A338E0054CE23 /* JSDOMConvertStrings.h */,
+                               7C8E34A91E4A338E0054CE23 /* JSDOMConvertUnion.h */,
+                               7C8E34AA1E4A338E0054CE23 /* JSDOMConvertVariadic.h */,
+                               7C8E34AB1E4A338E0054CE23 /* JSDOMConvertWebGL.h */,
+                               7C8E34AC1E4A338E0054CE23 /* JSDOMConvertXPathNSResolver.h */,
+                       );
+                       name = Conversions;
+                       sourceTree = "<group>";
+               };
                7E4DE10B198B10810051CB02 /* cocoa */ = {
                        isa = PBXGroup;
                        children = (
                        children = (
                                BCCE58A71061E82F008FB35A /* Callback Objects */,
                                BCCE58B41061E925008FB35A /* Constructors */,
+                               7C8E34911E4A33730054CE23 /* Conversions */,
                                BC4EDEF70C08F414007EDD49 /* Custom */,
                                14DFB33F0A7DF7630018F769 /* Derived Sources */,
                                2DFA488E1DB541C200362B99 /* BufferSource.h */,
                                7C45C9C91E3E8CD700AAB558 /* JSDOMBindingSecurity.h */,
                                7C45C9CD1E3E900B00AAB558 /* JSDOMConstructor.cpp */,
                                413C2C331BC29A7B0075204C /* JSDOMConstructor.h */,
-                               930841331CDDB15500B0958C /* JSDOMConvert.h */,
                                7C45C9CC1E3E8F0800AAB558 /* JSDOMExceptionHandling.cpp */,
                                7C45C9C71E3E8AFF00AAB558 /* JSDOMExceptionHandling.h */,
                                E1C36CBC0EB08062007410BC /* JSDOMGlobalObject.cpp */,
                                379E61CA126CA5C400B63E8D /* BaseButtonInputType.h in Headers */,
                                379E61CC126CA5C400B63E8D /* BaseCheckableInputType.h in Headers */,
                                F5E0C65C1643C42C00D6CB69 /* BaseChooserOnlyDateAndTimeInputType.h in Headers */,
+                               7C8E34C01E4A33B00054CE23 /* JSDOMConvertSequences.h in Headers */,
                                C33EE5C514FB49610002095A /* BaseClickableWithKeyInputType.h in Headers */,
                                F59C96001255B23F000623C0 /* BaseDateAndTimeInputType.h in Headers */,
                                F55B3DAE1251F12D003EF269 /* BaseTextInputType.h in Headers */,
                                E19AC3F51824DC7900349426 /* CryptoAlgorithmSHA512.h in Headers */,
                                E157A8E518173A3A009F821D /* CryptoKey.h in Headers */,
                                E125F84E1824289D00D84CD9 /* CryptoKeyAES.h in Headers */,
+                               7C8E34B81E4A33B00054CE23 /* JSDOMConvertInterface.h in Headers */,
                                E125F85E182C2DF600D84CD9 /* CryptoKeyData.h in Headers */,
                                E125F864182C303A00D84CD9 /* CryptoKeyDataOctetSequence.h in Headers */,
                                E1C266DF18319F31003F8B33 /* CryptoKeyDataRSAComponents.h in Headers */,
                                516C62211950D48700337E75 /* GamepadEvent.h in Headers */,
                                51A9D9EA195B931F001B2B5C /* GamepadManager.h in Headers */,
                                515BE1921D54F5FB00DD7C68 /* GamepadProvider.h in Headers */,
+                               7C8E34B31E4A33B00054CE23 /* JSDOMConvertDate.h in Headers */,
                                515BE1931D54F5FB00DD7C68 /* GamepadProviderClient.h in Headers */,
                                935C477509AC4D8E00A6AAB4 /* GapRects.h in Headers */,
                                1432E8470C51493800B1500F /* GCController.h in Headers */,
                                B27535740B053814002CE64F /* IntRect.h in Headers */,
                                A2B9217316C5CC420041DCD9 /* IntRectExtent.h in Headers */,
                                E134F5AB12EE343F004EC58D /* IntRectHash.h in Headers */,
+                               7C8E34C61E4A33B00054CE23 /* JSDOMConvertWebGL.h in Headers */,
                                B27535750B053814002CE64F /* IntSize.h in Headers */,
                                B27535760B053814002CE64F /* IntSizeHash.h in Headers */,
                                CE12524D1A1A77DE00864480 /* IOPMLibSPI.h in Headers */,
                                76808B50159DADFA002B5233 /* JSHTMLDialogElement.h in Headers */,
                                1A85B1E70A1B240500D8C87C /* JSHTMLDirectoryElement.h in Headers */,
                                1A85B2B70A1B2AC700D8C87C /* JSHTMLDivElement.h in Headers */,
+                               7C8E34C71E4A33B00054CE23 /* JSDOMConvertXPathNSResolver.h in Headers */,
                                1A85B1E90A1B240500D8C87C /* JSHTMLDListElement.h in Headers */,
                                1A494E350A12358B00FDAFC1 /* JSHTMLDocument.h in Headers */,
                                1A494BFB0A122F4400FDAFC1 /* JSHTMLElement.h in Headers */,
                                1A85B1EB0A1B240500D8C87C /* JSHTMLOListElement.h in Headers */,
                                A80E7E9B0A1A83E3007FB8C5 /* JSHTMLOptGroupElement.h in Headers */,
                                A80E7E990A1A83E3007FB8C5 /* JSHTMLOptionElement.h in Headers */,
+                               7C8E34BD1E4A33B00054CE23 /* JSDOMConvertNumbers.h in Headers */,
                                448A29BF0A46D9CB0030759F /* JSHTMLOptionsCollection.h in Headers */,
                                4AD0173D127E82860015035F /* JSHTMLOutputElement.h in Headers */,
                                1AE2ABA70A1CE90500B42B25 /* JSHTMLParagraphElement.h in Headers */,
                                B658FFA21522EF3A00DD5595 /* JSRadioNodeList.h in Headers */,
                                65DF320209D1CC60000BE325 /* JSRange.h in Headers */,
                                6C4C96DF1AD4483500363F64 /* JSReadableByteStreamController.h in Headers */,
+                               7C8E34B41E4A33B00054CE23 /* JSDOMConvertDictionary.h in Headers */,
                                7C4C96DD1AD4483500365A50 /* JSReadableStream.h in Headers */,
                                6C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultController.h in Headers */,
                                7C4C96DF1AD4483500365A50 /* JSReadableStreamDefaultReader.h in Headers */,
                                B2FA3DD10AB75A6F000E5AC4 /* JSSVGPathSegLinetoHorizontalAbs.h in Headers */,
                                B2FA3DD30AB75A6F000E5AC4 /* JSSVGPathSegLinetoHorizontalRel.h in Headers */,
                                B2FA3DD50AB75A6F000E5AC4 /* JSSVGPathSegLinetoRel.h in Headers */,
+                               7C8E34AF1E4A33AF0054CE23 /* JSDOMConvertBoolean.h in Headers */,
                                B2FA3DD70AB75A6F000E5AC4 /* JSSVGPathSegLinetoVerticalAbs.h in Headers */,
                                B2FA3DD90AB75A6F000E5AC4 /* JSSVGPathSegLinetoVerticalRel.h in Headers */,
                                B2FA3DDB0AB75A6F000E5AC4 /* JSSVGPathSegList.h in Headers */,
                                0C45342810CDBBFA00869157 /* JSWebGLUniformLocation.h in Headers */,
                                6F995A3A1A70833700A735F4 /* JSWebGLVertexArrayObject.h in Headers */,
                                77EF62F412F9DB7400C77BD2 /* JSWebGLVertexArrayObjectOES.h in Headers */,
+                               7C8E34C11E4A33B00054CE23 /* JSDOMConvertSerializedScriptValue.h in Headers */,
                                31C0FF3E0E4CEFAC007D6FE5 /* JSWebKitAnimationEvent.h in Headers */,
                                498391400F1E767500C23782 /* JSWebKitCSSMatrix.h in Headers */,
                                8AD0A59514C88336000D83C5 /* JSWebKitCSSRegionRule.h in Headers */,
                                BCDFD4960E30592F009D10AD /* JSXMLHttpRequestUpload.h in Headers */,
                                1ACE53F70A8D19470022947D /* JSXMLSerializer.h in Headers */,
                                1A762C740A074F2600989F5B /* JSXPathEvaluator.h in Headers */,
+                               7C8E34BB1E4A33B00054CE23 /* JSDOMConvertNullable.h in Headers */,
                                BC60DB4A0D2A3D1E00B9918F /* JSXPathException.h in Headers */,
                                1A762C760A074F2600989F5B /* JSXPathExpression.h in Headers */,
                                1A762C780A074F2600989F5B /* JSXPathNSResolver.h in Headers */,
                                D6E276B014637455001D280A /* MutationObserverRegistration.h in Headers */,
                                C6F08FBD1430FE8F00685849 /* MutationRecord.h in Headers */,
                                52B6C9C615E3F4DF00690B05 /* NamedFlowCollection.h in Headers */,
+                               7C8E34B61E4A33B00054CE23 /* JSDOMConvertEventListener.h in Headers */,
                                314BE3A71B3103FB00141982 /* NamedImageGeneratedImage.h in Headers */,
                                A81872230977D3C0005826D9 /* NamedNodeMap.h in Headers */,
                                A818721E0977D3C0005826D9 /* NameNodeList.h in Headers */,
                                0F13163E16ED0CC80035CC04 /* PlatformCAFilters.h in Headers */,
                                499B3EC5128CCC4700E726C2 /* PlatformCALayer.h in Headers */,
                                493E5E0912D6420500020081 /* PlatformCALayerClient.h in Headers */,
+                               7C8E34B71E4A33B00054CE23 /* JSDOMConvertIndexedDB.h in Headers */,
                                2D70BA1318074DDF0001908A /* PlatformCALayerCocoa.h in Headers */,
                                A14978711ABAF3A500CEF7E4 /* PlatformContentFilter.h in Headers */,
                                E1424C8A164B3B4E00F32D40 /* PlatformCookieJar.h in Headers */,
                                BCAA487014A052530088FAC4 /* PlatformEventFactoryMac.h in Headers */,
                                A723F77B1484CA4C008C6DBE /* PlatformExportMacros.h in Headers */,
                                515BE1951D54F5FB00DD7C68 /* PlatformGamepad.h in Headers */,
+                               7C8E34B01E4A33AF0054CE23 /* JSDOMConvertBufferSource.h in Headers */,
                                935C476809AC4D4300A6AAB4 /* PlatformKeyboardEvent.h in Headers */,
+                               7C8E34AE1E4A33AF0054CE23 /* JSDOMConvertBase.h in Headers */,
                                0562F9611573F88F0031CA16 /* PlatformLayer.h in Headers */,
                                F544F78915CFB2A800AF33A8 /* PlatformLocale.h in Headers */,
                                CEEFCD7C19DB33DC003876D7 /* PlatformMediaResourceLoader.h in Headers */,
                                078E092117D14D1C00420AA1 /* RTCDTMFToneChangeEvent.h in Headers */,
                                078E092317D14D1C00420AA1 /* RTCIceCandidate.h in Headers */,
                                078E094017D16E1C00420AA1 /* RTCIceCandidateDescriptor.h in Headers */,
+                               7C8E34BF1E4A33B00054CE23 /* JSDOMConvertRecord.h in Headers */,
                                078E092417D14D1C00420AA1 /* RTCIceCandidateEvent.h in Headers */,
                                07AB996B18DA3C010018771E /* RTCIceServer.h in Headers */,
                                073794FE19F5864E00E5A045 /* RTCNotifiersMock.h in Headers */,
                                7AAFE8D019CB8672000F56D8 /* ScrollLatchingState.h in Headers */,
                                F478755419983AFF0024A287 /* ScrollSnapAnimatorState.h in Headers */,
                                F46729281E0DE68500ACC3D8 /* ScrollSnapOffsetsInfo.h in Headers */,
+                               7C8E34B11E4A33B00054CE23 /* JSDOMConvertCallbacks.h in Headers */,
                                83C5795D1DA5C301006FACA8 /* ScrollToOptions.h in Headers */,
                                93C09C860B0657AA005ABD4D /* ScrollTypes.h in Headers */,
                                BC6D6E2609AF943500F59759 /* ScrollView.h in Headers */,
                                B2227AD40D00BF220071B782 /* SVGTitleElement.h in Headers */,
                                1CCDF5BE1990332400BCEBAD /* SVGToOTFFontConversion.h in Headers */,
                                B2227AD70D00BF220071B782 /* SVGTransform.h in Headers */,
+                               7C8E34AD1E4A33AF0054CE23 /* JSDOMConvertAny.h in Headers */,
                                B2227ADA0D00BF220071B782 /* SVGTransformable.h in Headers */,
                                B2227ADD0D00BF220071B782 /* SVGTransformDistance.h in Headers */,
                                B2227ADF0D00BF220071B782 /* SVGTransformList.h in Headers */,
                                E1FF57A30F01255B00891EBB /* ThreadGlobalData.h in Headers */,
                                51D7EFEA1BDE8F8C00E93E10 /* ThreadSafeDataBuffer.h in Headers */,
                                185BCF290F3279CE000EA262 /* ThreadTimers.h in Headers */,
+                               7C8E34C41E4A33B00054CE23 /* JSDOMConvertUnion.h in Headers */,
                                7AA3A69A194A64E7001CBD24 /* TileController.h in Headers */,
                                1F72BF0B187FD45C0009BCB3 /* TileControllerMemoryHandlerIOS.h in Headers */,
                                7AA3A6A4194B5C22001CBD24 /* TileCoverageMap.h in Headers */,
                                F55B3DDC1251F12D003EF269 /* TimeInputType.h in Headers */,
                                7553CFE8108F473F00EA281E /* TimelineRecordFactory.h in Headers */,
                                9305B24D098F1B6B00C28855 /* Timer.h in Headers */,
+                               7C8E34C31E4A33B00054CE23 /* JSDOMConvertStrings.h in Headers */,
                                E44613B00CD6331000FADA75 /* TimeRanges.h in Headers */,
                                2D7ED0AB1BAE99170043B3E5 /* TimerEventBasedMock.h in Headers */,
                                49E912AE0EFAC906009D0CAF /* TimingFunction.h in Headers */,
                                BCBD21AB0E417AD400A070F2 /* URLHash.h in Headers */,
                                F55B3DDE1251F12D003EF269 /* URLInputType.h in Headers */,
                                5C6E65431D5CEFBF00F7862E /* URLParser.h in Headers */,
+                               7C8E34B51E4A33B00054CE23 /* JSDOMConvertEnumeration.h in Headers */,
                                7CC289DF1AA0FE5D009A9CE3 /* URLRegistry.h in Headers */,
                                93D437A21D57B3FE00AB85EA /* URLUtils.h in Headers */,
                                A72763BF16689BFB002FCACB /* UserActionElementSet.h in Headers */,
                                A56C5B9B189F34570082D13C /* WebConsoleAgent.h in Headers */,
                                419BE7591BC7F42B00E1C85B /* WebCoreBuiltinNames.h in Headers */,
                                2D3EF44A1917915C00034184 /* WebCoreCALayerExtras.h in Headers */,
+                               7C8E34BE1E4A33B00054CE23 /* JSDOMConvertObject.h in Headers */,
                                515F79541CFCA3D500CCED93 /* WebCoreCrossThreadCopier.h in Headers */,
                                93F199A808245E59001E9ABC /* WebCoreFrameView.h in Headers */,
                                CDC69DDA16371FD4007C38DF /* WebCoreFullScreenPlaceholderView.h in Headers */,
                                7C48A6D1191C9D6500026674 /* WebKitNamespace.h in Headers */,
                                A5DEBDA416FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.h in Headers */,
                                494BD7950F55C8EE00747828 /* WebKitPoint.h in Headers */,
+                               7C8E34C51E4A33B00054CE23 /* JSDOMConvertVariadic.h in Headers */,
                                5709E8CF1D413D9A003244AC /* WebKitSubtleCrypto.h in Headers */,
                                31C0FF250E4CEB6E007D6FE5 /* WebKitTransitionEvent.h in Headers */,
                                0FCF332F0F2B9A25004B6795 /* WebLayer.h in Headers */,
                                416E6FE81BBD12DF000A6053 /* WritableStreamInternalsBuiltins.h in Headers */,
                                9BAF3B2412C1A39800014BF1 /* WritingDirection.h in Headers */,
                                14476AA815DC4BB100305DB2 /* WritingMode.h in Headers */,
+                               7C8E34BA1E4A33B00054CE23 /* JSDOMConvertNull.h in Headers */,
                                6565820209D1508D000E61D7 /* XLinkNames.h in Headers */,
                                830784B21C52EE2C00104D1D /* XMLDocument.h in Headers */,
                                00B9318813BA8DBA0035A948 /* XMLDocumentParser.h in Headers */,
                                BCDFD48E0E305290009D10AD /* XMLHttpRequestUpload.h in Headers */,
                                A833C80D0A2CF25600D57664 /* XMLNames.h in Headers */,
                                E15A36D71104572000B7B639 /* XMLNSNames.h in Headers */,
+                               7C8E34B91E4A33B00054CE23 /* JSDOMConvertJSON.h in Headers */,
                                1ACE53EB0A8D18E70022947D /* XMLSerializer.h in Headers */,
                                5905ADC01302F3CE00F116DF /* XMLTreeViewer.h in Headers */,
                                1AB7FC690A8B92EC00D9D37B /* XPathEvaluator.h in Headers */,
                                A80E6CF70A1989CA007FB8C5 /* CSSProperty.cpp in Sources */,
                                78D02BC5154A18DF00B62D05 /* CSSPropertyAnimation.cpp in Sources */,
                                1ABA76CA11D20E50004C201C /* CSSPropertyNames.cpp in Sources */,
+                               7C8E34B21E4A33B00054CE23 /* JSDOMConvertDate.cpp in Sources */,
                                946D37451D6D01D40077084F /* CSSPropertyParser.cpp in Sources */,
                                949C77041D6E39EA00C0DE4F /* CSSPropertyParserHelpers.cpp in Sources */,
                                82E3D8DE122EA0D1003AE5BC /* CSSPropertySourceData.cpp in Sources */,
                                9A528E8317D7F52F00AA9518 /* FloatingObjects.cpp in Sources */,
                                FE699871192087E7006936BD /* FloatingPointEnvironment.cpp in Sources */,
                                B27535680B053814002CE64F /* FloatPoint.cpp in Sources */,
+                               7C8E34C21E4A33B00054CE23 /* JSDOMConvertStrings.cpp in Sources */,
                                B2E27C9F0B0F2B0900F17C7B /* FloatPoint3D.cpp in Sources */,
                                B27535590B053814002CE64F /* FloatPointCG.cpp in Sources */,
                                B27535780B053814002CE64F /* FloatPointMac.mm in Sources */,
                                BCE32B9E1517C22700F542EC /* RenderMultiColumnSet.cpp in Sources */,
                                BC1A7D9718FCB5B000421879 /* RenderMultiColumnSpannerPlaceholder.cpp in Sources */,
                                8AC822FC180FC03300FB64D5 /* RenderNamedFlowFragment.cpp in Sources */,
+                               7C8E34BC1E4A33B00054CE23 /* JSDOMConvertNumbers.cpp in Sources */,
                                1A3FF9C315265359002288A1 /* RenderNamedFlowThread.cpp in Sources */,
                                BCEA487F097D93020094C9E4 /* RenderObject.cpp in Sources */,
                                A43BF59C1149292800C643CA /* RenderProgress.cpp in Sources */,
index aae1248..5195e77 100644 (file)
@@ -28,6 +28,7 @@
 #include "config.h"
 
 #if ENABLE(INDEXED_DATABASE)
+
 #include "IDBBindingUtilities.h"
 
 #include "IDBIndexInfo.h"
@@ -151,8 +152,11 @@ static RefPtr<IDBKey> createIDBKeyFromValue(ExecState& exec, JSValue value, Vect
     if (value.isString())
         return IDBKey::createString(asString(value)->value(&exec));
 
-    if (value.inherits(vm, DateInstance::info()) && !std::isnan(valueToDate(&exec, value)))
-        return IDBKey::createDate(valueToDate(&exec, value));
+    if (value.inherits(vm, DateInstance::info())) {
+        auto dateValue = valueToDate(exec, value);
+        if (!std::isnan(dateValue))
+            return IDBKey::createDate(dateValue);
+    }
 
     if (value.isObject()) {
         JSObject* object = asObject(value);
@@ -415,19 +419,6 @@ void generateIndexKeyForValue(ExecState& exec, const IDBIndexInfo& info, JSValue
     outKey = IndexKey(WTFMove(keyDatas));
 }
 
-JSValue toJS(ExecState& state, JSDOMGlobalObject& globalObject, const std::optional<IDBKeyPath>& keyPath)
-{
-    if (!keyPath)
-        return jsNull();
-
-    auto visitor = WTF::makeVisitor([&](const String& string) -> JSValue {
-        return toJS<IDLDOMString>(state, globalObject, string);
-    }, [&](const Vector<String>& vector) -> JSValue {
-        return toJS<IDLSequence<IDLDOMString>>(state, globalObject, vector);
-    });
-    return WTF::visit(visitor, keyPath.value());
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
index a86c10c..e213f4c 100644 (file)
@@ -45,10 +45,7 @@ class IDBKeyData;
 class IDBValue;
 class IndexKey;
 class JSDOMGlobalObject;
-class ThreadSafeDataBuffer;
 
-// FIXME: Remove this once we support returning union types.
-JSC::JSValue toJS(JSC::ExecState&, JSDOMGlobalObject&, const std::optional<IDBKeyPath>&);
 
 RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(JSC::ExecState&, const JSC::JSValue&, const IDBKeyPath&);
 bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&, const JSC::JSValue&, const IDBKeyPath&);
index 4b1e971..a71b71a 100644 (file)
@@ -26,8 +26,9 @@
 #include "config.h"
 #include "JSCrypto.h"
 
-#include "JSDOMBinding.h"
+#include "JSDOMConvertBufferSource.h"
 #include "JSDOMExceptionHandling.h"
+#include <heap/HeapInlines.h>
 #include <runtime/ArrayBufferView.h>
 #include <runtime/Error.h>
 #include <runtime/JSArrayBufferView.h>
index be33eab..2e35f2e 100644 (file)
@@ -28,7 +28,8 @@
 
 #if ENABLE(SUBTLE_CRYPTO)
 
-#include "JSDOMBinding.h"
+#include "JSDOMConvertBufferSource.h"
+#include <heap/HeapInlines.h>
 
 using namespace JSC;
 
index 35ad9d0..aef621d 100644 (file)
 #include "config.h"
 #include "JSDOMBinding.h"
 
-#include "CachedScript.h"
 #include "CommonVM.h"
-#include "Frame.h"
-#include "HTMLParserIdioms.h"
-#include "JSDOMConvert.h"
-#include <runtime/DateInstance.h>
-#include <stdarg.h>
-#include <wtf/MathExtras.h>
-#include <wtf/text/StringBuilder.h>
-#include <wtf/unicode/CharacterNames.h>
 
 using namespace JSC;
 
@@ -56,99 +47,6 @@ JSValue jsStringOrUndefined(ExecState* exec, const String& s)
     return jsStringWithCache(exec, s);
 }
 
-static inline String stringToByteString(ExecState& state, JSC::ThrowScope& scope, String&& string)
-{
-    if (!string.containsOnlyLatin1()) {
-        throwTypeError(&state, scope);
-        return { };
-    }
-
-    return string;
-}
-
-String identifierToByteString(ExecState& state, const Identifier& identifier)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    String string = identifier.string();
-    return stringToByteString(state, scope, WTFMove(string));
-}
-
-String valueToByteString(ExecState& state, JSValue value)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    String string = value.toWTFString(&state);
-    RETURN_IF_EXCEPTION(scope, { });
-
-    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&& string)
-{
-    // Fast path for the case where there are no unpaired surrogates.
-    if (!hasUnpairedSurrogate(string))
-        return string;
-
-    // Slow path: http://heycam.github.io/webidl/#dfn-obtain-unicode
-    // Replaces unpaired surrogates with the replacement character.
-    StringBuilder result;
-    result.reserveCapacity(string.length());
-    StringView view { string };
-    for (auto codePoint : view.codePoints()) {
-        if (U_IS_SURROGATE(codePoint))
-            result.append(replacementCharacter);
-        else
-            result.append(codePoint);
-    }
-    return result.toString();
-}
-
-String identifierToUSVString(ExecState&, const Identifier& identifier)
-{
-    String string = identifier.string();
-    return stringToUSVString(WTFMove(string));
-}
-
-String valueToUSVString(ExecState& state, JSValue value)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    String string = value.toWTFString(&state);
-    RETURN_IF_EXCEPTION(scope, { });
-
-    return stringToUSVString(WTFMove(string));
-}
-
-JSValue jsDate(ExecState* exec, double value)
-{
-    return DateInstance::create(exec->vm(), exec->lexicalGlobalObject()->dateStructure(), value);
-}
-
-double valueToDate(ExecState* exec, JSValue value)
-{
-    if (value.isNumber())
-        return value.asNumber();
-    if (!value.inherits(exec->vm(), DateInstance::info()))
-        return std::numeric_limits<double>::quiet_NaN();
-    return static_cast<DateInstance*>(value.toObject(exec))->internalNumber();
-}
-
 bool hasIteratorMethod(JSC::ExecState& state, JSC::JSValue value)
 {
     auto& vm = state.vm();
@@ -166,317 +64,4 @@ bool hasIteratorMethod(JSC::ExecState& state, JSC::JSValue value)
     return !applyMethod.isUndefined();
 }
 
-static const int32_t kMaxInt32 = 0x7fffffff;
-static const int32_t kMinInt32 = -kMaxInt32 - 1;
-static const uint32_t kMaxUInt32 = 0xffffffffU;
-static const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, largest integer exactly representable in ECMAScript.
-
-static String rangeErrorString(double value, double min, double max)
-{
-    return makeString("Value ", String::numberToStringECMAScript(value), " is outside the range [", String::numberToStringECMAScript(min), ", ", String::numberToStringECMAScript(max), "]");
-}
-
-static double enforceRange(ExecState& state, double x, double minimum, double maximum)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (std::isnan(x) || std::isinf(x)) {
-        throwTypeError(&state, scope, rangeErrorString(x, minimum, maximum));
-        return 0;
-    }
-    x = trunc(x);
-    if (x < minimum || x > maximum) {
-        throwTypeError(&state, scope, rangeErrorString(x, minimum, maximum));
-        return 0;
-    }
-    return x;
-}
-
-template <typename T>
-struct IntTypeLimits {
-};
-
-template <>
-struct IntTypeLimits<int8_t> {
-    static const int8_t minValue = -128;
-    static const int8_t maxValue = 127;
-    static const unsigned numberOfValues = 256; // 2^8
-};
-
-template <>
-struct IntTypeLimits<uint8_t> {
-    static const uint8_t maxValue = 255;
-    static const unsigned numberOfValues = 256; // 2^8
-};
-
-template <>
-struct IntTypeLimits<int16_t> {
-    static const short minValue = -32768;
-    static const short maxValue = 32767;
-    static const unsigned numberOfValues = 65536; // 2^16
-};
-
-template <>
-struct IntTypeLimits<uint16_t> {
-    static const unsigned short maxValue = 65535;
-    static const unsigned numberOfValues = 65536; // 2^16
-};
-
-template <typename T>
-static inline T toSmallerInt(ExecState& state, JSValue value, IntegerConversionConfiguration configuration)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    static_assert(std::is_signed<T>::value && std::is_integral<T>::value, "Should only be used for signed integral types");
-
-    typedef IntTypeLimits<T> LimitsTrait;
-    // Fast path if the value is already a 32-bit signed integer in the right range.
-    if (value.isInt32()) {
-        int32_t d = value.asInt32();
-        if (d >= LimitsTrait::minValue && d <= LimitsTrait::maxValue)
-            return static_cast<T>(d);
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            throwTypeError(&state, scope);
-            return 0;
-        case IntegerConversionConfiguration::Clamp:
-            return d < LimitsTrait::minValue ? LimitsTrait::minValue : LimitsTrait::maxValue;
-        }
-        d %= LimitsTrait::numberOfValues;
-        return static_cast<T>(d > LimitsTrait::maxValue ? d - LimitsTrait::numberOfValues : d);
-    }
-
-    double x = value.toNumber(&state);
-    RETURN_IF_EXCEPTION(scope, 0);
-
-    switch (configuration) {
-    case IntegerConversionConfiguration::Normal:
-        break;
-    case IntegerConversionConfiguration::EnforceRange:
-        return enforceRange(state, x, LimitsTrait::minValue, LimitsTrait::maxValue);
-    case IntegerConversionConfiguration::Clamp:
-        return std::isnan(x) ? 0 : clampTo<T>(x);
-    }
-
-    if (std::isnan(x) || std::isinf(x) || !x)
-        return 0;
-
-    x = x < 0 ? -floor(fabs(x)) : floor(fabs(x));
-    x = fmod(x, LimitsTrait::numberOfValues);
-
-    return static_cast<T>(x > LimitsTrait::maxValue ? x - LimitsTrait::numberOfValues : x);
-}
-
-template <typename T>
-static inline T toSmallerUInt(ExecState& state, JSValue value, IntegerConversionConfiguration configuration)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    static_assert(std::is_unsigned<T>::value && std::is_integral<T>::value, "Should only be used for unsigned integral types");
-
-    typedef IntTypeLimits<T> LimitsTrait;
-    // Fast path if the value is already a 32-bit unsigned integer in the right range.
-    if (value.isUInt32()) {
-        uint32_t d = value.asUInt32();
-        if (d <= LimitsTrait::maxValue)
-            return static_cast<T>(d);
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            return static_cast<T>(d);
-        case IntegerConversionConfiguration::EnforceRange:
-            throwTypeError(&state, scope);
-            return 0;
-        case IntegerConversionConfiguration::Clamp:
-            return LimitsTrait::maxValue;
-        }
-    }
-
-    double x = value.toNumber(&state);
-    RETURN_IF_EXCEPTION(scope, 0);
-
-    switch (configuration) {
-    case IntegerConversionConfiguration::Normal:
-        break;
-    case IntegerConversionConfiguration::EnforceRange:
-        return enforceRange(state, x, 0, LimitsTrait::maxValue);
-    case IntegerConversionConfiguration::Clamp:
-        return std::isnan(x) ? 0 : clampTo<T>(x);
-    }
-
-    if (std::isnan(x) || std::isinf(x) || !x)
-        return 0;
-
-    x = x < 0 ? -floor(fabs(x)) : floor(fabs(x));
-    return static_cast<T>(fmod(x, LimitsTrait::numberOfValues));
-}
-
-int8_t toInt8EnforceRange(JSC::ExecState& state, JSValue value)
-{
-    return toSmallerInt<int8_t>(state, value, IntegerConversionConfiguration::EnforceRange);
-}
-
-uint8_t toUInt8EnforceRange(JSC::ExecState& state, JSValue value)
-{
-    return toSmallerUInt<uint8_t>(state, value, IntegerConversionConfiguration::EnforceRange);
-}
-
-int8_t toInt8Clamp(JSC::ExecState& state, JSValue value)
-{
-    return toSmallerInt<int8_t>(state, value, IntegerConversionConfiguration::Clamp);
-}
-
-uint8_t toUInt8Clamp(JSC::ExecState& state, JSValue value)
-{
-    return toSmallerUInt<uint8_t>(state, value, IntegerConversionConfiguration::Clamp);
-}
-
-// http://www.w3.org/TR/WebIDL/#es-byte
-int8_t toInt8(ExecState& state, JSValue value)
-{
-    return toSmallerInt<int8_t>(state, value, IntegerConversionConfiguration::Normal);
-}
-
-// http://www.w3.org/TR/WebIDL/#es-octet
-uint8_t toUInt8(ExecState& state, JSValue value)
-{
-    return toSmallerUInt<uint8_t>(state, value, IntegerConversionConfiguration::Normal);
-}
-
-int16_t toInt16EnforceRange(ExecState& state, JSValue value)
-{
-    return toSmallerInt<int16_t>(state, value, IntegerConversionConfiguration::EnforceRange);
-}
-
-uint16_t toUInt16EnforceRange(ExecState& state, JSValue value)
-{
-    return toSmallerUInt<uint16_t>(state, value, IntegerConversionConfiguration::EnforceRange);
-}
-
-int16_t toInt16Clamp(ExecState& state, JSValue value)
-{
-    return toSmallerInt<int16_t>(state, value, IntegerConversionConfiguration::Clamp);
-}
-
-uint16_t toUInt16Clamp(ExecState& state, JSValue value)
-{
-    return toSmallerUInt<uint16_t>(state, value, IntegerConversionConfiguration::Clamp);
-}
-
-// http://www.w3.org/TR/WebIDL/#es-short
-int16_t toInt16(ExecState& state, JSValue value)
-{
-    return toSmallerInt<int16_t>(state, value, IntegerConversionConfiguration::Normal);
-}
-
-// http://www.w3.org/TR/WebIDL/#es-unsigned-short
-uint16_t toUInt16(ExecState& state, JSValue value)
-{
-    return toSmallerUInt<uint16_t>(state, value, IntegerConversionConfiguration::Normal);
-}
-
-// http://www.w3.org/TR/WebIDL/#es-long
-int32_t toInt32EnforceRange(ExecState& state, JSValue value)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (value.isInt32())
-        return value.asInt32();
-
-    double x = value.toNumber(&state);
-    RETURN_IF_EXCEPTION(scope, 0);
-    return enforceRange(state, x, kMinInt32, kMaxInt32);
-}
-
-int32_t toInt32Clamp(ExecState& state, JSValue value)
-{
-    if (value.isInt32())
-        return value.asInt32();
-
-    double x = value.toNumber(&state);
-    return std::isnan(x) ? 0 : clampTo<int32_t>(x);
-}
-
-uint32_t toUInt32Clamp(ExecState& state, JSValue value)
-{
-    if (value.isUInt32())
-        return value.asUInt32();
-
-    double x = value.toNumber(&state);
-    return std::isnan(x) ? 0 : clampTo<uint32_t>(x);
-}
-
-// http://www.w3.org/TR/WebIDL/#es-unsigned-long
-uint32_t toUInt32EnforceRange(ExecState& state, JSValue value)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (value.isUInt32())
-        return value.asUInt32();
-
-    double x = value.toNumber(&state);
-    RETURN_IF_EXCEPTION(scope, 0);
-    return enforceRange(state, x, 0, kMaxUInt32);
-}
-
-int64_t toInt64EnforceRange(ExecState& state, JSC::JSValue value)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    double x = value.toNumber(&state);
-    RETURN_IF_EXCEPTION(scope, 0);
-    return enforceRange(state, x, -kJSMaxInteger, kJSMaxInteger);
-}
-
-uint64_t toUInt64EnforceRange(ExecState& state, JSC::JSValue value)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    double x = value.toNumber(&state);
-    RETURN_IF_EXCEPTION(scope, 0);
-    return enforceRange(state, x, 0, kJSMaxInteger);
-}
-
-int64_t toInt64Clamp(ExecState& state, JSC::JSValue value)
-{
-    double x = value.toNumber(&state);
-    return std::isnan(x) ? 0 : static_cast<int64_t>(std::min<double>(std::max<double>(x, -kJSMaxInteger), kJSMaxInteger));
-}
-
-uint64_t toUInt64Clamp(ExecState& state, JSC::JSValue value)
-{
-    double x = value.toNumber(&state);
-    return std::isnan(x) ? 0 : static_cast<uint64_t>(std::min<double>(std::max<double>(x, 0), kJSMaxInteger));
-}
-
-// http://www.w3.org/TR/WebIDL/#es-long-long
-int64_t toInt64(ExecState& state, JSValue value)
-{
-    double x = value.toNumber(&state);
-
-    // Map NaNs and +/-Infinity to 0; convert finite values modulo 2^64.
-    unsigned long long n;
-    doubleToInteger(x, n);
-    return n;
-}
-
-// http://www.w3.org/TR/WebIDL/#es-unsigned-long-long
-uint64_t toUInt64(ExecState& state, JSValue value)
-{
-    double x = value.toNumber(&state);
-
-    // Map NaNs and +/-Infinity to 0; convert finite values modulo 2^64.
-    unsigned long long n;
-    doubleToInteger(x, n);
-    return n;
-}
-
 } // namespace WebCore
index 3d4a9cc..e2dda2e 100644 (file)
 #include <heap/HeapInlines.h>
 #include <heap/SlotVisitorInlines.h>
 #include <runtime/AuxiliaryBarrierInlines.h>
-#include <runtime/IteratorOperations.h>
 #include <runtime/JSArray.h>
 #include <runtime/JSCJSValueInlines.h>
 #include <runtime/JSCellInlines.h>
 #include <runtime/JSObjectInlines.h>
-#include <runtime/JSTypedArrays.h>
 #include <runtime/Lookup.h>
 #include <runtime/ObjectConstructor.h>
 #include <runtime/StructureInlines.h>
 #include <runtime/WriteBarrier.h>
 #include <wtf/Forward.h>
 #include <wtf/GetPtr.h>
-#include <wtf/Noncopyable.h>
 #include <wtf/Vector.h>
 
-// FIXME: We could make this file a lot easier to read by putting all function declarations at the top,
-// and function definitions below, even for template and inline functions.
-
 namespace JSC {
 class JSFunction;
 }
@@ -61,121 +55,22 @@ JSC::JSValue jsStringOrUndefined(JSC::ExecState*, const String&); // undefined i
 // object, to let the engine know that collecting the JSString wrapper is unlikely to save memory.
 JSC::JSValue jsOwnedStringOrNull(JSC::ExecState*, const String&);
 
-String propertyNameToString(JSC::PropertyName);
-AtomicString propertyNameToAtomicString(JSC::PropertyName);
-
-WEBCORE_EXPORT String identifierToByteString(JSC::ExecState&, const JSC::Identifier&);
-WEBCORE_EXPORT String valueToByteString(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT String identifierToUSVString(JSC::ExecState&, const JSC::Identifier&);
-WEBCORE_EXPORT String valueToUSVString(JSC::ExecState&, JSC::JSValue);
-
-// The following functions convert values to integers as per the WebIDL specification.
-// The conversion fails if the value cannot be converted to a number or, if EnforceRange is specified,
-// the value is outside the range of the destination integer type.
-
-WEBCORE_EXPORT int8_t toInt8EnforceRange(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint8_t toUInt8EnforceRange(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT int16_t toInt16EnforceRange(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint16_t toUInt16EnforceRange(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT int32_t toInt32EnforceRange(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint32_t toUInt32EnforceRange(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT int64_t toInt64EnforceRange(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint64_t toUInt64EnforceRange(JSC::ExecState&, JSC::JSValue);
-
-WEBCORE_EXPORT int8_t toInt8Clamp(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint8_t toUInt8Clamp(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT int16_t toInt16Clamp(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint16_t toUInt16Clamp(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT int32_t toInt32Clamp(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint32_t toUInt32Clamp(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT int64_t toInt64Clamp(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint64_t toUInt64Clamp(JSC::ExecState&, JSC::JSValue);
-
-WEBCORE_EXPORT int8_t toInt8(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint8_t toUInt8(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT int16_t toInt16(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint16_t toUInt16(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT int64_t toInt64(JSC::ExecState&, JSC::JSValue);
-WEBCORE_EXPORT uint64_t toUInt64(JSC::ExecState&, JSC::JSValue);
-
-JSC::JSValue jsDate(JSC::ExecState*, double value);
-
-// NaN if the value can't be converted to a date.
-double valueToDate(JSC::ExecState*, JSC::JSValue);
-
-JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, JSC::ArrayBuffer&);
-JSC::JSValue toJS(JSC::ExecState*, JSC::JSGlobalObject*, JSC::ArrayBufferView&);
-JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, JSC::ArrayBuffer*);
-JSC::JSValue toJS(JSC::ExecState*, JSC::JSGlobalObject*, JSC::ArrayBufferView*);
-
-RefPtr<JSC::ArrayBufferView> toPossiblySharedArrayBufferView(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Int8Array> toPossiblySharedInt8Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Int16Array> toPossiblySharedInt16Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Int32Array> toPossiblySharedInt32Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Uint8Array> toPossiblySharedUint8Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Uint8ClampedArray> toPossiblySharedUint8ClampedArray(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Uint16Array> toPossiblySharedUint16Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Uint32Array> toPossiblySharedUint32Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Float32Array> toPossiblySharedFloat32Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Float64Array> toPossiblySharedFloat64Array(JSC::VM&, JSC::JSValue);
-
-RefPtr<JSC::ArrayBufferView> toUnsharedArrayBufferView(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Int8Array> toUnsharedInt8Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Int16Array> toUnsharedInt16Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Int32Array> toUnsharedInt32Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Uint8Array> toUnsharedUint8Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Uint8ClampedArray> toUnsharedUint8ClampedArray(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Uint16Array> toUnsharedUint16Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Uint32Array> toUnsharedUint32Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Float32Array> toUnsharedFloat32Array(JSC::VM&, JSC::JSValue);
-RefPtr<JSC::Float64Array> toUnsharedFloat64Array(JSC::VM&, JSC::JSValue);
-
-String propertyNameToString(JSC::PropertyName);
-AtomicString propertyNameToAtomicString(JSC::PropertyName);
-
 WEBCORE_EXPORT bool hasIteratorMethod(JSC::ExecState&, JSC::JSValue);
 
-template<JSC::NativeFunction, int length> JSC::EncodedJSValue nonCachingStaticFunctionGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
-
-
-// Inline functions and template definitions.
-
-inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, JSC::ArrayBuffer& buffer)
-{
-    if (auto result = getCachedWrapper(globalObject->world(), buffer))
-        return result;
-
-    // The JSArrayBuffer::create function will register the wrapper in finishCreation.
-    return JSC::JSArrayBuffer::create(state->vm(), globalObject->arrayBufferStructure(buffer.sharingMode()), &buffer);
-}
-
-inline JSC::JSValue toJS(JSC::ExecState* state, JSC::JSGlobalObject* globalObject, JSC::ArrayBufferView& view)
-{
-    return view.wrap(state, globalObject);
-}
-
-inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, JSC::ArrayBuffer* buffer)
-{
-    if (!buffer)
-        return JSC::jsNull();
-    return toJS(state, globalObject, *buffer);
-}
-
-inline JSC::JSValue toJS(JSC::ExecState* state, JSC::JSGlobalObject* globalObject, JSC::ArrayBufferView* view)
+inline String propertyNameToString(JSC::PropertyName propertyName)
 {
-    if (!view)
-        return JSC::jsNull();
-    return toJS(state, globalObject, *view);
+    ASSERT(!propertyName.isSymbol());
+    return propertyName.uid() ? propertyName.uid() : propertyName.publicName();
 }
 
-template<typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, Ref<T>&& ptr)
+inline AtomicString propertyNameToAtomicString(JSC::PropertyName propertyName)
 {
-    return toJS(exec, globalObject, ptr.get());
+    return AtomicString(propertyName.uid() ? propertyName.uid() : propertyName.publicName());
 }
 
-template<typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, RefPtr<T>&& ptr)
+template<JSC::NativeFunction nativeFunction, int length> JSC::EncodedJSValue nonCachingStaticFunctionGetter(JSC::ExecState* exec, JSC::EncodedJSValue, JSC::PropertyName propertyName)
 {
-    return toJS(exec, globalObject, ptr.get());
+    return JSC::JSValue::encode(JSC::JSFunction::create(exec->vm(), exec->lexicalGlobalObject(), length, propertyName.publicName(), nativeFunction));
 }
 
 template<typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<T>& vector)
@@ -192,75 +87,4 @@ template<typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalO
     return array;
 }
 
-template<typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<RefPtr<T>>& vector)
-{
-    JSC::VM& vm = globalObject->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    JSC::JSArray* array = constructEmptyArray(exec, nullptr, vector.size());
-    RETURN_IF_EXCEPTION(scope, JSC::JSValue());
-    for (size_t i = 0; i < vector.size(); ++i) {
-        array->putDirectIndex(exec, i, toJS(exec, globalObject, vector[i].get()));
-        RETURN_IF_EXCEPTION(scope, JSC::JSValue());
-    }
-    return array;
-}
-
-inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject*, const JSC::PrivateName& privateName)
-{
-    return JSC::Symbol::create(exec->vm(), privateName.uid());
-}
-
-inline RefPtr<JSC::ArrayBufferView> toPossiblySharedArrayBufferView(JSC::VM& vm, JSC::JSValue value)
-{
-    auto* wrapper = jsDynamicDowncast<JSC::JSArrayBufferView*>(vm, value);
-    if (!wrapper)
-        return nullptr;
-    return wrapper->possiblySharedImpl();
-}
-
-inline RefPtr<JSC::ArrayBufferView> toUnsharedArrayBufferView(JSC::VM& vm, JSC::JSValue value)
-{
-    auto result = toPossiblySharedArrayBufferView(vm, value);
-    if (!result || result->isShared())
-        return nullptr;
-    return result;
-}
-
-inline RefPtr<JSC::Int8Array> toPossiblySharedInt8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int8Adaptor>(vm, value); }
-inline RefPtr<JSC::Int16Array> toPossiblySharedInt16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int16Adaptor>(vm, value); }
-inline RefPtr<JSC::Int32Array> toPossiblySharedInt32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int32Adaptor>(vm, value); }
-inline RefPtr<JSC::Uint8Array> toPossiblySharedUint8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint8Adaptor>(vm, value); }
-inline RefPtr<JSC::Uint8ClampedArray> toPossiblySharedUint8ClampedArray(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint8ClampedAdaptor>(vm, value); }
-inline RefPtr<JSC::Uint16Array> toPossiblySharedUint16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint16Adaptor>(vm, value); }
-inline RefPtr<JSC::Uint32Array> toPossiblySharedUint32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint32Adaptor>(vm, value); }
-inline RefPtr<JSC::Float32Array> toPossiblySharedFloat32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Float32Adaptor>(vm, value); }
-inline RefPtr<JSC::Float64Array> toPossiblySharedFloat64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Float64Adaptor>(vm, value); }
-
-inline RefPtr<JSC::Int8Array> toUnsharedInt8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int8Adaptor>(vm, value); }
-inline RefPtr<JSC::Int16Array> toUnsharedInt16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int16Adaptor>(vm, value); }
-inline RefPtr<JSC::Int32Array> toUnsharedInt32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int32Adaptor>(vm, value); }
-inline RefPtr<JSC::Uint8Array> toUnsharedUint8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint8Adaptor>(vm, value); }
-inline RefPtr<JSC::Uint8ClampedArray> toUnsharedUint8ClampedArray(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint8ClampedAdaptor>(vm, value); }
-inline RefPtr<JSC::Uint16Array> toUnsharedUint16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint16Adaptor>(vm, value); }
-inline RefPtr<JSC::Uint32Array> toUnsharedUint32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint32Adaptor>(vm, value); }
-inline RefPtr<JSC::Float32Array> toUnsharedFloat32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Float32Adaptor>(vm, value); }
-inline RefPtr<JSC::Float64Array> toUnsharedFloat64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Float64Adaptor>(vm, value); }
-
-inline String propertyNameToString(JSC::PropertyName propertyName)
-{
-    ASSERT(!propertyName.isSymbol());
-    return propertyName.uid() ? propertyName.uid() : propertyName.publicName();
-}
-
-inline AtomicString propertyNameToAtomicString(JSC::PropertyName propertyName)
-{
-    return AtomicString(propertyName.uid() ? propertyName.uid() : propertyName.publicName());
-}
-
-template<JSC::NativeFunction nativeFunction, int length> JSC::EncodedJSValue nonCachingStaticFunctionGetter(JSC::ExecState* exec, JSC::EncodedJSValue, JSC::PropertyName propertyName)
-{
-    return JSC::JSValue::encode(JSC::JSFunction::create(exec->vm(), exec->lexicalGlobalObject(), length, propertyName.publicName(), nativeFunction));
-}
-
 } // namespace WebCore
index 7dafbff..44afd4d 100644 (file)
 
 #pragma once
 
-#include "BufferSource.h"
-#include "IDBBindingUtilities.h"
-#include "IDLTypes.h"
-#include "JSDOMBinding.h"
-#include "JSDOMExceptionHandling.h"
-#include <runtime/JSGlobalObjectInlines.h>
-#include <runtime/JSONObject.h>
-
-namespace WebCore {
-
-// Conversion from JSValue -> Implementation
-template<typename T> struct Converter;
-
-enum class IntegerConversionConfiguration { Normal, EnforceRange, Clamp };
-enum class StringConversionConfiguration { Normal, TreatNullAsEmptyString };
-
-struct DefaultExceptionThrower {
-    void operator()(JSC::ExecState& state, JSC::ThrowScope& scope)
-    {
-        throwTypeError(&state, scope);
-    }
-};
-
-template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue);
-template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, JSC::JSObject&);
-template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, JSDOMGlobalObject&);
-template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, IntegerConversionConfiguration);
-template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, StringConversionConfiguration);
-template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, ExceptionThrower&&);
-template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, JSC::JSObject&, ExceptionThrower&&);
-template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, JSDOMGlobalObject&, ExceptionThrower&&);
-
-// Specialized by generated code for IDL dictionary conversion.
-template<typename T> T convertDictionary(JSC::ExecState&, JSC::JSValue);
-
-// Specialized by generated code for IDL enumeration conversion.
-template<typename T> std::optional<T> parseEnumeration(JSC::ExecState&, JSC::JSValue);
-template<typename T> T convertEnumeration(JSC::ExecState&, JSC::JSValue);
-template<typename T> const char* expectedEnumerationValues();
-
-template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-{
-    return Converter<T>::convert(state, value);
-}
-
-template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject)
-{
-    return Converter<T>::convert(state, value, thisObject);
-}
-
-template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject)
-{
-    return Converter<T>::convert(state, value, globalObject);
-}
-
-template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration)
-{
-    return Converter<T>::convert(state, value, configuration);
-}
-
-template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration)
-{
-    return Converter<T>::convert(state, value, configuration);
-}
-
-template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower)
-{
-    return Converter<T>::convert(state, value, std::forward<ExceptionThrower>(exceptionThrower));
-}
-
-template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject, ExceptionThrower&& exceptionThrower)
-{
-    return Converter<T>::convert(state, value, thisObject, std::forward<ExceptionThrower>(exceptionThrower));
-}
-
-template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower)
-{
-    return Converter<T>::convert(state, value, globalObject, std::forward<ExceptionThrower>(exceptionThrower));
-}
-
-// Conversion from Implementation -> JSValue
-template<typename T> struct JSConverter;
-
-template<typename T, typename U> inline JSC::JSValue toJS(U&&);
-template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState&, U&&);
-template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState&, JSDOMGlobalObject&, U&&);
-template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<U>&&);
-template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<U>&&);
-template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState&, JSDOMGlobalObject&, U&&);
-template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<U>&&);
-
-// Specialized by generated code for IDL enumeration conversion.
-template<typename T> JSC::JSString* convertEnumerationToJS(JSC::ExecState&, T);
-
-
-template<typename T, bool needsState = JSConverter<T>::needsState, bool needsGlobalObject = JSConverter<T>::needsGlobalObject>
-struct JSConverterOverloader;
-
-template<typename T>
-struct JSConverterOverloader<T, true, true> {
-    template<typename U> static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
-    {
-        return JSConverter<T>::convert(state, globalObject, std::forward<U>(value));
-    }
-};
-
-template<typename T>
-struct JSConverterOverloader<T, true, false> {
-    template<typename U> static JSC::JSValue convert(JSC::ExecState& state, U&& value)
-    {
-        return JSConverter<T>::convert(state, std::forward<U>(value));
-    }
-
-    template<typename U> static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject&, U&& value)
-    {
-        return JSConverter<T>::convert(state, std::forward<U>(value));
-    }
-};
-
-template<typename T>
-struct JSConverterOverloader<T, false, false> {
-    template<typename U> static JSC::JSValue convert(JSC::ExecState&, U&& value)
-    {
-        return JSConverter<T>::convert(std::forward<U>(value));
-    }
-
-    template<typename U> static JSC::JSValue convert(JSC::ExecState&, JSDOMGlobalObject&, U&& value)
-    {
-        return JSConverter<T>::convert(std::forward<U>(value));
-    }
-};
-
-template<typename T, typename U> inline JSC::JSValue toJS(U&& value)
-{
-    return JSConverter<T>::convert(std::forward<U>(value));
-}
-
-template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState& state, U&& value)
-{
-    return JSConverterOverloader<T>::convert(state, std::forward<U>(value));
-}
-
-template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
-{
-    return JSConverterOverloader<T>::convert(state, globalObject, std::forward<U>(value));
-}
-
-template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState& state, JSC::ThrowScope& throwScope, ExceptionOr<U>&& value)
-{
-    if (UNLIKELY(value.hasException())) {
-        propagateException(state, throwScope, value.releaseException());
-        return { };
-    }
-
-    return toJS<T>(state, value.releaseReturnValue());
-}
-
-template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, JSC::ThrowScope& throwScope, ExceptionOr<U>&& value)
-{
-    if (UNLIKELY(value.hasException())) {
-        propagateException(state, throwScope, value.releaseException());
-        return { };
-    }
-
-    return toJS<T>(state, globalObject, value.releaseReturnValue());
-}
-
-template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
-{
-    return JSConverter<T>::convertNewlyCreated(state, globalObject, std::forward<U>(value));
-}
-
-template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, JSC::ThrowScope& throwScope, ExceptionOr<U>&& value)
-{
-    if (UNLIKELY(value.hasException())) {
-        propagateException(state, throwScope, value.releaseException());
-        return { };
-    }
-
-    return toJSNewlyCreated<T>(state, globalObject, value.releaseReturnValue());
-}
-
-
-template<typename T> struct DefaultConverter {
-    using ReturnType = typename T::ImplementationType;
-};
-
-// MARK: -
-// MARK: Any type
-
-template<> struct Converter<IDLAny> : DefaultConverter<IDLAny> {
-    using ReturnType = JSC::JSValue;
-    
-    static JSC::JSValue convert(JSC::ExecState&, JSC::JSValue value)
-    {
-        return value;
-    }
-
-    static JSC::JSValue convert(const JSC::Strong<JSC::Unknown>& value)
-    {
-        return value.get();
-    }
-};
-
-template<> struct JSConverter<IDLAny> {
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(const JSC::JSValue& value)
-    {
-        return value;
-    }
-
-    static JSC::JSValue convert(const JSC::Strong<JSC::Unknown>& value)
-    {
-        return value.get();
-    }
-};
-
-// MARK: -
-// MARK: Nullable type
-
-namespace Detail {
-    template<typename IDLType>
-    struct NullableConversionType;
-
-    template<typename IDLType> 
-    struct NullableConversionType {
-        using Type = typename IDLNullable<IDLType>::ImplementationType;
-    };
-
-    template<typename T>
-    struct NullableConversionType<IDLInterface<T>> {
-        using Type = typename Converter<IDLInterface<T>>::ReturnType;
-    };
-
-    template<>
-    struct NullableConversionType<IDLAny> {
-        using Type = typename Converter<IDLAny>::ReturnType;
-    };
-}
-
-template<typename T> struct Converter<IDLNullable<T>> : DefaultConverter<IDLNullable<T>> {
-    using ReturnType = typename Detail::NullableConversionType<T>::Type;
-    
-    // 1. If Type(V) is not Object, and the conversion to an IDL value is being performed
-    // due to V being assigned to an attribute whose type is a nullable callback function
-    // that is annotated with [TreatNonObjectAsNull], then return the IDL nullable type T?
-    // value null.
-    //
-    // NOTE: Handled elsewhere.
-    //
-    // 2. Otherwise, if V is null or undefined, then return the IDL nullable type T? value null.
-    // 3. Otherwise, return the result of converting V using the rules for the inner IDL type T.
-
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        if (value.isUndefinedOrNull())
-            return T::nullValue();
-        return Converter<T>::convert(state, value);
-    }
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject)
-    {
-        if (value.isUndefinedOrNull())
-            return T::nullValue();
-        return Converter<T>::convert(state, value, thisObject);
-    }
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject)
-    {
-        if (value.isUndefinedOrNull())
-            return T::nullValue();
-        return Converter<T>::convert(state, value, globalObject);
-    }
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration)
-    {
-        if (value.isUndefinedOrNull())
-            return T::nullValue();
-        return Converter<T>::convert(state, value, configuration);
-    }
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration)
-    {
-        if (value.isUndefinedOrNull())
-            return T::nullValue();
-        return Converter<T>::convert(state, value, configuration);
-    }
-    template<typename ExceptionThrower = DefaultExceptionThrower>
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower)
-    {
-        if (value.isUndefinedOrNull())
-            return T::nullValue();
-        return Converter<T>::convert(state, value, std::forward<ExceptionThrower>(exceptionThrower));
-    }
-    template<typename ExceptionThrower = DefaultExceptionThrower>
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject, ExceptionThrower&& exceptionThrower)
-    {
-        if (value.isUndefinedOrNull())
-            return T::nullValue();
-        return Converter<T>::convert(state, value, thisObject, std::forward<ExceptionThrower>(exceptionThrower));
-    }
-    template<typename ExceptionThrower = DefaultExceptionThrower>
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower)
-    {
-        if (value.isUndefinedOrNull())
-            return T::nullValue();
-        return Converter<T>::convert(state, value, globalObject, std::forward<ExceptionThrower>(exceptionThrower));
-    }
-};
-
-template<typename T> struct JSConverter<IDLNullable<T>> {
-    using ImplementationType = typename IDLNullable<T>::ImplementationType;
-
-    static constexpr bool needsState = JSConverter<T>::needsState;
-    static constexpr bool needsGlobalObject = JSConverter<T>::needsGlobalObject;
-
-    template<typename U>
-    static JSC::JSValue convert(U&& value)
-    {
-        if (T::isNullValue(value))
-            return JSC::jsNull();
-        return JSConverter<T>::convert(T::extractValueFromNullable(value));
-    }
-    template<typename U>
-    static JSC::JSValue convert(JSC::ExecState& state, U&& value)
-    {
-        if (T::isNullValue(value))
-            return JSC::jsNull();
-        return JSConverter<T>::convert(state, T::extractValueFromNullable(value));
-    }
-    template<typename U>
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
-    {
-        if (T::isNullValue(value))
-            return JSC::jsNull();
-        return JSConverter<T>::convert(state, globalObject, T::extractValueFromNullable(value));
-    }
-
-    template<typename U>
-    static JSC::JSValue convertNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
-    {
-        if (T::isNullValue(value))
-            return JSC::jsNull();
-        return JSConverter<T>::convert(state, globalObject, T::extractValueFromNullable(value));
-    }
-};
-
-// MARK: -
-// MARK: Null type
-
-template<> struct Converter<IDLNull> : DefaultConverter<IDLNull> {
-    static std::nullptr_t convert(JSC::ExecState&, JSC::JSValue)
-    {
-        return nullptr;
-    }
-};
-
-template<> struct JSConverter<IDLNull> {
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(std::nullptr_t)
-    {
-        return JSC::jsNull();
-    }
-};
-
-// MARK: -
-// MARK: Boolean type
-
-template<> struct Converter<IDLBoolean> : DefaultConverter<IDLBoolean> {
-    static bool convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return value.toBoolean(&state);
-    }
-};
-
-template<> struct JSConverter<IDLBoolean> {
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(bool value)
-    {
-        return JSC::jsBoolean(value);
-    }
-};
-
-// ArrayBuffer support.
-template<> struct JSDOMWrapperConverterTraits<JSC::ArrayBuffer> {
-    using WrapperClass = JSC::JSArrayBuffer;
-    using ToWrappedReturnType = JSC::ArrayBuffer*;
-};
-
-// ArrayBufferView support.
-template<> struct JSDOMWrapperConverterTraits<JSC::ArrayBufferView> {
-    using WrapperClass = JSC::JSArrayBufferView;
-    using ToWrappedReturnType = RefPtr<ArrayBufferView>;
-};
-
-// Typed arrays support.
-template<typename Adaptor> struct JSDOMWrapperConverterTraits<JSC::GenericTypedArrayView<Adaptor>> {
-    using WrapperClass = JSC::JSGenericTypedArrayView<Adaptor>;
-    using ToWrappedReturnType = RefPtr<JSC::GenericTypedArrayView<Adaptor>>;
-};
-
-// MARK: -
-// MARK: Interface type
-
-template<typename T> struct Converter<IDLInterface<T>> : DefaultConverter<IDLInterface<T>> {
-    using ReturnType = typename JSDOMWrapperConverterTraits<T>::ToWrappedReturnType;
-    using WrapperType = typename JSDOMWrapperConverterTraits<T>::WrapperClass;
-
-    template<typename ExceptionThrower = DefaultExceptionThrower>
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        ReturnType object = WrapperType::toWrapped(vm, value);
-        if (UNLIKELY(!object))
-            exceptionThrower(state, scope);
-        return object;
-    }
-};
-
-namespace Detail {
-
-template <typename T> inline T* getPtrOrRef(const T* p) { return const_cast<T*>(p); }
-template <typename T> inline T& getPtrOrRef(const T& p) { return const_cast<T&>(p); }
-template <typename T> inline T* getPtrOrRef(const RefPtr<T>& p) { return p.get(); }
-template <typename T> inline T& getPtrOrRef(const Ref<T>& p) { return p.get(); }
-
-}
-
-template<typename T> struct JSConverter<IDLInterface<T>> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    template <typename U>
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const U& value)
-    {
-        return toJS(&state, &globalObject, Detail::getPtrOrRef(value));
-    }
-
-    template<typename U>
-    static JSC::JSValue convertNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
-    {
-        return toJSNewlyCreated(&state, &globalObject, std::forward<U>(value));
-    }
-};
-
-// MARK: -
-// MARK: Integer types
-
-template<> struct Converter<IDLByte> : DefaultConverter<IDLByte> {
-    static int8_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
-    {
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            return toInt8EnforceRange(state, value);
-        case IntegerConversionConfiguration::Clamp:
-            return toInt8Clamp(state, value);
-        }
-        return toInt8(state, value);
-    }
-};
-
-template<> struct JSConverter<IDLByte> {
-    using Type = typename IDLByte::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLOctet> : DefaultConverter<IDLOctet> {
-    static uint8_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
-    {
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            return toUInt8EnforceRange(state, value);
-        case IntegerConversionConfiguration::Clamp:
-            return toUInt8Clamp(state, value);
-        }
-        return toUInt8(state, value);
-    }
-};
-
-template<> struct JSConverter<IDLOctet> {
-    using Type = typename IDLOctet::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLShort> : DefaultConverter<IDLShort> {
-    static int16_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
-    {
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            return toInt16EnforceRange(state, value);
-        case IntegerConversionConfiguration::Clamp:
-            return toInt16Clamp(state, value);
-        }
-        return toInt16(state, value);
-    }
-};
-
-template<> struct JSConverter<IDLShort> {
-    using Type = typename IDLShort::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLUnsignedShort> : DefaultConverter<IDLUnsignedShort> {
-    static uint16_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
-    {
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            return toUInt16EnforceRange(state, value);
-        case IntegerConversionConfiguration::Clamp:
-            return toUInt16Clamp(state, value);
-        }
-        return toUInt16(state, value);
-    }
-};
-
-template<> struct JSConverter<IDLUnsignedShort> {
-    using Type = typename IDLUnsignedShort::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLLong> : DefaultConverter<IDLLong> {
-    static inline int32_t convert(JSC::ExecState&, JSC::ThrowScope&, double number)
-    {
-        return JSC::toInt32(number);
-    }
-
-    static int32_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
-    {
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            return toInt32EnforceRange(state, value);
-        case IntegerConversionConfiguration::Clamp:
-            return toInt32Clamp(state, value);
-        }
-        return value.toInt32(&state);
-    }
-};
-
-template<> struct JSConverter<IDLLong> {
-    using Type = typename IDLLong::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLUnsignedLong> : DefaultConverter<IDLUnsignedLong> {
-    static uint32_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
-    {
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            return toUInt32EnforceRange(state, value);
-        case IntegerConversionConfiguration::Clamp:
-            return toUInt32Clamp(state, value);
-        }
-        return value.toUInt32(&state);
-    }
-};
-
-template<> struct JSConverter<IDLUnsignedLong> {
-    using Type = typename IDLUnsignedLong::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLLongLong> : DefaultConverter<IDLLongLong> {
-    static int64_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
-    {
-        if (value.isInt32())
-            return value.asInt32();
-
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            return toInt64EnforceRange(state, value);
-        case IntegerConversionConfiguration::Clamp:
-            return toInt64Clamp(state, value);
-        }
-        return toInt64(state, value);
-    }
-};
-
-template<> struct JSConverter<IDLLongLong> {
-    using Type = typename IDLLongLong::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLUnsignedLongLong> : DefaultConverter<IDLUnsignedLongLong> {
-    static uint64_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
-    {
-        if (value.isUInt32())
-            return value.asUInt32();
-
-        switch (configuration) {
-        case IntegerConversionConfiguration::Normal:
-            break;
-        case IntegerConversionConfiguration::EnforceRange:
-            return toUInt64EnforceRange(state, value);
-        case IntegerConversionConfiguration::Clamp:
-            return toUInt64Clamp(state, value);
-        }
-        return toUInt64(state, value);
-    }
-};
-
-template<> struct JSConverter<IDLUnsignedLongLong> {
-    using Type = typename IDLUnsignedLongLong::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-// MARK: -
-// MARK: Floating point types
-
-template<> struct Converter<IDLFloat> : DefaultConverter<IDLFloat> {
-
-    static inline float convert(JSC::ExecState& state, JSC::ThrowScope& scope, double number)
-    {
-        if (UNLIKELY(!std::isfinite(number)))
-            throwNonFiniteTypeError(state, scope);
-        return static_cast<float>(number);
-    }
-
-    static float convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        double number = value.toNumber(&state);
-        if (UNLIKELY(!std::isfinite(number)))
-            throwNonFiniteTypeError(state, scope);
-        return static_cast<float>(number);
-    }
-};
-
-template<> struct JSConverter<IDLFloat> {
-    using Type = typename IDLFloat::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLUnrestrictedFloat> : DefaultConverter<IDLUnrestrictedFloat> {
-    static inline float convert(JSC::ExecState&, JSC::ThrowScope&, double number)
-    {
-        return static_cast<float>(number);
-    }
-
-    static float convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return static_cast<float>(value.toNumber(&state));
-    }
-};
-
-template<> struct JSConverter<IDLUnrestrictedFloat> {
-    using Type = typename IDLUnrestrictedFloat::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLDouble> : DefaultConverter<IDLDouble> {
-    static inline double convert(JSC::ExecState& state, JSC::ThrowScope& scope, double number)
-    {
-        if (UNLIKELY(!std::isfinite(number)))
-            throwNonFiniteTypeError(state, scope);
-        return number;
-    }
-
-    static double convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        double number = value.toNumber(&state);
-        if (UNLIKELY(!std::isfinite(number)))
-            throwNonFiniteTypeError(state, scope);
-        return number;
-    }
-};
-
-template<> struct JSConverter<IDLDouble> {
-    using Type = typename IDLDouble::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-};
-
-template<> struct Converter<IDLUnrestrictedDouble> : DefaultConverter<IDLUnrestrictedDouble> {
-    static inline double convert(JSC::ExecState&, JSC::ThrowScope&, double number)
-    {
-        return number;
-    }
-
-    static double convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return value.toNumber(&state);
-    }
-};
-
-template<> struct JSConverter<IDLUnrestrictedDouble> {
-    using Type = typename IDLUnrestrictedDouble::ImplementationType;
-
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(Type value)
-    {
-        return JSC::jsNumber(value);
-    }
-
-    // Add overload for MediaTime.
-    static JSC::JSValue convert(MediaTime value)
-    {
-        return JSC::jsNumber(value.toDouble());
-    }
-};
-
-// MARK: -
-// MARK: String types
-
-template<> struct Converter<IDLDOMString> : DefaultConverter<IDLDOMString> {
-    static String convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration = StringConversionConfiguration::Normal)
-    {
-        if (configuration == StringConversionConfiguration::TreatNullAsEmptyString && value.isNull())
-            return emptyString();
-        return value.toWTFString(&state);
-    }
-};
-
-template<> struct JSConverter<IDLDOMString> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(JSC::ExecState& state, const String& value)
-    {
-        return JSC::jsStringWithCache(&state, value);
-    }
-};
-
-template<> struct Converter<IDLByteString> : DefaultConverter<IDLByteString> {
-    static String convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration = StringConversionConfiguration::Normal)
-    {
-        if (configuration == StringConversionConfiguration::TreatNullAsEmptyString && value.isNull())
-            return emptyString();
-        return valueToByteString(state, value);
-    }
-};
-
-template<> struct JSConverter<IDLByteString> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(JSC::ExecState& state, const String& value)
-    {
-        return JSC::jsStringWithCache(&state, value);
-    }
-};
-
-template<> struct Converter<IDLUSVString> : DefaultConverter<IDLUSVString> {
-    static String convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration = StringConversionConfiguration::Normal)
-    {
-        if (configuration == StringConversionConfiguration::TreatNullAsEmptyString && value.isNull())
-            return emptyString();
-        return valueToUSVString(state, value);
-    }
-};
-
-template<> struct JSConverter<IDLUSVString> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(JSC::ExecState& state, const String& value)
-    {
-        return JSC::jsStringWithCache(&state, value);
-    }
-};
-
-// MARK: -
-// MARK: Object type
-
-template<> struct Converter<IDLObject> : DefaultConverter<IDLObject> {
-    template<typename ExceptionThrower = DefaultExceptionThrower>
-    static JSC::Strong<JSC::JSObject> convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        if (!value.isObject()) {
-            exceptionThrower(state, scope);
-            return { };
-        }
-        
-        return { vm, JSC::asObject(value) };
-    }
-};
-
-// MARK: -
-// MARK: Array-like types
-
-namespace Detail {
-    template<typename IDLType>
-    struct GenericSequenceConverter {
-        using ReturnType = Vector<typename IDLType::ImplementationType>;
-
-        static ReturnType convert(JSC::ExecState& state, JSC::JSObject* jsObject)
-        {
-            ReturnType result;
-            forEachInIterable(&state, jsObject, [&result](JSC::VM& vm, JSC::ExecState* state, JSC::JSValue jsValue) {
-                auto scope = DECLARE_THROW_SCOPE(vm);
-
-                auto convertedValue = Converter<IDLType>::convert(*state, jsValue);
-                if (UNLIKELY(scope.exception()))
-                    return;
-                result.append(WTFMove(convertedValue));
-            });
-            return result;
-        }
-    };
-
-    // Specialization for numeric types
-    // FIXME: This is only implemented for the IDLFloatingPointTypes and IDLLong. To add
-    // support for more numeric types, add an overload of Converter<IDLType>::convert that
-    // takes an ExecState, ThrowScope, double as its arguments.
-    template<typename IDLType>
-    struct NumericSequenceConverter {
-        using GenericConverter = GenericSequenceConverter<IDLType>;
-        using ReturnType = typename GenericConverter::ReturnType;
-
-        static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            auto& vm = state.vm();
-            auto scope = DECLARE_THROW_SCOPE(vm);
-
-            if (!value.isObject()) {
-                throwSequenceTypeError(state, scope);
-                return { };
-            }
-
-            JSC::JSObject* object = JSC::asObject(value);
-            if (!JSC::isJSArray(object))
-                return GenericConverter::convert(state, object);
-
-            JSC::JSArray* array = JSC::asArray(object);
-            if (!array->globalObject()->isArrayIteratorProtocolFastAndNonObservable())
-                return GenericConverter::convert(state, object);
-
-            unsigned length = array->length();
-
-            ReturnType result;
-            if (!result.tryReserveCapacity(length)) {
-                // FIXME: Is the right exception to throw?
-                throwTypeError(&state, scope);
-                return { };
-            }
-
-            JSC::IndexingType indexingType = array->indexingType() & JSC::IndexingShapeMask;
-
-            if (indexingType == JSC::ContiguousShape) {
-                for (unsigned i = 0; i < length; i++) {
-                    auto indexValue = array->butterfly()->contiguous()[i].get();
-                    if (!indexValue)
-                        result.uncheckedAppend(0);
-                    else {
-                        auto convertedValue = Converter<IDLType>::convert(state, indexValue);
-                        RETURN_IF_EXCEPTION(scope, { });
-
-                        result.uncheckedAppend(convertedValue);
-                    }
-                }
-                return result;
-            }
-            
-            if (indexingType == JSC::Int32Shape) {
-                for (unsigned i = 0; i < length; i++) {
-                    auto indexValue = array->butterfly()->contiguousInt32()[i].get();
-                    ASSERT(!indexValue || indexValue.isInt32());
-                    if (!indexValue)
-                        result.uncheckedAppend(0);
-                    else
-                        result.uncheckedAppend(indexValue.asInt32());
-                }
-                return result;
-            }
-
-            if (indexingType == JSC::DoubleShape) {
-                for (unsigned i = 0; i < length; i++) {
-                    auto doubleValue = array->butterfly()->contiguousDouble()[i];
-                    if (std::isnan(doubleValue))
-                        result.uncheckedAppend(0);
-                    else {
-                        auto convertedValue = Converter<IDLType>::convert(state, scope, doubleValue);
-                        RETURN_IF_EXCEPTION(scope, { });
-
-                        result.uncheckedAppend(convertedValue);
-                    }
-                }
-                return result;
-            }
-
-            for (unsigned i = 0; i < length; i++) {
-                auto indexValue = array->getDirectIndex(&state, i);
-                RETURN_IF_EXCEPTION(scope, { });
-                
-                if (!indexValue)
-                    result.uncheckedAppend(0);
-                else {
-                    auto convertedValue = Converter<IDLType>::convert(state, indexValue);
-                    RETURN_IF_EXCEPTION(scope, { });
-                    
-                    result.uncheckedAppend(convertedValue);
-                }
-            }
-            return result;
-        }
-    };
-
-    template<typename IDLType>
-    struct SequenceConverter {
-        using GenericConverter = GenericSequenceConverter<IDLType>;
-        using ReturnType = typename GenericConverter::ReturnType;
-
-        static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            auto& vm = state.vm();
-            auto scope = DECLARE_THROW_SCOPE(vm);
-
-            if (!value.isObject()) {
-                throwSequenceTypeError(state, scope);
-                return { };
-            }
-
-            JSC::JSObject* object = JSC::asObject(value);
-            if (!JSC::isJSArray(object))
-                return GenericConverter::convert(state, object);
-
-            JSC::JSArray* array = JSC::asArray(object);
-            if (!array->globalObject()->isArrayIteratorProtocolFastAndNonObservable())
-                return GenericConverter::convert(state, object);
-
-            unsigned length = array->length();
-
-            ReturnType result;
-            if (!result.tryReserveCapacity(length)) {
-                // FIXME: Is the right exception to throw?
-                throwTypeError(&state, scope);
-                return { };
-            }
-
-            JSC::IndexingType indexingType = array->indexingType() & JSC::IndexingShapeMask;
-
-            if (indexingType == JSC::ContiguousShape) {
-                for (unsigned i = 0; i < length; i++) {
-                    auto indexValue = array->butterfly()->contiguous()[i].get();
-                    if (!indexValue)
-                        indexValue = JSC::jsUndefined();
-
-                    auto convertedValue = Converter<IDLType>::convert(state, indexValue);
-                    RETURN_IF_EXCEPTION(scope, { });
-
-                    result.uncheckedAppend(convertedValue);
-                }
-                return result;
-            }
-
-            for (unsigned i = 0; i < length; i++) {
-                auto indexValue = array->getDirectIndex(&state, i);
-                RETURN_IF_EXCEPTION(scope, { });
-
-                if (!indexValue)
-                    indexValue = JSC::jsUndefined();
-
-                auto convertedValue = Converter<IDLType>::convert(state, indexValue);
-                RETURN_IF_EXCEPTION(scope, { });
-                
-                result.uncheckedAppend(convertedValue);
-            }
-            return result;
-        }
-    };
-
-    template<>
-    struct SequenceConverter<IDLLong> {
-        using ReturnType = typename GenericSequenceConverter<IDLLong>::ReturnType;
-
-        static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            return NumericSequenceConverter<IDLLong>::convert(state, value);
-        }
-    };
-
-    template<>
-    struct SequenceConverter<IDLFloat> {
-        using ReturnType = typename GenericSequenceConverter<IDLFloat>::ReturnType;
-
-        static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            return NumericSequenceConverter<IDLFloat>::convert(state, value);
-        }
-    };
-
-    template<>
-    struct SequenceConverter<IDLUnrestrictedFloat> {
-        using ReturnType = typename GenericSequenceConverter<IDLUnrestrictedFloat>::ReturnType;
-
-        static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            return NumericSequenceConverter<IDLUnrestrictedFloat>::convert(state, value);
-        }
-    };
-
-    template<>
-    struct SequenceConverter<IDLDouble> {
-        using ReturnType = typename GenericSequenceConverter<IDLDouble>::ReturnType;
-
-        static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            return NumericSequenceConverter<IDLDouble>::convert(state, value);
-        }
-    };
-
-    template<>
-    struct SequenceConverter<IDLUnrestrictedDouble> {
-        using ReturnType = typename GenericSequenceConverter<IDLUnrestrictedDouble>::ReturnType;
-
-        static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            return NumericSequenceConverter<IDLUnrestrictedDouble>::convert(state, value);
-        }
-    };
-}
-
-template<typename T> struct Converter<IDLSequence<T>> : DefaultConverter<IDLSequence<T>> {
-    using ReturnType = typename Detail::SequenceConverter<T>::ReturnType;
-
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return Detail::SequenceConverter<T>::convert(state, value);
-    }
-};
-
-template<typename T> struct JSConverter<IDLSequence<T>> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    template<typename U, size_t inlineCapacity>
-    static JSC::JSValue convert(JSC::ExecState& exec, JSDOMGlobalObject& globalObject, const Vector<U, inlineCapacity>& vector)
-    {
-        JSC::MarkedArgumentBuffer list;
-        for (auto& element : vector)
-            list.append(toJS<T>(exec, globalObject, element));
-        return JSC::constructArray(&exec, nullptr, &globalObject, list);
-    }
-};
-
-template<typename T> struct Converter<IDLFrozenArray<T>> : DefaultConverter<IDLFrozenArray<T>> {
-    using ReturnType = typename Detail::SequenceConverter<T>::ReturnType;
-
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return Detail::SequenceConverter<T>::convert(state, value);
-    }
-};
-
-template<typename T> struct JSConverter<IDLFrozenArray<T>> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    template<typename U, size_t inlineCapacity>
-    static JSC::JSValue convert(JSC::ExecState& exec, JSDOMGlobalObject& globalObject, const Vector<U, inlineCapacity>& vector)
-    {
-        JSC::MarkedArgumentBuffer list;
-        for (auto& element : vector)
-            list.append(toJS<T>(exec, globalObject, element));
-        auto* array = JSC::constructArray(&exec, nullptr, &globalObject, list);
-        return JSC::objectConstructorFreeze(&exec, array);
-    }
-};
-
-// MARK: -
-// MARK: Record type
-
-namespace Detail {
-    template<typename IDLStringType>
-    struct IdentifierConverter;
-
-    template<> struct IdentifierConverter<IDLDOMString> {
-        static String convert(JSC::ExecState&, const JSC::Identifier& identifier)
-        {
-            return identifier.string();
-        }
-    };
-
-    template<> struct IdentifierConverter<IDLByteString> {
-        static String convert(JSC::ExecState& state, const JSC::Identifier& identifier)
-        {
-            return identifierToByteString(state, identifier);
-        }
-    };
-
-    template<> struct IdentifierConverter<IDLUSVString> {
-        static String convert(JSC::ExecState& state, const JSC::Identifier& identifier)
-        {
-            return identifierToUSVString(state, identifier);
-        }
-    };
-}
-
-template<typename K, typename V> struct Converter<IDLRecord<K, V>> : DefaultConverter<IDLRecord<K, V>> {
-    using ReturnType = typename IDLRecord<K, V>::ImplementationType;
-    using KeyType = typename K::ImplementationType;
-    using ValueType = typename V::ImplementationType;
-
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        auto& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        // 1. Let result be a new empty instance of record<K, V>.
-        // 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(&state, scope);
-            return { };
-        }
-        
-        JSC::JSObject* object = JSC::asObject(value);
-    
-        ReturnType result;
-    
-        // 4. Let keys be ? O.[[OwnPropertyKeys]]().
-        JSC::PropertyNameArray keys(&vm, JSC::PropertyNameMode::Strings);
-        object->getOwnPropertyNames(object, &state, keys, JSC::EnumerationMode());
-        RETURN_IF_EXCEPTION(scope, { });
-
-        // 5. Repeat, for each element key of keys in List order:
-        for (auto& key : keys) {
-            // 1. Let desc be ? O.[[GetOwnProperty]](key).
-            JSC::PropertyDescriptor descriptor;
-            bool didGetDescriptor = object->getOwnPropertyDescriptor(&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() && descriptor.enumerable()) {
-                // 1. Let typedKey be key converted to an IDL value of type K.
-                auto typedKey = Detail::IdentifierConverter<K>::convert(state, key);
-
-                // 2. Let value be ? Get(O, key).
-                auto subValue = object->get(&state, key);
-                RETURN_IF_EXCEPTION(scope, { });
-
-                // 3. Let typedValue be value converted to an IDL value of type V.
-                auto typedValue = Converter<V>::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.
-                // FIXME: Handle this case.
-                
-                // 5. Otherwise, append to result a mapping (typedKey, typedValue).
-                result.append({ typedKey, typedValue });
-            }
-        }
-
-        // 6. Return result.
-        return result;
-    }
-};
-
-template<typename K, typename V> struct JSConverter<IDLRecord<K, V>> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    template<typename MapType>
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const MapType& map)
-    {
-        auto& vm = state.vm();
-    
-        // 1. Let result be ! ObjectCreate(%ObjectPrototype%).
-        auto result = constructEmptyObject(&state);
-        
-        // 2. Repeat, for each mapping (key, value) in D:
-        for (const auto& 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<V>(state, globalObject, keyValuePair.value);
-
-            // 3. Let created be ! CreateDataProperty(result, esKey, esValue).
-            bool created = result->putDirect(vm, JSC::Identifier::fromString(&vm, keyValuePair.key), esValue);
-
-            // 4. Assert: created is true.
-            ASSERT_UNUSED(created, created);
-        }
-
-        // 3. Return result.
-        return result;
-    }
-};
-
-// MARK: -
-// MARK: Dictionary type
-
-template<typename T> struct Converter<IDLDictionary<T>> : DefaultConverter<IDLDictionary<T>> {
-    using ReturnType = T;
-
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return convertDictionary<T>(state, value);
-    }
-};
-
-template<typename T> struct JSConverter<IDLDictionary<T>> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const T& dictionary)
-    {
-        return convertDictionaryToJS(state, globalObject, dictionary);
-    }
-};
-
-// MARK: -
-// MARK: Enumeration type
-
-template<typename T> struct Converter<IDLEnumeration<T>> : DefaultConverter<IDLEnumeration<T>> {
-    static T convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return convertEnumeration<T>(state, value);
-    }
-};
-
-template<typename T> struct JSConverter<IDLEnumeration<T>> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(JSC::ExecState& exec, T value)
-    {
-        return convertEnumerationToJS(exec, value);
-    }
-};
-
-// MARK: -
-// MARK: Callback function type
-
-template<typename T> struct Converter<IDLCallbackFunction<T>> : DefaultConverter<IDLCallbackFunction<T>> {
-    template<typename ExceptionThrower = DefaultExceptionThrower>
-    static RefPtr<T> convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower = ExceptionThrower())
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        if (!value.isFunction()) {
-            exceptionThrower(state, scope);
-            return nullptr;
-        }
-        
-        return T::create(JSC::asObject(value), &globalObject);
-    }
-};
-
-template<typename T> struct JSConverter<IDLCallbackFunction<T>> {
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    template <typename U>
-    static JSC::JSValue convert(const U& value)
-    {
-        return toJS(Detail::getPtrOrRef(value));
-    }
-
-    template<typename U>
-    static JSC::JSValue convertNewlyCreated(U&& value)
-    {
-        return toJSNewlyCreated(std::forward<U>(value));
-    }
-};
-
-// MARK: -
-// MARK: Callback interface type
-
-template<typename T> struct Converter<IDLCallbackInterface<T>> : DefaultConverter<IDLCallbackInterface<T>> {
-    template<typename ExceptionThrower = DefaultExceptionThrower>
-    static RefPtr<T> convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower = ExceptionThrower())
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        if (!value.isObject()) {
-            exceptionThrower(state, scope);
-            return nullptr;
-        }
-
-        return T::create(JSC::asObject(value), &globalObject);
-    }
-};
-
-template<typename T> struct JSConverter<IDLCallbackInterface<T>> {
-    static constexpr bool needsState = false;
-    static constexpr bool needsGlobalObject = false;
-
-    template <typename U>
-    static JSC::JSValue convert(const U& value)
-    {
-        return toJS(Detail::getPtrOrRef(value));
-    }
-
-    template<typename U>
-    static JSC::JSValue convertNewlyCreated(U&& value)
-    {
-        return toJSNewlyCreated(std::forward<U>(value));
-    }
-};
-
-// MARK: -
-// MARK: Union type
-
-template<typename ReturnType, typename T, bool enabled>
-struct ConditionalConverter;
-
-template<typename ReturnType, typename T>
-struct ConditionalConverter<ReturnType, T, true> {
-    static std::optional<ReturnType> convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return ReturnType(Converter<T>::convert(state, value));
-    }
-};
-
-template<typename ReturnType, typename T>
-struct ConditionalConverter<ReturnType, T, false> {
-    static std::optional<ReturnType> convert(JSC::ExecState&, JSC::JSValue)
-    {
-        return std::nullopt;
-    }
-};
-
-namespace Detail {
-    template<typename List, bool condition>
-    struct ConditionalFront;
-
-    template<typename List>
-    struct ConditionalFront<List, true>
-    {
-        using type = brigand::front<List>;
-    };
-
-    template<typename List>
-    struct ConditionalFront<List, false>
-    {
-        using type = void;
-    };
-}
-
-template<typename List, bool condition>
-using ConditionalFront = typename Detail::ConditionalFront<List, condition>::type;
-
-template<typename... T> struct Converter<IDLUnion<T...>> : DefaultConverter<IDLUnion<T...>> {
-    using Type = IDLUnion<T...>;
-    using TypeList = typename Type::TypeList;
-    using ReturnType = typename Type::ImplementationType;
-
-    using NumericTypeList = brigand::filter<TypeList, IsIDLNumber<brigand::_1>>;
-    static constexpr size_t numberOfNumericTypes = brigand::size<NumericTypeList>::value;
-    static_assert(numberOfNumericTypes == 0 || numberOfNumericTypes == 1, "There can be 0 or 1 numeric types in an IDLUnion.");
-    using NumericType = ConditionalFront<NumericTypeList, numberOfNumericTypes != 0>;
-
-    // FIXME: This should also check for IDLEnumeration<T>.
-    using StringTypeList = brigand::filter<TypeList, std::is_base_of<IDLString, brigand::_1>>;
-    static constexpr size_t numberOfStringTypes = brigand::size<StringTypeList>::value;
-    static_assert(numberOfStringTypes == 0 || numberOfStringTypes == 1, "There can be 0 or 1 string types in an IDLUnion.");
-    using StringType = ConditionalFront<StringTypeList, numberOfStringTypes != 0>;
-
-    using SequenceTypeList = brigand::filter<TypeList, IsIDLSequence<brigand::_1>>;
-    static constexpr size_t numberOfSequenceTypes = brigand::size<SequenceTypeList>::value;
-    static_assert(numberOfSequenceTypes == 0 || numberOfSequenceTypes == 1, "There can be 0 or 1 sequence types in an IDLUnion.");
-    using SequenceType = ConditionalFront<SequenceTypeList, numberOfSequenceTypes != 0>;
-
-    using FrozenArrayTypeList = brigand::filter<TypeList, IsIDLFrozenArray<brigand::_1>>;
-    static constexpr size_t numberOfFrozenArrayTypes = brigand::size<FrozenArrayTypeList>::value;
-    static_assert(numberOfFrozenArrayTypes == 0 || numberOfFrozenArrayTypes == 1, "There can be 0 or 1 FrozenArray types in an IDLUnion.");
-    using FrozenArrayType = ConditionalFront<FrozenArrayTypeList, numberOfFrozenArrayTypes != 0>;
-
-    using DictionaryTypeList = brigand::filter<TypeList, IsIDLDictionary<brigand::_1>>;
-    static constexpr size_t numberOfDictionaryTypes = brigand::size<DictionaryTypeList>::value;
-    static_assert(numberOfDictionaryTypes == 0 || numberOfDictionaryTypes == 1, "There can be 0 or 1 dictionary types in an IDLUnion.");
-    static constexpr bool hasDictionaryType = numberOfDictionaryTypes != 0;
-    using DictionaryType = ConditionalFront<DictionaryTypeList, hasDictionaryType>;
-
-    using RecordTypeList = brigand::filter<TypeList, IsIDLRecord<brigand::_1>>;
-    static constexpr size_t numberOfRecordTypes = brigand::size<RecordTypeList>::value;
-    static_assert(numberOfRecordTypes == 0 || numberOfRecordTypes == 1, "There can be 0 or 1 record types in an IDLUnion.");
-    static constexpr bool hasRecordType = numberOfRecordTypes != 0;
-    using RecordType = ConditionalFront<RecordTypeList, hasRecordType>;
-
-    static constexpr bool hasObjectType = (numberOfSequenceTypes + numberOfFrozenArrayTypes + numberOfDictionaryTypes + numberOfRecordTypes) > 0;
-
-    using InterfaceTypeList = brigand::filter<TypeList, IsIDLInterface<brigand::_1>>;
-
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-
-        // 1. If the union type includes a nullable type and V is null or undefined, then return the IDL value null.
-        constexpr bool hasNullType = brigand::any<TypeList, std::is_same<IDLNull, brigand::_1>>::value;
-        if (hasNullType) {
-            if (value.isUndefinedOrNull())
-                return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, IDLNull, hasNullType>::convert(state, value).value());
-        }
-        
-        // 2. Let types be the flattened member types of the union type.
-        // NOTE: Union is expected to be pre-flattented.
-        
-        // 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<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, DictionaryType, hasDictionaryType>::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<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, RecordType, hasRecordType>::convert(state, value).value());
-            }
-        }
-
-        // 4. If V is a platform object, then:
-        //     1. If types includes an interface type that V implements, then return the IDL value that is a reference to the object V.
-        //     2. If types includes object, then return the IDL value that is a reference to the object V.
-        //         (FIXME: Add support for object and step 4.2)
-        if (brigand::any<TypeList, IsIDLInterface<brigand::_1>>::value) {
-            std::optional<ReturnType> returnValue;
-            brigand::for_each<InterfaceTypeList>([&](auto&& type) {
-                if (returnValue)
-                    return;
-                
-                using Type = typename WTF::RemoveCVAndReference<decltype(type)>::type::type;
-                using ImplementationType = typename Type::ImplementationType;
-                using RawType = typename Type::RawType;
-                using WrapperType = typename JSDOMWrapperConverterTraits<RawType>::WrapperClass;
-
-                auto castedValue = WrapperType::toWrapped(vm, value);
-                if (!castedValue)
-                    return;
-                
-                returnValue = ReturnType(ImplementationType(castedValue));
-            });
-
-            if (returnValue)
-                return WTFMove(returnValue.value());
-        }
-        
-        // FIXME: Add support for steps 5 - 10.
-
-        // 11. If V is any kind of object, then:
-        if (hasObjectType) {
-            if (value.isCell()) {
-                JSC::JSCell* cell = value.asCell();
-                if (cell->isObject()) {
-                    // FIXME: We should be able to optimize the following code by making use
-                    // of the fact that we have proved that the value is an object. 
-                
-                    //     1. If types includes a sequence type, then:
-                    //         1. Let method be the result of GetMethod(V, @@iterator).
-                    //         2. ReturnIfAbrupt(method).
-                    //         3. If method is not undefined, return the result of creating a
-                    //            sequence of that type from V and method.        
-                    constexpr bool hasSequenceType = numberOfSequenceTypes != 0;
-                    if (hasSequenceType) {
-                        bool hasIterator = hasIteratorMethod(state, value);
-                        RETURN_IF_EXCEPTION(scope, ReturnType());
-                        if (hasIterator)
-                            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, SequenceType, hasSequenceType>::convert(state, value).value());
-                    }
-
-                    //     2. If types includes a frozen array type, then:
-                    //         1. Let method be the result of GetMethod(V, @@iterator).
-                    //         2. ReturnIfAbrupt(method).
-                    //         3. If method is not undefined, return the result of creating a
-                    //            frozen array of that type from V and method.
-                    constexpr bool hasFrozenArrayType = numberOfFrozenArrayTypes != 0;
-                    if (hasFrozenArrayType) {
-                        bool hasIterator = hasIteratorMethod(state, value);
-                        RETURN_IF_EXCEPTION(scope, ReturnType());
-                        if (hasIterator)
-                            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, FrozenArrayType, hasFrozenArrayType>::convert(state, value).value());
-                    }
-
-                    //     3. If types includes a dictionary type, then return the result of
-                    //        converting V to that dictionary type.
-                    if (hasDictionaryType)
-                        return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, DictionaryType, hasDictionaryType>::convert(state, value).value());
-
-                    //     4. If types includes a record type, then return the result of converting V to that record type.
-                    if (hasRecordType)
-                        return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, RecordType, hasRecordType>::convert(state, value).value());
-
-                    //     5. If types includes a callback interface type, then return the result of converting V to that interface type.
-                    //         (FIXME: Add support for callback interface type and step 12.5)
-                    //     6. If types includes object, then return the IDL value that is a reference to the object V.
-                    //         (FIXME: Add support for object and step 12.6)
-                }
-            }
-        }
-
-        // 12. If V is a Boolean value, then:
-        //     1. If types includes a boolean, then return the result of converting V to boolean.
-        constexpr bool hasBooleanType = brigand::any<TypeList, std::is_same<IDLBoolean, brigand::_1>>::value;
-        if (hasBooleanType) {
-            if (value.isBoolean())
-                return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, IDLBoolean, hasBooleanType>::convert(state, value).value());
-        }
-        
-        // 13. If V is a Number value, then:
-        //     1. If types includes a numeric type, then return the result of converting V to that numeric type.
-        constexpr bool hasNumericType = brigand::size<NumericTypeList>::value != 0;
-        if (hasNumericType) {
-            if (value.isNumber())
-                return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, NumericType, hasNumericType>::convert(state, value).value());
-        }
-        
-        // 14. If types includes a string type, then return the result of converting V to that type.
-        constexpr bool hasStringType = brigand::size<StringTypeList>::value != 0;
-        if (hasStringType)
-            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, StringType, hasStringType>::convert(state, value).value());
-
-        // 15. If types includes a numeric type, then return the result of converting V to that numeric type.
-        if (hasNumericType)
-            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, NumericType, hasNumericType>::convert(state, value).value());
-
-        // 16. If types includes a boolean, then return the result of converting V to boolean.
-        if (hasBooleanType)
-            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, IDLBoolean, hasBooleanType>::convert(state, value).value());
-
-        // 17. Throw a TypeError.
-        throwTypeError(&state, scope);
-        return ReturnType();
-    }
-};
-
-template<typename... T> struct JSConverter<IDLUnion<T...>> {
-    using Type = IDLUnion<T...>;
-    using TypeList = typename Type::TypeList;
-    using ImplementationType = typename Type::ImplementationType;
-
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    using Sequence = brigand::make_sequence<brigand::ptrdiff_t<0>, WTF::variant_size<ImplementationType>::value>;
-
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const ImplementationType& variant)
-    {
-        auto index = variant.index();
-
-        std::optional<JSC::JSValue> returnValue;
-        brigand::for_each<Sequence>([&](auto&& type) {
-            using I = typename WTF::RemoveCVAndReference<decltype(type)>::type::type;
-            if (I::value == index) {
-                ASSERT(!returnValue);
-                returnValue = toJS<brigand::at<TypeList, I>>(state, globalObject, WTF::get<I::value>(variant));
-            }
-        });
-
-        ASSERT(returnValue);
-        return returnValue.value();
-    }
-};
-
-// MARK: -
-// MARK: Date type
-
-template<> struct Converter<IDLDate> : DefaultConverter<IDLDate> {
-    static double convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return valueToDate(&state, value);
-    }
-};
-
-template<> struct JSConverter<IDLDate> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(JSC::ExecState& state, double value)
-    {
-        return jsDate(&state, value);
-    }
-};
-
-// MARK: -
-// MARK: IDLJSON type
-
-template<> struct Converter<IDLJSON> : DefaultConverter<IDLJSON> {
-    static String convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return JSC::JSONStringify(&state, value, 0);
-    }
-};
-
-template<> struct JSConverter<IDLJSON> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = false;
-
-    static JSC::JSValue convert(JSC::ExecState& state, const String& value)
-    {
-        return JSC::JSONParse(&state, value);
-    }
-};
-
-// MARK: -
-// MARK: SerializedScriptValue type
-
-template<typename T> struct Converter<IDLSerializedScriptValue<T>> : DefaultConverter<IDLSerializedScriptValue<T>> {
-    static RefPtr<T> convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        return T::create(state, value);
-    }
-};
-
-template<typename T> struct JSConverter<IDLSerializedScriptValue<T>> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, RefPtr<T> value)
-    {
-        return value ? value->deserialize(state, &globalObject) : JSC::jsNull();
-    }
-};
-
-// MARK: -
-// MARK: Event Listener type
-
-template<typename T> struct Converter<IDLEventListener<T>> : DefaultConverter<IDLEventListener<T>> {
-    using ReturnType = RefPtr<T>;
-
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject)
-    {
-        auto scope = DECLARE_THROW_SCOPE(state.vm());
-
-        auto listener = T::create(value, thisObject, false, currentWorld(&state));
-        if (!listener)
-            throwTypeError(&state, scope);
-    
-        return listener;
-    }
-};
-
-// MARK: -
-// MARK: XPathNSResolver type
-
-template<typename T> struct Converter<IDLXPathNSResolver<T>> : DefaultConverter<IDLXPathNSResolver<T>> {
-    using ReturnType = RefPtr<T>;
-    using WrapperType = typename JSDOMWrapperConverterTraits<T>::WrapperClass;
-
-    template<typename ExceptionThrower = DefaultExceptionThrower>
-    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
-    {
-        JSC::VM& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        ReturnType object = WrapperType::toWrapped(vm, state, value);
-        if (UNLIKELY(!object))
-            exceptionThrower(state, scope);
-        return object;
-    }
-};
-
-template<typename T> struct JSConverter<IDLXPathNSResolver<T>> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    template <typename U>
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const U& value)
-    {
-        return toJS(&state, &globalObject, Detail::getPtrOrRef(value));
-    }
-
-    template<typename U>
-    static JSC::JSValue convertNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
-    {
-        return toJSNewlyCreated(&state, &globalObject, std::forward<U>(value));
-    }
-};
-
-// MARK: -
-// MARK: IDLIDBKey type
-
-template<> struct JSConverter<IDLIDBKey> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    template <typename U>
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
-    {
-        return toJS(state, globalObject, std::forward<U>(value));
-    }
-};
-
-#if ENABLE(WEBGL)
-
-// MARK: -
-// MARK: IDLWebGLAny type
-
-template<> struct JSConverter<IDLWebGLAny> {
-    static constexpr bool needsState = true;
-    static constexpr bool needsGlobalObject = true;
-
-    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const WebGLAny& value)
-    {
-        return convertToJSValue(state, globalObject, value);
-    }
-};
-
-#endif
-
-// MARK: -
-// MARK: Support for variadic tail convertions
-
-namespace Detail {
-    template<typename IDLType>
-    struct VariadicConverterBase;
-
-    template<typename IDLType> 
-    struct VariadicConverterBase {
-        using Item = typename IDLType::ImplementationType;
-
-        static std::optional<Item> convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            auto& vm = state.vm();
-            auto scope = DECLARE_THROW_SCOPE(vm);
-
-            auto result = Converter<IDLType>::convert(state, value);
-            RETURN_IF_EXCEPTION(scope, std::nullopt);
-
-            return WTFMove(result);
-        }
-    };
-
-    template<typename T>
-    struct VariadicConverterBase<IDLInterface<T>> {
-        using Item = std::reference_wrapper<T>;
-
-        static std::optional<Item> convert(JSC::ExecState& state, JSC::JSValue value)
-        {
-            auto* result = Converter<IDLInterface<T>>::convert(state, value);
-            if (!result)
-                return std::nullopt;
-            return std::optional<Item>(*result);
-        }
-    };
-
-    template<typename IDLType>
-    struct VariadicConverter : VariadicConverterBase<IDLType> {
-        using Item = typename VariadicConverterBase<IDLType>::Item;
-        using Container = Vector<Item>;
-
-        struct Result {
-            size_t argumentIndex;
-            std::optional<Container> arguments;
-        };
-    };
-}
-
-template<typename IDLType> typename Detail::VariadicConverter<IDLType>::Result convertVariadicArguments(JSC::ExecState& state, size_t startIndex)
-{
-    size_t length = state.argumentCount();
-    if (startIndex > length)
-        return { 0, std::nullopt };
-
-    typename Detail::VariadicConverter<IDLType>::Container result;
-    result.reserveInitialCapacity(length - startIndex);
-
-    for (size_t i = startIndex; i < length; ++i) {
-        auto value = Detail::VariadicConverter<IDLType>::convert(state, state.uncheckedArgument(i));
-        if (!value)
-            return { i, std::nullopt };
-        result.uncheckedAppend(WTFMove(*value));
-    }
-
-    return { length, WTFMove(result) };
-}
-
-} // namespace WebCore
+#include "JSDOMConvertAny.h"
+#include "JSDOMConvertBoolean.h"
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMConvertCallbacks.h"
+#include "JSDOMConvertDate.h"
+#include "JSDOMConvertDictionary.h"
+#include "JSDOMConvertEnumeration.h"
+#include "JSDOMConvertEventListener.h"
+#include "JSDOMConvertIndexedDB.h"
+#include "JSDOMConvertInterface.h"
+#include "JSDOMConvertJSON.h"
+#include "JSDOMConvertNull.h"
+#include "JSDOMConvertNullable.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertObject.h"
+#include "JSDOMConvertRecord.h"
+#include "JSDOMConvertSequences.h"
+#include "JSDOMConvertSerializedScriptValue.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMConvertUnion.h"
+#include "JSDOMConvertWebGL.h"
+#include "JSDOMConvertXPathNSResolver.h"
diff --git a/Source/WebCore/bindings/js/JSDOMConvertAny.h b/Source/WebCore/bindings/js/JSDOMConvertAny.h
new file mode 100644 (file)
index 0000000..b27ab7c
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<> struct Converter<IDLAny> : DefaultConverter<IDLAny> {
+    using ReturnType = JSC::JSValue;
+    
+    static JSC::JSValue convert(JSC::ExecState&, JSC::JSValue value)
+    {
+        return value;
+    }
+
+    static JSC::JSValue convert(const JSC::Strong<JSC::Unknown>& value)
+    {
+        return value.get();
+    }
+};
+
+template<> struct JSConverter<IDLAny> {
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(const JSC::JSValue& value)
+    {
+        return value;
+    }
+
+    static JSC::JSValue convert(const JSC::Strong<JSC::Unknown>& value)
+    {
+        return value.get();
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertBase.h b/Source/WebCore/bindings/js/JSDOMConvertBase.h
new file mode 100644 (file)
index 0000000..bd23abe
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSDOMExceptionHandling.h"
+
+namespace WebCore {
+
+// Conversion from JSValue -> Implementation
+template<typename T> struct Converter;
+
+
+struct DefaultExceptionThrower {
+    void operator()(JSC::ExecState& state, JSC::ThrowScope& scope)
+    {
+        throwTypeError(&state, scope);
+    }
+};
+
+template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue);
+template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, JSC::JSObject&);
+template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, JSDOMGlobalObject&);
+template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, ExceptionThrower&&);
+template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, JSC::JSObject&, ExceptionThrower&&);
+template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, JSDOMGlobalObject&, ExceptionThrower&&);
+
+template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+{
+    return Converter<T>::convert(state, value);
+}
+
+template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject)
+{
+    return Converter<T>::convert(state, value, thisObject);
+}
+
+template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject)
+{
+    return Converter<T>::convert(state, value, globalObject);
+}
+
+template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower)
+{
+    return Converter<T>::convert(state, value, std::forward<ExceptionThrower>(exceptionThrower));
+}
+
+template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject, ExceptionThrower&& exceptionThrower)
+{
+    return Converter<T>::convert(state, value, thisObject, std::forward<ExceptionThrower>(exceptionThrower));
+}
+
+template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower)
+{
+    return Converter<T>::convert(state, value, globalObject, std::forward<ExceptionThrower>(exceptionThrower));
+}
+
+// Conversion from Implementation -> JSValue
+template<typename T> struct JSConverter;
+
+template<typename T, typename U> inline JSC::JSValue toJS(U&&);
+template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState&, U&&);
+template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState&, JSDOMGlobalObject&, U&&);
+template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState&, JSC::ThrowScope&, ExceptionOr<U>&&);
+template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<U>&&);
+template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState&, JSDOMGlobalObject&, U&&);
+template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState&, JSDOMGlobalObject&, JSC::ThrowScope&, ExceptionOr<U>&&);
+
+template<typename T, bool needsState = JSConverter<T>::needsState, bool needsGlobalObject = JSConverter<T>::needsGlobalObject>
+struct JSConverterOverloader;
+
+template<typename T>
+struct JSConverterOverloader<T, true, true> {
+    template<typename U> static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
+    {
+        return JSConverter<T>::convert(state, globalObject, std::forward<U>(value));
+    }
+};
+
+template<typename T>
+struct JSConverterOverloader<T, true, false> {
+    template<typename U> static JSC::JSValue convert(JSC::ExecState& state, U&& value)
+    {
+        return JSConverter<T>::convert(state, std::forward<U>(value));
+    }
+
+    template<typename U> static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject&, U&& value)
+    {
+        return JSConverter<T>::convert(state, std::forward<U>(value));
+    }
+};
+
+template<typename T>
+struct JSConverterOverloader<T, false, false> {
+    template<typename U> static JSC::JSValue convert(JSC::ExecState&, U&& value)
+    {
+        return JSConverter<T>::convert(std::forward<U>(value));
+    }
+
+    template<typename U> static JSC::JSValue convert(JSC::ExecState&, JSDOMGlobalObject&, U&& value)
+    {
+        return JSConverter<T>::convert(std::forward<U>(value));
+    }
+};
+
+template<typename T, typename U> inline JSC::JSValue toJS(U&& value)
+{
+    return JSConverter<T>::convert(std::forward<U>(value));
+}
+
+template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState& state, U&& value)
+{
+    return JSConverterOverloader<T>::convert(state, std::forward<U>(value));
+}
+
+template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
+{
+    return JSConverterOverloader<T>::convert(state, globalObject, std::forward<U>(value));
+}
+
+template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState& state, JSC::ThrowScope& throwScope, ExceptionOr<U>&& value)
+{
+    if (UNLIKELY(value.hasException())) {
+        propagateException(state, throwScope, value.releaseException());
+        return { };
+    }
+
+    return toJS<T>(state, value.releaseReturnValue());
+}
+
+template<typename T, typename U> inline JSC::JSValue toJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, JSC::ThrowScope& throwScope, ExceptionOr<U>&& value)
+{
+    if (UNLIKELY(value.hasException())) {
+        propagateException(state, throwScope, value.releaseException());
+        return { };
+    }
+
+    return toJS<T>(state, globalObject, value.releaseReturnValue());
+}
+
+template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
+{
+    return JSConverter<T>::convertNewlyCreated(state, globalObject, std::forward<U>(value));
+}
+
+template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, JSC::ThrowScope& throwScope, ExceptionOr<U>&& value)
+{
+    if (UNLIKELY(value.hasException())) {
+        propagateException(state, throwScope, value.releaseException());
+        return { };
+    }
+
+    return toJSNewlyCreated<T>(state, globalObject, value.releaseReturnValue());
+}
+
+
+template<typename T> struct DefaultConverter {
+    using ReturnType = typename T::ImplementationType;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertBoolean.h b/Source/WebCore/bindings/js/JSDOMConvertBoolean.h
new file mode 100644 (file)
index 0000000..853be0c
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<> struct Converter<IDLBoolean> : DefaultConverter<IDLBoolean> {
+    static bool convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return value.toBoolean(&state);
+    }
+};
+
+template<> struct JSConverter<IDLBoolean> {
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(bool value)
+    {
+        return JSC::jsBoolean(value);
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertBufferSource.h b/Source/WebCore/bindings/js/JSDOMConvertBufferSource.h
new file mode 100644 (file)
index 0000000..dc45fc1
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BufferSource.h"
+#include "JSDOMConvertInterface.h"
+#include "JSDOMWrapperCache.h"
+#include "JSDynamicDowncast.h"
+#include <runtime/JSTypedArrays.h>
+
+namespace WebCore {
+
+// FIXME: It is wrong that we treat buffer related types as interfaces, they should be their own IDL type. 
+
+// Add adaptors to make ArrayBuffer / ArrayBufferView / typed arrays act like normal interfaces.
+
+template<typename ImplementationClass> struct JSDOMWrapperConverterTraits;
+
+template<> struct JSDOMWrapperConverterTraits<JSC::ArrayBuffer> {
+    using WrapperClass = JSC::JSArrayBuffer;
+    using ToWrappedReturnType = JSC::ArrayBuffer*;
+};
+
+template<> struct JSDOMWrapperConverterTraits<JSC::ArrayBufferView> {
+    using WrapperClass = JSC::JSArrayBufferView;
+    using ToWrappedReturnType = RefPtr<ArrayBufferView>;
+};
+
+template<typename Adaptor> struct JSDOMWrapperConverterTraits<JSC::GenericTypedArrayView<Adaptor>> {
+    using WrapperClass = JSC::JSGenericTypedArrayView<Adaptor>;
+    using ToWrappedReturnType = RefPtr<JSC::GenericTypedArrayView<Adaptor>>;
+};
+
+
+inline RefPtr<JSC::Int8Array> toPossiblySharedInt8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int8Adaptor>(vm, value); }
+inline RefPtr<JSC::Int16Array> toPossiblySharedInt16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int16Adaptor>(vm, value); }
+inline RefPtr<JSC::Int32Array> toPossiblySharedInt32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int32Adaptor>(vm, value); }
+inline RefPtr<JSC::Uint8Array> toPossiblySharedUint8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint8Adaptor>(vm, value); }
+inline RefPtr<JSC::Uint8ClampedArray> toPossiblySharedUint8ClampedArray(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint8ClampedAdaptor>(vm, value); }
+inline RefPtr<JSC::Uint16Array> toPossiblySharedUint16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint16Adaptor>(vm, value); }
+inline RefPtr<JSC::Uint32Array> toPossiblySharedUint32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint32Adaptor>(vm, value); }
+inline RefPtr<JSC::Float32Array> toPossiblySharedFloat32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Float32Adaptor>(vm, value); }
+inline RefPtr<JSC::Float64Array> toPossiblySharedFloat64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Float64Adaptor>(vm, value); }
+
+inline RefPtr<JSC::Int8Array> toUnsharedInt8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int8Adaptor>(vm, value); }
+inline RefPtr<JSC::Int16Array> toUnsharedInt16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int16Adaptor>(vm, value); }
+inline RefPtr<JSC::Int32Array> toUnsharedInt32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int32Adaptor>(vm, value); }
+inline RefPtr<JSC::Uint8Array> toUnsharedUint8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint8Adaptor>(vm, value); }
+inline RefPtr<JSC::Uint8ClampedArray> toUnsharedUint8ClampedArray(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint8ClampedAdaptor>(vm, value); }
+inline RefPtr<JSC::Uint16Array> toUnsharedUint16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint16Adaptor>(vm, value); }
+inline RefPtr<JSC::Uint32Array> toUnsharedUint32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint32Adaptor>(vm, value); }
+inline RefPtr<JSC::Float32Array> toUnsharedFloat32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Float32Adaptor>(vm, value); }
+inline RefPtr<JSC::Float64Array> toUnsharedFloat64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Float64Adaptor>(vm, value); }
+
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, JSC::ArrayBuffer& buffer)
+{
+    if (auto result = getCachedWrapper(globalObject->world(), buffer))
+        return result;
+
+    // The JSArrayBuffer::create function will register the wrapper in finishCreation.
+    return JSC::JSArrayBuffer::create(state->vm(), globalObject->arrayBufferStructure(buffer.sharingMode()), &buffer);
+}
+
+inline JSC::JSValue toJS(JSC::ExecState* state, JSC::JSGlobalObject* globalObject, JSC::ArrayBufferView& view)
+{
+    return view.wrap(state, globalObject);
+}
+
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, JSC::ArrayBuffer* buffer)
+{
+    if (!buffer)
+        return JSC::jsNull();
+    return toJS(state, globalObject, *buffer);
+}
+
+inline JSC::JSValue toJS(JSC::ExecState* state, JSC::JSGlobalObject* globalObject, JSC::ArrayBufferView* view)
+{
+    if (!view)
+        return JSC::jsNull();
+    return toJS(state, globalObject, *view);
+}
+
+inline RefPtr<JSC::ArrayBufferView> toPossiblySharedArrayBufferView(JSC::VM& vm, JSC::JSValue value)
+{
+    auto* wrapper = jsDynamicDowncast<JSC::JSArrayBufferView*>(vm, value);
+    if (!wrapper)
+        return nullptr;
+    return wrapper->possiblySharedImpl();
+}
+
+inline RefPtr<JSC::ArrayBufferView> toUnsharedArrayBufferView(JSC::VM& vm, JSC::JSValue value)
+{
+    auto result = toPossiblySharedArrayBufferView(vm, value);
+    if (!result || result->isShared())
+        return nullptr;
+    return result;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertCallbacks.h b/Source/WebCore/bindings/js/JSDOMConvertCallbacks.h
new file mode 100644 (file)
index 0000000..3c1397a
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<typename T> struct Converter<IDLCallbackFunction<T>> : DefaultConverter<IDLCallbackFunction<T>> {
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static RefPtr<T> convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower = ExceptionThrower())
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        if (!value.isFunction()) {
+            exceptionThrower(state, scope);
+            return nullptr;
+        }
+        
+        return T::create(JSC::asObject(value), &globalObject);
+    }
+};
+
+template<typename T> struct JSConverter<IDLCallbackFunction<T>> {
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    template <typename U>
+    static JSC::JSValue convert(const U& value)
+    {
+        return toJS(Detail::getPtrOrRef(value));
+    }
+
+    template<typename U>
+    static JSC::JSValue convertNewlyCreated(U&& value)
+    {
+        return toJSNewlyCreated(std::forward<U>(value));
+    }
+};
+
+
+template<typename T> struct Converter<IDLCallbackInterface<T>> : DefaultConverter<IDLCallbackInterface<T>> {
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static RefPtr<T> convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower = ExceptionThrower())
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        if (!value.isObject()) {
+            exceptionThrower(state, scope);
+            return nullptr;
+        }
+
+        return T::create(JSC::asObject(value), &globalObject);
+    }
+};
+
+template<typename T> struct JSConverter<IDLCallbackInterface<T>> {
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    template <typename U>
+    static JSC::JSValue convert(const U& value)
+    {
+        return toJS(Detail::getPtrOrRef(value));
+    }
+
+    template<typename U>
+    static JSC::JSValue convertNewlyCreated(U&& value)
+    {
+        return toJSNewlyCreated(std::forward<U>(value));
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertDate.cpp b/Source/WebCore/bindings/js/JSDOMConvertDate.cpp
new file mode 100644 (file)
index 0000000..c019a6e
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004-2011, 2013, 2016 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ *  Copyright (C) 2013 Michael Pruett <michael@68k.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "JSDOMConvertDate.h"
+
+#include <heap/HeapInlines.h>
+#include <runtime/DateInstance.h>
+#include <runtime/JSCJSValueInlines.h>
+#include <runtime/JSGlobalObject.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+// FIXME: This should get passed a global object rather than getting it out of the ExecState.
+JSValue jsDate(ExecState& state, double value)
+{
+    return DateInstance::create(state.vm(), state.lexicalGlobalObject()->dateStructure(), value);
+}
+
+double valueToDate(ExecState& state, JSValue value)
+{
+    if (value.isNumber())
+        return value.asNumber();
+    if (!value.inherits(state.vm(), DateInstance::info()))
+        return std::numeric_limits<double>::quiet_NaN();
+    return static_cast<DateInstance*>(value.toObject(&state))->internalNumber();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertDate.h b/Source/WebCore/bindings/js/JSDOMConvertDate.h
new file mode 100644 (file)
index 0000000..4314de6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+JSC::JSValue jsDate(JSC::ExecState&, double value);
+double valueToDate(JSC::ExecState&, JSC::JSValue); // NaN if the value can't be converted to a date.
+
+template<> struct Converter<IDLDate> : DefaultConverter<IDLDate> {
+    static double convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return valueToDate(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLDate> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = false;
+
+    // FIXME: This should be taking a JSDOMGlobalObject and passing it to jsDate.
+    static JSC::JSValue convert(JSC::ExecState& state, double value)
+    {
+        return jsDate(state, value);
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertDictionary.h b/Source/WebCore/bindings/js/JSDOMConvertDictionary.h
new file mode 100644 (file)
index 0000000..19fceff
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+// Specialized by generated code for IDL dictionary conversion.
+template<typename T> T convertDictionary(JSC::ExecState&, JSC::JSValue);
+
+
+template<typename T> struct Converter<IDLDictionary<T>> : DefaultConverter<IDLDictionary<T>> {
+    using ReturnType = T;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return convertDictionary<T>(state, value);
+    }
+};
+
+template<typename T> struct JSConverter<IDLDictionary<T>> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const T& dictionary)
+    {
+        return convertDictionaryToJS(state, globalObject, dictionary);
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertEnumeration.h b/Source/WebCore/bindings/js/JSDOMConvertEnumeration.h
new file mode 100644 (file)
index 0000000..ec43133
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+// Specialized by generated code for IDL enumeration conversion.
+template<typename T> std::optional<T> parseEnumeration(JSC::ExecState&, JSC::JSValue);
+template<typename T> T convertEnumeration(JSC::ExecState&, JSC::JSValue);
+template<typename T> const char* expectedEnumerationValues();
+
+// Specialized by generated code for IDL enumeration conversion.
+template<typename T> JSC::JSString* convertEnumerationToJS(JSC::ExecState&, T);
+
+
+template<typename T> struct Converter<IDLEnumeration<T>> : DefaultConverter<IDLEnumeration<T>> {
+    static T convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return convertEnumeration<T>(state, value);
+    }
+};
+
+template<typename T> struct JSConverter<IDLEnumeration<T>> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(JSC::ExecState& exec, T value)
+    {
+        return convertEnumerationToJS(exec, value);
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertEventListener.h b/Source/WebCore/bindings/js/JSDOMConvertEventListener.h
new file mode 100644 (file)
index 0000000..e55f32c
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<typename T> struct Converter<IDLEventListener<T>> : DefaultConverter<IDLEventListener<T>> {
+    using ReturnType = RefPtr<T>;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject)
+    {
+        auto scope = DECLARE_THROW_SCOPE(state.vm());
+
+        auto listener = T::create(value, thisObject, false, currentWorld(&state));
+        if (!listener)
+            throwTypeError(&state, scope);
+    
+        return listener;
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertIndexedDB.h b/Source/WebCore/bindings/js/JSDOMConvertIndexedDB.h
new file mode 100644 (file)
index 0000000..8ee2287
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBBindingUtilities.h"
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<> struct JSConverter<IDLIDBKey> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    template <typename U>
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
+    {
+        return toJS(state, globalObject, std::forward<U>(value));
+    }
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/bindings/js/JSDOMConvertInterface.h b/Source/WebCore/bindings/js/JSDOMConvertInterface.h
new file mode 100644 (file)
index 0000000..6c0b5ee
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+#include "JSDOMExceptionHandling.h"
+
+namespace WebCore {
+
+template<typename ImplementationClass> struct JSDOMWrapperConverterTraits;
+
+template<typename T> struct Converter<IDLInterface<T>> : DefaultConverter<IDLInterface<T>> {
+    using ReturnType = typename JSDOMWrapperConverterTraits<T>::ToWrappedReturnType;
+    using WrapperType = typename JSDOMWrapperConverterTraits<T>::WrapperClass;
+
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
+    {
+        auto& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+        ReturnType object = WrapperType::toWrapped(vm, value);
+        if (UNLIKELY(!object))
+            exceptionThrower(state, scope);
+        return object;
+    }
+};
+
+namespace Detail {
+
+template <typename T> inline T* getPtrOrRef(const T* p) { return const_cast<T*>(p); }
+template <typename T> inline T& getPtrOrRef(const T& p) { return const_cast<T&>(p); }
+template <typename T> inline T* getPtrOrRef(const RefPtr<T>& p) { return p.get(); }
+template <typename T> inline T& getPtrOrRef(const Ref<T>& p) { return p.get(); }
+
+}
+
+template<typename T> struct JSConverter<IDLInterface<T>> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    template <typename U>
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const U& value)
+    {
+        return toJS(&state, &globalObject, Detail::getPtrOrRef(value));
+    }
+
+    template<typename U>
+    static JSC::JSValue convertNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
+    {
+        return toJSNewlyCreated(&state, &globalObject, std::forward<U>(value));
+    }
+};
+
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertJSON.h b/Source/WebCore/bindings/js/JSDOMConvertJSON.h
new file mode 100644 (file)
index 0000000..2f1b4d2
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+#include <runtime/JSONObject.h>
+
+namespace WebCore {
+
+template<> struct Converter<IDLJSON> : DefaultConverter<IDLJSON> {
+    static String convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return JSC::JSONStringify(&state, value, 0);
+    }
+};
+
+template<> struct JSConverter<IDLJSON> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(JSC::ExecState& state, const String& value)
+    {
+        return JSC::JSONParse(&state, value);
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertNull.h b/Source/WebCore/bindings/js/JSDOMConvertNull.h
new file mode 100644 (file)
index 0000000..262d751
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<> struct Converter<IDLNull> : DefaultConverter<IDLNull> {
+    static std::nullptr_t convert(JSC::ExecState&, JSC::JSValue)
+    {
+        return nullptr;
+    }
+};
+
+template<> struct JSConverter<IDLNull> {
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(std::nullptr_t)
+    {
+        return JSC::jsNull();
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertNullable.h b/Source/WebCore/bindings/js/JSDOMConvertNullable.h
new file mode 100644 (file)
index 0000000..c42c831
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertAny.h"
+#include "JSDOMConvertInterface.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+
+namespace WebCore {
+
+namespace Detail {
+
+template<typename IDLType>
+struct NullableConversionType;
+
+template<typename IDLType> 
+struct NullableConversionType {
+    using Type = typename IDLNullable<IDLType>::ImplementationType;
+};
+
+template<typename T>
+struct NullableConversionType<IDLInterface<T>> {
+    using Type = typename Converter<IDLInterface<T>>::ReturnType;
+};
+
+template<>
+struct NullableConversionType<IDLAny> {
+    using Type = typename Converter<IDLAny>::ReturnType;
+};
+
+}
+
+template<typename T> struct Converter<IDLNullable<T>> : DefaultConverter<IDLNullable<T>> {
+    using ReturnType = typename Detail::NullableConversionType<T>::Type;
+    
+    // 1. If Type(V) is not Object, and the conversion to an IDL value is being performed
+    // due to V being assigned to an attribute whose type is a nullable callback function
+    // that is annotated with [TreatNonObjectAsNull], then return the IDL nullable type T?
+    // value null.
+    //
+    // NOTE: Handled elsewhere.
+    //
+    // 2. Otherwise, if V is null or undefined, then return the IDL nullable type T? value null.
+    // 3. Otherwise, return the result of converting V using the rules for the inner IDL type T.
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
+        return Converter<T>::convert(state, value);
+    }
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject)
+    {
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
+        return Converter<T>::convert(state, value, thisObject);
+    }
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject)
+    {
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
+        return Converter<T>::convert(state, value, globalObject);
+    }
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration)
+    {
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
+        return Converter<T>::convert(state, value, configuration);
+    }
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration)
+    {
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
+        return Converter<T>::convert(state, value, configuration);
+    }
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower)
+    {
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
+        return Converter<T>::convert(state, value, std::forward<ExceptionThrower>(exceptionThrower));
+    }
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSC::JSObject& thisObject, ExceptionThrower&& exceptionThrower)
+    {
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
+        return Converter<T>::convert(state, value, thisObject, std::forward<ExceptionThrower>(exceptionThrower));
+    }
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower)
+    {
+        if (value.isUndefinedOrNull())
+            return T::nullValue();
+        return Converter<T>::convert(state, value, globalObject, std::forward<ExceptionThrower>(exceptionThrower));
+    }
+};
+
+template<typename T> struct JSConverter<IDLNullable<T>> {
+    using ImplementationType = typename IDLNullable<T>::ImplementationType;
+
+    static constexpr bool needsState = JSConverter<T>::needsState;
+    static constexpr bool needsGlobalObject = JSConverter<T>::needsGlobalObject;
+
+    template<typename U>
+    static JSC::JSValue convert(U&& value)
+    {
+        if (T::isNullValue(value))
+            return JSC::jsNull();
+        return JSConverter<T>::convert(T::extractValueFromNullable(value));
+    }
+    template<typename U>
+    static JSC::JSValue convert(JSC::ExecState& state, U&& value)
+    {
+        if (T::isNullValue(value))
+            return JSC::jsNull();
+        return JSConverter<T>::convert(state, T::extractValueFromNullable(value));
+    }
+    template<typename U>
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
+    {
+        if (T::isNullValue(value))
+            return JSC::jsNull();
+        return JSConverter<T>::convert(state, globalObject, T::extractValueFromNullable(value));
+    }
+
+    template<typename U>
+    static JSC::JSValue convertNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
+    {
+        if (T::isNullValue(value))
+            return JSC::jsNull();
+        return JSConverter<T>::convert(state, globalObject, T::extractValueFromNullable(value));
+    }
+};
+
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertNumbers.cpp b/Source/WebCore/bindings/js/JSDOMConvertNumbers.cpp
new file mode 100644 (file)
index 0000000..ff1f970
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004-2011, 2013, 2016 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ *  Copyright (C) 2013 Michael Pruett <michael@68k.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "JSDOMConvertNumbers.h"
+
+#include "JSDOMExceptionHandling.h"
+#include <heap/HeapInlines.h>
+#include <runtime/JSCJSValueInlines.h>
+#include <wtf/MathExtras.h>
+#include <wtf/text/WTFString.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+static const int32_t kMaxInt32 = 0x7fffffff;
+static const int32_t kMinInt32 = -kMaxInt32 - 1;
+static const uint32_t kMaxUInt32 = 0xffffffffU;
+static const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, largest integer exactly representable in ECMAScript.
+
+static String rangeErrorString(double value, double min, double max)
+{
+    return makeString("Value ", String::numberToStringECMAScript(value), " is outside the range [", String::numberToStringECMAScript(min), ", ", String::numberToStringECMAScript(max), "]");
+}
+
+static double enforceRange(ExecState& state, double x, double minimum, double maximum)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (std::isnan(x) || std::isinf(x)) {
+        throwTypeError(&state, scope, rangeErrorString(x, minimum, maximum));
+        return 0;
+    }
+    x = trunc(x);
+    if (x < minimum || x > maximum) {
+        throwTypeError(&state, scope, rangeErrorString(x, minimum, maximum));
+        return 0;
+    }
+    return x;
+}
+
+template <typename T>
+struct IntTypeLimits {
+};
+
+template <>
+struct IntTypeLimits<int8_t> {
+    static const int8_t minValue = -128;
+    static const int8_t maxValue = 127;
+    static const unsigned numberOfValues = 256; // 2^8
+};
+
+template <>
+struct IntTypeLimits<uint8_t> {
+    static const uint8_t maxValue = 255;
+    static const unsigned numberOfValues = 256; // 2^8
+};
+
+template <>
+struct IntTypeLimits<int16_t> {
+    static const short minValue = -32768;
+    static const short maxValue = 32767;
+    static const unsigned numberOfValues = 65536; // 2^16
+};
+
+template <>
+struct IntTypeLimits<uint16_t> {
+    static const unsigned short maxValue = 65535;
+    static const unsigned numberOfValues = 65536; // 2^16
+};
+
+template <typename T>
+static inline T toSmallerInt(ExecState& state, JSValue value, IntegerConversionConfiguration configuration)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    static_assert(std::is_signed<T>::value && std::is_integral<T>::value, "Should only be used for signed integral types");
+
+    typedef IntTypeLimits<T> LimitsTrait;
+    // Fast path if the value is already a 32-bit signed integer in the right range.
+    if (value.isInt32()) {
+        int32_t d = value.asInt32();
+        if (d >= LimitsTrait::minValue && d <= LimitsTrait::maxValue)
+            return static_cast<T>(d);
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            throwTypeError(&state, scope);
+            return 0;
+        case IntegerConversionConfiguration::Clamp:
+            return d < LimitsTrait::minValue ? LimitsTrait::minValue : LimitsTrait::maxValue;
+        }
+        d %= LimitsTrait::numberOfValues;
+        return static_cast<T>(d > LimitsTrait::maxValue ? d - LimitsTrait::numberOfValues : d);
+    }
+
+    double x = value.toNumber(&state);
+    RETURN_IF_EXCEPTION(scope, 0);
+
+    switch (configuration) {
+    case IntegerConversionConfiguration::Normal:
+        break;
+    case IntegerConversionConfiguration::EnforceRange:
+        return enforceRange(state, x, LimitsTrait::minValue, LimitsTrait::maxValue);
+    case IntegerConversionConfiguration::Clamp:
+        return std::isnan(x) ? 0 : clampTo<T>(x);
+    }
+
+    if (std::isnan(x) || std::isinf(x) || !x)
+        return 0;
+
+    x = x < 0 ? -floor(fabs(x)) : floor(fabs(x));
+    x = fmod(x, LimitsTrait::numberOfValues);
+
+    return static_cast<T>(x > LimitsTrait::maxValue ? x - LimitsTrait::numberOfValues : x);
+}
+
+template <typename T>
+static inline T toSmallerUInt(ExecState& state, JSValue value, IntegerConversionConfiguration configuration)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    static_assert(std::is_unsigned<T>::value && std::is_integral<T>::value, "Should only be used for unsigned integral types");
+
+    typedef IntTypeLimits<T> LimitsTrait;
+    // Fast path if the value is already a 32-bit unsigned integer in the right range.
+    if (value.isUInt32()) {
+        uint32_t d = value.asUInt32();
+        if (d <= LimitsTrait::maxValue)
+            return static_cast<T>(d);
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            return static_cast<T>(d);
+        case IntegerConversionConfiguration::EnforceRange:
+            throwTypeError(&state, scope);
+            return 0;
+        case IntegerConversionConfiguration::Clamp:
+            return LimitsTrait::maxValue;
+        }
+    }
+
+    double x = value.toNumber(&state);
+    RETURN_IF_EXCEPTION(scope, 0);
+
+    switch (configuration) {
+    case IntegerConversionConfiguration::Normal:
+        break;
+    case IntegerConversionConfiguration::EnforceRange:
+        return enforceRange(state, x, 0, LimitsTrait::maxValue);
+    case IntegerConversionConfiguration::Clamp:
+        return std::isnan(x) ? 0 : clampTo<T>(x);
+    }
+
+    if (std::isnan(x) || std::isinf(x) || !x)
+        return 0;
+
+    x = x < 0 ? -floor(fabs(x)) : floor(fabs(x));
+    return static_cast<T>(fmod(x, LimitsTrait::numberOfValues));
+}
+
+int8_t toInt8EnforceRange(JSC::ExecState& state, JSValue value)
+{
+    return toSmallerInt<int8_t>(state, value, IntegerConversionConfiguration::EnforceRange);
+}
+
+uint8_t toUInt8EnforceRange(JSC::ExecState& state, JSValue value)
+{
+    return toSmallerUInt<uint8_t>(state, value, IntegerConversionConfiguration::EnforceRange);
+}
+
+int8_t toInt8Clamp(JSC::ExecState& state, JSValue value)
+{
+    return toSmallerInt<int8_t>(state, value, IntegerConversionConfiguration::Clamp);
+}
+
+uint8_t toUInt8Clamp(JSC::ExecState& state, JSValue value)
+{
+    return toSmallerUInt<uint8_t>(state, value, IntegerConversionConfiguration::Clamp);
+}
+
+// http://www.w3.org/TR/WebIDL/#es-byte
+int8_t toInt8(ExecState& state, JSValue value)
+{
+    return toSmallerInt<int8_t>(state, value, IntegerConversionConfiguration::Normal);
+}
+
+// http://www.w3.org/TR/WebIDL/#es-octet
+uint8_t toUInt8(ExecState& state, JSValue value)
+{
+    return toSmallerUInt<uint8_t>(state, value, IntegerConversionConfiguration::Normal);
+}
+
+int16_t toInt16EnforceRange(ExecState& state, JSValue value)
+{
+    return toSmallerInt<int16_t>(state, value, IntegerConversionConfiguration::EnforceRange);
+}
+
+uint16_t toUInt16EnforceRange(ExecState& state, JSValue value)
+{
+    return toSmallerUInt<uint16_t>(state, value, IntegerConversionConfiguration::EnforceRange);
+}
+
+int16_t toInt16Clamp(ExecState& state, JSValue value)
+{
+    return toSmallerInt<int16_t>(state, value, IntegerConversionConfiguration::Clamp);
+}
+
+uint16_t toUInt16Clamp(ExecState& state, JSValue value)
+{
+    return toSmallerUInt<uint16_t>(state, value, IntegerConversionConfiguration::Clamp);
+}
+
+// http://www.w3.org/TR/WebIDL/#es-short
+int16_t toInt16(ExecState& state, JSValue value)
+{
+    return toSmallerInt<int16_t>(state, value, IntegerConversionConfiguration::Normal);
+}
+
+// http://www.w3.org/TR/WebIDL/#es-unsigned-short
+uint16_t toUInt16(ExecState& state, JSValue value)
+{
+    return toSmallerUInt<uint16_t>(state, value, IntegerConversionConfiguration::Normal);
+}
+
+// http://www.w3.org/TR/WebIDL/#es-long
+int32_t toInt32EnforceRange(ExecState& state, JSValue value)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (value.isInt32())
+        return value.asInt32();
+
+    double x = value.toNumber(&state);
+    RETURN_IF_EXCEPTION(scope, 0);
+    return enforceRange(state, x, kMinInt32, kMaxInt32);
+}
+
+int32_t toInt32Clamp(ExecState& state, JSValue value)
+{
+    if (value.isInt32())
+        return value.asInt32();
+
+    double x = value.toNumber(&state);
+    return std::isnan(x) ? 0 : clampTo<int32_t>(x);
+}
+
+uint32_t toUInt32Clamp(ExecState& state, JSValue value)
+{
+    if (value.isUInt32())
+        return value.asUInt32();
+
+    double x = value.toNumber(&state);
+    return std::isnan(x) ? 0 : clampTo<uint32_t>(x);
+}
+
+// http://www.w3.org/TR/WebIDL/#es-unsigned-long
+uint32_t toUInt32EnforceRange(ExecState& state, JSValue value)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (value.isUInt32())
+        return value.asUInt32();
+
+    double x = value.toNumber(&state);
+    RETURN_IF_EXCEPTION(scope, 0);
+    return enforceRange(state, x, 0, kMaxUInt32);
+}
+
+int64_t toInt64EnforceRange(ExecState& state, JSC::JSValue value)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    double x = value.toNumber(&state);
+    RETURN_IF_EXCEPTION(scope, 0);
+    return enforceRange(state, x, -kJSMaxInteger, kJSMaxInteger);
+}
+
+uint64_t toUInt64EnforceRange(ExecState& state, JSC::JSValue value)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    double x = value.toNumber(&state);
+    RETURN_IF_EXCEPTION(scope, 0);
+    return enforceRange(state, x, 0, kJSMaxInteger);
+}
+
+int64_t toInt64Clamp(ExecState& state, JSC::JSValue value)
+{
+    double x = value.toNumber(&state);
+    return std::isnan(x) ? 0 : static_cast<int64_t>(std::min<double>(std::max<double>(x, -kJSMaxInteger), kJSMaxInteger));
+}
+
+uint64_t toUInt64Clamp(ExecState& state, JSC::JSValue value)
+{
+    double x = value.toNumber(&state);
+    return std::isnan(x) ? 0 : static_cast<uint64_t>(std::min<double>(std::max<double>(x, 0), kJSMaxInteger));
+}
+
+// http://www.w3.org/TR/WebIDL/#es-long-long
+int64_t toInt64(ExecState& state, JSValue value)
+{
+    double x = value.toNumber(&state);
+
+    // Map NaNs and +/-Infinity to 0; convert finite values modulo 2^64.
+    unsigned long long n;
+    doubleToInteger(x, n);
+    return n;
+}
+
+// http://www.w3.org/TR/WebIDL/#es-unsigned-long-long
+uint64_t toUInt64(ExecState& state, JSValue value)
+{
+    double x = value.toNumber(&state);
+
+    // Map NaNs and +/-Infinity to 0; convert finite values modulo 2^64.
+    unsigned long long n;
+    doubleToInteger(x, n);
+    return n;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertNumbers.h b/Source/WebCore/bindings/js/JSDOMConvertNumbers.h
new file mode 100644 (file)
index 0000000..d60dd2a
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+#include "JSDOMExceptionHandling.h"
+
+namespace WebCore {
+
+enum class IntegerConversionConfiguration { Normal, EnforceRange, Clamp };
+
+template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, IntegerConversionConfiguration);
+
+template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration)
+{
+    return Converter<T>::convert(state, value, configuration);
+}
+
+// The following functions convert values to integers as per the WebIDL specification.
+// The conversion fails if the value cannot be converted to a number or, if EnforceRange is specified,
+// the value is outside the range of the destination integer type.
+
+WEBCORE_EXPORT int8_t toInt8EnforceRange(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint8_t toUInt8EnforceRange(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT int16_t toInt16EnforceRange(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint16_t toUInt16EnforceRange(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT int32_t toInt32EnforceRange(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint32_t toUInt32EnforceRange(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT int64_t toInt64EnforceRange(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint64_t toUInt64EnforceRange(JSC::ExecState&, JSC::JSValue);
+
+WEBCORE_EXPORT int8_t toInt8Clamp(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint8_t toUInt8Clamp(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT int16_t toInt16Clamp(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint16_t toUInt16Clamp(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT int32_t toInt32Clamp(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint32_t toUInt32Clamp(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT int64_t toInt64Clamp(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint64_t toUInt64Clamp(JSC::ExecState&, JSC::JSValue);
+
+WEBCORE_EXPORT int8_t toInt8(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint8_t toUInt8(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT int16_t toInt16(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint16_t toUInt16(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT int64_t toInt64(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT uint64_t toUInt64(JSC::ExecState&, JSC::JSValue);
+
+
+// MARK: -
+// MARK: Integer types
+
+template<> struct Converter<IDLByte> : DefaultConverter<IDLByte> {
+    static int8_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
+    {
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            return toInt8EnforceRange(state, value);
+        case IntegerConversionConfiguration::Clamp:
+            return toInt8Clamp(state, value);
+        }
+        return toInt8(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLByte> {
+    using Type = typename IDLByte::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLOctet> : DefaultConverter<IDLOctet> {
+    static uint8_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
+    {
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            return toUInt8EnforceRange(state, value);
+        case IntegerConversionConfiguration::Clamp:
+            return toUInt8Clamp(state, value);
+        }
+        return toUInt8(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLOctet> {
+    using Type = typename IDLOctet::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLShort> : DefaultConverter<IDLShort> {
+    static int16_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
+    {
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            return toInt16EnforceRange(state, value);
+        case IntegerConversionConfiguration::Clamp:
+            return toInt16Clamp(state, value);
+        }
+        return toInt16(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLShort> {
+    using Type = typename IDLShort::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLUnsignedShort> : DefaultConverter<IDLUnsignedShort> {
+    static uint16_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
+    {
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            return toUInt16EnforceRange(state, value);
+        case IntegerConversionConfiguration::Clamp:
+            return toUInt16Clamp(state, value);
+        }
+        return toUInt16(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLUnsignedShort> {
+    using Type = typename IDLUnsignedShort::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLLong> : DefaultConverter<IDLLong> {
+    static inline int32_t convert(JSC::ExecState&, JSC::ThrowScope&, double number)
+    {
+        return JSC::toInt32(number);
+    }
+
+    static int32_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
+    {
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            return toInt32EnforceRange(state, value);
+        case IntegerConversionConfiguration::Clamp:
+            return toInt32Clamp(state, value);
+        }
+        return value.toInt32(&state);
+    }
+};
+
+template<> struct JSConverter<IDLLong> {
+    using Type = typename IDLLong::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLUnsignedLong> : DefaultConverter<IDLUnsignedLong> {
+    static uint32_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
+    {
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            return toUInt32EnforceRange(state, value);
+        case IntegerConversionConfiguration::Clamp:
+            return toUInt32Clamp(state, value);
+        }
+        return value.toUInt32(&state);
+    }
+};
+
+template<> struct JSConverter<IDLUnsignedLong> {
+    using Type = typename IDLUnsignedLong::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLLongLong> : DefaultConverter<IDLLongLong> {
+    static int64_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
+    {
+        if (value.isInt32())
+            return value.asInt32();
+
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            return toInt64EnforceRange(state, value);
+        case IntegerConversionConfiguration::Clamp:
+            return toInt64Clamp(state, value);
+        }
+        return toInt64(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLLongLong> {
+    using Type = typename IDLLongLong::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLUnsignedLongLong> : DefaultConverter<IDLUnsignedLongLong> {
+    static uint64_t convert(JSC::ExecState& state, JSC::JSValue value, IntegerConversionConfiguration configuration = IntegerConversionConfiguration::Normal)
+    {
+        if (value.isUInt32())
+            return value.asUInt32();
+
+        switch (configuration) {
+        case IntegerConversionConfiguration::Normal:
+            break;
+        case IntegerConversionConfiguration::EnforceRange:
+            return toUInt64EnforceRange(state, value);
+        case IntegerConversionConfiguration::Clamp:
+            return toUInt64Clamp(state, value);
+        }
+        return toUInt64(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLUnsignedLongLong> {
+    using Type = typename IDLUnsignedLongLong::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+// MARK: -
+// MARK: Floating point types
+
+template<> struct Converter<IDLFloat> : DefaultConverter<IDLFloat> {
+
+    static inline float convert(JSC::ExecState& state, JSC::ThrowScope& scope, double number)
+    {
+        if (UNLIKELY(!std::isfinite(number)))
+            throwNonFiniteTypeError(state, scope);
+        return static_cast<float>(number);
+    }
+
+    static float convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+        double number = value.toNumber(&state);
+        if (UNLIKELY(!std::isfinite(number)))
+            throwNonFiniteTypeError(state, scope);
+        return static_cast<float>(number);
+    }
+};
+
+template<> struct JSConverter<IDLFloat> {
+    using Type = typename IDLFloat::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLUnrestrictedFloat> : DefaultConverter<IDLUnrestrictedFloat> {
+    static inline float convert(JSC::ExecState&, JSC::ThrowScope&, double number)
+    {
+        return static_cast<float>(number);
+    }
+
+    static float convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return static_cast<float>(value.toNumber(&state));
+    }
+};
+
+template<> struct JSConverter<IDLUnrestrictedFloat> {
+    using Type = typename IDLUnrestrictedFloat::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLDouble> : DefaultConverter<IDLDouble> {
+    static inline double convert(JSC::ExecState& state, JSC::ThrowScope& scope, double number)
+    {
+        if (UNLIKELY(!std::isfinite(number)))
+            throwNonFiniteTypeError(state, scope);
+        return number;
+    }
+
+    static double convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+        double number = value.toNumber(&state);
+        if (UNLIKELY(!std::isfinite(number)))
+            throwNonFiniteTypeError(state, scope);
+        return number;
+    }
+};
+
+template<> struct JSConverter<IDLDouble> {
+    using Type = typename IDLDouble::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+};
+
+template<> struct Converter<IDLUnrestrictedDouble> : DefaultConverter<IDLUnrestrictedDouble> {
+    static inline double convert(JSC::ExecState&, JSC::ThrowScope&, double number)
+    {
+        return number;
+    }
+
+    static double convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return value.toNumber(&state);
+    }
+};
+
+template<> struct JSConverter<IDLUnrestrictedDouble> {
+    using Type = typename IDLUnrestrictedDouble::ImplementationType;
+
+    static constexpr bool needsState = false;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(Type value)
+    {
+        return JSC::jsNumber(value);
+    }
+
+    // Add overload for MediaTime.
+    static JSC::JSValue convert(MediaTime value)
+    {
+        return JSC::jsNumber(value.toDouble());
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertObject.h b/Source/WebCore/bindings/js/JSDOMConvertObject.h
new file mode 100644 (file)
index 0000000..379eb42
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<> struct Converter<IDLObject> : DefaultConverter<IDLObject> {
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static JSC::Strong<JSC::JSObject> convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        if (!value.isObject()) {
+            exceptionThrower(state, scope);
+            return { };
+        }
+        
+        return { vm, JSC::asObject(value) };
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertRecord.h b/Source/WebCore/bindings/js/JSDOMConvertRecord.h
new file mode 100644 (file)
index 0000000..db1dabf
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertStrings.h"
+#include <runtime/ObjectConstructor.h>
+
+namespace WebCore {
+
+namespace Detail {
+
+template<typename IDLStringType>
+struct IdentifierConverter;
+
+template<> struct IdentifierConverter<IDLDOMString> {
+    static String convert(JSC::ExecState&, const JSC::Identifier& identifier)
+    {
+        return identifier.string();
+    }
+};
+
+template<> struct IdentifierConverter<IDLByteString> {
+    static String convert(JSC::ExecState& state, const JSC::Identifier& identifier)
+    {
+        return identifierToByteString(state, identifier);
+    }
+};
+
+template<> struct IdentifierConverter<IDLUSVString> {
+    static String convert(JSC::ExecState& state, const JSC::Identifier& identifier)
+    {
+        return identifierToUSVString(state, identifier);
+    }
+};
+
+}
+
+template<typename K, typename V> struct Converter<IDLRecord<K, V>> : DefaultConverter<IDLRecord<K, V>> {
+    using ReturnType = typename IDLRecord<K, V>::ImplementationType;
+    using KeyType = typename K::ImplementationType;
+    using ValueType = typename V::ImplementationType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        auto& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        // 1. Let result be a new empty instance of record<K, V>.
+        // 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(&state, scope);
+            return { };
+        }
+        
+        JSC::JSObject* object = JSC::asObject(value);
+    
+        ReturnType result;
+    
+        // 4. Let keys be ? O.[[OwnPropertyKeys]]().
+        JSC::PropertyNameArray keys(&vm, JSC::PropertyNameMode::Strings);
+        object->getOwnPropertyNames(object, &state, keys, JSC::EnumerationMode());
+        RETURN_IF_EXCEPTION(scope, { });
+
+        // 5. Repeat, for each element key of keys in List order:
+        for (auto& key : keys) {
+            // 1. Let desc be ? O.[[GetOwnProperty]](key).
+            JSC::PropertyDescriptor descriptor;
+            bool didGetDescriptor = object->getOwnPropertyDescriptor(&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() && descriptor.enumerable()) {
+                // 1. Let typedKey be key converted to an IDL value of type K.
+                auto typedKey = Detail::IdentifierConverter<K>::convert(state, key);
+
+                // 2. Let value be ? Get(O, key).
+                auto subValue = object->get(&state, key);
+                RETURN_IF_EXCEPTION(scope, { });
+
+                // 3. Let typedValue be value converted to an IDL value of type V.
+                auto typedValue = Converter<V>::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.
+                // FIXME: Handle this case.
+                
+                // 5. Otherwise, append to result a mapping (typedKey, typedValue).
+                result.append({ typedKey, typedValue });
+            }
+        }
+
+        // 6. Return result.
+        return result;
+    }
+};
+
+template<typename K, typename V> struct JSConverter<IDLRecord<K, V>> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    template<typename MapType>
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const MapType& map)
+    {
+        auto& vm = state.vm();
+    
+        // 1. Let result be ! ObjectCreate(%ObjectPrototype%).
+        auto result = constructEmptyObject(&state);
+        
+        // 2. Repeat, for each mapping (key, value) in D:
+        for (const auto& 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<V>(state, globalObject, keyValuePair.value);
+
+            // 3. Let created be ! CreateDataProperty(result, esKey, esValue).
+            bool created = result->putDirect(vm, JSC::Identifier::fromString(&vm, keyValuePair.key), esValue);
+
+            // 4. Assert: created is true.
+            ASSERT_UNUSED(created, created);
+        }
+
+        // 3. Return result.
+        return result;
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertSequences.h b/Source/WebCore/bindings/js/JSDOMConvertSequences.h
new file mode 100644 (file)
index 0000000..f42f459
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+#include <runtime/IteratorOperations.h>
+#include <runtime/JSArray.h>
+#include <runtime/JSGlobalObjectInlines.h>
+
+namespace WebCore {
+
+namespace Detail {
+
+template<typename IDLType>
+struct GenericSequenceConverter {
+    using ReturnType = Vector<typename IDLType::ImplementationType>;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSObject* jsObject)
+    {
+        ReturnType result;
+        forEachInIterable(&state, jsObject, [&result](JSC::VM& vm, JSC::ExecState* state, JSC::JSValue jsValue) {
+            auto scope = DECLARE_THROW_SCOPE(vm);
+
+            auto convertedValue = Converter<IDLType>::convert(*state, jsValue);
+            if (UNLIKELY(scope.exception()))
+                return;
+            result.append(WTFMove(convertedValue));
+        });
+        return result;
+    }
+};
+
+// Specialization for numeric types
+// FIXME: This is only implemented for the IDLFloatingPointTypes and IDLLong. To add
+// support for more numeric types, add an overload of Converter<IDLType>::convert that
+// takes an ExecState, ThrowScope, double as its arguments.
+template<typename IDLType>
+struct NumericSequenceConverter {
+    using GenericConverter = GenericSequenceConverter<IDLType>;
+    using ReturnType = typename GenericConverter::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        auto& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        if (!value.isObject()) {
+            throwSequenceTypeError(state, scope);
+            return { };
+        }
+
+        JSC::JSObject* object = JSC::asObject(value);
+        if (!JSC::isJSArray(object))
+            return GenericConverter::convert(state, object);
+
+        JSC::JSArray* array = JSC::asArray(object);
+        if (!array->globalObject()->isArrayIteratorProtocolFastAndNonObservable())
+            return GenericConverter::convert(state, object);
+
+        unsigned length = array->length();
+
+        ReturnType result;
+        if (!result.tryReserveCapacity(length)) {
+            // FIXME: Is the right exception to throw?
+            throwTypeError(&state, scope);
+            return { };
+        }
+
+        JSC::IndexingType indexingType = array->indexingType() & JSC::IndexingShapeMask;
+
+        if (indexingType == JSC::ContiguousShape) {
+            for (unsigned i = 0; i < length; i++) {
+                auto indexValue = array->butterfly()->contiguous()[i].get();
+                if (!indexValue)
+                    result.uncheckedAppend(0);
+                else {
+                    auto convertedValue = Converter<IDLType>::convert(state, indexValue);
+                    RETURN_IF_EXCEPTION(scope, { });
+
+                    result.uncheckedAppend(convertedValue);
+                }
+            }
+            return result;
+        }
+        
+        if (indexingType == JSC::Int32Shape) {
+            for (unsigned i = 0; i < length; i++) {
+                auto indexValue = array->butterfly()->contiguousInt32()[i].get();
+                ASSERT(!indexValue || indexValue.isInt32());
+                if (!indexValue)
+                    result.uncheckedAppend(0);
+                else
+                    result.uncheckedAppend(indexValue.asInt32());
+            }
+            return result;
+        }
+
+        if (indexingType == JSC::DoubleShape) {
+            for (unsigned i = 0; i < length; i++) {
+                auto doubleValue = array->butterfly()->contiguousDouble()[i];
+                if (std::isnan(doubleValue))
+                    result.uncheckedAppend(0);
+                else {
+                    auto convertedValue = Converter<IDLType>::convert(state, scope, doubleValue);
+                    RETURN_IF_EXCEPTION(scope, { });
+
+                    result.uncheckedAppend(convertedValue);
+                }
+            }
+            return result;
+        }
+
+        for (unsigned i = 0; i < length; i++) {
+            auto indexValue = array->getDirectIndex(&state, i);
+            RETURN_IF_EXCEPTION(scope, { });
+            
+            if (!indexValue)
+                result.uncheckedAppend(0);
+            else {
+                auto convertedValue = Converter<IDLType>::convert(state, indexValue);
+                RETURN_IF_EXCEPTION(scope, { });
+                
+                result.uncheckedAppend(convertedValue);
+            }
+        }
+        return result;
+    }
+};
+
+template<typename IDLType>
+struct SequenceConverter {
+    using GenericConverter = GenericSequenceConverter<IDLType>;
+    using ReturnType = typename GenericConverter::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        auto& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        if (!value.isObject()) {
+            throwSequenceTypeError(state, scope);
+            return { };
+        }
+
+        JSC::JSObject* object = JSC::asObject(value);
+        if (!JSC::isJSArray(object))
+            return GenericConverter::convert(state, object);
+
+        JSC::JSArray* array = JSC::asArray(object);
+        if (!array->globalObject()->isArrayIteratorProtocolFastAndNonObservable())
+            return GenericConverter::convert(state, object);
+
+        unsigned length = array->length();
+
+        ReturnType result;
+        if (!result.tryReserveCapacity(length)) {
+            // FIXME: Is the right exception to throw?
+            throwTypeError(&state, scope);
+            return { };
+        }
+
+        JSC::IndexingType indexingType = array->indexingType() & JSC::IndexingShapeMask;
+
+        if (indexingType == JSC::ContiguousShape) {
+            for (unsigned i = 0; i < length; i++) {
+                auto indexValue = array->butterfly()->contiguous()[i].get();
+                if (!indexValue)
+                    indexValue = JSC::jsUndefined();
+
+                auto convertedValue = Converter<IDLType>::convert(state, indexValue);
+                RETURN_IF_EXCEPTION(scope, { });
+
+                result.uncheckedAppend(convertedValue);
+            }
+            return result;
+        }
+
+        for (unsigned i = 0; i < length; i++) {
+            auto indexValue = array->getDirectIndex(&state, i);
+            RETURN_IF_EXCEPTION(scope, { });
+
+            if (!indexValue)
+                indexValue = JSC::jsUndefined();
+
+            auto convertedValue = Converter<IDLType>::convert(state, indexValue);
+            RETURN_IF_EXCEPTION(scope, { });
+            
+            result.uncheckedAppend(convertedValue);
+        }
+        return result;
+    }
+};
+
+template<>
+struct SequenceConverter<IDLLong> {
+    using ReturnType = typename GenericSequenceConverter<IDLLong>::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return NumericSequenceConverter<IDLLong>::convert(state, value);
+    }
+};
+
+template<>
+struct SequenceConverter<IDLFloat> {
+    using ReturnType = typename GenericSequenceConverter<IDLFloat>::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return NumericSequenceConverter<IDLFloat>::convert(state, value);
+    }
+};
+
+template<>
+struct SequenceConverter<IDLUnrestrictedFloat> {
+    using ReturnType = typename GenericSequenceConverter<IDLUnrestrictedFloat>::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return NumericSequenceConverter<IDLUnrestrictedFloat>::convert(state, value);
+    }
+};
+
+template<>
+struct SequenceConverter<IDLDouble> {
+    using ReturnType = typename GenericSequenceConverter<IDLDouble>::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return NumericSequenceConverter<IDLDouble>::convert(state, value);
+    }
+};
+
+template<>
+struct SequenceConverter<IDLUnrestrictedDouble> {
+    using ReturnType = typename GenericSequenceConverter<IDLUnrestrictedDouble>::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return NumericSequenceConverter<IDLUnrestrictedDouble>::convert(state, value);
+    }
+};
+
+}
+
+template<typename T> struct Converter<IDLSequence<T>> : DefaultConverter<IDLSequence<T>> {
+    using ReturnType = typename Detail::SequenceConverter<T>::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return Detail::SequenceConverter<T>::convert(state, value);
+    }
+};
+
+template<typename T> struct JSConverter<IDLSequence<T>> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    template<typename U, size_t inlineCapacity>
+    static JSC::JSValue convert(JSC::ExecState& exec, JSDOMGlobalObject& globalObject, const Vector<U, inlineCapacity>& vector)
+    {
+        JSC::MarkedArgumentBuffer list;
+        for (auto& element : vector)
+            list.append(toJS<T>(exec, globalObject, element));
+        return JSC::constructArray(&exec, nullptr, &globalObject, list);
+    }
+};
+
+template<typename T> struct Converter<IDLFrozenArray<T>> : DefaultConverter<IDLFrozenArray<T>> {
+    using ReturnType = typename Detail::SequenceConverter<T>::ReturnType;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return Detail::SequenceConverter<T>::convert(state, value);
+    }
+};
+
+template<typename T> struct JSConverter<IDLFrozenArray<T>> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    template<typename U, size_t inlineCapacity>
+    static JSC::JSValue convert(JSC::ExecState& exec, JSDOMGlobalObject& globalObject, const Vector<U, inlineCapacity>& vector)
+    {
+        JSC::MarkedArgumentBuffer list;
+        for (auto& element : vector)
+            list.append(toJS<T>(exec, globalObject, element));
+        auto* array = JSC::constructArray(&exec, nullptr, &globalObject, list);
+        return JSC::objectConstructorFreeze(&exec, array);
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertSerializedScriptValue.h b/Source/WebCore/bindings/js/JSDOMConvertSerializedScriptValue.h
new file mode 100644 (file)
index 0000000..10b69f9
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertStrings.h"
+
+namespace WebCore {
+
+template<typename T> struct Converter<IDLSerializedScriptValue<T>> : DefaultConverter<IDLSerializedScriptValue<T>> {
+    static RefPtr<T> convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return T::create(state, value);
+    }
+};
+
+template<typename T> struct JSConverter<IDLSerializedScriptValue<T>> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, RefPtr<T> value)
+    {
+        return value ? value->deserialize(state, &globalObject) : JSC::jsNull();
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertStrings.cpp b/Source/WebCore/bindings/js/JSDOMConvertStrings.cpp
new file mode 100644 (file)
index 0000000..6c95f66
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004-2011, 2013, 2016 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ *  Copyright (C) 2013 Michael Pruett <michael@68k.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "JSDOMConvertStrings.h"
+
+#include "JSDOMExceptionHandling.h"
+#include <heap/HeapInlines.h>
+#include <runtime/JSCJSValueInlines.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/unicode/CharacterNames.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+static inline String stringToByteString(ExecState& state, JSC::ThrowScope& scope, String&& string)
+{
+    if (!string.containsOnlyLatin1()) {
+        throwTypeError(&state, scope);
+        return { };
+    }
+
+    return string;
+}
+
+String identifierToByteString(ExecState& state, const Identifier& identifier)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto string = identifier.string();
+    return stringToByteString(state, scope, WTFMove(string));
+}
+
+String valueToByteString(ExecState& state, JSValue value)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto string = value.toWTFString(&state);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    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&& string)
+{
+    // Fast path for the case where there are no unpaired surrogates.
+    if (!hasUnpairedSurrogate(string))
+        return string;
+
+    // Slow path: http://heycam.github.io/webidl/#dfn-obtain-unicode
+    // Replaces unpaired surrogates with the replacement character.
+    StringBuilder result;
+    result.reserveCapacity(string.length());
+    StringView view { string };
+    for (auto codePoint : view.codePoints()) {
+        if (U_IS_SURROGATE(codePoint))
+            result.append(replacementCharacter);
+        else
+            result.append(codePoint);
+    }
+    return result.toString();
+}
+
+String identifierToUSVString(ExecState&, const Identifier& identifier)
+{
+    auto string = identifier.string();
+    return stringToUSVString(WTFMove(string));
+}
+
+String valueToUSVString(ExecState& state, JSValue value)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto string = value.toWTFString(&state);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    return stringToUSVString(WTFMove(string));
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertStrings.h b/Source/WebCore/bindings/js/JSDOMConvertStrings.h
new file mode 100644 (file)
index 0000000..a836a3d
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+#include "JSDOMExceptionHandling.h"
+
+namespace WebCore {
+
+enum class StringConversionConfiguration { Normal, TreatNullAsEmptyString };
+
+template<typename T> typename Converter<T>::ReturnType convert(JSC::ExecState&, JSC::JSValue, StringConversionConfiguration);
+
+template<typename T> inline typename Converter<T>::ReturnType convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration)
+{
+    return Converter<T>::convert(state, value, configuration);
+}
+
+WEBCORE_EXPORT String identifierToByteString(JSC::ExecState&, const JSC::Identifier&);
+WEBCORE_EXPORT String valueToByteString(JSC::ExecState&, JSC::JSValue);
+WEBCORE_EXPORT String identifierToUSVString(JSC::ExecState&, const JSC::Identifier&);
+WEBCORE_EXPORT String valueToUSVString(JSC::ExecState&, JSC::JSValue);
+
+// MARK: -
+// MARK: String types
+
+template<> struct Converter<IDLDOMString> : DefaultConverter<IDLDOMString> {
+    static String convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration = StringConversionConfiguration::Normal)
+    {
+        if (configuration == StringConversionConfiguration::TreatNullAsEmptyString && value.isNull())
+            return emptyString();
+        return value.toWTFString(&state);
+    }
+};
+
+template<> struct JSConverter<IDLDOMString> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(JSC::ExecState& state, const String& value)
+    {
+        return JSC::jsStringWithCache(&state, value);
+    }
+};
+
+template<> struct Converter<IDLByteString> : DefaultConverter<IDLByteString> {
+    static String convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration = StringConversionConfiguration::Normal)
+    {
+        if (configuration == StringConversionConfiguration::TreatNullAsEmptyString && value.isNull())
+            return emptyString();
+        return valueToByteString(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLByteString> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(JSC::ExecState& state, const String& value)
+    {
+        return JSC::jsStringWithCache(&state, value);
+    }
+};
+
+template<> struct Converter<IDLUSVString> : DefaultConverter<IDLUSVString> {
+    static String convert(JSC::ExecState& state, JSC::JSValue value, StringConversionConfiguration configuration = StringConversionConfiguration::Normal)
+    {
+        if (configuration == StringConversionConfiguration::TreatNullAsEmptyString && value.isNull())
+            return emptyString();
+        return valueToUSVString(state, value);
+    }
+};
+
+template<> struct JSConverter<IDLUSVString> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = false;
+
+    static JSC::JSValue convert(JSC::ExecState& state, const String& value)
+    {
+        return JSC::jsStringWithCache(&state, value);
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertUnion.h b/Source/WebCore/bindings/js/JSDOMConvertUnion.h
new file mode 100644 (file)
index 0000000..7c40d7f
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<typename ReturnType, typename T, bool enabled>
+struct ConditionalConverter;
+
+template<typename ReturnType, typename T>
+struct ConditionalConverter<ReturnType, T, true> {
+    static std::optional<ReturnType> convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        return ReturnType(Converter<T>::convert(state, value));
+    }
+};
+
+template<typename ReturnType, typename T>
+struct ConditionalConverter<ReturnType, T, false> {
+    static std::optional<ReturnType> convert(JSC::ExecState&, JSC::JSValue)
+    {
+        return std::nullopt;
+    }
+};
+
+namespace Detail {
+
+template<typename List, bool condition>
+struct ConditionalFront;
+
+template<typename List>
+struct ConditionalFront<List, true> {
+    using type = brigand::front<List>;
+};
+
+template<typename List>
+struct ConditionalFront<List, false> {
+    using type = void;
+};
+
+}
+
+template<typename List, bool condition>
+using ConditionalFront = typename Detail::ConditionalFront<List, condition>::type;
+
+template<typename... T> struct Converter<IDLUnion<T...>> : DefaultConverter<IDLUnion<T...>> {
+    using Type = IDLUnion<T...>;
+    using TypeList = typename Type::TypeList;
+    using ReturnType = typename Type::ImplementationType;
+
+    using NumericTypeList = brigand::filter<TypeList, IsIDLNumber<brigand::_1>>;
+    static constexpr size_t numberOfNumericTypes = brigand::size<NumericTypeList>::value;
+    static_assert(numberOfNumericTypes == 0 || numberOfNumericTypes == 1, "There can be 0 or 1 numeric types in an IDLUnion.");
+    using NumericType = ConditionalFront<NumericTypeList, numberOfNumericTypes != 0>;
+
+    // FIXME: This should also check for IDLEnumeration<T>.
+    using StringTypeList = brigand::filter<TypeList, std::is_base_of<IDLString, brigand::_1>>;
+    static constexpr size_t numberOfStringTypes = brigand::size<StringTypeList>::value;
+    static_assert(numberOfStringTypes == 0 || numberOfStringTypes == 1, "There can be 0 or 1 string types in an IDLUnion.");
+    using StringType = ConditionalFront<StringTypeList, numberOfStringTypes != 0>;
+
+    using SequenceTypeList = brigand::filter<TypeList, IsIDLSequence<brigand::_1>>;
+    static constexpr size_t numberOfSequenceTypes = brigand::size<SequenceTypeList>::value;
+    static_assert(numberOfSequenceTypes == 0 || numberOfSequenceTypes == 1, "There can be 0 or 1 sequence types in an IDLUnion.");
+    using SequenceType = ConditionalFront<SequenceTypeList, numberOfSequenceTypes != 0>;
+
+    using FrozenArrayTypeList = brigand::filter<TypeList, IsIDLFrozenArray<brigand::_1>>;
+    static constexpr size_t numberOfFrozenArrayTypes = brigand::size<FrozenArrayTypeList>::value;
+    static_assert(numberOfFrozenArrayTypes == 0 || numberOfFrozenArrayTypes == 1, "There can be 0 or 1 FrozenArray types in an IDLUnion.");
+    using FrozenArrayType = ConditionalFront<FrozenArrayTypeList, numberOfFrozenArrayTypes != 0>;
+
+    using DictionaryTypeList = brigand::filter<TypeList, IsIDLDictionary<brigand::_1>>;
+    static constexpr size_t numberOfDictionaryTypes = brigand::size<DictionaryTypeList>::value;
+    static_assert(numberOfDictionaryTypes == 0 || numberOfDictionaryTypes == 1, "There can be 0 or 1 dictionary types in an IDLUnion.");
+    static constexpr bool hasDictionaryType = numberOfDictionaryTypes != 0;
+    using DictionaryType = ConditionalFront<DictionaryTypeList, hasDictionaryType>;
+
+    using RecordTypeList = brigand::filter<TypeList, IsIDLRecord<brigand::_1>>;
+    static constexpr size_t numberOfRecordTypes = brigand::size<RecordTypeList>::value;
+    static_assert(numberOfRecordTypes == 0 || numberOfRecordTypes == 1, "There can be 0 or 1 record types in an IDLUnion.");
+    static constexpr bool hasRecordType = numberOfRecordTypes != 0;
+    using RecordType = ConditionalFront<RecordTypeList, hasRecordType>;
+
+    static constexpr bool hasObjectType = (numberOfSequenceTypes + numberOfFrozenArrayTypes + numberOfDictionaryTypes + numberOfRecordTypes) > 0;
+
+    using InterfaceTypeList = brigand::filter<TypeList, IsIDLInterface<brigand::_1>>;
+
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        // 1. If the union type includes a nullable type and V is null or undefined, then return the IDL value null.
+        constexpr bool hasNullType = brigand::any<TypeList, std::is_same<IDLNull, brigand::_1>>::value;
+        if (hasNullType) {
+            if (value.isUndefinedOrNull())
+                return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, IDLNull, hasNullType>::convert(state, value).value());
+        }
+        
+        // 2. Let types be the flattened member types of the union type.
+        // NOTE: Union is expected to be pre-flattented.
+        
+        // 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<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, DictionaryType, hasDictionaryType>::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<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, RecordType, hasRecordType>::convert(state, value).value());
+            }
+        }
+
+        // 4. If V is a platform object, then:
+        //     1. If types includes an interface type that V implements, then return the IDL value that is a reference to the object V.
+        //     2. If types includes object, then return the IDL value that is a reference to the object V.
+        //         (FIXME: Add support for object and step 4.2)
+        if (brigand::any<TypeList, IsIDLInterface<brigand::_1>>::value) {
+            std::optional<ReturnType> returnValue;
+            brigand::for_each<InterfaceTypeList>([&](auto&& type) {
+                if (returnValue)
+                    return;
+                
+                using Type = typename WTF::RemoveCVAndReference<decltype(type)>::type::type;
+                using ImplementationType = typename Type::ImplementationType;
+                using RawType = typename Type::RawType;
+                using WrapperType = typename JSDOMWrapperConverterTraits<RawType>::WrapperClass;
+
+                auto castedValue = WrapperType::toWrapped(vm, value);
+                if (!castedValue)
+                    return;
+                
+                returnValue = ReturnType(ImplementationType(castedValue));
+            });
+
+            if (returnValue)
+                return WTFMove(returnValue.value());
+        }
+        
+        // FIXME: Add support for steps 5 - 10.
+
+        // 11. If V is any kind of object, then:
+        if (hasObjectType) {
+            if (value.isCell()) {
+                JSC::JSCell* cell = value.asCell();
+                if (cell->isObject()) {
+                    // FIXME: We should be able to optimize the following code by making use
+                    // of the fact that we have proved that the value is an object. 
+                
+                    //     1. If types includes a sequence type, then:
+                    //         1. Let method be the result of GetMethod(V, @@iterator).
+                    //         2. ReturnIfAbrupt(method).
+                    //         3. If method is not undefined, return the result of creating a
+                    //            sequence of that type from V and method.        
+                    constexpr bool hasSequenceType = numberOfSequenceTypes != 0;
+                    if (hasSequenceType) {
+                        bool hasIterator = hasIteratorMethod(state, value);
+                        RETURN_IF_EXCEPTION(scope, ReturnType());
+                        if (hasIterator)
+                            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, SequenceType, hasSequenceType>::convert(state, value).value());
+                    }
+
+                    //     2. If types includes a frozen array type, then:
+                    //         1. Let method be the result of GetMethod(V, @@iterator).
+                    //         2. ReturnIfAbrupt(method).
+                    //         3. If method is not undefined, return the result of creating a
+                    //            frozen array of that type from V and method.
+                    constexpr bool hasFrozenArrayType = numberOfFrozenArrayTypes != 0;
+                    if (hasFrozenArrayType) {
+                        bool hasIterator = hasIteratorMethod(state, value);
+                        RETURN_IF_EXCEPTION(scope, ReturnType());
+                        if (hasIterator)
+                            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, FrozenArrayType, hasFrozenArrayType>::convert(state, value).value());
+                    }
+
+                    //     3. If types includes a dictionary type, then return the result of
+                    //        converting V to that dictionary type.
+                    if (hasDictionaryType)
+                        return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, DictionaryType, hasDictionaryType>::convert(state, value).value());
+
+                    //     4. If types includes a record type, then return the result of converting V to that record type.
+                    if (hasRecordType)
+                        return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, RecordType, hasRecordType>::convert(state, value).value());
+
+                    //     5. If types includes a callback interface type, then return the result of converting V to that interface type.
+                    //         (FIXME: Add support for callback interface type and step 12.5)
+                    //     6. If types includes object, then return the IDL value that is a reference to the object V.
+                    //         (FIXME: Add support for object and step 12.6)
+                }
+            }
+        }
+
+        // 12. If V is a Boolean value, then:
+        //     1. If types includes a boolean, then return the result of converting V to boolean.
+        constexpr bool hasBooleanType = brigand::any<TypeList, std::is_same<IDLBoolean, brigand::_1>>::value;
+        if (hasBooleanType) {
+            if (value.isBoolean())
+                return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, IDLBoolean, hasBooleanType>::convert(state, value).value());
+        }
+        
+        // 13. If V is a Number value, then:
+        //     1. If types includes a numeric type, then return the result of converting V to that numeric type.
+        constexpr bool hasNumericType = brigand::size<NumericTypeList>::value != 0;
+        if (hasNumericType) {
+            if (value.isNumber())
+                return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, NumericType, hasNumericType>::convert(state, value).value());
+        }
+        
+        // 14. If types includes a string type, then return the result of converting V to that type.
+        constexpr bool hasStringType = brigand::size<StringTypeList>::value != 0;
+        if (hasStringType)
+            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, StringType, hasStringType>::convert(state, value).value());
+
+        // 15. If types includes a numeric type, then return the result of converting V to that numeric type.
+        if (hasNumericType)
+            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, NumericType, hasNumericType>::convert(state, value).value());
+
+        // 16. If types includes a boolean, then return the result of converting V to boolean.
+        if (hasBooleanType)
+            return std::move<WTF::CheckMoveParameter>(ConditionalConverter<ReturnType, IDLBoolean, hasBooleanType>::convert(state, value).value());
+
+        // 17. Throw a TypeError.
+        throwTypeError(&state, scope);
+        return ReturnType();
+    }
+};
+
+template<typename... T> struct JSConverter<IDLUnion<T...>> {
+    using Type = IDLUnion<T...>;
+    using TypeList = typename Type::TypeList;
+    using ImplementationType = typename Type::ImplementationType;
+
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    using Sequence = brigand::make_sequence<brigand::ptrdiff_t<0>, WTF::variant_size<ImplementationType>::value>;
+
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const ImplementationType& variant)
+    {
+        auto index = variant.index();
+
+        std::optional<JSC::JSValue> returnValue;
+        brigand::for_each<Sequence>([&](auto&& type) {
+            using I = typename WTF::RemoveCVAndReference<decltype(type)>::type::type;
+            if (I::value == index) {
+                ASSERT(!returnValue);
+                returnValue = toJS<brigand::at<TypeList, I>>(state, globalObject, WTF::get<I::value>(variant));
+            }
+        });
+
+        ASSERT(returnValue);
+        return returnValue.value();
+    }
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertVariadic.h b/Source/WebCore/bindings/js/JSDOMConvertVariadic.h
new file mode 100644 (file)
index 0000000..79b2b9d
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+namespace Detail {
+
+template<typename IDLType>
+struct VariadicConverterBase;
+
+template<typename IDLType> 
+struct VariadicConverterBase {
+    using Item = typename IDLType::ImplementationType;
+
+    static std::optional<Item> convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        auto& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        auto result = Converter<IDLType>::convert(state, value);
+        RETURN_IF_EXCEPTION(scope, std::nullopt);
+
+        return WTFMove(result);
+    }
+};
+
+template<typename T>
+struct VariadicConverterBase<IDLInterface<T>> {
+    using Item = std::reference_wrapper<T>;
+
+    static std::optional<Item> convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        auto* result = Converter<IDLInterface<T>>::convert(state, value);
+        if (!result)
+            return std::nullopt;
+        return std::optional<Item>(*result);
+    }
+};
+
+template<typename IDLType>
+struct VariadicConverter : VariadicConverterBase<IDLType> {
+    using Item = typename VariadicConverterBase<IDLType>::Item;
+    using Container = Vector<Item>;
+
+    struct Result {
+        size_t argumentIndex;
+        std::optional<Container> arguments;
+    };
+};
+
+}
+
+template<typename IDLType> typename Detail::VariadicConverter<IDLType>::Result convertVariadicArguments(JSC::ExecState& state, size_t startIndex)
+{
+    size_t length = state.argumentCount();
+    if (startIndex > length)
+        return { 0, std::nullopt };
+
+    typename Detail::VariadicConverter<IDLType>::Container result;
+    result.reserveInitialCapacity(length - startIndex);
+
+    for (size_t i = startIndex; i < length; ++i) {
+        auto value = Detail::VariadicConverter<IDLType>::convert(state, state.uncheckedArgument(i));
+        if (!value)
+            return { i, std::nullopt };
+        result.uncheckedAppend(WTFMove(*value));
+    }
+
+    return { length, WTFMove(result) };
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMConvertWebGL.h b/Source/WebCore/bindings/js/JSDOMConvertWebGL.h
new file mode 100644 (file)
index 0000000..c2740d5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGL)
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<> struct JSConverter<IDLWebGLAny> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const WebGLAny& value)
+    {
+        return convertToJSValue(state, globalObject, value);
+    }
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/bindings/js/JSDOMConvertXPathNSResolver.h b/Source/WebCore/bindings/js/JSDOMConvertXPathNSResolver.h
new file mode 100644 (file)
index 0000000..94df3f4
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+
+namespace WebCore {
+
+template<typename T> struct Converter<IDLXPathNSResolver<T>> : DefaultConverter<IDLXPathNSResolver<T>> {
+    using ReturnType = RefPtr<T>;
+    using WrapperType = typename JSDOMWrapperConverterTraits<T>::WrapperClass;
+
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static ReturnType convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+        ReturnType object = WrapperType::toWrapped(vm, state, value);
+        if (UNLIKELY(!object))
+            exceptionThrower(state, scope);
+        return object;
+    }
+};
+
+template<typename T> struct JSConverter<IDLXPathNSResolver<T>> {
+    static constexpr bool needsState = true;
+    static constexpr bool needsGlobalObject = true;
+
+    template <typename U>
+    static JSC::JSValue convert(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const U& value)
+    {
+        return toJS(&state, &globalObject, Detail::getPtrOrRef(value));
+    }
+
+    template<typename U>
+    static JSC::JSValue convertNewlyCreated(JSC::ExecState& state, JSDOMGlobalObject& globalObject, U&& value)
+    {
+        return toJSNewlyCreated(&state, &globalObject, std::forward<U>(value));
+    }
+};
+
+} // namespace WebCore
index a25c865..518b5ef 100644 (file)
 #include "config.h"
 #include "JSImageData.h"
 
-#include "ImageData.h"
-#include "JSDOMBinding.h"
+#include "JSDOMConvertBufferSource.h"
+#include "JSDOMWrapperCache.h"
+#include <heap/HeapInlines.h>
+#include <runtime/IdentifierInlines.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/text/WTFString.h>
 
index 439b088..a2ab8d8 100644 (file)
@@ -34,6 +34,8 @@
 #if ENABLE(READABLE_STREAM_API)
 
 #include "WebCoreJSClientData.h"
+#include <heap/HeapInlines.h>
+#include <runtime/IdentifierInlines.h>
 
 namespace WebCore {
 
index b7e4a8c..c3500b1 100644 (file)
@@ -30,7 +30,7 @@
 
 #if ENABLE(READABLE_STREAM_API)
 
-#include "JSDOMBinding.h"
+#include "JSDOMConvertBufferSource.h"
 #include "JSReadableStreamDefaultController.h"
 #include <runtime/JSCJSValue.h>
 #include <runtime/JSCJSValueInlines.h>
index dd09c43..a3c9385 100644 (file)
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "WebCoreTypedArrayController.h"
 
-#include "JSDOMBinding.h"
+#include "JSDOMConvertBufferSource.h"
 #include "JSDOMGlobalObject.h"
 #include <runtime/ArrayBuffer.h>
 #include <runtime/JSArrayBuffer.h>
index 0629756..a29f5da 100644 (file)
@@ -4681,7 +4681,7 @@ sub GenerateParametersCheck
         my $value = $name;
 
         if ($argument->isVariadic) {
-            AddToImplIncludes("JSDOMConvert.h", $conditional);
+            AddToImplIncludes("JSDOMConvertVariadic.h", $conditional);
             AddToImplIncludesForIDLType($type, $conditional);
         
             my $IDLType = GetIDLType($interface, $type);
index e95b25b..75ce051 100644 (file)
@@ -28,7 +28,7 @@
 
 #if ENABLE(WEBGL)
 
-#include "JSDOMBinding.h"
+#include "JSDOMConvert.h"
 #include "JSWebGLBuffer.h"
 #include "JSWebGLFramebuffer.h"
 #include "JSWebGLProgram.h"
index 2d79d14..849a8bf 100644 (file)
@@ -28,7 +28,7 @@
 #if ENABLE(VIDEO_TRACK) && ENABLE(DATACUE_VALUE)
 #include "SerializedPlatformRepresentationMac.h"
 
-#import "JSDOMBinding.h"
+#import "JSDOMConvertBufferSource.h"
 #import "SoftLinking.h"
 #import <AVFoundation/AVMetadataItem.h>
 #import <Foundation/NSString.h>
@@ -146,10 +146,10 @@ static JSValue *jsValueWithDataInContext(NSData *data, JSContext *context)
 {
     auto dataArray = ArrayBuffer::tryCreate([data bytes], [data length]);
 
-    JSC::ExecState* exec = toJS([context JSGlobalContextRef]);
-    JSC::JSValue array = toJS(exec, JSC::jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), dataArray.get());
+    auto* state = toJS([context JSGlobalContextRef]);
+    JSC::JSValue array = toJS(state, JSC::jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject()), dataArray.get());
 
-    return [JSValue valueWithJSValueRef:toRef(exec, array) inContext:context];
+    return [JSValue valueWithJSValueRef:toRef(state, array) inContext:context];
 }
 
 static JSValue *jsValueWithArrayInContext(NSArray *array, JSContext *context)