summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/ScriptExecutionContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/ScriptExecutionContext.h')
-rw-r--r--Source/WebCore/dom/ScriptExecutionContext.h216
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