Title: [219873] trunk/Source/WebCore
Revision
219873
Author
wei...@apple.com
Date
2017-07-25 11:02:57 -0700 (Tue, 25 Jul 2017)

Log Message

[WebIDL] Add support for generating timer bindings
https://bugs.webkit.org/show_bug.cgi?id=174766

Reviewed by Darin Adler.

Adds a new non-standard type, ScheduledAction, which stands in for the
standard (DOMString or Function). It would be good to move to that in
future, but for now, this allows for forward momentum on removing custom
bindings.

* WebCore.xcodeproj/project.pbxproj:
Add JSDOMConvertScheduledAction.h.

* bindings/IDLTypes.h:
Add IDLScheduledAction.

* bindings/js/JSDOMConvertScheduledAction.h: Added.
(WebCore::Converter<IDLScheduledAction>::convert):
Add conversion from JSValue -> ScheduledAction. This is moved from the old ScheduledAction
create function.

* bindings/js/JSDOMConvertVariadic.h:
(WebCore::convertVariadicArguments):
(WebCore::Detail::VariadicConverterBase::convert): Deleted.
(WebCore::Detail::VariadicConverterBase<IDLInterface<T>>::convert): Deleted.
* bindings/js/JSDOMConvertBase.h:
* bindings/js/JSDOMConvertAny.h:
(WebCore::VariadicConverter<IDLAny>::convert):
* bindings/js/JSDOMConvertInterface.h:
(WebCore::VariadicConverter<IDLInterface<T>>::convert):
Rename VariadicConverter to VariadicConverterDetails, and remove base class. Rename 
VariadicConverterBase to VariadicConverter, and move specializations to the file
containing the base converter for that IDL type 

* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::setTimeout): Deleted.
(WebCore::JSDOMWindow::setInterval): Deleted.
* bindings/js/JSWorkerGlobalScopeCustom.cpp:
(WebCore::JSWorkerGlobalScope::setTimeout): Deleted.
(WebCore::JSWorkerGlobalScope::setInterval): Deleted.
Remove custom implementations of setTimeout and setInterval.

* bindings/js/ScheduledAction.cpp:
(WebCore::ScheduledAction::create):
(WebCore::ScheduledAction::ScheduledAction):
(WebCore::ScheduledAction::~ScheduledAction):
(WebCore::ScheduledAction::addArguments):
(WebCore::ScheduledAction::executeFunctionInContext):
* bindings/js/ScheduledAction.h:
(WebCore::ScheduledAction::ScheduledAction): Deleted.
Rework ScheduledAction. Now has two create functions, one for the function
form, one for the string form. These are now called by the Converter. Also,
rather than extracting the arguments directly from the ExecState, allow the
bindings to work as designed, and have the arguments come in as variadic 
arguments to setTimeout/setInterval and get added to the ScheduledAction if
needed. Also, move ContentSecurityPolicy check out of construction, and into
setTimeout/setInterval.

* bindings/scripts/CodeGenerator.pm:
(IsBuiltinType):
Add ScheduledAction to the builtin list.

* bindings/scripts/CodeGeneratorJS.pm:
(AddToIncludesForIDLType):
Add the correct include when ScheduledAction is used.

(GenerateParametersCheck):
Remove rule disallowing optional arguments before variadic arguments. That works
just fine.

(GetBaseIDLType):
Add mapping of ScheduledAction -> IDLScheduledAction.

(JSValueToNativeDOMConvertNeedsGlobalObject):
Add ScheduledAction to the list of types that need a global object
for conversion.

* page/WindowOrWorkerGlobalScope.idl:
Update interface to match spec and add FIXMEs for moving to TimerHandler.

* page/DOMWindow.cpp:
(WebCore::DOMWindow::setTimeout):
(WebCore::DOMWindow::setInterval):
* page/DOMWindow.h:
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::setTimeout):
(WebCore::WorkerGlobalScope::setInterval):
* workers/WorkerGlobalScope.h:
Update for new signatures. WorkerGlobalScope now has to return ExceptionOr<int>
even though it never throws, due to having one IDL file defining these. This is 
unfortunate and something we should look at addressing the future.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (219872 => 219873)


--- trunk/Source/WebCore/ChangeLog	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/ChangeLog	2017-07-25 18:02:57 UTC (rev 219873)
@@ -1,3 +1,97 @@
+2017-07-23  Sam Weinig  <s...@webkit.org>
+
+        [WebIDL] Add support for generating timer bindings
+        https://bugs.webkit.org/show_bug.cgi?id=174766
+
+        Reviewed by Darin Adler.
+
+        Adds a new non-standard type, ScheduledAction, which stands in for the
+        standard (DOMString or Function). It would be good to move to that in
+        future, but for now, this allows for forward momentum on removing custom
+        bindings.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Add JSDOMConvertScheduledAction.h.
+
+        * bindings/IDLTypes.h:
+        Add IDLScheduledAction.
+
+        * bindings/js/JSDOMConvertScheduledAction.h: Added.
+        (WebCore::Converter<IDLScheduledAction>::convert):
+        Add conversion from JSValue -> ScheduledAction. This is moved from the old ScheduledAction
+        create function.
+
+        * bindings/js/JSDOMConvertVariadic.h:
+        (WebCore::convertVariadicArguments):
+        (WebCore::Detail::VariadicConverterBase::convert): Deleted.
+        (WebCore::Detail::VariadicConverterBase<IDLInterface<T>>::convert): Deleted.
+        * bindings/js/JSDOMConvertBase.h:
+        * bindings/js/JSDOMConvertAny.h:
+        (WebCore::VariadicConverter<IDLAny>::convert):
+        * bindings/js/JSDOMConvertInterface.h:
+        (WebCore::VariadicConverter<IDLInterface<T>>::convert):
+        Rename VariadicConverter to VariadicConverterDetails, and remove base class. Rename 
+        VariadicConverterBase to VariadicConverter, and move specializations to the file
+        containing the base converter for that IDL type 
+
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::setTimeout): Deleted.
+        (WebCore::JSDOMWindow::setInterval): Deleted.
+        * bindings/js/JSWorkerGlobalScopeCustom.cpp:
+        (WebCore::JSWorkerGlobalScope::setTimeout): Deleted.
+        (WebCore::JSWorkerGlobalScope::setInterval): Deleted.
+        Remove custom implementations of setTimeout and setInterval.
+
+        * bindings/js/ScheduledAction.cpp:
+        (WebCore::ScheduledAction::create):
+        (WebCore::ScheduledAction::ScheduledAction):
+        (WebCore::ScheduledAction::~ScheduledAction):
+        (WebCore::ScheduledAction::addArguments):
+        (WebCore::ScheduledAction::executeFunctionInContext):
+        * bindings/js/ScheduledAction.h:
+        (WebCore::ScheduledAction::ScheduledAction): Deleted.
+        Rework ScheduledAction. Now has two create functions, one for the function
+        form, one for the string form. These are now called by the Converter. Also,
+        rather than extracting the arguments directly from the ExecState, allow the
+        bindings to work as designed, and have the arguments come in as variadic 
+        arguments to setTimeout/setInterval and get added to the ScheduledAction if
+        needed. Also, move ContentSecurityPolicy check out of construction, and into
+        setTimeout/setInterval.
+
+        * bindings/scripts/CodeGenerator.pm:
+        (IsBuiltinType):
+        Add ScheduledAction to the builtin list.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (AddToIncludesForIDLType):
+        Add the correct include when ScheduledAction is used.
+
+        (GenerateParametersCheck):
+        Remove rule disallowing optional arguments before variadic arguments. That works
+        just fine.
+
+        (GetBaseIDLType):
+        Add mapping of ScheduledAction -> IDLScheduledAction.
+
+        (JSValueToNativeDOMConvertNeedsGlobalObject):
+        Add ScheduledAction to the list of types that need a global object
+        for conversion.
+
+        * page/WindowOrWorkerGlobalScope.idl:
+        Update interface to match spec and add FIXMEs for moving to TimerHandler.
+
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::setTimeout):
+        (WebCore::DOMWindow::setInterval):
+        * page/DOMWindow.h:
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::setTimeout):
+        (WebCore::WorkerGlobalScope::setInterval):
+        * workers/WorkerGlobalScope.h:
+        Update for new signatures. WorkerGlobalScope now has to return ExceptionOr<int>
+        even though it never throws, due to having one IDL file defining these. This is 
+        unfortunate and something we should look at addressing the future.
+
 2017-07-25  Yoshiaki Jitsukawa  <yoshiaki.jitsuk...@sony.com>
 
         [WinCairo] Fix build with AllInOnes disabled

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (219872 => 219873)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-07-25 18:02:57 UTC (rev 219873)
@@ -3114,6 +3114,7 @@
 		7C1E8D011ED0C2DA00B1D983 /* CallbackResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C1E8D001ED0C2BE00B1D983 /* CallbackResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7C1E97271A9F9834007BF0FB /* AutoFillButtonElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C1E97251A9F9834007BF0FB /* AutoFillButtonElement.cpp */; };
 		7C1E97281A9F9834007BF0FB /* AutoFillButtonElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C1E97261A9F9834007BF0FB /* AutoFillButtonElement.h */; };
+		7C1F5D591F22FF7300A8874F /* JSDOMConvertScheduledAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C1F5D581F22FF7300A8874F /* JSDOMConvertScheduledAction.h */; };
 		7C2BDD3D17C7F98C0038FF15 /* JSDOMGlobalObjectTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2BDD3B17C7F98B0038FF15 /* JSDOMGlobalObjectTask.cpp */; };
 		7C2BDD3E17C7F98C0038FF15 /* JSDOMGlobalObjectTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C2BDD3C17C7F98B0038FF15 /* JSDOMGlobalObjectTask.h */; };
 		7C2FA6111EA95A3900A03108 /* ResourceCryptographicDigest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2FA60F1EA95A3200A03108 /* ResourceCryptographicDigest.cpp */; };
@@ -11120,6 +11121,7 @@
 		7C1E8D001ED0C2BE00B1D983 /* CallbackResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackResult.h; sourceTree = "<group>"; };
 		7C1E97251A9F9834007BF0FB /* AutoFillButtonElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AutoFillButtonElement.cpp; sourceTree = "<group>"; };
 		7C1E97261A9F9834007BF0FB /* AutoFillButtonElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoFillButtonElement.h; sourceTree = "<group>"; };
+		7C1F5D581F22FF7300A8874F /* JSDOMConvertScheduledAction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertScheduledAction.h; sourceTree = "<group>"; };
 		7C2BDD3B17C7F98B0038FF15 /* JSDOMGlobalObjectTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMGlobalObjectTask.cpp; sourceTree = "<group>"; };
 		7C2BDD3C17C7F98B0038FF15 /* JSDOMGlobalObjectTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMGlobalObjectTask.h; sourceTree = "<group>"; };
 		7C2FA60F1EA95A3200A03108 /* ResourceCryptographicDigest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceCryptographicDigest.cpp; sourceTree = "<group>"; };
@@ -19591,6 +19593,8 @@
 				BC46C1ED0C0DDBDF0020CFC3 /* JSCSSRuleCustom.cpp */,
 				AD726FE916D9F40A003A4E6D /* JSCSSRuleCustom.h */,
 				9392262E10321084006E7D5D /* JSCSSRuleListCustom.cpp */,
+				BC5825F20C0B89380053F1B5 /* JSCSSStyleDeclarationCustom.cpp */,
+				AD726FEA16D9F40B003A4E6D /* JSCSSStyleDeclarationCustom.h */,
 				BC20FB7E0C0E8E6C00D1447F /* JSDeprecatedCSSOMValueCustom.cpp */,
 				49C7BA8C1042F5B10009D447 /* JSDocumentCustom.cpp */,
 				ADDA94BF19686F8000453029 /* JSDocumentCustom.h */,
@@ -19636,6 +19640,7 @@
 				49EED14C1051971A00099FAB /* JSWebGLRenderingContextCustom.cpp */,
 				31A088C41E737B2C003B6609 /* JSWebGPURenderingContextCustom.cpp */,
 				31A088C51E737B2C003B6609 /* JSWebGPURenderPassAttachmentDescriptorCustom.cpp */,
+				E18258AB0EF3CD7000933242 /* JSWorkerGlobalScopeCustom.cpp */,
 				83A4A9F81CE7FD7E00709B00 /* JSXMLDocumentCustom.cpp */,
 				836C14421CDEAFCA0073493F /* JSXPathNSResolverCustom.cpp */,
 				A1C7FAA1133A5D3500D6732D /* JSXPathResultCustom.cpp */,
@@ -19697,6 +19702,7 @@
 				7C8E34A31E4A338E0054CE23 /* JSDOMConvertObject.h */,
 				E323CFF91E5AF6A500F0B4A0 /* JSDOMConvertPromise.h */,
 				7C8E34A41E4A338E0054CE23 /* JSDOMConvertRecord.h */,
+				7C1F5D581F22FF7300A8874F /* JSDOMConvertScheduledAction.h */,
 				7C8E34A51E4A338E0054CE23 /* JSDOMConvertSequences.h */,
 				7C8E34A61E4A338E0054CE23 /* JSDOMConvertSerializedScriptValue.h */,
 				7C8E34A71E4A338E0054CE23 /* JSDOMConvertStrings.cpp */,
@@ -19703,8 +19709,8 @@
 				7C8E34A81E4A338E0054CE23 /* JSDOMConvertStrings.h */,
 				7C8E34A91E4A338E0054CE23 /* JSDOMConvertUnion.h */,
 				7C8E34AA1E4A338E0054CE23 /* JSDOMConvertVariadic.h */,
+				7CBA5BA61F0B4BDE0034D745 /* JSDOMConvertWebGL.cpp */,
 				7C8E34AB1E4A338E0054CE23 /* JSDOMConvertWebGL.h */,
-				7CBA5BA61F0B4BDE0034D745 /* JSDOMConvertWebGL.cpp */,
 				7C8E34AC1E4A338E0054CE23 /* JSDOMConvertXPathNSResolver.h */,
 			);
 			name = Conversions;
@@ -23499,8 +23505,6 @@
 				7C3D8EE41E08BABE0023B084 /* GC / Wrapping Only */,
 				7CBA5BA91F0B51480034D745 /* Promises Only */,
 				E157A8E618184C67009F821D /* JSCryptoKeyCustom.cpp */,
-				BC5825F20C0B89380053F1B5 /* JSCSSStyleDeclarationCustom.cpp */,
-				AD726FEA16D9F40B003A4E6D /* JSCSSStyleDeclarationCustom.h */,
 				9BC5F9DF1D5AAF6A002B749D /* JSCustomElementRegistryCustom.cpp */,
 				DEC2975D1B4DEB2A005F5945 /* JSCustomEventCustom.cpp */,
 				BCD9C25E0C17AA67005C90A2 /* JSDOMWindowCustom.cpp */,
@@ -23517,7 +23521,6 @@
 				51D0C5150DAA90B7003B3831 /* JSStorageCustom.cpp */,
 				57A9C88D1DA70BF800BC7305 /* JSSubtleCryptoCustom.cpp */,
 				E1FF8F661807460800132674 /* JSWebKitSubtleCryptoCustom.cpp */,
-				E18258AB0EF3CD7000933242 /* JSWorkerGlobalScopeCustom.cpp */,
 				BC348BBD0DB7F531004ABAB9 /* JSXMLHttpRequestCustom.cpp */,
 			);
 			name = Custom;
@@ -27250,6 +27253,7 @@
 				BC23F0DB0DAFF4A4009FDC91 /* GeneratedImage.h in Headers */,
 				830030F61B7D33B500ED3AAC /* GenericCachedHTMLCollection.h in Headers */,
 				0720B0A114D3323500642955 /* GenericEventQueue.h in Headers */,
+				7C1F5D591F22FF7300A8874F /* JSDOMConvertScheduledAction.h in Headers */,
 				CD62FB961AF018E70012ED7D /* GenericTaskQueue.h in Headers */,
 				9746AF2414F4DDE6003E7A70 /* Geolocation.h in Headers */,
 				9746AF2514F4DDE6003E7A71 /* GeolocationClient.h in Headers */,

Modified: trunk/Source/WebCore/bindings/IDLTypes.h (219872 => 219873)


--- trunk/Source/WebCore/bindings/IDLTypes.h	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/IDLTypes.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -51,6 +51,7 @@
 class IDBKeyData;
 class IDBValue;
 class DOMPromise;
+class ScheduledAction;
 
 #if ENABLE(WEBGL)
 class WebGLExtension;
@@ -255,6 +256,7 @@
     template <typename U> static U&& extractValueFromNullable(U&& value) { return std::forward<U>(value); }
 };
 
+struct IDLScheduledAction : IDLType<std::unique_ptr<ScheduledAction>> { };
 template<typename T> struct IDLSerializedScriptValue : IDLWrapper<T> { };
 template<typename T> struct IDLEventListener : IDLWrapper<T> { };
 template<typename T> struct IDLXPathNSResolver : IDLWrapper<T> { };

Modified: trunk/Source/WebCore/bindings/js/JSDOMConvertAny.h (219872 => 219873)


--- trunk/Source/WebCore/bindings/js/JSDOMConvertAny.h	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvertAny.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -61,4 +61,19 @@
     }
 };
 
+template<> struct VariadicConverter<IDLAny> {
+    using Item = typename IDLAny::ImplementationType;
+
+    static std::optional<Item> convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        auto& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        auto result = Converter<IDLAny>::convert(state, value);
+        RETURN_IF_EXCEPTION(scope, std::nullopt);
+
+        return Item { vm, result };
+    }
+};
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/JSDOMConvertBase.h (219872 => 219873)


--- trunk/Source/WebCore/bindings/js/JSDOMConvertBase.h	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvertBase.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -199,4 +199,7 @@
     static constexpr bool conversionHasSideEffects = true;
 };
 
+// Conversion from JSValue -> Implementation for variadic arguments
+template<typename IDLType> struct VariadicConverter;
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/JSDOMConvertInterface.h (219872 => 219873)


--- trunk/Source/WebCore/bindings/js/JSDOMConvertInterface.h	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvertInterface.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -66,5 +66,16 @@
     }
 };
 
+template<typename T> struct VariadicConverter<IDLInterface<T>> {
+    using Item = std::reference_wrapper<T>;
 
+    static std::optional<Item> convert(JSC::ExecState& state, JSC::JSValue value)
+    {
+        auto* result = Converter<IDLInterface<T>>::convert(state, value);
+        if (!result)
+            return std::nullopt;
+        return std::optional<Item> { *result };
+    }
+};
+
 } // namespace WebCore

Added: trunk/Source/WebCore/bindings/js/JSDOMConvertScheduledAction.h (0 => 219873)


--- trunk/Source/WebCore/bindings/js/JSDOMConvertScheduledAction.h	                        (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvertScheduledAction.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
+#include "JSDOMConvertStrings.h"
+#include "ScheduledAction.h"
+
+namespace WebCore {
+
+template<> struct Converter<IDLScheduledAction> : DefaultConverter<IDLScheduledAction> {
+    static std::unique_ptr<ScheduledAction> convert(JSC::ExecState& state, JSC::JSValue value, JSDOMGlobalObject& globalObject)
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        JSC::CallData callData;
+        if (getCallData(value, callData) == JSC::CallType::None) {
+            auto code = Converter<IDLDOMString>::convert(state, value);
+            RETURN_IF_EXCEPTION(scope, nullptr);
+            return ScheduledAction::create(globalObject.world(), WTFMove(code));
+        }
+
+        // The value must be an object at this point because no non-object values are callable.
+        ASSERT(value.isObject());
+        return ScheduledAction::create(globalObject.world(), JSC::Strong<JSC::Unknown> { vm, JSC::asObject(value) });
+    }
+};
+
+}
+

Modified: trunk/Source/WebCore/bindings/js/JSDOMConvertVariadic.h (219872 => 219873)


--- trunk/Source/WebCore/bindings/js/JSDOMConvertVariadic.h	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvertVariadic.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -26,16 +26,12 @@
 #pragma once
 
 #include "IDLTypes.h"
+#include "JSDOMConvertBase.h"
 
 namespace WebCore {
 
-namespace Detail {
-
 template<typename IDLType>
-struct VariadicConverterBase;
-
-template<typename IDLType> 
-struct VariadicConverterBase {
+struct VariadicConverter {
     using Item = typename IDLType::ImplementationType;
 
     static std::optional<Item> convert(JSC::ExecState& state, JSC::JSValue value)
@@ -50,49 +46,23 @@
     }
 };
 
-template<typename T>
-struct VariadicConverterBase<IDLInterface<T>> {
-    using Item = std::reference_wrapper<T>;
-
-    static std::optional<Item> convert(JSC::ExecState& state, JSC::JSValue value)
-    {
-        auto* result = Converter<IDLInterface<T>>::convert(state, value);
-        if (!result)
-            return std::nullopt;
-        return std::optional<Item>(*result);
-    }
-};
-
-template<typename IDLType>
-struct VariadicConverter : VariadicConverterBase<IDLType> {
-    using Item = typename VariadicConverterBase<IDLType>::Item;
-    using Container = Vector<Item>;
-
-    struct Result {
-        size_t argumentIndex;
-        std::optional<Container> arguments;
-    };
-};
-
-}
-
-template<typename IDLType> typename Detail::VariadicConverter<IDLType>::Result convertVariadicArguments(JSC::ExecState& state, size_t startIndex)
+template<typename IDLType> Vector<typename VariadicConverter<IDLType>::Item> convertVariadicArguments(JSC::ExecState& state, size_t startIndex)
 {
     size_t length = state.argumentCount();
-    if (startIndex > length)
-        return { 0, std::nullopt };
+    if (startIndex >= length)
+        return { };
 
-    typename Detail::VariadicConverter<IDLType>::Container result;
+    Vector<typename VariadicConverter<IDLType>::Item> result;
     result.reserveInitialCapacity(length - startIndex);
 
     for (size_t i = startIndex; i < length; ++i) {
-        auto value = Detail::VariadicConverter<IDLType>::convert(state, state.uncheckedArgument(i));
+        auto value = VariadicConverter<IDLType>::convert(state, state.uncheckedArgument(i));
         if (!value)
-            return { i, std::nullopt };
+            return { };
         result.uncheckedAppend(WTFMove(*value));
     }
 
-    return { length, WTFMove(result) };
+    return WTFMove(result);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp (219872 => 219873)


--- trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp	2017-07-25 18:02:57 UTC (rev 219873)
@@ -459,42 +459,6 @@
     return handler.returnValue();
 }
 
-JSValue JSDOMWindow::setTimeout(ExecState& state)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(state.argumentCount() < 1))
-        return throwException(&state, scope, createNotEnoughArgumentsError(&state));
-
-    auto* contentSecurityPolicy = wrapped().document() ? wrapped().document()->contentSecurityPolicy() : nullptr;
-    auto action = "" globalObject()->world(), contentSecurityPolicy);
-    RETURN_IF_EXCEPTION(scope, JSValue());
-    if (!action)
-        return jsNumber(0);
-
-    int delay = state.argument(1).toInt32(&state);
-    return toJS<IDLLong>(state, scope, wrapped().setTimeout(WTFMove(action), delay));
-}
-
-JSValue JSDOMWindow::setInterval(ExecState& state)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(state.argumentCount() < 1))
-        return throwException(&state, scope, createNotEnoughArgumentsError(&state));
-
-    auto* contentSecurityPolicy = wrapped().document() ? wrapped().document()->contentSecurityPolicy() : nullptr;
-    auto action = "" globalObject()->world(), contentSecurityPolicy);
-    RETURN_IF_EXCEPTION(scope, JSValue());
-    if (!action)
-        return jsNumber(0);
-
-    int delay = state.argument(1).toInt32(&state);
-    return toJS<IDLLong>(state, scope, wrapped().setInterval(WTFMove(action), delay));
-}
-
 DOMWindow* JSDOMWindow::toWrapped(VM& vm, JSValue value)
 {
     if (!value.isObject())

Modified: trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp (219872 => 219873)


--- trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp	2017-07-25 18:02:57 UTC (rev 219873)
@@ -26,8 +26,6 @@
 #include "config.h"
 #include "JSWorkerGlobalScope.h"
 
-#include "JSDOMConvert.h"
-#include "ScheduledAction.h"
 #include "WorkerGlobalScope.h"
 
 using namespace JSC;
@@ -49,36 +47,4 @@
     wrapped().visitJSEventListeners(visitor);
 }
 
-JSValue JSWorkerGlobalScope::setTimeout(ExecState& state)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(state.argumentCount() < 1))
-        return throwException(&state, scope, createNotEnoughArgumentsError(&state));
-
-    std::unique_ptr<ScheduledAction> action = "" globalObject()->world(), wrapped().contentSecurityPolicy());
-    RETURN_IF_EXCEPTION(scope, JSValue());
-    if (!action)
-        return jsNumber(0);
-    int delay = state.argument(1).toInt32(&state);
-    return jsNumber(wrapped().setTimeout(WTFMove(action), delay));
-}
-
-JSValue JSWorkerGlobalScope::setInterval(ExecState& state)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(state.argumentCount() < 1))
-        return throwException(&state, scope, createNotEnoughArgumentsError(&state));
-
-    std::unique_ptr<ScheduledAction> action = "" globalObject()->world(), wrapped().contentSecurityPolicy());
-    RETURN_IF_EXCEPTION(scope, JSValue());
-    if (!action)
-        return jsNumber(0);
-    int delay = state.argument(1).toInt32(&state);
-    return jsNumber(wrapped().setInterval(WTFMove(action), delay));
-}
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/ScheduledAction.cpp (219872 => 219873)


--- trunk/Source/WebCore/bindings/js/ScheduledAction.cpp	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/js/ScheduledAction.cpp	2017-07-25 18:02:57 UTC (rev 219873)
@@ -26,6 +26,7 @@
 
 #include "ContentSecurityPolicy.h"
 #include "DOMWindow.h"
+#include "DOMWrapperWorld.h"
 #include "Document.h"
 #include "Frame.h"
 #include "FrameLoader.h"
@@ -45,34 +46,43 @@
 
 namespace WebCore {
 
-std::unique_ptr<ScheduledAction> ScheduledAction::create(ExecState* exec, DOMWrapperWorld& isolatedWorld, ContentSecurityPolicy* policy)
+std::unique_ptr<ScheduledAction> ScheduledAction::create(DOMWrapperWorld& isolatedWorld, JSC::Strong<JSC::Unknown>&& function)
 {
-    VM& vm = exec->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
+    return std::unique_ptr<ScheduledAction>(new ScheduledAction(isolatedWorld, WTFMove(function)));
+}
 
-    JSValue v = exec->argument(0);
-    CallData callData;
-    if (getCallData(v, callData) == CallType::None) {
-        if (policy && !policy->allowEval(exec))
-            return nullptr;
-        String string = v.toWTFString(exec);
-        RETURN_IF_EXCEPTION(scope, nullptr);
-        return std::unique_ptr<ScheduledAction>(new ScheduledAction(string, isolatedWorld));
-    }
+std::unique_ptr<ScheduledAction> ScheduledAction::create(DOMWrapperWorld& isolatedWorld, String&& code)
+{
+    return std::unique_ptr<ScheduledAction>(new ScheduledAction(isolatedWorld, WTFMove(code)));
+}
 
-    return std::unique_ptr<ScheduledAction>(new ScheduledAction(exec, v, isolatedWorld));
+ScheduledAction::ScheduledAction(DOMWrapperWorld& isolatedWorld, JSC::Strong<JSC::Unknown>&& function)
+    : m_isolatedWorld(isolatedWorld)
+    , m_function(WTFMove(function))
+{
 }
 
-ScheduledAction::ScheduledAction(ExecState* exec, JSValue function, DOMWrapperWorld& isolatedWorld)
-    : m_function(exec->vm(), function)
-    , m_isolatedWorld(isolatedWorld)
+ScheduledAction::ScheduledAction(DOMWrapperWorld& isolatedWorld, String&& code)
+    : m_isolatedWorld(isolatedWorld)
+    , m_function(isolatedWorld.vm())
+    , m_code(WTFMove(code))
 {
-    // setTimeout(function, interval, arg0, arg1...).
-    // Start at 2 to skip function and interval.
-    for (size_t i = 2; i < exec->argumentCount(); ++i)
-        m_args.append(Strong<JSC::Unknown>(exec->vm(), exec->uncheckedArgument(i)));
 }
 
+ScheduledAction::~ScheduledAction()
+{
+}
+
+void ScheduledAction::addArguments(Vector<JSC::Strong<JSC::Unknown>>&& arguments)
+{
+    m_arguments = WTFMove(arguments);
+}
+
+auto ScheduledAction::type() const -> Type
+{
+    return m_function ? Type::Function : Type::Code;
+}
+
 void ScheduledAction::execute(ScriptExecutionContext& context)
 {
     if (is<Document>(context))
@@ -93,18 +103,17 @@
 
     ExecState* exec = globalObject->globalExec();
 
-    MarkedArgumentBuffer args;
-    size_t size = m_args.size();
-    for (size_t i = 0; i < size; ++i)
-        args.append(m_args[i].get());
+    MarkedArgumentBuffer arguments;
+    for (auto& argument : m_arguments)
+        arguments.append(argument.get());
 
     InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(&context, callType, callData);
 
     NakedPtr<JSC::Exception> exception;
     if (is<Document>(context))
-        JSMainThreadExecState::profiledCall(exec, JSC::ProfilingReason::Other, m_function.get(), callType, callData, thisValue, args, exception);
+        JSMainThreadExecState::profiledCall(exec, JSC::ProfilingReason::Other, m_function.get(), callType, callData, thisValue, arguments, exception);
     else
-        JSC::profiledCall(exec, JSC::ProfilingReason::Other, m_function.get(), callType, callData, thisValue, args, exception);
+        JSC::profiledCall(exec, JSC::ProfilingReason::Other, m_function.get(), callType, callData, thisValue, arguments, exception);
 
     InspectorInstrumentation::didCallFunction(cookie, &context);
 

Modified: trunk/Source/WebCore/bindings/js/ScheduledAction.h (219872 => 219873)


--- trunk/Source/WebCore/bindings/js/ScheduledAction.h	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/js/ScheduledAction.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -19,7 +19,6 @@
 
 #pragma once
 
-#include "JSDOMBinding.h"
 #include <heap/Strong.h>
 #include <heap/StrongInlines.h>
 #include <memory>
@@ -27,44 +26,42 @@
 #include <wtf/text/WTFString.h>
 
 namespace JSC {
-    class JSGlobalObject;
+class JSGlobalObject;
 }
 
 namespace WebCore {
 
-    class Document;
-    class ContentSecurityPolicy;
-    class ScriptExecutionContext;
-    class WorkerGlobalScope;
+class DOMWrapperWorld;
+class Document;
+class ScriptExecutionContext;
+class WorkerGlobalScope;
 
-   /* An action (either function or string) to be executed after a specified
-    * time interval, either once or repeatedly. Used for window.setTimeout()
-    * and window.setInterval()
-    */
-    class ScheduledAction {
-        WTF_MAKE_NONCOPYABLE(ScheduledAction); WTF_MAKE_FAST_ALLOCATED;
-    public:
-        static std::unique_ptr<ScheduledAction> create(JSC::ExecState*, DOMWrapperWorld& isolatedWorld, ContentSecurityPolicy*);
+class ScheduledAction {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static std::unique_ptr<ScheduledAction> create(DOMWrapperWorld&, JSC::Strong<JSC::Unknown>&&);
+    static std::unique_ptr<ScheduledAction> create(DOMWrapperWorld&, String&&);
+    ~ScheduledAction();
 
-        void execute(ScriptExecutionContext&);
+    void addArguments(Vector<JSC::Strong<JSC::Unknown>>&&);
 
-    private:
-        ScheduledAction(JSC::ExecState*, JSC::JSValue function, DOMWrapperWorld& isolatedWorld);
-        ScheduledAction(const String& code, DOMWrapperWorld& isolatedWorld)
-            : m_function(isolatedWorld.vm())
-            , m_code(code)
-            , m_isolatedWorld(isolatedWorld)
-        {
-        }
+    enum class Type { Code, Function };
+    Type type() const;
 
-        void executeFunctionInContext(JSC::JSGlobalObject*, JSC::JSValue thisValue, ScriptExecutionContext&);
-        void execute(Document&);
-        void execute(WorkerGlobalScope&);
+    void execute(ScriptExecutionContext&);
 
-        JSC::Strong<JSC::Unknown> m_function;
-        Vector<JSC::Strong<JSC::Unknown>> m_args;
-        String m_code;
-        Ref<DOMWrapperWorld> m_isolatedWorld;
-    };
+private:
+    ScheduledAction(DOMWrapperWorld&, JSC::Strong<JSC::Unknown>&&);
+    ScheduledAction(DOMWrapperWorld&, String&&);
 
+    void executeFunctionInContext(JSC::JSGlobalObject*, JSC::JSValue thisValue, ScriptExecutionContext&);
+    void execute(Document&);
+    void execute(WorkerGlobalScope&);
+
+    Ref<DOMWrapperWorld> m_isolatedWorld;
+    JSC::Strong<JSC::Unknown> m_function;
+    Vector<JSC::Strong<JSC::Unknown>> m_arguments;
+    String m_code;
+};
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm (219872 => 219873)


--- trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm	2017-07-25 18:02:57 UTC (rev 219873)
@@ -870,6 +870,7 @@
     return 1 if $type->name eq "EventListener";
     return 1 if $type->name eq "JSON";
     return 1 if $type->name eq "Promise";
+    return 1 if $type->name eq "ScheduledAction";
     return 1 if $type->name eq "SerializedScriptValue";
     return 1 if $type->name eq "XPathNSResolver";
     return 1 if $type->name eq "any";

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (219872 => 219873)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2017-07-25 18:02:57 UTC (rev 219873)
@@ -417,6 +417,11 @@
         return;
     }
 
+    if ($type->name eq "ScheduledAction") {
+        AddToIncludes("JSDOMConvertScheduledAction.h", $includesRef, $conditional);
+        return;
+    }
+
     if ($type->name eq "SerializedScriptValue") {
         AddToIncludes("SerializedScriptValue.h", $includesRef, $conditional);
         AddToIncludes("JSDOMConvertSerializedScriptValue.h", $includesRef, $conditional);
@@ -5524,7 +5529,6 @@
         my $type = $argument->type;
 
         die "Optional arguments of non-nullable wrapper types are not supported" if $argument->isOptional && !$type->isNullable && $codeGenerator->IsWrapperType($type);
-        die "Optional arguments preceding variadic arguments are not supported" if ($argument->isOptional &&  @{$operation->arguments}[$numArguments - 1]->isVariadic);
 
         if ($argument->isOptional && !defined($argument->default)) {
             # As per Web IDL, optional dictionary arguments are always considered to have a default value of an empty dictionary, unless otherwise specified.
@@ -5559,7 +5563,7 @@
             push(@$outputArray, $indent . "auto ${name} = convertVariadicArguments<${IDLType}>(*state, ${argumentIndex});\n");
             push(@$outputArray, $indent . "RETURN_IF_EXCEPTION(throwScope, encodedJSValue());\n");
 
-            $value = "WTFMove(${name}.arguments.value())";
+            $value = "WTFMove(${name})";
         } else {
             my $argumentLookupForConversion;
             my $optionalCheck;
@@ -6251,6 +6255,7 @@
         "Date" => "IDLDate",
         "EventListener" => "IDLEventListener<JSEventListener>",
         "JSON" => "IDLJSON",
+        "ScheduledAction" => "IDLScheduledAction",
         "SerializedScriptValue" => "IDLSerializedScriptValue<SerializedScriptValue>",
         "XPathNSResolver" => "IDLXPathNSResolver<XPathNSResolver>",
     );
@@ -6316,6 +6321,7 @@
 
     return 1 if $codeGenerator->IsCallbackInterface($type);
     return 1 if $codeGenerator->IsCallbackFunction($type);
+    return 1 if $type->name eq "ScheduledAction";
     return 0;
 }
 

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (219872 => 219873)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2017-07-25 18:02:57 UTC (rev 219873)
@@ -6740,7 +6740,7 @@
     auto& impl = castedThis->wrapped();
     auto blobArgs = convertVariadicArguments<IDLInterface<Blob>>(*state, 0);
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    impl.overloadedMethod(WTFMove(blobArgs.arguments.value()));
+    impl.overloadedMethod(WTFMove(blobArgs));
     return JSValue::encode(jsUndefined());
 }
 
@@ -7539,7 +7539,7 @@
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     auto tail = convertVariadicArguments<IDLDOMString>(*state, 1);
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    impl.variadicStringMethod(WTFMove(head), WTFMove(tail.arguments.value()));
+    impl.variadicStringMethod(WTFMove(head), WTFMove(tail));
     return JSValue::encode(jsUndefined());
 }
 
@@ -7559,7 +7559,7 @@
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     auto tail = convertVariadicArguments<IDLUnrestrictedDouble>(*state, 1);
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    impl.variadicDoubleMethod(WTFMove(head), WTFMove(tail.arguments.value()));
+    impl.variadicDoubleMethod(WTFMove(head), WTFMove(tail));
     return JSValue::encode(jsUndefined());
 }
 
@@ -7579,7 +7579,7 @@
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     auto tail = convertVariadicArguments<IDLInterface<Node>>(*state, 1);
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    impl.variadicNodeMethod(*head, WTFMove(tail.arguments.value()));
+    impl.variadicNodeMethod(*head, WTFMove(tail));
     return JSValue::encode(jsUndefined());
 }
 
@@ -7599,7 +7599,7 @@
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     auto tail = convertVariadicArguments<IDLUnion<IDLInterface<Node>, IDLDOMString>>(*state, 1);
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    impl.variadicUnionMethod(WTFMove(head), WTFMove(tail.arguments.value()));
+    impl.variadicUnionMethod(WTFMove(head), WTFMove(tail));
     return JSValue::encode(jsUndefined());
 }
 

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp (219872 => 219873)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp	2017-07-25 18:02:57 UTC (rev 219873)
@@ -132,7 +132,7 @@
     ASSERT(castedThis);
     auto longArgs = convertVariadicArguments<IDLLong>(*state, 0);
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    auto object = TestOverloadedConstructors::create(WTFMove(longArgs.arguments.value()));
+    auto object = TestOverloadedConstructors::create(WTFMove(longArgs));
     return JSValue::encode(toJSNewlyCreated<IDLInterface<TestOverloadedConstructors>>(*state, *castedThis->globalObject(), WTFMove(object)));
 }
 

Modified: trunk/Source/WebCore/page/DOMWindow.cpp (219872 => 219873)


--- trunk/Source/WebCore/page/DOMWindow.cpp	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/page/DOMWindow.cpp	2017-07-25 18:02:57 UTC (rev 219873)
@@ -1666,11 +1666,20 @@
     page->chrome().setWindowRect(adjustWindowRect(*page, update));
 }
 
-ExceptionOr<int> DOMWindow::setTimeout(std::unique_ptr<ScheduledAction> action, int timeout)
+ExceptionOr<int> DOMWindow::setTimeout(JSC::ExecState& state, std::unique_ptr<ScheduledAction> action, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
 {
     auto* context = scriptExecutionContext();
     if (!context)
         return Exception { InvalidAccessError };
+
+    // FIXME: Should this check really happen here? Or should it happen when code is about to eval?
+    if (action->type() == ScheduledAction::Type::Code) {
+        if (!context->contentSecurityPolicy()->allowEval(&state))
+            return 0;
+    }
+
+    action->addArguments(WTFMove(arguments));
+
     return DOMTimer::install(*context, WTFMove(action), Seconds::fromMilliseconds(timeout), true);
 }
 
@@ -1698,11 +1707,20 @@
     DOMTimer::removeById(*context, timeoutId);
 }
 
-ExceptionOr<int> DOMWindow::setInterval(std::unique_ptr<ScheduledAction> action, int timeout)
+ExceptionOr<int> DOMWindow::setInterval(JSC::ExecState& state, std::unique_ptr<ScheduledAction> action, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
 {
     auto* context = scriptExecutionContext();
     if (!context)
         return Exception { InvalidAccessError };
+
+    // FIXME: Should this check really happen here? Or should it happen when code is about to eval?
+    if (action->type() == ScheduledAction::Type::Code) {
+        if (!context->contentSecurityPolicy()->allowEval(&state))
+            return 0;
+    }
+
+    action->addArguments(WTFMove(arguments));
+
     return DOMTimer::install(*context, WTFMove(action), Seconds::fromMilliseconds(timeout), false);
 }
 

Modified: trunk/Source/WebCore/page/DOMWindow.h (219872 => 219873)


--- trunk/Source/WebCore/page/DOMWindow.h	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/page/DOMWindow.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -33,6 +33,7 @@
 #include "FrameDestructionObserver.h"
 #include "ScrollToOptions.h"
 #include "Supplementable.h"
+#include <heap/HandleTypes.h>
 #include <wtf/Function.h>
 #include <wtf/HashSet.h>
 #include <wtf/WeakPtr.h>
@@ -239,9 +240,9 @@
     void resizeTo(float width, float height) const;
 
     // Timers
-    ExceptionOr<int> setTimeout(std::unique_ptr<ScheduledAction>, int timeout);
+    ExceptionOr<int> setTimeout(JSC::ExecState&, std::unique_ptr<ScheduledAction>, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
     void clearTimeout(int timeoutId);
-    ExceptionOr<int> setInterval(std::unique_ptr<ScheduledAction>, int timeout);
+    ExceptionOr<int> setInterval(JSC::ExecState&, std::unique_ptr<ScheduledAction>, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
     void clearInterval(int timeoutId);
 
     int requestAnimationFrame(Ref<RequestAnimationFrameCallback>&&);

Modified: trunk/Source/WebCore/page/WindowOrWorkerGlobalScope.idl (219872 => 219873)


--- trunk/Source/WebCore/page/WindowOrWorkerGlobalScope.idl	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/page/WindowOrWorkerGlobalScope.idl	2017-07-25 18:02:57 UTC (rev 219873)
@@ -31,9 +31,11 @@
     [Replaceable] readonly attribute USVString origin;
 
     // Timers
-    [Custom] long setTimeout(any handler, optional long timeout = 0);
+    // FIXME: This should take a TimerHandler (a.k.a. (DOMString or Function)) rather than a ScheduledAction.
+    [CallWith=ScriptState, MayThrowException] long setTimeout(ScheduledAction handler, optional long timeout = 0, any... arguments);
     void clearTimeout(optional long handle = 0);
-    [Custom] long setInterval(any handler, optional long timeout = 0);
+    // FIXME: This should take a TimerHandler (a.k.a. (DOMString or Function)) rather than a ScheduledAction.
+    [CallWith=ScriptState, MayThrowException] long setInterval(ScheduledAction handler, optional long timeout = 0, any... arguments);
     void clearInterval(optional long handle = 0);
 
     // Base64 utility methods.

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (219872 => 219873)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2017-07-25 18:02:57 UTC (rev 219873)
@@ -222,8 +222,16 @@
     thread().runLoop().postTask(WTFMove(task));
 }
 
-int WorkerGlobalScope::setTimeout(std::unique_ptr<ScheduledAction> action, int timeout)
+ExceptionOr<int> WorkerGlobalScope::setTimeout(JSC::ExecState& state, std::unique_ptr<ScheduledAction> action, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
 {
+    // FIXME: Should this check really happen here? Or should it happen when code is about to eval?
+    if (action->type() == ScheduledAction::Type::Code) {
+        if (!contentSecurityPolicy()->allowEval(&state))
+            return 0;
+    }
+
+    action->addArguments(WTFMove(arguments));
+
     return DOMTimer::install(*this, WTFMove(action), Seconds::fromMilliseconds(timeout), true);
 }
 
@@ -232,8 +240,16 @@
     DOMTimer::removeById(*this, timeoutId);
 }
 
-int WorkerGlobalScope::setInterval(std::unique_ptr<ScheduledAction> action, int timeout)
+ExceptionOr<int> WorkerGlobalScope::setInterval(JSC::ExecState& state, std::unique_ptr<ScheduledAction> action, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
 {
+    // FIXME: Should this check really happen here? Or should it happen when code is about to eval?
+    if (action->type() == ScheduledAction::Type::Code) {
+        if (!contentSecurityPolicy()->allowEval(&state))
+            return 0;
+    }
+
+    action->addArguments(WTFMove(arguments));
+
     return DOMTimer::install(*this, WTFMove(action), Seconds::fromMilliseconds(timeout), false);
 }
 

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.h (219872 => 219873)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.h	2017-07-25 17:42:09 UTC (rev 219872)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.h	2017-07-25 18:02:57 UTC (rev 219873)
@@ -83,9 +83,9 @@
     virtual ExceptionOr<void> importScripts(const Vector<String>& urls);
     WorkerNavigator& navigator() const;
 
-    int setTimeout(std::unique_ptr<ScheduledAction>, int timeout);
+    ExceptionOr<int> setTimeout(JSC::ExecState&, std::unique_ptr<ScheduledAction>, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
     void clearTimeout(int timeoutId);
-    int setInterval(std::unique_ptr<ScheduledAction>, int timeout);
+    ExceptionOr<int> setInterval(JSC::ExecState&, std::unique_ptr<ScheduledAction>, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
     void clearInterval(int timeoutId);
 
     bool isContextThread() const final;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to