Add checked casts for ScriptExecutionContext.
[WebKit-https.git] / Source / WebCore / dom / ScriptExecutionContext.h
1 /*
2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3  * Copyright (C) 2012 Google Inc. All Rights Reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27
28 #ifndef ScriptExecutionContext_h
29 #define ScriptExecutionContext_h
30
31 #include "ActiveDOMObject.h"
32 #include "SecurityContext.h"
33 #include "Supplementable.h"
34 #include "URL.h"
35 #include <inspector/ConsoleTypes.h>
36 #include <wtf/HashSet.h>
37
38 namespace JSC {
39 class ExecState;
40 class VM;
41 }
42
43 namespace Inspector {
44 class ScriptCallStack;
45 }
46
47 namespace WebCore {
48
49 class CachedScript;
50 class DatabaseContext;
51 class DOMTimer;
52 class EventListener;
53 class EventQueue;
54 class EventTarget;
55 class MessagePort;
56
57 #if ENABLE(BLOB)
58 class PublicURLManager;
59 #endif
60
61 class ScriptExecutionContext : public SecurityContext, public Supplementable<ScriptExecutionContext> {
62 public:
63     ScriptExecutionContext();
64     virtual ~ScriptExecutionContext();
65
66     virtual bool isDocument() const { return false; }
67     virtual bool isWorkerGlobalScope() const { return false; }
68
69     virtual bool isContextThread() const { return true; }
70     virtual bool isJSExecutionForbidden() const = 0;
71
72     virtual const URL& url() const = 0;
73     virtual URL completeURL(const String& url) const = 0;
74
75     virtual String userAgent(const URL&) const = 0;
76
77     virtual void disableEval(const String& errorMessage) = 0;
78
79     bool sanitizeScriptError(String& errorMessage, int& lineNumber, int& columnNumber, String& sourceURL, CachedScript* = 0);
80     // FIXME: <http://webkit.org/b/114315> ScriptExecutionContext log exception should include a column number
81     void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, PassRefPtr<Inspector::ScriptCallStack>, CachedScript* = 0);
82
83     void addConsoleMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = 0, unsigned long requestIdentifier = 0);
84     virtual void addConsoleMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0) = 0;
85
86     virtual SecurityOrigin* topOrigin() const = 0;
87
88 #if ENABLE(BLOB)
89     PublicURLManager& publicURLManager();
90 #endif
91
92     // Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked.
93     bool canSuspendActiveDOMObjects();
94     // Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' -
95     // step-by-step JS debugging is one example.
96     virtual void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
97     virtual void resumeActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
98     virtual void stopActiveDOMObjects();
99
100     bool activeDOMObjectsAreSuspended() const { return m_activeDOMObjectsAreSuspended; }
101     bool activeDOMObjectsAreStopped() const { return m_activeDOMObjectsAreStopped; }
102
103     // Called from the constructor and destructors of ActiveDOMObject.
104     void didCreateActiveDOMObject(ActiveDOMObject*);
105     void willDestroyActiveDOMObject(ActiveDOMObject*);
106
107     // Called after the construction of an ActiveDOMObject to synchronize suspend state.
108     void suspendActiveDOMObjectIfNeeded(ActiveDOMObject*);
109
110     typedef HashSet<ActiveDOMObject*> ActiveDOMObjectsSet;
111     const ActiveDOMObjectsSet& activeDOMObjects() const { return m_activeDOMObjects; }
112
113     void didCreateDestructionObserver(ContextDestructionObserver*);
114     void willDestroyDestructionObserver(ContextDestructionObserver*);
115
116     // MessagePort is conceptually a kind of ActiveDOMObject, but it needs to be tracked separately for message dispatch.
117     void processMessagePortMessagesSoon();
118     void dispatchMessagePortEvents();
119     void createdMessagePort(MessagePort*);
120     void destroyedMessagePort(MessagePort*);
121     const HashSet<MessagePort*>& messagePorts() const { return m_messagePorts; }
122
123     void ref() { refScriptExecutionContext(); }
124     void deref() { derefScriptExecutionContext(); }
125
126     class Task {
127         WTF_MAKE_NONCOPYABLE(Task);
128         WTF_MAKE_FAST_ALLOCATED;
129     public:
130         Task() { }
131         virtual ~Task();
132         virtual void performTask(ScriptExecutionContext*) = 0;
133         // Certain tasks get marked specially so that they aren't discarded, and are executed, when the context is shutting down its message queue.
134         virtual bool isCleanupTask() const { return false; }
135     };
136
137     virtual void postTask(PassOwnPtr<Task>) = 0; // Executes the task on context's thread asynchronously.
138
139     // Gets the next id in a circular sequence from 1 to 2^31-1.
140     int circularSequentialID();
141
142     bool addTimeout(int timeoutId, DOMTimer* timer) { return m_timeouts.add(timeoutId, timer).isNewEntry; }
143     void removeTimeout(int timeoutId) { m_timeouts.remove(timeoutId); }
144     DOMTimer* findTimeout(int timeoutId) { return m_timeouts.get(timeoutId); }
145
146     JSC::VM* vm();
147
148     // Interval is in seconds.
149     void adjustMinimumTimerInterval(double oldMinimumTimerInterval);
150     virtual double minimumTimerInterval() const;
151
152     void didChangeTimerAlignmentInterval();
153     virtual double timerAlignmentInterval() const;
154
155     virtual EventQueue& eventQueue() const = 0;
156
157 #if ENABLE(SQL_DATABASE)
158     void setDatabaseContext(DatabaseContext*);
159 #endif
160
161 #if ENABLE(SUBTLE_CRYPTO)
162     virtual bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) = 0;
163     virtual bool unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) = 0;
164 #endif
165
166 protected:
167     class AddConsoleMessageTask : public Task {
168     public:
169         static PassOwnPtr<AddConsoleMessageTask> create(MessageSource source, MessageLevel level, const String& message)
170         {
171             return adoptPtr(new AddConsoleMessageTask(source, level, message));
172         }
173         virtual void performTask(ScriptExecutionContext*) override;
174     private:
175         AddConsoleMessageTask(MessageSource source, MessageLevel level, const String& message)
176             : m_source(source)
177             , m_level(level)
178             , m_message(message.isolatedCopy())
179         {
180         }
181         MessageSource m_source;
182         MessageLevel m_level;
183         String m_message;
184     };
185
186     ActiveDOMObject::ReasonForSuspension reasonForSuspendingActiveDOMObjects() const { return m_reasonForSuspendingActiveDOMObjects; }
187
188 private:
189     virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, PassRefPtr<Inspector::ScriptCallStack>, JSC::ExecState* = 0, unsigned long requestIdentifier = 0) = 0;
190     virtual EventTarget* errorEventTarget() = 0;
191     virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<Inspector::ScriptCallStack>) = 0;
192     bool dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, CachedScript*);
193
194     void closeMessagePorts();
195
196     virtual void refScriptExecutionContext() = 0;
197     virtual void derefScriptExecutionContext() = 0;
198
199     HashSet<MessagePort*> m_messagePorts;
200     HashSet<ContextDestructionObserver*> m_destructionObservers;
201     ActiveDOMObjectsSet m_activeDOMObjects;
202     bool m_iteratingActiveDOMObjects;
203     bool m_inDestructor;
204
205     int m_circularSequentialID;
206     typedef HashMap<int, DOMTimer*> TimeoutMap;
207     TimeoutMap m_timeouts;
208
209     bool m_inDispatchErrorEvent;
210     class PendingException;
211     OwnPtr<Vector<OwnPtr<PendingException>>> m_pendingExceptions;
212
213     bool m_activeDOMObjectsAreSuspended;
214     ActiveDOMObject::ReasonForSuspension m_reasonForSuspendingActiveDOMObjects;
215     bool m_activeDOMObjectsAreStopped;
216
217 #if ENABLE(BLOB)
218     OwnPtr<PublicURLManager> m_publicURLManager;
219 #endif
220
221 #if ENABLE(SQL_DATABASE)
222     RefPtr<DatabaseContext> m_databaseContext;
223 #endif
224 };
225
226 #define SCRIPT_EXECUTION_CONTEXT_TYPE_CASTS(ToValueTypeName) \
227     TYPE_CASTS_BASE(ToValueTypeName, ScriptExecutionContext, context, context->is##ToValueTypeName(), context.is##ToValueTypeName())
228
229 } // namespace WebCore
230
231 #endif // ScriptExecutionContext_h