1/*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
27#ifndef ScriptExecutionContext_h
28#define ScriptExecutionContext_h
29
30#include "ActiveDOMObject.h"
31#include "Console.h"
32#include "KURL.h"
33#include <wtf/Forward.h>
34#include <wtf/HashMap.h>
35#include <wtf/HashSet.h>
36#include <wtf/Noncopyable.h>
37#include <wtf/OwnPtr.h>
38#include <wtf/PassOwnPtr.h>
39#include <wtf/PassRefPtr.h>
40#include <wtf/RefPtr.h>
41#include <wtf/Threading.h>
42#include <wtf/text/StringHash.h>
43
44#if USE(JSC)
45#include <runtime/JSGlobalData.h>
46#endif
47
48namespace WebCore {
49
50    class Blob;
51#if ENABLE(DATABASE)
52    class Database;
53    class DatabaseTaskSynchronizer;
54    class DatabaseThread;
55#endif
56    class DOMTimer;
57    class EventListener;
58    class EventTarget;
59#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
60    class FileThread;
61#endif
62    class MessagePort;
63    class DOMURL;
64    class SecurityOrigin;
65    class ScriptCallStack;
66
67    class ScriptExecutionContext {
68    public:
69        ScriptExecutionContext();
70        virtual ~ScriptExecutionContext();
71
72        virtual bool isDocument() const { return false; }
73        virtual bool isWorkerContext() const { return false; }
74
75#if ENABLE(DATABASE)
76        virtual bool allowDatabaseAccess() const = 0;
77        virtual void databaseExceededQuota(const String& name) = 0;
78        DatabaseThread* databaseThread();
79        void setHasOpenDatabases() { m_hasOpenDatabases = true; }
80        bool hasOpenDatabases() const { return m_hasOpenDatabases; }
81        // When the database cleanup is done, cleanupSync will be signalled.
82        void stopDatabases(DatabaseTaskSynchronizer*);
83#endif
84        virtual bool isContextThread() const = 0;
85        virtual bool isJSExecutionForbidden() const = 0;
86
87        const KURL& url() const { return virtualURL(); }
88        KURL completeURL(const String& url) const { return virtualCompleteURL(url); }
89
90        virtual String userAgent(const KURL&) const = 0;
91
92        SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); }
93
94        bool sanitizeScriptError(String& errorMessage, int& lineNumber, String& sourceURL);
95        void reportException(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>);
96        virtual void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>) = 0;
97
98        // Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked.
99        bool canSuspendActiveDOMObjects();
100        // Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' -
101        // step-by-step JS debugging is one example.
102        void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
103        void resumeActiveDOMObjects();
104        void stopActiveDOMObjects();
105        void createdActiveDOMObject(ActiveDOMObject*, void* upcastPointer);
106        void destroyedActiveDOMObject(ActiveDOMObject*);
107        typedef const HashMap<ActiveDOMObject*, void*> ActiveDOMObjectsMap;
108        ActiveDOMObjectsMap& activeDOMObjects() const { return m_activeDOMObjects; }
109
110        virtual void suspendScriptedAnimationControllerCallbacks() { }
111        virtual void resumeScriptedAnimationControllerCallbacks() { }
112
113        // MessagePort is conceptually a kind of ActiveDOMObject, but it needs to be tracked separately for message dispatch.
114        void processMessagePortMessagesSoon();
115        void dispatchMessagePortEvents();
116        void createdMessagePort(MessagePort*);
117        void destroyedMessagePort(MessagePort*);
118        const HashSet<MessagePort*>& messagePorts() const { return m_messagePorts; }
119
120#if ENABLE(BLOB)
121        void createdDomUrl(DOMURL*);
122        void destroyedDomUrl(DOMURL*);
123        const HashSet<DOMURL*>& domUrls() const { return m_domUrls; }
124#endif
125        void ref() { refScriptExecutionContext(); }
126        void deref() { derefScriptExecutionContext(); }
127
128        class Task {
129            WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED;
130        public:
131            Task() { }
132            virtual ~Task();
133            virtual void performTask(ScriptExecutionContext*) = 0;
134            // Certain tasks get marked specially so that they aren't discarded, and are executed, when the context is shutting down its message queue.
135            virtual bool isCleanupTask() const { return false; }
136        };
137
138        virtual void postTask(PassOwnPtr<Task>) = 0; // Executes the task on context's thread asynchronously.
139
140        void addTimeout(int timeoutId, DOMTimer*);
141        void removeTimeout(int timeoutId);
142        DOMTimer* findTimeout(int timeoutId);
143
144#if ENABLE(BLOB)
145        KURL createPublicBlobURL(Blob*);
146        void revokePublicBlobURL(const KURL&);
147#endif
148
149#if USE(JSC)
150        JSC::JSGlobalData* globalData();
151#endif
152
153#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
154        FileThread* fileThread();
155        void stopFileThread();
156#endif
157
158        // Interval is in seconds.
159        void adjustMinimumTimerInterval(double oldMinimumTimerInterval);
160        virtual double minimumTimerInterval() const;
161
162    protected:
163        // Explicitly override the security origin for this script context.
164        // Note: It is dangerous to change the security origin of a script context
165        //       that already contains content.
166        void setSecurityOrigin(PassRefPtr<SecurityOrigin>);
167
168    private:
169        virtual const KURL& virtualURL() const = 0;
170        virtual KURL virtualCompleteURL(const String&) const = 0;
171
172        virtual EventTarget* errorEventTarget() = 0;
173        virtual void logExceptionToConsole(const String& errorMessage, int lineNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>) = 0;
174        bool dispatchErrorEvent(const String& errorMessage, int lineNumber, const String& sourceURL);
175
176        void closeMessagePorts();
177
178        RefPtr<SecurityOrigin> m_securityOrigin;
179
180        HashSet<MessagePort*> m_messagePorts;
181
182        HashMap<ActiveDOMObject*, void*> m_activeDOMObjects;
183        bool m_iteratingActiveDOMObjects;
184        bool m_inDestructor;
185
186        typedef HashMap<int, DOMTimer*> TimeoutMap;
187        TimeoutMap m_timeouts;
188
189#if ENABLE(BLOB)
190        HashSet<String> m_publicBlobURLs;
191        HashSet<DOMURL*> m_domUrls;
192#endif
193
194        virtual void refScriptExecutionContext() = 0;
195        virtual void derefScriptExecutionContext() = 0;
196
197        bool m_inDispatchErrorEvent;
198        class PendingException;
199        OwnPtr<Vector<OwnPtr<PendingException> > > m_pendingExceptions;
200
201#if ENABLE(DATABASE)
202        RefPtr<DatabaseThread> m_databaseThread;
203        bool m_hasOpenDatabases; // This never changes back to false, even after the database thread is closed.
204#endif
205
206#if ENABLE(BLOB) || ENABLE(FILE_SYSTEM)
207        RefPtr<FileThread> m_fileThread;
208#endif
209    };
210
211} // namespace WebCore
212
213
214#endif // ScriptExecutionContext_h
215