diff options
author | 2022-04-09 19:53:17 -0700 | |
---|---|---|
committer | 2022-04-09 19:53:17 -0700 | |
commit | c5d637fbb15874caa0d9669ac8cc79912ed4d5d9 (patch) | |
tree | f20a9b0047ba763b0003a60032d6c4ae1f9dcb47 /src/javascript/jsc/bindings/webcore/ActiveDOMObject.cpp | |
parent | fb82e2bf86a13211f08b407c3ec80fc0db45a77c (diff) | |
download | bun-jarred/workers.tar.gz bun-jarred/workers.tar.zst bun-jarred/workers.zip |
Diffstat (limited to 'src/javascript/jsc/bindings/webcore/ActiveDOMObject.cpp')
-rw-r--r-- | src/javascript/jsc/bindings/webcore/ActiveDOMObject.cpp | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/src/javascript/jsc/bindings/webcore/ActiveDOMObject.cpp b/src/javascript/jsc/bindings/webcore/ActiveDOMObject.cpp new file mode 100644 index 000000000..059b8039c --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/ActiveDOMObject.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 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 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 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.h" +#include "ActiveDOMObject.h" + +// #include "Document.h" +#include "Event.h" +#include "EventTarget.h" +#include "EventLoop.h" +#include "ScriptExecutionContext.h" + +namespace WebCore { + +static inline ScriptExecutionContext* suitableScriptExecutionContext(ScriptExecutionContext* scriptExecutionContext) +{ + // For detached documents, make sure we observe their context document instead. + // return is<Document>(scriptExecutionContext) ? &downcast<Document>(*scriptExecutionContext).contextDocument() : scriptExecutionContext; + return scriptExecutionContext; +} + +inline ActiveDOMObject::ActiveDOMObject(ScriptExecutionContext* context, CheckedScriptExecutionContextType) + : ContextDestructionObserver(context) +{ + // ASSERT(!is<Document>(context) || &downcast<Document>(context)->contextDocument() == downcast<Document>(context)); + if (!context) + return; + + ASSERT(context->isContextThread()); + context->didCreateActiveDOMObject(*this); +} + +ActiveDOMObject::ActiveDOMObject(ScriptExecutionContext* scriptExecutionContext) + : ActiveDOMObject(suitableScriptExecutionContext(scriptExecutionContext), CheckedScriptExecutionContext) +{ +} + +// ActiveDOMObject::ActiveDOMObject(Document* document) +// : ActiveDOMObject(document ? &document->contextDocument() : nullptr, CheckedScriptExecutionContext) +// { +// } + +// ActiveDOMObject::ActiveDOMObject(Document& document) +// : ActiveDOMObject(&document.contextDocument(), CheckedScriptExecutionContext) +// { +// } + +ActiveDOMObject::~ActiveDOMObject() +{ + ASSERT(canCurrentThreadAccessThreadLocalData(m_creationThread)); + + // ActiveDOMObject may be inherited by a sub-class whose life-cycle + // exceeds that of the associated ScriptExecutionContext. In those cases, + // m_scriptExecutionContext would/should have been nullified by + // ContextDestructionObserver::contextDestroyed() (which we implement / + // inherit). Hence, we should ensure that this is not 0 before use it + // here. + auto* context = scriptExecutionContext(); + if (!context) + return; + + ASSERT(m_suspendIfNeededWasCalled); + ASSERT(context->isContextThread()); + context->willDestroyActiveDOMObject(*this); +} + +void ActiveDOMObject::suspendIfNeeded() +{ +#if ASSERT_ENABLED + ASSERT(!m_suspendIfNeededWasCalled); + m_suspendIfNeededWasCalled = true; +#endif + if (auto* context = scriptExecutionContext()) + context->suspendActiveDOMObjectIfNeeded(*this); +} + +#if ASSERT_ENABLED + +void ActiveDOMObject::assertSuspendIfNeededWasCalled() const +{ + if (!m_suspendIfNeededWasCalled) + WTFLogAlways("Failed to call suspendIfNeeded() for %s", activeDOMObjectName()); + ASSERT(m_suspendIfNeededWasCalled); +} + +#endif // ASSERT_ENABLED + +void ActiveDOMObject::suspend(ReasonForSuspension) +{ +} + +void ActiveDOMObject::resume() +{ +} + +void ActiveDOMObject::stop() +{ +} + +bool ActiveDOMObject::isContextStopped() const +{ + return !scriptExecutionContext() || scriptExecutionContext()->activeDOMObjectsAreStopped(); +} + +bool ActiveDOMObject::isAllowedToRunScript() const +{ + return scriptExecutionContext() && !scriptExecutionContext()->activeDOMObjectsAreStopped() && !scriptExecutionContext()->activeDOMObjectsAreSuspended(); +} + +void ActiveDOMObject::queueTaskInEventLoop(TaskSource source, Function<void()>&& function) +{ + auto* context = scriptExecutionContext(); + if (!context) + return; + context->eventLoop().queueTask(source, WTFMove(function)); +} + +class ActiveDOMObjectEventDispatchTask : public EventLoopTask { +public: + ActiveDOMObjectEventDispatchTask(TaskSource source, EventLoopTaskGroup& group, ActiveDOMObject& object, Function<void()>&& dispatchEvent) + : EventLoopTask(source, group) + , m_object(object) + , m_dispatchEvent(WTFMove(dispatchEvent)) + { + ++m_object.m_pendingActivityInstanceCount; + } + + ~ActiveDOMObjectEventDispatchTask() + { + ASSERT(m_object.m_pendingActivityInstanceCount); + --m_object.m_pendingActivityInstanceCount; + } + + void execute() final + { + // If this task executes after the script execution context has been stopped, don't + // actually dispatch the event. + if (m_object.isAllowedToRunScript()) + m_dispatchEvent(); + } + +private: + ActiveDOMObject& m_object; + Function<void()> m_dispatchEvent; +}; + +void ActiveDOMObject::queueTaskToDispatchEventInternal(EventTarget& target, TaskSource source, Ref<Event>&& event) +{ + ASSERT(!event->target() || &target == event->target()); + auto* context = scriptExecutionContext(); + if (!context) + return; + auto& eventLoopTaskGroup = context->eventLoop(); + auto task = makeUnique<ActiveDOMObjectEventDispatchTask>(source, eventLoopTaskGroup, *this, [target = Ref { target }, event = WTFMove(event)] { + target->dispatchEvent(event); + }); + eventLoopTaskGroup.queueTask(WTFMove(task)); +} + +void ActiveDOMObject::queueCancellableTaskToDispatchEventInternal(EventTarget& target, TaskSource source, TaskCancellationGroup& cancellationGroup, Ref<Event>&& event) +{ + ASSERT(!event->target() || &target == event->target()); + auto* context = scriptExecutionContext(); + if (!context) + return; + auto& eventLoopTaskGroup = context->eventLoop(); + auto task = makeUnique<ActiveDOMObjectEventDispatchTask>(source, eventLoopTaskGroup, *this, CancellableTask(cancellationGroup, [target = Ref { target }, event = WTFMove(event)] { + target->dispatchEvent(event); + })); + eventLoopTaskGroup.queueTask(WTFMove(task)); +} + +} // namespace WebCore |