Title: [219622] trunk
Revision
219622
Author
wei...@apple.com
Date
2017-07-18 13:12:15 -0700 (Tue, 18 Jul 2017)

Log Message

[WebIDL] Replace some custom bindings code in JSCSSStyleDeclarationCustom.cpp with named getters/setters
https://bugs.webkit.org/show_bug.cgi?id=174529

Reviewed by Chris Dumez.

Source/WebCore:

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSAllInOne.cpp:
Add CSSStyleDeclaration.cpp

* bindings/js/JSCSSStyleDeclarationCustom.cpp:
Move getter / setter / getOwnProperties logic from here to CSSStyleDeclaration.cpp.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateGetOwnPropertySlot):
(GenerateGetOwnPropertySlotByIndex):
(InstanceOverridesGetOwnPropertySlot):
(GenerateHeader):
Remove support for no longer needed [CustomGetOwnPropertySlotAndDescriptor].
Add support for [PutOnlyForSupportedProperties], which allows named setters to behave
a bit more like normal setters by allowing the implementation to note which properties
are supported which in turn, allows the bindings to continue down the normal put path
for unsupported properties. This is necessary to mimic the behavior of CSSStyleDeclaration
which is using named setters in place hundreds of additional properties.

(InstanceOverridesDefineOwnProperty):
Add [DefaultDefineOwnProperty] to allow disabling defineOwnProperty overriding that comes
automatically with named setters. We need this for CSSStyleDeclaration since the named
setter usage modeling real properties, not a dictionary style setter. We may want to 
revisit this, and add support for DefineOwnProperty here, but this allows us to maintain
the status quo.

(GenerateDefineOwnProperty):
Fix the case when you have a named setter, an indexed getter, but no indexed setter. In that
case, we would get a compile error, due to the index variable being unused.

* bindings/scripts/IDLAttributes.json:
Remove support for no longer needed [CustomGetOwnPropertySlotAndDescriptor], add
[PutOnlyForSupportedProperties] and [DefaultDefineOwnProperty].

* css/CSSStyleDeclaration.h:
* css/CSSStyleDeclaration.cpp: Added.
(WebCore::CSSStyleDeclaration::namedItem):
(WebCore::CSSStyleDeclaration::setNamedItem):
(WebCore::CSSStyleDeclaration::isSupportedPropertyName):
(WebCore::CSSStyleDeclaration::supportedPropertyNames):
Use standard getter / setter functions to implement CSS property name getting and setting.
Convert from Identifier to AtomicString, which are now bridgeable.

* css/CSSStyleDeclaration.idl:
Add named getter and setter. Remove [CustomGetOwnPropertyNames], [CustomGetOwnPropertySlotAndDescriptor]
and [CustomPut], add [DefaultDefineOwnProperty].

* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp: Added.
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h: Added.
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp: Added.
* bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h: Added.
* bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl: Added.
* bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl: Added.
Add tests for improved behavior when using named setters with variations of indexed getters and setters as well.

LayoutTests:

* fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt:
* fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html:
Update test and result to match standard and other browsers. 

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (219621 => 219622)


--- trunk/LayoutTests/ChangeLog	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/LayoutTests/ChangeLog	2017-07-18 20:12:15 UTC (rev 219622)
@@ -1,3 +1,14 @@
+2017-07-18  Sam Weinig  <s...@webkit.org>
+
+        [WebIDL] Replace some custom bindings code in JSCSSStyleDeclarationCustom.cpp with named getters/setters
+        https://bugs.webkit.org/show_bug.cgi?id=174529
+
+        Reviewed by Chris Dumez.
+
+        * fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt:
+        * fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html:
+        Update test and result to match standard and other browsers. 
+
 2017-07-18  Matt Lewis  <jlew...@apple.com>
 
         Unreviewed, rolling out r219610.

Modified: trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt (219621 => 219622)


--- trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor-expected.txt	2017-07-18 20:12:15 UTC (rev 219622)
@@ -5,7 +5,7 @@
 
 PASS descriptor['writable'] is true
 PASS descriptor['enumerable'] is true
-PASS descriptor['configurable'] is false
+PASS descriptor['configurable'] is true
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html (219621 => 219622)


--- trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/LayoutTests/fast/dom/CSSStyleDeclaration/cssstyledeclaration-properties-descriptor.html	2017-07-18 20:12:15 UTC (rev 219622)
@@ -8,7 +8,7 @@
         var descriptor = Object.getOwnPropertyDescriptor(document.body.style, 'color');
         shouldBeTrue("descriptor['writable']");
         shouldBeTrue("descriptor['enumerable']");
-        shouldBeFalse("descriptor['configurable']");
+        shouldBeTrue("descriptor['configurable']");
     </script>
     <script src=""
 </body>

Modified: trunk/Source/WebCore/CMakeLists.txt (219621 => 219622)


--- trunk/Source/WebCore/CMakeLists.txt	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/CMakeLists.txt	2017-07-18 20:12:15 UTC (rev 219622)
@@ -1356,6 +1356,7 @@
     css/CSSSelector.cpp
     css/CSSSelectorList.cpp
     css/CSSShadowValue.cpp
+    css/CSSStyleDeclaration.cpp
     css/CSSStyleRule.cpp
     css/CSSStyleSheet.cpp
     css/CSSSupportsRule.cpp

Modified: trunk/Source/WebCore/ChangeLog (219621 => 219622)


--- trunk/Source/WebCore/ChangeLog	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/ChangeLog	2017-07-18 20:12:15 UTC (rev 219622)
@@ -1,3 +1,66 @@
+2017-07-18  Sam Weinig  <s...@webkit.org>
+
+        [WebIDL] Replace some custom bindings code in JSCSSStyleDeclarationCustom.cpp with named getters/setters
+        https://bugs.webkit.org/show_bug.cgi?id=174529
+
+        Reviewed by Chris Dumez.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSAllInOne.cpp:
+        Add CSSStyleDeclaration.cpp
+
+        * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+        Move getter / setter / getOwnProperties logic from here to CSSStyleDeclaration.cpp.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateGetOwnPropertySlot):
+        (GenerateGetOwnPropertySlotByIndex):
+        (InstanceOverridesGetOwnPropertySlot):
+        (GenerateHeader):
+        Remove support for no longer needed [CustomGetOwnPropertySlotAndDescriptor].
+        Add support for [PutOnlyForSupportedProperties], which allows named setters to behave
+        a bit more like normal setters by allowing the implementation to note which properties
+        are supported which in turn, allows the bindings to continue down the normal put path
+        for unsupported properties. This is necessary to mimic the behavior of CSSStyleDeclaration
+        which is using named setters in place hundreds of additional properties.
+
+        (InstanceOverridesDefineOwnProperty):
+        Add [DefaultDefineOwnProperty] to allow disabling defineOwnProperty overriding that comes
+        automatically with named setters. We need this for CSSStyleDeclaration since the named
+        setter usage modeling real properties, not a dictionary style setter. We may want to 
+        revisit this, and add support for DefineOwnProperty here, but this allows us to maintain
+        the status quo.
+
+        (GenerateDefineOwnProperty):
+        Fix the case when you have a named setter, an indexed getter, but no indexed setter. In that
+        case, we would get a compile error, due to the index variable being unused.
+
+        * bindings/scripts/IDLAttributes.json:
+        Remove support for no longer needed [CustomGetOwnPropertySlotAndDescriptor], add
+        [PutOnlyForSupportedProperties] and [DefaultDefineOwnProperty].
+
+        * css/CSSStyleDeclaration.h:
+        * css/CSSStyleDeclaration.cpp: Added.
+        (WebCore::CSSStyleDeclaration::namedItem):
+        (WebCore::CSSStyleDeclaration::setNamedItem):
+        (WebCore::CSSStyleDeclaration::isSupportedPropertyName):
+        (WebCore::CSSStyleDeclaration::supportedPropertyNames):
+        Use standard getter / setter functions to implement CSS property name getting and setting.
+        Convert from Identifier to AtomicString, which are now bridgeable.
+
+        * css/CSSStyleDeclaration.idl:
+        Add named getter and setter. Remove [CustomGetOwnPropertyNames], [CustomGetOwnPropertySlotAndDescriptor]
+        and [CustomPut], add [DefaultDefineOwnProperty].
+
+        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp: Added.
+        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h: Added.
+        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp: Added.
+        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h: Added.
+        * bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl: Added.
+        * bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl: Added.
+        Add tests for improved behavior when using named setters with variations of indexed getters and setters as well.
+
 2017-07-18  Antoine Quint  <grao...@apple.com>
 
         [iOS] WebKit media controls are sometimes shown after exiting full screen on vimeo.com

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (219621 => 219622)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-07-18 20:12:15 UTC (rev 219622)
@@ -3281,6 +3281,7 @@
 		7CD0BA051B8F79C9005CEBBE /* ActiveDOMCallbackMicrotask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CD0BA031B8F79C9005CEBBE /* ActiveDOMCallbackMicrotask.h */; };
 		7CD494CC1A86EB1D000A87EC /* RenderAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CD494CA1A86EB1D000A87EC /* RenderAttachment.cpp */; };
 		7CD494CD1A86EB1D000A87EC /* RenderAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CD494CB1A86EB1D000A87EC /* RenderAttachment.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		7CDE8EBE1F193BCB00168FE7 /* CSSStyleDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CDE8EBC1F193BC500168FE7 /* CSSStyleDeclaration.cpp */; };
 		7CE58D4A1DD64A5B00128552 /* SVGPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE58D491DD64A5B00128552 /* SVGPoint.h */; };
 		7CE58D4E1DD694FE00128552 /* SVGRectTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE58D4D1DD694FE00128552 /* SVGRectTraits.h */; };
 		7CE58D501DD69A1E00128552 /* SVGNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE58D4F1DD69A1E00128552 /* SVGNumber.h */; };
@@ -11354,6 +11355,7 @@
 		7CD0BA031B8F79C9005CEBBE /* ActiveDOMCallbackMicrotask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveDOMCallbackMicrotask.h; sourceTree = "<group>"; };
 		7CD494CA1A86EB1D000A87EC /* RenderAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderAttachment.cpp; sourceTree = "<group>"; };
 		7CD494CB1A86EB1D000A87EC /* RenderAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderAttachment.h; sourceTree = "<group>"; };
+		7CDE8EBC1F193BC500168FE7 /* CSSStyleDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSStyleDeclaration.cpp; sourceTree = "<group>"; };
 		7CE58D491DD64A5B00128552 /* SVGPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPoint.h; sourceTree = "<group>"; };
 		7CE58D4D1DD694FE00128552 /* SVGRectTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGRectTraits.h; sourceTree = "<group>"; };
 		7CE58D4F1DD69A1E00128552 /* SVGNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGNumber.h; sourceTree = "<group>"; };
@@ -25067,6 +25069,7 @@
 				E4C178960EE6903800824D69 /* CSSSelectorList.h */,
 				A80E6CCA0A1989CA007FB8C5 /* CSSShadowValue.cpp */,
 				A80E6CBE0A1989CA007FB8C5 /* CSSShadowValue.h */,
+				7CDE8EBC1F193BC500168FE7 /* CSSStyleDeclaration.cpp */,
 				A80E6E0D0A19911C007FB8C5 /* CSSStyleDeclaration.h */,
 				142011AE0A003117008303F9 /* CSSStyleDeclaration.idl */,
 				A80E6CC50A1989CA007FB8C5 /* CSSStyleRule.cpp */,
@@ -30816,6 +30819,7 @@
 				49484FC4102CF23C00187DD3 /* CanvasPattern.cpp in Sources */,
 				49C7B9DC1042D32F0009D447 /* CanvasRenderingContext.cpp in Sources */,
 				49484FCA102CF23C00187DD3 /* CanvasRenderingContext2D.cpp in Sources */,
+				7CDE8EBE1F193BCB00168FE7 /* CSSStyleDeclaration.cpp in Sources */,
 				49484FCD102CF23C00187DD3 /* CanvasStyle.cpp in Sources */,
 				072CA86116CB4DC3008AE131 /* CaptionUserPreferences.cpp in Sources */,
 				079D086C162F21F900DB8658 /* CaptionUserPreferencesMediaAF.cpp in Sources */,

Modified: trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp (219621 => 219622)


--- trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp	2017-07-18 20:12:15 UTC (rev 219622)
@@ -24,31 +24,16 @@
  */
 
 #include "config.h"
-#include "JSCSSStyleDeclarationCustom.h"
+#include "JSCSSStyleDeclaration.h"
 
-#include "CSSPropertyNames.h"
-#include "CSSPropertyParser.h"
-#include "CSSRule.h"
-#include "CSSStyleDeclaration.h"
-#include "CSSStyleSheet.h"
-#include "CustomElementReactionQueue.h"
-#include "DeprecatedCSSOMPrimitiveValue.h"
-#include "HashTools.h"
-#include "JSCSSStyleDeclaration.h"
-#include "JSDOMConvertNullable.h"
+#include "DOMWrapperWorld.h"
+#include "JSCSSRuleCustom.h"
+#include "JSDOMConvertInterface.h"
 #include "JSDOMConvertStrings.h"
 #include "JSDeprecatedCSSOMValue.h"
-#include "JSNode.h"
+#include "JSNodeCustom.h"
 #include "JSStyleSheetCustom.h"
-#include "RuntimeEnabledFeatures.h"
-#include "Settings.h"
-#include "StyleProperties.h"
 #include "StyledElement.h"
-#include <runtime/IdentifierInlines.h>
-#include <runtime/StringPrototype.h>
-#include <wtf/ASCIICType.h>
-#include <wtf/text/AtomicString.h>
-#include <wtf/text/StringConcatenate.h>
 
 using namespace JSC;
 
@@ -71,314 +56,6 @@
     visitor.addOpaqueRoot(root(&wrapped()));
 }
 
-enum class PropertyNamePrefix {
-    None, Epub, CSS, Pixel, Pos, WebKit,
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
-    Apple, KHTML,
-#endif
-};
-
-template<size_t prefixCStringLength>
-static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength])
-{
-    size_t prefixLength = prefixCStringLength - 1;
-
-    ASSERT(toASCIILower(propertyName[0]) == prefix[0]);
-    const size_t offset = 1;
-
-#ifndef NDEBUG
-    for (size_t i = 0; i < prefixLength; ++i)
-        ASSERT(isASCIILower(prefix[i]));
-    ASSERT(!prefix[prefixLength]);
-    ASSERT(propertyName.length());
-#endif
-
-    // The prefix within the property name must be followed by a capital letter.
-    // Other characters in the prefix within the property name must be lowercase.
-    if (propertyName.length() < prefixLength + 1)
-        return false;
-
-    for (size_t i = offset; i < prefixLength; ++i) {
-        if (propertyName[i] != prefix[i])
-            return false;
-    }
-
-    if (!isASCIIUpper(propertyName[prefixLength]))
-        return false;
-
-    return true;
-}
-
-static PropertyNamePrefix propertyNamePrefix(const StringImpl& propertyName)
-{
-    ASSERT(propertyName.length());
-
-    // First character of the prefix within the property name may be upper or lowercase.
-    UChar firstChar = toASCIILower(propertyName[0]);
-    switch (firstChar) {
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
-    case 'a':
-        if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled() && matchesCSSPropertyNamePrefix(propertyName, "apple"))
-            return PropertyNamePrefix::Apple;
-        break;
-#endif
-    case 'c':
-        if (matchesCSSPropertyNamePrefix(propertyName, "css"))
-            return PropertyNamePrefix::CSS;
-        break;
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
-    case 'k':
-        if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled() && matchesCSSPropertyNamePrefix(propertyName, "khtml"))
-            return PropertyNamePrefix::KHTML;
-        break;
-#endif
-    case 'e':
-        if (matchesCSSPropertyNamePrefix(propertyName, "epub"))
-            return PropertyNamePrefix::Epub;
-        break;
-    case 'p':
-        if (matchesCSSPropertyNamePrefix(propertyName, "pos"))
-            return PropertyNamePrefix::Pos;
-        if (matchesCSSPropertyNamePrefix(propertyName, "pixel"))
-            return PropertyNamePrefix::Pixel;
-        break;
-    case 'w':
-        if (matchesCSSPropertyNamePrefix(propertyName, "webkit"))
-            return PropertyNamePrefix::WebKit;
-        break;
-    default:
-        break;
-    }
-    return PropertyNamePrefix::None;
-}
-
-static inline void writeWebKitPrefix(char*& buffer)
-{
-    *buffer++ = '-';
-    *buffer++ = 'w';
-    *buffer++ = 'e';
-    *buffer++ = 'b';
-    *buffer++ = 'k';
-    *buffer++ = 'i';
-    *buffer++ = 't';
-    *buffer++ = '-';
-}
-
-static inline void writeEpubPrefix(char*& buffer)
-{
-    *buffer++ = '-';
-    *buffer++ = 'e';
-    *buffer++ = 'p';
-    *buffer++ = 'u';
-    *buffer++ = 'b';
-    *buffer++ = '-';
-}
-
-struct CSSPropertyInfo {
-    CSSPropertyID propertyID;
-    bool hadPixelOrPosPrefix;
-};
-
-static CSSPropertyInfo parseJavaScriptCSSPropertyName(PropertyName propertyName)
-{
-    CSSPropertyInfo propertyInfo = {CSSPropertyInvalid, false};
-    bool hadPixelOrPosPrefix = false;
-
-    StringImpl* propertyNameString = propertyName.publicName();
-    if (!propertyNameString)
-        return propertyInfo;
-    unsigned length = propertyNameString->length();
-    if (!length)
-        return propertyInfo;
-
-    String stringForCache = String(propertyNameString);
-    using CSSPropertyInfoMap = HashMap<String, CSSPropertyInfo>;
-    static NeverDestroyed<CSSPropertyInfoMap> propertyInfoCache;
-    propertyInfo = propertyInfoCache.get().get(stringForCache);
-    if (propertyInfo.propertyID)
-        return propertyInfo;
-
-    const size_t bufferSize = maxCSSPropertyNameLength + 1;
-    char buffer[bufferSize];
-    char* bufferPtr = buffer;
-    const char* name = bufferPtr;
-
-    unsigned i = 0;
-    // Prefixes CSS, Pixel, Pos are ignored.
-    // Prefixes Apple, KHTML and Webkit are transposed to "-webkit-".
-    // The prefix "Epub" becomes "-epub-".
-    switch (propertyNamePrefix(*propertyNameString)) {
-    case PropertyNamePrefix::None:
-        if (isASCIIUpper((*propertyNameString)[0]))
-            return propertyInfo;
-        break;
-    case PropertyNamePrefix::CSS:
-        i += 3;
-        break;
-    case PropertyNamePrefix::Pixel:
-        i += 5;
-        hadPixelOrPosPrefix = true;
-        break;
-    case PropertyNamePrefix::Pos:
-        i += 3;
-        hadPixelOrPosPrefix = true;
-        break;
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
-    case PropertyNamePrefix::Apple:
-    case PropertyNamePrefix::KHTML:
-        ASSERT(RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled());
-        writeWebKitPrefix(bufferPtr);
-        i += 5;
-        break;
-#endif
-    case PropertyNamePrefix::Epub:
-        writeEpubPrefix(bufferPtr);
-        i += 4;
-        break;
-    case PropertyNamePrefix::WebKit:
-        writeWebKitPrefix(bufferPtr);
-        i += 6;
-        break;
-    }
-
-    *bufferPtr++ = toASCIILower((*propertyNameString)[i++]);
-
-    char* bufferEnd = buffer + bufferSize;
-    char* stringEnd = bufferEnd - 1;
-    size_t bufferSizeLeft = stringEnd - bufferPtr;
-    size_t propertySizeLeft = length - i;
-    if (propertySizeLeft > bufferSizeLeft)
-        return propertyInfo;
-
-    for (; i < length; ++i) {
-        UChar c = (*propertyNameString)[i];
-        if (!c || !isASCII(c))
-            return propertyInfo; // illegal character
-        if (isASCIIUpper(c)) {
-            size_t bufferSizeLeft = stringEnd - bufferPtr;
-            size_t propertySizeLeft = length - i + 1;
-            if (propertySizeLeft > bufferSizeLeft)
-                return propertyInfo;
-            *bufferPtr++ = '-';
-            *bufferPtr++ = toASCIILowerUnchecked(c);
-        } else
-            *bufferPtr++ = c;
-        ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
-    }
-    ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
-    *bufferPtr = '\0';
-
-    unsigned outputLength = bufferPtr - buffer;
-#if PLATFORM(IOS)
-    cssPropertyNameIOSAliasing(buffer, name, outputLength);
-#endif
-
-    auto* hashTableEntry = findProperty(name, outputLength);
-    if (auto propertyID = hashTableEntry ? hashTableEntry->id : 0) {
-        propertyInfo.hadPixelOrPosPrefix = hadPixelOrPosPrefix;
-        propertyInfo.propertyID = static_cast<CSSPropertyID>(propertyID);
-        propertyInfoCache.get().add(stringForCache, propertyInfo);
-    }
-    return propertyInfo;
-}
-
-static inline JSValue stylePropertyGetter(ExecState& state, JSCSSStyleDeclaration& thisObject, CSSPropertyID propertyID, const RefPtr<CSSValue>& value)
-{
-    if (value)
-        return toJS<IDLNullable<IDLDOMString>>(state, value->cssText());
-    // If the property is a shorthand property (such as "padding"), it can only be accessed using getPropertyValue.
-    return toJS<IDLDOMString>(state, thisObject.wrapped().getPropertyValueInternal(propertyID));
-}
-
-static inline JSValue stylePropertyGetter(ExecState& state, JSCSSStyleDeclaration& thisObject, CSSPropertyID propertyID)
-{
-    return stylePropertyGetter(state, thisObject, propertyID, thisObject.wrapped().getPropertyCSSValueInternal(propertyID));
-}
-
-static inline JSValue stylePropertyGetterPixelOrPosPrefix(ExecState& state, JSCSSStyleDeclaration& thisObject, CSSPropertyID propertyID)
-{
-    // Call this version of the getter so that, e.g., pixelTop returns top as a number
-    // in pixel units and posTop should does the same _if_ this is a positioned element.
-    // FIXME: If not a positioned element, MSIE documentation says posTop should return 0; this rule is not implemented.
-    auto value = thisObject.wrapped().getPropertyCSSValueInternal(propertyID);
-    if (is<CSSPrimitiveValue>(value.get()))
-        return jsNumber(downcast<CSSPrimitiveValue>(*value).floatValue(CSSPrimitiveValue::CSS_PX));
-    return stylePropertyGetter(state, thisObject, propertyID, value);
-}
-
-static inline JSValue stylePropertyGetter(ExecState& state, JSCSSStyleDeclaration& thisObject, const CSSPropertyInfo& propertyInfo)
-{
-    if (propertyInfo.hadPixelOrPosPrefix)
-        return stylePropertyGetterPixelOrPosPrefix(state, thisObject, propertyInfo.propertyID);
-    return stylePropertyGetter(state, thisObject, propertyInfo.propertyID);
-}
-
-// FIXME: This should be converted to be a named getter.
-bool JSCSSStyleDeclaration::getOwnPropertySlotDelegate(ExecState* state, PropertyName propertyName, PropertySlot& slot)
-{
-    auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
-    if (!propertyInfo.propertyID)
-        return false;
-    slot.setValue(this, DontDelete, stylePropertyGetter(*state, *this, propertyInfo));
-    return true;
-}
-
-// FIXME: This should be converted to be a named setter.
-static bool putCommon(JSCSSStyleDeclaration& thisObject, ExecState& state, PropertyName propertyName, JSValue value, bool& putResult)
-{
-    CustomElementReactionStack customElementReactionStack;
-    auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
-    if (!propertyInfo.propertyID)
-        return false;
-
-    auto propertyValue = convert<IDLTreatNullAsEmptyAdaptor<IDLDOMString>>(state, value);
-    if (propertyInfo.hadPixelOrPosPrefix)
-        propertyValue.append("px");
-
-    bool important = false;
-    if (Settings::shouldRespectPriorityInCSSAttributeSetters()) {
-        auto importantIndex = propertyValue.findIgnoringASCIICase("!important");
-        if (importantIndex && importantIndex != notFound) {
-            important = true;
-            propertyValue = propertyValue.left(importantIndex - 1);
-        }
-    }
-
-    auto setPropertyInternalResult = thisObject.wrapped().setPropertyInternal(propertyInfo.propertyID, propertyValue, important);
-    if (setPropertyInternalResult.hasException()) {
-        auto& vm = state.vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        propagateException(state, scope, setPropertyInternalResult.releaseException());
-        return true;
-    }
-    putResult = setPropertyInternalResult.releaseReturnValue();
-    return true;
-}
-
-bool JSCSSStyleDeclaration::put(JSCell* cell, ExecState* state, PropertyName propertyName, JSValue value, PutPropertySlot& putPropertySlot)
-{
-    auto* thisObject = jsCast<JSCSSStyleDeclaration*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-
-    bool putResult = false;
-    if (putCommon(*thisObject, *state, propertyName, value, putResult))
-        return putResult;
-
-    return JSObject::put(thisObject, state, propertyName, value, putPropertySlot);
-}
-
-bool JSCSSStyleDeclaration::putByIndex(JSCell* cell, ExecState* state, unsigned index, JSValue value, bool shouldThrow)
-{
-    auto* thisObject = jsCast<JSCSSStyleDeclaration*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-
-    bool putResult = false;
-    if (putCommon(*thisObject, *state, Identifier::from(state, index), value, putResult))
-        return putResult;
-
-    return JSObject::putByIndex(cell, state, index, value, shouldThrow);
-}
-
 JSValue JSCSSStyleDeclaration::getPropertyCSSValue(ExecState& state)
 {
     VM& vm = state.vm();
@@ -387,8 +64,8 @@
     if (UNLIKELY(state.argumentCount() < 1))
         return throwException(&state, scope, createNotEnoughArgumentsError(&state));
 
-    auto propertyName = state.uncheckedArgument(0).toWTFString(&state);
-    RETURN_IF_EXCEPTION(scope, JSValue());
+    auto propertyName = convert<IDLDOMString>(state, state.uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(scope, { });
 
     auto value = wrapped().getPropertyCSSValue(propertyName);
     if (!value)
@@ -395,29 +72,7 @@
         return jsNull();
 
     globalObject()->world().m_deprecatedCSSOMValueRoots.add(value.get(), root(&wrapped())); // Balanced by JSDeprecatedCSSOMValueOwner::finalize().
-    return toJS(&state, globalObject(), *value);
+    return toJS<IDLInterface<DeprecatedCSSOMValue>>(state, *globalObject(), *value);
 }
 
-void JSCSSStyleDeclaration::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
-{
-    static const Identifier* const cssPropertyNames = [state] {
-        String names[numCSSProperties];
-        for (int i = 0; i < numCSSProperties; ++i)
-            names[i] = getJSPropertyName(static_cast<CSSPropertyID>(firstCSSProperty + i));
-        std::sort(&names[0], &names[numCSSProperties], WTF::codePointCompareLessThan);
-        auto* identifiers = new Identifier[numCSSProperties];
-        for (int i = 0; i < numCSSProperties; ++i)
-            identifiers[i] = Identifier::fromString(state, names[i]);
-        return identifiers;
-    }();
-
-    unsigned length = jsCast<JSCSSStyleDeclaration*>(object)->wrapped().length();
-    for (unsigned i = 0; i < length; ++i)
-        propertyNames.add(Identifier::from(state, i));
-    for (int i = 0; i < numCSSProperties; ++i)
-        propertyNames.add(cssPropertyNames[i]);
-
-    Base::getOwnPropertyNames(object, state, propertyNames, mode);
-}
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (219621 => 219622)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2017-07-18 20:12:15 UTC (rev 219622)
@@ -667,7 +667,7 @@
         # 1.3. Set ignoreNamedProps to true.
         # NOTE: Setting ignoreNamedProps has the effect of skipping step 2, so we can early return here
         #       rather than going through the paces of having an actual ignoreNamedProps update.
-        if ($namedGetterOperation || $interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor} || $interface->extendedAttributes->{Plugin}) {
+        if ($namedGetterOperation || $interface->extendedAttributes->{Plugin}) {
             push(@$outputArray, "        return JSObject::getOwnPropertySlot(object, state, propertyName, slot);\n");
         }
         push(@$outputArray, "    }\n");
@@ -702,12 +702,6 @@
         push(@$outputArray, "    }\n");
     }
 
-    # FIXME: There is only one remaining user of this, CSSStyleDeclaration.idl. Let's get them onto named / indexed getters.
-    if ($interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor}) {
-        push(@$outputArray, "    if (thisObject->getOwnPropertySlotDelegate(state, propertyName, slot))\n");
-        push(@$outputArray, "        return true;\n");
-    }
-
     if ($interface->extendedAttributes->{Plugin}) {
         AddToImplIncludes("JSPluginElementFunctions.h");
         push(@$outputArray, "    if (pluginElementCustomGetOwnPropertySlot(thisObject, state, propertyName, slot))\n");
@@ -779,7 +773,7 @@
         # 1.3. Set ignoreNamedProps to true.
         # NOTE: Setting ignoreNamedProps has the effect of skipping step 2, so we can early return here
         #       rather than going through the paces of having an actual ignoreNamedProps update.
-        if ($namedGetterOperation || $interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor} || $interface->extendedAttributes->{Plugin}) {
+        if ($namedGetterOperation || $interface->extendedAttributes->{Plugin}) {
             push(@$outputArray, "        return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);\n");
         }
         push(@$outputArray, "    }\n");
@@ -816,14 +810,6 @@
         push(@$outputArray, "    }\n");
     }
     
-    # FIXME: There is only one remaining user of this, CSSStyleDeclaration.idl. Let's get them onto named / indexed getters.
-    if ($interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor}) {
-        &$propertyNameGeneration();
-    
-        push(@$outputArray, "    if (thisObject->getOwnPropertySlotDelegate(state, propertyName, slot))\n");
-        push(@$outputArray, "        return true;\n");
-    }
-
     if ($interface->extendedAttributes->{Plugin}) {
         &$propertyNameGeneration();
 
@@ -916,12 +902,20 @@
     push(@$outputArray, $indent . "auto throwScope = DECLARE_THROW_SCOPE(state->vm());\n");
     push(@$outputArray, $indent . "auto nativeValue = ${nativeValue};\n");
     push(@$outputArray, $indent . "RETURN_IF_EXCEPTION(throwScope, true);\n");
-    
+
+    push(@$outputArray, $indent . "bool isPropertySupported = true;\n") if $namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties};
+
     my $namedSetterFunctionName = $namedSetterOperation->name || "setNamedItem";
     my $nativeValuePassExpression = PassArgumentExpression("nativeValue", $argument);
-    my $functionString = "thisObject->wrapped().${namedSetterFunctionName}(propertyNameToString(propertyName), ${nativeValuePassExpression})";
+
+    my @arguments = ();
+    push(@arguments, "propertyNameToString(propertyName)");
+    push(@arguments, $nativeValuePassExpression);
+    push(@arguments, "isPropertySupported") if $namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties};
+
+    my $functionString = "thisObject->wrapped().${namedSetterFunctionName}(" . join(", ", @arguments) . ")";
     $functionString = "propagateException(*state, throwScope, ${functionString})" if NeedsExplicitPropagateExceptionCall($namedSetterOperation);
-    
+
     push(@$outputArray, $indent . $functionString . ";\n");
 }
 
@@ -966,10 +960,14 @@
             push(@$outputArray, "        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {\n");
             $additionalIndent .= "    ";
         }
-        
+
         GenerateInvokeNamedPropertySetter($outputArray, $additionalIndent . "        ", $interface, $namedSetterOperation, "value");
+        if ($namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties}) {
+            push(@$outputArray, $additionalIndent . "        if (!isPropertySupported)\n");
+            push(@$outputArray, $additionalIndent . "            return JSObject::put(thisObject, state, propertyName, value, putPropertySlot);\n");
+        }
         push(@$outputArray, $additionalIndent . "        return true;\n");
-        
+
         if (!$overrideBuiltins) {
             push(@$outputArray, "        }\n");
         }
@@ -1000,7 +998,7 @@
     my $indexedSetterOperation = GetIndexedSetterOperation($interface);
     
     my $overrideBuiltins = $codeGenerator->InheritsExtendedAttribute($interface, "OverrideBuiltins");
-    my $ellidesCallsToBase = ($namedSetterOperation && $overrideBuiltins) && !$interface->extendedAttributes->{Plugin};
+    my $ellidesCallsToBase = ($namedSetterOperation && $overrideBuiltins) && !$interface->extendedAttributes->{Plugin} && !$namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties};
     
     push(@$outputArray, "bool ${className}::putByIndex(JSCell* cell, ExecState* state, unsigned index, JSValue value, bool" . (!$ellidesCallsToBase ? " shouldThrow" : "") . ")\n");
     push(@$outputArray, "{\n");
@@ -1033,6 +1031,10 @@
         }
         
         GenerateInvokeNamedPropertySetter($outputArray, $additionalIndent . "    ", $interface, $namedSetterOperation, "value");
+        if ($namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties}) {
+            push(@$outputArray, $additionalIndent . "    if (!isPropertySupported)\n");
+            push(@$outputArray, $additionalIndent . "        return JSObject::putByIndex(cell, state, index, value, shouldThrow);\n");
+        }
         push(@$outputArray, $additionalIndent . "    return true;\n");
         
         if (!$overrideBuiltins) {
@@ -1106,15 +1108,16 @@
     
     # 1. If O supports indexed properties and P is an array index property name, then:
     if (GetIndexedGetterOperation($interface)) {
-        push(@$outputArray, "    if (auto index = parseIndex(propertyName)) {\n");
-        
         # NOTE: The numbers are out of order because there is no reason doing steps 1, 3, and 4 if there
         # is no indexed property setter.
-        
+
         if (!$indexedSetterOperation) {
             # 2. If O does not implement an interface with an indexed property setter, then return false.
-            push(@$outputArray, "        return false;\n");
+            push(@$outputArray, "    if (parseIndex(propertyName))\n");
+            push(@$outputArray, "        return false;\n\n");
         } else {
+            push(@$outputArray, "    if (auto index = parseIndex(propertyName)) {\n");
+
             # 1. If the result of calling IsDataDescriptor(Desc) is false, then return false.
             push(@$outputArray, "        if (!propertyDescriptor.isDataDescriptor())\n");
             push(@$outputArray, "            return false;\n");
@@ -1124,8 +1127,8 @@
             
             # 4. Return true.
             push(@$outputArray, "        return true;\n");
+            push(@$outputArray, "    }\n\n");
         }
-        push(@$outputArray, "    }\n\n");
     }
     
     # 2. If O supports named properties, O does not implement an interface with the [Global] or [PrimaryGlobal]
@@ -1169,7 +1172,10 @@
             
             # 2.2.2. Invoke the named property setter with P and Desc.[[Value]].
             GenerateInvokeNamedPropertySetter($outputArray, $additionalIndent . "        ", $interface, $namedSetterOperation, "propertyDescriptor.value()");
-            
+            if ($namedSetterOperation->extendedAttributes->{CallNamedSetterOnlyForSupportedProperties}) {
+                push(@$outputArray, $additionalIndent . "    if (!isPropertySupported)\n");
+                push(@$outputArray, $additionalIndent . "        return JSObject::defineOwnProperty(object, state, propertyName, propertyDescriptor, shouldThrow);\n");
+            }
             # 2.2.3. Return true.
             push(@$outputArray, $additionalIndent . "        return true;\n");
         }
@@ -1810,7 +1816,6 @@
 {
     my $interface = shift;
     return $interface->extendedAttributes->{CustomGetOwnPropertySlot}
-        || $interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor}
         || $interface->extendedAttributes->{Plugin}
         || GetIndexedGetterOperation($interface)
         || GetNamedGetterOperation($interface);
@@ -1836,6 +1841,9 @@
 sub InstanceOverridesDefineOwnProperty
 {
     my $interface = shift;
+
+    return 0 if $interface->extendedAttributes->{DefaultDefineOwnProperty};
+
     return $interface->extendedAttributes->{CustomDefineOwnProperty}
         || GetIndexedSetterOperation($interface)
         || GetNamedSetterOperation($interface);
@@ -2530,7 +2538,7 @@
     my $namedGetterOperation = GetNamedGetterOperation($interface);
     my $indexedGetterOperation = GetIndexedGetterOperation($interface);
 
-    # FIXME: Why doesn't this also include Indexed Getters, [CustomGetOwnPropertySlot] and [CustomGetOwnPropertySlotAndDescriptor]
+    # FIXME: Why doesn't this also include Indexed Getters and [CustomGetOwnPropertySlot]
     if ($namedGetterOperation) {
         if ($codeGenerator->InheritsExtendedAttribute($interface, "OverrideBuiltins")) {
             $structureFlags{"JSC::GetOwnPropertySlotIsImpure"} = 1;
@@ -2793,10 +2801,6 @@
         push(@headerContent, "    void finishCreation(JSC::VM&);\n");
     }
 
-    if ($interface->extendedAttributes->{CustomGetOwnPropertySlotAndDescriptor}) {
-        push(@headerContent, "    bool getOwnPropertySlotDelegate(JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);\n");
-    }
-
     push(@headerContent, "};\n\n");
 
     if (ShouldGenerateWrapperOwnerCode($hasParent, $interface)) {

Modified: trunk/Source/WebCore/bindings/scripts/IDLAttributes.json (219621 => 219622)


--- trunk/Source/WebCore/bindings/scripts/IDLAttributes.json	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/bindings/scripts/IDLAttributes.json	2017-07-18 20:12:15 UTC (rev 219622)
@@ -34,6 +34,9 @@
         "CallbackNeedsOperatorEqual": {
             "contextsAllowed": ["callback-function"]
         },
+        "CallNamedSetterOnlyForSupportedProperties": {
+            "contextsAllowed": ["operation"]
+        },
         "CallWith": {
             "contextsAllowed": ["attribute", "operation"],
             "values": ["Document", "ScriptExecutionContext", "ScriptState", "GlobalObject", "ActiveWindow", "FirstWindow", "ResponsibleDocument", "World"]
@@ -99,9 +102,6 @@
         "CustomGetOwnPropertySlot": {
             "contextsAllowed": ["interface"]
         },
-        "CustomGetOwnPropertySlotAndDescriptor": {
-            "contextsAllowed": ["interface"]
-        },
         "CustomGetPrototype": {
             "contextsAllowed": ["interface"]
         },
@@ -142,6 +142,9 @@
             "contextsAllowed": ["interface", "attribute", "operation"],
             "values": ["", "ReadDOM", "Getter"]
         },
+        "DefaultDefineOwnProperty": {
+            "contextsAllowed": ["interface"]
+        },
         "DoNotCheckConstants": {
             "contextsAllowed": ["interface"]
         },

Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp (0 => 219622)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp	                        (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp	2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,401 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "JSTestNamedSetterWithIndexedGetter.h"
+
+#include "JSDOMAbstractOperations.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConstructorNotConstructable.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMExceptionHandling.h"
+#include "JSDOMOperation.h"
+#include "JSDOMWrapperCache.h"
+#include "URL.h"
+#include <runtime/FunctionPrototype.h>
+#include <runtime/JSCInlines.h>
+#include <runtime/PropertyNameArray.h>
+#include <wtf/GetPtr.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+// Functions
+
+JSC::EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetter(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetter(JSC::ExecState*);
+
+// Attributes
+
+JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestNamedSetterWithIndexedGetterConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+
+class JSTestNamedSetterWithIndexedGetterPrototype : public JSC::JSNonFinalObject {
+public:
+    using Base = JSC::JSNonFinalObject;
+    static JSTestNamedSetterWithIndexedGetterPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
+    {
+        JSTestNamedSetterWithIndexedGetterPrototype* ptr = new (NotNull, JSC::allocateCell<JSTestNamedSetterWithIndexedGetterPrototype>(vm.heap)) JSTestNamedSetterWithIndexedGetterPrototype(vm, globalObject, structure);
+        ptr->finishCreation(vm);
+        return ptr;
+    }
+
+    DECLARE_INFO;
+    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+private:
+    JSTestNamedSetterWithIndexedGetterPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+        : JSC::JSNonFinalObject(vm, structure)
+    {
+    }
+
+    void finishCreation(JSC::VM&);
+};
+
+using JSTestNamedSetterWithIndexedGetterConstructor = JSDOMConstructorNotConstructable<JSTestNamedSetterWithIndexedGetter>;
+
+template<> JSValue JSTestNamedSetterWithIndexedGetterConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
+{
+    UNUSED_PARAM(vm);
+    return globalObject.functionPrototype();
+}
+
+template<> void JSTestNamedSetterWithIndexedGetterConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    putDirect(vm, vm.propertyNames->prototype, JSTestNamedSetterWithIndexedGetter::prototype(vm, globalObject), DontDelete | ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestNamedSetterWithIndexedGetter"))), ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
+}
+
+template<> const ClassInfo JSTestNamedSetterWithIndexedGetterConstructor::s_info = { "TestNamedSetterWithIndexedGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterConstructor) };
+
+/* Hash table for prototype */
+
+static const HashTableValue JSTestNamedSetterWithIndexedGetterPrototypeTableValues[] =
+{
+    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestNamedSetterWithIndexedGetterConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestNamedSetterWithIndexedGetterConstructor) } },
+    { "namedSetter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetter), (intptr_t) (2) } },
+    { "indexedSetter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetter), (intptr_t) (1) } },
+};
+
+const ClassInfo JSTestNamedSetterWithIndexedGetterPrototype::s_info = { "TestNamedSetterWithIndexedGetterPrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterPrototype) };
+
+void JSTestNamedSetterWithIndexedGetterPrototype::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    reifyStaticProperties(vm, JSTestNamedSetterWithIndexedGetterPrototypeTableValues, *this);
+}
+
+const ClassInfo JSTestNamedSetterWithIndexedGetter::s_info = { "TestNamedSetterWithIndexedGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetter) };
+
+JSTestNamedSetterWithIndexedGetter::JSTestNamedSetterWithIndexedGetter(Structure* structure, JSDOMGlobalObject& globalObject, Ref<TestNamedSetterWithIndexedGetter>&& impl)
+    : JSDOMWrapper<TestNamedSetterWithIndexedGetter>(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSTestNamedSetterWithIndexedGetter::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(vm, info()));
+
+}
+
+JSObject* JSTestNamedSetterWithIndexedGetter::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    return JSTestNamedSetterWithIndexedGetterPrototype::create(vm, &globalObject, JSTestNamedSetterWithIndexedGetterPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+JSObject* JSTestNamedSetterWithIndexedGetter::prototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    return getDOMPrototype<JSTestNamedSetterWithIndexedGetter>(vm, globalObject);
+}
+
+JSValue JSTestNamedSetterWithIndexedGetter::getConstructor(VM& vm, const JSGlobalObject* globalObject)
+{
+    return getDOMConstructor<JSTestNamedSetterWithIndexedGetterConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
+}
+
+void JSTestNamedSetterWithIndexedGetter::destroy(JSC::JSCell* cell)
+{
+    JSTestNamedSetterWithIndexedGetter* thisObject = static_cast<JSTestNamedSetterWithIndexedGetter*>(cell);
+    thisObject->JSTestNamedSetterWithIndexedGetter::~JSTestNamedSetterWithIndexedGetter();
+}
+
+bool JSTestNamedSetterWithIndexedGetter::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (auto index = parseIndex(propertyName)) {
+        if (index.value() < thisObject->wrapped().length()) {
+            auto value = toJS<IDLDOMString>(*state, thisObject->wrapped().indexedSetter(index.value()));
+            slot.setValue(thisObject, ReadOnly, value);
+            return true;
+        }
+        return JSObject::getOwnPropertySlot(object, state, propertyName, slot);
+    }
+    using GetterIDLType = IDLDOMString;
+    auto getterFunctor = [] (auto& thisObject, auto propertyName) -> std::optional<typename GetterIDLType::ImplementationType> {
+        auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName));
+        if (!GetterIDLType::isNullValue(result))
+            return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) };
+        return std::nullopt;
+    };
+    if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) {
+        auto value = toJS<IDLDOMString>(*state, WTFMove(namedProperty.value()));
+        slot.setValue(thisObject, 0, value);
+        return true;
+    }
+    return JSObject::getOwnPropertySlot(object, state, propertyName, slot);
+}
+
+bool JSTestNamedSetterWithIndexedGetter::getOwnPropertySlotByIndex(JSObject* object, ExecState* state, unsigned index, PropertySlot& slot)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (LIKELY(index <= MAX_ARRAY_INDEX)) {
+        if (index < thisObject->wrapped().length()) {
+            auto value = toJS<IDLDOMString>(*state, thisObject->wrapped().indexedSetter(index));
+            slot.setValue(thisObject, ReadOnly, value);
+            return true;
+        }
+        return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);
+    }
+    auto propertyName = Identifier::from(state, index);
+    using GetterIDLType = IDLDOMString;
+    auto getterFunctor = [] (auto& thisObject, auto propertyName) -> std::optional<typename GetterIDLType::ImplementationType> {
+        auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName));
+        if (!GetterIDLType::isNullValue(result))
+            return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) };
+        return std::nullopt;
+    };
+    if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) {
+        auto value = toJS<IDLDOMString>(*state, WTFMove(namedProperty.value()));
+        slot.setValue(thisObject, 0, value);
+        return true;
+    }
+    return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);
+}
+
+void JSTestNamedSetterWithIndexedGetter::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(object);
+    ASSERT_GC_OBJECT_INHERITS(object, info());
+    for (unsigned i = 0, count = thisObject->wrapped().length(); i < count; ++i)
+        propertyNames.add(Identifier::from(state, i));
+    for (auto& propertyName : thisObject->wrapped().supportedPropertyNames())
+        propertyNames.add(Identifier::fromString(state, propertyName));
+    JSObject::getOwnPropertyNames(object, state, propertyNames, mode);
+}
+
+bool JSTestNamedSetterWithIndexedGetter::put(JSCell* cell, ExecState* state, PropertyName propertyName, JSValue value, PutPropertySlot& putPropertySlot)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+    if (!propertyName.isSymbol()) {
+        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+        JSValue prototype = thisObject->getPrototypeDirect();
+        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
+            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+            auto nativeValue = convert<IDLDOMString>(*state, value);
+            RETURN_IF_EXCEPTION(throwScope, true);
+            thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+            return true;
+        }
+    }
+
+    return JSObject::put(thisObject, state, propertyName, value, putPropertySlot);
+}
+
+bool JSTestNamedSetterWithIndexedGetter::putByIndex(JSCell* cell, ExecState* state, unsigned index, JSValue value, bool shouldThrow)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+    auto propertyName = Identifier::from(state, index);
+    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+    JSValue prototype = thisObject->getPrototypeDirect();
+    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
+        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+        auto nativeValue = convert<IDLDOMString>(*state, value);
+        RETURN_IF_EXCEPTION(throwScope, true);
+        thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+        return true;
+    }
+
+    return JSObject::putByIndex(cell, state, index, value, shouldThrow);
+}
+
+bool JSTestNamedSetterWithIndexedGetter::defineOwnProperty(JSObject* object, ExecState* state, PropertyName propertyName, const PropertyDescriptor& propertyDescriptor, bool shouldThrow)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+    if (parseIndex(propertyName))
+        return false;
+
+    if (!propertyName.isSymbol()) {
+        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+        if (!JSObject::getOwnPropertySlot(thisObject, state, propertyName, slot)) {
+            if (!propertyDescriptor.isDataDescriptor())
+                return false;
+            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+            auto nativeValue = convert<IDLDOMString>(*state, propertyDescriptor.value());
+            RETURN_IF_EXCEPTION(throwScope, true);
+            thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+            return true;
+        }
+    }
+
+    PropertyDescriptor newPropertyDescriptor = propertyDescriptor;
+    newPropertyDescriptor.setConfigurable(true);
+    return JSObject::defineOwnProperty(object, state, propertyName, newPropertyDescriptor, shouldThrow);
+}
+
+template<> inline JSTestNamedSetterWithIndexedGetter* IDLOperation<JSTestNamedSetterWithIndexedGetter>::cast(ExecState& state)
+{
+    return jsDynamicDowncast<JSTestNamedSetterWithIndexedGetter*>(state.vm(), state.thisValue());
+}
+
+EncodedJSValue jsTestNamedSetterWithIndexedGetterConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    VM& vm = state->vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    auto* prototype = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterPrototype*>(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!prototype))
+        return throwVMTypeError(state, throwScope);
+    return JSValue::encode(JSTestNamedSetterWithIndexedGetter::getConstructor(state->vm(), prototype->globalObject()));
+}
+
+bool setJSTestNamedSetterWithIndexedGetterConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    VM& vm = state->vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    auto* prototype = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterPrototype*>(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!prototype)) {
+        throwVMTypeError(state, throwScope);
+        return false;
+    }
+    // Shadowing a built-in constructor
+    return prototype->putDirect(state->vm(), state->propertyNames().constructor, JSValue::decode(encodedValue));
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetterBody(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto& impl = castedThis->wrapped();
+    if (UNLIKELY(state->argumentCount() < 2))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto name = convert<IDLDOMString>(*state, state->uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    auto value = convert<IDLDOMString>(*state, state->uncheckedArgument(1));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.namedSetter(WTFMove(name), WTFMove(value));
+    return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetter(ExecState* state)
+{
+    return IDLOperation<JSTestNamedSetterWithIndexedGetter>::call<jsTestNamedSetterWithIndexedGetterPrototypeFunctionNamedSetterBody>(*state, "namedSetter");
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetterBody(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto& impl = castedThis->wrapped();
+    if (UNLIKELY(state->argumentCount() < 1))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto index = convert<IDLUnsignedLong>(*state, state->uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS<IDLDOMString>(*state, impl.indexedSetter(WTFMove(index))));
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetter(ExecState* state)
+{
+    return IDLOperation<JSTestNamedSetterWithIndexedGetter>::call<jsTestNamedSetterWithIndexedGetterPrototypeFunctionIndexedSetterBody>(*state, "indexedSetter");
+}
+
+bool JSTestNamedSetterWithIndexedGetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
+{
+    UNUSED_PARAM(handle);
+    UNUSED_PARAM(visitor);
+    return false;
+}
+
+void JSTestNamedSetterWithIndexedGetterOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
+{
+    auto* jsTestNamedSetterWithIndexedGetter = static_cast<JSTestNamedSetterWithIndexedGetter*>(handle.slot()->asCell());
+    auto& world = *static_cast<DOMWrapperWorld*>(context);
+    uncacheWrapper(world, &jsTestNamedSetterWithIndexedGetter->wrapped(), jsTestNamedSetterWithIndexedGetter);
+}
+
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern "C" { extern void (*const __identifier("??_7TestNamedSetterWithIndexedGetter@WebCore@@6B@")[])(); }
+#else
+extern "C" { extern void* _ZTVN7WebCore32TestNamedSetterWithIndexedGetterE[]; }
+#endif
+#endif
+
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<TestNamedSetterWithIndexedGetter>&& impl)
+{
+
+#if ENABLE(BINDING_INTEGRITY)
+    void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
+#if PLATFORM(WIN)
+    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7TestNamedSetterWithIndexedGetter@WebCore@@6B@"));
+#else
+    void* expectedVTablePointer = &_ZTVN7WebCore32TestNamedSetterWithIndexedGetterE[2];
+#endif
+
+    // If this fails TestNamedSetterWithIndexedGetter does not have a vtable, so you need to add the
+    // ImplementationLacksVTable attribute to the interface definition
+    static_assert(std::is_polymorphic<TestNamedSetterWithIndexedGetter>::value, "TestNamedSetterWithIndexedGetter is not polymorphic");
+
+    // If you hit this assertion you either have a use after free bug, or
+    // TestNamedSetterWithIndexedGetter has subclasses. If TestNamedSetterWithIndexedGetter has subclasses that get passed
+    // to toJS() we currently require TestNamedSetterWithIndexedGetter you to opt out of binding hardening
+    // by adding the SkipVTableValidation attribute to the interface IDL definition
+    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+    return createWrapper<TestNamedSetterWithIndexedGetter>(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNamedSetterWithIndexedGetter& impl)
+{
+    return wrap(state, globalObject, impl);
+}
+
+TestNamedSetterWithIndexedGetter* JSTestNamedSetterWithIndexedGetter::toWrapped(JSC::VM& vm, JSC::JSValue value)
+{
+    if (auto* wrapper = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetter*>(vm, value))
+        return &wrapper->wrapped();
+    return nullptr;
+}
+
+}

Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h (0 => 219622)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h	                        (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h	2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,93 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include "JSDOMWrapper.h"
+#include "TestNamedSetterWithIndexedGetter.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+class JSTestNamedSetterWithIndexedGetter : public JSDOMWrapper<TestNamedSetterWithIndexedGetter> {
+public:
+    using Base = JSDOMWrapper<TestNamedSetterWithIndexedGetter>;
+    static JSTestNamedSetterWithIndexedGetter* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<TestNamedSetterWithIndexedGetter>&& impl)
+    {
+        JSTestNamedSetterWithIndexedGetter* ptr = new (NotNull, JSC::allocateCell<JSTestNamedSetterWithIndexedGetter>(globalObject->vm().heap)) JSTestNamedSetterWithIndexedGetter(structure, *globalObject, WTFMove(impl));
+        ptr->finishCreation(globalObject->vm());
+        return ptr;
+    }
+
+    static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
+    static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
+    static TestNamedSetterWithIndexedGetter* toWrapped(JSC::VM&, JSC::JSValue);
+    static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);
+    static bool getOwnPropertySlotByIndex(JSC::JSObject*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
+    static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode = JSC::EnumerationMode());
+    static bool put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&);
+    static bool putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool shouldThrow);
+    static bool defineOwnProperty(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, const JSC::PropertyDescriptor&, bool shouldThrow);
+    static void destroy(JSC::JSCell*);
+
+    DECLARE_INFO;
+
+    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
+public:
+    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
+protected:
+    JSTestNamedSetterWithIndexedGetter(JSC::Structure*, JSDOMGlobalObject&, Ref<TestNamedSetterWithIndexedGetter>&&);
+
+    void finishCreation(JSC::VM&);
+};
+
+class JSTestNamedSetterWithIndexedGetterOwner : public JSC::WeakHandleOwner {
+public:
+    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
+    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, TestNamedSetterWithIndexedGetter*)
+{
+    static NeverDestroyed<JSTestNamedSetterWithIndexedGetterOwner> owner;
+    return &owner.get();
+}
+
+inline void* wrapperKey(TestNamedSetterWithIndexedGetter* wrappableObject)
+{
+    return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestNamedSetterWithIndexedGetter&);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNamedSetterWithIndexedGetter* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, Ref<TestNamedSetterWithIndexedGetter>&&);
+inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* state, JSDOMGlobalObject* globalObject, RefPtr<TestNamedSetterWithIndexedGetter>&& impl) { return impl ? toJSNewlyCreated(state, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template<> struct JSDOMWrapperConverterTraits<TestNamedSetterWithIndexedGetter> {
+    using WrapperClass = JSTestNamedSetterWithIndexedGetter;
+    using ToWrappedReturnType = TestNamedSetterWithIndexedGetter*;
+};
+
+} // namespace WebCore

Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp (0 => 219622)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp	                        (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp	2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,451 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "JSTestNamedSetterWithIndexedGetterAndSetter.h"
+
+#include "JSDOMAbstractOperations.h"
+#include "JSDOMBinding.h"
+#include "JSDOMConstructorNotConstructable.h"
+#include "JSDOMConvertNumbers.h"
+#include "JSDOMConvertStrings.h"
+#include "JSDOMExceptionHandling.h"
+#include "JSDOMOperation.h"
+#include "JSDOMWrapperCache.h"
+#include "URL.h"
+#include <runtime/FunctionPrototype.h>
+#include <runtime/JSCInlines.h>
+#include <runtime/PropertyNameArray.h>
+#include <wtf/GetPtr.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+// Functions
+
+JSC::EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetter(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter(JSC::ExecState*);
+
+// Attributes
+
+JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestNamedSetterWithIndexedGetterAndSetterConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+
+class JSTestNamedSetterWithIndexedGetterAndSetterPrototype : public JSC::JSNonFinalObject {
+public:
+    using Base = JSC::JSNonFinalObject;
+    static JSTestNamedSetterWithIndexedGetterAndSetterPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
+    {
+        JSTestNamedSetterWithIndexedGetterAndSetterPrototype* ptr = new (NotNull, JSC::allocateCell<JSTestNamedSetterWithIndexedGetterAndSetterPrototype>(vm.heap)) JSTestNamedSetterWithIndexedGetterAndSetterPrototype(vm, globalObject, structure);
+        ptr->finishCreation(vm);
+        return ptr;
+    }
+
+    DECLARE_INFO;
+    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+private:
+    JSTestNamedSetterWithIndexedGetterAndSetterPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
+        : JSC::JSNonFinalObject(vm, structure)
+    {
+    }
+
+    void finishCreation(JSC::VM&);
+};
+
+using JSTestNamedSetterWithIndexedGetterAndSetterConstructor = JSDOMConstructorNotConstructable<JSTestNamedSetterWithIndexedGetterAndSetter>;
+
+template<> JSValue JSTestNamedSetterWithIndexedGetterAndSetterConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
+{
+    UNUSED_PARAM(vm);
+    return globalObject.functionPrototype();
+}
+
+template<> void JSTestNamedSetterWithIndexedGetterAndSetterConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    putDirect(vm, vm.propertyNames->prototype, JSTestNamedSetterWithIndexedGetterAndSetter::prototype(vm, globalObject), DontDelete | ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestNamedSetterWithIndexedGetterAndSetter"))), ReadOnly | DontEnum);
+    putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
+}
+
+template<> const ClassInfo JSTestNamedSetterWithIndexedGetterAndSetterConstructor::s_info = { "TestNamedSetterWithIndexedGetterAndSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterAndSetterConstructor) };
+
+/* Hash table for prototype */
+
+static const HashTableValue JSTestNamedSetterWithIndexedGetterAndSetterPrototypeTableValues[] =
+{
+    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestNamedSetterWithIndexedGetterAndSetterConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestNamedSetterWithIndexedGetterAndSetterConstructor) } },
+    { "namedSetter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetter), (intptr_t) (2) } },
+    { "indexedSetter", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter), (intptr_t) (1) } },
+};
+
+const ClassInfo JSTestNamedSetterWithIndexedGetterAndSetterPrototype::s_info = { "TestNamedSetterWithIndexedGetterAndSetterPrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterAndSetterPrototype) };
+
+void JSTestNamedSetterWithIndexedGetterAndSetterPrototype::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    reifyStaticProperties(vm, JSTestNamedSetterWithIndexedGetterAndSetterPrototypeTableValues, *this);
+}
+
+const ClassInfo JSTestNamedSetterWithIndexedGetterAndSetter::s_info = { "TestNamedSetterWithIndexedGetterAndSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestNamedSetterWithIndexedGetterAndSetter) };
+
+JSTestNamedSetterWithIndexedGetterAndSetter::JSTestNamedSetterWithIndexedGetterAndSetter(Structure* structure, JSDOMGlobalObject& globalObject, Ref<TestNamedSetterWithIndexedGetterAndSetter>&& impl)
+    : JSDOMWrapper<TestNamedSetterWithIndexedGetterAndSetter>(structure, globalObject, WTFMove(impl))
+{
+}
+
+void JSTestNamedSetterWithIndexedGetterAndSetter::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    ASSERT(inherits(vm, info()));
+
+}
+
+JSObject* JSTestNamedSetterWithIndexedGetterAndSetter::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    return JSTestNamedSetterWithIndexedGetterAndSetterPrototype::create(vm, &globalObject, JSTestNamedSetterWithIndexedGetterAndSetterPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
+}
+
+JSObject* JSTestNamedSetterWithIndexedGetterAndSetter::prototype(VM& vm, JSDOMGlobalObject& globalObject)
+{
+    return getDOMPrototype<JSTestNamedSetterWithIndexedGetterAndSetter>(vm, globalObject);
+}
+
+JSValue JSTestNamedSetterWithIndexedGetterAndSetter::getConstructor(VM& vm, const JSGlobalObject* globalObject)
+{
+    return getDOMConstructor<JSTestNamedSetterWithIndexedGetterAndSetterConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
+}
+
+void JSTestNamedSetterWithIndexedGetterAndSetter::destroy(JSC::JSCell* cell)
+{
+    JSTestNamedSetterWithIndexedGetterAndSetter* thisObject = static_cast<JSTestNamedSetterWithIndexedGetterAndSetter*>(cell);
+    thisObject->JSTestNamedSetterWithIndexedGetterAndSetter::~JSTestNamedSetterWithIndexedGetterAndSetter();
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (auto index = parseIndex(propertyName)) {
+        if (index.value() < thisObject->wrapped().length()) {
+            auto value = toJS<IDLDOMString>(*state, thisObject->wrapped().indexedSetter(index.value()));
+            slot.setValue(thisObject, 0, value);
+            return true;
+        }
+        return JSObject::getOwnPropertySlot(object, state, propertyName, slot);
+    }
+    using GetterIDLType = IDLDOMString;
+    auto getterFunctor = [] (auto& thisObject, auto propertyName) -> std::optional<typename GetterIDLType::ImplementationType> {
+        auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName));
+        if (!GetterIDLType::isNullValue(result))
+            return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) };
+        return std::nullopt;
+    };
+    if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) {
+        auto value = toJS<IDLDOMString>(*state, WTFMove(namedProperty.value()));
+        slot.setValue(thisObject, 0, value);
+        return true;
+    }
+    return JSObject::getOwnPropertySlot(object, state, propertyName, slot);
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::getOwnPropertySlotByIndex(JSObject* object, ExecState* state, unsigned index, PropertySlot& slot)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    if (LIKELY(index <= MAX_ARRAY_INDEX)) {
+        if (index < thisObject->wrapped().length()) {
+            auto value = toJS<IDLDOMString>(*state, thisObject->wrapped().indexedSetter(index));
+            slot.setValue(thisObject, 0, value);
+            return true;
+        }
+        return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);
+    }
+    auto propertyName = Identifier::from(state, index);
+    using GetterIDLType = IDLDOMString;
+    auto getterFunctor = [] (auto& thisObject, auto propertyName) -> std::optional<typename GetterIDLType::ImplementationType> {
+        auto result = thisObject.wrapped().namedItem(propertyNameToAtomicString(propertyName));
+        if (!GetterIDLType::isNullValue(result))
+            return typename GetterIDLType::ImplementationType { GetterIDLType::extractValueFromNullable(result) };
+        return std::nullopt;
+    };
+    if (auto namedProperty = accessVisibleNamedProperty<OverrideBuiltins::No>(*state, *thisObject, propertyName, getterFunctor)) {
+        auto value = toJS<IDLDOMString>(*state, WTFMove(namedProperty.value()));
+        slot.setValue(thisObject, 0, value);
+        return true;
+    }
+    return JSObject::getOwnPropertySlotByIndex(object, state, index, slot);
+}
+
+void JSTestNamedSetterWithIndexedGetterAndSetter::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(object);
+    ASSERT_GC_OBJECT_INHERITS(object, info());
+    for (unsigned i = 0, count = thisObject->wrapped().length(); i < count; ++i)
+        propertyNames.add(Identifier::from(state, i));
+    for (auto& propertyName : thisObject->wrapped().supportedPropertyNames())
+        propertyNames.add(Identifier::fromString(state, propertyName));
+    JSObject::getOwnPropertyNames(object, state, propertyNames, mode);
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::put(JSCell* cell, ExecState* state, PropertyName propertyName, JSValue value, PutPropertySlot& putPropertySlot)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+    if (auto index = parseIndex(propertyName)) {
+        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+        auto nativeValue = convert<IDLDOMString>(*state, value);
+        RETURN_IF_EXCEPTION(throwScope, true);
+        thisObject->wrapped().indexedSetter(index.value(), WTFMove(nativeValue));
+        return true;
+    }
+
+    if (!propertyName.isSymbol()) {
+        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+        JSValue prototype = thisObject->getPrototypeDirect();
+        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
+            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+            auto nativeValue = convert<IDLDOMString>(*state, value);
+            RETURN_IF_EXCEPTION(throwScope, true);
+            thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+            return true;
+        }
+    }
+
+    return JSObject::put(thisObject, state, propertyName, value, putPropertySlot);
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::putByIndex(JSCell* cell, ExecState* state, unsigned index, JSValue value, bool shouldThrow)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+    if (LIKELY(index <= MAX_ARRAY_INDEX)) {
+        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+        auto nativeValue = convert<IDLDOMString>(*state, value);
+        RETURN_IF_EXCEPTION(throwScope, true);
+        thisObject->wrapped().indexedSetter(index, WTFMove(nativeValue));
+        return true;
+    }
+
+    auto propertyName = Identifier::from(state, index);
+    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+    JSValue prototype = thisObject->getPrototypeDirect();
+    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
+        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+        auto nativeValue = convert<IDLDOMString>(*state, value);
+        RETURN_IF_EXCEPTION(throwScope, true);
+        thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+        return true;
+    }
+
+    return JSObject::putByIndex(cell, state, index, value, shouldThrow);
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetter::defineOwnProperty(JSObject* object, ExecState* state, PropertyName propertyName, const PropertyDescriptor& propertyDescriptor, bool shouldThrow)
+{
+    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+
+    if (auto index = parseIndex(propertyName)) {
+        if (!propertyDescriptor.isDataDescriptor())
+            return false;
+        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+        auto nativeValue = convert<IDLDOMString>(*state, propertyDescriptor.value());
+        RETURN_IF_EXCEPTION(throwScope, true);
+        thisObject->wrapped().indexedSetter(index.value(), WTFMove(nativeValue));
+        return true;
+    }
+
+    if (!propertyName.isSymbol()) {
+        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
+        if (!JSObject::getOwnPropertySlot(thisObject, state, propertyName, slot)) {
+            if (!propertyDescriptor.isDataDescriptor())
+                return false;
+            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
+            auto nativeValue = convert<IDLDOMString>(*state, propertyDescriptor.value());
+            RETURN_IF_EXCEPTION(throwScope, true);
+            thisObject->wrapped().namedSetter(propertyNameToString(propertyName), WTFMove(nativeValue));
+            return true;
+        }
+    }
+
+    PropertyDescriptor newPropertyDescriptor = propertyDescriptor;
+    newPropertyDescriptor.setConfigurable(true);
+    return JSObject::defineOwnProperty(object, state, propertyName, newPropertyDescriptor, shouldThrow);
+}
+
+template<> inline JSTestNamedSetterWithIndexedGetterAndSetter* IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::cast(ExecState& state)
+{
+    return jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterAndSetter*>(state.vm(), state.thisValue());
+}
+
+EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    VM& vm = state->vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    auto* prototype = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterAndSetterPrototype*>(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!prototype))
+        return throwVMTypeError(state, throwScope);
+    return JSValue::encode(JSTestNamedSetterWithIndexedGetterAndSetter::getConstructor(state->vm(), prototype->globalObject()));
+}
+
+bool setJSTestNamedSetterWithIndexedGetterAndSetterConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    VM& vm = state->vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    auto* prototype = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterAndSetterPrototype*>(vm, JSValue::decode(thisValue));
+    if (UNLIKELY(!prototype)) {
+        throwVMTypeError(state, throwScope);
+        return false;
+    }
+    // Shadowing a built-in constructor
+    return prototype->putDirect(state->vm(), state->propertyNames().constructor, JSValue::decode(encodedValue));
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetterBody(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto& impl = castedThis->wrapped();
+    if (UNLIKELY(state->argumentCount() < 2))
+        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+    auto name = convert<IDLDOMString>(*state, state->uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    auto value = convert<IDLDOMString>(*state, state->uncheckedArgument(1));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.namedSetter(WTFMove(name), WTFMove(value));
+    return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetter(ExecState* state)
+{
+    return IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::call<jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionNamedSetterBody>(*state, "namedSetter");
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter1Body(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto& impl = castedThis->wrapped();
+    auto index = convert<IDLUnsignedLong>(*state, state->uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    auto value = convert<IDLDOMString>(*state, state->uncheckedArgument(1));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.indexedSetter(WTFMove(index), WTFMove(value));
+    return JSValue::encode(jsUndefined());
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter2Body(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto& impl = castedThis->wrapped();
+    auto index = convert<IDLUnsignedLong>(*state, state->uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS<IDLDOMString>(*state, impl.indexedSetter(WTFMove(index))));
+}
+
+static inline JSC::EncodedJSValue jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetterOverloadDispatcher(JSC::ExecState* state, typename IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    VM& vm = state->vm();
+    UNUSED_PARAM(vm);
+    size_t argsCount = std::min<size_t>(2, state->argumentCount());
+    if (argsCount == 1) {
+        return jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter2Body(state, castedThis, throwScope);
+    }
+    if (argsCount == 2) {
+        return jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter1Body(state, castedThis, throwScope);
+    }
+    return argsCount < 1 ? throwVMError(state, throwScope, createNotEnoughArgumentsError(state)) : throwVMTypeError(state, throwScope);
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetter(ExecState* state)
+{
+    return IDLOperation<JSTestNamedSetterWithIndexedGetterAndSetter>::call<jsTestNamedSetterWithIndexedGetterAndSetterPrototypeFunctionIndexedSetterOverloadDispatcher>(*state, "indexedSetter");
+}
+
+bool JSTestNamedSetterWithIndexedGetterAndSetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
+{
+    UNUSED_PARAM(handle);
+    UNUSED_PARAM(visitor);
+    return false;
+}
+
+void JSTestNamedSetterWithIndexedGetterAndSetterOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
+{
+    auto* jsTestNamedSetterWithIndexedGetterAndSetter = static_cast<JSTestNamedSetterWithIndexedGetterAndSetter*>(handle.slot()->asCell());
+    auto& world = *static_cast<DOMWrapperWorld*>(context);
+    uncacheWrapper(world, &jsTestNamedSetterWithIndexedGetterAndSetter->wrapped(), jsTestNamedSetterWithIndexedGetterAndSetter);
+}
+
+#if ENABLE(BINDING_INTEGRITY)
+#if PLATFORM(WIN)
+#pragma warning(disable: 4483)
+extern "C" { extern void (*const __identifier("??_7TestNamedSetterWithIndexedGetterAndSetter@WebCore@@6B@")[])(); }
+#else
+extern "C" { extern void* _ZTVN7WebCore41TestNamedSetterWithIndexedGetterAndSetterE[]; }
+#endif
+#endif
+
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<TestNamedSetterWithIndexedGetterAndSetter>&& impl)
+{
+
+#if ENABLE(BINDING_INTEGRITY)
+    void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
+#if PLATFORM(WIN)
+    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7TestNamedSetterWithIndexedGetterAndSetter@WebCore@@6B@"));
+#else
+    void* expectedVTablePointer = &_ZTVN7WebCore41TestNamedSetterWithIndexedGetterAndSetterE[2];
+#endif
+
+    // If this fails TestNamedSetterWithIndexedGetterAndSetter does not have a vtable, so you need to add the
+    // ImplementationLacksVTable attribute to the interface definition
+    static_assert(std::is_polymorphic<TestNamedSetterWithIndexedGetterAndSetter>::value, "TestNamedSetterWithIndexedGetterAndSetter is not polymorphic");
+
+    // If you hit this assertion you either have a use after free bug, or
+    // TestNamedSetterWithIndexedGetterAndSetter has subclasses. If TestNamedSetterWithIndexedGetterAndSetter has subclasses that get passed
+    // to toJS() we currently require TestNamedSetterWithIndexedGetterAndSetter you to opt out of binding hardening
+    // by adding the SkipVTableValidation attribute to the interface IDL definition
+    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
+#endif
+    return createWrapper<TestNamedSetterWithIndexedGetterAndSetter>(globalObject, WTFMove(impl));
+}
+
+JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNamedSetterWithIndexedGetterAndSetter& impl)
+{
+    return wrap(state, globalObject, impl);
+}
+
+TestNamedSetterWithIndexedGetterAndSetter* JSTestNamedSetterWithIndexedGetterAndSetter::toWrapped(JSC::VM& vm, JSC::JSValue value)
+{
+    if (auto* wrapper = jsDynamicDowncast<JSTestNamedSetterWithIndexedGetterAndSetter*>(vm, value))
+        return &wrapper->wrapped();
+    return nullptr;
+}
+
+}

Added: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h (0 => 219622)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h	                        (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h	2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,93 @@
+/*
+    This file is part of the WebKit open source project.
+    This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#pragma once
+
+#include "JSDOMWrapper.h"
+#include "TestNamedSetterWithIndexedGetterAndSetter.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+class JSTestNamedSetterWithIndexedGetterAndSetter : public JSDOMWrapper<TestNamedSetterWithIndexedGetterAndSetter> {
+public:
+    using Base = JSDOMWrapper<TestNamedSetterWithIndexedGetterAndSetter>;
+    static JSTestNamedSetterWithIndexedGetterAndSetter* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<TestNamedSetterWithIndexedGetterAndSetter>&& impl)
+    {
+        JSTestNamedSetterWithIndexedGetterAndSetter* ptr = new (NotNull, JSC::allocateCell<JSTestNamedSetterWithIndexedGetterAndSetter>(globalObject->vm().heap)) JSTestNamedSetterWithIndexedGetterAndSetter(structure, *globalObject, WTFMove(impl));
+        ptr->finishCreation(globalObject->vm());
+        return ptr;
+    }
+
+    static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
+    static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
+    static TestNamedSetterWithIndexedGetterAndSetter* toWrapped(JSC::VM&, JSC::JSValue);
+    static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);
+    static bool getOwnPropertySlotByIndex(JSC::JSObject*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
+    static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode = JSC::EnumerationMode());
+    static bool put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&);
+    static bool putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool shouldThrow);
+    static bool defineOwnProperty(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, const JSC::PropertyDescriptor&, bool shouldThrow);
+    static void destroy(JSC::JSCell*);
+
+    DECLARE_INFO;
+
+    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+    {
+        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
+    }
+
+    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
+public:
+    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
+protected:
+    JSTestNamedSetterWithIndexedGetterAndSetter(JSC::Structure*, JSDOMGlobalObject&, Ref<TestNamedSetterWithIndexedGetterAndSetter>&&);
+
+    void finishCreation(JSC::VM&);
+};
+
+class JSTestNamedSetterWithIndexedGetterAndSetterOwner : public JSC::WeakHandleOwner {
+public:
+    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
+    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
+};
+
+inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, TestNamedSetterWithIndexedGetterAndSetter*)
+{
+    static NeverDestroyed<JSTestNamedSetterWithIndexedGetterAndSetterOwner> owner;
+    return &owner.get();
+}
+
+inline void* wrapperKey(TestNamedSetterWithIndexedGetterAndSetter* wrappableObject)
+{
+    return wrappableObject;
+}
+
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, TestNamedSetterWithIndexedGetterAndSetter&);
+inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TestNamedSetterWithIndexedGetterAndSetter* impl) { return impl ? toJS(state, globalObject, *impl) : JSC::jsNull(); }
+JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, Ref<TestNamedSetterWithIndexedGetterAndSetter>&&);
+inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* state, JSDOMGlobalObject* globalObject, RefPtr<TestNamedSetterWithIndexedGetterAndSetter>&& impl) { return impl ? toJSNewlyCreated(state, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
+
+template<> struct JSDOMWrapperConverterTraits<TestNamedSetterWithIndexedGetterAndSetter> {
+    using WrapperClass = JSTestNamedSetterWithIndexedGetterAndSetter;
+    using ToWrappedReturnType = TestNamedSetterWithIndexedGetterAndSetter*;
+};
+
+} // namespace WebCore

Added: trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl (0 => 219622)


--- trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl	                        (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetter.idl	2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+interface TestNamedSetterWithIndexedGetter {
+    setter void namedSetter(DOMString name, DOMString value);
+    getter DOMString (DOMString name);
+
+    getter DOMString indexedSetter(unsigned long index);
+};

Added: trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl (0 => 219622)


--- trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl	                        (rev 0)
+++ trunk/Source/WebCore/bindings/scripts/test/TestNamedSetterWithIndexedGetterAndSetter.idl	2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+interface TestNamedSetterWithIndexedGetterAndSetter {
+    setter void namedSetter(DOMString name, DOMString value);
+    getter DOMString (DOMString name);
+
+    setter void indexedSetter(unsigned long index, DOMString value);
+    getter DOMString indexedSetter(unsigned long index);
+};

Modified: trunk/Source/WebCore/css/CSSAllInOne.cpp (219621 => 219622)


--- trunk/Source/WebCore/css/CSSAllInOne.cpp	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/css/CSSAllInOne.cpp	2017-07-18 20:12:15 UTC (rev 219622)
@@ -78,6 +78,7 @@
 #include "CSSSelector.cpp"
 #include "CSSSelectorList.cpp"
 #include "CSSShadowValue.cpp"
+#include "CSSStyleDeclaration.cpp"
 #include "CSSStyleRule.cpp"
 #include "CSSStyleSheet.cpp"
 #include "CSSSupportsRule.cpp"

Added: trunk/Source/WebCore/css/CSSStyleDeclaration.cpp (0 => 219622)


--- trunk/Source/WebCore/css/CSSStyleDeclaration.cpp	                        (rev 0)
+++ trunk/Source/WebCore/css/CSSStyleDeclaration.cpp	2017-07-18 20:12:15 UTC (rev 219622)
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "config.h"
+#include "CSSStyleDeclaration.h"
+
+#include "CSSPropertyNames.h"
+#include "CSSPropertyParser.h"
+#include "HashTools.h"
+#include "RuntimeEnabledFeatures.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+namespace {
+
+enum class PropertyNamePrefix {
+    None, Epub, CSS, Pixel, Pos, WebKit,
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+    Apple, KHTML,
+#endif
+};
+
+template<size_t prefixCStringLength>
+static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength])
+{
+    size_t prefixLength = prefixCStringLength - 1;
+
+    ASSERT(toASCIILower(propertyName[0]) == prefix[0]);
+    const size_t offset = 1;
+
+#ifndef NDEBUG
+    for (size_t i = 0; i < prefixLength; ++i)
+        ASSERT(isASCIILower(prefix[i]));
+    ASSERT(!prefix[prefixLength]);
+    ASSERT(propertyName.length());
+#endif
+
+    // The prefix within the property name must be followed by a capital letter.
+    // Other characters in the prefix within the property name must be lowercase.
+    if (propertyName.length() < prefixLength + 1)
+        return false;
+
+    for (size_t i = offset; i < prefixLength; ++i) {
+        if (propertyName[i] != prefix[i])
+            return false;
+    }
+
+    if (!isASCIIUpper(propertyName[prefixLength]))
+        return false;
+
+    return true;
+}
+
+static PropertyNamePrefix propertyNamePrefix(const StringImpl& propertyName)
+{
+    ASSERT(propertyName.length());
+
+    // First character of the prefix within the property name may be upper or lowercase.
+    UChar firstChar = toASCIILower(propertyName[0]);
+    switch (firstChar) {
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+    case 'a':
+        if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled() && matchesCSSPropertyNamePrefix(propertyName, "apple"))
+            return PropertyNamePrefix::Apple;
+        break;
+#endif
+    case 'c':
+        if (matchesCSSPropertyNamePrefix(propertyName, "css"))
+            return PropertyNamePrefix::CSS;
+        break;
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+    case 'k':
+        if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled() && matchesCSSPropertyNamePrefix(propertyName, "khtml"))
+            return PropertyNamePrefix::KHTML;
+        break;
+#endif
+    case 'e':
+        if (matchesCSSPropertyNamePrefix(propertyName, "epub"))
+            return PropertyNamePrefix::Epub;
+        break;
+    case 'p':
+        if (matchesCSSPropertyNamePrefix(propertyName, "pos"))
+            return PropertyNamePrefix::Pos;
+        if (matchesCSSPropertyNamePrefix(propertyName, "pixel"))
+            return PropertyNamePrefix::Pixel;
+        break;
+    case 'w':
+        if (matchesCSSPropertyNamePrefix(propertyName, "webkit"))
+            return PropertyNamePrefix::WebKit;
+        break;
+    default:
+        break;
+    }
+    return PropertyNamePrefix::None;
+}
+
+static inline void writeWebKitPrefix(char*& buffer)
+{
+    *buffer++ = '-';
+    *buffer++ = 'w';
+    *buffer++ = 'e';
+    *buffer++ = 'b';
+    *buffer++ = 'k';
+    *buffer++ = 'i';
+    *buffer++ = 't';
+    *buffer++ = '-';
+}
+
+static inline void writeEpubPrefix(char*& buffer)
+{
+    *buffer++ = '-';
+    *buffer++ = 'e';
+    *buffer++ = 'p';
+    *buffer++ = 'u';
+    *buffer++ = 'b';
+    *buffer++ = '-';
+}
+
+struct CSSPropertyInfo {
+    CSSPropertyID propertyID;
+    bool hadPixelOrPosPrefix;
+};
+
+static CSSPropertyInfo parseJavaScriptCSSPropertyName(const AtomicString& propertyName)
+{
+    using CSSPropertyInfoMap = HashMap<String, CSSPropertyInfo>;
+    static NeverDestroyed<CSSPropertyInfoMap> propertyInfoCache;
+
+    CSSPropertyInfo propertyInfo = { CSSPropertyInvalid, false };
+
+    auto* propertyNameString = propertyName.impl();
+    if (!propertyNameString)
+        return propertyInfo;
+    unsigned length = propertyNameString->length();
+    if (!length)
+        return propertyInfo;
+
+    propertyInfo = propertyInfoCache.get().get(propertyNameString);
+    if (propertyInfo.propertyID)
+        return propertyInfo;
+
+    bool hadPixelOrPosPrefix = false;
+
+    constexpr size_t bufferSize = maxCSSPropertyNameLength + 1;
+    char buffer[bufferSize];
+    char* bufferPtr = buffer;
+    const char* name = bufferPtr;
+
+    unsigned i = 0;
+    // Prefixes CSS, Pixel, Pos are ignored.
+    // Prefixes Apple, KHTML and Webkit are transposed to "-webkit-".
+    // The prefix "Epub" becomes "-epub-".
+    switch (propertyNamePrefix(*propertyNameString)) {
+    case PropertyNamePrefix::None:
+        if (isASCIIUpper((*propertyNameString)[0]))
+            return propertyInfo;
+        break;
+    case PropertyNamePrefix::CSS:
+        i += 3;
+        break;
+    case PropertyNamePrefix::Pixel:
+        i += 5;
+        hadPixelOrPosPrefix = true;
+        break;
+    case PropertyNamePrefix::Pos:
+        i += 3;
+        hadPixelOrPosPrefix = true;
+        break;
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+    case PropertyNamePrefix::Apple:
+    case PropertyNamePrefix::KHTML:
+        ASSERT(RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled());
+        writeWebKitPrefix(bufferPtr);
+        i += 5;
+        break;
+#endif
+    case PropertyNamePrefix::Epub:
+        writeEpubPrefix(bufferPtr);
+        i += 4;
+        break;
+    case PropertyNamePrefix::WebKit:
+        writeWebKitPrefix(bufferPtr);
+        i += 6;
+        break;
+    }
+
+    *bufferPtr++ = toASCIILower((*propertyNameString)[i++]);
+
+    char* bufferEnd = buffer + bufferSize;
+    char* stringEnd = bufferEnd - 1;
+    size_t bufferSizeLeft = stringEnd - bufferPtr;
+    size_t propertySizeLeft = length - i;
+    if (propertySizeLeft > bufferSizeLeft)
+        return propertyInfo;
+
+    for (; i < length; ++i) {
+        UChar c = (*propertyNameString)[i];
+        if (!c || !isASCII(c))
+            return propertyInfo; // illegal character
+        if (isASCIIUpper(c)) {
+            size_t bufferSizeLeft = stringEnd - bufferPtr;
+            size_t propertySizeLeft = length - i + 1;
+            if (propertySizeLeft > bufferSizeLeft)
+                return propertyInfo;
+            *bufferPtr++ = '-';
+            *bufferPtr++ = toASCIILowerUnchecked(c);
+        } else
+            *bufferPtr++ = c;
+        ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
+    }
+    ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
+    *bufferPtr = '\0';
+
+    unsigned outputLength = bufferPtr - buffer;
+#if PLATFORM(IOS)
+    cssPropertyNameIOSAliasing(buffer, name, outputLength);
+#endif
+
+    auto* hashTableEntry = findProperty(name, outputLength);
+    if (auto propertyID = hashTableEntry ? hashTableEntry->id : 0) {
+        propertyInfo.hadPixelOrPosPrefix = hadPixelOrPosPrefix;
+        propertyInfo.propertyID = static_cast<CSSPropertyID>(propertyID);
+        propertyInfoCache.get().add(propertyNameString, propertyInfo);
+    }
+    return propertyInfo;
+}
+
+}
+
+std::optional<Variant<String, double>> CSSStyleDeclaration::namedItem(const AtomicString& propertyName)
+{
+    auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
+    if (!propertyInfo.propertyID)
+        return std::nullopt;
+
+    auto value = getPropertyCSSValueInternal(propertyInfo.propertyID);
+    if (!value) {
+        // If the property is a shorthand property (such as "padding"), it can only be accessed using getPropertyValue.
+        return Variant<String, double> { getPropertyValueInternal(propertyInfo.propertyID) };
+    }
+    
+    if (propertyInfo.hadPixelOrPosPrefix && is<CSSPrimitiveValue>(*value)) {
+        // Call this version of the getter so that, e.g., pixelTop returns top as a number
+        // in pixel units and posTop should does the same _if_ this is a positioned element.
+        // FIXME: If not a positioned element, MSIE documentation says posTop should return 0; this rule is not implemented.
+        return Variant<String, double> { downcast<CSSPrimitiveValue>(*value).floatValue(CSSPrimitiveValue::CSS_PX) };
+    }
+
+    return Variant<String, double> { value->cssText() };
+}
+
+ExceptionOr<void> CSSStyleDeclaration::setNamedItem(const AtomicString& propertyName, String value, bool& propertySupported)
+{
+    auto propertyInfo = parseJavaScriptCSSPropertyName(propertyName);
+    if (!propertyInfo.propertyID) {
+        propertySupported = false;
+        return { };
+    }
+
+    propertySupported = true;
+
+    if (propertyInfo.hadPixelOrPosPrefix)
+        value.append("px");
+
+    bool important = false;
+    if (Settings::shouldRespectPriorityInCSSAttributeSetters()) {
+        auto importantIndex = value.findIgnoringASCIICase("!important");
+        if (importantIndex && importantIndex != notFound) {
+            important = true;
+            value = value.left(importantIndex - 1);
+        }
+    }
+
+    auto setPropertyInternalResult = setPropertyInternal(propertyInfo.propertyID, value, important);
+    if (setPropertyInternalResult.hasException())
+        return setPropertyInternalResult.releaseException();
+
+    return { };
+}
+
+Vector<AtomicString> CSSStyleDeclaration::supportedPropertyNames() const
+{
+    static const AtomicString* const cssPropertyNames = [] {
+        String names[numCSSProperties];
+        for (int i = 0; i < numCSSProperties; ++i)
+            names[i] = getJSPropertyName(static_cast<CSSPropertyID>(firstCSSProperty + i));
+        std::sort(&names[0], &names[numCSSProperties], WTF::codePointCompareLessThan);
+        auto* identifiers = new AtomicString[numCSSProperties];
+        for (int i = 0; i < numCSSProperties; ++i)
+            identifiers[i] = names[i];
+        return identifiers;
+    }();
+
+    Vector<AtomicString> result;
+    result.reserveInitialCapacity(numCSSProperties);
+
+    for (unsigned i = 0; i < numCSSProperties; ++i)
+        result.uncheckedAppend(cssPropertyNames[i]);
+
+    return result;
+}
+
+}

Modified: trunk/Source/WebCore/css/CSSStyleDeclaration.h (219621 => 219622)


--- trunk/Source/WebCore/css/CSSStyleDeclaration.h	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/css/CSSStyleDeclaration.h	2017-07-18 20:12:15 UTC (rev 219622)
@@ -25,6 +25,8 @@
 #include "ExceptionOr.h"
 #include "ScriptWrappable.h"
 #include <wtf/Forward.h>
+#include <wtf/Optional.h>
+#include <wtf/Variant.h>
 
 namespace WebCore {
 
@@ -69,6 +71,11 @@
 
     virtual CSSStyleSheet* parentStyleSheet() const { return nullptr; }
 
+    // Bindings support.
+    std::optional<Variant<String, double>> namedItem(const AtomicString&);
+    ExceptionOr<void> setNamedItem(const AtomicString& name, String value, bool& propertySupported);
+    Vector<AtomicString> supportedPropertyNames() const;
+
 protected:
     CSSStyleDeclaration() { }
 };

Modified: trunk/Source/WebCore/css/CSSStyleDeclaration.idl (219621 => 219622)


--- trunk/Source/WebCore/css/CSSStyleDeclaration.idl	2017-07-18 19:59:13 UTC (rev 219621)
+++ trunk/Source/WebCore/css/CSSStyleDeclaration.idl	2017-07-18 20:12:15 UTC (rev 219622)
@@ -19,10 +19,8 @@
  */
 
 [
-    CustomGetOwnPropertyNames,
-    CustomGetOwnPropertySlotAndDescriptor,
-    CustomPut,
     ExportMacro=WEBCORE_EXPORT,
+    DefaultDefineOwnProperty,
     GenerateIsReachable,
     JSCustomHeader,
     JSCustomMarkFunction,
@@ -32,9 +30,6 @@
 
     DOMString getPropertyValue(DOMString propertyName);
 
-    // This method is deprecated, and we would like to drop support for it someday
-    [Custom] DeprecatedCSSOMValue? getPropertyCSSValue(DOMString propertyName);
-
     [CEReactions, MayThrowException] DOMString removeProperty(DOMString propertyName);
     DOMString? getPropertyPriority(DOMString propertyName);
 
@@ -47,4 +42,14 @@
     // FIXME: Using "undefined" as default parameter value is wrong.
     DOMString? getPropertyShorthand(optional DOMString propertyName = "undefined");
     boolean isPropertyImplicit(optional DOMString propertyName = "undefined");
+
+    // Use named getters/setters for all support CSS property names. The spec says
+    // these should be normal attributes, but there are too many combinations with
+    // prefixes for this to be practical. If we remove legacy aliases, we should
+    // reconsider this decision.
+    getter (DOMString or double) (DOMString name);
+    [CEReactions, MayThrowException, CallNamedSetterOnlyForSupportedProperties] setter void (DOMString name, [TreatNullAs=EmptyString] DOMString value);
+
+    // This method is deprecated, and we would like to drop support for it someday
+    [Custom] DeprecatedCSSOMValue? getPropertyCSSValue(DOMString propertyName);
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to