diff options
Diffstat (limited to 'Source/WebCore/dom/ScriptExecutionContext.h')
-rw-r--r-- | Source/WebCore/dom/ScriptExecutionContext.h | 216 |
1 files changed, 134 insertions, 82 deletions
diff --git a/Source/WebCore/dom/ScriptExecutionContext.h b/Source/WebCore/dom/ScriptExecutionContext.h index 1c7f0dae1..ddf3471ef 100644 --- a/Source/WebCore/dom/ScriptExecutionContext.h +++ b/Source/WebCore/dom/ScriptExecutionContext.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Apple Inc. All Rights Reserved. * Copyright (C) 2012 Google Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,10 +11,10 @@ * 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 COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * 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 @@ -25,37 +25,47 @@ * */ -#ifndef ScriptExecutionContext_h -#define ScriptExecutionContext_h +#pragma once #include "ActiveDOMObject.h" -#include "ConsoleTypes.h" -#include "URL.h" +#include "DOMTimer.h" #include "SecurityContext.h" #include "Supplementable.h" +#include <heap/HandleTypes.h> +#include <runtime/ConsoleTypes.h> +#include <wtf/CrossThreadTask.h> +#include <wtf/Function.h> #include <wtf/HashSet.h> namespace JSC { +class Exception; class ExecState; class VM; +template<typename> class Strong; +} + +namespace Inspector { +class ScriptCallStack; } namespace WebCore { class CachedScript; class DatabaseContext; -class DOMTimer; -class EventListener; class EventQueue; class EventTarget; class MessagePort; -class ScriptCallStack; - -#if ENABLE(BLOB) class PublicURLManager; -#endif +class ResourceRequest; +class SecurityOrigin; +class SocketProvider; +class URL; -class ScriptExecutionContext : public SecurityContext, public Supplementable<ScriptExecutionContext> { +namespace IDBClient { +class IDBConnectionProxy; +} + +class ScriptExecutionContext : public SecurityContext { public: ScriptExecutionContext(); virtual ~ScriptExecutionContext(); @@ -73,21 +83,31 @@ public: virtual void disableEval(const String& errorMessage) = 0; - bool sanitizeScriptError(String& errorMessage, int& lineNumber, int& columnNumber, String& sourceURL, CachedScript* = 0); - // FIXME: <http://webkit.org/b/114315> ScriptExecutionContext log exception should include a column number - void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>, CachedScript* = 0); +#if ENABLE(INDEXED_DATABASE) + virtual IDBClient::IDBConnectionProxy* idbConnectionProxy() = 0; +#endif +#if ENABLE(WEB_SOCKETS) + virtual SocketProvider* socketProvider() = 0; +#endif + + virtual String resourceRequestIdentifier() const { return String(); }; - void addConsoleMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = 0, unsigned long requestIdentifier = 0); + bool sanitizeScriptError(String& errorMessage, int& lineNumber, int& columnNumber, String& sourceURL, JSC::Strong<JSC::Unknown>& error, CachedScript* = nullptr); + void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception*, RefPtr<Inspector::ScriptCallStack>&&, CachedScript* = nullptr); + + void addConsoleMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0); virtual void addConsoleMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0) = 0; - virtual SecurityOrigin* topOrigin() const = 0; + virtual SecurityOrigin& topOrigin() const = 0; + + virtual bool shouldBypassMainWorldContentSecurityPolicy() const { return false; } -#if ENABLE(BLOB) PublicURLManager& publicURLManager(); -#endif + // Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked. - bool canSuspendActiveDOMObjects(); - // Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' - + WEBCORE_EXPORT bool canSuspendActiveDOMObjectsForDocumentSuspension(Vector<ActiveDOMObject*>* unsuspendableObjects = nullptr); + + // Active objects can be asked to suspend even if canSuspendActiveDOMObjectsForDocumentSuspension() returns 'false' - // step-by-step JS debugging is one example. virtual void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension); virtual void resumeActiveDOMObjects(ActiveDOMObject::ReasonForSuspension); @@ -97,123 +117,155 @@ public: bool activeDOMObjectsAreStopped() const { return m_activeDOMObjectsAreStopped; } // Called from the constructor and destructors of ActiveDOMObject. - void didCreateActiveDOMObject(ActiveDOMObject*); - void willDestroyActiveDOMObject(ActiveDOMObject*); + void didCreateActiveDOMObject(ActiveDOMObject&); + void willDestroyActiveDOMObject(ActiveDOMObject&); // Called after the construction of an ActiveDOMObject to synchronize suspend state. - void suspendActiveDOMObjectIfNeeded(ActiveDOMObject*); - - typedef HashSet<ActiveDOMObject*> ActiveDOMObjectsSet; - const ActiveDOMObjectsSet& activeDOMObjects() const { return m_activeDOMObjects; } + void suspendActiveDOMObjectIfNeeded(ActiveDOMObject&); - void didCreateDestructionObserver(ContextDestructionObserver*); - void willDestroyDestructionObserver(ContextDestructionObserver*); + void didCreateDestructionObserver(ContextDestructionObserver&); + void willDestroyDestructionObserver(ContextDestructionObserver&); // MessagePort is conceptually a kind of ActiveDOMObject, but it needs to be tracked separately for message dispatch. void processMessagePortMessagesSoon(); void dispatchMessagePortEvents(); - void createdMessagePort(MessagePort*); - void destroyedMessagePort(MessagePort*); - const HashSet<MessagePort*>& messagePorts() const { return m_messagePorts; } + void createdMessagePort(MessagePort&); + void destroyedMessagePort(MessagePort&); + + virtual void didLoadResourceSynchronously(); void ref() { refScriptExecutionContext(); } void deref() { derefScriptExecutionContext(); } class Task { - WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED; public: - Task() { } - virtual ~Task(); - virtual void performTask(ScriptExecutionContext*) = 0; - // Certain tasks get marked specially so that they aren't discarded, and are executed, when the context is shutting down its message queue. - virtual bool isCleanupTask() const { return false; } + enum CleanupTaskTag { CleanupTask }; + + template<typename T, typename = typename std::enable_if<!std::is_base_of<Task, T>::value && std::is_convertible<T, WTF::Function<void (ScriptExecutionContext&)>>::value>::type> + Task(T task) + : m_task(WTFMove(task)) + , m_isCleanupTask(false) + { + } + + Task(WTF::Function<void ()>&& task) + : m_task([task = WTFMove(task)](ScriptExecutionContext&) { task(); }) + , m_isCleanupTask(false) + { + } + + template<typename T, typename = typename std::enable_if<std::is_convertible<T, WTF::Function<void (ScriptExecutionContext&)>>::value>::type> + Task(CleanupTaskTag, T task) + : m_task(WTFMove(task)) + , m_isCleanupTask(true) + { + } + + void performTask(ScriptExecutionContext& context) { m_task(context); } + bool isCleanupTask() const { return m_isCleanupTask; } + + protected: + WTF::Function<void (ScriptExecutionContext&)> m_task; + bool m_isCleanupTask; }; - virtual void postTask(PassOwnPtr<Task>) = 0; // Executes the task on context's thread asynchronously. + virtual void postTask(Task&&) = 0; // Executes the task on context's thread asynchronously. + + template<typename... Arguments> + void postCrossThreadTask(Arguments&&... arguments) + { + postTask([crossThreadTask = createCrossThreadTask(arguments...)](ScriptExecutionContext&) mutable { + crossThreadTask.performTask(); + }); + } // Gets the next id in a circular sequence from 1 to 2^31-1. int circularSequentialID(); - bool addTimeout(int timeoutId, DOMTimer* timer) { return m_timeouts.add(timeoutId, timer).isNewEntry; } + bool addTimeout(int timeoutId, DOMTimer& timer) { return m_timeouts.add(timeoutId, &timer).isNewEntry; } void removeTimeout(int timeoutId) { m_timeouts.remove(timeoutId); } DOMTimer* findTimeout(int timeoutId) { return m_timeouts.get(timeoutId); } - JSC::VM* vm(); + WEBCORE_EXPORT JSC::VM& vm(); // Interval is in seconds. - void adjustMinimumTimerInterval(double oldMinimumTimerInterval); - virtual double minimumTimerInterval() const; + void adjustMinimumTimerInterval(std::chrono::milliseconds oldMinimumTimerInterval); + virtual std::chrono::milliseconds minimumTimerInterval() const; void didChangeTimerAlignmentInterval(); - virtual double timerAlignmentInterval() const; + virtual std::chrono::milliseconds timerAlignmentInterval(bool hasReachedMaxNestingLevel) const; virtual EventQueue& eventQueue() const = 0; -#if ENABLE(SQL_DATABASE) + DatabaseContext* databaseContext() { return m_databaseContext.get(); } void setDatabaseContext(DatabaseContext*); + +#if ENABLE(SUBTLE_CRYPTO) + virtual bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) = 0; + virtual bool unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) = 0; #endif + int timerNestingLevel() const { return m_timerNestingLevel; } + void setTimerNestingLevel(int timerNestingLevel) { m_timerNestingLevel = timerNestingLevel; } + + JSC::ExecState* execState(); + protected: class AddConsoleMessageTask : public Task { public: - static PassOwnPtr<AddConsoleMessageTask> create(MessageSource source, MessageLevel level, const String& message) - { - return adoptPtr(new AddConsoleMessageTask(source, level, message)); - } - virtual void performTask(ScriptExecutionContext*) override; - private: AddConsoleMessageTask(MessageSource source, MessageLevel level, const String& message) - : m_source(source) - , m_level(level) - , m_message(message.isolatedCopy()) + : Task([source, level, message = message.isolatedCopy()](ScriptExecutionContext& context) { + context.addConsoleMessage(source, level, message); + }) { } - MessageSource m_source; - MessageLevel m_level; - String m_message; }; ActiveDOMObject::ReasonForSuspension reasonForSuspendingActiveDOMObjects() const { return m_reasonForSuspendingActiveDOMObjects; } + bool hasPendingActivity() const; + private: - virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, PassRefPtr<ScriptCallStack>, JSC::ExecState* = 0, unsigned long requestIdentifier = 0) = 0; + virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, RefPtr<Inspector::ScriptCallStack>&&, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0) = 0; virtual EventTarget* errorEventTarget() = 0; - virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) = 0; - bool dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, CachedScript*); - - void closeMessagePorts(); + virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, RefPtr<Inspector::ScriptCallStack>&&) = 0; + bool dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception*, CachedScript*); virtual void refScriptExecutionContext() = 0; virtual void derefScriptExecutionContext() = 0; + void checkConsistency() const; + HashSet<MessagePort*> m_messagePorts; HashSet<ContextDestructionObserver*> m_destructionObservers; - ActiveDOMObjectsSet m_activeDOMObjects; - bool m_iteratingActiveDOMObjects; - bool m_inDestructor; + HashSet<ActiveDOMObject*> m_activeDOMObjects; - int m_circularSequentialID; - typedef HashMap<int, DOMTimer*> TimeoutMap; - TimeoutMap m_timeouts; + int m_circularSequentialID { 0 }; + HashMap<int, RefPtr<DOMTimer>> m_timeouts; - bool m_inDispatchErrorEvent; - class PendingException; - OwnPtr<Vector<OwnPtr<PendingException>>> m_pendingExceptions; + bool m_inDispatchErrorEvent { false }; + struct PendingException; + std::unique_ptr<Vector<std::unique_ptr<PendingException>>> m_pendingExceptions; - bool m_activeDOMObjectsAreSuspended; - ActiveDOMObject::ReasonForSuspension m_reasonForSuspendingActiveDOMObjects; - bool m_activeDOMObjectsAreStopped; + bool m_activeDOMObjectsAreSuspended { false }; + ActiveDOMObject::ReasonForSuspension m_reasonForSuspendingActiveDOMObjects { static_cast<ActiveDOMObject::ReasonForSuspension>(-1) }; + bool m_activeDOMObjectsAreStopped { false }; -#if ENABLE(BLOB) - OwnPtr<PublicURLManager> m_publicURLManager; -#endif + std::unique_ptr<PublicURLManager> m_publicURLManager; -#if ENABLE(SQL_DATABASE) RefPtr<DatabaseContext> m_databaseContext; + + bool m_activeDOMObjectAdditionForbidden { false }; + bool m_willProcessMessagePortMessagesSoon { false }; + int m_timerNestingLevel { 0 }; + +#if !ASSERT_DISABLED + bool m_inScriptExecutionContextDestructor { false }; +#endif +#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS) + bool m_activeDOMObjectRemovalForbidden { false }; #endif }; } // namespace WebCore - -#endif // ScriptExecutionContext_h |