Add support for WebIDL set-like forEach
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Dec 2019 20:49:10 +0000 (20:49 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Dec 2019 20:49:10 +0000 (20:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204847

Reviewed by Chris Dumez.

Source/WebCore:

Add support to setlike forEach as done for maplike.
Covered by rebased binding tests and updated layout test.

* bindings/js/JSDOMBindingInternals.js:
(forEachWrapper):
* bindings/js/JSDOMMapLike.cpp:
(WebCore::forwardForEachCallToBackingMap):
* bindings/js/JSDOMSetLike.cpp:
(WebCore::DOMSetAdapter::clear):
(WebCore::forwardForEachCallToBackingSet):
* bindings/js/JSDOMSetLike.h:
(WebCore::DOMSetAdapter::add):
(WebCore::getAndInitializeBackingSet):
(WebCore::forwardSizeToSetLike):
(WebCore::forwardEntriesToSetLike):
(WebCore::forwardKeysToSetLike):
(WebCore::forwardValuesToSetLike):
(WebCore::forwardForEachToSetLike):
(WebCore::forwardClearToSetLike):
(WebCore::forwardHasToSetLike):
(WebCore::forwardAddToSetLike):
(WebCore::forwardDeleteToSetLike):
* bindings/scripts/IDLParser.pm:
(parseSetLikeProperties):
* bindings/scripts/test/JS/JSReadOnlySetLike.cpp:
(WebCore::jsReadOnlySetLikePrototypeFunctionForEachBody):
(WebCore::jsReadOnlySetLikePrototypeFunctionForEach):
* bindings/scripts/test/JS/JSSetLike.cpp:
(WebCore::jsSetLikePrototypeFunctionForEachBody):
(WebCore::jsSetLikePrototypeFunctionForEach):

LayoutTests:

* js/dom/maplike.html:
* js/dom/setlike.html:

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

LayoutTests/ChangeLog
LayoutTests/js/dom/maplike.html
LayoutTests/js/dom/setlike.html
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMBindingInternals.js
Source/WebCore/bindings/js/JSDOMMapLike.cpp
Source/WebCore/bindings/js/JSDOMSetLike.cpp
Source/WebCore/bindings/js/JSDOMSetLike.h
Source/WebCore/bindings/scripts/IDLParser.pm
Source/WebCore/bindings/scripts/test/JS/JSReadOnlySetLike.cpp
Source/WebCore/bindings/scripts/test/JS/JSSetLike.cpp

index ee0bdad..a21d907 100644 (file)
@@ -1,3 +1,13 @@
+2019-12-13  youenn fablet  <youenn@apple.com>
+
+        Add support for WebIDL set-like forEach
+        https://bugs.webkit.org/show_bug.cgi?id=204847
+
+        Reviewed by Chris Dumez.
+
+        * js/dom/maplike.html:
+        * js/dom/setlike.html:
+
 2019-12-13  Chris Dumez  <cdumez@apple.com>
 
         REGRESSION: (r251677) imported/w3c/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-3.html is a flaky failure
index c36e52d..fcc2b02 100644 (file)
@@ -48,8 +48,9 @@ test(() => {
     }
     assert_equals(keysTest, "testAtestB", "keys test");
 
+    assert_equals(maplike.forEach.length, 1);
     let forEachTest = "";
-    maplike.forEach((value, key, object) => {
+    const forEachResult = maplike.forEach((value, key, object) => {
         forEachTest += key;
         forEachTest += ',';
         forEachTest += value;
@@ -57,6 +58,7 @@ test(() => {
         assert_equals(object, maplike);
     });
     assert_equals(forEachTest, "testA,2 testB,3 ", "forEach test");
+    assert_equals(forEachResult, undefined);
 
     maplike.clear();
     assert_array_equals(maplike.inspectKeys(), []);
index b2958bb..28e12f2 100644 (file)
@@ -42,6 +42,16 @@ test(() => {
     }
     assert_equals(keysTest, "testtest2", "keys test");
 
+    assert_equals(setlike.forEach.length, 1);
+    let forEachTest = "";
+    const forEachResult = setlike.forEach((key, value, object) => {
+        forEachTest += key;
+        forEachTest += value;
+        assert_equals(object, setlike);
+    });
+    assert_equals(forEachTest, "testtesttest2test2", "forEach test");
+    assert_equals(forEachResult, undefined);
+
     setlike.clear();
     assert_array_equals(setlike.items(), []);
 }, "Basic add/remove/clear functionality");
index ac10fc5..9b62888 100644 (file)
@@ -1,3 +1,41 @@
+2019-12-13  youenn fablet  <youenn@apple.com>
+
+        Add support for WebIDL set-like forEach
+        https://bugs.webkit.org/show_bug.cgi?id=204847
+
+        Reviewed by Chris Dumez.
+
+        Add support to setlike forEach as done for maplike.
+        Covered by rebased binding tests and updated layout test.
+
+        * bindings/js/JSDOMBindingInternals.js:
+        (forEachWrapper):
+        * bindings/js/JSDOMMapLike.cpp:
+        (WebCore::forwardForEachCallToBackingMap):
+        * bindings/js/JSDOMSetLike.cpp:
+        (WebCore::DOMSetAdapter::clear):
+        (WebCore::forwardForEachCallToBackingSet):
+        * bindings/js/JSDOMSetLike.h:
+        (WebCore::DOMSetAdapter::add):
+        (WebCore::getAndInitializeBackingSet):
+        (WebCore::forwardSizeToSetLike):
+        (WebCore::forwardEntriesToSetLike):
+        (WebCore::forwardKeysToSetLike):
+        (WebCore::forwardValuesToSetLike):
+        (WebCore::forwardForEachToSetLike):
+        (WebCore::forwardClearToSetLike):
+        (WebCore::forwardHasToSetLike):
+        (WebCore::forwardAddToSetLike):
+        (WebCore::forwardDeleteToSetLike):
+        * bindings/scripts/IDLParser.pm:
+        (parseSetLikeProperties):
+        * bindings/scripts/test/JS/JSReadOnlySetLike.cpp:
+        (WebCore::jsReadOnlySetLikePrototypeFunctionForEachBody):
+        (WebCore::jsReadOnlySetLikePrototypeFunctionForEach):
+        * bindings/scripts/test/JS/JSSetLike.cpp:
+        (WebCore::jsSetLikePrototypeFunctionForEachBody):
+        (WebCore::jsSetLikePrototypeFunctionForEach):
+
 2019-12-13  Chris Dumez  <cdumez@apple.com>
 
         REGRESSION: (r251677) imported/w3c/web-platform-tests/html/semantics/forms/form-submission-0/form-double-submit-3.html is a flaky failure
index 7f4edb7..97edb6f 100644 (file)
 
 // @internal
 
-function mapLikeForEach(callback)
+function forEachWrapper(mapLikeOrSetLike, callback)
 {
     "use strict";
-    @getByIdDirectPrivate(this, "backingMap").forEach((value, key, map) => {
+    mapLikeOrSetLike.forEach((value, key, backingMapOrSet) => {
         callback(value, key, this);
     });
 }
index eb09fe7..2364ad9 100644 (file)
@@ -101,13 +101,18 @@ JSC::JSValue forwardFunctionCallToBackingMap(JSC::JSGlobalObject& lexicalGlobalO
 
 JSC::JSValue forwardForEachCallToBackingMap(JSDOMGlobalObject& globalObject, JSC::CallFrame& callFrame, JSC::JSObject& mapLike)
 {
-    auto* function = globalObject.builtinInternalFunctions().jsDOMBindingInternals().m_mapLikeForEachFunction.get();
+    auto result = getBackingMap(globalObject, mapLike);
+    ASSERT(!result.first);
+
+    auto* function = globalObject.builtinInternalFunctions().jsDOMBindingInternals().m_forEachWrapperFunction.get();
     ASSERT(function);
 
     JSC::CallData callData;
     auto callType = JSC::getCallData(globalObject.vm(), function, callData);
     ASSERT(callType != JSC::CallType::None);
+
     JSC::MarkedArgumentBuffer arguments;
+    arguments.append(&result.second.get());
     for (size_t cptr = 0; cptr < callFrame.argumentCount(); ++cptr)
         arguments.append(callFrame.uncheckedArgument(cptr));
     ASSERT(!arguments.hasOverflowed());
index 1de7a81..46392d6 100644 (file)
 
 namespace WebCore {
 
+void DOMSetAdapter::clear()
+{
+    clearBackingSet(m_lexicalGlobalObject, m_backingSet);
+}
+
 std::pair<bool, std::reference_wrapper<JSC::JSObject>> getBackingSet(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject& setLike)
 {
     auto& vm = lexicalGlobalObject.vm();
@@ -96,4 +101,24 @@ JSC::JSValue forwardFunctionCallToBackingSet(JSC::JSGlobalObject& lexicalGlobalO
     return JSC::call(&lexicalGlobalObject, function, callType, callData, &backingSet, arguments);
 }
 
+JSC::JSValue forwardForEachCallToBackingSet(JSDOMGlobalObject& globalObject, JSC::CallFrame& callFrame, JSC::JSObject& setLike)
+{
+    auto result = getBackingSet(globalObject, setLike);
+    ASSERT(!result.first);
+
+    auto* function = globalObject.builtinInternalFunctions().jsDOMBindingInternals().m_forEachWrapperFunction.get();
+    ASSERT(function);
+
+    JSC::CallData callData;
+    JSC::CallType callType = JSC::getCallData(globalObject.vm(), function, callData);
+    ASSERT(callType != JSC::CallType::None);
+
+    JSC::MarkedArgumentBuffer arguments;
+    arguments.append(&result.second.get());
+    for (size_t cptr = 0; cptr < callFrame.argumentCount(); ++cptr)
+        arguments.append(callFrame.uncheckedArgument(cptr));
+    ASSERT(!arguments.hasOverflowed());
+    return JSC::call(&globalObject, function, callType, callData, &setLike, arguments);
+}
+
 }
index 1188b36..0718944 100644 (file)
@@ -34,6 +34,7 @@
 namespace WebCore {
 
 WEBCORE_EXPORT std::pair<bool, std::reference_wrapper<JSC::JSObject>> getBackingSet(JSC::JSGlobalObject&, JSC::JSObject& setLike);
+WEBCORE_EXPORT JSC::JSValue forwardForEachCallToBackingSet(JSDOMGlobalObject&, JSC::CallFrame&, JSC::JSObject& setLike);
 WEBCORE_EXPORT JSC::JSValue forwardAttributeGetterToBackingSet(JSC::JSGlobalObject&, JSC::JSObject&, const JSC::Identifier&);
 WEBCORE_EXPORT JSC::JSValue forwardFunctionCallToBackingSet(JSC::JSGlobalObject&, JSC::CallFrame&, JSC::JSObject&, const JSC::Identifier&);
 WEBCORE_EXPORT void clearBackingSet(JSC::JSGlobalObject&, JSC::JSObject&);
@@ -44,7 +45,9 @@ template<typename WrapperClass> JSC::JSValue forwardSizeToSetLike(JSC::JSGlobalO
 template<typename WrapperClass> JSC::JSValue forwardEntriesToSetLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&);
 template<typename WrapperClass> JSC::JSValue forwardKeysToSetLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&);
 template<typename WrapperClass> JSC::JSValue forwardValuesToSetLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&);
+template<typename WrapperClass, typename Callback> JSC::JSValue forwardForEachToSetLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, Callback&&);
 template<typename WrapperClass> JSC::JSValue forwardClearToSetLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&);
+
 template<typename WrapperClass, typename ItemType> JSC::JSValue forwardHasToSetLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, ItemType&&);
 template<typename WrapperClass, typename ItemType> JSC::JSValue forwardAddToSetLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, ItemType&&);
 template<typename WrapperClass, typename ItemType> JSC::JSValue forwardDeleteToSetLike(JSC::JSGlobalObject&, JSC::CallFrame&, WrapperClass&, ItemType&&);
@@ -52,7 +55,7 @@ template<typename WrapperClass, typename ItemType> JSC::JSValue forwardDeleteToS
 class DOMSetAdapter {
 public:
     DOMSetAdapter(JSC::JSGlobalObject&, JSC::JSObject&);
-    template<class IDLType> void add(typename IDLType::ParameterType value);
+    template<typename IDLType> void add(typename IDLType::ParameterType value);
     void clear();
 
 private:
@@ -66,20 +69,16 @@ inline DOMSetAdapter::DOMSetAdapter(JSC::JSGlobalObject& lexicalGlobalObject, JS
 {
 }
 
-template<class IDLType>
-inline void DOMSetAdapter::add(typename IDLType::ParameterType value)
+template<typename IDLType>
+void DOMSetAdapter::add(typename IDLType::ParameterType value)
 {
     JSC::JSLockHolder locker(&m_lexicalGlobalObject);
     auto item = toJS<IDLType>(m_lexicalGlobalObject, *JSC::jsCast<JSDOMGlobalObject*>(&m_lexicalGlobalObject), std::forward<typename IDLType::ParameterType>(value));
     addToBackingSet(m_lexicalGlobalObject, m_backingSet, item);
 }
 
-inline void DOMSetAdapter::clear()
-{
-    clearBackingSet(m_lexicalGlobalObject, m_backingSet);
-}
-
-template<typename WrapperClass> inline JSC::JSObject& getAndInitializeBackingSet(JSC::JSGlobalObject& lexicalGlobalObject, WrapperClass& setLike)
+template<typename WrapperClass>
+JSC::JSObject& getAndInitializeBackingSet(JSC::JSGlobalObject& lexicalGlobalObject, WrapperClass& setLike)
 {
     auto pair = getBackingSet(lexicalGlobalObject, setLike);
     if (pair.first) {
@@ -89,37 +88,43 @@ template<typename WrapperClass> inline JSC::JSObject& getAndInitializeBackingSet
     return pair.second.get();
 }
 
-template<typename WrapperClass> inline JSC::JSValue forwardSizeToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, WrapperClass& setLike)
+template<typename WrapperClass>
+JSC::JSValue forwardSizeToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, WrapperClass& setLike)
 {
     auto& vm = JSC::getVM(&lexicalGlobalObject);
     return forwardAttributeGetterToBackingSet(lexicalGlobalObject, getAndInitializeBackingSet(lexicalGlobalObject, setLike), vm.propertyNames->size);
 }
 
-template<typename WrapperClass> inline JSC::JSValue forwardEntriesToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike)
+template<typename WrapperClass>
+JSC::JSValue forwardEntriesToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike)
 {
     auto& vm = JSC::getVM(&lexicalGlobalObject);
     return forwardFunctionCallToBackingSet(lexicalGlobalObject, callFrame, getAndInitializeBackingSet(lexicalGlobalObject, setLike), vm.propertyNames->builtinNames().entriesPublicName());
 }
 
-template<typename WrapperClass> inline JSC::JSValue forwardKeysToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike)
+template<typename WrapperClass>
+JSC::JSValue forwardKeysToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike)
 {
     auto& vm = JSC::getVM(&lexicalGlobalObject);
     return forwardFunctionCallToBackingSet(lexicalGlobalObject, callFrame, getAndInitializeBackingSet(lexicalGlobalObject, setLike), vm.propertyNames->builtinNames().keysPublicName());
 }
 
-template<typename WrapperClass> inline JSC::JSValue forwardValuesToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike)
+template<typename WrapperClass>
+JSC::JSValue forwardValuesToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike)
 {
     auto& vm = JSC::getVM(&lexicalGlobalObject);
     return forwardFunctionCallToBackingSet(lexicalGlobalObject, callFrame, getAndInitializeBackingSet(lexicalGlobalObject, setLike), vm.propertyNames->builtinNames().valuesPublicName());
 }
 
-template<typename WrapperClass, typename ItemType> inline JSC::JSValue forwardHasToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike, ItemType&&)
+template<typename WrapperClass, typename Callback>
+JSC::JSValue forwardForEachToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike, Callback&&)
 {
-    auto& vm = JSC::getVM(&lexicalGlobalObject);
-    return forwardFunctionCallToBackingSet(lexicalGlobalObject, callFrame, getAndInitializeBackingSet(lexicalGlobalObject, setLike), vm.propertyNames->builtinNames().hasPublicName());
+    getAndInitializeBackingSet(lexicalGlobalObject, setLike);
+    return forwardForEachCallToBackingSet(*JSC::jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject), callFrame, setLike);
 }
 
-template<typename WrapperClass> inline JSC::JSValue forwardClearToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike)
+template<typename WrapperClass>
+JSC::JSValue forwardClearToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike)
 {
     setLike.wrapped().clearFromSetLike();
 
@@ -127,7 +132,15 @@ template<typename WrapperClass> inline JSC::JSValue forwardClearToSetLike(JSC::J
     return forwardFunctionCallToBackingSet(lexicalGlobalObject, callFrame, getAndInitializeBackingSet(lexicalGlobalObject, setLike), vm.propertyNames->clear);
 }
 
-template<typename WrapperClass, typename ItemType> inline JSC::JSValue forwardAddToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike, ItemType&& item)
+template<typename WrapperClass, typename ItemType>
+JSC::JSValue forwardHasToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike, ItemType&&)
+{
+    auto& vm = JSC::getVM(&lexicalGlobalObject);
+    return forwardFunctionCallToBackingSet(lexicalGlobalObject, callFrame, getAndInitializeBackingSet(lexicalGlobalObject, setLike), vm.propertyNames->builtinNames().hasPublicName());
+}
+
+template<typename WrapperClass, typename ItemType>
+JSC::JSValue forwardAddToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike, ItemType&& item)
 {
     setLike.wrapped().addToSetLike(std::forward<ItemType>(item));
 
@@ -136,7 +149,8 @@ template<typename WrapperClass, typename ItemType> inline JSC::JSValue forwardAd
     return &setLike;
 }
 
-template<typename WrapperClass, typename ItemType> inline JSC::JSValue forwardDeleteToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike, ItemType&& item)
+template<typename WrapperClass, typename ItemType>
+JSC::JSValue forwardDeleteToSetLike(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, WrapperClass& setLike, ItemType&& item)
 {
     auto isDeleted = setLike.wrapped().removeFromSetLike(std::forward<ItemType>(item));
     UNUSED_PARAM(isDeleted);
index 8e12759..896dd54 100644 (file)
@@ -2110,12 +2110,23 @@ sub parseSetLikeProperties
     $valuesOperation->extendedAttributes->{NotEnumerable} = 1;
     $valuesOperation->type(makeSimpleType("any"));
 
-    # FIXME: Add support to forEach
+    my $forEachOperation = IDLOperation->new();
+    $forEachOperation->name("forEach");
+    $forEachOperation->isSetLike(1);
+    my $forEachArgument = IDLArgument->new();
+    $forEachArgument->name("callback");
+    $forEachArgument->type(makeSimpleType("any"));
+    $forEachArgument->extendedAttributes($extendedAttributeList);
+    push(@{$forEachOperation->arguments}, ($forEachArgument));
+    $forEachOperation->extendedAttributes($extendedAttributeList);
+    $forEachOperation->extendedAttributes->{Enumerable} = 1;
+    $forEachOperation->type(makeSimpleType("any"));
 
     push(@{$setlike->operations}, $hasOperation);
     push(@{$setlike->operations}, $entriesOperation);
     push(@{$setlike->operations}, $keysOperation);
     push(@{$setlike->operations}, $valuesOperation);
+    push(@{$setlike->operations}, $forEachOperation);
 
     return $setlike if $isReadOnly;
 
index 34cfdbd..bdc1571 100644 (file)
@@ -50,6 +50,7 @@ JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlySetLikePrototypeFunctionHas(JSC::JSG
 JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlySetLikePrototypeFunctionEntries(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlySetLikePrototypeFunctionKeys(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlySetLikePrototypeFunctionValues(JSC::JSGlobalObject*, JSC::CallFrame*);
+JSC::EncodedJSValue JSC_HOST_CALL jsReadOnlySetLikePrototypeFunctionForEach(JSC::JSGlobalObject*, JSC::CallFrame*);
 
 // Attributes
 
@@ -110,6 +111,7 @@ static const HashTableValue JSReadOnlySetLikePrototypeTableValues[] =
     { "entries", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsReadOnlySetLikePrototypeFunctionEntries), (intptr_t) (0) } },
     { "keys", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsReadOnlySetLikePrototypeFunctionKeys), (intptr_t) (0) } },
     { "values", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsReadOnlySetLikePrototypeFunctionValues), (intptr_t) (0) } },
+    { "forEach", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsReadOnlySetLikePrototypeFunctionForEach), (intptr_t) (1) } },
 };
 
 const ClassInfo JSReadOnlySetLikePrototype::s_info = { "ReadOnlySetLikePrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadOnlySetLikePrototype) };
@@ -260,6 +262,23 @@ EncodedJSValue JSC_HOST_CALL jsReadOnlySetLikePrototypeFunctionValues(JSGlobalOb
     return IDLOperation<JSReadOnlySetLike>::call<jsReadOnlySetLikePrototypeFunctionValuesBody>(*lexicalGlobalObject, *callFrame, "values");
 }
 
+static inline JSC::EncodedJSValue jsReadOnlySetLikePrototypeFunctionForEachBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSReadOnlySetLike>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(lexicalGlobalObject);
+    UNUSED_PARAM(callFrame);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(callFrame->argumentCount() < 1))
+        return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+    auto callback = convert<IDLAny>(*lexicalGlobalObject, callFrame->uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS<IDLAny>(forwardForEachToSetLike(*lexicalGlobalObject, *callFrame, *castedThis, WTFMove(callback))));
+}
+
+EncodedJSValue JSC_HOST_CALL jsReadOnlySetLikePrototypeFunctionForEach(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
+{
+    return IDLOperation<JSReadOnlySetLike>::call<jsReadOnlySetLikePrototypeFunctionForEachBody>(*lexicalGlobalObject, *callFrame, "forEach");
+}
+
 void JSReadOnlySetLike::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
 {
     auto* thisObject = jsCast<JSReadOnlySetLike*>(cell);
index 73e64a8..246d4d4 100644 (file)
@@ -50,6 +50,7 @@ JSC::EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionHas(JSC::JSGlobalObj
 JSC::EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionEntries(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionKeys(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionValues(JSC::JSGlobalObject*, JSC::CallFrame*);
+JSC::EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionForEach(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionAdd(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionClear(JSC::JSGlobalObject*, JSC::CallFrame*);
 JSC::EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionDelete(JSC::JSGlobalObject*, JSC::CallFrame*);
@@ -113,6 +114,7 @@ static const HashTableValue JSSetLikePrototypeTableValues[] =
     { "entries", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSetLikePrototypeFunctionEntries), (intptr_t) (0) } },
     { "keys", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSetLikePrototypeFunctionKeys), (intptr_t) (0) } },
     { "values", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSetLikePrototypeFunctionValues), (intptr_t) (0) } },
+    { "forEach", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSetLikePrototypeFunctionForEach), (intptr_t) (1) } },
     { "add", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSetLikePrototypeFunctionAdd), (intptr_t) (1) } },
     { "clear", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSetLikePrototypeFunctionClear), (intptr_t) (0) } },
     { "delete", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsSetLikePrototypeFunctionDelete), (intptr_t) (1) } },
@@ -266,6 +268,23 @@ EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionValues(JSGlobalObject* le
     return IDLOperation<JSSetLike>::call<jsSetLikePrototypeFunctionValuesBody>(*lexicalGlobalObject, *callFrame, "values");
 }
 
+static inline JSC::EncodedJSValue jsSetLikePrototypeFunctionForEachBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSSetLike>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(lexicalGlobalObject);
+    UNUSED_PARAM(callFrame);
+    UNUSED_PARAM(throwScope);
+    if (UNLIKELY(callFrame->argumentCount() < 1))
+        return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
+    auto callback = convert<IDLAny>(*lexicalGlobalObject, callFrame->uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    return JSValue::encode(toJS<IDLAny>(forwardForEachToSetLike(*lexicalGlobalObject, *callFrame, *castedThis, WTFMove(callback))));
+}
+
+EncodedJSValue JSC_HOST_CALL jsSetLikePrototypeFunctionForEach(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
+{
+    return IDLOperation<JSSetLike>::call<jsSetLikePrototypeFunctionForEachBody>(*lexicalGlobalObject, *callFrame, "forEach");
+}
+
 static inline JSC::EncodedJSValue jsSetLikePrototypeFunctionAddBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSSetLike>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
 {
     UNUSED_PARAM(lexicalGlobalObject);