TimeoutHandler.h (3849B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_timeout_handler_h 8 #define mozilla_dom_timeout_handler_h 9 10 #include "js/Promise.h" // JS::Dispatchable 11 #include "mozilla/Attributes.h" 12 #include "mozilla/HoldDropJSObjects.h" 13 #include "mozilla/SourceLocation.h" 14 #include "mozilla/dom/FunctionBinding.h" 15 #include "nsCOMPtr.h" 16 #include "nsCycleCollectionParticipant.h" 17 #include "nsIGlobalObject.h" 18 #include "nsISupports.h" 19 #include "nsString.h" 20 21 namespace mozilla::dom { 22 23 /** 24 * Utility class for implementing nsITimeoutHandlers, designed to be subclassed. 25 */ 26 class TimeoutHandler : public nsISupports, public JSHolderBase { 27 public: 28 MOZ_CAN_RUN_SCRIPT virtual bool Call(const char* /* unused */); 29 // Append a UTF-8 string to aOutString that describes the callback function, 30 // for use in logging or profiler markers. 31 // The string contains the function name and its source location, if 32 // available, in the following format: 33 // "<functionName> (<sourceURL>:<lineNumber>:<columnNumber>)" 34 virtual void GetDescription(nsACString& aOutString); 35 virtual void MarkForCC() {} 36 37 protected: 38 TimeoutHandler() = default; 39 explicit TimeoutHandler(JSContext* aCx) 40 : mCaller(JSCallingLocation::Get(aCx)) {} 41 42 virtual ~TimeoutHandler() = default; 43 44 // filename, line number and JS language version string of the 45 // caller of setTimeout() 46 const JSCallingLocation mCaller = {}; 47 48 private: 49 TimeoutHandler(const TimeoutHandler&) = delete; 50 TimeoutHandler& operator=(const TimeoutHandler&) = delete; 51 TimeoutHandler& operator=(const TimeoutHandler&&) = delete; 52 }; 53 54 class ScriptTimeoutHandler : public TimeoutHandler { 55 public: 56 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 57 NS_DECL_CYCLE_COLLECTION_CLASS(ScriptTimeoutHandler) 58 59 ScriptTimeoutHandler(JSContext* aCx, nsIGlobalObject* aGlobal, 60 const nsAString& aExpression); 61 62 MOZ_CAN_RUN_SCRIPT virtual bool Call(const char* /* unused */) override { 63 return false; 64 }; 65 virtual void GetDescription(nsACString& aOutString) override; 66 67 protected: 68 virtual ~ScriptTimeoutHandler() = default; 69 70 nsCOMPtr<nsIGlobalObject> mGlobal; 71 // The expression to evaluate or function to call. If mFunction is non-null 72 // it should be used, else use mExpr. 73 nsString mExpr; 74 }; 75 76 class CallbackTimeoutHandler final : public TimeoutHandler { 77 public: 78 NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINAL 79 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CallbackTimeoutHandler) 80 81 CallbackTimeoutHandler(JSContext* aCx, nsIGlobalObject* aGlobal, 82 Function* aFunction, 83 nsTArray<JS::Heap<JS::Value>>&& aArguments); 84 85 MOZ_CAN_RUN_SCRIPT virtual bool Call(const char* aExecutionReason) override; 86 virtual void MarkForCC() override; 87 virtual void GetDescription(nsACString& aOutString) override; 88 89 void ReleaseJSObjects(); 90 91 private: 92 virtual ~CallbackTimeoutHandler() { ReleaseJSObjects(); } 93 94 nsCOMPtr<nsIGlobalObject> mGlobal; 95 RefPtr<Function> mFunction; 96 nsTArray<JS::Heap<JS::Value>> mArgs; 97 }; 98 99 class DelayedJSDispatchableHandler final : public TimeoutHandler { 100 public: 101 DelayedJSDispatchableHandler(JSContext* aCx, 102 js::UniquePtr<JS::Dispatchable>&& aDispatchable) 103 : TimeoutHandler(aCx), mDispatchable(std::move(aDispatchable)) {} 104 105 NS_DECL_ISUPPORTS 106 107 MOZ_CAN_RUN_SCRIPT bool Call(const char* /* unused */) override; 108 109 private: 110 ~DelayedJSDispatchableHandler() override; 111 js::UniquePtr<JS::Dispatchable> mDispatchable; 112 }; 113 114 } // namespace mozilla::dom 115 116 #endif // mozilla_dom_timeout_handler_h