mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Upgrade AbortSignal & AbortController to latest from WebKit (#10106)
Fixes https://github.com/oven-sh/bun/issues/9977 Closes https://github.com/oven-sh/bun/pull/10086 Thank you @lithdew for investigating and most of the fixes. This adds more of the changes we missed from WebKit into Bun like the ability to follow other signals Co-authored-by: Kenta Iwasaki <63115601+lithdew@users.noreply.github.com>
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
|
||||
namespace WebCore {
|
||||
|
||||
class WebCoreOpaqueRoot {
|
||||
@@ -38,48 +40,28 @@ public:
|
||||
|
||||
WebCoreOpaqueRoot(std::nullptr_t) {}
|
||||
|
||||
bool isNode() const { return false; }
|
||||
void* pointer() const { return m_pointer; }
|
||||
|
||||
private:
|
||||
void* m_pointer { nullptr };
|
||||
bool m_isNode { false };
|
||||
};
|
||||
|
||||
template<typename Visitor>
|
||||
ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, WebCoreOpaqueRoot root)
|
||||
{
|
||||
visitor.addOpaqueRoot(root.pointer());
|
||||
}
|
||||
inline void addWebCoreOpaqueRoot(Visitor&, WebCoreOpaqueRoot);
|
||||
|
||||
template<typename Visitor, typename ImplType>
|
||||
ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, ImplType* impl)
|
||||
{
|
||||
addWebCoreOpaqueRoot(visitor, root(impl));
|
||||
}
|
||||
inline void addWebCoreOpaqueRoot(Visitor&, ImplType*);
|
||||
|
||||
template<typename Visitor, typename ImplType>
|
||||
ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, ImplType& impl)
|
||||
{
|
||||
addWebCoreOpaqueRoot(visitor, root(&impl));
|
||||
}
|
||||
inline void addWebCoreOpaqueRoot(Visitor&, ImplType&);
|
||||
|
||||
template<typename Visitor>
|
||||
ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, WebCoreOpaqueRoot root)
|
||||
{
|
||||
return visitor.containsOpaqueRoot(root.pointer());
|
||||
}
|
||||
inline bool containsWebCoreOpaqueRoot(Visitor&, WebCoreOpaqueRoot);
|
||||
|
||||
template<typename Visitor, typename ImplType>
|
||||
ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, ImplType& impl)
|
||||
{
|
||||
return containsWebCoreOpaqueRoot(visitor, root(&impl));
|
||||
}
|
||||
inline bool containsWebCoreOpaqueRoot(Visitor&, ImplType&);
|
||||
|
||||
template<typename Visitor, typename ImplType>
|
||||
ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, ImplType* impl)
|
||||
{
|
||||
return containsWebCoreOpaqueRoot(visitor, root(impl));
|
||||
}
|
||||
inline bool containsWebCoreOpaqueRoot(Visitor&, ImplType*);
|
||||
|
||||
} // namespace WebCore
|
||||
|
||||
68
src/bun.js/bindings/WebCoreOpaqueRootInlines.h
Normal file
68
src/bun.js/bindings/WebCoreOpaqueRootInlines.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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. AND ITS CONTRIBUTORS ``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 ITS 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "WebCoreOpaqueRoot.h"
|
||||
|
||||
namespace WebCore {
|
||||
|
||||
template<typename Visitor>
|
||||
ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, WebCoreOpaqueRoot root)
|
||||
{
|
||||
visitor.addOpaqueRoot(root.pointer());
|
||||
}
|
||||
|
||||
template<typename Visitor, typename ImplType>
|
||||
ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, ImplType* impl)
|
||||
{
|
||||
addWebCoreOpaqueRoot(visitor, root(impl));
|
||||
}
|
||||
|
||||
template<typename Visitor, typename ImplType>
|
||||
ALWAYS_INLINE void addWebCoreOpaqueRoot(Visitor& visitor, ImplType& impl)
|
||||
{
|
||||
addWebCoreOpaqueRoot(visitor, root(&impl));
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, WebCoreOpaqueRoot root)
|
||||
{
|
||||
return visitor.containsOpaqueRoot(root.pointer());
|
||||
}
|
||||
|
||||
template<typename Visitor, typename ImplType>
|
||||
ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, ImplType& impl)
|
||||
{
|
||||
return containsWebCoreOpaqueRoot(visitor, root(&impl));
|
||||
}
|
||||
|
||||
template<typename Visitor, typename ImplType>
|
||||
ALWAYS_INLINE bool containsWebCoreOpaqueRoot(Visitor& visitor, ImplType* impl)
|
||||
{
|
||||
return containsWebCoreOpaqueRoot(visitor, root(impl));
|
||||
}
|
||||
|
||||
} // namespace WebCore
|
||||
@@ -1835,7 +1835,6 @@ JSC_DECLARE_HOST_FUNCTION(makeGetterTypeErrorForBuiltins);
|
||||
JSC_DECLARE_HOST_FUNCTION(makeDOMExceptionForBuiltins);
|
||||
JSC_DECLARE_HOST_FUNCTION(createWritableStreamFromInternal);
|
||||
JSC_DECLARE_HOST_FUNCTION(getInternalWritableStream);
|
||||
JSC_DECLARE_HOST_FUNCTION(whenSignalAborted);
|
||||
JSC_DECLARE_HOST_FUNCTION(isAbortSignal);
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(makeThisTypeErrorForBuiltins, (JSGlobalObject * globalObject, CallFrame* callFrame))
|
||||
@@ -1918,7 +1917,7 @@ JSC_DEFINE_HOST_FUNCTION(createWritableStreamFromInternal, (JSGlobalObject * glo
|
||||
return JSValue::encode(toJSNewlyCreated(globalObject, jsDOMGlobalObject, WritableStream::create(WTFMove(internalWritableStream))));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(whenSignalAborted, (JSGlobalObject * globalObject, CallFrame* callFrame))
|
||||
JSC_DEFINE_HOST_FUNCTION(addAbortAlgorithmToSignal, (JSGlobalObject * globalObject, CallFrame* callFrame))
|
||||
{
|
||||
ASSERT(callFrame);
|
||||
ASSERT(callFrame->argumentCount() == 2);
|
||||
@@ -1930,8 +1929,21 @@ JSC_DEFINE_HOST_FUNCTION(whenSignalAborted, (JSGlobalObject * globalObject, Call
|
||||
|
||||
Ref<AbortAlgorithm> abortAlgorithm = JSAbortAlgorithm::create(vm, callFrame->uncheckedArgument(1).getObject());
|
||||
|
||||
bool result = WebCore::AbortSignal::whenSignalAborted(abortSignal->wrapped(), WTFMove(abortAlgorithm));
|
||||
return JSValue::encode(result ? JSValue(JSC::JSValue::JSTrue) : JSValue(JSC::JSValue::JSFalse));
|
||||
auto algorithmIdentifier = AbortSignal::addAbortAlgorithmToSignal(abortSignal->wrapped(), WTFMove(abortAlgorithm));
|
||||
return JSValue::encode(JSC::jsNumber(algorithmIdentifier));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(removeAbortAlgorithmFromSignal, (JSGlobalObject*, CallFrame* callFrame))
|
||||
{
|
||||
ASSERT(callFrame);
|
||||
ASSERT(callFrame->argumentCount() == 2);
|
||||
|
||||
auto* abortSignal = jsDynamicCast<JSAbortSignal*>(callFrame->uncheckedArgument(0));
|
||||
if (UNLIKELY(!abortSignal))
|
||||
return JSValue::encode(JSValue(JSC::JSValue::JSFalse));
|
||||
|
||||
AbortSignal::removeAbortAlgorithmFromSignal(abortSignal->wrapped(), callFrame->uncheckedArgument(1).asUInt32());
|
||||
return JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(isAbortSignal, (JSGlobalObject*, CallFrame* callFrame))
|
||||
@@ -3351,7 +3363,8 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
|
||||
GlobalPropertyInfo(builtinNames.makeThisTypeErrorPrivateName(), JSFunction::create(vm, this, 2, String(), makeThisTypeErrorForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
GlobalPropertyInfo(builtinNames.makeGetterTypeErrorPrivateName(), JSFunction::create(vm, this, 2, String(), makeGetterTypeErrorForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
GlobalPropertyInfo(builtinNames.makeDOMExceptionPrivateName(), JSFunction::create(vm, this, 2, String(), makeDOMExceptionForBuiltins, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
GlobalPropertyInfo(builtinNames.whenSignalAbortedPrivateName(), JSFunction::create(vm, this, 2, String(), whenSignalAborted, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
GlobalPropertyInfo(builtinNames.addAbortAlgorithmToSignalPrivateName(), JSFunction::create(vm, this, 2, String(), addAbortAlgorithmToSignal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
GlobalPropertyInfo(builtinNames.removeAbortAlgorithmFromSignalPrivateName(), JSFunction::create(vm, this, 2, String(), removeAbortAlgorithmFromSignal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
GlobalPropertyInfo(builtinNames.cloneArrayBufferPrivateName(), JSFunction::create(vm, this, 3, String(), cloneArrayBuffer, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
GlobalPropertyInfo(builtinNames.structuredCloneForStreamPrivateName(), JSFunction::create(vm, this, 1, String(), structuredCloneForStream, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
GlobalPropertyInfo(builtinNames.isAbortSignalPrivateName(), JSFunction::create(vm, this, 1, String(), isAbortSignal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
|
||||
|
||||
@@ -5261,7 +5261,7 @@ extern "C" bool WebCore__AbortSignal__aborted(WebCore__AbortSignal* arg0)
|
||||
extern "C" JSC__JSValue WebCore__AbortSignal__abortReason(WebCore__AbortSignal* arg0)
|
||||
{
|
||||
WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0);
|
||||
return JSC::JSValue::encode(abortSignal->reason());
|
||||
return JSC::JSValue::encode(abortSignal->reason().getValue(jsNull()));
|
||||
}
|
||||
|
||||
extern "C" WebCore__AbortSignal* WebCore__AbortSignal__ref(WebCore__AbortSignal* arg0)
|
||||
@@ -5288,7 +5288,7 @@ extern "C" WebCore__AbortSignal* WebCore__AbortSignal__addListener(WebCore__Abor
|
||||
WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0);
|
||||
|
||||
if (abortSignal->aborted()) {
|
||||
callback(ctx, JSC::JSValue::encode(abortSignal->reason()));
|
||||
callback(ctx, JSC::JSValue::encode(abortSignal->reason().getValue(jsNull())));
|
||||
return arg0;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
#include "AbortSignal.h"
|
||||
#include "DOMException.h"
|
||||
#include "JSDOMException.h"
|
||||
// #include <wtf/IsoMallocInlines.h>
|
||||
#include <wtf/IsoMallocInlines.h>
|
||||
#include "WebCoreOpaqueRoot.h"
|
||||
#include "WebCoreOpaqueRootInlines.h"
|
||||
|
||||
namespace WebCore {
|
||||
|
||||
@@ -56,9 +58,19 @@ void AbortController::abort(JSDOMGlobalObject& globalObject, JSC::JSValue reason
|
||||
{
|
||||
ASSERT(reason);
|
||||
if (reason.isUndefined())
|
||||
reason = toJS(&globalObject, &globalObject, DOMException::create(AbortError));
|
||||
reason = toJS(&globalObject, &globalObject, DOMException::create(ExceptionCode::AbortError));
|
||||
|
||||
m_signal->signalAbort(reason);
|
||||
protectedSignal()->signalAbort(reason);
|
||||
}
|
||||
|
||||
WebCoreOpaqueRoot AbortController::opaqueRoot()
|
||||
{
|
||||
return root(&signal());
|
||||
}
|
||||
|
||||
Ref<AbortSignal> AbortController::protectedSignal() const
|
||||
{
|
||||
return m_signal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ class GlobalObject;
|
||||
|
||||
namespace WebCore {
|
||||
|
||||
class WebCoreOpaqueRoot;
|
||||
|
||||
class AbortSignal;
|
||||
|
||||
class ScriptExecutionContext;
|
||||
@@ -55,8 +57,11 @@ public:
|
||||
~AbortController();
|
||||
|
||||
AbortSignal& signal();
|
||||
Ref<AbortSignal> protectedSignal() const;
|
||||
void abort(Zig::GlobalObject&, JSC::JSValue reason);
|
||||
|
||||
WebCoreOpaqueRoot opaqueRoot();
|
||||
|
||||
private:
|
||||
explicit AbortController(ScriptExecutionContext&);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2022 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2023 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -33,9 +33,10 @@
|
||||
#include "EventNames.h"
|
||||
#include "JSDOMException.h"
|
||||
#include "ScriptExecutionContext.h"
|
||||
#include "WebCoreOpaqueRoot.h"
|
||||
#include <JavaScriptCore/Exception.h>
|
||||
#include <JavaScriptCore/JSCast.h>
|
||||
// #include <wtf/IsoMallocInlines.h>
|
||||
#include <wtf/IsoMallocInlines.h>
|
||||
|
||||
namespace WebCore {
|
||||
|
||||
@@ -51,7 +52,7 @@ Ref<AbortSignal> AbortSignal::abort(JSDOMGlobalObject& globalObject, ScriptExecu
|
||||
{
|
||||
ASSERT(reason);
|
||||
if (reason.isUndefined())
|
||||
reason = toJS(&globalObject, &globalObject, DOMException::create(AbortError));
|
||||
reason = toJS(&globalObject, &globalObject, DOMException::create(ExceptionCode::AbortError));
|
||||
return adoptRef(*new AbortSignal(&context, Aborted::Yes, reason));
|
||||
}
|
||||
|
||||
@@ -82,16 +83,51 @@ Ref<AbortSignal> AbortSignal::timeout(ScriptExecutionContext& context, uint64_t
|
||||
return signal;
|
||||
}
|
||||
|
||||
Ref<AbortSignal> AbortSignal::any(ScriptExecutionContext& context, const Vector<RefPtr<AbortSignal>>& signals)
|
||||
{
|
||||
Ref resultSignal = AbortSignal::create(&context);
|
||||
|
||||
auto abortedSignalIndex = signals.findIf([](auto& signal) { return signal->aborted(); });
|
||||
if (abortedSignalIndex != notFound) {
|
||||
resultSignal->signalAbort(signals[abortedSignalIndex]->reason().getValue());
|
||||
return resultSignal;
|
||||
}
|
||||
|
||||
resultSignal->markAsDependent();
|
||||
for (auto& signal : signals)
|
||||
resultSignal->addSourceSignal(*signal);
|
||||
|
||||
return resultSignal;
|
||||
}
|
||||
|
||||
AbortSignal::AbortSignal(ScriptExecutionContext* context, Aborted aborted, JSC::JSValue reason)
|
||||
: ContextDestructionObserver(context)
|
||||
, m_reason(reason)
|
||||
, m_aborted(aborted == Aborted::Yes)
|
||||
, m_reason(context->vm(), reason)
|
||||
{
|
||||
ASSERT(reason);
|
||||
}
|
||||
|
||||
AbortSignal::~AbortSignal() = default;
|
||||
|
||||
void AbortSignal::addSourceSignal(AbortSignal& signal)
|
||||
{
|
||||
if (signal.isDependent()) {
|
||||
for (Ref sourceSignal : signal.sourceSignals())
|
||||
addSourceSignal(sourceSignal);
|
||||
return;
|
||||
}
|
||||
ASSERT(!signal.aborted());
|
||||
ASSERT(signal.sourceSignals().isEmptyIgnoringNullReferences());
|
||||
m_sourceSignals.add(signal);
|
||||
signal.addDependentSignal(*this);
|
||||
}
|
||||
|
||||
void AbortSignal::addDependentSignal(AbortSignal& signal)
|
||||
{
|
||||
m_dependentSignals.add(signal);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#abortsignal-signal-abort
|
||||
void AbortSignal::signalAbort(JSC::JSValue reason)
|
||||
{
|
||||
@@ -101,15 +137,12 @@ void AbortSignal::signalAbort(JSC::JSValue reason)
|
||||
|
||||
// 2. Set signal’s aborted flag.
|
||||
m_aborted = true;
|
||||
m_sourceSignals.clear();
|
||||
|
||||
// FIXME: This code is wrong: we should emit a write-barrier. Otherwise, GC can collect it.
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=236353
|
||||
ASSERT(reason);
|
||||
auto& vm = scriptExecutionContext()->vm();
|
||||
m_reason.set(vm, reason);
|
||||
|
||||
Ref protectedThis { *this };
|
||||
auto algorithms = std::exchange(m_algorithms, {});
|
||||
for (auto& algorithm : algorithms)
|
||||
algorithm(reason);
|
||||
m_reason.setWeakly(reason);
|
||||
|
||||
auto callbacks = std::exchange(m_native_callbacks, {});
|
||||
for (auto callback : callbacks) {
|
||||
@@ -117,6 +150,10 @@ void AbortSignal::signalAbort(JSC::JSValue reason)
|
||||
func(ctx, JSC::JSValue::encode(reason));
|
||||
}
|
||||
|
||||
auto algorithms = std::exchange(m_algorithms, {});
|
||||
for (auto& algorithm : algorithms)
|
||||
algorithm.second(reason);
|
||||
|
||||
// 5. Fire an event named abort at signal.
|
||||
dispatchEvent(Event::create(eventNames().abortEvent, Event::CanBubble::No, Event::IsCancelable::No));
|
||||
}
|
||||
@@ -140,21 +177,15 @@ void AbortSignal::signalFollow(AbortSignal& signal)
|
||||
return;
|
||||
|
||||
if (signal.aborted()) {
|
||||
signalAbort(signal.reason());
|
||||
signalAbort(signal.reason().getValue());
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(!m_followingSignal);
|
||||
m_followingSignal = signal;
|
||||
signal.addAlgorithm([weakThis = WeakPtr { this }](JSC::JSValue reason) {
|
||||
if (weakThis) {
|
||||
if (reason.isEmpty() || reason.isUndefined()) {
|
||||
weakThis->signalAbort(weakThis->m_followingSignal ? weakThis->m_followingSignal->reason()
|
||||
: JSC::jsUndefined());
|
||||
} else {
|
||||
weakThis->signalAbort(reason);
|
||||
}
|
||||
}
|
||||
signal.addAlgorithm([weakThis = WeakPtr { *this }](JSC::JSValue reason) {
|
||||
if (RefPtr signal = weakThis.get())
|
||||
signal->signalAbort(reason);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -163,16 +194,33 @@ void AbortSignal::eventListenersDidChange()
|
||||
m_hasAbortEventListener = hasEventListeners(eventNames().abortEvent);
|
||||
}
|
||||
|
||||
bool AbortSignal::whenSignalAborted(AbortSignal& signal, Ref<AbortAlgorithm>&& algorithm)
|
||||
uint32_t AbortSignal::addAbortAlgorithmToSignal(AbortSignal& signal, Ref<AbortAlgorithm>&& algorithm)
|
||||
{
|
||||
if (signal.aborted()) {
|
||||
algorithm->handleEvent(signal.m_reason.get());
|
||||
return true;
|
||||
algorithm->handleEvent(signal.m_reason.getValue());
|
||||
return 0;
|
||||
}
|
||||
signal.addAlgorithm([algorithm = WTFMove(algorithm)](JSC::JSValue value) mutable {
|
||||
return signal.addAlgorithm([algorithm = WTFMove(algorithm)](JSC::JSValue value) mutable {
|
||||
algorithm->handleEvent(value);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
void AbortSignal::removeAbortAlgorithmFromSignal(AbortSignal& signal, uint32_t algorithmIdentifier)
|
||||
{
|
||||
signal.removeAlgorithm(algorithmIdentifier);
|
||||
}
|
||||
|
||||
uint32_t AbortSignal::addAlgorithm(Algorithm&& algorithm)
|
||||
{
|
||||
m_algorithms.append(std::make_pair(++m_algorithmIdentifier, WTFMove(algorithm)));
|
||||
return m_algorithmIdentifier;
|
||||
}
|
||||
|
||||
void AbortSignal::removeAlgorithm(uint32_t algorithmIdentifier)
|
||||
{
|
||||
m_algorithms.removeFirstMatching([algorithmIdentifier](auto& pair) {
|
||||
return pair.first == algorithmIdentifier;
|
||||
});
|
||||
}
|
||||
|
||||
void AbortSignal::throwIfAborted(JSC::JSGlobalObject& lexicalGlobalObject)
|
||||
@@ -180,9 +228,14 @@ void AbortSignal::throwIfAborted(JSC::JSGlobalObject& lexicalGlobalObject)
|
||||
if (!aborted())
|
||||
return;
|
||||
|
||||
auto& vm = lexicalGlobalObject.vm();
|
||||
Ref vm = lexicalGlobalObject.vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
throwException(&lexicalGlobalObject, scope, m_reason.get());
|
||||
throwException(&lexicalGlobalObject, scope, m_reason.getValue());
|
||||
}
|
||||
|
||||
WebCoreOpaqueRoot root(AbortSignal* signal)
|
||||
{
|
||||
return WebCoreOpaqueRoot { signal };
|
||||
}
|
||||
|
||||
} // namespace WebCore
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2022 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2017-2023 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -25,19 +25,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ContextDestructionObserver.h"
|
||||
#include "EventTarget.h"
|
||||
// #include "JSDOMPromiseDeferred.h"
|
||||
#include "JSValueInWrappedObject.h"
|
||||
#include <wtf/Function.h>
|
||||
#include <wtf/Ref.h>
|
||||
#include <wtf/RefCounted.h>
|
||||
#include <wtf/WeakListHashSet.h>
|
||||
#include <wtf/WeakPtr.h>
|
||||
|
||||
namespace WebCore {
|
||||
|
||||
class AbortAlgorithm;
|
||||
class ScriptExecutionContext;
|
||||
class WebCoreOpaqueRoot;
|
||||
|
||||
class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWithInlineData, private ContextDestructionObserver {
|
||||
WTF_MAKE_ISO_ALLOCATED_EXPORT(AbortSignal, WEBCORE_EXPORT);
|
||||
@@ -49,14 +52,19 @@ public:
|
||||
|
||||
static Ref<AbortSignal> abort(JSDOMGlobalObject&, ScriptExecutionContext&, JSC::JSValue reason);
|
||||
static Ref<AbortSignal> timeout(ScriptExecutionContext&, uint64_t milliseconds);
|
||||
static Ref<AbortSignal> any(ScriptExecutionContext&, const Vector<RefPtr<AbortSignal>>&);
|
||||
|
||||
static bool whenSignalAborted(AbortSignal&, Ref<AbortAlgorithm>&&);
|
||||
static uint32_t addAbortAlgorithmToSignal(AbortSignal&, Ref<AbortAlgorithm>&&);
|
||||
static void removeAbortAlgorithmFromSignal(AbortSignal&, uint32_t algorithmIdentifier);
|
||||
|
||||
void signalAbort(JSC::JSValue reason);
|
||||
void signalFollow(AbortSignal&);
|
||||
|
||||
bool aborted() const { return m_aborted; }
|
||||
JSValue reason() const { return m_reason.get(); }
|
||||
const JSValueInWrappedObject& reason() const { return m_reason; }
|
||||
|
||||
void cleanNativeBindings(void* ref);
|
||||
void addNativeCallback(NativeCallbackTuple callback) { m_native_callbacks.append(callback); }
|
||||
|
||||
bool hasActiveTimeoutTimer() const { return m_hasActiveTimeoutTimer; }
|
||||
bool hasAbortEventListener() const { return m_hasAbortEventListener; }
|
||||
@@ -64,15 +72,18 @@ public:
|
||||
using RefCounted::deref;
|
||||
using RefCounted::ref;
|
||||
|
||||
using Algorithm = Function<void(JSValue)>;
|
||||
void addAlgorithm(Algorithm&& algorithm) { m_algorithms.append(WTFMove(algorithm)); }
|
||||
void cleanNativeBindings(void* ref);
|
||||
void addNativeCallback(NativeCallbackTuple callback) { m_native_callbacks.append(callback); }
|
||||
using Algorithm = Function<void(JSC::JSValue reason)>;
|
||||
uint32_t addAlgorithm(Algorithm&&);
|
||||
void removeAlgorithm(uint32_t);
|
||||
|
||||
bool isFollowingSignal() const { return !!m_followingSignal; }
|
||||
|
||||
void throwIfAborted(JSC::JSGlobalObject&);
|
||||
|
||||
using AbortSignalSet = WeakListHashSet<AbortSignal, WeakPtrImplWithEventTargetData>;
|
||||
const AbortSignalSet& sourceSignals() const { return m_sourceSignals; }
|
||||
AbortSignalSet& sourceSignals() { return m_sourceSignals; }
|
||||
|
||||
private:
|
||||
enum class Aborted : bool { No,
|
||||
Yes };
|
||||
@@ -80,6 +91,11 @@ private:
|
||||
|
||||
void setHasActiveTimeoutTimer(bool hasActiveTimeoutTimer) { m_hasActiveTimeoutTimer = hasActiveTimeoutTimer; }
|
||||
|
||||
bool isDependent() const { return m_isDependent; }
|
||||
void markAsDependent() { m_isDependent = true; }
|
||||
void addSourceSignal(AbortSignal&);
|
||||
void addDependentSignal(AbortSignal&);
|
||||
|
||||
// EventTarget.
|
||||
EventTargetInterface eventTargetInterface() const final { return AbortSignalEventTargetInterfaceType; }
|
||||
ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
|
||||
@@ -87,13 +103,19 @@ private:
|
||||
void derefEventTarget() final { deref(); }
|
||||
void eventListenersDidChange() final;
|
||||
|
||||
bool m_aborted { false };
|
||||
Vector<Algorithm, 2> m_algorithms;
|
||||
Vector<std::pair<uint32_t, Algorithm>> m_algorithms;
|
||||
WeakPtr<AbortSignal, WeakPtrImplWithEventTargetData> m_followingSignal;
|
||||
AbortSignalSet m_sourceSignals;
|
||||
AbortSignalSet m_dependentSignals;
|
||||
JSValueInWrappedObject m_reason;
|
||||
Vector<NativeCallbackTuple, 2> m_native_callbacks;
|
||||
WeakPtr<AbortSignal> m_followingSignal;
|
||||
JSC::Strong<JSC::Unknown> m_reason;
|
||||
uint32_t m_algorithmIdentifier { 0 };
|
||||
bool m_aborted { false };
|
||||
bool m_hasActiveTimeoutTimer { false };
|
||||
bool m_hasAbortEventListener { false };
|
||||
bool m_isDependent { false };
|
||||
};
|
||||
|
||||
}
|
||||
WebCoreOpaqueRoot root(AbortSignal*);
|
||||
|
||||
} // namespace WebCore
|
||||
|
||||
@@ -72,7 +72,7 @@ static HashMap<BroadcastChannelIdentifier, ScriptExecutionContextIdentifier>& ch
|
||||
// return { WTFMove(topOrigin), WTFMove(securityOrigin) };
|
||||
// }
|
||||
|
||||
class BroadcastChannel::MainThreadBridge : public ThreadSafeRefCounted<MainThreadBridge, WTF::DestructionThread::Main> {
|
||||
class BroadcastChannel::MainThreadBridge : public ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr<MainThreadBridge> {
|
||||
public:
|
||||
static Ref<MainThreadBridge> create(BroadcastChannel& channel, const String& name, ScriptExecutionContext& context)
|
||||
{
|
||||
@@ -87,13 +87,15 @@ public:
|
||||
BroadcastChannelIdentifier identifier() const { return m_identifier; }
|
||||
ScriptExecutionContextIdentifier contextId() const { return m_contextId; }
|
||||
|
||||
using ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr::deref;
|
||||
using ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr::ref;
|
||||
|
||||
private:
|
||||
MainThreadBridge(BroadcastChannel&, const String& name, ScriptExecutionContext&);
|
||||
|
||||
void ensureOnMainThread(Function<void(void*)>&&);
|
||||
|
||||
// WeakPtr<BroadcastChannel, WeakPtrImplWithEventTargetData> m_broadcastChannel;
|
||||
WeakPtr<BroadcastChannel> m_broadcastChannel;
|
||||
WeakPtr<BroadcastChannel, WeakPtrImplWithEventTargetData> m_broadcastChannel;
|
||||
const BroadcastChannelIdentifier m_identifier;
|
||||
const String m_name; // Main thread only.
|
||||
ScriptExecutionContextIdentifier m_contextId;
|
||||
|
||||
@@ -65,7 +65,22 @@ public:
|
||||
bool isFiringEventListeners { false };
|
||||
};
|
||||
|
||||
class EventTarget : public ScriptWrappable, public CanMakeWeakPtr<EventTarget> {
|
||||
// Do not make WeakPtrImplWithEventTargetData a derived class of DefaultWeakPtrImpl to catch the bug which uses incorrect impl class.
|
||||
class WeakPtrImplWithEventTargetData final : public WTF::WeakPtrImplBaseSingleThread<WeakPtrImplWithEventTargetData> {
|
||||
public:
|
||||
EventTargetData& eventTargetData() { return m_eventTargetData; }
|
||||
const EventTargetData& eventTargetData() const { return m_eventTargetData; }
|
||||
|
||||
template<typename T> WeakPtrImplWithEventTargetData(T* ptr)
|
||||
: WTF::WeakPtrImplBaseSingleThread<WeakPtrImplWithEventTargetData>(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
EventTargetData m_eventTargetData;
|
||||
};
|
||||
|
||||
class EventTarget : public ScriptWrappable, public CanMakeWeakPtrWithBitField<EventTarget, WeakPtrFactoryInitialization::Lazy, WeakPtrImplWithEventTargetData> {
|
||||
WTF_MAKE_ISO_ALLOCATED(EventTarget);
|
||||
|
||||
public:
|
||||
|
||||
@@ -39,9 +39,10 @@
|
||||
#include "JSDOMWrapperCache.h"
|
||||
#include "ScriptExecutionContext.h"
|
||||
#include "WebCoreJSClientData.h"
|
||||
#include "WebCoreOpaqueRootInlines.h"
|
||||
#include <JavaScriptCore/FunctionPrototype.h>
|
||||
#include <JavaScriptCore/HeapAnalyzer.h>
|
||||
|
||||
#include <JavaScriptCore/JSCInlines.h>
|
||||
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
|
||||
#include <JavaScriptCore/SlotVisitorMacros.h>
|
||||
#include <JavaScriptCore/SubspaceInlines.h>
|
||||
@@ -49,8 +50,6 @@
|
||||
#include <wtf/PointerPreparations.h>
|
||||
#include <wtf/URL.h>
|
||||
|
||||
#include "weak_handle.h"
|
||||
|
||||
namespace WebCore {
|
||||
using namespace JSC;
|
||||
|
||||
@@ -97,9 +96,9 @@ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSAbortControllerPrototype, JSAbortControlle
|
||||
|
||||
using JSAbortControllerDOMConstructor = JSDOMConstructor<JSAbortController>;
|
||||
|
||||
template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSAbortControllerDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
|
||||
template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSAbortControllerDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
|
||||
{
|
||||
VM& vm = lexicalGlobalObject->vm();
|
||||
auto& vm = lexicalGlobalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
auto* castedThis = jsCast<JSAbortControllerDOMConstructor*>(callFrame->jsCallee());
|
||||
ASSERT(castedThis);
|
||||
@@ -139,8 +138,8 @@ template<> void JSAbortControllerDOMConstructor::initializeProperties(VM& vm, JS
|
||||
/* Hash table for prototype */
|
||||
|
||||
static const HashTableValue JSAbortControllerPrototypeTableValues[] = {
|
||||
{ "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortControllerConstructor, 0 } },
|
||||
{ "signal"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortController_signal, 0 } },
|
||||
{ "constructor"_s, static_cast<unsigned>(PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortControllerConstructor, 0 } },
|
||||
{ "signal"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortController_signal, 0 } },
|
||||
{ "abort"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsAbortControllerPrototypeFunction_abort, 0 } },
|
||||
};
|
||||
|
||||
@@ -160,13 +159,7 @@ JSAbortController::JSAbortController(Structure* structure, JSDOMGlobalObject& gl
|
||||
{
|
||||
}
|
||||
|
||||
void JSAbortController::finishCreation(VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
ASSERT(inherits(info()));
|
||||
|
||||
// static_assert(!std::is_base_of<ActiveDOMObject, AbortController>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
|
||||
}
|
||||
// static_assert(!std::is_base_of<ActiveDOMObject, AbortController>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject.");
|
||||
|
||||
JSObject* JSAbortController::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
|
||||
{
|
||||
@@ -191,14 +184,14 @@ void JSAbortController::destroy(JSC::JSCell* cell)
|
||||
thisObject->JSAbortController::~JSAbortController();
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortControllerConstructor, (JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, PropertyName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortControllerConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
|
||||
{
|
||||
VM& vm = JSC::getVM(lexicalGlobalObject);
|
||||
auto& vm = JSC::getVM(lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
auto* prototype = jsDynamicCast<JSAbortControllerPrototype*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!prototype))
|
||||
return throwVMTypeError(lexicalGlobalObject, throwScope);
|
||||
return JSValue::encode(JSAbortController::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
|
||||
return JSValue::encode(JSAbortController::getConstructor(vm, prototype->globalObject()));
|
||||
}
|
||||
|
||||
static inline JSValue jsAbortController_signalGetter(JSGlobalObject& lexicalGlobalObject, JSAbortController& thisObject)
|
||||
@@ -209,7 +202,7 @@ static inline JSValue jsAbortController_signalGetter(JSGlobalObject& lexicalGlob
|
||||
RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<AbortSignal>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.signal())));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortController_signal, (JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, PropertyName attributeName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortController_signal, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
|
||||
{
|
||||
return IDLAttribute<JSAbortController>::get<jsAbortController_signalGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
|
||||
}
|
||||
@@ -248,7 +241,7 @@ void JSAbortController::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
auto* thisObject = jsCast<JSAbortController*>(cell);
|
||||
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
|
||||
Base::visitChildren(thisObject, visitor);
|
||||
visitor.addOpaqueRoot(WTF::getPtr(thisObject->wrapped().signal()));
|
||||
addWebCoreOpaqueRoot(visitor, thisObject->wrapped().opaqueRoot());
|
||||
}
|
||||
|
||||
DEFINE_VISIT_CHILDREN(JSAbortController);
|
||||
@@ -258,7 +251,7 @@ void JSAbortController::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
|
||||
auto* thisObject = jsCast<JSAbortController*>(cell);
|
||||
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
|
||||
if (thisObject->scriptExecutionContext())
|
||||
analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
|
||||
analyzer.setLabelForCell(cell, "url "_s + thisObject->scriptExecutionContext()->url().string());
|
||||
Base::analyzeHeap(cell, analyzer);
|
||||
}
|
||||
|
||||
@@ -277,8 +270,44 @@ void JSAbortControllerOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* co
|
||||
uncacheWrapper(world, &jsAbortController->wrapped(), jsAbortController);
|
||||
}
|
||||
|
||||
void JSAbortController::finishCreation(VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
ASSERT(inherits(info()));
|
||||
}
|
||||
|
||||
#if ENABLE(BINDING_INTEGRITY)
|
||||
#if PLATFORM(WIN)
|
||||
#pragma warning(disable : 4483)
|
||||
extern "C" {
|
||||
extern void (*const __identifier("??_7AbortController@WebCore@@6B@")[])();
|
||||
}
|
||||
#else
|
||||
extern "C" {
|
||||
extern void* _ZTVN7WebCore15AbortControllerE[];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<AbortController>&& impl)
|
||||
{
|
||||
|
||||
if constexpr (std::is_polymorphic_v<AbortController>) {
|
||||
#if ENABLE(BINDING_INTEGRITY)
|
||||
const void* actualVTablePointer = getVTablePointer(impl.ptr());
|
||||
#if PLATFORM(WIN)
|
||||
void* expectedVTablePointer = __identifier("??_7AbortController@WebCore@@6B@");
|
||||
#else
|
||||
void* expectedVTablePointer = &_ZTVN7WebCore15AbortControllerE[2];
|
||||
#endif
|
||||
|
||||
// If you hit this assertion you either have a use after free bug, or
|
||||
// AbortController has subclasses. If AbortController has subclasses that get passed
|
||||
// to toJS() we currently require AbortController you to opt out of binding hardening
|
||||
// by adding the SkipVTableValidation attribute to the interface IDL definition
|
||||
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
|
||||
#endif
|
||||
}
|
||||
return createWrapper<AbortController>(globalObject, WTFMove(impl));
|
||||
}
|
||||
|
||||
@@ -287,7 +316,7 @@ JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* g
|
||||
return wrap(lexicalGlobalObject, globalObject, impl);
|
||||
}
|
||||
|
||||
AbortController* JSAbortController::toWrapped(JSC::VM& vm, JSC::JSValue value)
|
||||
AbortController* JSAbortController::toWrapped(JSC::VM&, JSC::JSValue value)
|
||||
{
|
||||
if (auto* wrapper = jsDynamicCast<JSAbortController*>(value))
|
||||
return &wrapper->wrapped();
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "AbortController.h"
|
||||
#include "JSDOMWrapper.h"
|
||||
#include <wtf/NeverDestroyed.h>
|
||||
@@ -33,8 +31,9 @@ public:
|
||||
using Base = JSDOMWrapper<AbortController>;
|
||||
static JSAbortController* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<AbortController>&& impl)
|
||||
{
|
||||
JSAbortController* ptr = new (NotNull, JSC::allocateCell<JSAbortController>(globalObject->vm())) JSAbortController(structure, *globalObject, WTFMove(impl));
|
||||
ptr->finishCreation(globalObject->vm());
|
||||
auto& vm = globalObject->vm();
|
||||
JSAbortController* ptr = new (NotNull, JSC::allocateCell<JSAbortController>(vm)) JSAbortController(structure, *globalObject, WTFMove(impl));
|
||||
ptr->finishCreation(vm);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "ExtendedDOMClientIsoSubspaces.h"
|
||||
#include "ExtendedDOMIsoSubspaces.h"
|
||||
#include "IDLTypes.h"
|
||||
#include "JSAbortAlgorithm.h"
|
||||
#include "JSAbortSignal.h"
|
||||
#include "JSDOMAttribute.h"
|
||||
#include "JSDOMBinding.h"
|
||||
@@ -34,9 +33,9 @@
|
||||
#include "JSDOMConvertAny.h"
|
||||
#include "JSDOMConvertBase.h"
|
||||
#include "JSDOMConvertBoolean.h"
|
||||
#include "JSDOMConvertCallbacks.h"
|
||||
#include "JSDOMConvertInterface.h"
|
||||
#include "JSDOMConvertNumbers.h"
|
||||
#include "JSDOMConvertSequences.h"
|
||||
#include "JSDOMExceptionHandling.h"
|
||||
#include "JSDOMGlobalObject.h"
|
||||
#include "JSDOMGlobalObjectInlines.h"
|
||||
@@ -46,6 +45,7 @@
|
||||
#include "ScriptExecutionContext.h"
|
||||
#include "WebCoreJSClientData.h"
|
||||
#include <JavaScriptCore/HeapAnalyzer.h>
|
||||
#include <JavaScriptCore/JSArray.h>
|
||||
#include <JavaScriptCore/JSCInlines.h>
|
||||
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
|
||||
#include <JavaScriptCore/SlotVisitorMacros.h>
|
||||
@@ -59,9 +59,9 @@ using namespace JSC;
|
||||
|
||||
// Functions
|
||||
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsAbortSignalConstructorFunction_whenSignalAborted);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsAbortSignalConstructorFunction_abort);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsAbortSignalConstructorFunction_timeout);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsAbortSignalConstructorFunction_any);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsAbortSignalPrototypeFunction_throwIfAborted);
|
||||
|
||||
// Attributes
|
||||
@@ -109,9 +109,9 @@ using JSAbortSignalDOMConstructor = JSDOMConstructorNotConstructable<JSAbortSign
|
||||
/* Hash table for constructor */
|
||||
|
||||
static const HashTableValue JSAbortSignalConstructorTableValues[] = {
|
||||
{ "whenSignalAborted"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsAbortSignalConstructorFunction_whenSignalAborted, 2 } },
|
||||
{ "abort"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsAbortSignalConstructorFunction_abort, 0 } },
|
||||
{ "timeout"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsAbortSignalConstructorFunction_timeout, 1 } },
|
||||
{ "any"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsAbortSignalConstructorFunction_any, 1 } },
|
||||
};
|
||||
|
||||
template<> const ClassInfo JSAbortSignalDOMConstructor::s_info = { "AbortSignal"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAbortSignalDOMConstructor) };
|
||||
@@ -129,18 +129,27 @@ template<> void JSAbortSignalDOMConstructor::initializeProperties(VM& vm, JSDOMG
|
||||
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
|
||||
putDirect(vm, vm.propertyNames->prototype, JSAbortSignal::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
|
||||
reifyStaticProperties(vm, JSAbortSignal::info(), JSAbortSignalConstructorTableValues, *this);
|
||||
// if (!((&globalObject)->inherits<JSDOMWindowBase>() || (&globalObject)->inherits<JSWorkerGlobalScopeBase>())) {
|
||||
// auto propertyName = Identifier::fromString(vm, "timeout"_s);
|
||||
// VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
|
||||
// DeletePropertySlot slot;
|
||||
// JSObject::deleteProperty(this, &globalObject, propertyName, slot);
|
||||
// }
|
||||
// if (!jsCast<JSDOMGlobalObject*>(&globalObject)->scriptExecutionContext()->settingsValues().abortSignalAnyOperationEnabled) {
|
||||
// auto propertyName = Identifier::fromString(vm, "any"_s);
|
||||
// VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
|
||||
// DeletePropertySlot slot;
|
||||
// JSObject::deleteProperty(this, &globalObject, propertyName, slot);
|
||||
// }
|
||||
}
|
||||
|
||||
/* Hash table for prototype */
|
||||
|
||||
static const HashTableValue JSAbortSignalPrototypeTableValues[] = {
|
||||
{ "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortSignalConstructor, 0 } },
|
||||
{ "aborted"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortSignal_aborted, 0 } },
|
||||
{ "reason"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortSignal_reason, 0 } },
|
||||
{ "onabort"_s,
|
||||
static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute),
|
||||
NoIntrinsic,
|
||||
{ HashTableValue::GetterSetterType, jsAbortSignal_onabort, setJSAbortSignal_onabort } },
|
||||
{ "constructor"_s, static_cast<unsigned>(PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortSignalConstructor, 0 } },
|
||||
{ "aborted"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortSignal_aborted, 0 } },
|
||||
{ "reason"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortSignal_reason, 0 } },
|
||||
{ "onabort"_s, JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsAbortSignal_onabort, setJSAbortSignal_onabort } },
|
||||
{ "throwIfAborted"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsAbortSignalPrototypeFunction_throwIfAborted, 0 } },
|
||||
};
|
||||
|
||||
@@ -150,7 +159,6 @@ void JSAbortSignalPrototype::finishCreation(VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
reifyStaticProperties(vm, JSAbortSignal::info(), JSAbortSignalPrototypeTableValues, *this);
|
||||
putDirect(vm, static_cast<JSVMClientData*>(vm.clientData)->builtinNames().whenSignalAbortedPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsAbortSignalConstructorFunction_whenSignalAborted, ImplementationVisibility::Public), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
|
||||
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
|
||||
}
|
||||
|
||||
@@ -167,9 +175,16 @@ void JSAbortSignal::finishCreation(VM& vm)
|
||||
ASSERT(inherits(info()));
|
||||
}
|
||||
|
||||
Ref<AbortSignal> JSAbortSignal::protectedWrapped() const
|
||||
{
|
||||
return wrapped();
|
||||
}
|
||||
|
||||
JSObject* JSAbortSignal::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
|
||||
{
|
||||
return JSAbortSignalPrototype::create(vm, &globalObject, JSAbortSignalPrototype::createStructure(vm, &globalObject, JSEventTarget::prototype(vm, globalObject)));
|
||||
auto* structure = JSAbortSignalPrototype::createStructure(vm, &globalObject, JSEventTarget::prototype(vm, globalObject));
|
||||
structure->setMayBePrototype(true);
|
||||
return JSAbortSignalPrototype::create(vm, &globalObject, structure);
|
||||
}
|
||||
|
||||
JSObject* JSAbortSignal::prototype(VM& vm, JSDOMGlobalObject& globalObject)
|
||||
@@ -182,14 +197,14 @@ JSValue JSAbortSignal::getConstructor(VM& vm, const JSGlobalObject* globalObject
|
||||
return getDOMConstructor<JSAbortSignalDOMConstructor, DOMConstructorID::AbortSignal>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignalConstructor, (JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, PropertyName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignalConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
|
||||
{
|
||||
VM& vm = JSC::getVM(lexicalGlobalObject);
|
||||
auto& vm = JSC::getVM(lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
auto* prototype = jsDynamicCast<JSAbortSignalPrototype*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!prototype))
|
||||
return throwVMTypeError(lexicalGlobalObject, throwScope);
|
||||
return JSValue::encode(JSAbortSignal::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject()));
|
||||
return JSValue::encode(JSAbortSignal::getConstructor(vm, prototype->globalObject()));
|
||||
}
|
||||
|
||||
static inline JSValue jsAbortSignal_abortedGetter(JSGlobalObject& lexicalGlobalObject, JSAbortSignal& thisObject)
|
||||
@@ -200,7 +215,7 @@ static inline JSValue jsAbortSignal_abortedGetter(JSGlobalObject& lexicalGlobalO
|
||||
RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.aborted())));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_aborted, (JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, PropertyName attributeName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_aborted, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
|
||||
{
|
||||
return IDLAttribute<JSAbortSignal>::get<jsAbortSignal_abortedGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
|
||||
}
|
||||
@@ -213,7 +228,7 @@ static inline JSValue jsAbortSignal_reasonGetter(JSGlobalObject& lexicalGlobalOb
|
||||
RELEASE_AND_RETURN(throwScope, (toJS<IDLAny>(lexicalGlobalObject, throwScope, impl.reason())));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_reason, (JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, PropertyName attributeName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_reason, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
|
||||
{
|
||||
return IDLAttribute<JSAbortSignal>::get<jsAbortSignal_reasonGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
|
||||
}
|
||||
@@ -221,10 +236,10 @@ JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_reason, (JSGlobalObject * lexicalGlobalOb
|
||||
static inline JSValue jsAbortSignal_onabortGetter(JSGlobalObject& lexicalGlobalObject, JSAbortSignal& thisObject)
|
||||
{
|
||||
UNUSED_PARAM(lexicalGlobalObject);
|
||||
return eventHandlerAttribute(thisObject.wrapped(), eventNames().abortEvent, worldForDOMObject(thisObject));
|
||||
return eventHandlerAttribute(thisObject.protectedWrapped(), eventNames().abortEvent, worldForDOMObject(thisObject));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_onabort, (JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, PropertyName attributeName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_onabort, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
|
||||
{
|
||||
return IDLAttribute<JSAbortSignal>::get<jsAbortSignal_onabortGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
|
||||
}
|
||||
@@ -232,40 +247,19 @@ JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_onabort, (JSGlobalObject * lexicalGlobalO
|
||||
static inline bool setJSAbortSignal_onabortSetter(JSGlobalObject& lexicalGlobalObject, JSAbortSignal& thisObject, JSValue value)
|
||||
{
|
||||
auto& vm = JSC::getVM(&lexicalGlobalObject);
|
||||
setEventHandlerAttribute<JSEventListener>(thisObject.wrapped(), eventNames().abortEvent, value, thisObject);
|
||||
UNUSED_PARAM(vm);
|
||||
setEventHandlerAttribute<JSEventListener>(thisObject.protectedWrapped(), eventNames().abortEvent, value, thisObject);
|
||||
vm.writeBarrier(&thisObject, value);
|
||||
ensureStillAliveHere(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(setJSAbortSignal_onabort, (JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue encodedValue, PropertyName attributeName))
|
||||
JSC_DEFINE_CUSTOM_SETTER(setJSAbortSignal_onabort, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName))
|
||||
{
|
||||
return IDLAttribute<JSAbortSignal>::set<setJSAbortSignal_onabortSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName);
|
||||
}
|
||||
|
||||
static inline JSC::EncodedJSValue jsAbortSignalConstructorFunction_whenSignalAbortedBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
auto& vm = JSC::getVM(lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
UNUSED_PARAM(throwScope);
|
||||
UNUSED_PARAM(callFrame);
|
||||
if (UNLIKELY(callFrame->argumentCount() < 2))
|
||||
return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
|
||||
EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
|
||||
auto object = convert<IDLInterface<AbortSignal>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "object", "AbortSignal", "whenSignalAborted", "AbortSignal"); });
|
||||
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
|
||||
EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
|
||||
auto algorithm = convert<IDLCallbackFunction<JSAbortAlgorithm>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeFunctionError(lexicalGlobalObject, scope, 1, "algorithm", "AbortSignal", "whenSignalAborted"); });
|
||||
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
|
||||
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLBoolean>(*lexicalGlobalObject, throwScope, AbortSignal::whenSignalAborted(*object, algorithm.releaseNonNull()))));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsAbortSignalConstructorFunction_whenSignalAborted, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
|
||||
{
|
||||
return IDLOperation<JSAbortSignal>::callStatic<jsAbortSignalConstructorFunction_whenSignalAbortedBody, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, *callFrame, "whenSignalAborted");
|
||||
}
|
||||
|
||||
static inline JSC::EncodedJSValue jsAbortSignalConstructorFunction_abortBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
auto& vm = JSC::getVM(lexicalGlobalObject);
|
||||
@@ -308,6 +302,28 @@ JSC_DEFINE_HOST_FUNCTION(jsAbortSignalConstructorFunction_timeout, (JSGlobalObje
|
||||
return IDLOperation<JSAbortSignal>::callStatic<jsAbortSignalConstructorFunction_timeoutBody>(*lexicalGlobalObject, *callFrame, "timeout");
|
||||
}
|
||||
|
||||
static inline JSC::EncodedJSValue jsAbortSignalConstructorFunction_anyBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
auto& vm = JSC::getVM(lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
UNUSED_PARAM(throwScope);
|
||||
UNUSED_PARAM(callFrame);
|
||||
if (UNLIKELY(callFrame->argumentCount() < 1))
|
||||
return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject));
|
||||
auto* context = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject)->scriptExecutionContext();
|
||||
if (UNLIKELY(!context))
|
||||
return JSValue::encode(jsUndefined());
|
||||
EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
|
||||
auto signals = convert<IDLSequence<IDLInterface<AbortSignal>>>(*lexicalGlobalObject, argument0.value());
|
||||
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
|
||||
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJSNewlyCreated<IDLInterface<AbortSignal>>(*lexicalGlobalObject, *jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), throwScope, AbortSignal::any(*context, WTFMove(signals)))));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsAbortSignalConstructorFunction_any, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
|
||||
{
|
||||
return IDLOperation<JSAbortSignal>::callStatic<jsAbortSignalConstructorFunction_anyBody>(*lexicalGlobalObject, *callFrame, "any");
|
||||
}
|
||||
|
||||
static inline JSC::EncodedJSValue jsAbortSignalPrototypeFunction_throwIfAbortedBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSAbortSignal>::ClassParameter castedThis)
|
||||
{
|
||||
auto& vm = JSC::getVM(lexicalGlobalObject);
|
||||
@@ -360,7 +376,7 @@ void JSAbortSignal::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
|
||||
auto* thisObject = jsCast<JSAbortSignal*>(cell);
|
||||
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
|
||||
if (thisObject->scriptExecutionContext())
|
||||
analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
|
||||
analyzer.setLabelForCell(cell, "url "_s + thisObject->scriptExecutionContext()->url().string());
|
||||
Base::analyzeHeap(cell, analyzer);
|
||||
}
|
||||
|
||||
@@ -368,7 +384,7 @@ void JSAbortSignalOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* contex
|
||||
{
|
||||
auto* jsAbortSignal = static_cast<JSAbortSignal*>(handle.slot()->asCell());
|
||||
auto& world = *static_cast<DOMWrapperWorld*>(context);
|
||||
uncacheWrapper(world, &jsAbortSignal->wrapped(), jsAbortSignal);
|
||||
uncacheWrapper(world, jsAbortSignal->protectedWrapped().ptr(), jsAbortSignal);
|
||||
}
|
||||
|
||||
#if ENABLE(BINDING_INTEGRITY)
|
||||
@@ -411,10 +427,11 @@ JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* g
|
||||
return wrap(lexicalGlobalObject, globalObject, impl);
|
||||
}
|
||||
|
||||
AbortSignal* JSAbortSignal::toWrapped(JSC::VM& vm, JSC::JSValue value)
|
||||
AbortSignal* JSAbortSignal::toWrapped(JSC::VM&, JSC::JSValue value)
|
||||
{
|
||||
if (auto* wrapper = jsDynamicCast<JSAbortSignal*>(value))
|
||||
return &wrapper->wrapped();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,8 +33,9 @@ public:
|
||||
using DOMWrapped = AbortSignal;
|
||||
static JSAbortSignal* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<AbortSignal>&& impl)
|
||||
{
|
||||
JSAbortSignal* ptr = new (NotNull, JSC::allocateCell<JSAbortSignal>(globalObject->vm())) JSAbortSignal(structure, *globalObject, WTFMove(impl));
|
||||
ptr->finishCreation(globalObject->vm());
|
||||
auto& vm = globalObject->vm();
|
||||
JSAbortSignal* ptr = new (NotNull, JSC::allocateCell<JSAbortSignal>(vm)) JSAbortSignal(structure, *globalObject, WTFMove(impl));
|
||||
ptr->finishCreation(vm);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -66,6 +67,9 @@ public:
|
||||
{
|
||||
return static_cast<AbortSignal&>(Base::wrapped());
|
||||
}
|
||||
|
||||
Ref<AbortSignal> protectedWrapped() const;
|
||||
|
||||
protected:
|
||||
JSAbortSignal(JSC::Structure*, JSDOMGlobalObject&, Ref<AbortSignal>&&);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2022 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -95,23 +95,24 @@ struct NumericSequenceConverter {
|
||||
auto indexValue = array->butterfly()->contiguousInt32().at(array, i).get();
|
||||
ASSERT(!indexValue || indexValue.isInt32());
|
||||
if (!indexValue)
|
||||
result.unsafeAppendWithoutCapacityCheck(0);
|
||||
result.append(0);
|
||||
else
|
||||
result.unsafeAppendWithoutCapacityCheck(indexValue.asInt32());
|
||||
result.append(indexValue.asInt32());
|
||||
}
|
||||
return WTFMove(result);
|
||||
}
|
||||
|
||||
ASSERT(indexingType == JSC::DoubleShape);
|
||||
ASSERT(JSC::Options::allowDoubleShape());
|
||||
for (unsigned i = 0; i < length; i++) {
|
||||
double doubleValue = array->butterfly()->contiguousDouble().at(array, i);
|
||||
if (std::isnan(doubleValue))
|
||||
result.unsafeAppendWithoutCapacityCheck(0);
|
||||
result.append(0);
|
||||
else {
|
||||
auto convertedValue = Converter<IDLType>::convert(lexicalGlobalObject, scope, doubleValue);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
result.unsafeAppendWithoutCapacityCheck(convertedValue);
|
||||
result.append(convertedValue);
|
||||
}
|
||||
}
|
||||
return WTFMove(result);
|
||||
@@ -219,7 +220,7 @@ struct SequenceConverter {
|
||||
auto convertedValue = Converter<IDLType>::convert(lexicalGlobalObject, indexValue);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
result.unsafeAppendWithoutCapacityCheck(convertedValue);
|
||||
result.append(convertedValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -234,7 +235,7 @@ struct SequenceConverter {
|
||||
auto convertedValue = Converter<IDLType>::convert(lexicalGlobalObject, indexValue);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
result.unsafeAppendWithoutCapacityCheck(convertedValue);
|
||||
result.append(convertedValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
|
||||
#include "DOMWrapperWorld.h"
|
||||
#include "JSDOMWrapper.h"
|
||||
#include <JavaScriptCore/JSCJSValue.h>
|
||||
#include <JavaScriptCore/JSCJSValueInlines.h>
|
||||
#include <JavaScriptCore/SlotVisitor.h>
|
||||
#include <JavaScriptCore/Weak.h>
|
||||
#include <JavaScriptCore/WeakInlines.h>
|
||||
#include <variant>
|
||||
|
||||
namespace WebCore {
|
||||
@@ -51,10 +51,6 @@ public:
|
||||
void setWeakly(JSC::JSValue);
|
||||
JSC::JSValue getValue(JSC::JSValue nullValue = JSC::jsUndefined()) const;
|
||||
|
||||
// FIXME: Remove this once IDBRequest semantic bug is fixed.
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=236278
|
||||
void setWithoutBarrier(JSValueInWrappedObject&);
|
||||
|
||||
private:
|
||||
// Keep in mind that all of these fields are accessed concurrently without lock from concurrent GC thread.
|
||||
JSC::JSValue m_nonCell {};
|
||||
@@ -62,7 +58,6 @@ private:
|
||||
};
|
||||
|
||||
JSC::JSValue cachedPropertyValue(JSC::ThrowScope&, JSC::JSGlobalObject&, const JSDOMObject& owner, JSValueInWrappedObject& cacheSlot, const Function<JSC::JSValue(JSC::ThrowScope&)>&);
|
||||
JSC::JSValue cachedPropertyValue(JSC::JSGlobalObject&, const JSDOMObject& owner, JSValueInWrappedObject& cacheSlot, const Function<JSC::JSValue()>&);
|
||||
|
||||
inline JSValueInWrappedObject::JSValueInWrappedObject(JSC::JSValue value)
|
||||
{
|
||||
@@ -115,14 +110,6 @@ inline void JSValueInWrappedObject::clear()
|
||||
m_cell.clear();
|
||||
}
|
||||
|
||||
inline void JSValueInWrappedObject::setWithoutBarrier(JSValueInWrappedObject& other)
|
||||
{
|
||||
JSC::Weak weak { other.m_cell.get() };
|
||||
WTF::storeStoreFence(); // Ensure Weak is fully initialized for concurrent access.
|
||||
m_nonCell = other.m_nonCell;
|
||||
m_cell = WTFMove(weak);
|
||||
}
|
||||
|
||||
inline JSC::JSValue cachedPropertyValue(JSC::JSGlobalObject& lexicalGlobalObject, const JSDOMObject& owner, JSValueInWrappedObject& cachedValue, const Function<JSC::JSValue()>& function)
|
||||
{
|
||||
if (cachedValue && isWorldCompatible(lexicalGlobalObject, cachedValue.getValue()))
|
||||
|
||||
2
src/js/builtins.d.ts
vendored
2
src/js/builtins.d.ts
vendored
@@ -228,6 +228,7 @@ declare const $asyncContext: InternalFieldObject<[ReadonlyArray<any> | undefined
|
||||
declare var $_events: TODO;
|
||||
declare function $abortAlgorithm(): TODO;
|
||||
declare function $abortSteps(): TODO;
|
||||
declare function $addAbortAlgorithmToSignal(signal: AbortSignal, algorithm: () => void): TODO;
|
||||
declare function $addEventListener(): TODO;
|
||||
declare function $appendFromJS(): TODO;
|
||||
declare function $argv(): TODO;
|
||||
@@ -367,6 +368,7 @@ declare function $readableStreamToArray(): TODO;
|
||||
declare function $reader(): TODO;
|
||||
declare function $readyPromise(): TODO;
|
||||
declare function $readyPromiseCapability(): TODO;
|
||||
declare function $removeAbortAlgorithmFromSignal(signal: AbortSignal, algorithmIdentifier: number): TODO;
|
||||
declare function $redirect(): TODO;
|
||||
declare function $relative(): TODO;
|
||||
declare function $releaseLock(): TODO;
|
||||
|
||||
@@ -25,6 +25,7 @@ using namespace JSC;
|
||||
macro(abortAlgorithm) \
|
||||
macro(AbortSignal) \
|
||||
macro(abortSteps) \
|
||||
macro(addAbortAlgorithmToSignal) \
|
||||
macro(addEventListener) \
|
||||
macro(appendFromJS) \
|
||||
macro(argv) \
|
||||
@@ -180,6 +181,7 @@ using namespace JSC;
|
||||
macro(readRequests) \
|
||||
macro(readyPromise) \
|
||||
macro(readyPromiseCapability) \
|
||||
macro(removeAbortAlgorithmFromSignal) \
|
||||
macro(redirect) \
|
||||
macro(relative) \
|
||||
macro(releaseLock) \
|
||||
@@ -234,7 +236,6 @@ using namespace JSC;
|
||||
macro(version) \
|
||||
macro(versions) \
|
||||
macro(view) \
|
||||
macro(whenSignalAborted) \
|
||||
macro(writable) \
|
||||
macro(WritableStream) \
|
||||
macro(WritableStreamDefaultController) \
|
||||
|
||||
@@ -245,7 +245,6 @@ export function readableStreamPipeToWritableStream(
|
||||
|
||||
source.$disturbed = true;
|
||||
|
||||
pipeState.finalized = false;
|
||||
pipeState.shuttingDown = false;
|
||||
pipeState.promiseCapability = $newPromiseCapability(Promise);
|
||||
pipeState.pendingReadPromiseCapability = $newPromiseCapability(Promise);
|
||||
@@ -254,8 +253,6 @@ export function readableStreamPipeToWritableStream(
|
||||
|
||||
if (signal !== undefined) {
|
||||
const algorithm = reason => {
|
||||
if (pipeState.finalized) return;
|
||||
|
||||
$pipeToShutdownWithAction(
|
||||
pipeState,
|
||||
() => {
|
||||
@@ -290,7 +287,13 @@ export function readableStreamPipeToWritableStream(
|
||||
reason,
|
||||
);
|
||||
};
|
||||
if ($whenSignalAborted(signal, algorithm)) return pipeState.promiseCapability.promise;
|
||||
const abortAlgorithmIdentifier = (pipeState.abortAlgorithmIdentifier = $addAbortAlgorithmToSignal(
|
||||
signal,
|
||||
algorithm,
|
||||
));
|
||||
|
||||
if (!abortAlgorithmIdentifier) return pipeState.promiseCapability.promise;
|
||||
pipeState.signal = signal;
|
||||
}
|
||||
|
||||
$pipeToErrorsMustBePropagatedForward(pipeState);
|
||||
@@ -480,8 +483,8 @@ export function pipeToFinalize(pipeState) {
|
||||
$writableStreamDefaultWriterRelease(pipeState.writer);
|
||||
$readableStreamReaderGenericRelease(pipeState.reader);
|
||||
|
||||
// Instead of removing the abort algorithm as per spec, we make it a no-op which is equivalent.
|
||||
pipeState.finalized = true;
|
||||
const signal = pipeState.signal;
|
||||
if (signal) $removeAbortAlgorithmFromSignal(signal, pipeState.abortAlgorithmIdentifier);
|
||||
|
||||
if (arguments.length > 1) pipeState.promiseCapability.reject.$call(undefined, arguments[1]);
|
||||
else pipeState.promiseCapability.resolve.$call();
|
||||
|
||||
Reference in New Issue
Block a user