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 48 namespace 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