Avoid double hash lookup in our JS bindings named property getter code
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Aug 2015 00:06:30 +0000 (00:06 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Aug 2015 00:06:30 +0000 (00:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148193

Reviewed by Geoffrey Garen.

Avoid double hash lookup in our JS bindings named property getter code
for performance reasons.

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

* bindings/js/JSDOMNamedFlowCollectionCustom.cpp: Added.
(WebCore::JSDOMNamedFlowCollection::nameGetter):
Moved custom named getter code for DOMNamedFlowCollection from the
bindings generator to an actual custom bindings file.

* bindings/scripts/test/JS/JSTestCustomNamedGetter.cpp:
* bindings/scripts/test/JS/JSTestCustomNamedGetter.h:
* bindings/scripts/test/JS/JSTestEventTarget.cpp:
* bindings/scripts/test/JS/JSTestEventTarget.h:
* bindings/scripts/test/JS/JSTestOverrideBuiltins.cpp:
* bindings/scripts/test/JS/JSTestOverrideBuiltins.h:
Rebaseline bindings tests.

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

42 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/RTCStatsResponse.cpp
Source/WebCore/Modules/mediastream/RTCStatsResponse.h
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSDOMMimeTypeArrayCustom.cpp
Source/WebCore/bindings/js/JSDOMNamedFlowCollectionCustom.cpp [new file with mode: 0644]
Source/WebCore/bindings/js/JSDOMPluginArrayCustom.cpp
Source/WebCore/bindings/js/JSDOMPluginCustom.cpp
Source/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp
Source/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
Source/WebCore/bindings/js/JSHTMLFormControlsCollectionCustom.cpp
Source/WebCore/bindings/js/JSHTMLFormElementCustom.cpp
Source/WebCore/bindings/js/JSHTMLFrameSetElementCustom.cpp
Source/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp
Source/WebCore/bindings/js/JSNamedNodeMapCustom.cpp
Source/WebCore/bindings/js/JSNodeListCustom.cpp
Source/WebCore/bindings/js/JSRTCStatsResponseCustom.cpp
Source/WebCore/bindings/js/JSStorageCustom.cpp
Source/WebCore/bindings/js/JSStyleSheetListCustom.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestCustomNamedGetter.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestCustomNamedGetter.h
Source/WebCore/bindings/scripts/test/JS/JSTestEventTarget.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestEventTarget.h
Source/WebCore/bindings/scripts/test/JS/JSTestOverrideBuiltins.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestOverrideBuiltins.h
Source/WebCore/dom/DOMNamedFlowCollection.cpp
Source/WebCore/dom/DOMNamedFlowCollection.h
Source/WebCore/html/HTMLCollection.cpp
Source/WebCore/html/HTMLCollection.h
Source/WebCore/html/HTMLFormElement.cpp
Source/WebCore/html/HTMLFormElement.h
Source/WebCore/plugins/DOMMimeTypeArray.cpp
Source/WebCore/plugins/DOMMimeTypeArray.h
Source/WebCore/plugins/DOMPlugin.cpp
Source/WebCore/plugins/DOMPlugin.h
Source/WebCore/plugins/DOMPluginArray.cpp
Source/WebCore/plugins/DOMPluginArray.h

index 8468b6d..522efd1 100644 (file)
@@ -1108,6 +1108,7 @@ set(WebCore_SOURCES
     bindings/js/JSDOMGlobalObject.cpp
     bindings/js/JSDOMGlobalObjectTask.cpp
     bindings/js/JSDOMMimeTypeArrayCustom.cpp
+    bindings/js/JSDOMNamedFlowCollectionCustom.cpp
     bindings/js/JSDOMPluginArrayCustom.cpp
     bindings/js/JSDOMPluginCustom.cpp
     bindings/js/JSDOMPromise.cpp
index f88f70f..d739045 100644 (file)
@@ -1,3 +1,30 @@
+2015-08-19  Chris Dumez  <cdumez@apple.com>
+
+        Avoid double hash lookup in our JS bindings named property getter code
+        https://bugs.webkit.org/show_bug.cgi?id=148193
+
+        Reviewed by Geoffrey Garen.
+
+        Avoid double hash lookup in our JS bindings named property getter code
+        for performance reasons.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        Add new file.
+
+        * bindings/js/JSDOMNamedFlowCollectionCustom.cpp: Added.
+        (WebCore::JSDOMNamedFlowCollection::nameGetter):
+        Moved custom named getter code for DOMNamedFlowCollection from the
+        bindings generator to an actual custom bindings file.
+
+        * bindings/scripts/test/JS/JSTestCustomNamedGetter.cpp:
+        * bindings/scripts/test/JS/JSTestCustomNamedGetter.h:
+        * bindings/scripts/test/JS/JSTestEventTarget.cpp:
+        * bindings/scripts/test/JS/JSTestEventTarget.h:
+        * bindings/scripts/test/JS/JSTestOverrideBuiltins.cpp:
+        * bindings/scripts/test/JS/JSTestOverrideBuiltins.h:
+        Rebaseline bindings tests.
+
 2015-08-19  Simon Fraser  <simon.fraser@apple.com>
 
         Add CSS will-change to the feature list
index bb3ee32..c385bef 100644 (file)
@@ -39,18 +39,13 @@ RTCStatsResponse::RTCStatsResponse()
 {
 }
 
-PassRefPtr<RTCStatsReport> RTCStatsResponse::namedItem(const AtomicString& name)
+RefPtr<RTCStatsReport> RTCStatsResponse::namedItem(const AtomicString& name)
 {
     if (m_idmap.find(name) != m_idmap.end())
         return m_result[m_idmap.get(name)];
     return nullptr;
 }
 
-bool RTCStatsResponse::canGetItemsForName(const AtomicString& name)
-{
-    return m_idmap.contains(name);
-}
-
 size_t RTCStatsResponse::addReport(String id, String type, double timestamp)
 {
     m_result.append(RTCStatsReport::create(id, type, timestamp));
index d41b9b8..d704ac2 100644 (file)
@@ -45,8 +45,7 @@ public:
 
     const Vector<RefPtr<RTCStatsReport>>& result() const { return m_result; };
 
-    PassRefPtr<RTCStatsReport> namedItem(const AtomicString&);
-    bool canGetItemsForName(const AtomicString&);
+    RefPtr<RTCStatsReport> namedItem(const AtomicString&);
 
     virtual size_t addReport(String id, String type, double timestamp) override;
     virtual void addStatistic(size_t report, String name, String value) override;
index da12073..bc556d3 100644 (file)
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="..\bindings\js\JSDOMNamedFlowCollectionCustom.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\bindings\js\JSDOMPluginArrayCustom.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
index e1ae88e..fe4a78d 100644 (file)
     <ClCompile Include="..\bindings\js\JSDOMMimeTypeArrayCustom.cpp">
       <Filter>bindings\js</Filter>
     </ClCompile>
+    <ClCompile Include="..\bindings\js\JSDOMNamedFlowCollectionCustom.cpp">
+      <Filter>bindings\js</Filter>
+    </ClCompile>
     <ClCompile Include="..\bindings\js\JSDOMPluginArrayCustom.cpp">
       <Filter>bindings\js</Filter>
     </ClCompile>
       <Filter>platform\win</Filter>
     </MASM>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 2be613e..06a20de 100644 (file)
                45FEA5D0156DDE8C00654101 /* Decimal.h in Headers */ = {isa = PBXBuildFile; fileRef = 45FEA5CE156DDE8C00654101 /* Decimal.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4634592C1AC2271000ECB71C /* PowerObserverMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4634592B1AC2271000ECB71C /* PowerObserverMac.cpp */; };
                4634592E1AC2273C00ECB71C /* SharedTimerCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4634592D1AC2273C00ECB71C /* SharedTimerCF.cpp */; };
+               4669B2871B852A0B000F905F /* JSDOMNamedFlowCollectionCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F2768E1B85297F005C2556 /* JSDOMNamedFlowCollectionCustom.cpp */; };
                4689F1AF1267BAE100E8D380 /* FileMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 4689F1AE1267BAE100E8D380 /* FileMetadata.h */; };
                46C83EFD1A9BBE2900A79A41 /* GeoNotifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46C83EFB1A9BBE2900A79A41 /* GeoNotifier.cpp */; };
                46C83EFE1A9BBE2900A79A41 /* GeoNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C83EFC1A9BBE2900A79A41 /* GeoNotifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46DB7D591B20FE58005651B2 /* VNodeTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VNodeTracker.h; sourceTree = "<group>"; };
                46DBB64E1AB8C96F00D9A813 /* PowerObserverMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PowerObserverMac.h; sourceTree = "<group>"; };
                46EBEA011B7D4D5D00BE4941 /* CollectionTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionTraversal.h; sourceTree = "<group>"; };
+               46F2768E1B85297F005C2556 /* JSDOMNamedFlowCollectionCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMNamedFlowCollectionCustom.cpp; sourceTree = "<group>"; };
                490707E41219C04300D90E51 /* ANGLEWebKitBridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ANGLEWebKitBridge.cpp; sourceTree = "<group>"; };
                490707E51219C04300D90E51 /* ANGLEWebKitBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ANGLEWebKitBridge.h; sourceTree = "<group>"; };
                49291E4A134172C800E753DE /* ImageRenderingMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageRenderingMode.h; sourceTree = "<group>"; };
                                E1C36C020EB076D6007410BC /* JSDOMGlobalObject.h */,
                                7C2BDD3B17C7F98B0038FF15 /* JSDOMGlobalObjectTask.cpp */,
                                7C2BDD3C17C7F98B0038FF15 /* JSDOMGlobalObjectTask.h */,
+                               46F2768E1B85297F005C2556 /* JSDOMNamedFlowCollectionCustom.cpp */,
                                E172AF8D1811BC3700FBADB9 /* JSDOMPromise.cpp */,
                                E172AF8E1811BC3700FBADB9 /* JSDOMPromise.h */,
                                BC6932710D7E293900AE44D1 /* JSDOMWindowBase.cpp */,
                                A8DF4AEC0980C42C0052981B /* RenderTable.cpp in Sources */,
                                6ED878C4147493F4004C3597 /* RenderTableCaption.cpp in Sources */,
                                A8DF4AEA0980C42C0052981B /* RenderTableCell.cpp in Sources */,
+                               4669B2871B852A0B000F905F /* JSDOMNamedFlowCollectionCustom.cpp in Sources */,
                                A8DF4AE80980C42C0052981B /* RenderTableCol.cpp in Sources */,
                                A8DF4AF00980C42C0052981B /* RenderTableRow.cpp in Sources */,
                                A8DF4AED0980C42C0052981B /* RenderTableSection.cpp in Sources */,
index 7031ba1..4312ae2 100644 (file)
@@ -29,17 +29,14 @@ namespace WebCore {
 
 using namespace JSC;
 
-bool JSDOMMimeTypeArray::canGetItemsForName(ExecState*, DOMMimeTypeArray* mimeTypeArray, PropertyName propertyName)
+bool JSDOMMimeTypeArray::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return mimeTypeArray->canGetItemsForName(propertyNameToAtomicString(propertyName));
-}
+    auto item = impl().namedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
 
-EncodedJSValue JSDOMMimeTypeArray::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSDOMMimeTypeArray* thisObj = jsDynamicCast<JSDOMMimeTypeArray*>(slotBase);
-    if (!thisObj)
-        return throwVMTypeError(exec);
-    return JSValue::encode(toJS(exec, thisObj->globalObject(), thisObj->impl().namedItem(propertyNameToAtomicString(propertyName))));
+    value = toJS(exec, globalObject(), item);
+    return true;
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSDOMNamedFlowCollectionCustom.cpp b/Source/WebCore/bindings/js/JSDOMNamedFlowCollectionCustom.cpp
new file mode 100644 (file)
index 0000000..b72bad3
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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 "JSDOMNamedFlowCollection.h"
+
+#include "DOMNamedFlowCollection.h"
+#include "JSDOMBinding.h"
+#include "JSWebKitNamedFlow.h"
+
+namespace WebCore {
+
+using namespace JSC;
+
+bool JSDOMNamedFlowCollection::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
+{
+    auto item = impl().namedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
+
+    value = toJS(exec, globalObject(), item);
+    return true;
+}
+
+} // namespace WebCore
index 168287a..2669d83 100644 (file)
@@ -29,15 +29,14 @@ namespace WebCore {
 
 using namespace JSC;
 
-bool JSDOMPluginArray::canGetItemsForName(ExecState*, DOMPluginArray* pluginArray, PropertyName propertyName)
+bool JSDOMPluginArray::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return pluginArray->canGetItemsForName(propertyNameToAtomicString(propertyName));
-}
+    auto item = impl().namedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
 
-EncodedJSValue JSDOMPluginArray::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSDOMPluginArray* thisObj = jsCast<JSDOMPluginArray*>(slotBase);
-    return JSValue::encode(toJS(exec, thisObj->globalObject(), thisObj->impl().namedItem(propertyNameToAtomicString(propertyName))));
+    value = toJS(exec, globalObject(), item);
+    return true;
 }
 
 } // namespace WebCore
index fb7da06..1a7586d 100644 (file)
@@ -27,15 +27,14 @@ namespace WebCore {
 
 using namespace JSC;
 
-bool JSDOMPlugin::canGetItemsForName(ExecState*, DOMPlugin* plugin, PropertyName propertyName)
+bool JSDOMPlugin::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return plugin->canGetItemsForName(propertyNameToAtomicString(propertyName));
-}
+    auto item = impl().namedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
 
-EncodedJSValue JSDOMPlugin::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSDOMPlugin* thisObj = jsCast<JSDOMPlugin*>(slotBase);
-    return JSValue::encode(toJS(exec, thisObj->globalObject(), thisObj->impl().namedItem(propertyNameToAtomicString(propertyName))));
+    value = toJS(exec, globalObject(), item);
+    return true;
 }
 
 } // namespace WebCore
index 2d5630e..75cfe5f 100644 (file)
@@ -88,15 +88,14 @@ CallType JSHTMLAllCollection::getCallData(JSCell*, CallData& callData)
     return CallTypeHost;
 }
 
-bool JSHTMLAllCollection::canGetItemsForName(ExecState*, HTMLAllCollection* collection, PropertyName propertyName)
+bool JSHTMLAllCollection::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return collection->hasNamedItem(propertyNameToAtomicString(propertyName));
-}
+    JSValue items = namedItems(exec, this, propertyName);
+    if (items.isUndefined())
+        return false;
 
-EncodedJSValue JSHTMLAllCollection::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSHTMLAllCollection* thisObj = jsCast<JSHTMLAllCollection*>(slotBase);
-    return JSValue::encode(namedItems(exec, thisObj, propertyName));
+    value = items;
+    return true;
 }
 
 JSValue JSHTMLAllCollection::item(ExecState* exec)
index 364024f..7279a94 100644 (file)
@@ -40,18 +40,17 @@ using namespace JSC;
 
 namespace WebCore {
 
-bool JSHTMLCollection::canGetItemsForName(ExecState*, HTMLCollection* collection, PropertyName propertyName)
+bool JSHTMLCollection::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return collection->hasNamedItem(propertyNameToAtomicString(propertyName));
-}
+    ASSERT_WITH_MESSAGE(impl().type() != FormControls, "Should call the subclass' nameGetter");
+    ASSERT_WITH_MESSAGE(impl().type() != SelectOptions, "Should call the subclass' nameGetter");
 
-EncodedJSValue JSHTMLCollection::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSHTMLCollection* collection = jsCast<JSHTMLCollection*>(slotBase);
-    ASSERT_WITH_MESSAGE(collection->impl().type() != FormControls, "Should call the subclass' nameGetter");
-    ASSERT_WITH_MESSAGE(collection->impl().type() != SelectOptions, "Should call the subclass' nameGetter");
-    const AtomicString& name = propertyNameToAtomicString(propertyName);
-    return JSValue::encode(toJS(exec, collection->globalObject(), collection->impl().namedItem(name)));
+    auto item = impl().namedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
+
+    value = toJS(exec, globalObject(), item);
+    return true;
 }
 
 JSValue toJS(ExecState*, JSDOMGlobalObject* globalObject, HTMLCollection* collection)
index 6d39c45..052a546 100644 (file)
@@ -52,12 +52,6 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-bool JSHTMLDocument::canGetItemsForName(ExecState*, HTMLDocument* document, PropertyName propertyName)
-{
-    AtomicStringImpl* atomicPropertyName = propertyName.publicName();
-    return atomicPropertyName && document->hasDocumentNamedItem(*atomicPropertyName);
-}
-
 bool JSHTMLDocument::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
     JSHTMLDocument* thisObject = jsCast<JSHTMLDocument*>(object);
@@ -71,8 +65,9 @@ bool JSHTMLDocument::getOwnPropertySlot(JSObject* object, ExecState* exec, Prope
         return true;
     }
 
-    if (canGetItemsForName(exec, &thisObject->impl(), propertyName)) {
-        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);
+    JSValue value;
+    if (thisObject->nameGetter(exec, propertyName, value)) {
+        slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);
         return true;
     }
 
@@ -84,28 +79,31 @@ bool JSHTMLDocument::getOwnPropertySlot(JSObject* object, ExecState* exec, Prope
     return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
 }
 
-EncodedJSValue JSHTMLDocument::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
+bool JSHTMLDocument::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    JSHTMLDocument* thisObj = jsCast<JSHTMLDocument*>(slotBase);
-    HTMLDocument& document = thisObj->impl();
+    auto& document = impl();
 
     AtomicStringImpl* atomicPropertyName = propertyName.publicName();
     if (!atomicPropertyName || !document.hasDocumentNamedItem(*atomicPropertyName))
-        return JSValue::encode(jsUndefined());
+        return false;
 
     if (UNLIKELY(document.documentNamedItemContainsMultipleElements(*atomicPropertyName))) {
         Ref<HTMLCollection> collection = document.documentNamedItems(atomicPropertyName);
         ASSERT(collection->length() > 1);
-        return JSValue::encode(toJS(exec, thisObj->globalObject(), WTF::getPtr(collection)));
+        value = toJS(exec, globalObject(), WTF::getPtr(collection));
+        return true;
     }
 
     Element* element = document.documentNamedItem(*atomicPropertyName);
     if (UNLIKELY(is<HTMLIFrameElement>(*element))) {
-        if (Frame* frame = downcast<HTMLIFrameElement>(*element).contentFrame())
-            return JSValue::encode(toJS(exec, frame));
+        if (Frame* frame = downcast<HTMLIFrameElement>(*element).contentFrame()) {
+            value = toJS(exec, frame);
+            return true;
+        }
     }
 
-    return JSValue::encode(toJS(exec, thisObj->globalObject(), element));
+    value = toJS(exec, globalObject(), element);
+    return true;
 }
 
 // Custom attributes
index 2848971..ec7f7db 100644 (file)
@@ -44,15 +44,14 @@ static JSValue namedItems(ExecState* exec, JSHTMLFormControlsCollection* collect
     return toJS(exec, collection->globalObject(), collection->impl().ownerNode().radioNodeList(name).get());
 }
 
-bool JSHTMLFormControlsCollection::canGetItemsForName(ExecState*, HTMLFormControlsCollection* collection, PropertyName propertyName)
+bool JSHTMLFormControlsCollection::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return collection->hasNamedItem(propertyNameToAtomicString(propertyName));
-}
+    auto items = namedItems(exec, this, propertyName);
+    if (items.isUndefined())
+        return false;
 
-EncodedJSValue JSHTMLFormControlsCollection::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSHTMLFormControlsCollection* thisObj = jsCast<JSHTMLFormControlsCollection*>(slotBase);
-    return JSValue::encode(namedItems(exec, thisObj, propertyName));
+    value = items;
+    return true;
 }
 
 JSValue JSHTMLFormControlsCollection::namedItem(ExecState* exec)
index 3d39bd1..e34c035 100644 (file)
@@ -37,25 +37,20 @@ using namespace JSC;
 
 namespace WebCore {
 
-bool JSHTMLFormElement::canGetItemsForName(ExecState*, HTMLFormElement* form, PropertyName propertyName)
+bool JSHTMLFormElement::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return form->hasNamedElement(propertyNameToAtomicString(propertyName));
-}
-
-EncodedJSValue JSHTMLFormElement::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSHTMLFormElement* jsForm = jsCast<JSHTMLFormElement*>(slotBase);
-    HTMLFormElement& form = jsForm->impl();
-
-    Vector<Ref<Element>> namedItems = form.namedElements(propertyNameToAtomicString(propertyName));
+    Vector<Ref<Element>> namedItems = impl().namedElements(propertyNameToAtomicString(propertyName));
     
     if (namedItems.isEmpty())
-        return JSValue::encode(jsUndefined());
-    if (namedItems.size() == 1)
-        return JSValue::encode(toJS(exec, jsForm->globalObject(), &namedItems[0].get()));
+        return false;
+    if (namedItems.size() == 1) {
+        value = toJS(exec, globalObject(), namedItems[0].ptr());
+        return true;
+    }
 
     // FIXME: HTML5 specifies that this should be a RadioNodeList.
-    return JSValue::encode(toJS(exec, jsForm->globalObject(), StaticElementList::adopt(namedItems).get()));
+    value = toJS(exec, globalObject(), StaticElementList::adopt(namedItems).get());
+    return true;
 }
 
 }
index 77eaff5..70856e5 100644 (file)
@@ -30,7 +30,6 @@
 #include "HTMLCollection.h"
 #include "HTMLFrameElement.h"
 #include "HTMLFrameSetElement.h"
-#include "HTMLNames.h"
 #include "JSDOMWindow.h"
 #include "JSDOMWindowShell.h"
 #include "JSDOMBinding.h"
@@ -39,23 +38,19 @@ using namespace JSC;
 
 namespace WebCore {
 
-using namespace HTMLNames;
-
-bool JSHTMLFrameSetElement::canGetItemsForName(ExecState*, HTMLFrameSetElement* frameSet, PropertyName propertyName)
-{
-    Node* frame = frameSet->children()->namedItem(propertyNameToAtomicString(propertyName));
-    return frame && frame->hasTagName(frameTag);
-}
-
-EncodedJSValue JSHTMLFrameSetElement::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
+bool JSHTMLFrameSetElement::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    HTMLElement& element = jsCast<JSHTMLElement*>(slotBase)->impl();
-    Node* frameElement = element.children()->namedItem(propertyNameToAtomicString(propertyName));
-    if (Document* document = downcast<HTMLFrameElement>(frameElement)->contentDocument()) {
-        if (JSDOMWindowShell* window = toJSDOMWindowShell(document->frame(), currentWorld(exec)))
-            return JSValue::encode(window);
+    auto* frameElement = impl().children()->namedItem(propertyNameToAtomicString(propertyName));
+    if (!is<HTMLFrameElement>(frameElement))
+        return false;
+
+    if (auto* document = downcast<HTMLFrameElement>(*frameElement).contentDocument()) {
+        if (JSDOMWindowShell* window = toJSDOMWindowShell(document->frame(), currentWorld(exec))) {
+            value = window;
+            return true;
+        }
     }
-    return JSValue::encode(jsUndefined());
+    return false;
 }
 
 } // namespace WebCore
index 7c0d690..fb375ef 100644 (file)
@@ -37,16 +37,14 @@ using namespace JSC;
 
 namespace WebCore {
 
-bool JSHTMLOptionsCollection::canGetItemsForName(ExecState*, HTMLOptionsCollection* collection, PropertyName propertyName)
+bool JSHTMLOptionsCollection::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return collection->hasNamedItem(propertyNameToAtomicString(propertyName));
-}
+    auto item = impl().namedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
 
-EncodedJSValue JSHTMLOptionsCollection::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSHTMLCollection* collection = jsCast<JSHTMLCollection*>(slotBase);
-    const AtomicString& name = propertyNameToAtomicString(propertyName);
-    return JSValue::encode(toJS(exec, collection->globalObject(), collection->impl().namedItem(name)));
+    value = toJS(exec, globalObject(), item);
+    return true;
 }
 
 void JSHTMLOptionsCollection::setLength(ExecState* exec, JSValue value)
index e10122c..846cf8f 100644 (file)
@@ -35,15 +35,14 @@ using namespace JSC;
 
 namespace WebCore {
 
-bool JSNamedNodeMap::canGetItemsForName(ExecState*, NamedNodeMap* impl, PropertyName propertyName)
+bool JSNamedNodeMap::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return impl->getNamedItem(propertyNameToAtomicString(propertyName));
-}
+    auto item = impl().getNamedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
 
-EncodedJSValue JSNamedNodeMap::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSNamedNodeMap* thisObj = jsCast<JSNamedNodeMap*>(slotBase);
-    return JSValue::encode(toJS(exec, thisObj->globalObject(), thisObj->impl().getNamedItem(propertyNameToAtomicString(propertyName))));
+    value = toJS(exec, globalObject(), item);
+    return true;
 }
 
 } // namespace WebCore
index 69d3be7..2fd9f33 100644 (file)
@@ -51,20 +51,16 @@ bool JSNodeListOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handl
     return false;
 }
 
-bool JSNodeList::canGetItemsForName(ExecState*, NodeList* nodeList, PropertyName propertyName)
+// FIXME: NodeList should not have a named getter. It currently has one because getElementByTagName()
+// returns a NodeList instead of an HTMLCollection.
+bool JSNodeList::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    // FIXME: NodeList should not have a named getter. It currently has one because getElementByTagName()
-    // returns a NodeList instead of an HTMLCollection.
-    return nodeList->namedItem(propertyNameToAtomicString(propertyName));
-}
+    auto item = impl().namedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
 
-EncodedJSValue JSNodeList::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    // FIXME: NodeList should not have a named getter. It currently has one because getElementByTagName()
-    // returns a NodeList instead of an HTMLCollection.
-    JSNodeList* nodeList = jsCast<JSNodeList*>(slotBase);
-    const AtomicString& name = propertyNameToAtomicString(propertyName);
-    return JSValue::encode(toJS(exec, nodeList->globalObject(), nodeList->impl().namedItem(name)));
+    value = toJS(exec, globalObject(), item);
+    return true;
 }
 
 JSC::JSValue createWrapper(JSDOMGlobalObject& globalObject, NodeList& nodeList)
index 3f71289..9ef5e93 100644 (file)
@@ -36,15 +36,14 @@ using namespace JSC;
 
 namespace WebCore {
 
-bool JSRTCStatsResponse::canGetItemsForName(ExecState*, RTCStatsResponse* response, PropertyName propertyName)
+bool JSRTCStatsResponse::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
-    return response->canGetItemsForName(propertyNameToAtomicString(propertyName));
-}
+    auto item = impl().namedItem(propertyNameToAtomicString(propertyName));
+    if (!item)
+        return false;
 
-EncodedJSValue JSRTCStatsResponse::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSRTCStatsResponse* thisObj = jsCast<JSRTCStatsResponse*>(slotBase);
-    return JSValue::encode(toJS(exec, thisObj->globalObject(), thisObj->impl().namedItem(propertyNameToAtomicString(propertyName))));
+    value = toJS(exec, globalObject(), item);
+    return true;
 }
 
 } // namespace WebCore
index e651340..9cc585b 100644 (file)
@@ -35,32 +35,20 @@ using namespace JSC;
 
 namespace WebCore {
 
-bool JSStorage::canGetItemsForName(ExecState* exec, Storage* impl, PropertyName propertyName)
+bool JSStorage::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
     if (propertyName.isSymbol())
         return false;
 
     ExceptionCode ec = 0;
-    bool result = impl->contains(propertyNameToString(propertyName), ec);
+    String item = impl().getItem(propertyNameToString(propertyName), ec);
     setDOMException(exec, ec);
-    return result;
-}
-
-EncodedJSValue JSStorage::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSStorage* thisObject = jsCast<JSStorage*>(slotBase);
-    JSValue prototype = thisObject->prototype();
-    PropertySlot slot(thisObject);
-    if (prototype.isObject() && asObject(prototype)->getPropertySlot(exec, propertyName, slot))
-        return JSValue::encode(slot.getValue(exec, propertyName));
 
-    if (propertyName.isSymbol())
+    if (item.isNull())
         return false;
 
-    ExceptionCode ec = 0;
-    JSValue result = jsStringOrNull(exec, thisObject->impl().getItem(propertyNameToString(propertyName), ec));
-    setDOMException(exec, ec);
-    return JSValue::encode(result);
+    value = jsStringWithCache(exec, item);
+    return true;
 }
 
 bool JSStorage::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
index 8d9b94a..d1c6065 100644 (file)
@@ -35,19 +35,17 @@ using namespace JSC;
 
 namespace WebCore {
 
-bool JSStyleSheetList::canGetItemsForName(ExecState*, StyleSheetList* styleSheetList, PropertyName propertyName)
+bool JSStyleSheetList::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
 {
     if (propertyName.isSymbol())
         return false;
-    return styleSheetList->getNamedItem(propertyNameToString(propertyName));
-}
 
-EncodedJSValue JSStyleSheetList::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)
-{
-    JSStyleSheetList* thisObj = jsCast<JSStyleSheetList*>(slotBase);
-    HTMLStyleElement* element = thisObj->impl().getNamedItem(propertyNameToString(propertyName));
-    ASSERT(element);
-    return JSValue::encode(toJS(exec, thisObj->globalObject(), element->sheet()));
+    auto* item = impl().getNamedItem(propertyNameToString(propertyName));
+    if (!item)
+        return false;
+
+    value = toJS(exec, globalObject(), item->sheet());
+    return true;
 }
 
 } // namespace WebCore
index e5f3cf4..4e3fae9 100644 (file)
@@ -432,10 +432,13 @@ sub GenerateGetOwnPropertySlotBody
             &$prototypeCheck();
         }
 
-        # The first condition is to make sure we use the subclass' named getter instead of the base class one when possible.
-        push(@getOwnPropertySlotImpl, "    if (thisObject->classInfo() == info() && canGetItemsForName(exec, &thisObject->impl(), propertyName)) {\n");
-        push(@getOwnPropertySlotImpl, "        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);\n");
-        push(@getOwnPropertySlotImpl, "        return true;\n");
+        # This condition is to make sure we use the subclass' named getter instead of the base class one when possible.
+        push(@getOwnPropertySlotImpl, "    if (thisObject->classInfo() == info()) {\n");
+        push(@getOwnPropertySlotImpl, "        JSValue value;\n");
+        push(@getOwnPropertySlotImpl, "        if (thisObject->nameGetter(exec, propertyName, value)) {\n");
+        push(@getOwnPropertySlotImpl, "            slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);\n");
+        push(@getOwnPropertySlotImpl, "            return true;\n");
+        push(@getOwnPropertySlotImpl, "        }\n");
         push(@getOwnPropertySlotImpl, "    }\n");
         if ($inlined) {
             $headerIncludes{"wtf/text/AtomicString.h"} = 1;
@@ -1162,8 +1165,7 @@ sub GenerateHeader
     # Name getter
     if ($namedGetterFunction || $interface->extendedAttributes->{"CustomNamedGetter"}) {
         push(@headerContent, "private:\n");
-        push(@headerContent, "    static bool canGetItemsForName(JSC::ExecState*, $interfaceName*, JSC::PropertyName);\n");
-        push(@headerContent, "    static JSC::EncodedJSValue nameGetter(JSC::ExecState*, JSC::JSObject*, JSC::EncodedJSValue, JSC::PropertyName);\n");
+        push(@headerContent, "    bool nameGetter(JSC::ExecState*, JSC::PropertyName, JSC::JSValue&);\n");
     }
 
     push(@headerContent, "};\n\n");
@@ -2185,10 +2187,13 @@ sub GenerateImplementation
             if ($namedGetterFunction || $interface->extendedAttributes->{"CustomNamedGetter"}) {
                 &$propertyNameGeneration();
 
-                # The first condition is to make sure we use the subclass' named getter instead of the base class one when possible.
-                push(@implContent, "    if (thisObject->classInfo() == info() && canGetItemsForName(exec, &thisObject->impl(), propertyName)) {\n");
-                push(@implContent, "        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);\n");
-                push(@implContent, "        return true;\n");
+                # This condition is to make sure we use the subclass' named getter instead of the base class one when possible.
+                push(@implContent, "    if (thisObject->classInfo() == info()) {\n");
+                push(@implContent, "        JSValue value;\n");
+                push(@implContent, "        if (thisObject->nameGetter(exec, propertyName, value)) {\n");
+                push(@implContent, "            slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);\n");
+                push(@implContent, "            return true;\n");
+                push(@implContent, "        }\n");
                 push(@implContent, "    }\n");
                 $implIncludes{"wtf/text/AtomicString.h"} = 1;
             }
@@ -2926,20 +2931,6 @@ sub GenerateImplementation
         }
     }
 
-    if ($interfaceName eq "DOMNamedFlowCollection") {
-        if ($namedGetterFunction) {
-            push(@implContent, "bool ${className}::canGetItemsForName(ExecState*, $interfaceName* collection, PropertyName propertyName)\n");
-            push(@implContent, "{\n");
-            push(@implContent, "    return collection->hasNamedItem(propertyNameToAtomicString(propertyName));\n");
-            push(@implContent, "}\n\n");
-            push(@implContent, "EncodedJSValue ${className}::nameGetter(ExecState* exec, JSObject* slotBase, EncodedJSValue, PropertyName propertyName)\n");
-            push(@implContent, "{\n");
-            push(@implContent, "    auto* thisObject = jsCast<$className*>(slotBase);\n");
-            push(@implContent, "    return JSValue::encode(toJS(exec, thisObject->globalObject(), thisObject->impl().namedItem(propertyNameToAtomicString(propertyName))));\n");
-            push(@implContent, "}\n\n");
-        }
-    }
-
     if ((!$hasParent && !GetCustomIsReachable($interface)) || GetGenerateIsReachable($interface) || $codeGenerator->InheritsExtendedAttribute($interface, "ActiveDOMObject")) {
 
         push(@implContent, "bool JS${interfaceName}Owner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)\n");
index b8b5a4c..ede043d 100644 (file)
@@ -170,9 +170,12 @@ bool JSTestCustomNamedGetter::getOwnPropertySlot(JSObject* object, ExecState* ex
     if (proto.isObject() && jsCast<JSObject*>(proto)->hasProperty(exec, propertyName))
         return false;
 
-    if (thisObject->classInfo() == info() && canGetItemsForName(exec, &thisObject->impl(), propertyName)) {
-        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);
-        return true;
+    if (thisObject->classInfo() == info()) {
+        JSValue value;
+        if (thisObject->nameGetter(exec, propertyName, value)) {
+            slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);
+            return true;
+        }
     }
     return false;
 }
@@ -182,9 +185,12 @@ bool JSTestCustomNamedGetter::getOwnPropertySlotByIndex(JSObject* object, ExecSt
     auto* thisObject = jsCast<JSTestCustomNamedGetter*>(object);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     Identifier propertyName = Identifier::from(exec, index);
-    if (thisObject->classInfo() == info() && canGetItemsForName(exec, &thisObject->impl(), propertyName)) {
-        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);
-        return true;
+    if (thisObject->classInfo() == info()) {
+        JSValue value;
+        if (thisObject->nameGetter(exec, propertyName, value)) {
+            slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);
+            return true;
+        }
     }
     return Base::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
 }
index e641572..4f99291 100644 (file)
@@ -70,8 +70,7 @@ protected:
     }
 
 private:
-    static bool canGetItemsForName(JSC::ExecState*, TestCustomNamedGetter*, JSC::PropertyName);
-    static JSC::EncodedJSValue nameGetter(JSC::ExecState*, JSC::JSObject*, JSC::EncodedJSValue, JSC::PropertyName);
+    bool nameGetter(JSC::ExecState*, JSC::PropertyName, JSC::JSValue&);
 };
 
 class JSTestCustomNamedGetterOwner : public JSC::WeakHandleOwner {
index 3332a07..a834d53 100644 (file)
@@ -189,9 +189,12 @@ bool JSTestEventTarget::getOwnPropertySlot(JSObject* object, ExecState* exec, Pr
     if (proto.isObject() && jsCast<JSObject*>(proto)->hasProperty(exec, propertyName))
         return false;
 
-    if (thisObject->classInfo() == info() && canGetItemsForName(exec, &thisObject->impl(), propertyName)) {
-        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);
-        return true;
+    if (thisObject->classInfo() == info()) {
+        JSValue value;
+        if (thisObject->nameGetter(exec, propertyName, value)) {
+            slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);
+            return true;
+        }
     }
     return false;
 }
@@ -206,9 +209,12 @@ bool JSTestEventTarget::getOwnPropertySlotByIndex(JSObject* object, ExecState* e
         return true;
     }
     Identifier propertyName = Identifier::from(exec, index);
-    if (thisObject->classInfo() == info() && canGetItemsForName(exec, &thisObject->impl(), propertyName)) {
-        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);
-        return true;
+    if (thisObject->classInfo() == info()) {
+        JSValue value;
+        if (thisObject->nameGetter(exec, propertyName, value)) {
+            slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);
+            return true;
+        }
     }
     return Base::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
 }
index 492b77d..831daf9 100644 (file)
@@ -74,8 +74,7 @@ protected:
     }
 
 private:
-    static bool canGetItemsForName(JSC::ExecState*, TestEventTarget*, JSC::PropertyName);
-    static JSC::EncodedJSValue nameGetter(JSC::ExecState*, JSC::JSObject*, JSC::EncodedJSValue, JSC::PropertyName);
+    bool nameGetter(JSC::ExecState*, JSC::PropertyName, JSC::JSValue&);
 };
 
 class JSTestEventTargetOwner : public JSC::WeakHandleOwner {
index 306db28..b185674 100644 (file)
@@ -166,9 +166,12 @@ bool JSTestOverrideBuiltins::getOwnPropertySlot(JSObject* object, ExecState* exe
 {
     auto* thisObject = jsCast<JSTestOverrideBuiltins*>(object);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    if (thisObject->classInfo() == info() && canGetItemsForName(exec, &thisObject->impl(), propertyName)) {
-        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);
-        return true;
+    if (thisObject->classInfo() == info()) {
+        JSValue value;
+        if (thisObject->nameGetter(exec, propertyName, value)) {
+            slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);
+            return true;
+        }
     }
     if (getStaticValueSlot<JSTestOverrideBuiltins, Base>(exec, JSTestOverrideBuiltinsTable, thisObject, propertyName, slot))
         return true;
@@ -180,9 +183,12 @@ bool JSTestOverrideBuiltins::getOwnPropertySlotByIndex(JSObject* object, ExecSta
     auto* thisObject = jsCast<JSTestOverrideBuiltins*>(object);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     Identifier propertyName = Identifier::from(exec, index);
-    if (thisObject->classInfo() == info() && canGetItemsForName(exec, &thisObject->impl(), propertyName)) {
-        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, thisObject->nameGetter);
-        return true;
+    if (thisObject->classInfo() == info()) {
+        JSValue value;
+        if (thisObject->nameGetter(exec, propertyName, value)) {
+            slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);
+            return true;
+        }
     }
     return Base::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
 }
index 7cc8f0b..f5ad555 100644 (file)
@@ -70,8 +70,7 @@ protected:
     }
 
 private:
-    static bool canGetItemsForName(JSC::ExecState*, TestOverrideBuiltins*, JSC::PropertyName);
-    static JSC::EncodedJSValue nameGetter(JSC::ExecState*, JSC::JSObject*, JSC::EncodedJSValue, JSC::PropertyName);
+    bool nameGetter(JSC::ExecState*, JSC::PropertyName, JSC::JSValue&);
 };
 
 class JSTestOverrideBuiltinsOwner : public JSC::WeakHandleOwner {
index 5ed8cd5..ddd32e6 100644 (file)
@@ -53,7 +53,7 @@ PassRefPtr<WebKitNamedFlow> DOMNamedFlowCollection::item(unsigned long index) co
     return *it;
 }
 
-PassRefPtr<WebKitNamedFlow> DOMNamedFlowCollection::namedItem(const AtomicString& name) const
+RefPtr<WebKitNamedFlow> DOMNamedFlowCollection::namedItem(const AtomicString& name) const
 {
     DOMNamedFlowSet::const_iterator it = m_namedFlows.find<String, DOMNamedFlowHashTranslator>(name);
     if (it != m_namedFlows.end())
@@ -61,11 +61,6 @@ PassRefPtr<WebKitNamedFlow> DOMNamedFlowCollection::namedItem(const AtomicString
     return nullptr;
 }
 
-bool DOMNamedFlowCollection::hasNamedItem(const AtomicString& name) const
-{
-    return namedItem(name);
-}
-
 // The HashFunctions object used by the HashSet to compare between RefPtr<NamedFlows>.
 // It is safe to set safeToCompareToEmptyOrDeleted because the HashSet will never contain null pointers or deleted values.
 struct DOMNamedFlowCollection::DOMNamedFlowHashFunctions {
index d9a798b..09f97d0 100644 (file)
@@ -49,9 +49,7 @@ public:
 
     unsigned long length() const;
     PassRefPtr<WebKitNamedFlow> item(unsigned long index) const;
-    PassRefPtr<WebKitNamedFlow> namedItem(const AtomicString& name) const;
-
-    bool hasNamedItem(const AtomicString& name) const;
+    RefPtr<WebKitNamedFlow> namedItem(const AtomicString& name) const;
 
 private:
     struct DOMNamedFlowHashFunctions;
index 1182cfb..fa2bccb 100644 (file)
@@ -173,12 +173,6 @@ void HTMLCollection::updateNamedElementCache() const
     setNamedItemCache(WTF::move(cache));
 }
 
-bool HTMLCollection::hasNamedItem(const AtomicString& name) const
-{
-    // FIXME: We can do better when there are multiple elements of the same name.
-    return namedItem(name);
-}
-
 Vector<Ref<Element>> HTMLCollection::namedItems(const AtomicString& name) const
 {
     // FIXME: This non-virtual function can't possibly be doing the correct thing for
index b42061a..c0da6b6 100644 (file)
@@ -69,7 +69,6 @@ public:
     PassRefPtr<NodeList> tags(const String&);
 
     // Non-DOM API
-    bool hasNamedItem(const AtomicString& name) const;
     Vector<Ref<Element>> namedItems(const AtomicString& name) const;
     virtual size_t memoryCost() const;
 
index 054279f..6aa0f5f 100644 (file)
@@ -794,11 +794,6 @@ bool HTMLFormElement::matchesInvalidPseudoClass() const
     return !m_invalidAssociatedFormControls.isEmpty();
 }
 
-bool HTMLFormElement::hasNamedElement(const AtomicString& name)
-{
-    return elements()->hasNamedItem(name) || elementFromPastNamesMap(name);
-}
-
 // FIXME: Use Ref<HTMLElement> for the function result since there are no non-HTML elements returned here.
 Vector<Ref<Element>> HTMLFormElement::namedElements(const AtomicString& name)
 {
index 00515a3..d01581d 100644 (file)
@@ -51,7 +51,6 @@ public:
     virtual ~HTMLFormElement();
 
     Ref<HTMLCollection> elements();
-    bool hasNamedElement(const AtomicString&);
     Vector<Ref<Element>> namedElements(const AtomicString&);
 
     unsigned length() const;
index da20449..c438d8a 100644 (file)
@@ -70,27 +70,11 @@ PassRefPtr<DOMMimeType> DOMMimeTypeArray::item(unsigned index)
     return DOMMimeType::create(data, m_frame, index);
 }
 
-bool DOMMimeTypeArray::canGetItemsForName(const AtomicString& propertyName)
+RefPtr<DOMMimeType> DOMMimeTypeArray::namedItem(const AtomicString& propertyName)
 {
-    PluginData *data = getPluginData();
-    if (!data)
-        return 0;
-
-    Vector<MimeClassInfo> mimes;
-    Vector<size_t> mimePluginIndices;
-    data->getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
-    for (auto& mime : mimes) {
-        if (mime.type == propertyName)
-            return true;
-    }
-    return false;
-}
-
-PassRefPtr<DOMMimeType> DOMMimeTypeArray::namedItem(const AtomicString& propertyName)
-{
-    PluginData *data = getPluginData();
+    PluginData* data = getPluginData();
     if (!data)
-        return 0;
+        return nullptr;
 
     Vector<MimeClassInfo> mimes;
     Vector<size_t> mimePluginIndices;
@@ -99,7 +83,7 @@ PassRefPtr<DOMMimeType> DOMMimeTypeArray::namedItem(const AtomicString& property
         if (mimes[i].type == propertyName)
             return DOMMimeType::create(data, m_frame, i);
     }
-    return 0;
+    return nullptr;
 }
 
 PluginData* DOMMimeTypeArray::getPluginData() const
index 96d5b56..ec41c78 100644 (file)
@@ -39,8 +39,7 @@ public:
 
     unsigned length() const;
     PassRefPtr<DOMMimeType> item(unsigned index);
-    bool canGetItemsForName(const AtomicString& propertyName);
-    PassRefPtr<DOMMimeType> namedItem(const AtomicString& propertyName);
+    RefPtr<DOMMimeType> namedItem(const AtomicString& propertyName);
 
 private:
     explicit DOMMimeTypeArray(Frame*);
index c027e99..fa13291 100644 (file)
@@ -74,19 +74,7 @@ PassRefPtr<DOMMimeType> DOMPlugin::item(unsigned index)
     return 0;
 }
 
-bool DOMPlugin::canGetItemsForName(const AtomicString& propertyName)
-{
-    Vector<MimeClassInfo> mimes;
-    Vector<size_t> mimePluginIndices;
-    m_pluginData->getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
-    for (auto& mime : mimes) {
-        if (mime.type == propertyName)
-            return true;
-    }
-    return false;
-}
-
-PassRefPtr<DOMMimeType> DOMPlugin::namedItem(const AtomicString& propertyName)
+RefPtr<DOMMimeType> DOMPlugin::namedItem(const AtomicString& propertyName)
 {
     Vector<MimeClassInfo> mimes;
     Vector<size_t> mimePluginIndices;
@@ -94,7 +82,7 @@ PassRefPtr<DOMMimeType> DOMPlugin::namedItem(const AtomicString& propertyName)
     for (unsigned i = 0; i < mimes.size(); ++i)
         if (mimes[i].type == propertyName)
             return DOMMimeType::create(m_pluginData.get(), m_frame, i);
-    return 0;
+    return nullptr;
 }
 
 } // namespace WebCore
index 68ea057..ab11e59 100644 (file)
@@ -43,8 +43,7 @@ public:
     unsigned length() const;
 
     PassRefPtr<DOMMimeType> item(unsigned index);
-    bool canGetItemsForName(const AtomicString& propertyName);
-    PassRefPtr<DOMMimeType> namedItem(const AtomicString& propertyName);
+    RefPtr<DOMMimeType> namedItem(const AtomicString& propertyName);
 
 private:
     DOMPlugin(PluginData*, Frame*, PluginInfo);
index 9478b7d..72ecac6 100644 (file)
@@ -64,30 +64,17 @@ PassRefPtr<DOMPlugin> DOMPluginArray::item(unsigned index)
     return DOMPlugin::create(data, m_frame, plugins[index]);
 }
 
-bool DOMPluginArray::canGetItemsForName(const AtomicString& propertyName)
+RefPtr<DOMPlugin> DOMPluginArray::namedItem(const AtomicString& propertyName)
 {
     PluginData* data = pluginData();
     if (!data)
-        return 0;
-
-    for (auto& plugin : data->webVisiblePlugins()) {
-        if (plugin.name == propertyName)
-            return true;
-    }
-    return false;
-}
-
-PassRefPtr<DOMPlugin> DOMPluginArray::namedItem(const AtomicString& propertyName)
-{
-    PluginData* data = pluginData();
-    if (!data)
-        return 0;
+        return nullptr;
 
     for (auto& plugin : data->webVisiblePlugins()) {
         if (plugin.name == propertyName)
             return DOMPlugin::create(data, m_frame, plugin);
     }
-    return 0;
+    return nullptr;
 }
 
 void DOMPluginArray::refresh(bool reload)
index 67de68b..7e0c76d 100644 (file)
@@ -39,8 +39,7 @@ public:
 
     unsigned length() const;
     PassRefPtr<DOMPlugin> item(unsigned index);
-    bool canGetItemsForName(const AtomicString& propertyName);
-    PassRefPtr<DOMPlugin> namedItem(const AtomicString& propertyName);
+    RefPtr<DOMPlugin> namedItem(const AtomicString& propertyName);
 
     void refresh(bool reload);